summaryrefslogtreecommitdiff
path: root/src/libstrongswan/plugins
diff options
context:
space:
mode:
authorRene Mayrhofer <rene@mayrhofer.eu.org>2008-07-10 12:47:56 +0000
committerRene Mayrhofer <rene@mayrhofer.eu.org>2008-07-10 12:47:56 +0000
commiteb841c5ef668a48782ef1154fda65cb6048f5885 (patch)
tree00dd0cb4313bf2291d94ed511fe51f0b4bc7ea7a /src/libstrongswan/plugins
parent738206039047924ae7e4762a53d121be1ca43000 (diff)
downloadvyos-strongswan-eb841c5ef668a48782ef1154fda65cb6048f5885.tar.gz
vyos-strongswan-eb841c5ef668a48782ef1154fda65cb6048f5885.zip
- Updated to new upstream.
Diffstat (limited to 'src/libstrongswan/plugins')
-rw-r--r--src/libstrongswan/plugins/aes/Makefile.am10
-rw-r--r--src/libstrongswan/plugins/aes/Makefile.in494
-rw-r--r--src/libstrongswan/plugins/aes/aes_crypter.c1580
-rw-r--r--src/libstrongswan/plugins/aes/aes_crypter.h50
-rw-r--r--src/libstrongswan/plugins/aes/aes_plugin.c60
-rw-r--r--src/libstrongswan/plugins/aes/aes_plugin.h47
-rw-r--r--src/libstrongswan/plugins/curl/Makefile.am11
-rw-r--r--src/libstrongswan/plugins/curl/Makefile.in495
-rw-r--r--src/libstrongswan/plugins/curl/curl_fetcher.c176
-rw-r--r--src/libstrongswan/plugins/curl/curl_fetcher.h47
-rw-r--r--src/libstrongswan/plugins/curl/curl_plugin.c79
-rw-r--r--src/libstrongswan/plugins/curl/curl_plugin.h47
-rw-r--r--src/libstrongswan/plugins/des/Makefile.am10
-rw-r--r--src/libstrongswan/plugins/des/Makefile.in494
-rw-r--r--src/libstrongswan/plugins/des/des_crypter.c1517
-rw-r--r--src/libstrongswan/plugins/des/des_crypter.h49
-rw-r--r--src/libstrongswan/plugins/des/des_plugin.c62
-rw-r--r--src/libstrongswan/plugins/des/des_plugin.h47
-rw-r--r--src/libstrongswan/plugins/fips_prf/Makefile.am10
-rw-r--r--src/libstrongswan/plugins/fips_prf/Makefile.in496
-rw-r--r--src/libstrongswan/plugins/fips_prf/fips_prf.c252
-rw-r--r--src/libstrongswan/plugins/fips_prf/fips_prf.h59
-rw-r--r--src/libstrongswan/plugins/fips_prf/fips_prf_plugin.c59
-rw-r--r--src/libstrongswan/plugins/fips_prf/fips_prf_plugin.h47
-rw-r--r--src/libstrongswan/plugins/gmp/Makefile.am15
-rw-r--r--src/libstrongswan/plugins/gmp/Makefile.in502
-rw-r--r--src/libstrongswan/plugins/gmp/gmp_diffie_hellman.c567
-rw-r--r--src/libstrongswan/plugins/gmp/gmp_diffie_hellman.h49
-rw-r--r--src/libstrongswan/plugins/gmp/gmp_plugin.c85
-rw-r--r--src/libstrongswan/plugins/gmp/gmp_plugin.h47
-rw-r--r--src/libstrongswan/plugins/gmp/gmp_rsa_private_key.c842
-rw-r--r--src/libstrongswan/plugins/gmp/gmp_rsa_private_key.h48
-rw-r--r--src/libstrongswan/plugins/gmp/gmp_rsa_public_key.c587
-rw-r--r--src/libstrongswan/plugins/gmp/gmp_rsa_public_key.h50
-rw-r--r--src/libstrongswan/plugins/hmac/Makefile.am11
-rw-r--r--src/libstrongswan/plugins/hmac/Makefile.in499
-rw-r--r--src/libstrongswan/plugins/hmac/hmac.c214
-rw-r--r--src/libstrongswan/plugins/hmac/hmac.h93
-rw-r--r--src/libstrongswan/plugins/hmac/hmac_plugin.c84
-rw-r--r--src/libstrongswan/plugins/hmac/hmac_plugin.h47
-rw-r--r--src/libstrongswan/plugins/hmac/hmac_prf.c137
-rw-r--r--src/libstrongswan/plugins/hmac/hmac_prf.h51
-rw-r--r--src/libstrongswan/plugins/hmac/hmac_signer.c199
-rw-r--r--src/libstrongswan/plugins/hmac/hmac_signer.h55
-rw-r--r--src/libstrongswan/plugins/ldap/Makefile.am11
-rw-r--r--src/libstrongswan/plugins/ldap/Makefile.in495
-rw-r--r--src/libstrongswan/plugins/ldap/ldap_fetcher.c213
-rw-r--r--src/libstrongswan/plugins/ldap/ldap_fetcher.h42
-rw-r--r--src/libstrongswan/plugins/ldap/ldap_plugin.c62
-rw-r--r--src/libstrongswan/plugins/ldap/ldap_plugin.h47
-rw-r--r--src/libstrongswan/plugins/md5/Makefile.am10
-rw-r--r--src/libstrongswan/plugins/md5/Makefile.in494
-rw-r--r--src/libstrongswan/plugins/md5/md5_hasher.c392
-rw-r--r--src/libstrongswan/plugins/md5/md5_hasher.h48
-rw-r--r--src/libstrongswan/plugins/md5/md5_plugin.c60
-rw-r--r--src/libstrongswan/plugins/md5/md5_plugin.h47
-rw-r--r--src/libstrongswan/plugins/mysql/Makefile.am12
-rw-r--r--src/libstrongswan/plugins/mysql/Makefile.in497
-rw-r--r--src/libstrongswan/plugins/mysql/mysql_database.c695
-rw-r--r--src/libstrongswan/plugins/mysql/mysql_database.h58
-rw-r--r--src/libstrongswan/plugins/mysql/mysql_plugin.c69
-rw-r--r--src/libstrongswan/plugins/mysql/mysql_plugin.h47
-rw-r--r--src/libstrongswan/plugins/openssl/Makefile.am21
-rw-r--r--src/libstrongswan/plugins/openssl/Makefile.in518
-rw-r--r--src/libstrongswan/plugins/openssl/openssl_crypter.c258
-rw-r--r--src/libstrongswan/plugins/openssl/openssl_crypter.h51
-rw-r--r--src/libstrongswan/plugins/openssl/openssl_diffie_hellman.c242
-rw-r--r--src/libstrongswan/plugins/openssl/openssl_diffie_hellman.h50
-rw-r--r--src/libstrongswan/plugins/openssl/openssl_ec_diffie_hellman.c342
-rw-r--r--src/libstrongswan/plugins/openssl/openssl_ec_diffie_hellman.h50
-rw-r--r--src/libstrongswan/plugins/openssl/openssl_ec_private_key.c445
-rw-r--r--src/libstrongswan/plugins/openssl/openssl_ec_private_key.h49
-rw-r--r--src/libstrongswan/plugins/openssl/openssl_ec_public_key.c447
-rw-r--r--src/libstrongswan/plugins/openssl/openssl_ec_public_key.h49
-rw-r--r--src/libstrongswan/plugins/openssl/openssl_hasher.c185
-rw-r--r--src/libstrongswan/plugins/openssl/openssl_hasher.h50
-rw-r--r--src/libstrongswan/plugins/openssl/openssl_plugin.c164
-rw-r--r--src/libstrongswan/plugins/openssl/openssl_plugin.h49
-rw-r--r--src/libstrongswan/plugins/openssl/openssl_rsa_private_key.c422
-rw-r--r--src/libstrongswan/plugins/openssl/openssl_rsa_private_key.h49
-rw-r--r--src/libstrongswan/plugins/openssl/openssl_rsa_public_key.c433
-rw-r--r--src/libstrongswan/plugins/openssl/openssl_rsa_public_key.h49
-rw-r--r--src/libstrongswan/plugins/openssl/openssl_util.c120
-rw-r--r--src/libstrongswan/plugins/openssl/openssl_util.h70
-rw-r--r--src/libstrongswan/plugins/padlock/Makefile.am12
-rw-r--r--src/libstrongswan/plugins/padlock/Makefile.in500
-rw-r--r--src/libstrongswan/plugins/padlock/padlock_aes_crypter.c201
-rw-r--r--src/libstrongswan/plugins/padlock/padlock_aes_crypter.h50
-rw-r--r--src/libstrongswan/plugins/padlock/padlock_plugin.c64
-rw-r--r--src/libstrongswan/plugins/padlock/padlock_plugin.h47
-rw-r--r--src/libstrongswan/plugins/padlock/padlock_sha1_hasher.c177
-rw-r--r--src/libstrongswan/plugins/padlock/padlock_sha1_hasher.h48
-rw-r--r--src/libstrongswan/plugins/plugin.h49
-rw-r--r--src/libstrongswan/plugins/plugin_loader.c193
-rw-r--r--src/libstrongswan/plugins/plugin_loader.h67
-rw-r--r--src/libstrongswan/plugins/pubkey/Makefile.am13
-rw-r--r--src/libstrongswan/plugins/pubkey/Makefile.in500
-rw-r--r--src/libstrongswan/plugins/pubkey/pubkey_cert.c284
-rw-r--r--src/libstrongswan/plugins/pubkey/pubkey_cert.h51
-rw-r--r--src/libstrongswan/plugins/pubkey/pubkey_plugin.c65
-rw-r--r--src/libstrongswan/plugins/pubkey/pubkey_plugin.h47
-rw-r--r--src/libstrongswan/plugins/pubkey/pubkey_public_key.c185
-rw-r--r--src/libstrongswan/plugins/pubkey/pubkey_public_key.h36
-rw-r--r--src/libstrongswan/plugins/random/Makefile.am11
-rw-r--r--src/libstrongswan/plugins/random/Makefile.in497
-rw-r--r--src/libstrongswan/plugins/random/random_plugin.c62
-rw-r--r--src/libstrongswan/plugins/random/random_plugin.h47
-rw-r--r--src/libstrongswan/plugins/random/random_rng.c134
-rw-r--r--src/libstrongswan/plugins/random/random_rng.h49
-rw-r--r--src/libstrongswan/plugins/sha1/Makefile.am10
-rw-r--r--src/libstrongswan/plugins/sha1/Makefile.in494
-rw-r--r--src/libstrongswan/plugins/sha1/sha1_hasher.c366
-rw-r--r--src/libstrongswan/plugins/sha1/sha1_hasher.h69
-rw-r--r--src/libstrongswan/plugins/sha1/sha1_plugin.c64
-rw-r--r--src/libstrongswan/plugins/sha1/sha1_plugin.h47
-rw-r--r--src/libstrongswan/plugins/sha2/Makefile.am10
-rw-r--r--src/libstrongswan/plugins/sha2/Makefile.in494
-rw-r--r--src/libstrongswan/plugins/sha2/sha2_hasher.c632
-rw-r--r--src/libstrongswan/plugins/sha2/sha2_hasher.h50
-rw-r--r--src/libstrongswan/plugins/sha2/sha2_plugin.c64
-rw-r--r--src/libstrongswan/plugins/sha2/sha2_plugin.h47
-rw-r--r--src/libstrongswan/plugins/sqlite/Makefile.am12
-rw-r--r--src/libstrongswan/plugins/sqlite/Makefile.in499
-rw-r--r--src/libstrongswan/plugins/sqlite/sqlite_database.c321
-rw-r--r--src/libstrongswan/plugins/sqlite/sqlite_database.h46
-rw-r--r--src/libstrongswan/plugins/sqlite/sqlite_plugin.c60
-rw-r--r--src/libstrongswan/plugins/sqlite/sqlite_plugin.h47
-rw-r--r--src/libstrongswan/plugins/x509/Makefile.am16
-rw-r--r--src/libstrongswan/plugins/x509/Makefile.in508
-rw-r--r--src/libstrongswan/plugins/x509/ietf_attr_list.c396
-rw-r--r--src/libstrongswan/plugins/x509/ietf_attr_list.h81
-rw-r--r--src/libstrongswan/plugins/x509/x509_ac.c1140
-rw-r--r--src/libstrongswan/plugins/x509/x509_ac.h59
-rw-r--r--src/libstrongswan/plugins/x509/x509_cert.c1295
-rw-r--r--src/libstrongswan/plugins/x509/x509_cert.h49
-rw-r--r--src/libstrongswan/plugins/x509/x509_crl.c742
-rw-r--r--src/libstrongswan/plugins/x509/x509_crl.h48
-rw-r--r--src/libstrongswan/plugins/x509/x509_ocsp_request.c612
-rw-r--r--src/libstrongswan/plugins/x509/x509_ocsp_request.h54
-rw-r--r--src/libstrongswan/plugins/x509/x509_ocsp_response.c990
-rw-r--r--src/libstrongswan/plugins/x509/x509_ocsp_response.h47
-rw-r--r--src/libstrongswan/plugins/x509/x509_plugin.c80
-rw-r--r--src/libstrongswan/plugins/x509/x509_plugin.h47
-rw-r--r--src/libstrongswan/plugins/xcbc/Makefile.am11
-rw-r--r--src/libstrongswan/plugins/xcbc/Makefile.in499
-rw-r--r--src/libstrongswan/plugins/xcbc/xcbc.c299
-rw-r--r--src/libstrongswan/plugins/xcbc/xcbc.h78
-rw-r--r--src/libstrongswan/plugins/xcbc/xcbc_plugin.c65
-rw-r--r--src/libstrongswan/plugins/xcbc/xcbc_plugin.h47
-rw-r--r--src/libstrongswan/plugins/xcbc/xcbc_prf.c131
-rw-r--r--src/libstrongswan/plugins/xcbc/xcbc_prf.h50
-rw-r--r--src/libstrongswan/plugins/xcbc/xcbc_signer.c177
-rw-r--r--src/libstrongswan/plugins/xcbc/xcbc_signer.h47
153 files changed, 32081 insertions, 0 deletions
diff --git a/src/libstrongswan/plugins/aes/Makefile.am b/src/libstrongswan/plugins/aes/Makefile.am
new file mode 100644
index 000000000..e73040f27
--- /dev/null
+++ b/src/libstrongswan/plugins/aes/Makefile.am
@@ -0,0 +1,10 @@
+
+INCLUDES = -I$(top_srcdir)/src/libstrongswan
+
+AM_CFLAGS = -rdynamic
+
+plugin_LTLIBRARIES = libstrongswan-aes.la
+
+libstrongswan_aes_la_SOURCES = aes_plugin.h aes_plugin.c aes_crypter.c aes_crypter.h
+libstrongswan_aes_la_LDFLAGS = -module
+
diff --git a/src/libstrongswan/plugins/aes/Makefile.in b/src/libstrongswan/plugins/aes/Makefile.in
new file mode 100644
index 000000000..ed3dfb621
--- /dev/null
+++ b/src/libstrongswan/plugins/aes/Makefile.in
@@ -0,0 +1,494 @@
+# Makefile.in generated by automake 1.10.1 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+VPATH = @srcdir@
+pkgdatadir = $(datadir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+subdir = src/libstrongswan/plugins/aes
+DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/configure.in
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+mkinstalldirs = $(install_sh) -d
+CONFIG_CLEAN_FILES =
+am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
+am__vpath_adj = case $$p in \
+ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
+ *) f=$$p;; \
+ esac;
+am__strip_dir = `echo $$p | sed -e 's|^.*/||'`;
+am__installdirs = "$(DESTDIR)$(plugindir)"
+pluginLTLIBRARIES_INSTALL = $(INSTALL)
+LTLIBRARIES = $(plugin_LTLIBRARIES)
+libstrongswan_aes_la_LIBADD =
+am_libstrongswan_aes_la_OBJECTS = aes_plugin.lo aes_crypter.lo
+libstrongswan_aes_la_OBJECTS = $(am_libstrongswan_aes_la_OBJECTS)
+libstrongswan_aes_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(libstrongswan_aes_la_LDFLAGS) $(LDFLAGS) -o $@
+DEFAULT_INCLUDES = -I.@am__isrc@
+depcomp = $(SHELL) $(top_srcdir)/depcomp
+am__depfiles_maybe = depfiles
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+ --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
+ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+CCLD = $(CC)
+LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+ --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \
+ $(LDFLAGS) -o $@
+SOURCES = $(libstrongswan_aes_la_SOURCES)
+DIST_SOURCES = $(libstrongswan_aes_la_SOURCES)
+ETAGS = etags
+CTAGS = ctags
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+AMTAR = @AMTAR@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CXX = @CXX@
+CXXCPP = @CXXCPP@
+CXXDEPMODE = @CXXDEPMODE@
+CXXFLAGS = @CXXFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DSYMUTIL = @DSYMUTIL@
+ECHO = @ECHO@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+F77 = @F77@
+FFLAGS = @FFLAGS@
+GPERF = @GPERF@
+GREP = @GREP@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+IPSEC_ROUTING_TABLE = @IPSEC_ROUTING_TABLE@
+IPSEC_ROUTING_TABLE_PRIO = @IPSEC_ROUTING_TABLE_PRIO@
+LDFLAGS = @LDFLAGS@
+LEX = @LEX@
+LEXLIB = @LEXLIB@
+LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LINUX_HEADERS = @LINUX_HEADERS@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+MAKEINFO = @MAKEINFO@
+MKDIR_P = @MKDIR_P@
+NMEDIT = @NMEDIT@
+OBJEXT = @OBJEXT@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PERL = @PERL@
+PKG_CONFIG = @PKG_CONFIG@
+RANLIB = @RANLIB@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRIP = @STRIP@
+VERSION = @VERSION@
+YACC = @YACC@
+YFLAGS = @YFLAGS@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_CXX = @ac_ct_CXX@
+ac_ct_F77 = @ac_ct_F77@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+confdir = @confdir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+gtk_CFLAGS = @gtk_CFLAGS@
+gtk_LIBS = @gtk_LIBS@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+ipsecdir = @ipsecdir@
+ipsecgroup = @ipsecgroup@
+ipsecuser = @ipsecuser@
+libdir = @libdir@
+libexecdir = @libexecdir@
+libstrongswan_plugins = @libstrongswan_plugins@
+linuxdir = @linuxdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+piddir = @piddir@
+plugindir = @plugindir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+resolv_conf = @resolv_conf@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+simreader = @simreader@
+srcdir = @srcdir@
+strongswan_conf = @strongswan_conf@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+xml_CFLAGS = @xml_CFLAGS@
+xml_LIBS = @xml_LIBS@
+INCLUDES = -I$(top_srcdir)/src/libstrongswan
+AM_CFLAGS = -rdynamic
+plugin_LTLIBRARIES = libstrongswan-aes.la
+libstrongswan_aes_la_SOURCES = aes_plugin.h aes_plugin.c aes_crypter.c aes_crypter.h
+libstrongswan_aes_la_LDFLAGS = -module
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .c .lo .o .obj
+$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \
+ && exit 0; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/libstrongswan/plugins/aes/Makefile'; \
+ cd $(top_srcdir) && \
+ $(AUTOMAKE) --gnu src/libstrongswan/plugins/aes/Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+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) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(pluginLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) '$$p' '$(DESTDIR)$(plugindir)/$$f'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(pluginLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) "$$p" "$(DESTDIR)$(plugindir)/$$f"; \
+ else :; fi; \
+ done
+
+uninstall-pluginLTLIBRARIES:
+ @$(NORMAL_UNINSTALL)
+ @list='$(plugin_LTLIBRARIES)'; for p in $$list; do \
+ p=$(am__strip_dir) \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(plugindir)/$$p'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(plugindir)/$$p"; \
+ 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
+libstrongswan-aes.la: $(libstrongswan_aes_la_OBJECTS) $(libstrongswan_aes_la_DEPENDENCIES)
+ $(libstrongswan_aes_la_LINK) -rpath $(plugindir) $(libstrongswan_aes_la_OBJECTS) $(libstrongswan_aes_la_LIBADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/aes_crypter.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/aes_plugin.Plo@am__quote@
+
+.c.o:
+@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(COMPILE) -c $<
+
+.c.obj:
+@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'`
+
+.c.lo:
+@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $<
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+
+ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonemtpy = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ mkid -fID $$unique
+tags: TAGS
+
+TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ tags=; \
+ here=`pwd`; \
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \
+ test -n "$$unique" || unique=$$empty_fix; \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ $$tags $$unique; \
+ fi
+ctags: CTAGS
+CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ tags=; \
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ test -z "$(CTAGS_ARGS)$$tags$$unique" \
+ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+ $$tags $$unique
+
+GTAGS:
+ here=`$(am__cd) $(top_builddir) && pwd` \
+ && cd $(top_srcdir) \
+ && gtags -i $(GTAGS_ARGS) $$here
+
+distclean-tags:
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+distdir: $(DISTFILES)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ list='$(DISTFILES)'; \
+ dist_files=`for file in $$list; do echo $$file; done | \
+ sed -e "s|^$$srcdirstrip/||;t" \
+ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+ case $$dist_files in \
+ */*) $(MKDIR_P) `echo "$$dist_files" | \
+ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+ sort -u` ;; \
+ esac; \
+ for file in $$dist_files; do \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ if test -d $$d/$$file; then \
+ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
+ fi; \
+ cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
+ else \
+ test -f $(distdir)/$$file \
+ || cp -p $$d/$$file $(distdir)/$$file \
+ || exit 1; \
+ fi; \
+ done
+check-am: all-am
+check: check-am
+all-am: Makefile $(LTLIBRARIES)
+installdirs:
+ for dir in "$(DESTDIR)$(plugindir)"; do \
+ test -z "$$dir" || $(MKDIR_P) "$$dir"; \
+ done
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ `test -z '$(STRIP)' || \
+ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+clean: clean-am
+
+clean-am: clean-generic clean-libtool clean-pluginLTLIBRARIES \
+ mostlyclean-am
+
+distclean: distclean-am
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+ distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+info: info-am
+
+info-am:
+
+install-data-am: install-pluginLTLIBRARIES
+
+install-dvi: install-dvi-am
+
+install-exec-am:
+
+install-html: install-html-am
+
+install-info: install-info-am
+
+install-man:
+
+install-pdf: install-pdf-am
+
+install-ps: install-ps-am
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic \
+ mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am: uninstall-pluginLTLIBRARIES
+
+.MAKE: install-am install-strip
+
+.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \
+ clean-libtool clean-pluginLTLIBRARIES ctags distclean \
+ distclean-compile distclean-generic distclean-libtool \
+ distclean-tags distdir dvi dvi-am html html-am info info-am \
+ install install-am install-data install-data-am install-dvi \
+ install-dvi-am install-exec install-exec-am install-html \
+ install-html-am install-info install-info-am install-man \
+ install-pdf install-pdf-am install-pluginLTLIBRARIES \
+ install-ps install-ps-am install-strip installcheck \
+ installcheck-am installdirs maintainer-clean \
+ maintainer-clean-generic mostlyclean mostlyclean-compile \
+ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
+ tags uninstall uninstall-am uninstall-pluginLTLIBRARIES
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/src/libstrongswan/plugins/aes/aes_crypter.c b/src/libstrongswan/plugins/aes/aes_crypter.c
new file mode 100644
index 000000000..ce4c6da99
--- /dev/null
+++ b/src/libstrongswan/plugins/aes/aes_crypter.c
@@ -0,0 +1,1580 @@
+/*
+ * Copyright (C) 2001 Dr B. R. Gladman <brg@gladman.uk.net>
+ * 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
+ * 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.
+ *
+ * $Id: aes_crypter.c 3900 2008-04-30 14:02:25Z martin $
+ */
+
+#include "aes_crypter.h"
+
+/*
+ * The number of key schedule words for different block and key lengths
+ * allowing for method of computation which requires the length to be a
+ * multiple of the key length. This version of AES implementation supports
+ * all three keylengths 16, 24 and 32 bytes!
+ *
+ * Nk = 4 6 8
+ * -------------
+ * Nb = 4 | 60 60 64
+ * 6 | 96 90 96
+ * 8 | 120 120 120
+ */
+#define AES_KS_LENGTH 120
+#define AES_RC_LENGTH 29
+
+#define AES_BLOCK_SIZE 16
+
+typedef struct private_aes_crypter_t private_aes_crypter_t;
+
+/**
+ * Class implementing the AES symmetric encryption algorithm.
+ *
+ * @ingroup crypters
+ */
+struct private_aes_crypter_t {
+
+ /**
+ * Public part of this class.
+ */
+ aes_crypter_t public;
+
+ /**
+ * Number of words in the key input block.
+ */
+ u_int32_t aes_Nkey;
+
+ /**
+ * The number of cipher rounds.
+ */
+ u_int32_t aes_Nrnd;
+
+ /**
+ * The encryption key schedule.
+ */
+ u_int32_t aes_e_key[AES_KS_LENGTH];
+
+ /**
+ * The decryption key schedule.
+ */
+ u_int32_t aes_d_key[AES_KS_LENGTH];
+
+ /**
+ * Key size of this AES cypher object.
+ */
+ u_int32_t key_size;
+};
+
+
+/* ugly macro stuff */
+
+/* 1. Define UNROLL for full loop unrolling in encryption and decryption.
+ * 2. Define PARTIAL_UNROLL to unroll two loops in encryption and decryption.
+ * 3. Define FIXED_TABLES for compiled rather than dynamic tables.
+ * 4. Define FF_TABLES to use tables for field multiplies and inverses.
+ * Do not enable this without understanding stack space requirements.
+ * 5. Define ARRAYS to use arrays to hold the local state block. If this
+ * is not defined, individually declared 32-bit words are used.
+ * 6. Define FAST_VARIABLE if a high speed variable block implementation
+ * is needed (essentially three separate fixed block size code sequences)
+ * 7. Define either ONE_TABLE or FOUR_TABLES for a fast table driven
+ * version using 1 table (2 kbytes of table space) or 4 tables (8
+ * kbytes of table space) for higher speed.
+ * 8. Define either ONE_LR_TABLE or FOUR_LR_TABLES for a further speed
+ * increase by using tables for the last rounds but with more table
+ * space (2 or 8 kbytes extra).
+ * 9. If neither ONE_TABLE nor FOUR_TABLES is defined, a compact but
+ * slower version is provided.
+ * 10. If fast decryption key scheduling is needed define ONE_IM_TABLE
+ * or FOUR_IM_TABLES for higher speed (2 or 8 kbytes extra).
+ */
+
+#define UNROLL
+//#define PARTIAL_UNROLL
+
+#define FIXED_TABLES
+//#define FF_TABLES
+//#define ARRAYS
+#define FAST_VARIABLE
+
+//#define ONE_TABLE
+#define FOUR_TABLES
+
+//#define ONE_LR_TABLE
+#define FOUR_LR_TABLES
+
+//#define ONE_IM_TABLE
+#define FOUR_IM_TABLES
+
+#if defined(UNROLL) && defined (PARTIAL_UNROLL)
+#error both UNROLL and PARTIAL_UNROLL are defined
+#endif
+
+#if defined(ONE_TABLE) && defined (FOUR_TABLES)
+#error both ONE_TABLE and FOUR_TABLES are defined
+#endif
+
+#if defined(ONE_LR_TABLE) && defined (FOUR_LR_TABLES)
+#error both ONE_LR_TABLE and FOUR_LR_TABLES are defined
+#endif
+
+#if defined(ONE_IM_TABLE) && defined (FOUR_IM_TABLES)
+#error both ONE_IM_TABLE and FOUR_IM_TABLES are defined
+#endif
+
+#if defined(AES_BLOCK_SIZE) && AES_BLOCK_SIZE != 16 && AES_BLOCK_SIZE != 24 && AES_BLOCK_SIZE != 32
+#error an illegal block size has been specified
+#endif
+
+/**
+ * Rotates bytes within words by n positions, moving bytes
+ * to higher index positions with wrap around into low positions.
+ */
+#define upr(x,n) (((x) << 8 * (n)) | ((x) >> (32 - 8 * (n))))
+/**
+ * Moves bytes by n positions to higher index positions in
+ * words but without wrap around.
+ */
+#define ups(x,n) ((x) << 8 * (n))
+
+/**
+ * Extracts a byte from a word.
+ */
+#define bval(x,n) ((unsigned char)((x) >> 8 * (n)))
+#define bytes2word(b0, b1, b2, b3) \
+ ((u_int32_t)(b3) << 24 | (u_int32_t)(b2) << 16 | (u_int32_t)(b1) << 8 | (b0))
+
+
+/* little endian processor without data alignment restrictions: AES_LE_OK */
+/* original code: i386 */
+#if defined(i386) || defined(_I386) || defined(__i386__) || defined(__i386)
+#define AES_LE_OK 1
+/* added (tested): alpha --jjo */
+#elif defined(__alpha__)|| defined (__alpha)
+#define AES_LE_OK 1
+/* added (tested): ia64 --jjo */
+#elif defined(__ia64__)|| defined (__ia64)
+#define AES_LE_OK 1
+#endif
+
+#ifdef AES_LE_OK
+/* little endian processor without data alignment restrictions */
+#define word_in(x) *(u_int32_t*)(x)
+#define const_word_in(x) *(const u_int32_t*)(x)
+#define word_out(x,v) *(u_int32_t*)(x) = (v)
+#define const_word_out(x,v) *(const u_int32_t*)(x) = (v)
+#else
+/* slower but generic big endian or with data alignment restrictions */
+/* some additional "const" touches to stop "gcc -Wcast-qual" complains --jjo */
+#define word_in(x) ((u_int32_t)(((unsigned char *)(x))[0])|((u_int32_t)(((unsigned char *)(x))[1])<<8)|((u_int32_t)(((unsigned char *)(x))[2])<<16)|((u_int32_t)(((unsigned char *)(x))[3])<<24))
+#define const_word_in(x) ((const u_int32_t)(((const unsigned char *)(x))[0])|((const u_int32_t)(((const unsigned char *)(x))[1])<<8)|((const u_int32_t)(((const unsigned char *)(x))[2])<<16)|((const u_int32_t)(((const unsigned char *)(x))[3])<<24))
+#define word_out(x,v) ((unsigned char *)(x))[0]=(v),((unsigned char *)(x))[1]=((v)>>8),((unsigned char *)(x))[2]=((v)>>16),((unsigned char *)(x))[3]=((v)>>24)
+#define const_word_out(x,v) ((const unsigned char *)(x))[0]=(v),((const unsigned char *)(x))[1]=((v)>>8),((const unsigned char *)(x))[2]=((v)>>16),((const unsigned char *)(x))[3]=((v)>>24)
+#endif
+
+// Disable at least some poor combinations of options
+
+#if !defined(ONE_TABLE) && !defined(FOUR_TABLES)
+#define FIXED_TABLES
+#undef UNROLL
+#undef ONE_LR_TABLE
+#undef FOUR_LR_TABLES
+#undef ONE_IM_TABLE
+#undef FOUR_IM_TABLES
+#elif !defined(FOUR_TABLES)
+#ifdef FOUR_LR_TABLES
+#undef FOUR_LR_TABLES
+#define ONE_LR_TABLE
+#endif
+#ifdef FOUR_IM_TABLES
+#undef FOUR_IM_TABLES
+#define ONE_IM_TABLE
+#endif
+#elif !defined(AES_BLOCK_SIZE)
+#if defined(UNROLL)
+#define PARTIAL_UNROLL
+#undef UNROLL
+#endif
+#endif
+
+// the finite field modular polynomial and elements
+
+#define ff_poly 0x011b
+#define ff_hi 0x80
+
+// multiply four bytes in GF(2^8) by 'x' {02} in parallel
+
+#define m1 0x80808080
+#define m2 0x7f7f7f7f
+#define m3 0x0000001b
+#define FFmulX(x) ((((x) & m2) << 1) ^ ((((x) & m1) >> 7) * m3))
+
+// The following defines provide alternative definitions of FFmulX that might
+// give improved performance if a fast 32-bit multiply is not available. Note
+// that a temporary variable u needs to be defined where FFmulX is used.
+
+// #define FFmulX(x) (u = (x) & m1, u |= (u >> 1), ((x) & m2) << 1) ^ ((u >> 3) | (u >> 6))
+// #define m4 0x1b1b1b1b
+// #define FFmulX(x) (u = (x) & m1, ((x) & m2) << 1) ^ ((u - (u >> 7)) & m4)
+
+// perform column mix operation on four bytes in parallel
+
+#define fwd_mcol(x) (f2 = FFmulX(x), f2 ^ upr(x ^ f2,3) ^ upr(x,2) ^ upr(x,1))
+
+#if defined(FIXED_TABLES)
+
+// the S-Box table
+
+static const unsigned char s_box[256] =
+{
+ 0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5,
+ 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76,
+ 0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0,
+ 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0,
+ 0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc,
+ 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15,
+ 0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a,
+ 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75,
+ 0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0,
+ 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84,
+ 0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b,
+ 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf,
+ 0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85,
+ 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8,
+ 0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5,
+ 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2,
+ 0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17,
+ 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73,
+ 0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88,
+ 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb,
+ 0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c,
+ 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79,
+ 0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9,
+ 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08,
+ 0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6,
+ 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a,
+ 0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e,
+ 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e,
+ 0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94,
+ 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf,
+ 0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68,
+ 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16
+};
+
+// the inverse S-Box table
+
+static const unsigned char inv_s_box[256] =
+{
+ 0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38,
+ 0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb,
+ 0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87,
+ 0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb,
+ 0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d,
+ 0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e,
+ 0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2,
+ 0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25,
+ 0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16,
+ 0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92,
+ 0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda,
+ 0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84,
+ 0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a,
+ 0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06,
+ 0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02,
+ 0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b,
+ 0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea,
+ 0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73,
+ 0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85,
+ 0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e,
+ 0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89,
+ 0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b,
+ 0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20,
+ 0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4,
+ 0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31,
+ 0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f,
+ 0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d,
+ 0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef,
+ 0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0,
+ 0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61,
+ 0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26,
+ 0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d
+};
+
+#define w0(p) 0x000000##p
+
+// Number of elements required in this table for different
+// block and key lengths is:
+//
+// Nk = 4 6 8
+// ----------
+// Nb = 4 | 10 8 7
+// 6 | 19 12 11
+// 8 | 29 19 14
+//
+// this table can be a table of bytes if the key schedule
+// code is adjusted accordingly
+
+static const u_int32_t rcon_tab[29] =
+{
+ w0(01), w0(02), w0(04), w0(08),
+ w0(10), w0(20), w0(40), w0(80),
+ w0(1b), w0(36), w0(6c), w0(d8),
+ w0(ab), w0(4d), w0(9a), w0(2f),
+ w0(5e), w0(bc), w0(63), w0(c6),
+ w0(97), w0(35), w0(6a), w0(d4),
+ w0(b3), w0(7d), w0(fa), w0(ef),
+ w0(c5)
+};
+
+#undef w0
+
+#define r0(p,q,r,s) 0x##p##q##r##s
+#define r1(p,q,r,s) 0x##q##r##s##p
+#define r2(p,q,r,s) 0x##r##s##p##q
+#define r3(p,q,r,s) 0x##s##p##q##r
+#define w0(p) 0x000000##p
+#define w1(p) 0x0000##p##00
+#define w2(p) 0x00##p##0000
+#define w3(p) 0x##p##000000
+
+#if defined(FIXED_TABLES) && (defined(ONE_TABLE) || defined(FOUR_TABLES))
+
+// data for forward tables (other than last round)
+
+#define f_table \
+ r(a5,63,63,c6), r(84,7c,7c,f8), r(99,77,77,ee), r(8d,7b,7b,f6),\
+ r(0d,f2,f2,ff), r(bd,6b,6b,d6), r(b1,6f,6f,de), r(54,c5,c5,91),\
+ r(50,30,30,60), r(03,01,01,02), r(a9,67,67,ce), r(7d,2b,2b,56),\
+ r(19,fe,fe,e7), r(62,d7,d7,b5), r(e6,ab,ab,4d), r(9a,76,76,ec),\
+ r(45,ca,ca,8f), r(9d,82,82,1f), r(40,c9,c9,89), r(87,7d,7d,fa),\
+ r(15,fa,fa,ef), r(eb,59,59,b2), r(c9,47,47,8e), r(0b,f0,f0,fb),\
+ r(ec,ad,ad,41), r(67,d4,d4,b3), r(fd,a2,a2,5f), r(ea,af,af,45),\
+ r(bf,9c,9c,23), r(f7,a4,a4,53), r(96,72,72,e4), r(5b,c0,c0,9b),\
+ r(c2,b7,b7,75), r(1c,fd,fd,e1), r(ae,93,93,3d), r(6a,26,26,4c),\
+ r(5a,36,36,6c), r(41,3f,3f,7e), r(02,f7,f7,f5), r(4f,cc,cc,83),\
+ r(5c,34,34,68), r(f4,a5,a5,51), r(34,e5,e5,d1), r(08,f1,f1,f9),\
+ r(93,71,71,e2), r(73,d8,d8,ab), r(53,31,31,62), r(3f,15,15,2a),\
+ r(0c,04,04,08), r(52,c7,c7,95), r(65,23,23,46), r(5e,c3,c3,9d),\
+ r(28,18,18,30), r(a1,96,96,37), r(0f,05,05,0a), r(b5,9a,9a,2f),\
+ r(09,07,07,0e), r(36,12,12,24), r(9b,80,80,1b), r(3d,e2,e2,df),\
+ r(26,eb,eb,cd), r(69,27,27,4e), r(cd,b2,b2,7f), r(9f,75,75,ea),\
+ r(1b,09,09,12), r(9e,83,83,1d), r(74,2c,2c,58), r(2e,1a,1a,34),\
+ r(2d,1b,1b,36), r(b2,6e,6e,dc), r(ee,5a,5a,b4), r(fb,a0,a0,5b),\
+ r(f6,52,52,a4), r(4d,3b,3b,76), r(61,d6,d6,b7), r(ce,b3,b3,7d),\
+ r(7b,29,29,52), r(3e,e3,e3,dd), r(71,2f,2f,5e), r(97,84,84,13),\
+ r(f5,53,53,a6), r(68,d1,d1,b9), r(00,00,00,00), r(2c,ed,ed,c1),\
+ r(60,20,20,40), r(1f,fc,fc,e3), r(c8,b1,b1,79), r(ed,5b,5b,b6),\
+ r(be,6a,6a,d4), r(46,cb,cb,8d), r(d9,be,be,67), r(4b,39,39,72),\
+ r(de,4a,4a,94), r(d4,4c,4c,98), r(e8,58,58,b0), r(4a,cf,cf,85),\
+ r(6b,d0,d0,bb), r(2a,ef,ef,c5), r(e5,aa,aa,4f), r(16,fb,fb,ed),\
+ r(c5,43,43,86), r(d7,4d,4d,9a), r(55,33,33,66), r(94,85,85,11),\
+ r(cf,45,45,8a), r(10,f9,f9,e9), r(06,02,02,04), r(81,7f,7f,fe),\
+ r(f0,50,50,a0), r(44,3c,3c,78), r(ba,9f,9f,25), r(e3,a8,a8,4b),\
+ r(f3,51,51,a2), r(fe,a3,a3,5d), r(c0,40,40,80), r(8a,8f,8f,05),\
+ r(ad,92,92,3f), r(bc,9d,9d,21), r(48,38,38,70), r(04,f5,f5,f1),\
+ r(df,bc,bc,63), r(c1,b6,b6,77), r(75,da,da,af), r(63,21,21,42),\
+ r(30,10,10,20), r(1a,ff,ff,e5), r(0e,f3,f3,fd), r(6d,d2,d2,bf),\
+ r(4c,cd,cd,81), r(14,0c,0c,18), r(35,13,13,26), r(2f,ec,ec,c3),\
+ r(e1,5f,5f,be), r(a2,97,97,35), r(cc,44,44,88), r(39,17,17,2e),\
+ r(57,c4,c4,93), r(f2,a7,a7,55), r(82,7e,7e,fc), r(47,3d,3d,7a),\
+ r(ac,64,64,c8), r(e7,5d,5d,ba), r(2b,19,19,32), r(95,73,73,e6),\
+ r(a0,60,60,c0), r(98,81,81,19), r(d1,4f,4f,9e), r(7f,dc,dc,a3),\
+ r(66,22,22,44), r(7e,2a,2a,54), r(ab,90,90,3b), r(83,88,88,0b),\
+ r(ca,46,46,8c), r(29,ee,ee,c7), r(d3,b8,b8,6b), r(3c,14,14,28),\
+ r(79,de,de,a7), r(e2,5e,5e,bc), r(1d,0b,0b,16), r(76,db,db,ad),\
+ r(3b,e0,e0,db), r(56,32,32,64), r(4e,3a,3a,74), r(1e,0a,0a,14),\
+ r(db,49,49,92), r(0a,06,06,0c), r(6c,24,24,48), r(e4,5c,5c,b8),\
+ r(5d,c2,c2,9f), r(6e,d3,d3,bd), r(ef,ac,ac,43), r(a6,62,62,c4),\
+ r(a8,91,91,39), r(a4,95,95,31), r(37,e4,e4,d3), r(8b,79,79,f2),\
+ r(32,e7,e7,d5), r(43,c8,c8,8b), r(59,37,37,6e), r(b7,6d,6d,da),\
+ r(8c,8d,8d,01), r(64,d5,d5,b1), r(d2,4e,4e,9c), r(e0,a9,a9,49),\
+ r(b4,6c,6c,d8), r(fa,56,56,ac), r(07,f4,f4,f3), r(25,ea,ea,cf),\
+ r(af,65,65,ca), r(8e,7a,7a,f4), r(e9,ae,ae,47), r(18,08,08,10),\
+ r(d5,ba,ba,6f), r(88,78,78,f0), r(6f,25,25,4a), r(72,2e,2e,5c),\
+ r(24,1c,1c,38), r(f1,a6,a6,57), r(c7,b4,b4,73), r(51,c6,c6,97),\
+ r(23,e8,e8,cb), r(7c,dd,dd,a1), r(9c,74,74,e8), r(21,1f,1f,3e),\
+ r(dd,4b,4b,96), r(dc,bd,bd,61), r(86,8b,8b,0d), r(85,8a,8a,0f),\
+ r(90,70,70,e0), r(42,3e,3e,7c), r(c4,b5,b5,71), r(aa,66,66,cc),\
+ r(d8,48,48,90), r(05,03,03,06), r(01,f6,f6,f7), r(12,0e,0e,1c),\
+ r(a3,61,61,c2), r(5f,35,35,6a), r(f9,57,57,ae), r(d0,b9,b9,69),\
+ r(91,86,86,17), r(58,c1,c1,99), r(27,1d,1d,3a), r(b9,9e,9e,27),\
+ r(38,e1,e1,d9), r(13,f8,f8,eb), r(b3,98,98,2b), r(33,11,11,22),\
+ r(bb,69,69,d2), r(70,d9,d9,a9), r(89,8e,8e,07), r(a7,94,94,33),\
+ r(b6,9b,9b,2d), r(22,1e,1e,3c), r(92,87,87,15), r(20,e9,e9,c9),\
+ r(49,ce,ce,87), r(ff,55,55,aa), r(78,28,28,50), r(7a,df,df,a5),\
+ r(8f,8c,8c,03), r(f8,a1,a1,59), r(80,89,89,09), r(17,0d,0d,1a),\
+ r(da,bf,bf,65), r(31,e6,e6,d7), r(c6,42,42,84), r(b8,68,68,d0),\
+ r(c3,41,41,82), r(b0,99,99,29), r(77,2d,2d,5a), r(11,0f,0f,1e),\
+ r(cb,b0,b0,7b), r(fc,54,54,a8), r(d6,bb,bb,6d), r(3a,16,16,2c)
+
+// data for inverse tables (other than last round)
+
+#define i_table \
+ r(50,a7,f4,51), r(53,65,41,7e), r(c3,a4,17,1a), r(96,5e,27,3a),\
+ r(cb,6b,ab,3b), r(f1,45,9d,1f), r(ab,58,fa,ac), r(93,03,e3,4b),\
+ r(55,fa,30,20), r(f6,6d,76,ad), r(91,76,cc,88), r(25,4c,02,f5),\
+ r(fc,d7,e5,4f), r(d7,cb,2a,c5), r(80,44,35,26), r(8f,a3,62,b5),\
+ r(49,5a,b1,de), r(67,1b,ba,25), r(98,0e,ea,45), r(e1,c0,fe,5d),\
+ r(02,75,2f,c3), r(12,f0,4c,81), r(a3,97,46,8d), r(c6,f9,d3,6b),\
+ r(e7,5f,8f,03), r(95,9c,92,15), r(eb,7a,6d,bf), r(da,59,52,95),\
+ r(2d,83,be,d4), r(d3,21,74,58), r(29,69,e0,49), r(44,c8,c9,8e),\
+ r(6a,89,c2,75), r(78,79,8e,f4), r(6b,3e,58,99), r(dd,71,b9,27),\
+ r(b6,4f,e1,be), r(17,ad,88,f0), r(66,ac,20,c9), r(b4,3a,ce,7d),\
+ r(18,4a,df,63), r(82,31,1a,e5), r(60,33,51,97), r(45,7f,53,62),\
+ r(e0,77,64,b1), r(84,ae,6b,bb), r(1c,a0,81,fe), r(94,2b,08,f9),\
+ r(58,68,48,70), r(19,fd,45,8f), r(87,6c,de,94), r(b7,f8,7b,52),\
+ r(23,d3,73,ab), r(e2,02,4b,72), r(57,8f,1f,e3), r(2a,ab,55,66),\
+ r(07,28,eb,b2), r(03,c2,b5,2f), r(9a,7b,c5,86), r(a5,08,37,d3),\
+ r(f2,87,28,30), r(b2,a5,bf,23), r(ba,6a,03,02), r(5c,82,16,ed),\
+ r(2b,1c,cf,8a), r(92,b4,79,a7), r(f0,f2,07,f3), r(a1,e2,69,4e),\
+ r(cd,f4,da,65), r(d5,be,05,06), r(1f,62,34,d1), r(8a,fe,a6,c4),\
+ r(9d,53,2e,34), r(a0,55,f3,a2), r(32,e1,8a,05), r(75,eb,f6,a4),\
+ r(39,ec,83,0b), r(aa,ef,60,40), r(06,9f,71,5e), r(51,10,6e,bd),\
+ r(f9,8a,21,3e), r(3d,06,dd,96), r(ae,05,3e,dd), r(46,bd,e6,4d),\
+ r(b5,8d,54,91), r(05,5d,c4,71), r(6f,d4,06,04), r(ff,15,50,60),\
+ r(24,fb,98,19), r(97,e9,bd,d6), r(cc,43,40,89), r(77,9e,d9,67),\
+ r(bd,42,e8,b0), r(88,8b,89,07), r(38,5b,19,e7), r(db,ee,c8,79),\
+ r(47,0a,7c,a1), r(e9,0f,42,7c), r(c9,1e,84,f8), r(00,00,00,00),\
+ r(83,86,80,09), r(48,ed,2b,32), r(ac,70,11,1e), r(4e,72,5a,6c),\
+ r(fb,ff,0e,fd), r(56,38,85,0f), r(1e,d5,ae,3d), r(27,39,2d,36),\
+ r(64,d9,0f,0a), r(21,a6,5c,68), r(d1,54,5b,9b), r(3a,2e,36,24),\
+ r(b1,67,0a,0c), r(0f,e7,57,93), r(d2,96,ee,b4), r(9e,91,9b,1b),\
+ r(4f,c5,c0,80), r(a2,20,dc,61), r(69,4b,77,5a), r(16,1a,12,1c),\
+ r(0a,ba,93,e2), r(e5,2a,a0,c0), r(43,e0,22,3c), r(1d,17,1b,12),\
+ r(0b,0d,09,0e), r(ad,c7,8b,f2), r(b9,a8,b6,2d), r(c8,a9,1e,14),\
+ r(85,19,f1,57), r(4c,07,75,af), r(bb,dd,99,ee), r(fd,60,7f,a3),\
+ r(9f,26,01,f7), r(bc,f5,72,5c), r(c5,3b,66,44), r(34,7e,fb,5b),\
+ r(76,29,43,8b), r(dc,c6,23,cb), r(68,fc,ed,b6), r(63,f1,e4,b8),\
+ r(ca,dc,31,d7), r(10,85,63,42), r(40,22,97,13), r(20,11,c6,84),\
+ r(7d,24,4a,85), r(f8,3d,bb,d2), r(11,32,f9,ae), r(6d,a1,29,c7),\
+ r(4b,2f,9e,1d), r(f3,30,b2,dc), r(ec,52,86,0d), r(d0,e3,c1,77),\
+ r(6c,16,b3,2b), r(99,b9,70,a9), r(fa,48,94,11), r(22,64,e9,47),\
+ r(c4,8c,fc,a8), r(1a,3f,f0,a0), r(d8,2c,7d,56), r(ef,90,33,22),\
+ r(c7,4e,49,87), r(c1,d1,38,d9), r(fe,a2,ca,8c), r(36,0b,d4,98),\
+ r(cf,81,f5,a6), r(28,de,7a,a5), r(26,8e,b7,da), r(a4,bf,ad,3f),\
+ r(e4,9d,3a,2c), r(0d,92,78,50), r(9b,cc,5f,6a), r(62,46,7e,54),\
+ r(c2,13,8d,f6), r(e8,b8,d8,90), r(5e,f7,39,2e), r(f5,af,c3,82),\
+ r(be,80,5d,9f), r(7c,93,d0,69), r(a9,2d,d5,6f), r(b3,12,25,cf),\
+ r(3b,99,ac,c8), r(a7,7d,18,10), r(6e,63,9c,e8), r(7b,bb,3b,db),\
+ r(09,78,26,cd), r(f4,18,59,6e), r(01,b7,9a,ec), r(a8,9a,4f,83),\
+ r(65,6e,95,e6), r(7e,e6,ff,aa), r(08,cf,bc,21), r(e6,e8,15,ef),\
+ r(d9,9b,e7,ba), r(ce,36,6f,4a), r(d4,09,9f,ea), r(d6,7c,b0,29),\
+ r(af,b2,a4,31), r(31,23,3f,2a), r(30,94,a5,c6), r(c0,66,a2,35),\
+ r(37,bc,4e,74), r(a6,ca,82,fc), r(b0,d0,90,e0), r(15,d8,a7,33),\
+ r(4a,98,04,f1), r(f7,da,ec,41), r(0e,50,cd,7f), r(2f,f6,91,17),\
+ r(8d,d6,4d,76), r(4d,b0,ef,43), r(54,4d,aa,cc), r(df,04,96,e4),\
+ r(e3,b5,d1,9e), r(1b,88,6a,4c), r(b8,1f,2c,c1), r(7f,51,65,46),\
+ r(04,ea,5e,9d), r(5d,35,8c,01), r(73,74,87,fa), r(2e,41,0b,fb),\
+ r(5a,1d,67,b3), r(52,d2,db,92), r(33,56,10,e9), r(13,47,d6,6d),\
+ r(8c,61,d7,9a), r(7a,0c,a1,37), r(8e,14,f8,59), r(89,3c,13,eb),\
+ r(ee,27,a9,ce), r(35,c9,61,b7), r(ed,e5,1c,e1), r(3c,b1,47,7a),\
+ r(59,df,d2,9c), r(3f,73,f2,55), r(79,ce,14,18), r(bf,37,c7,73),\
+ r(ea,cd,f7,53), r(5b,aa,fd,5f), r(14,6f,3d,df), r(86,db,44,78),\
+ r(81,f3,af,ca), r(3e,c4,68,b9), r(2c,34,24,38), r(5f,40,a3,c2),\
+ r(72,c3,1d,16), r(0c,25,e2,bc), r(8b,49,3c,28), r(41,95,0d,ff),\
+ r(71,01,a8,39), r(de,b3,0c,08), r(9c,e4,b4,d8), r(90,c1,56,64),\
+ r(61,84,cb,7b), r(70,b6,32,d5), r(74,5c,6c,48), r(42,57,b8,d0)
+
+// generate the required tables in the desired endian format
+
+#undef r
+#define r r0
+
+#if defined(ONE_TABLE)
+static const u_int32_t ft_tab[256] =
+ { f_table };
+#elif defined(FOUR_TABLES)
+static const u_int32_t ft_tab[4][256] =
+{ { f_table },
+#undef r
+#define r r1
+ { f_table },
+#undef r
+#define r r2
+ { f_table },
+#undef r
+#define r r3
+ { f_table }
+};
+#endif
+
+#undef r
+#define r r0
+#if defined(ONE_TABLE)
+static const u_int32_t it_tab[256] =
+ { i_table };
+#elif defined(FOUR_TABLES)
+static const u_int32_t it_tab[4][256] =
+{ { i_table },
+#undef r
+#define r r1
+ { i_table },
+#undef r
+#define r r2
+ { i_table },
+#undef r
+#define r r3
+ { i_table }
+};
+#endif
+
+#endif
+
+#if defined(FIXED_TABLES) && (defined(ONE_LR_TABLE) || defined(FOUR_LR_TABLES))
+
+// data for inverse tables (last round)
+
+#define li_table \
+ w(52), w(09), w(6a), w(d5), w(30), w(36), w(a5), w(38),\
+ w(bf), w(40), w(a3), w(9e), w(81), w(f3), w(d7), w(fb),\
+ w(7c), w(e3), w(39), w(82), w(9b), w(2f), w(ff), w(87),\
+ w(34), w(8e), w(43), w(44), w(c4), w(de), w(e9), w(cb),\
+ w(54), w(7b), w(94), w(32), w(a6), w(c2), w(23), w(3d),\
+ w(ee), w(4c), w(95), w(0b), w(42), w(fa), w(c3), w(4e),\
+ w(08), w(2e), w(a1), w(66), w(28), w(d9), w(24), w(b2),\
+ w(76), w(5b), w(a2), w(49), w(6d), w(8b), w(d1), w(25),\
+ w(72), w(f8), w(f6), w(64), w(86), w(68), w(98), w(16),\
+ w(d4), w(a4), w(5c), w(cc), w(5d), w(65), w(b6), w(92),\
+ w(6c), w(70), w(48), w(50), w(fd), w(ed), w(b9), w(da),\
+ w(5e), w(15), w(46), w(57), w(a7), w(8d), w(9d), w(84),\
+ w(90), w(d8), w(ab), w(00), w(8c), w(bc), w(d3), w(0a),\
+ w(f7), w(e4), w(58), w(05), w(b8), w(b3), w(45), w(06),\
+ w(d0), w(2c), w(1e), w(8f), w(ca), w(3f), w(0f), w(02),\
+ w(c1), w(af), w(bd), w(03), w(01), w(13), w(8a), w(6b),\
+ w(3a), w(91), w(11), w(41), w(4f), w(67), w(dc), w(ea),\
+ w(97), w(f2), w(cf), w(ce), w(f0), w(b4), w(e6), w(73),\
+ w(96), w(ac), w(74), w(22), w(e7), w(ad), w(35), w(85),\
+ w(e2), w(f9), w(37), w(e8), w(1c), w(75), w(df), w(6e),\
+ w(47), w(f1), w(1a), w(71), w(1d), w(29), w(c5), w(89),\
+ w(6f), w(b7), w(62), w(0e), w(aa), w(18), w(be), w(1b),\
+ w(fc), w(56), w(3e), w(4b), w(c6), w(d2), w(79), w(20),\
+ w(9a), w(db), w(c0), w(fe), w(78), w(cd), w(5a), w(f4),\
+ w(1f), w(dd), w(a8), w(33), w(88), w(07), w(c7), w(31),\
+ w(b1), w(12), w(10), w(59), w(27), w(80), w(ec), w(5f),\
+ w(60), w(51), w(7f), w(a9), w(19), w(b5), w(4a), w(0d),\
+ w(2d), w(e5), w(7a), w(9f), w(93), w(c9), w(9c), w(ef),\
+ w(a0), w(e0), w(3b), w(4d), w(ae), w(2a), w(f5), w(b0),\
+ w(c8), w(eb), w(bb), w(3c), w(83), w(53), w(99), w(61),\
+ w(17), w(2b), w(04), w(7e), w(ba), w(77), w(d6), w(26),\
+ w(e1), w(69), w(14), w(63), w(55), w(21), w(0c), w(7d),
+
+// generate the required tables in the desired endian format
+
+#undef r
+#define r(p,q,r,s) w0(q)
+#if defined(ONE_LR_TABLE)
+static const u_int32_t fl_tab[256] =
+ { f_table };
+#elif defined(FOUR_LR_TABLES)
+static const u_int32_t fl_tab[4][256] =
+{ { f_table },
+#undef r
+#define r(p,q,r,s) w1(q)
+ { f_table },
+#undef r
+#define r(p,q,r,s) w2(q)
+ { f_table },
+#undef r
+#define r(p,q,r,s) w3(q)
+ { f_table }
+};
+#endif
+
+#undef w
+#define w w0
+#if defined(ONE_LR_TABLE)
+static const u_int32_t il_tab[256] =
+ { li_table };
+#elif defined(FOUR_LR_TABLES)
+static const u_int32_t il_tab[4][256] =
+{ { li_table },
+#undef w
+#define w w1
+ { li_table },
+#undef w
+#define w w2
+ { li_table },
+#undef w
+#define w w3
+ { li_table }
+};
+#endif
+
+#endif
+
+#if defined(FIXED_TABLES) && (defined(ONE_IM_TABLE) || defined(FOUR_IM_TABLES))
+
+#define m_table \
+ r(00,00,00,00), r(0b,0d,09,0e), r(16,1a,12,1c), r(1d,17,1b,12),\
+ r(2c,34,24,38), r(27,39,2d,36), r(3a,2e,36,24), r(31,23,3f,2a),\
+ r(58,68,48,70), r(53,65,41,7e), r(4e,72,5a,6c), r(45,7f,53,62),\
+ r(74,5c,6c,48), r(7f,51,65,46), r(62,46,7e,54), r(69,4b,77,5a),\
+ r(b0,d0,90,e0), r(bb,dd,99,ee), r(a6,ca,82,fc), r(ad,c7,8b,f2),\
+ r(9c,e4,b4,d8), r(97,e9,bd,d6), r(8a,fe,a6,c4), r(81,f3,af,ca),\
+ r(e8,b8,d8,90), r(e3,b5,d1,9e), r(fe,a2,ca,8c), r(f5,af,c3,82),\
+ r(c4,8c,fc,a8), r(cf,81,f5,a6), r(d2,96,ee,b4), r(d9,9b,e7,ba),\
+ r(7b,bb,3b,db), r(70,b6,32,d5), r(6d,a1,29,c7), r(66,ac,20,c9),\
+ r(57,8f,1f,e3), r(5c,82,16,ed), r(41,95,0d,ff), r(4a,98,04,f1),\
+ r(23,d3,73,ab), r(28,de,7a,a5), r(35,c9,61,b7), r(3e,c4,68,b9),\
+ r(0f,e7,57,93), r(04,ea,5e,9d), r(19,fd,45,8f), r(12,f0,4c,81),\
+ r(cb,6b,ab,3b), r(c0,66,a2,35), r(dd,71,b9,27), r(d6,7c,b0,29),\
+ r(e7,5f,8f,03), r(ec,52,86,0d), r(f1,45,9d,1f), r(fa,48,94,11),\
+ r(93,03,e3,4b), r(98,0e,ea,45), r(85,19,f1,57), r(8e,14,f8,59),\
+ r(bf,37,c7,73), r(b4,3a,ce,7d), r(a9,2d,d5,6f), r(a2,20,dc,61),\
+ r(f6,6d,76,ad), r(fd,60,7f,a3), r(e0,77,64,b1), r(eb,7a,6d,bf),\
+ r(da,59,52,95), r(d1,54,5b,9b), r(cc,43,40,89), r(c7,4e,49,87),\
+ r(ae,05,3e,dd), r(a5,08,37,d3), r(b8,1f,2c,c1), r(b3,12,25,cf),\
+ r(82,31,1a,e5), r(89,3c,13,eb), r(94,2b,08,f9), r(9f,26,01,f7),\
+ r(46,bd,e6,4d), r(4d,b0,ef,43), r(50,a7,f4,51), r(5b,aa,fd,5f),\
+ r(6a,89,c2,75), r(61,84,cb,7b), r(7c,93,d0,69), r(77,9e,d9,67),\
+ r(1e,d5,ae,3d), r(15,d8,a7,33), r(08,cf,bc,21), r(03,c2,b5,2f),\
+ r(32,e1,8a,05), r(39,ec,83,0b), r(24,fb,98,19), r(2f,f6,91,17),\
+ r(8d,d6,4d,76), r(86,db,44,78), r(9b,cc,5f,6a), r(90,c1,56,64),\
+ r(a1,e2,69,4e), r(aa,ef,60,40), r(b7,f8,7b,52), r(bc,f5,72,5c),\
+ r(d5,be,05,06), r(de,b3,0c,08), r(c3,a4,17,1a), r(c8,a9,1e,14),\
+ r(f9,8a,21,3e), r(f2,87,28,30), r(ef,90,33,22), r(e4,9d,3a,2c),\
+ r(3d,06,dd,96), r(36,0b,d4,98), r(2b,1c,cf,8a), r(20,11,c6,84),\
+ r(11,32,f9,ae), r(1a,3f,f0,a0), r(07,28,eb,b2), r(0c,25,e2,bc),\
+ r(65,6e,95,e6), r(6e,63,9c,e8), r(73,74,87,fa), r(78,79,8e,f4),\
+ r(49,5a,b1,de), r(42,57,b8,d0), r(5f,40,a3,c2), r(54,4d,aa,cc),\
+ r(f7,da,ec,41), r(fc,d7,e5,4f), r(e1,c0,fe,5d), r(ea,cd,f7,53),\
+ r(db,ee,c8,79), r(d0,e3,c1,77), r(cd,f4,da,65), r(c6,f9,d3,6b),\
+ r(af,b2,a4,31), r(a4,bf,ad,3f), r(b9,a8,b6,2d), r(b2,a5,bf,23),\
+ r(83,86,80,09), r(88,8b,89,07), r(95,9c,92,15), r(9e,91,9b,1b),\
+ r(47,0a,7c,a1), r(4c,07,75,af), r(51,10,6e,bd), r(5a,1d,67,b3),\
+ r(6b,3e,58,99), r(60,33,51,97), r(7d,24,4a,85), r(76,29,43,8b),\
+ r(1f,62,34,d1), r(14,6f,3d,df), r(09,78,26,cd), r(02,75,2f,c3),\
+ r(33,56,10,e9), r(38,5b,19,e7), r(25,4c,02,f5), r(2e,41,0b,fb),\
+ r(8c,61,d7,9a), r(87,6c,de,94), r(9a,7b,c5,86), r(91,76,cc,88),\
+ r(a0,55,f3,a2), r(ab,58,fa,ac), r(b6,4f,e1,be), r(bd,42,e8,b0),\
+ r(d4,09,9f,ea), r(df,04,96,e4), r(c2,13,8d,f6), r(c9,1e,84,f8),\
+ r(f8,3d,bb,d2), r(f3,30,b2,dc), r(ee,27,a9,ce), r(e5,2a,a0,c0),\
+ r(3c,b1,47,7a), r(37,bc,4e,74), r(2a,ab,55,66), r(21,a6,5c,68),\
+ r(10,85,63,42), r(1b,88,6a,4c), r(06,9f,71,5e), r(0d,92,78,50),\
+ r(64,d9,0f,0a), r(6f,d4,06,04), r(72,c3,1d,16), r(79,ce,14,18),\
+ r(48,ed,2b,32), r(43,e0,22,3c), r(5e,f7,39,2e), r(55,fa,30,20),\
+ r(01,b7,9a,ec), r(0a,ba,93,e2), r(17,ad,88,f0), r(1c,a0,81,fe),\
+ r(2d,83,be,d4), r(26,8e,b7,da), r(3b,99,ac,c8), r(30,94,a5,c6),\
+ r(59,df,d2,9c), r(52,d2,db,92), r(4f,c5,c0,80), r(44,c8,c9,8e),\
+ r(75,eb,f6,a4), r(7e,e6,ff,aa), r(63,f1,e4,b8), r(68,fc,ed,b6),\
+ r(b1,67,0a,0c), r(ba,6a,03,02), r(a7,7d,18,10), r(ac,70,11,1e),\
+ r(9d,53,2e,34), r(96,5e,27,3a), r(8b,49,3c,28), r(80,44,35,26),\
+ r(e9,0f,42,7c), r(e2,02,4b,72), r(ff,15,50,60), r(f4,18,59,6e),\
+ r(c5,3b,66,44), r(ce,36,6f,4a), r(d3,21,74,58), r(d8,2c,7d,56),\
+ r(7a,0c,a1,37), r(71,01,a8,39), r(6c,16,b3,2b), r(67,1b,ba,25),\
+ r(56,38,85,0f), r(5d,35,8c,01), r(40,22,97,13), r(4b,2f,9e,1d),\
+ r(22,64,e9,47), r(29,69,e0,49), r(34,7e,fb,5b), r(3f,73,f2,55),\
+ r(0e,50,cd,7f), r(05,5d,c4,71), r(18,4a,df,63), r(13,47,d6,6d),\
+ r(ca,dc,31,d7), r(c1,d1,38,d9), r(dc,c6,23,cb), r(d7,cb,2a,c5),\
+ r(e6,e8,15,ef), r(ed,e5,1c,e1), r(f0,f2,07,f3), r(fb,ff,0e,fd),\
+ r(92,b4,79,a7), r(99,b9,70,a9), r(84,ae,6b,bb), r(8f,a3,62,b5),\
+ r(be,80,5d,9f), r(b5,8d,54,91), r(a8,9a,4f,83), r(a3,97,46,8d)
+
+#undef r
+#define r r0
+
+#if defined(ONE_IM_TABLE)
+static const u_int32_t im_tab[256] =
+ { m_table };
+#elif defined(FOUR_IM_TABLES)
+static const u_int32_t im_tab[4][256] =
+{ { m_table },
+#undef r
+#define r r1
+ { m_table },
+#undef r
+#define r r2
+ { m_table },
+#undef r
+#define r r3
+ { m_table }
+};
+#endif
+
+#endif
+
+#else
+
+static int tab_gen = 0;
+
+static unsigned char s_box[256]; // the S box
+static unsigned char inv_s_box[256]; // the inverse S box
+static u_int32_t rcon_tab[AES_RC_LENGTH]; // table of round constants
+
+#if defined(ONE_TABLE)
+static u_int32_t ft_tab[256];
+static u_int32_t it_tab[256];
+#elif defined(FOUR_TABLES)
+static u_int32_t ft_tab[4][256];
+static u_int32_t it_tab[4][256];
+#endif
+
+#if defined(ONE_LR_TABLE)
+static u_int32_t fl_tab[256];
+static u_int32_t il_tab[256];
+#elif defined(FOUR_LR_TABLES)
+static u_int32_t fl_tab[4][256];
+static u_int32_t il_tab[4][256];
+#endif
+
+#if defined(ONE_IM_TABLE)
+static u_int32_t im_tab[256];
+#elif defined(FOUR_IM_TABLES)
+static u_int32_t im_tab[4][256];
+#endif
+
+// Generate the tables for the dynamic table option
+
+#if !defined(FF_TABLES)
+
+// It will generally be sensible to use tables to compute finite
+// field multiplies and inverses but where memory is scarse this
+// code might sometimes be better.
+
+// return 2 ^ (n - 1) where n is the bit number of the highest bit
+// set in x with x in the range 1 < x < 0x00000200. This form is
+// used so that locals within FFinv can be bytes rather than words
+
+static unsigned char hibit(const u_int32_t x)
+{ unsigned char r = (unsigned char)((x >> 1) | (x >> 2));
+
+ r |= (r >> 2);
+ r |= (r >> 4);
+ return (r + 1) >> 1;
+}
+
+// return the inverse of the finite field element x
+
+static unsigned char FFinv(const unsigned char x)
+{ unsigned char p1 = x, p2 = 0x1b, n1 = hibit(x), n2 = 0x80, v1 = 1, v2 = 0;
+
+ if(x < 2) return x;
+
+ for(;;)
+ {
+ if(!n1) return v1;
+
+ while(n2 >= n1)
+ {
+ n2 /= n1; p2 ^= p1 * n2; v2 ^= v1 * n2; n2 = hibit(p2);
+ }
+
+ if(!n2) return v2;
+
+ while(n1 >= n2)
+ {
+ n1 /= n2; p1 ^= p2 * n1; v1 ^= v2 * n1; n1 = hibit(p1);
+ }
+ }
+}
+
+// define the finite field multiplies required for Rijndael
+
+#define FFmul02(x) ((((x) & 0x7f) << 1) ^ ((x) & 0x80 ? 0x1b : 0))
+#define FFmul03(x) ((x) ^ FFmul02(x))
+#define FFmul09(x) ((x) ^ FFmul02(FFmul02(FFmul02(x))))
+#define FFmul0b(x) ((x) ^ FFmul02((x) ^ FFmul02(FFmul02(x))))
+#define FFmul0d(x) ((x) ^ FFmul02(FFmul02((x) ^ FFmul02(x))))
+#define FFmul0e(x) FFmul02((x) ^ FFmul02((x) ^ FFmul02(x)))
+
+#else
+
+#define FFinv(x) ((x) ? pow[255 - log[x]]: 0)
+
+#define FFmul02(x) (x ? pow[log[x] + 0x19] : 0)
+#define FFmul03(x) (x ? pow[log[x] + 0x01] : 0)
+#define FFmul09(x) (x ? pow[log[x] + 0xc7] : 0)
+#define FFmul0b(x) (x ? pow[log[x] + 0x68] : 0)
+#define FFmul0d(x) (x ? pow[log[x] + 0xee] : 0)
+#define FFmul0e(x) (x ? pow[log[x] + 0xdf] : 0)
+
+#endif
+
+// The forward and inverse affine transformations used in the S-box
+
+#define fwd_affine(x) \
+ (w = (u_int32_t)x, w ^= (w<<1)^(w<<2)^(w<<3)^(w<<4), 0x63^(unsigned char)(w^(w>>8)))
+
+#define inv_affine(x) \
+ (w = (u_int32_t)x, w = (w<<1)^(w<<3)^(w<<6), 0x05^(unsigned char)(w^(w>>8)))
+
+static void gen_tabs(void)
+{ u_int32_t i, w;
+
+#if defined(FF_TABLES)
+
+ unsigned char pow[512], log[256];
+
+ // log and power tables for GF(2^8) finite field with
+ // 0x011b as modular polynomial - the simplest primitive
+ // root is 0x03, used here to generate the tables
+
+ i = 0; w = 1;
+ do
+ {
+ pow[i] = (unsigned char)w;
+ pow[i + 255] = (unsigned char)w;
+ log[w] = (unsigned char)i++;
+ w ^= (w << 1) ^ (w & ff_hi ? ff_poly : 0);
+ }
+ while (w != 1);
+
+#endif
+
+ for(i = 0, w = 1; i < AES_RC_LENGTH; ++i)
+ {
+ rcon_tab[i] = bytes2word(w, 0, 0, 0);
+ w = (w << 1) ^ (w & ff_hi ? ff_poly : 0);
+ }
+
+ for(i = 0; i < 256; ++i)
+ { unsigned char b;
+
+ s_box[i] = b = fwd_affine(FFinv((unsigned char)i));
+
+ w = bytes2word(b, 0, 0, 0);
+#if defined(ONE_LR_TABLE)
+ fl_tab[i] = w;
+#elif defined(FOUR_LR_TABLES)
+ fl_tab[0][i] = w;
+ fl_tab[1][i] = upr(w,1);
+ fl_tab[2][i] = upr(w,2);
+ fl_tab[3][i] = upr(w,3);
+#endif
+ w = bytes2word(FFmul02(b), b, b, FFmul03(b));
+#if defined(ONE_TABLE)
+ ft_tab[i] = w;
+#elif defined(FOUR_TABLES)
+ ft_tab[0][i] = w;
+ ft_tab[1][i] = upr(w,1);
+ ft_tab[2][i] = upr(w,2);
+ ft_tab[3][i] = upr(w,3);
+#endif
+ inv_s_box[i] = b = FFinv(inv_affine((unsigned char)i));
+
+ w = bytes2word(b, 0, 0, 0);
+#if defined(ONE_LR_TABLE)
+ il_tab[i] = w;
+#elif defined(FOUR_LR_TABLES)
+ il_tab[0][i] = w;
+ il_tab[1][i] = upr(w,1);
+ il_tab[2][i] = upr(w,2);
+ il_tab[3][i] = upr(w,3);
+#endif
+ w = bytes2word(FFmul0e(b), FFmul09(b), FFmul0d(b), FFmul0b(b));
+#if defined(ONE_TABLE)
+ it_tab[i] = w;
+#elif defined(FOUR_TABLES)
+ it_tab[0][i] = w;
+ it_tab[1][i] = upr(w,1);
+ it_tab[2][i] = upr(w,2);
+ it_tab[3][i] = upr(w,3);
+#endif
+#if defined(ONE_IM_TABLE)
+ im_tab[b] = w;
+#elif defined(FOUR_IM_TABLES)
+ im_tab[0][b] = w;
+ im_tab[1][b] = upr(w,1);
+ im_tab[2][b] = upr(w,2);
+ im_tab[3][b] = upr(w,3);
+#endif
+
+ }
+}
+
+#endif
+
+#define no_table(x,box,vf,rf,c) bytes2word( \
+ box[bval(vf(x,0,c),rf(0,c))], \
+ box[bval(vf(x,1,c),rf(1,c))], \
+ box[bval(vf(x,2,c),rf(2,c))], \
+ box[bval(vf(x,3,c),rf(3,c))])
+
+#define one_table(x,op,tab,vf,rf,c) \
+ ( tab[bval(vf(x,0,c),rf(0,c))] \
+ ^ op(tab[bval(vf(x,1,c),rf(1,c))],1) \
+ ^ op(tab[bval(vf(x,2,c),rf(2,c))],2) \
+ ^ op(tab[bval(vf(x,3,c),rf(3,c))],3))
+
+#define four_tables(x,tab,vf,rf,c) \
+ ( tab[0][bval(vf(x,0,c),rf(0,c))] \
+ ^ tab[1][bval(vf(x,1,c),rf(1,c))] \
+ ^ tab[2][bval(vf(x,2,c),rf(2,c))] \
+ ^ tab[3][bval(vf(x,3,c),rf(3,c))])
+
+#define vf1(x,r,c) (x)
+#define rf1(r,c) (r)
+#define rf2(r,c) ((r-c)&3)
+
+#if defined(FOUR_LR_TABLES)
+#define ls_box(x,c) four_tables(x,fl_tab,vf1,rf2,c)
+#elif defined(ONE_LR_TABLE)
+#define ls_box(x,c) one_table(x,upr,fl_tab,vf1,rf2,c)
+#else
+#define ls_box(x,c) no_table(x,s_box,vf1,rf2,c)
+#endif
+
+#if defined(FOUR_IM_TABLES)
+#define inv_mcol(x) four_tables(x,im_tab,vf1,rf1,0)
+#elif defined(ONE_IM_TABLE)
+#define inv_mcol(x) one_table(x,upr,im_tab,vf1,rf1,0)
+#else
+#define inv_mcol(x) \
+ (f9 = (x),f2 = FFmulX(f9), f4 = FFmulX(f2), f8 = FFmulX(f4), f9 ^= f8, \
+ f2 ^= f4 ^ f8 ^ upr(f2 ^ f9,3) ^ upr(f4 ^ f9,2) ^ upr(f9,1))
+#endif
+
+#define nc (AES_BLOCK_SIZE/4)
+
+// Initialise the key schedule from the user supplied key. The key
+// length is now specified in bytes - 16, 24 or 32 as appropriate.
+// This corresponds to bit lengths of 128, 192 and 256 bits, and
+// to Nk values of 4, 6 and 8 respectively.
+
+#define mx(t,f) (*t++ = inv_mcol(*f),f++)
+#define cp(t,f) *t++ = *f++
+
+#if AES_BLOCK_SIZE == 16
+#define cpy(d,s) cp(d,s); cp(d,s); cp(d,s); cp(d,s)
+#define mix(d,s) mx(d,s); mx(d,s); mx(d,s); mx(d,s)
+#elif AES_BLOCK_SIZE == 24
+#define cpy(d,s) cp(d,s); cp(d,s); cp(d,s); cp(d,s); \
+ cp(d,s); cp(d,s)
+#define mix(d,s) mx(d,s); mx(d,s); mx(d,s); mx(d,s); \
+ mx(d,s); mx(d,s)
+#elif AES_BLOCK_SIZE == 32
+#define cpy(d,s) cp(d,s); cp(d,s); cp(d,s); cp(d,s); \
+ cp(d,s); cp(d,s); cp(d,s); cp(d,s)
+#define mix(d,s) mx(d,s); mx(d,s); mx(d,s); mx(d,s); \
+ mx(d,s); mx(d,s); mx(d,s); mx(d,s)
+#else
+
+#define cpy(d,s) \
+switch(nc) \
+{ case 8: cp(d,s); cp(d,s); \
+ case 6: cp(d,s); cp(d,s); \
+ case 4: cp(d,s); cp(d,s); \
+ cp(d,s); cp(d,s); \
+}
+
+#define mix(d,s) \
+switch(nc) \
+{ case 8: mx(d,s); mx(d,s); \
+ case 6: mx(d,s); mx(d,s); \
+ case 4: mx(d,s); mx(d,s); \
+ mx(d,s); mx(d,s); \
+}
+
+#endif
+
+// y = output word, x = input word, r = row, c = column
+// for r = 0, 1, 2 and 3 = column accessed for row r
+
+#if defined(ARRAYS)
+#define s(x,c) x[c]
+#else
+#define s(x,c) x##c
+#endif
+
+// I am grateful to Frank Yellin for the following constructions
+// which, given the column (c) of the output state variable that
+// is being computed, return the input state variables which are
+// needed for each row (r) of the state
+
+// For the fixed block size options, compilers reduce these two
+// expressions to fixed variable references. For variable block
+// size code conditional clauses will sometimes be returned
+
+#define unused 77 // Sunset Strip
+
+#define fwd_var(x,r,c) \
+ ( r==0 ? \
+ ( c==0 ? s(x,0) \
+ : c==1 ? s(x,1) \
+ : c==2 ? s(x,2) \
+ : c==3 ? s(x,3) \
+ : c==4 ? s(x,4) \
+ : c==5 ? s(x,5) \
+ : c==6 ? s(x,6) \
+ : s(x,7)) \
+ : r==1 ? \
+ ( c==0 ? s(x,1) \
+ : c==1 ? s(x,2) \
+ : c==2 ? s(x,3) \
+ : c==3 ? nc==4 ? s(x,0) : s(x,4) \
+ : c==4 ? s(x,5) \
+ : c==5 ? nc==8 ? s(x,6) : s(x,0) \
+ : c==6 ? s(x,7) \
+ : s(x,0)) \
+ : r==2 ? \
+ ( c==0 ? nc==8 ? s(x,3) : s(x,2) \
+ : c==1 ? nc==8 ? s(x,4) : s(x,3) \
+ : c==2 ? nc==4 ? s(x,0) : nc==8 ? s(x,5) : s(x,4) \
+ : c==3 ? nc==4 ? s(x,1) : nc==8 ? s(x,6) : s(x,5) \
+ : c==4 ? nc==8 ? s(x,7) : s(x,0) \
+ : c==5 ? nc==8 ? s(x,0) : s(x,1) \
+ : c==6 ? s(x,1) \
+ : s(x,2)) \
+ : \
+ ( c==0 ? nc==8 ? s(x,4) : s(x,3) \
+ : c==1 ? nc==4 ? s(x,0) : nc==8 ? s(x,5) : s(x,4) \
+ : c==2 ? nc==4 ? s(x,1) : nc==8 ? s(x,6) : s(x,5) \
+ : c==3 ? nc==4 ? s(x,2) : nc==8 ? s(x,7) : s(x,0) \
+ : c==4 ? nc==8 ? s(x,0) : s(x,1) \
+ : c==5 ? nc==8 ? s(x,1) : s(x,2) \
+ : c==6 ? s(x,2) \
+ : s(x,3)))
+
+#define inv_var(x,r,c) \
+ ( r==0 ? \
+ ( c==0 ? s(x,0) \
+ : c==1 ? s(x,1) \
+ : c==2 ? s(x,2) \
+ : c==3 ? s(x,3) \
+ : c==4 ? s(x,4) \
+ : c==5 ? s(x,5) \
+ : c==6 ? s(x,6) \
+ : s(x,7)) \
+ : r==1 ? \
+ ( c==0 ? nc==4 ? s(x,3) : nc==8 ? s(x,7) : s(x,5) \
+ : c==1 ? s(x,0) \
+ : c==2 ? s(x,1) \
+ : c==3 ? s(x,2) \
+ : c==4 ? s(x,3) \
+ : c==5 ? s(x,4) \
+ : c==6 ? s(x,5) \
+ : s(x,6)) \
+ : r==2 ? \
+ ( c==0 ? nc==4 ? s(x,2) : nc==8 ? s(x,5) : s(x,4) \
+ : c==1 ? nc==4 ? s(x,3) : nc==8 ? s(x,6) : s(x,5) \
+ : c==2 ? nc==8 ? s(x,7) : s(x,0) \
+ : c==3 ? nc==8 ? s(x,0) : s(x,1) \
+ : c==4 ? nc==8 ? s(x,1) : s(x,2) \
+ : c==5 ? nc==8 ? s(x,2) : s(x,3) \
+ : c==6 ? s(x,3) \
+ : s(x,4)) \
+ : \
+ ( c==0 ? nc==4 ? s(x,1) : nc==8 ? s(x,4) : s(x,3) \
+ : c==1 ? nc==4 ? s(x,2) : nc==8 ? s(x,5) : s(x,4) \
+ : c==2 ? nc==4 ? s(x,3) : nc==8 ? s(x,6) : s(x,5) \
+ : c==3 ? nc==8 ? s(x,7) : s(x,0) \
+ : c==4 ? nc==8 ? s(x,0) : s(x,1) \
+ : c==5 ? nc==8 ? s(x,1) : s(x,2) \
+ : c==6 ? s(x,2) \
+ : s(x,3)))
+
+#define si(y,x,k,c) s(y,c) = const_word_in(x + 4 * c) ^ k[c]
+#define so(y,x,c) word_out(y + 4 * c, s(x,c))
+
+#if defined(FOUR_TABLES)
+#define fwd_rnd(y,x,k,c) s(y,c)= (k)[c] ^ four_tables(x,ft_tab,fwd_var,rf1,c)
+#define inv_rnd(y,x,k,c) s(y,c)= (k)[c] ^ four_tables(x,it_tab,inv_var,rf1,c)
+#elif defined(ONE_TABLE)
+#define fwd_rnd(y,x,k,c) s(y,c)= (k)[c] ^ one_table(x,upr,ft_tab,fwd_var,rf1,c)
+#define inv_rnd(y,x,k,c) s(y,c)= (k)[c] ^ one_table(x,upr,it_tab,inv_var,rf1,c)
+#else
+#define fwd_rnd(y,x,k,c) s(y,c) = fwd_mcol(no_table(x,s_box,fwd_var,rf1,c)) ^ (k)[c]
+#define inv_rnd(y,x,k,c) s(y,c) = inv_mcol(no_table(x,inv_s_box,inv_var,rf1,c) ^ (k)[c])
+#endif
+
+#if defined(FOUR_LR_TABLES)
+#define fwd_lrnd(y,x,k,c) s(y,c)= (k)[c] ^ four_tables(x,fl_tab,fwd_var,rf1,c)
+#define inv_lrnd(y,x,k,c) s(y,c)= (k)[c] ^ four_tables(x,il_tab,inv_var,rf1,c)
+#elif defined(ONE_LR_TABLE)
+#define fwd_lrnd(y,x,k,c) s(y,c)= (k)[c] ^ one_table(x,ups,fl_tab,fwd_var,rf1,c)
+#define inv_lrnd(y,x,k,c) s(y,c)= (k)[c] ^ one_table(x,ups,il_tab,inv_var,rf1,c)
+#else
+#define fwd_lrnd(y,x,k,c) s(y,c) = no_table(x,s_box,fwd_var,rf1,c) ^ (k)[c]
+#define inv_lrnd(y,x,k,c) s(y,c) = no_table(x,inv_s_box,inv_var,rf1,c) ^ (k)[c]
+#endif
+
+#if AES_BLOCK_SIZE == 16
+
+#if defined(ARRAYS)
+#define locals(y,x) x[4],y[4]
+#else
+#define locals(y,x) x##0,x##1,x##2,x##3,y##0,y##1,y##2,y##3
+// the following defines prevent the compiler requiring the declaration
+// of generated but unused variables in the fwd_var and inv_var macros
+#define b04 unused
+#define b05 unused
+#define b06 unused
+#define b07 unused
+#define b14 unused
+#define b15 unused
+#define b16 unused
+#define b17 unused
+#endif
+#define l_copy(y, x) s(y,0) = s(x,0); s(y,1) = s(x,1); \
+ s(y,2) = s(x,2); s(y,3) = s(x,3);
+#define state_in(y,x,k) si(y,x,k,0); si(y,x,k,1); si(y,x,k,2); si(y,x,k,3)
+#define state_out(y,x) so(y,x,0); so(y,x,1); so(y,x,2); so(y,x,3)
+#define round(rm,y,x,k) rm(y,x,k,0); rm(y,x,k,1); rm(y,x,k,2); rm(y,x,k,3)
+
+#elif AES_BLOCK_SIZE == 24
+
+#if defined(ARRAYS)
+#define locals(y,x) x[6],y[6]
+#else
+#define locals(y,x) x##0,x##1,x##2,x##3,x##4,x##5, \
+ y##0,y##1,y##2,y##3,y##4,y##5
+#define b06 unused
+#define b07 unused
+#define b16 unused
+#define b17 unused
+#endif
+#define l_copy(y, x) s(y,0) = s(x,0); s(y,1) = s(x,1); \
+ s(y,2) = s(x,2); s(y,3) = s(x,3); \
+ s(y,4) = s(x,4); s(y,5) = s(x,5);
+#define state_in(y,x,k) si(y,x,k,0); si(y,x,k,1); si(y,x,k,2); \
+ si(y,x,k,3); si(y,x,k,4); si(y,x,k,5)
+#define state_out(y,x) so(y,x,0); so(y,x,1); so(y,x,2); \
+ so(y,x,3); so(y,x,4); so(y,x,5)
+#define round(rm,y,x,k) rm(y,x,k,0); rm(y,x,k,1); rm(y,x,k,2); \
+ rm(y,x,k,3); rm(y,x,k,4); rm(y,x,k,5)
+#else
+
+#if defined(ARRAYS)
+#define locals(y,x) x[8],y[8]
+#else
+#define locals(y,x) x##0,x##1,x##2,x##3,x##4,x##5,x##6,x##7, \
+ y##0,y##1,y##2,y##3,y##4,y##5,y##6,y##7
+#endif
+#define l_copy(y, x) s(y,0) = s(x,0); s(y,1) = s(x,1); \
+ s(y,2) = s(x,2); s(y,3) = s(x,3); \
+ s(y,4) = s(x,4); s(y,5) = s(x,5); \
+ s(y,6) = s(x,6); s(y,7) = s(x,7);
+
+#if AES_BLOCK_SIZE == 32
+
+#define state_in(y,x,k) si(y,x,k,0); si(y,x,k,1); si(y,x,k,2); si(y,x,k,3); \
+ si(y,x,k,4); si(y,x,k,5); si(y,x,k,6); si(y,x,k,7)
+#define state_out(y,x) so(y,x,0); so(y,x,1); so(y,x,2); so(y,x,3); \
+ so(y,x,4); so(y,x,5); so(y,x,6); so(y,x,7)
+#define round(rm,y,x,k) rm(y,x,k,0); rm(y,x,k,1); rm(y,x,k,2); rm(y,x,k,3); \
+ rm(y,x,k,4); rm(y,x,k,5); rm(y,x,k,6); rm(y,x,k,7)
+#else
+
+#define state_in(y,x,k) \
+switch(nc) \
+{ case 8: si(y,x,k,7); si(y,x,k,6); \
+ case 6: si(y,x,k,5); si(y,x,k,4); \
+ case 4: si(y,x,k,3); si(y,x,k,2); \
+ si(y,x,k,1); si(y,x,k,0); \
+}
+
+#define state_out(y,x) \
+switch(nc) \
+{ case 8: so(y,x,7); so(y,x,6); \
+ case 6: so(y,x,5); so(y,x,4); \
+ case 4: so(y,x,3); so(y,x,2); \
+ so(y,x,1); so(y,x,0); \
+}
+
+#if defined(FAST_VARIABLE)
+
+#define round(rm,y,x,k) \
+switch(nc) \
+{ case 8: rm(y,x,k,7); rm(y,x,k,6); \
+ rm(y,x,k,5); rm(y,x,k,4); \
+ rm(y,x,k,3); rm(y,x,k,2); \
+ rm(y,x,k,1); rm(y,x,k,0); \
+ break; \
+ case 6: rm(y,x,k,5); rm(y,x,k,4); \
+ rm(y,x,k,3); rm(y,x,k,2); \
+ rm(y,x,k,1); rm(y,x,k,0); \
+ break; \
+ case 4: rm(y,x,k,3); rm(y,x,k,2); \
+ rm(y,x,k,1); rm(y,x,k,0); \
+ break; \
+}
+#else
+
+#define round(rm,y,x,k) \
+switch(nc) \
+{ case 8: rm(y,x,k,7); rm(y,x,k,6); \
+ case 6: rm(y,x,k,5); rm(y,x,k,4); \
+ case 4: rm(y,x,k,3); rm(y,x,k,2); \
+ rm(y,x,k,1); rm(y,x,k,0); \
+}
+
+#endif
+
+#endif
+#endif
+
+/**
+ * Encrypt a single block of data.
+ */
+static void encrypt_block(const private_aes_crypter_t *this, const unsigned char in_blk[], unsigned char out_blk[])
+{ u_int32_t locals(b0, b1);
+ const u_int32_t *kp = this->aes_e_key;
+
+#if !defined(ONE_TABLE) && !defined(FOUR_TABLES)
+ u_int32_t f2;
+#endif
+
+ state_in(b0, in_blk, kp); kp += nc;
+
+#if defined(UNROLL)
+
+ switch(this->aes_Nrnd)
+ {
+ case 14: round(fwd_rnd, b1, b0, kp );
+ round(fwd_rnd, b0, b1, kp + nc ); kp += 2 * nc;
+ case 12: round(fwd_rnd, b1, b0, kp );
+ round(fwd_rnd, b0, b1, kp + nc ); kp += 2 * nc;
+ case 10: round(fwd_rnd, b1, b0, kp );
+ round(fwd_rnd, b0, b1, kp + nc);
+ round(fwd_rnd, b1, b0, kp + 2 * nc);
+ round(fwd_rnd, b0, b1, kp + 3 * nc);
+ round(fwd_rnd, b1, b0, kp + 4 * nc);
+ round(fwd_rnd, b0, b1, kp + 5 * nc);
+ round(fwd_rnd, b1, b0, kp + 6 * nc);
+ round(fwd_rnd, b0, b1, kp + 7 * nc);
+ round(fwd_rnd, b1, b0, kp + 8 * nc);
+ round(fwd_lrnd, b0, b1, kp + 9 * nc);
+ }
+
+#elif defined(PARTIAL_UNROLL)
+ { u_int32_t rnd;
+
+ for(rnd = 0; rnd < (this->aes_Nrnd >> 1) - 1; ++rnd)
+ {
+ round(fwd_rnd, b1, b0, kp);
+ round(fwd_rnd, b0, b1, kp + nc); kp += 2 * nc;
+ }
+
+ round(fwd_rnd, b1, b0, kp);
+ round(fwd_lrnd, b0, b1, kp + nc);
+ }
+#else
+ { u_int32_t rnd;
+
+ for(rnd = 0; rnd < this->aes_Nrnd - 1; ++rnd)
+ {
+ round(fwd_rnd, b1, b0, kp);
+ l_copy(b0, b1); kp += nc;
+ }
+
+ round(fwd_lrnd, b0, b1, kp);
+ }
+#endif
+
+ state_out(out_blk, b0);
+}
+
+/**
+ * Decrypt a single block of data.
+ */
+static void decrypt_block(const private_aes_crypter_t *this, const unsigned char in_blk[], unsigned char out_blk[])
+{ u_int32_t locals(b0, b1);
+ const u_int32_t *kp = this->aes_d_key;
+
+#if !defined(ONE_TABLE) && !defined(FOUR_TABLES)
+ u_int32_t f2, f4, f8, f9;
+#endif
+
+ state_in(b0, in_blk, kp); kp += nc;
+
+#if defined(UNROLL)
+
+ switch(this->aes_Nrnd)
+ {
+ case 14: round(inv_rnd, b1, b0, kp );
+ round(inv_rnd, b0, b1, kp + nc ); kp += 2 * nc;
+ case 12: round(inv_rnd, b1, b0, kp );
+ round(inv_rnd, b0, b1, kp + nc ); kp += 2 * nc;
+ case 10: round(inv_rnd, b1, b0, kp );
+ round(inv_rnd, b0, b1, kp + nc);
+ round(inv_rnd, b1, b0, kp + 2 * nc);
+ round(inv_rnd, b0, b1, kp + 3 * nc);
+ round(inv_rnd, b1, b0, kp + 4 * nc);
+ round(inv_rnd, b0, b1, kp + 5 * nc);
+ round(inv_rnd, b1, b0, kp + 6 * nc);
+ round(inv_rnd, b0, b1, kp + 7 * nc);
+ round(inv_rnd, b1, b0, kp + 8 * nc);
+ round(inv_lrnd, b0, b1, kp + 9 * nc);
+ }
+
+#elif defined(PARTIAL_UNROLL)
+ { u_int32_t rnd;
+
+ for(rnd = 0; rnd < (this->aes_Nrnd >> 1) - 1; ++rnd)
+ {
+ round(inv_rnd, b1, b0, kp);
+ round(inv_rnd, b0, b1, kp + nc); kp += 2 * nc;
+ }
+
+ round(inv_rnd, b1, b0, kp);
+ round(inv_lrnd, b0, b1, kp + nc);
+ }
+#else
+ { u_int32_t rnd;
+
+ for(rnd = 0; rnd < this->aes_Nrnd - 1; ++rnd)
+ {
+ round(inv_rnd, b1, b0, kp);
+ l_copy(b0, b1); kp += nc;
+ }
+
+ round(inv_lrnd, b0, b1, kp);
+ }
+#endif
+
+ state_out(out_blk, b0);
+}
+
+/**
+ * Implementation of crypter_t.decrypt.
+ */
+static void decrypt(private_aes_crypter_t *this, chunk_t data, chunk_t iv,
+ chunk_t *decrypted)
+{
+ int pos;
+ const u_int32_t *iv_i;
+ u_int8_t *in, *out;
+
+ if (decrypted)
+ {
+ *decrypted = chunk_alloc(data.len);
+ out = decrypted->ptr;
+ }
+ else
+ {
+ out = data.ptr;
+ }
+ in = data.ptr;
+
+ pos = data.len-16;
+ in += pos;
+ out += pos;
+ while (pos >= 0)
+ {
+ decrypt_block(this, in, out);
+ if (pos==0)
+ {
+ iv_i=(const u_int32_t*) (iv.ptr);
+ }
+ else
+ {
+ iv_i=(const u_int32_t*) (in-16);
+ }
+ *((u_int32_t *)(&out[ 0])) ^= iv_i[0];
+ *((u_int32_t *)(&out[ 4])) ^= iv_i[1];
+ *((u_int32_t *)(&out[ 8])) ^= iv_i[2];
+ *((u_int32_t *)(&out[12])) ^= iv_i[3];
+ in-=16;
+ out-=16;
+ pos-=16;
+ }
+}
+
+
+/**
+ * Implementation of crypter_t.decrypt.
+ */
+static void encrypt (private_aes_crypter_t *this, chunk_t data, chunk_t iv,
+ chunk_t *encrypted)
+{
+ int pos;
+ const u_int32_t *iv_i;
+ u_int8_t *in, *out;
+
+ in = data.ptr;
+ out = data.ptr;
+ if (encrypted)
+ {
+ *encrypted = chunk_alloc(data.len);
+ out = encrypted->ptr;
+ }
+
+ pos=0;
+ while(pos<data.len)
+ {
+ if (pos==0)
+ {
+ iv_i=(const u_int32_t*) iv.ptr;
+ }
+ else
+ {
+ iv_i=(const u_int32_t*) (out-16);
+ }
+ *((u_int32_t *)(&out[ 0])) = iv_i[0]^*((const u_int32_t *)(&in[ 0]));
+ *((u_int32_t *)(&out[ 4])) = iv_i[1]^*((const u_int32_t *)(&in[ 4]));
+ *((u_int32_t *)(&out[ 8])) = iv_i[2]^*((const u_int32_t *)(&in[ 8]));
+ *((u_int32_t *)(&out[12])) = iv_i[3]^*((const u_int32_t *)(&in[12]));
+ encrypt_block(this, out, out);
+ in+=16;
+ out+=16;
+ pos+=16;
+ }
+}
+
+/**
+ * Implementation of crypter_t.get_block_size.
+ */
+static size_t get_block_size (private_aes_crypter_t *this)
+{
+ return AES_BLOCK_SIZE;
+}
+
+/**
+ * Implementation of crypter_t.get_key_size.
+ */
+static size_t get_key_size (private_aes_crypter_t *this)
+{
+ return this->key_size;
+}
+
+/**
+ * Implementation of crypter_t.set_key.
+ */
+static void set_key (private_aes_crypter_t *this, chunk_t key)
+{
+ u_int32_t *kf, *kt, rci, f = 0;
+ u_int8_t *in_key = key.ptr;
+
+ this->aes_Nrnd = (this->aes_Nkey > (nc) ? this->aes_Nkey : (nc)) + 6;
+
+ this->aes_e_key[0] = const_word_in(in_key );
+ this->aes_e_key[1] = const_word_in(in_key + 4);
+ this->aes_e_key[2] = const_word_in(in_key + 8);
+ this->aes_e_key[3] = const_word_in(in_key + 12);
+
+ kf = this->aes_e_key;
+ kt = kf + nc * (this->aes_Nrnd + 1) - this->aes_Nkey;
+ rci = 0;
+
+ switch(this->aes_Nkey)
+ {
+ case 4: do
+ { kf[4] = kf[0] ^ ls_box(kf[3],3) ^ rcon_tab[rci++];
+ kf[5] = kf[1] ^ kf[4];
+ kf[6] = kf[2] ^ kf[5];
+ kf[7] = kf[3] ^ kf[6];
+ kf += 4;
+ }
+ while(kf < kt);
+ break;
+
+ case 6: this->aes_e_key[4] = const_word_in(in_key + 16);
+ this->aes_e_key[5] = const_word_in(in_key + 20);
+ do
+ { kf[ 6] = kf[0] ^ ls_box(kf[5],3) ^ rcon_tab[rci++];
+ kf[ 7] = kf[1] ^ kf[ 6];
+ kf[ 8] = kf[2] ^ kf[ 7];
+ kf[ 9] = kf[3] ^ kf[ 8];
+ kf[10] = kf[4] ^ kf[ 9];
+ kf[11] = kf[5] ^ kf[10];
+ kf += 6;
+ }
+ while(kf < kt);
+ break;
+
+ case 8: this->aes_e_key[4] = const_word_in(in_key + 16);
+ this->aes_e_key[5] = const_word_in(in_key + 20);
+ this->aes_e_key[6] = const_word_in(in_key + 24);
+ this->aes_e_key[7] = const_word_in(in_key + 28);
+ do
+ { kf[ 8] = kf[0] ^ ls_box(kf[7],3) ^ rcon_tab[rci++];
+ kf[ 9] = kf[1] ^ kf[ 8];
+ kf[10] = kf[2] ^ kf[ 9];
+ kf[11] = kf[3] ^ kf[10];
+ kf[12] = kf[4] ^ ls_box(kf[11],0);
+ kf[13] = kf[5] ^ kf[12];
+ kf[14] = kf[6] ^ kf[13];
+ kf[15] = kf[7] ^ kf[14];
+ kf += 8;
+ }
+ while (kf < kt);
+ break;
+ }
+
+ if(!f)
+ {
+ u_int32_t i;
+
+ kt = this->aes_d_key + nc * this->aes_Nrnd;
+ kf = this->aes_e_key;
+
+ cpy(kt, kf); kt -= 2 * nc;
+
+ for(i = 1; i < this->aes_Nrnd; ++i)
+ {
+#if defined(ONE_TABLE) || defined(FOUR_TABLES)
+#if !defined(ONE_IM_TABLE) && !defined(FOUR_IM_TABLES)
+ u_int32_t f2, f4, f8, f9;
+#endif
+ mix(kt, kf);
+#else
+ cpy(kt, kf);
+#endif
+ kt -= 2 * nc;
+ }
+ cpy(kt, kf);
+ }
+}
+
+/**
+ * Implementation of crypter_t.destroy and aes_crypter_t.destroy.
+ */
+static void destroy (private_aes_crypter_t *this)
+{
+ free(this);
+}
+
+/*
+ * Described in header
+ */
+aes_crypter_t *aes_crypter_create(encryption_algorithm_t algo, size_t key_size)
+{
+ private_aes_crypter_t *this;
+
+ if (algo != ENCR_AES_CBC)
+ {
+ return NULL;
+ }
+
+ this = malloc_thing(private_aes_crypter_t);
+
+ #if !defined(FIXED_TABLES)
+ if(!tab_gen) { gen_tabs(); tab_gen = 1; }
+ #endif
+
+ this->key_size = key_size;
+ switch(key_size)
+ {
+ case 32: /* bytes */
+ this->aes_Nkey = 8;
+ break;
+ case 24: /* bytes */
+ this->aes_Nkey = 6;
+ break;
+ case 16: /* bytes */
+ this->aes_Nkey = 4;
+ break;
+ default:
+ free(this);
+ return NULL;
+ }
+
+ this->public.crypter_interface.encrypt = (void (*) (crypter_t *, chunk_t,chunk_t, chunk_t *)) encrypt;
+ this->public.crypter_interface.decrypt = (void (*) (crypter_t *, chunk_t , chunk_t, chunk_t *)) decrypt;
+ this->public.crypter_interface.get_block_size = (size_t (*) (crypter_t *)) get_block_size;
+ this->public.crypter_interface.get_key_size = (size_t (*) (crypter_t *)) get_key_size;
+ this->public.crypter_interface.set_key = (void (*) (crypter_t *,chunk_t)) set_key;
+ this->public.crypter_interface.destroy = (void (*) (crypter_t *)) destroy;
+
+ return &(this->public);
+}
diff --git a/src/libstrongswan/plugins/aes/aes_crypter.h b/src/libstrongswan/plugins/aes/aes_crypter.h
new file mode 100644
index 000000000..e42a6bc5b
--- /dev/null
+++ b/src/libstrongswan/plugins/aes/aes_crypter.h
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2005-2008 Martin Willi
+ * Copyright (C) 2005 Jan Hutter
+ * Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+/**
+ * @defgroup aes_crypter aes_crypter
+ * @{ @ingroup aes_p
+ */
+
+#ifndef AES_CRYPTER_H_
+#define AES_CRYPTER_H_
+
+typedef struct aes_crypter_t aes_crypter_t;
+
+#include <crypto/crypters/crypter.h>
+
+/**
+ * Class implementing the AES encryption algorithm.
+ */
+struct aes_crypter_t {
+
+ /**
+ * The crypter_t interface.
+ */
+ crypter_t crypter_interface;
+};
+
+/**
+ * Constructor to create aes_crypter_t objects.
+ *
+ * @param key_size key size in bytes
+ * @param algo algorithm to implement
+ * @return aes_crypter_t object, NULL if not supported
+ */
+aes_crypter_t *aes_crypter_create(encryption_algorithm_t algo,
+ size_t key_size);
+
+#endif /* AES_CRYPTER_H_ @}*/
diff --git a/src/libstrongswan/plugins/aes/aes_plugin.c b/src/libstrongswan/plugins/aes/aes_plugin.c
new file mode 100644
index 000000000..71e49ad73
--- /dev/null
+++ b/src/libstrongswan/plugins/aes/aes_plugin.c
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2008 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.
+ *
+ * $Id: aes_plugin.c 3488 2008-02-21 15:10:02Z martin $
+ */
+
+#include "aes_plugin.h"
+
+#include <library.h>
+#include "aes_crypter.h"
+
+typedef struct private_aes_plugin_t private_aes_plugin_t;
+
+/**
+ * private data of aes_plugin
+ */
+struct private_aes_plugin_t {
+
+ /**
+ * public functions
+ */
+ aes_plugin_t public;
+};
+
+/**
+ * Implementation of aes_plugin_t.destroy
+ */
+static void destroy(private_aes_plugin_t *this)
+{
+ lib->crypto->remove_crypter(lib->crypto,
+ (crypter_constructor_t)aes_crypter_create);
+ free(this);
+}
+
+/*
+ * see header file
+ */
+plugin_t *plugin_create()
+{
+ private_aes_plugin_t *this = malloc_thing(private_aes_plugin_t);
+
+ this->public.plugin.destroy = (void(*)(plugin_t*))destroy;
+
+ lib->crypto->add_crypter(lib->crypto, ENCR_AES_CBC,
+ (crypter_constructor_t)aes_crypter_create);
+
+ return &this->public.plugin;
+}
+
diff --git a/src/libstrongswan/plugins/aes/aes_plugin.h b/src/libstrongswan/plugins/aes/aes_plugin.h
new file mode 100644
index 000000000..4cf0bc15e
--- /dev/null
+++ b/src/libstrongswan/plugins/aes/aes_plugin.h
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2008 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.
+ */
+
+/**
+ * @defgroup aes_p aes
+ * @ingroup plugins
+ *
+ * @defgroup aes_plugin aes_plugin
+ * @{ @ingroup aes_p
+ */
+
+#ifndef AES_PLUGIN_H_
+#define AES_PLUGIN_H_
+
+#include <plugins/plugin.h>
+
+typedef struct aes_plugin_t aes_plugin_t;
+
+/**
+ * Plugin implementing AES based algorithms in software.
+ */
+struct aes_plugin_t {
+
+ /**
+ * implements plugin interface
+ */
+ plugin_t plugin;
+};
+
+/**
+ * Create a aes_plugin instance.
+ */
+plugin_t *plugin_create();
+
+#endif /* AES_PLUGIN_H_ @}*/
diff --git a/src/libstrongswan/plugins/curl/Makefile.am b/src/libstrongswan/plugins/curl/Makefile.am
new file mode 100644
index 000000000..1b44516b2
--- /dev/null
+++ b/src/libstrongswan/plugins/curl/Makefile.am
@@ -0,0 +1,11 @@
+
+INCLUDES = -I$(top_srcdir)/src/libstrongswan
+
+AM_CFLAGS = -rdynamic
+
+plugin_LTLIBRARIES = libstrongswan-curl.la
+
+libstrongswan_curl_la_SOURCES = curl_plugin.h curl_plugin.c curl_fetcher.c curl_fetcher.h
+libstrongswan_curl_la_LDFLAGS = -module
+libstrongswan_curl_la_LIBADD = -lcurl
+
diff --git a/src/libstrongswan/plugins/curl/Makefile.in b/src/libstrongswan/plugins/curl/Makefile.in
new file mode 100644
index 000000000..d3f7b443d
--- /dev/null
+++ b/src/libstrongswan/plugins/curl/Makefile.in
@@ -0,0 +1,495 @@
+# Makefile.in generated by automake 1.10.1 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+VPATH = @srcdir@
+pkgdatadir = $(datadir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+subdir = src/libstrongswan/plugins/curl
+DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/configure.in
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+mkinstalldirs = $(install_sh) -d
+CONFIG_CLEAN_FILES =
+am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
+am__vpath_adj = case $$p in \
+ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
+ *) f=$$p;; \
+ esac;
+am__strip_dir = `echo $$p | sed -e 's|^.*/||'`;
+am__installdirs = "$(DESTDIR)$(plugindir)"
+pluginLTLIBRARIES_INSTALL = $(INSTALL)
+LTLIBRARIES = $(plugin_LTLIBRARIES)
+libstrongswan_curl_la_DEPENDENCIES =
+am_libstrongswan_curl_la_OBJECTS = curl_plugin.lo curl_fetcher.lo
+libstrongswan_curl_la_OBJECTS = $(am_libstrongswan_curl_la_OBJECTS)
+libstrongswan_curl_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(libstrongswan_curl_la_LDFLAGS) $(LDFLAGS) -o $@
+DEFAULT_INCLUDES = -I.@am__isrc@
+depcomp = $(SHELL) $(top_srcdir)/depcomp
+am__depfiles_maybe = depfiles
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+ --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
+ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+CCLD = $(CC)
+LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+ --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \
+ $(LDFLAGS) -o $@
+SOURCES = $(libstrongswan_curl_la_SOURCES)
+DIST_SOURCES = $(libstrongswan_curl_la_SOURCES)
+ETAGS = etags
+CTAGS = ctags
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+AMTAR = @AMTAR@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CXX = @CXX@
+CXXCPP = @CXXCPP@
+CXXDEPMODE = @CXXDEPMODE@
+CXXFLAGS = @CXXFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DSYMUTIL = @DSYMUTIL@
+ECHO = @ECHO@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+F77 = @F77@
+FFLAGS = @FFLAGS@
+GPERF = @GPERF@
+GREP = @GREP@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+IPSEC_ROUTING_TABLE = @IPSEC_ROUTING_TABLE@
+IPSEC_ROUTING_TABLE_PRIO = @IPSEC_ROUTING_TABLE_PRIO@
+LDFLAGS = @LDFLAGS@
+LEX = @LEX@
+LEXLIB = @LEXLIB@
+LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LINUX_HEADERS = @LINUX_HEADERS@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+MAKEINFO = @MAKEINFO@
+MKDIR_P = @MKDIR_P@
+NMEDIT = @NMEDIT@
+OBJEXT = @OBJEXT@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PERL = @PERL@
+PKG_CONFIG = @PKG_CONFIG@
+RANLIB = @RANLIB@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRIP = @STRIP@
+VERSION = @VERSION@
+YACC = @YACC@
+YFLAGS = @YFLAGS@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_CXX = @ac_ct_CXX@
+ac_ct_F77 = @ac_ct_F77@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+confdir = @confdir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+gtk_CFLAGS = @gtk_CFLAGS@
+gtk_LIBS = @gtk_LIBS@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+ipsecdir = @ipsecdir@
+ipsecgroup = @ipsecgroup@
+ipsecuser = @ipsecuser@
+libdir = @libdir@
+libexecdir = @libexecdir@
+libstrongswan_plugins = @libstrongswan_plugins@
+linuxdir = @linuxdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+piddir = @piddir@
+plugindir = @plugindir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+resolv_conf = @resolv_conf@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+simreader = @simreader@
+srcdir = @srcdir@
+strongswan_conf = @strongswan_conf@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+xml_CFLAGS = @xml_CFLAGS@
+xml_LIBS = @xml_LIBS@
+INCLUDES = -I$(top_srcdir)/src/libstrongswan
+AM_CFLAGS = -rdynamic
+plugin_LTLIBRARIES = libstrongswan-curl.la
+libstrongswan_curl_la_SOURCES = curl_plugin.h curl_plugin.c curl_fetcher.c curl_fetcher.h
+libstrongswan_curl_la_LDFLAGS = -module
+libstrongswan_curl_la_LIBADD = -lcurl
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .c .lo .o .obj
+$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \
+ && exit 0; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/libstrongswan/plugins/curl/Makefile'; \
+ cd $(top_srcdir) && \
+ $(AUTOMAKE) --gnu src/libstrongswan/plugins/curl/Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+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) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(pluginLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) '$$p' '$(DESTDIR)$(plugindir)/$$f'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(pluginLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) "$$p" "$(DESTDIR)$(plugindir)/$$f"; \
+ else :; fi; \
+ done
+
+uninstall-pluginLTLIBRARIES:
+ @$(NORMAL_UNINSTALL)
+ @list='$(plugin_LTLIBRARIES)'; for p in $$list; do \
+ p=$(am__strip_dir) \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(plugindir)/$$p'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(plugindir)/$$p"; \
+ 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
+libstrongswan-curl.la: $(libstrongswan_curl_la_OBJECTS) $(libstrongswan_curl_la_DEPENDENCIES)
+ $(libstrongswan_curl_la_LINK) -rpath $(plugindir) $(libstrongswan_curl_la_OBJECTS) $(libstrongswan_curl_la_LIBADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/curl_fetcher.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/curl_plugin.Plo@am__quote@
+
+.c.o:
+@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(COMPILE) -c $<
+
+.c.obj:
+@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'`
+
+.c.lo:
+@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $<
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+
+ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonemtpy = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ mkid -fID $$unique
+tags: TAGS
+
+TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ tags=; \
+ here=`pwd`; \
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \
+ test -n "$$unique" || unique=$$empty_fix; \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ $$tags $$unique; \
+ fi
+ctags: CTAGS
+CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ tags=; \
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ test -z "$(CTAGS_ARGS)$$tags$$unique" \
+ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+ $$tags $$unique
+
+GTAGS:
+ here=`$(am__cd) $(top_builddir) && pwd` \
+ && cd $(top_srcdir) \
+ && gtags -i $(GTAGS_ARGS) $$here
+
+distclean-tags:
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+distdir: $(DISTFILES)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ list='$(DISTFILES)'; \
+ dist_files=`for file in $$list; do echo $$file; done | \
+ sed -e "s|^$$srcdirstrip/||;t" \
+ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+ case $$dist_files in \
+ */*) $(MKDIR_P) `echo "$$dist_files" | \
+ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+ sort -u` ;; \
+ esac; \
+ for file in $$dist_files; do \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ if test -d $$d/$$file; then \
+ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
+ fi; \
+ cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
+ else \
+ test -f $(distdir)/$$file \
+ || cp -p $$d/$$file $(distdir)/$$file \
+ || exit 1; \
+ fi; \
+ done
+check-am: all-am
+check: check-am
+all-am: Makefile $(LTLIBRARIES)
+installdirs:
+ for dir in "$(DESTDIR)$(plugindir)"; do \
+ test -z "$$dir" || $(MKDIR_P) "$$dir"; \
+ done
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ `test -z '$(STRIP)' || \
+ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+clean: clean-am
+
+clean-am: clean-generic clean-libtool clean-pluginLTLIBRARIES \
+ mostlyclean-am
+
+distclean: distclean-am
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+ distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+info: info-am
+
+info-am:
+
+install-data-am: install-pluginLTLIBRARIES
+
+install-dvi: install-dvi-am
+
+install-exec-am:
+
+install-html: install-html-am
+
+install-info: install-info-am
+
+install-man:
+
+install-pdf: install-pdf-am
+
+install-ps: install-ps-am
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic \
+ mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am: uninstall-pluginLTLIBRARIES
+
+.MAKE: install-am install-strip
+
+.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \
+ clean-libtool clean-pluginLTLIBRARIES ctags distclean \
+ distclean-compile distclean-generic distclean-libtool \
+ distclean-tags distdir dvi dvi-am html html-am info info-am \
+ install install-am install-data install-data-am install-dvi \
+ install-dvi-am install-exec install-exec-am install-html \
+ install-html-am install-info install-info-am install-man \
+ install-pdf install-pdf-am install-pluginLTLIBRARIES \
+ install-ps install-ps-am install-strip installcheck \
+ installcheck-am installdirs maintainer-clean \
+ maintainer-clean-generic mostlyclean mostlyclean-compile \
+ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
+ tags uninstall uninstall-am uninstall-pluginLTLIBRARIES
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/src/libstrongswan/plugins/curl/curl_fetcher.c b/src/libstrongswan/plugins/curl/curl_fetcher.c
new file mode 100644
index 000000000..4754d569e
--- /dev/null
+++ b/src/libstrongswan/plugins/curl/curl_fetcher.c
@@ -0,0 +1,176 @@
+/*
+ * Copyright (C) 2008 Martin Willi
+ * Copyright (C) 2007 Andreas Steffen
+ * Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * $Id: curl_fetcher.c 3529 2008-03-05 15:26:24Z martin $
+ */
+
+#include <curl/curl.h>
+
+#include <library.h>
+#include <debug.h>
+
+#include "curl_fetcher.h"
+
+#define DEFAULT_TIMEOUT 10
+
+typedef struct private_curl_fetcher_t private_curl_fetcher_t;
+
+/**
+ * private data of a curl_fetcher_t object.
+ */
+struct private_curl_fetcher_t {
+ /**
+ * Public data
+ */
+ curl_fetcher_t public;
+
+ /**
+ * CURL handle
+ */
+ CURL* curl;
+
+ /**
+ * request type, as set with FETCH_REQUEST_TYPE
+ */
+ char *request_type;
+};
+
+/**
+ * writes data into a dynamically resizeable chunk_t
+ */
+static size_t append(void *ptr, size_t size, size_t nmemb, chunk_t *data)
+{
+ size_t realsize = size * nmemb;
+
+ data->ptr = (u_char*)realloc(data->ptr, data->len + realsize);
+ if (data->ptr)
+ {
+ memcpy(&data->ptr[data->len], ptr, realsize);
+ data->len += realsize;
+ }
+ return realsize;
+}
+
+/**
+ * Implements fetcher_t.fetch.
+ */
+static status_t fetch(private_curl_fetcher_t *this, char *uri, chunk_t *result)
+{
+ struct curl_slist *headers = NULL;
+ char error[CURL_ERROR_SIZE];
+ char buf[256];;
+ status_t status;
+
+ *result = chunk_empty;
+
+ if (curl_easy_setopt(this->curl, CURLOPT_URL, uri) != CURLE_OK)
+ { /* URL type not supported by curl */
+ return NOT_SUPPORTED;
+ }
+ curl_easy_setopt(this->curl, CURLOPT_ERRORBUFFER, error);
+ curl_easy_setopt(this->curl, CURLOPT_FAILONERROR, TRUE);
+ curl_easy_setopt(this->curl, CURLOPT_NOSIGNAL, TRUE);
+ curl_easy_setopt(this->curl, CURLOPT_CONNECTTIMEOUT, DEFAULT_TIMEOUT);
+ curl_easy_setopt(this->curl, CURLOPT_WRITEFUNCTION, (void*)append);
+ curl_easy_setopt(this->curl, CURLOPT_WRITEDATA, (void*)result);
+ if (this->request_type)
+ {
+ snprintf(buf, sizeof(buf), "Content-Type: %s", this->request_type);
+ headers = curl_slist_append(headers, buf);
+ curl_easy_setopt(this->curl, CURLOPT_HTTPHEADER, headers);
+ }
+
+ DBG2("sending http request to '%s'...", uri);
+ switch (curl_easy_perform(this->curl))
+ {
+ case CURLE_UNSUPPORTED_PROTOCOL:
+ status = NOT_SUPPORTED;
+ break;
+ case CURLE_OK:
+ status = SUCCESS;
+ break;
+ default:
+ DBG1("libcurl http request failed: %s", error);
+ status = FAILED;
+ break;
+ }
+ curl_slist_free_all(headers);
+ return status;
+}
+
+/**
+ * Implementation of fetcher_t.set_option.
+ */
+static bool set_option(private_curl_fetcher_t *this, fetcher_option_t option, ...)
+{
+ va_list args;
+
+ va_start(args, option);
+ switch (option)
+ {
+ case FETCH_REQUEST_DATA:
+ {
+ chunk_t data = va_arg(args, chunk_t);
+ curl_easy_setopt(this->curl, CURLOPT_POSTFIELDS, data.ptr);
+ curl_easy_setopt(this->curl, CURLOPT_POSTFIELDSIZE, data.len);
+ return TRUE;
+ }
+ case FETCH_REQUEST_TYPE:
+ {
+ this->request_type = va_arg(args, char*);
+ return TRUE;
+ }
+ case FETCH_TIMEOUT:
+ {
+ curl_easy_setopt(this->curl, CURLOPT_CONNECTTIMEOUT,
+ va_arg(args, u_int));
+ return TRUE;
+ }
+ default:
+ return FALSE;
+ }
+}
+
+/**
+ * Implements fetcher_t.destroy
+ */
+static void destroy(private_curl_fetcher_t *this)
+{
+ curl_easy_cleanup(this->curl);
+ free(this);
+}
+
+/*
+ * Described in header.
+ */
+curl_fetcher_t *curl_fetcher_create()
+{
+ private_curl_fetcher_t *this = malloc_thing(private_curl_fetcher_t);
+
+ this->curl = curl_easy_init();
+ if (this->curl == NULL)
+ {
+ free(this);
+ return NULL;
+ }
+ this->request_type = NULL;
+
+ this->public.interface.fetch = (status_t(*)(fetcher_t*,char*,chunk_t*))fetch;
+ this->public.interface.set_option = (bool(*)(fetcher_t*, fetcher_option_t option, ...))set_option;
+ this->public.interface.destroy = (void (*)(fetcher_t*))destroy;
+
+ return &this->public;
+}
+
diff --git a/src/libstrongswan/plugins/curl/curl_fetcher.h b/src/libstrongswan/plugins/curl/curl_fetcher.h
new file mode 100644
index 000000000..3028eac1b
--- /dev/null
+++ b/src/libstrongswan/plugins/curl/curl_fetcher.h
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2008 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.
+ */
+
+/**
+ * @defgroup curl_fetcher curl_fetcher
+ * @{ @ingroup curl_p
+ */
+
+#ifndef CURL_FETCHER_H_
+#define CURL_FETCHER_H_
+
+typedef struct curl_fetcher_t curl_fetcher_t;
+
+/**
+ * Fetcher implementation using libcurl
+ */
+struct curl_fetcher_t {
+
+ /**
+ * Implements fetcher interface
+ */
+ fetcher_t interface;
+
+ /**
+ * Destroy a curl_fetcher instance.
+ */
+ void (*destroy)(curl_fetcher_t *this);
+};
+
+/**
+ * Create a curl_fetcher instance.
+ */
+curl_fetcher_t *curl_fetcher_create();
+
+#endif /* CURL_FETCHER_H_ @}*/
diff --git a/src/libstrongswan/plugins/curl/curl_plugin.c b/src/libstrongswan/plugins/curl/curl_plugin.c
new file mode 100644
index 000000000..a41c3815c
--- /dev/null
+++ b/src/libstrongswan/plugins/curl/curl_plugin.c
@@ -0,0 +1,79 @@
+/*
+ * Copyright (C) 2008 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.
+ *
+ * $Id: curl_plugin.c 3529 2008-03-05 15:26:24Z martin $
+ */
+
+#include "curl_plugin.h"
+
+#include <library.h>
+#include <debug.h>
+#include "curl_fetcher.h"
+
+#include <curl/curl.h>
+
+typedef struct private_curl_plugin_t private_curl_plugin_t;
+
+/**
+ * private data of curl_plugin
+ */
+struct private_curl_plugin_t {
+
+ /**
+ * public functions
+ */
+ curl_plugin_t public;
+};
+
+/**
+ * Implementation of curl_plugin_t.curltroy
+ */
+static void destroy(private_curl_plugin_t *this)
+{
+ lib->fetcher->remove_fetcher(lib->fetcher,
+ (fetcher_constructor_t)curl_fetcher_create);
+ curl_global_cleanup();
+ free(this);
+}
+
+/*
+ * see header file
+ */
+plugin_t *plugin_create()
+{
+ CURLcode res;
+ private_curl_plugin_t *this = malloc_thing(private_curl_plugin_t);
+
+ this->public.plugin.destroy = (void(*)(plugin_t*))destroy;
+
+ res = curl_global_init(CURL_GLOBAL_NOTHING);
+ if (res == CURLE_OK)
+ {
+ lib->fetcher->add_fetcher(lib->fetcher,
+ (fetcher_constructor_t)curl_fetcher_create, "file://");
+ lib->fetcher->add_fetcher(lib->fetcher,
+ (fetcher_constructor_t)curl_fetcher_create, "http://");
+ lib->fetcher->add_fetcher(lib->fetcher,
+ (fetcher_constructor_t)curl_fetcher_create, "https://");
+ lib->fetcher->add_fetcher(lib->fetcher,
+ (fetcher_constructor_t)curl_fetcher_create, "ftp://");
+ }
+ else
+ {
+ DBG1("global libcurl initializing failed: %s, curl disabled",
+ curl_easy_strerror(res));
+ }
+ return &this->public.plugin;
+}
+
diff --git a/src/libstrongswan/plugins/curl/curl_plugin.h b/src/libstrongswan/plugins/curl/curl_plugin.h
new file mode 100644
index 000000000..73166a25b
--- /dev/null
+++ b/src/libstrongswan/plugins/curl/curl_plugin.h
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2008 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.
+ */
+
+/**
+ * @defgroup curl_p curl
+ * @ingroup plugins
+ *
+ * @defgroup curl_plugin curl_plugin
+ * @{ @ingroup curl_p
+ */
+
+#ifndef CURL_PLUGIN_H_
+#define CURL_PLUGIN_H_
+
+#include <plugins/plugin.h>
+
+typedef struct curl_plugin_t curl_plugin_t;
+
+/**
+ * Plugin implementing fetcher interface using libcurl http library.
+ */
+struct curl_plugin_t {
+
+ /**
+ * implements plugin interface
+ */
+ plugin_t plugin;
+};
+
+/**
+ * Create a curl_plugin instance.
+ */
+plugin_t *plugin_create();
+
+#endif /* CURL_PLUGIN_H_ @}*/
diff --git a/src/libstrongswan/plugins/des/Makefile.am b/src/libstrongswan/plugins/des/Makefile.am
new file mode 100644
index 000000000..ea94eda8a
--- /dev/null
+++ b/src/libstrongswan/plugins/des/Makefile.am
@@ -0,0 +1,10 @@
+
+INCLUDES = -I$(top_srcdir)/src/libstrongswan
+
+AM_CFLAGS = -rdynamic
+
+plugin_LTLIBRARIES = libstrongswan-des.la
+
+libstrongswan_des_la_SOURCES = des_plugin.h des_plugin.c des_crypter.c des_crypter.h
+libstrongswan_des_la_LDFLAGS = -module
+
diff --git a/src/libstrongswan/plugins/des/Makefile.in b/src/libstrongswan/plugins/des/Makefile.in
new file mode 100644
index 000000000..5072a2cab
--- /dev/null
+++ b/src/libstrongswan/plugins/des/Makefile.in
@@ -0,0 +1,494 @@
+# Makefile.in generated by automake 1.10.1 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+VPATH = @srcdir@
+pkgdatadir = $(datadir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+subdir = src/libstrongswan/plugins/des
+DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/configure.in
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+mkinstalldirs = $(install_sh) -d
+CONFIG_CLEAN_FILES =
+am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
+am__vpath_adj = case $$p in \
+ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
+ *) f=$$p;; \
+ esac;
+am__strip_dir = `echo $$p | sed -e 's|^.*/||'`;
+am__installdirs = "$(DESTDIR)$(plugindir)"
+pluginLTLIBRARIES_INSTALL = $(INSTALL)
+LTLIBRARIES = $(plugin_LTLIBRARIES)
+libstrongswan_des_la_LIBADD =
+am_libstrongswan_des_la_OBJECTS = des_plugin.lo des_crypter.lo
+libstrongswan_des_la_OBJECTS = $(am_libstrongswan_des_la_OBJECTS)
+libstrongswan_des_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(libstrongswan_des_la_LDFLAGS) $(LDFLAGS) -o $@
+DEFAULT_INCLUDES = -I.@am__isrc@
+depcomp = $(SHELL) $(top_srcdir)/depcomp
+am__depfiles_maybe = depfiles
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+ --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
+ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+CCLD = $(CC)
+LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+ --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \
+ $(LDFLAGS) -o $@
+SOURCES = $(libstrongswan_des_la_SOURCES)
+DIST_SOURCES = $(libstrongswan_des_la_SOURCES)
+ETAGS = etags
+CTAGS = ctags
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+AMTAR = @AMTAR@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CXX = @CXX@
+CXXCPP = @CXXCPP@
+CXXDEPMODE = @CXXDEPMODE@
+CXXFLAGS = @CXXFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DSYMUTIL = @DSYMUTIL@
+ECHO = @ECHO@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+F77 = @F77@
+FFLAGS = @FFLAGS@
+GPERF = @GPERF@
+GREP = @GREP@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+IPSEC_ROUTING_TABLE = @IPSEC_ROUTING_TABLE@
+IPSEC_ROUTING_TABLE_PRIO = @IPSEC_ROUTING_TABLE_PRIO@
+LDFLAGS = @LDFLAGS@
+LEX = @LEX@
+LEXLIB = @LEXLIB@
+LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LINUX_HEADERS = @LINUX_HEADERS@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+MAKEINFO = @MAKEINFO@
+MKDIR_P = @MKDIR_P@
+NMEDIT = @NMEDIT@
+OBJEXT = @OBJEXT@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PERL = @PERL@
+PKG_CONFIG = @PKG_CONFIG@
+RANLIB = @RANLIB@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRIP = @STRIP@
+VERSION = @VERSION@
+YACC = @YACC@
+YFLAGS = @YFLAGS@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_CXX = @ac_ct_CXX@
+ac_ct_F77 = @ac_ct_F77@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+confdir = @confdir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+gtk_CFLAGS = @gtk_CFLAGS@
+gtk_LIBS = @gtk_LIBS@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+ipsecdir = @ipsecdir@
+ipsecgroup = @ipsecgroup@
+ipsecuser = @ipsecuser@
+libdir = @libdir@
+libexecdir = @libexecdir@
+libstrongswan_plugins = @libstrongswan_plugins@
+linuxdir = @linuxdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+piddir = @piddir@
+plugindir = @plugindir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+resolv_conf = @resolv_conf@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+simreader = @simreader@
+srcdir = @srcdir@
+strongswan_conf = @strongswan_conf@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+xml_CFLAGS = @xml_CFLAGS@
+xml_LIBS = @xml_LIBS@
+INCLUDES = -I$(top_srcdir)/src/libstrongswan
+AM_CFLAGS = -rdynamic
+plugin_LTLIBRARIES = libstrongswan-des.la
+libstrongswan_des_la_SOURCES = des_plugin.h des_plugin.c des_crypter.c des_crypter.h
+libstrongswan_des_la_LDFLAGS = -module
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .c .lo .o .obj
+$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \
+ && exit 0; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/libstrongswan/plugins/des/Makefile'; \
+ cd $(top_srcdir) && \
+ $(AUTOMAKE) --gnu src/libstrongswan/plugins/des/Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+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) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(pluginLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) '$$p' '$(DESTDIR)$(plugindir)/$$f'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(pluginLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) "$$p" "$(DESTDIR)$(plugindir)/$$f"; \
+ else :; fi; \
+ done
+
+uninstall-pluginLTLIBRARIES:
+ @$(NORMAL_UNINSTALL)
+ @list='$(plugin_LTLIBRARIES)'; for p in $$list; do \
+ p=$(am__strip_dir) \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(plugindir)/$$p'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(plugindir)/$$p"; \
+ 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
+libstrongswan-des.la: $(libstrongswan_des_la_OBJECTS) $(libstrongswan_des_la_DEPENDENCIES)
+ $(libstrongswan_des_la_LINK) -rpath $(plugindir) $(libstrongswan_des_la_OBJECTS) $(libstrongswan_des_la_LIBADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/des_crypter.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/des_plugin.Plo@am__quote@
+
+.c.o:
+@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(COMPILE) -c $<
+
+.c.obj:
+@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'`
+
+.c.lo:
+@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $<
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+
+ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonemtpy = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ mkid -fID $$unique
+tags: TAGS
+
+TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ tags=; \
+ here=`pwd`; \
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \
+ test -n "$$unique" || unique=$$empty_fix; \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ $$tags $$unique; \
+ fi
+ctags: CTAGS
+CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ tags=; \
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ test -z "$(CTAGS_ARGS)$$tags$$unique" \
+ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+ $$tags $$unique
+
+GTAGS:
+ here=`$(am__cd) $(top_builddir) && pwd` \
+ && cd $(top_srcdir) \
+ && gtags -i $(GTAGS_ARGS) $$here
+
+distclean-tags:
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+distdir: $(DISTFILES)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ list='$(DISTFILES)'; \
+ dist_files=`for file in $$list; do echo $$file; done | \
+ sed -e "s|^$$srcdirstrip/||;t" \
+ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+ case $$dist_files in \
+ */*) $(MKDIR_P) `echo "$$dist_files" | \
+ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+ sort -u` ;; \
+ esac; \
+ for file in $$dist_files; do \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ if test -d $$d/$$file; then \
+ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
+ fi; \
+ cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
+ else \
+ test -f $(distdir)/$$file \
+ || cp -p $$d/$$file $(distdir)/$$file \
+ || exit 1; \
+ fi; \
+ done
+check-am: all-am
+check: check-am
+all-am: Makefile $(LTLIBRARIES)
+installdirs:
+ for dir in "$(DESTDIR)$(plugindir)"; do \
+ test -z "$$dir" || $(MKDIR_P) "$$dir"; \
+ done
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ `test -z '$(STRIP)' || \
+ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+clean: clean-am
+
+clean-am: clean-generic clean-libtool clean-pluginLTLIBRARIES \
+ mostlyclean-am
+
+distclean: distclean-am
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+ distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+info: info-am
+
+info-am:
+
+install-data-am: install-pluginLTLIBRARIES
+
+install-dvi: install-dvi-am
+
+install-exec-am:
+
+install-html: install-html-am
+
+install-info: install-info-am
+
+install-man:
+
+install-pdf: install-pdf-am
+
+install-ps: install-ps-am
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic \
+ mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am: uninstall-pluginLTLIBRARIES
+
+.MAKE: install-am install-strip
+
+.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \
+ clean-libtool clean-pluginLTLIBRARIES ctags distclean \
+ distclean-compile distclean-generic distclean-libtool \
+ distclean-tags distdir dvi dvi-am html html-am info info-am \
+ install install-am install-data install-data-am install-dvi \
+ install-dvi-am install-exec install-exec-am install-html \
+ install-html-am install-info install-info-am install-man \
+ install-pdf install-pdf-am install-pluginLTLIBRARIES \
+ install-ps install-ps-am install-strip installcheck \
+ installcheck-am installdirs maintainer-clean \
+ maintainer-clean-generic mostlyclean mostlyclean-compile \
+ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
+ tags uninstall uninstall-am uninstall-pluginLTLIBRARIES
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/src/libstrongswan/plugins/des/des_crypter.c b/src/libstrongswan/plugins/des/des_crypter.c
new file mode 100644
index 000000000..43aff4dd1
--- /dev/null
+++ b/src/libstrongswan/plugins/des/des_crypter.c
@@ -0,0 +1,1517 @@
+/* Copyright (C) 2006 Martin Willi
+ * Hochschule fuer Technik Rapperswil
+ *
+ * Derived from Plutos DES library by Eric Young.
+ *
+ * Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * "This product includes cryptographic software written by
+ * Eric Young (eay@cryptsoft.com)"
+ * The word 'cryptographic' can be left out if the rouines from the library
+ * being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ * the apps directory (application code) you must include an acknowledgement:
+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed. i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ *
+ * $Id: des_crypter.c 3910 2008-05-07 11:54:30Z martin $
+ */
+
+#include "des_crypter.h"
+
+typedef u_char des_cblock[8];
+
+typedef struct des_ks_struct {
+ des_cblock _;
+} des_key_schedule[16];
+
+
+typedef struct private_des_crypter_t private_des_crypter_t;
+
+/**
+ * Private data for des_crypter_t
+ */
+struct private_des_crypter_t {
+
+ /**
+ * Public part of this class.
+ */
+ des_crypter_t public;
+
+ /**
+ * Key size, depends on algoritm...
+ */
+ size_t key_size;
+
+ union {
+ /** key schedule for single des */
+ des_key_schedule ks;
+ /** key schedule for 3des */
+ des_key_schedule ks3[3];
+ };
+};
+
+
+#define DES_ENCRYPT 1
+#define DES_DECRYPT 0
+
+#define DES_LONG u_int32_t
+
+#if defined(WIN32) || defined(WIN16)
+#ifndef MSDOS
+#define MSDOS
+#endif
+#endif
+
+#ifndef DES_DEFAULT_OPTIONS
+/* the following is tweaked from a config script, that is why it is a
+ * protected undef/define */
+#ifndef DES_PTR
+#define DES_PTR
+#endif
+
+/* This helps C compiler generate the correct code for multiple functional
+ * units. It reduces register dependancies at the expense of 2 more
+ * registers */
+#ifndef DES_RISC1
+#define DES_RISC1
+#endif
+
+#ifndef DES_RISC2
+#undef DES_RISC2
+#endif
+
+#if defined(DES_RISC1) && defined(DES_RISC2)
+YOU SHOULD NOT HAVE BOTH DES_RISC1 AND DES_RISC2 DEFINED!!!!!
+#endif
+
+/* Unroll the inner loop, this sometimes helps, sometimes hinders.
+ * Very mucy CPU dependant */
+#ifndef DES_UNROLL
+#define DES_UNROLL
+#endif
+
+/* These default values were supplied by
+ * Peter Gutman <pgut001@cs.auckland.ac.nz>
+ * They are only used if nothing else has been defined */
+#if !defined(DES_PTR) && !defined(DES_RISC1) && !defined(DES_RISC2) && !defined(DES_UNROLL)
+/* Special defines which change the way the code is built depending on the
+ CPU and OS. For SGI machines you can use _MIPS_SZLONG (32 or 64) to find
+ even newer MIPS CPU's, but at the moment one size fits all for
+ optimization options. Older Sparc's work better with only UNROLL, but
+ there's no way to tell at compile time what it is you're running on */
+
+#if defined( sun ) /* Newer Sparc's */
+#define DES_PTR
+#define DES_RISC1
+#define DES_UNROLL
+#elif defined( __ultrix ) /* Older MIPS */
+#define DES_PTR
+#define DES_RISC2
+#define DES_UNROLL
+#elif defined( __osf1__ ) /* Alpha */
+#define DES_PTR
+#define DES_RISC2
+#elif defined ( _AIX ) /* RS6000 */
+ /* Unknown */
+#elif defined( __hpux ) /* HP-PA */
+ /* Unknown */
+#elif defined( __aux ) /* 68K */
+ /* Unknown */
+#elif defined( __dgux ) /* 88K (but P6 in latest boxes) */
+#define DES_UNROLL
+#elif defined( __sgi ) /* Newer MIPS */
+#define DES_PTR
+#define DES_RISC2
+#define DES_UNROLL
+#elif defined( i386 ) /* x86 boxes, should be gcc */
+#define DES_PTR
+#define DES_RISC1
+#define DES_UNROLL
+#endif /* Systems-specific speed defines */
+#endif
+
+#endif /* DES_DEFAULT_OPTIONS */
+
+#ifdef MSDOS /* Visual C++ 2.1 (Windows NT/95) */
+#include <stdlib.h>
+#include <errno.h>
+#include <time.h>
+#include <io.h>
+#ifndef RAND
+#define RAND
+#endif
+#undef NOPROTO
+#endif
+
+#if defined(__STDC__) || defined(VMS) || defined(M_XENIX) || defined(MSDOS)
+#ifndef __KERNEL__
+#include <string.h>
+#else
+#include <linux/string.h>
+#endif
+#endif
+
+#ifndef RAND
+#define RAND
+#endif
+
+#ifdef linux
+#undef RAND
+#endif
+
+#ifdef MSDOS
+#define getpid() 2
+#define RAND
+#undef NOPROTO
+#endif
+
+#if defined(NOCONST)
+#define const
+#endif
+
+#ifdef __STDC__
+#undef NOPROTO
+#endif
+
+#ifdef RAND
+#define srandom(s) srand(s)
+#define random rand
+#endif
+
+#define ITERATIONS 16
+#define HALF_ITERATIONS 8
+
+/* used in des_read and des_write */
+#define MAXWRITE (1024*16)
+#define BSIZE (MAXWRITE+4)
+
+#define c2l(c,l) (l =((DES_LONG)(*((c)++))) , \
+ l|=((DES_LONG)(*((c)++)))<< 8L, \
+ l|=((DES_LONG)(*((c)++)))<<16L, \
+ l|=((DES_LONG)(*((c)++)))<<24L)
+
+/* NOTE - c is not incremented as per c2l */
+#define c2ln(c,l1,l2,n) { \
+ c+=n; \
+ l1=l2=0; \
+ switch (n) { \
+ case 8: l2 =((DES_LONG)(*(--(c))))<<24L; \
+ case 7: l2|=((DES_LONG)(*(--(c))))<<16L; \
+ case 6: l2|=((DES_LONG)(*(--(c))))<< 8L; \
+ case 5: l2|=((DES_LONG)(*(--(c)))); \
+ case 4: l1 =((DES_LONG)(*(--(c))))<<24L; \
+ case 3: l1|=((DES_LONG)(*(--(c))))<<16L; \
+ case 2: l1|=((DES_LONG)(*(--(c))))<< 8L; \
+ case 1: l1|=((DES_LONG)(*(--(c)))); \
+} \
+}
+
+#define l2c(l,c) (*((c)++)=(unsigned char)(((l) )&0xff), \
+ *((c)++)=(unsigned char)(((l)>> 8L)&0xff), \
+ *((c)++)=(unsigned char)(((l)>>16L)&0xff), \
+ *((c)++)=(unsigned char)(((l)>>24L)&0xff))
+
+/* replacements for htonl and ntohl since I have no idea what to do
+ * when faced with machines with 8 byte longs. */
+#define HDRSIZE 4
+
+#define n2l(c,l) (l =((DES_LONG)(*((c)++)))<<24L, \
+ l|=((DES_LONG)(*((c)++)))<<16L, \
+ l|=((DES_LONG)(*((c)++)))<< 8L, \
+ l|=((DES_LONG)(*((c)++))))
+
+#define l2n(l,c) (*((c)++)=(unsigned char)(((l)>>24L)&0xff), \
+ *((c)++)=(unsigned char)(((l)>>16L)&0xff), \
+ *((c)++)=(unsigned char)(((l)>> 8L)&0xff), \
+ *((c)++)=(unsigned char)(((l) )&0xff))
+
+/* NOTE - c is not incremented as per l2c */
+#define l2cn(l1,l2,c,n) { \
+ c+=n; \
+ switch (n) { \
+ case 8: *(--(c))=(unsigned char)(((l2)>>24L)&0xff); \
+ case 7: *(--(c))=(unsigned char)(((l2)>>16L)&0xff); \
+ case 6: *(--(c))=(unsigned char)(((l2)>> 8L)&0xff); \
+ case 5: *(--(c))=(unsigned char)(((l2) )&0xff); \
+ case 4: *(--(c))=(unsigned char)(((l1)>>24L)&0xff); \
+ case 3: *(--(c))=(unsigned char)(((l1)>>16L)&0xff); \
+ case 2: *(--(c))=(unsigned char)(((l1)>> 8L)&0xff); \
+ case 1: *(--(c))=(unsigned char)(((l1) )&0xff); \
+} \
+}
+
+#if defined(WIN32)
+#define ROTATE(a,n) (_lrotr(a,n))
+#else
+#define ROTATE(a,n) (((a)>>(n))+((a)<<(32-(n))))
+#endif
+
+/* Don't worry about the LOAD_DATA() stuff, that is used by
+ * fcrypt() to add it's little bit to the front */
+
+#ifdef DES_FCRYPT
+
+#define LOAD_DATA_tmp(R,S,u,t,E0,E1) \
+{ DES_LONG tmp; LOAD_DATA(R,S,u,t,E0,E1,tmp); }
+
+#define LOAD_DATA(R,S,u,t,E0,E1,tmp) \
+ t=R^(R>>16L); \
+ u=t&E0; t&=E1; \
+ tmp=(u<<16); u^=R^s[S ]; u^=tmp; \
+ tmp=(t<<16); t^=R^s[S+1]; t^=tmp
+#else
+#define LOAD_DATA_tmp(a,b,c,d,e,f) LOAD_DATA(a,b,c,d,e,f,g)
+#define LOAD_DATA(R,S,u,t,E0,E1,tmp) \
+ u=R^s[S ]; \
+ t=R^s[S+1]
+#endif
+
+/* The changes to this macro may help or hinder, depending on the
+ * compiler and the achitecture. gcc2 always seems to do well :-).
+ * Inspired by Dana How <how@isl.stanford.edu>
+ * DO NOT use the alternative version on machines with 8 byte longs.
+ * It does not seem to work on the Alpha, even when DES_LONG is 4
+ * bytes, probably an issue of accessing non-word aligned objects :-( */
+#ifdef DES_PTR
+
+/* It recently occured to me that 0^0^0^0^0^0^0 == 0, so there
+ * is no reason to not xor all the sub items together. This potentially
+ * saves a register since things can be xored directly into L */
+
+#if defined(DES_RISC1) || defined(DES_RISC2)
+#ifdef DES_RISC1
+#define D_ENCRYPT(LL,R,S) { \
+ unsigned int u1,u2,u3; \
+ LOAD_DATA(R,S,u,t,E0,E1,u1); \
+ u2=(int)u>>8L; \
+ u1=(int)u&0xfc; \
+ u2&=0xfc; \
+ t=ROTATE(t,4); \
+ u>>=16L; \
+ LL^= *(DES_LONG *)((unsigned char *)des_SP +u1); \
+ LL^= *(DES_LONG *)((unsigned char *)des_SP+0x200+u2); \
+ u3=(int)(u>>8L); \
+ u1=(int)u&0xfc; \
+ u3&=0xfc; \
+ LL^= *(DES_LONG *)((unsigned char *)des_SP+0x400+u1); \
+ LL^= *(DES_LONG *)((unsigned char *)des_SP+0x600+u3); \
+ u2=(int)t>>8L; \
+ u1=(int)t&0xfc; \
+ u2&=0xfc; \
+ t>>=16L; \
+ LL^= *(DES_LONG *)((unsigned char *)des_SP+0x100+u1); \
+ LL^= *(DES_LONG *)((unsigned char *)des_SP+0x300+u2); \
+ u3=(int)t>>8L; \
+ u1=(int)t&0xfc; \
+ u3&=0xfc; \
+ LL^= *(DES_LONG *)((unsigned char *)des_SP+0x500+u1); \
+ LL^= *(DES_LONG *)((unsigned char *)des_SP+0x700+u3); }
+#endif
+#ifdef DES_RISC2
+#define D_ENCRYPT(LL,R,S) { \
+ unsigned int u1,u2,s1,s2; \
+ LOAD_DATA(R,S,u,t,E0,E1,u1); \
+ u2=(int)u>>8L; \
+ u1=(int)u&0xfc; \
+ u2&=0xfc; \
+ t=ROTATE(t,4); \
+ LL^= *(DES_LONG *)((unsigned char *)des_SP +u1); \
+ LL^= *(DES_LONG *)((unsigned char *)des_SP+0x200+u2); \
+ s1=(int)(u>>16L); \
+ s2=(int)(u>>24L); \
+ s1&=0xfc; \
+ s2&=0xfc; \
+ LL^= *(DES_LONG *)((unsigned char *)des_SP+0x400+s1); \
+ LL^= *(DES_LONG *)((unsigned char *)des_SP+0x600+s2); \
+ u2=(int)t>>8L; \
+ u1=(int)t&0xfc; \
+ u2&=0xfc; \
+ LL^= *(DES_LONG *)((unsigned char *)des_SP+0x100+u1); \
+ LL^= *(DES_LONG *)((unsigned char *)des_SP+0x300+u2); \
+ s1=(int)(t>>16L); \
+ s2=(int)(t>>24L); \
+ s1&=0xfc; \
+ s2&=0xfc; \
+ LL^= *(DES_LONG *)((unsigned char *)des_SP+0x500+s1); \
+ LL^= *(DES_LONG *)((unsigned char *)des_SP+0x700+s2); }
+#endif
+#else
+#define D_ENCRYPT(LL,R,S) { \
+ LOAD_DATA_tmp(R,S,u,t,E0,E1); \
+ t=ROTATE(t,4); \
+ LL^= \
+ *(DES_LONG *)((unsigned char *)des_SP +((u )&0xfc))^ \
+ *(DES_LONG *)((unsigned char *)des_SP+0x200+((u>> 8L)&0xfc))^ \
+ *(DES_LONG *)((unsigned char *)des_SP+0x400+((u>>16L)&0xfc))^ \
+ *(DES_LONG *)((unsigned char *)des_SP+0x600+((u>>24L)&0xfc))^ \
+ *(DES_LONG *)((unsigned char *)des_SP+0x100+((t )&0xfc))^ \
+ *(DES_LONG *)((unsigned char *)des_SP+0x300+((t>> 8L)&0xfc))^ \
+ *(DES_LONG *)((unsigned char *)des_SP+0x500+((t>>16L)&0xfc))^ \
+ *(DES_LONG *)((unsigned char *)des_SP+0x700+((t>>24L)&0xfc)); }
+#endif
+
+#else /* original version */
+
+#if defined(DES_RISC1) || defined(DES_RISC2)
+#ifdef DES_RISC1
+#define D_ENCRYPT(LL,R,S) {\
+ unsigned int u1,u2,u3; \
+ LOAD_DATA(R,S,u,t,E0,E1,u1); \
+ u>>=2L; \
+ t=ROTATE(t,6); \
+ u2=(int)u>>8L; \
+ u1=(int)u&0x3f; \
+ u2&=0x3f; \
+ u>>=16L; \
+ LL^=des_SPtrans[0][u1]; \
+ LL^=des_SPtrans[2][u2]; \
+ u3=(int)u>>8L; \
+ u1=(int)u&0x3f; \
+ u3&=0x3f; \
+ LL^=des_SPtrans[4][u1]; \
+ LL^=des_SPtrans[6][u3]; \
+ u2=(int)t>>8L; \
+ u1=(int)t&0x3f; \
+ u2&=0x3f; \
+ t>>=16L; \
+ LL^=des_SPtrans[1][u1]; \
+ LL^=des_SPtrans[3][u2]; \
+ u3=(int)t>>8L; \
+ u1=(int)t&0x3f; \
+ u3&=0x3f; \
+ LL^=des_SPtrans[5][u1]; \
+ LL^=des_SPtrans[7][u3]; }
+#endif
+#ifdef DES_RISC2
+#define D_ENCRYPT(LL,R,S) {\
+ unsigned int u1,u2,s1,s2; \
+ LOAD_DATA(R,S,u,t,E0,E1,u1); \
+ u>>=2L; \
+ t=ROTATE(t,6); \
+ u2=(int)u>>8L; \
+ u1=(int)u&0x3f; \
+ u2&=0x3f; \
+ LL^=des_SPtrans[0][u1]; \
+ LL^=des_SPtrans[2][u2]; \
+ s1=(int)u>>16L; \
+ s2=(int)u>>24L; \
+ s1&=0x3f; \
+ s2&=0x3f; \
+ LL^=des_SPtrans[4][s1]; \
+ LL^=des_SPtrans[6][s2]; \
+ u2=(int)t>>8L; \
+ u1=(int)t&0x3f; \
+ u2&=0x3f; \
+ LL^=des_SPtrans[1][u1]; \
+ LL^=des_SPtrans[3][u2]; \
+ s1=(int)t>>16; \
+ s2=(int)t>>24L; \
+ s1&=0x3f; \
+ s2&=0x3f; \
+ LL^=des_SPtrans[5][s1]; \
+ LL^=des_SPtrans[7][s2]; }
+#endif
+
+#else
+
+#define D_ENCRYPT(LL,R,S) {\
+ LOAD_DATA_tmp(R,S,u,t,E0,E1); \
+ t=ROTATE(t,4); \
+ LL^=\
+ des_SPtrans[0][(u>> 2L)&0x3f]^ \
+ des_SPtrans[2][(u>>10L)&0x3f]^ \
+ des_SPtrans[4][(u>>18L)&0x3f]^ \
+ des_SPtrans[6][(u>>26L)&0x3f]^ \
+ des_SPtrans[1][(t>> 2L)&0x3f]^ \
+ des_SPtrans[3][(t>>10L)&0x3f]^ \
+ des_SPtrans[5][(t>>18L)&0x3f]^ \
+ des_SPtrans[7][(t>>26L)&0x3f]; }
+#endif
+#endif
+
+ /* IP and FP
+ * The problem is more of a geometric problem that random bit fiddling.
+ 0 1 2 3 4 5 6 7 62 54 46 38 30 22 14 6
+ 8 9 10 11 12 13 14 15 60 52 44 36 28 20 12 4
+ 16 17 18 19 20 21 22 23 58 50 42 34 26 18 10 2
+ 24 25 26 27 28 29 30 31 to 56 48 40 32 24 16 8 0
+
+ 32 33 34 35 36 37 38 39 63 55 47 39 31 23 15 7
+ 40 41 42 43 44 45 46 47 61 53 45 37 29 21 13 5
+ 48 49 50 51 52 53 54 55 59 51 43 35 27 19 11 3
+ 56 57 58 59 60 61 62 63 57 49 41 33 25 17 9 1
+
+ The output has been subject to swaps of the form
+ 0 1 -> 3 1 but the odd and even bits have been put into
+ 2 3 2 0
+ different words. The main trick is to remember that
+ t=((l>>size)^r)&(mask);
+ r^=t;
+ l^=(t<<size);
+ can be used to swap and move bits between words.
+
+ So l = 0 1 2 3 r = 16 17 18 19
+ 4 5 6 7 20 21 22 23
+ 8 9 10 11 24 25 26 27
+ 12 13 14 15 28 29 30 31
+ becomes (for size == 2 and mask == 0x3333)
+ t = 2^16 3^17 -- -- l = 0 1 16 17 r = 2 3 18 19
+ 6^20 7^21 -- -- 4 5 20 21 6 7 22 23
+ 10^24 11^25 -- -- 8 9 24 25 10 11 24 25
+ 14^28 15^29 -- -- 12 13 28 29 14 15 28 29
+
+ Thanks for hints from Richard Outerbridge - he told me IP&FP
+ could be done in 15 xor, 10 shifts and 5 ands.
+ When I finally started to think of the problem in 2D
+ I first got ~42 operations without xors. When I remembered
+ how to use xors :-) I got it to its final state.
+ */
+#define PERM_OP(a,b,t,n,m) ((t)=((((a)>>(n))^(b))&(m)),\
+ (b)^=(t),\
+ (a)^=((t)<<(n)))
+
+#define IP(l,r) \
+{ \
+ register DES_LONG tt; \
+ PERM_OP(r,l,tt, 4,0x0f0f0f0fL); \
+ PERM_OP(l,r,tt,16,0x0000ffffL); \
+ PERM_OP(r,l,tt, 2,0x33333333L); \
+ PERM_OP(l,r,tt, 8,0x00ff00ffL); \
+ PERM_OP(r,l,tt, 1,0x55555555L); \
+}
+
+#define FP(l,r) \
+{ \
+ register DES_LONG tt; \
+ PERM_OP(l,r,tt, 1,0x55555555L); \
+ PERM_OP(r,l,tt, 8,0x00ff00ffL); \
+ PERM_OP(l,r,tt, 2,0x33333333L); \
+ PERM_OP(r,l,tt,16,0x0000ffffL); \
+ PERM_OP(l,r,tt, 4,0x0f0f0f0fL); \
+}
+
+#ifndef NOPROTO
+void fcrypt_body(DES_LONG *out,des_key_schedule ks,
+ DES_LONG Eswap0, DES_LONG Eswap1);
+#else
+void fcrypt_body();
+#endif
+
+static const DES_LONG des_skb[8][64]={
+ { /* for C bits (numbered as per FIPS 46) 1 2 3 4 5 6 */
+ 0x00000000L,0x00000010L,0x20000000L,0x20000010L,
+ 0x00010000L,0x00010010L,0x20010000L,0x20010010L,
+ 0x00000800L,0x00000810L,0x20000800L,0x20000810L,
+ 0x00010800L,0x00010810L,0x20010800L,0x20010810L,
+ 0x00000020L,0x00000030L,0x20000020L,0x20000030L,
+ 0x00010020L,0x00010030L,0x20010020L,0x20010030L,
+ 0x00000820L,0x00000830L,0x20000820L,0x20000830L,
+ 0x00010820L,0x00010830L,0x20010820L,0x20010830L,
+ 0x00080000L,0x00080010L,0x20080000L,0x20080010L,
+ 0x00090000L,0x00090010L,0x20090000L,0x20090010L,
+ 0x00080800L,0x00080810L,0x20080800L,0x20080810L,
+ 0x00090800L,0x00090810L,0x20090800L,0x20090810L,
+ 0x00080020L,0x00080030L,0x20080020L,0x20080030L,
+ 0x00090020L,0x00090030L,0x20090020L,0x20090030L,
+ 0x00080820L,0x00080830L,0x20080820L,0x20080830L,
+ 0x00090820L,0x00090830L,0x20090820L,0x20090830L,
+ },
+ { /* for C bits (numbered as per FIPS 46) 7 8 10 11 12 13 */
+ 0x00000000L,0x02000000L,0x00002000L,0x02002000L,
+ 0x00200000L,0x02200000L,0x00202000L,0x02202000L,
+ 0x00000004L,0x02000004L,0x00002004L,0x02002004L,
+ 0x00200004L,0x02200004L,0x00202004L,0x02202004L,
+ 0x00000400L,0x02000400L,0x00002400L,0x02002400L,
+ 0x00200400L,0x02200400L,0x00202400L,0x02202400L,
+ 0x00000404L,0x02000404L,0x00002404L,0x02002404L,
+ 0x00200404L,0x02200404L,0x00202404L,0x02202404L,
+ 0x10000000L,0x12000000L,0x10002000L,0x12002000L,
+ 0x10200000L,0x12200000L,0x10202000L,0x12202000L,
+ 0x10000004L,0x12000004L,0x10002004L,0x12002004L,
+ 0x10200004L,0x12200004L,0x10202004L,0x12202004L,
+ 0x10000400L,0x12000400L,0x10002400L,0x12002400L,
+ 0x10200400L,0x12200400L,0x10202400L,0x12202400L,
+ 0x10000404L,0x12000404L,0x10002404L,0x12002404L,
+ 0x10200404L,0x12200404L,0x10202404L,0x12202404L,
+ },
+ { /* for C bits (numbered as per FIPS 46) 14 15 16 17 19 20 */
+ 0x00000000L,0x00000001L,0x00040000L,0x00040001L,
+ 0x01000000L,0x01000001L,0x01040000L,0x01040001L,
+ 0x00000002L,0x00000003L,0x00040002L,0x00040003L,
+ 0x01000002L,0x01000003L,0x01040002L,0x01040003L,
+ 0x00000200L,0x00000201L,0x00040200L,0x00040201L,
+ 0x01000200L,0x01000201L,0x01040200L,0x01040201L,
+ 0x00000202L,0x00000203L,0x00040202L,0x00040203L,
+ 0x01000202L,0x01000203L,0x01040202L,0x01040203L,
+ 0x08000000L,0x08000001L,0x08040000L,0x08040001L,
+ 0x09000000L,0x09000001L,0x09040000L,0x09040001L,
+ 0x08000002L,0x08000003L,0x08040002L,0x08040003L,
+ 0x09000002L,0x09000003L,0x09040002L,0x09040003L,
+ 0x08000200L,0x08000201L,0x08040200L,0x08040201L,
+ 0x09000200L,0x09000201L,0x09040200L,0x09040201L,
+ 0x08000202L,0x08000203L,0x08040202L,0x08040203L,
+ 0x09000202L,0x09000203L,0x09040202L,0x09040203L,
+ },
+ { /* for C bits (numbered as per FIPS 46) 21 23 24 26 27 28 */
+ 0x00000000L,0x00100000L,0x00000100L,0x00100100L,
+ 0x00000008L,0x00100008L,0x00000108L,0x00100108L,
+ 0x00001000L,0x00101000L,0x00001100L,0x00101100L,
+ 0x00001008L,0x00101008L,0x00001108L,0x00101108L,
+ 0x04000000L,0x04100000L,0x04000100L,0x04100100L,
+ 0x04000008L,0x04100008L,0x04000108L,0x04100108L,
+ 0x04001000L,0x04101000L,0x04001100L,0x04101100L,
+ 0x04001008L,0x04101008L,0x04001108L,0x04101108L,
+ 0x00020000L,0x00120000L,0x00020100L,0x00120100L,
+ 0x00020008L,0x00120008L,0x00020108L,0x00120108L,
+ 0x00021000L,0x00121000L,0x00021100L,0x00121100L,
+ 0x00021008L,0x00121008L,0x00021108L,0x00121108L,
+ 0x04020000L,0x04120000L,0x04020100L,0x04120100L,
+ 0x04020008L,0x04120008L,0x04020108L,0x04120108L,
+ 0x04021000L,0x04121000L,0x04021100L,0x04121100L,
+ 0x04021008L,0x04121008L,0x04021108L,0x04121108L,
+ },
+ { /* for D bits (numbered as per FIPS 46) 1 2 3 4 5 6 */
+ 0x00000000L,0x10000000L,0x00010000L,0x10010000L,
+ 0x00000004L,0x10000004L,0x00010004L,0x10010004L,
+ 0x20000000L,0x30000000L,0x20010000L,0x30010000L,
+ 0x20000004L,0x30000004L,0x20010004L,0x30010004L,
+ 0x00100000L,0x10100000L,0x00110000L,0x10110000L,
+ 0x00100004L,0x10100004L,0x00110004L,0x10110004L,
+ 0x20100000L,0x30100000L,0x20110000L,0x30110000L,
+ 0x20100004L,0x30100004L,0x20110004L,0x30110004L,
+ 0x00001000L,0x10001000L,0x00011000L,0x10011000L,
+ 0x00001004L,0x10001004L,0x00011004L,0x10011004L,
+ 0x20001000L,0x30001000L,0x20011000L,0x30011000L,
+ 0x20001004L,0x30001004L,0x20011004L,0x30011004L,
+ 0x00101000L,0x10101000L,0x00111000L,0x10111000L,
+ 0x00101004L,0x10101004L,0x00111004L,0x10111004L,
+ 0x20101000L,0x30101000L,0x20111000L,0x30111000L,
+ 0x20101004L,0x30101004L,0x20111004L,0x30111004L,
+ },
+ { /* for D bits (numbered as per FIPS 46) 8 9 11 12 13 14 */
+ 0x00000000L,0x08000000L,0x00000008L,0x08000008L,
+ 0x00000400L,0x08000400L,0x00000408L,0x08000408L,
+ 0x00020000L,0x08020000L,0x00020008L,0x08020008L,
+ 0x00020400L,0x08020400L,0x00020408L,0x08020408L,
+ 0x00000001L,0x08000001L,0x00000009L,0x08000009L,
+ 0x00000401L,0x08000401L,0x00000409L,0x08000409L,
+ 0x00020001L,0x08020001L,0x00020009L,0x08020009L,
+ 0x00020401L,0x08020401L,0x00020409L,0x08020409L,
+ 0x02000000L,0x0A000000L,0x02000008L,0x0A000008L,
+ 0x02000400L,0x0A000400L,0x02000408L,0x0A000408L,
+ 0x02020000L,0x0A020000L,0x02020008L,0x0A020008L,
+ 0x02020400L,0x0A020400L,0x02020408L,0x0A020408L,
+ 0x02000001L,0x0A000001L,0x02000009L,0x0A000009L,
+ 0x02000401L,0x0A000401L,0x02000409L,0x0A000409L,
+ 0x02020001L,0x0A020001L,0x02020009L,0x0A020009L,
+ 0x02020401L,0x0A020401L,0x02020409L,0x0A020409L,
+ },
+ { /* for D bits (numbered as per FIPS 46) 16 17 18 19 20 21 */
+ 0x00000000L,0x00000100L,0x00080000L,0x00080100L,
+ 0x01000000L,0x01000100L,0x01080000L,0x01080100L,
+ 0x00000010L,0x00000110L,0x00080010L,0x00080110L,
+ 0x01000010L,0x01000110L,0x01080010L,0x01080110L,
+ 0x00200000L,0x00200100L,0x00280000L,0x00280100L,
+ 0x01200000L,0x01200100L,0x01280000L,0x01280100L,
+ 0x00200010L,0x00200110L,0x00280010L,0x00280110L,
+ 0x01200010L,0x01200110L,0x01280010L,0x01280110L,
+ 0x00000200L,0x00000300L,0x00080200L,0x00080300L,
+ 0x01000200L,0x01000300L,0x01080200L,0x01080300L,
+ 0x00000210L,0x00000310L,0x00080210L,0x00080310L,
+ 0x01000210L,0x01000310L,0x01080210L,0x01080310L,
+ 0x00200200L,0x00200300L,0x00280200L,0x00280300L,
+ 0x01200200L,0x01200300L,0x01280200L,0x01280300L,
+ 0x00200210L,0x00200310L,0x00280210L,0x00280310L,
+ 0x01200210L,0x01200310L,0x01280210L,0x01280310L,
+ },
+ { /* for D bits (numbered as per FIPS 46) 22 23 24 25 27 28 */
+ 0x00000000L,0x04000000L,0x00040000L,0x04040000L,
+ 0x00000002L,0x04000002L,0x00040002L,0x04040002L,
+ 0x00002000L,0x04002000L,0x00042000L,0x04042000L,
+ 0x00002002L,0x04002002L,0x00042002L,0x04042002L,
+ 0x00000020L,0x04000020L,0x00040020L,0x04040020L,
+ 0x00000022L,0x04000022L,0x00040022L,0x04040022L,
+ 0x00002020L,0x04002020L,0x00042020L,0x04042020L,
+ 0x00002022L,0x04002022L,0x00042022L,0x04042022L,
+ 0x00000800L,0x04000800L,0x00040800L,0x04040800L,
+ 0x00000802L,0x04000802L,0x00040802L,0x04040802L,
+ 0x00002800L,0x04002800L,0x00042800L,0x04042800L,
+ 0x00002802L,0x04002802L,0x00042802L,0x04042802L,
+ 0x00000820L,0x04000820L,0x00040820L,0x04040820L,
+ 0x00000822L,0x04000822L,0x00040822L,0x04040822L,
+ 0x00002820L,0x04002820L,0x00042820L,0x04042820L,
+ 0x00002822L,0x04002822L,0x00042822L,0x04042822L,
+ }
+};
+
+const DES_LONG des_SPtrans[8][64]={
+ {
+ /* nibble 0 */
+ 0x02080800L, 0x00080000L, 0x02000002L, 0x02080802L,
+ 0x02000000L, 0x00080802L, 0x00080002L, 0x02000002L,
+ 0x00080802L, 0x02080800L, 0x02080000L, 0x00000802L,
+ 0x02000802L, 0x02000000L, 0x00000000L, 0x00080002L,
+ 0x00080000L, 0x00000002L, 0x02000800L, 0x00080800L,
+ 0x02080802L, 0x02080000L, 0x00000802L, 0x02000800L,
+ 0x00000002L, 0x00000800L, 0x00080800L, 0x02080002L,
+ 0x00000800L, 0x02000802L, 0x02080002L, 0x00000000L,
+ 0x00000000L, 0x02080802L, 0x02000800L, 0x00080002L,
+ 0x02080800L, 0x00080000L, 0x00000802L, 0x02000800L,
+ 0x02080002L, 0x00000800L, 0x00080800L, 0x02000002L,
+ 0x00080802L, 0x00000002L, 0x02000002L, 0x02080000L,
+ 0x02080802L, 0x00080800L, 0x02080000L, 0x02000802L,
+ 0x02000000L, 0x00000802L, 0x00080002L, 0x00000000L,
+ 0x00080000L, 0x02000000L, 0x02000802L, 0x02080800L,
+ 0x00000002L, 0x02080002L, 0x00000800L, 0x00080802L,
+ },
+ { /* nibble 1 */
+ 0x40108010L, 0x00000000L, 0x00108000L, 0x40100000L,
+ 0x40000010L, 0x00008010L, 0x40008000L, 0x00108000L,
+ 0x00008000L, 0x40100010L, 0x00000010L, 0x40008000L,
+ 0x00100010L, 0x40108000L, 0x40100000L, 0x00000010L,
+ 0x00100000L, 0x40008010L, 0x40100010L, 0x00008000L,
+ 0x00108010L, 0x40000000L, 0x00000000L, 0x00100010L,
+ 0x40008010L, 0x00108010L, 0x40108000L, 0x40000010L,
+ 0x40000000L, 0x00100000L, 0x00008010L, 0x40108010L,
+ 0x00100010L, 0x40108000L, 0x40008000L, 0x00108010L,
+ 0x40108010L, 0x00100010L, 0x40000010L, 0x00000000L,
+ 0x40000000L, 0x00008010L, 0x00100000L, 0x40100010L,
+ 0x00008000L, 0x40000000L, 0x00108010L, 0x40008010L,
+ 0x40108000L, 0x00008000L, 0x00000000L, 0x40000010L,
+ 0x00000010L, 0x40108010L, 0x00108000L, 0x40100000L,
+ 0x40100010L, 0x00100000L, 0x00008010L, 0x40008000L,
+ 0x40008010L, 0x00000010L, 0x40100000L, 0x00108000L,
+ },
+ { /* nibble 2 */
+ 0x04000001L, 0x04040100L, 0x00000100L, 0x04000101L,
+ 0x00040001L, 0x04000000L, 0x04000101L, 0x00040100L,
+ 0x04000100L, 0x00040000L, 0x04040000L, 0x00000001L,
+ 0x04040101L, 0x00000101L, 0x00000001L, 0x04040001L,
+ 0x00000000L, 0x00040001L, 0x04040100L, 0x00000100L,
+ 0x00000101L, 0x04040101L, 0x00040000L, 0x04000001L,
+ 0x04040001L, 0x04000100L, 0x00040101L, 0x04040000L,
+ 0x00040100L, 0x00000000L, 0x04000000L, 0x00040101L,
+ 0x04040100L, 0x00000100L, 0x00000001L, 0x00040000L,
+ 0x00000101L, 0x00040001L, 0x04040000L, 0x04000101L,
+ 0x00000000L, 0x04040100L, 0x00040100L, 0x04040001L,
+ 0x00040001L, 0x04000000L, 0x04040101L, 0x00000001L,
+ 0x00040101L, 0x04000001L, 0x04000000L, 0x04040101L,
+ 0x00040000L, 0x04000100L, 0x04000101L, 0x00040100L,
+ 0x04000100L, 0x00000000L, 0x04040001L, 0x00000101L,
+ 0x04000001L, 0x00040101L, 0x00000100L, 0x04040000L,
+ },
+ { /* nibble 3 */
+ 0x00401008L, 0x10001000L, 0x00000008L, 0x10401008L,
+ 0x00000000L, 0x10400000L, 0x10001008L, 0x00400008L,
+ 0x10401000L, 0x10000008L, 0x10000000L, 0x00001008L,
+ 0x10000008L, 0x00401008L, 0x00400000L, 0x10000000L,
+ 0x10400008L, 0x00401000L, 0x00001000L, 0x00000008L,
+ 0x00401000L, 0x10001008L, 0x10400000L, 0x00001000L,
+ 0x00001008L, 0x00000000L, 0x00400008L, 0x10401000L,
+ 0x10001000L, 0x10400008L, 0x10401008L, 0x00400000L,
+ 0x10400008L, 0x00001008L, 0x00400000L, 0x10000008L,
+ 0x00401000L, 0x10001000L, 0x00000008L, 0x10400000L,
+ 0x10001008L, 0x00000000L, 0x00001000L, 0x00400008L,
+ 0x00000000L, 0x10400008L, 0x10401000L, 0x00001000L,
+ 0x10000000L, 0x10401008L, 0x00401008L, 0x00400000L,
+ 0x10401008L, 0x00000008L, 0x10001000L, 0x00401008L,
+ 0x00400008L, 0x00401000L, 0x10400000L, 0x10001008L,
+ 0x00001008L, 0x10000000L, 0x10000008L, 0x10401000L,
+ },
+ { /* nibble 4 */
+ 0x08000000L, 0x00010000L, 0x00000400L, 0x08010420L,
+ 0x08010020L, 0x08000400L, 0x00010420L, 0x08010000L,
+ 0x00010000L, 0x00000020L, 0x08000020L, 0x00010400L,
+ 0x08000420L, 0x08010020L, 0x08010400L, 0x00000000L,
+ 0x00010400L, 0x08000000L, 0x00010020L, 0x00000420L,
+ 0x08000400L, 0x00010420L, 0x00000000L, 0x08000020L,
+ 0x00000020L, 0x08000420L, 0x08010420L, 0x00010020L,
+ 0x08010000L, 0x00000400L, 0x00000420L, 0x08010400L,
+ 0x08010400L, 0x08000420L, 0x00010020L, 0x08010000L,
+ 0x00010000L, 0x00000020L, 0x08000020L, 0x08000400L,
+ 0x08000000L, 0x00010400L, 0x08010420L, 0x00000000L,
+ 0x00010420L, 0x08000000L, 0x00000400L, 0x00010020L,
+ 0x08000420L, 0x00000400L, 0x00000000L, 0x08010420L,
+ 0x08010020L, 0x08010400L, 0x00000420L, 0x00010000L,
+ 0x00010400L, 0x08010020L, 0x08000400L, 0x00000420L,
+ 0x00000020L, 0x00010420L, 0x08010000L, 0x08000020L,
+ },
+ { /* nibble 5 */
+ 0x80000040L, 0x00200040L, 0x00000000L, 0x80202000L,
+ 0x00200040L, 0x00002000L, 0x80002040L, 0x00200000L,
+ 0x00002040L, 0x80202040L, 0x00202000L, 0x80000000L,
+ 0x80002000L, 0x80000040L, 0x80200000L, 0x00202040L,
+ 0x00200000L, 0x80002040L, 0x80200040L, 0x00000000L,
+ 0x00002000L, 0x00000040L, 0x80202000L, 0x80200040L,
+ 0x80202040L, 0x80200000L, 0x80000000L, 0x00002040L,
+ 0x00000040L, 0x00202000L, 0x00202040L, 0x80002000L,
+ 0x00002040L, 0x80000000L, 0x80002000L, 0x00202040L,
+ 0x80202000L, 0x00200040L, 0x00000000L, 0x80002000L,
+ 0x80000000L, 0x00002000L, 0x80200040L, 0x00200000L,
+ 0x00200040L, 0x80202040L, 0x00202000L, 0x00000040L,
+ 0x80202040L, 0x00202000L, 0x00200000L, 0x80002040L,
+ 0x80000040L, 0x80200000L, 0x00202040L, 0x00000000L,
+ 0x00002000L, 0x80000040L, 0x80002040L, 0x80202000L,
+ 0x80200000L, 0x00002040L, 0x00000040L, 0x80200040L,
+ },
+ { /* nibble 6 */
+ 0x00004000L, 0x00000200L, 0x01000200L, 0x01000004L,
+ 0x01004204L, 0x00004004L, 0x00004200L, 0x00000000L,
+ 0x01000000L, 0x01000204L, 0x00000204L, 0x01004000L,
+ 0x00000004L, 0x01004200L, 0x01004000L, 0x00000204L,
+ 0x01000204L, 0x00004000L, 0x00004004L, 0x01004204L,
+ 0x00000000L, 0x01000200L, 0x01000004L, 0x00004200L,
+ 0x01004004L, 0x00004204L, 0x01004200L, 0x00000004L,
+ 0x00004204L, 0x01004004L, 0x00000200L, 0x01000000L,
+ 0x00004204L, 0x01004000L, 0x01004004L, 0x00000204L,
+ 0x00004000L, 0x00000200L, 0x01000000L, 0x01004004L,
+ 0x01000204L, 0x00004204L, 0x00004200L, 0x00000000L,
+ 0x00000200L, 0x01000004L, 0x00000004L, 0x01000200L,
+ 0x00000000L, 0x01000204L, 0x01000200L, 0x00004200L,
+ 0x00000204L, 0x00004000L, 0x01004204L, 0x01000000L,
+ 0x01004200L, 0x00000004L, 0x00004004L, 0x01004204L,
+ 0x01000004L, 0x01004200L, 0x01004000L, 0x00004004L,
+ },
+ { /* nibble 7 */
+ 0x20800080L, 0x20820000L, 0x00020080L, 0x00000000L,
+ 0x20020000L, 0x00800080L, 0x20800000L, 0x20820080L,
+ 0x00000080L, 0x20000000L, 0x00820000L, 0x00020080L,
+ 0x00820080L, 0x20020080L, 0x20000080L, 0x20800000L,
+ 0x00020000L, 0x00820080L, 0x00800080L, 0x20020000L,
+ 0x20820080L, 0x20000080L, 0x00000000L, 0x00820000L,
+ 0x20000000L, 0x00800000L, 0x20020080L, 0x20800080L,
+ 0x00800000L, 0x00020000L, 0x20820000L, 0x00000080L,
+ 0x00800000L, 0x00020000L, 0x20000080L, 0x20820080L,
+ 0x00020080L, 0x20000000L, 0x00000000L, 0x00820000L,
+ 0x20800080L, 0x20020080L, 0x20020000L, 0x00800080L,
+ 0x20820000L, 0x00000080L, 0x00800080L, 0x20020000L,
+ 0x20820080L, 0x00800000L, 0x20800000L, 0x20000080L,
+ 0x00820000L, 0x00020080L, 0x20020080L, 0x20800000L,
+ 0x00000080L, 0x20820000L, 0x00820080L, 0x00000000L,
+ 0x20000000L, 0x20800080L, 0x00020000L, 0x00820080L,
+ }
+};
+
+#define HPERM_OP(a,t,n,m) ((t)=((((a)<<(16-(n)))^(a))&(m)),\
+ (a)=(a)^(t)^(t>>(16-(n))))
+
+static const unsigned char odd_parity[256]={
+ 1, 1, 2, 2, 4, 4, 7, 7, 8, 8, 11, 11, 13, 13, 14, 14,
+ 16, 16, 19, 19, 21, 21, 22, 22, 25, 25, 26, 26, 28, 28, 31, 31,
+ 32, 32, 35, 35, 37, 37, 38, 38, 41, 41, 42, 42, 44, 44, 47, 47,
+ 49, 49, 50, 50, 52, 52, 55, 55, 56, 56, 59, 59, 61, 61, 62, 62,
+ 64, 64, 67, 67, 69, 69, 70, 70, 73, 73, 74, 74, 76, 76, 79, 79,
+ 81, 81, 82, 82, 84, 84, 87, 87, 88, 88, 91, 91, 93, 93, 94, 94,
+ 97, 97, 98, 98,100,100,103,103,104,104,107,107,109,109,110,110,
+ 112,112,115,115,117,117,118,118,121,121,122,122,124,124,127,127,
+ 128,128,131,131,133,133,134,134,137,137,138,138,140,140,143,143,
+ 145,145,146,146,148,148,151,151,152,152,155,155,157,157,158,158,
+ 161,161,162,162,164,164,167,167,168,168,171,171,173,173,174,174,
+ 176,176,179,179,181,181,182,182,185,185,186,186,188,188,191,191,
+ 193,193,194,194,196,196,199,199,200,200,203,203,205,205,206,206,
+ 208,208,211,211,213,213,214,214,217,217,218,218,220,220,223,223,
+ 224,224,227,227,229,229,230,230,233,233,234,234,236,236,239,239,
+ 241,241,242,242,244,244,247,247,248,248,251,251,253,253,254,254
+};
+
+/**
+ * Create key schedule for a single DES 64Bit key
+ */
+static int des_set_key(des_cblock *key, des_key_schedule *schedule)
+{
+ static int shifts2[16] = {0,0,1,1,1,1,1,1,0,1,1,1,1,1,1,0};
+ register DES_LONG c,d,t,s,t2;
+ register unsigned char *in;
+ register DES_LONG *k;
+ register int i;
+ des_cblock odd;
+
+ for (i = 0; i < sizeof(des_cblock); i++)
+ {
+ odd[i] = odd_parity[(*key)[i]];
+ }
+
+ k=(DES_LONG *)schedule;
+ in=(unsigned char *)&odd;
+
+ c2l(in,c);
+ c2l(in,d);
+
+ /* do PC1 in 60 simple operations */
+/* PERM_OP(d,c,t,4,0x0f0f0f0fL);
+ HPERM_OP(c,t,-2, 0xcccc0000L);
+ HPERM_OP(c,t,-1, 0xaaaa0000L);
+ HPERM_OP(c,t, 8, 0x00ff0000L);
+ HPERM_OP(c,t,-1, 0xaaaa0000L);
+ HPERM_OP(d,t,-8, 0xff000000L);
+ HPERM_OP(d,t, 8, 0x00ff0000L);
+ HPERM_OP(d,t, 2, 0x33330000L);
+ d=((d&0x00aa00aaL)<<7L)|((d&0x55005500L)>>7L)|(d&0xaa55aa55L);
+ d=(d>>8)|((c&0xf0000000L)>>4);
+ c&=0x0fffffffL; */
+
+ /* I now do it in 47 simple operations :-)
+ * Thanks to John Fletcher (john_fletcher@lccmail.ocf.llnl.gov)
+ * for the inspiration. :-) */
+ PERM_OP (d,c,t,4,0x0f0f0f0fL);
+ HPERM_OP(c,t,-2,0xcccc0000L);
+ HPERM_OP(d,t,-2,0xcccc0000L);
+ PERM_OP (d,c,t,1,0x55555555L);
+ PERM_OP (c,d,t,8,0x00ff00ffL);
+ PERM_OP (d,c,t,1,0x55555555L);
+ d= (((d&0x000000ffL)<<16L)| (d&0x0000ff00L) |
+ ((d&0x00ff0000L)>>16L)|((c&0xf0000000L)>>4L));
+ c&=0x0fffffffL;
+
+ for (i=0; i<ITERATIONS; i++)
+ {
+ if (shifts2[i])
+ { c=((c>>2L)|(c<<26L)); d=((d>>2L)|(d<<26L)); }
+ else
+ { c=((c>>1L)|(c<<27L)); d=((d>>1L)|(d<<27L)); }
+ c&=0x0fffffffL;
+ d&=0x0fffffffL;
+ /* could be a few less shifts but I am to lazy at this
+ * point in time to investigate */
+ s= des_skb[0][ (c )&0x3f ]|
+ des_skb[1][((c>> 6)&0x03)|((c>> 7L)&0x3c)]|
+ des_skb[2][((c>>13)&0x0f)|((c>>14L)&0x30)]|
+ des_skb[3][((c>>20)&0x01)|((c>>21L)&0x06) |
+ ((c>>22L)&0x38)];
+ t= des_skb[4][ (d )&0x3f ]|
+ des_skb[5][((d>> 7L)&0x03)|((d>> 8L)&0x3c)]|
+ des_skb[6][ (d>>15L)&0x3f ]|
+ des_skb[7][((d>>21L)&0x0f)|((d>>22L)&0x30)];
+
+ /* table contained 0213 4657 */
+ t2=((t<<16L)|(s&0x0000ffffL))&0xffffffffL;
+ *(k++)=ROTATE(t2,30)&0xffffffffL;
+
+ t2=((s>>16L)|(t&0xffff0000L));
+ *(k++)=ROTATE(t2,26)&0xffffffffL;
+ }
+ return(0);
+}
+
+
+static void des_encrypt(DES_LONG *data, des_key_schedule ks, int enc)
+{
+ register DES_LONG l,r,t,u;
+#ifdef DES_PTR
+ register unsigned char *des_SP=(unsigned char *)des_SPtrans;
+#endif
+#ifndef DES_UNROLL
+ register int i;
+#endif
+ register DES_LONG *s;
+
+ r=data[0];
+ l=data[1];
+
+ IP(r,l);
+ /* Things have been modified so that the initial rotate is
+ * done outside the loop. This required the
+ * des_SPtrans values in sp.h to be rotated 1 bit to the right.
+ * One perl script later and things have a 5% speed up on a sparc2.
+ * Thanks to Richard Outerbridge <71755.204@CompuServe.COM>
+ * for pointing this out. */
+ /* clear the top bits on machines with 8byte longs */
+ /* shift left by 2 */
+ r=ROTATE(r,29)&0xffffffffL;
+ l=ROTATE(l,29)&0xffffffffL;
+
+ s=(DES_LONG *)ks;
+ /* I don't know if it is worth the effort of loop unrolling the
+ * inner loop */
+ if (enc)
+ {
+#ifdef DES_UNROLL
+ D_ENCRYPT(l,r, 0); /* 1 */
+ D_ENCRYPT(r,l, 2); /* 2 */
+ D_ENCRYPT(l,r, 4); /* 3 */
+ D_ENCRYPT(r,l, 6); /* 4 */
+ D_ENCRYPT(l,r, 8); /* 5 */
+ D_ENCRYPT(r,l,10); /* 6 */
+ D_ENCRYPT(l,r,12); /* 7 */
+ D_ENCRYPT(r,l,14); /* 8 */
+ D_ENCRYPT(l,r,16); /* 9 */
+ D_ENCRYPT(r,l,18); /* 10 */
+ D_ENCRYPT(l,r,20); /* 11 */
+ D_ENCRYPT(r,l,22); /* 12 */
+ D_ENCRYPT(l,r,24); /* 13 */
+ D_ENCRYPT(r,l,26); /* 14 */
+ D_ENCRYPT(l,r,28); /* 15 */
+ D_ENCRYPT(r,l,30); /* 16 */
+#else
+ for (i=0; i<32; i+=8)
+{
+ D_ENCRYPT(l,r,i+0); /* 1 */
+ D_ENCRYPT(r,l,i+2); /* 2 */
+ D_ENCRYPT(l,r,i+4); /* 3 */
+ D_ENCRYPT(r,l,i+6); /* 4 */
+}
+#endif
+ }
+ else
+{
+#ifdef DES_UNROLL
+ D_ENCRYPT(l,r,30); /* 16 */
+ D_ENCRYPT(r,l,28); /* 15 */
+ D_ENCRYPT(l,r,26); /* 14 */
+ D_ENCRYPT(r,l,24); /* 13 */
+ D_ENCRYPT(l,r,22); /* 12 */
+ D_ENCRYPT(r,l,20); /* 11 */
+ D_ENCRYPT(l,r,18); /* 10 */
+ D_ENCRYPT(r,l,16); /* 9 */
+ D_ENCRYPT(l,r,14); /* 8 */
+ D_ENCRYPT(r,l,12); /* 7 */
+ D_ENCRYPT(l,r,10); /* 6 */
+ D_ENCRYPT(r,l, 8); /* 5 */
+ D_ENCRYPT(l,r, 6); /* 4 */
+ D_ENCRYPT(r,l, 4); /* 3 */
+ D_ENCRYPT(l,r, 2); /* 2 */
+ D_ENCRYPT(r,l, 0); /* 1 */
+#else
+ for (i=30; i>0; i-=8)
+{
+ D_ENCRYPT(l,r,i-0); /* 16 */
+ D_ENCRYPT(r,l,i-2); /* 15 */
+ D_ENCRYPT(l,r,i-4); /* 14 */
+ D_ENCRYPT(r,l,i-6); /* 13 */
+}
+#endif
+}
+
+ /* rotate and clear the top bits on machines with 8byte longs */
+ l=ROTATE(l,3)&0xffffffffL;
+ r=ROTATE(r,3)&0xffffffffL;
+
+ FP(r,l);
+ data[0]=l;
+ data[1]=r;
+ l=r=t=u=0;
+}
+
+/**
+ * DES CBC encrypt decrypt routine
+ */
+static void des_cbc_encrypt(des_cblock *input, des_cblock *output, long length,
+ des_key_schedule schedule, des_cblock *ivec, int enc)
+{
+ register DES_LONG tin0,tin1;
+ register DES_LONG tout0,tout1,xor0,xor1;
+ register unsigned char *in,*out;
+ register long l=length;
+ DES_LONG tin[2];
+ unsigned char *iv;
+
+ in=(unsigned char *)input;
+ out=(unsigned char *)output;
+ iv=(unsigned char *)ivec;
+
+ if (enc)
+ {
+ c2l(iv,tout0);
+ c2l(iv,tout1);
+ for (l-=8; l>=0; l-=8)
+ {
+ c2l(in,tin0);
+ c2l(in,tin1);
+ tin0^=tout0; tin[0]=tin0;
+ tin1^=tout1; tin[1]=tin1;
+ des_encrypt((DES_LONG *)tin,schedule,DES_ENCRYPT);
+ tout0=tin[0]; l2c(tout0,out);
+ tout1=tin[1]; l2c(tout1,out);
+ }
+ if (l != -8)
+ {
+ c2ln(in,tin0,tin1,l+8);
+ tin0^=tout0; tin[0]=tin0;
+ tin1^=tout1; tin[1]=tin1;
+ des_encrypt((DES_LONG *)tin,schedule,DES_ENCRYPT);
+ tout0=tin[0]; l2c(tout0,out);
+ tout1=tin[1]; l2c(tout1,out);
+ }
+ }
+ else
+ {
+ c2l(iv,xor0);
+ c2l(iv,xor1);
+ for (l-=8; l>=0; l-=8)
+ {
+ c2l(in,tin0); tin[0]=tin0;
+ c2l(in,tin1); tin[1]=tin1;
+ des_encrypt((DES_LONG *)tin,schedule,DES_DECRYPT);
+ tout0=tin[0]^xor0;
+ tout1=tin[1]^xor1;
+ l2c(tout0,out);
+ l2c(tout1,out);
+ xor0=tin0;
+ xor1=tin1;
+ }
+ if (l != -8)
+ {
+ c2l(in,tin0); tin[0]=tin0;
+ c2l(in,tin1); tin[1]=tin1;
+ des_encrypt((DES_LONG *)tin,schedule,DES_DECRYPT);
+ tout0=tin[0]^xor0;
+ tout1=tin[1]^xor1;
+ l2cn(tout0,tout1,out,l+8);
+ /* xor0=tin0;
+ xor1=tin1; */
+ }
+ }
+ tin0=tin1=tout0=tout1=xor0=xor1=0;
+ tin[0]=tin[1]=0;
+}
+
+static void des_encrypt2(DES_LONG *data, des_key_schedule ks, int enc)
+{
+ register DES_LONG l,r,t,u;
+#ifdef DES_PTR
+ register unsigned char *des_SP=(unsigned char *)des_SPtrans;
+#endif
+#ifndef DES_UNROLL
+ register int i;
+#endif
+ register DES_LONG *s;
+
+ r=data[0];
+ l=data[1];
+
+ /* Things have been modified so that the initial rotate is
+ * done outside the loop. This required the
+ * des_SPtrans values in sp.h to be rotated 1 bit to the right.
+ * One perl script later and things have a 5% speed up on a sparc2.
+ * Thanks to Richard Outerbridge <71755.204@CompuServe.COM>
+ * for pointing this out.
+ * clear the top bits on machines with 8byte longs */
+ r=ROTATE(r,29)&0xffffffffL;
+ l=ROTATE(l,29)&0xffffffffL;
+
+ s=(DES_LONG *)ks;
+ /* I don't know if it is worth the effort of loop unrolling the
+ * inner loop */
+ if (enc)
+ {
+#ifdef DES_UNROLL
+ D_ENCRYPT(l,r, 0); /* 1 */
+ D_ENCRYPT(r,l, 2); /* 2 */
+ D_ENCRYPT(l,r, 4); /* 3 */
+ D_ENCRYPT(r,l, 6); /* 4 */
+ D_ENCRYPT(l,r, 8); /* 5 */
+ D_ENCRYPT(r,l,10); /* 6 */
+ D_ENCRYPT(l,r,12); /* 7 */
+ D_ENCRYPT(r,l,14); /* 8 */
+ D_ENCRYPT(l,r,16); /* 9 */
+ D_ENCRYPT(r,l,18); /* 10 */
+ D_ENCRYPT(l,r,20); /* 11 */
+ D_ENCRYPT(r,l,22); /* 12 */
+ D_ENCRYPT(l,r,24); /* 13 */
+ D_ENCRYPT(r,l,26); /* 14 */
+ D_ENCRYPT(l,r,28); /* 15 */
+ D_ENCRYPT(r,l,30); /* 16 */
+#else
+ for (i=0; i<32; i+=8)
+{
+ D_ENCRYPT(l,r,i+0); /* 1 */
+ D_ENCRYPT(r,l,i+2); /* 2 */
+ D_ENCRYPT(l,r,i+4); /* 3 */
+ D_ENCRYPT(r,l,i+6); /* 4 */
+}
+#endif
+ }
+ else
+{
+#ifdef DES_UNROLL
+ D_ENCRYPT(l,r,30); /* 16 */
+ D_ENCRYPT(r,l,28); /* 15 */
+ D_ENCRYPT(l,r,26); /* 14 */
+ D_ENCRYPT(r,l,24); /* 13 */
+ D_ENCRYPT(l,r,22); /* 12 */
+ D_ENCRYPT(r,l,20); /* 11 */
+ D_ENCRYPT(l,r,18); /* 10 */
+ D_ENCRYPT(r,l,16); /* 9 */
+ D_ENCRYPT(l,r,14); /* 8 */
+ D_ENCRYPT(r,l,12); /* 7 */
+ D_ENCRYPT(l,r,10); /* 6 */
+ D_ENCRYPT(r,l, 8); /* 5 */
+ D_ENCRYPT(l,r, 6); /* 4 */
+ D_ENCRYPT(r,l, 4); /* 3 */
+ D_ENCRYPT(l,r, 2); /* 2 */
+ D_ENCRYPT(r,l, 0); /* 1 */
+#else
+ for (i=30; i>0; i-=8)
+{
+ D_ENCRYPT(l,r,i-0); /* 16 */
+ D_ENCRYPT(r,l,i-2); /* 15 */
+ D_ENCRYPT(l,r,i-4); /* 14 */
+ D_ENCRYPT(r,l,i-6); /* 13 */
+}
+#endif
+}
+ /* rotate and clear the top bits on machines with 8byte longs */
+ data[0]=ROTATE(l,3)&0xffffffffL;
+ data[1]=ROTATE(r,3)&0xffffffffL;
+ l=r=t=u=0;
+}
+
+/**
+ * Single block 3DES EDE encrypt routine
+ */
+static void des_encrypt3(DES_LONG *data, des_key_schedule ks1,
+ des_key_schedule ks2, des_key_schedule ks3)
+{
+ register DES_LONG l,r;
+
+ l=data[0];
+ r=data[1];
+ IP(l,r);
+ data[0]=l;
+ data[1]=r;
+ des_encrypt2((DES_LONG *)data,ks1,DES_ENCRYPT);
+ des_encrypt2((DES_LONG *)data,ks2,DES_DECRYPT);
+ des_encrypt2((DES_LONG *)data,ks3,DES_ENCRYPT);
+ l=data[0];
+ r=data[1];
+ FP(r,l);
+ data[0]=l;
+ data[1]=r;
+}
+
+/**
+ * Single block 3DES EDE decrypt routine
+ */
+static void des_decrypt3(DES_LONG *data, des_key_schedule ks1,
+ des_key_schedule ks2, des_key_schedule ks3)
+{
+ register DES_LONG l,r;
+
+ l=data[0];
+ r=data[1];
+ IP(l,r);
+ data[0]=l;
+ data[1]=r;
+ des_encrypt2((DES_LONG *)data,ks3,DES_DECRYPT);
+ des_encrypt2((DES_LONG *)data,ks2,DES_ENCRYPT);
+ des_encrypt2((DES_LONG *)data,ks1,DES_DECRYPT);
+ l=data[0];
+ r=data[1];
+ FP(r,l);
+ data[0]=l;
+ data[1]=r;
+}
+
+/**
+ * 3DES EDE CBC encrypt/decrypt routine
+ */
+static void des_ede3_cbc_encrypt(des_cblock *input, des_cblock *output, long length,
+ des_key_schedule ks1, des_key_schedule ks2,
+ des_key_schedule ks3, des_cblock *ivec, int enc)
+{
+ register DES_LONG tin0,tin1;
+ register DES_LONG tout0,tout1,xor0,xor1;
+ register unsigned char *in,*out;
+ register long l=length;
+ DES_LONG tin[2];
+ unsigned char *iv;
+
+ in=(unsigned char *)input;
+ out=(unsigned char *)output;
+ iv=(unsigned char *)ivec;
+
+ if (enc)
+ {
+ c2l(iv,tout0);
+ c2l(iv,tout1);
+ for (l-=8; l>=0; l-=8)
+ {
+ c2l(in,tin0);
+ c2l(in,tin1);
+ tin0^=tout0;
+ tin1^=tout1;
+
+ tin[0]=tin0;
+ tin[1]=tin1;
+ des_encrypt3((DES_LONG *)tin,ks1,ks2,ks3);
+ tout0=tin[0];
+ tout1=tin[1];
+
+ l2c(tout0,out);
+ l2c(tout1,out);
+ }
+ if (l != -8)
+ {
+ c2ln(in,tin0,tin1,l+8);
+ tin0^=tout0;
+ tin1^=tout1;
+
+ tin[0]=tin0;
+ tin[1]=tin1;
+ des_encrypt3((DES_LONG *)tin,ks1,ks2,ks3);
+ tout0=tin[0];
+ tout1=tin[1];
+
+ l2c(tout0,out);
+ l2c(tout1,out);
+ }
+ iv=(unsigned char *)ivec;
+ l2c(tout0,iv);
+ l2c(tout1,iv);
+ }
+ else
+ {
+ register DES_LONG t0,t1;
+
+ c2l(iv,xor0);
+ c2l(iv,xor1);
+ for (l-=8; l>=0; l-=8)
+ {
+ c2l(in,tin0);
+ c2l(in,tin1);
+
+ t0=tin0;
+ t1=tin1;
+
+ tin[0]=tin0;
+ tin[1]=tin1;
+ des_decrypt3((DES_LONG *)tin,ks1,ks2,ks3);
+ tout0=tin[0];
+ tout1=tin[1];
+
+ tout0^=xor0;
+ tout1^=xor1;
+ l2c(tout0,out);
+ l2c(tout1,out);
+ xor0=t0;
+ xor1=t1;
+ }
+ if (l != -8)
+ {
+ c2l(in,tin0);
+ c2l(in,tin1);
+
+ t0=tin0;
+ t1=tin1;
+
+ tin[0]=tin0;
+ tin[1]=tin1;
+ des_decrypt3((DES_LONG *)tin,ks1,ks2,ks3);
+ tout0=tin[0];
+ tout1=tin[1];
+
+ tout0^=xor0;
+ tout1^=xor1;
+ l2cn(tout0,tout1,out,l+8);
+ xor0=t0;
+ xor1=t1;
+ }
+
+ iv=(unsigned char *)ivec;
+ l2c(xor0,iv);
+ l2c(xor1,iv);
+ }
+ tin0=tin1=tout0=tout1=xor0=xor1=0;
+ tin[0]=tin[1]=0;
+}
+
+/**
+ * Implementation of crypter_t.decrypt for DES.
+ */
+static void decrypt(private_des_crypter_t *this, chunk_t data, chunk_t iv,
+ chunk_t *decrypted)
+{
+ des_cblock ivb;
+ u_int8_t *out;
+
+ out = data.ptr;
+ if (decrypted)
+ {
+ *decrypted = chunk_alloc(data.len);
+ out = decrypted->ptr;
+ }
+ memcpy(&ivb, iv.ptr, sizeof(des_cblock));
+ des_cbc_encrypt((des_cblock*)(data.ptr), (des_cblock*)out,
+ data.len, this->ks, &ivb, DES_DECRYPT);
+}
+
+
+/**
+ * Implementation of crypter_t.decrypt for DES.
+ */
+static void encrypt(private_des_crypter_t *this, chunk_t data, chunk_t iv,
+ chunk_t *encrypted)
+{
+ des_cblock ivb;
+ u_int8_t *out;
+
+ out = data.ptr;
+ if (encrypted)
+ {
+ *encrypted = chunk_alloc(data.len);
+ out = encrypted->ptr;
+ }
+ memcpy(&ivb, iv.ptr, sizeof(des_cblock));
+ des_cbc_encrypt((des_cblock*)(data.ptr), (des_cblock*)out,
+ data.len, this->ks, &ivb, DES_ENCRYPT);
+}
+
+/**
+ * Implementation of crypter_t.decrypt for 3DES.
+ */
+static void decrypt3(private_des_crypter_t *this, chunk_t data, chunk_t iv,
+ chunk_t *decrypted)
+{
+ des_cblock ivb;
+ u_int8_t *out;
+
+ out = data.ptr;
+ if (decrypted)
+ {
+ *decrypted = chunk_alloc(data.len);
+ out = decrypted->ptr;
+ }
+ memcpy(&ivb, iv.ptr, sizeof(des_cblock));
+ des_ede3_cbc_encrypt((des_cblock*)(data.ptr), (des_cblock*)out,
+ data.len, this->ks3[0], this->ks3[1], this->ks3[2],
+ &ivb, DES_DECRYPT);
+}
+
+/**
+ * Implementation of crypter_t.decrypt for 3DES.
+ */
+static void encrypt3(private_des_crypter_t *this, chunk_t data, chunk_t iv,
+ chunk_t *encrypted)
+{
+ des_cblock ivb;
+ u_int8_t *out;
+
+ out = data.ptr;
+ if (encrypted)
+ {
+ *encrypted = chunk_alloc(data.len);
+ out = encrypted->ptr;
+ }
+ memcpy(&ivb, iv.ptr, sizeof(des_cblock));
+ des_ede3_cbc_encrypt((des_cblock*)(data.ptr), (des_cblock*)out,
+ data.len, this->ks3[0], this->ks3[1], this->ks3[2],
+ &ivb, DES_ENCRYPT);
+}
+
+/**
+ * Implementation of crypter_t.get_block_size.
+ */
+static size_t get_block_size (private_des_crypter_t *this)
+{
+ return sizeof(des_cblock);
+}
+
+/**
+ * Implementation of crypter_t.get_key_size.
+ */
+static size_t get_key_size (private_des_crypter_t *this)
+{
+ return this->key_size;
+}
+
+/**
+ * Implementation of crypter_t.set_key for DES.
+ */
+static void set_key(private_des_crypter_t *this, chunk_t key)
+{
+ des_set_key((des_cblock*)(key.ptr), &this->ks);
+}
+
+/**
+ * Implementation of crypter_t.set_key for 3DES.
+ */
+static void set_key3(private_des_crypter_t *this, chunk_t key)
+{
+ des_set_key((des_cblock*)(key.ptr) + 0, &this->ks3[0]);
+ des_set_key((des_cblock*)(key.ptr) + 1, &this->ks3[1]);
+ des_set_key((des_cblock*)(key.ptr) + 2, &this->ks3[2]);
+}
+
+/**
+ * Implementation of crypter_t.destroy and des_crypter_t.destroy.
+ */
+static void destroy(private_des_crypter_t *this)
+{
+ free(this);
+}
+
+/*
+ * Described in header
+ */
+des_crypter_t *des_crypter_create(encryption_algorithm_t algo)
+{
+ private_des_crypter_t *this = malloc_thing(private_des_crypter_t);
+
+ /* functions of crypter_t interface */
+ this->public.crypter_interface.get_block_size = (size_t (*) (crypter_t *)) get_block_size;
+ this->public.crypter_interface.get_key_size = (size_t (*) (crypter_t *)) get_key_size;
+ this->public.crypter_interface.destroy = (void (*) (crypter_t *)) destroy;
+
+ /* use functions depending on algorithm */
+ switch (algo)
+ {
+ case ENCR_DES:
+ this->key_size = sizeof(des_cblock);
+ this->public.crypter_interface.set_key = (void (*) (crypter_t *,chunk_t)) set_key;
+ this->public.crypter_interface.encrypt = (void (*) (crypter_t *, chunk_t,chunk_t, chunk_t *)) encrypt;
+ this->public.crypter_interface.decrypt = (void (*) (crypter_t *, chunk_t , chunk_t, chunk_t *)) decrypt;
+ break;
+ case ENCR_3DES:
+ this->key_size = 3 * sizeof(des_cblock);
+ this->public.crypter_interface.set_key = (void (*) (crypter_t *,chunk_t)) set_key3;
+ this->public.crypter_interface.encrypt = (void (*) (crypter_t *, chunk_t,chunk_t, chunk_t *)) encrypt3;
+ this->public.crypter_interface.decrypt = (void (*) (crypter_t *, chunk_t , chunk_t, chunk_t *)) decrypt3;
+ break;
+ default:
+ free(this);
+ return NULL;
+ }
+ return &this->public;
+}
diff --git a/src/libstrongswan/plugins/des/des_crypter.h b/src/libstrongswan/plugins/des/des_crypter.h
new file mode 100644
index 000000000..d40d9cf2f
--- /dev/null
+++ b/src/libstrongswan/plugins/des/des_crypter.h
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2006-2008 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.
+ */
+
+/**
+ * @defgroup des_crypter des_crypter
+ * @{ @ingroup des_p
+ */
+
+#ifndef DES_CRYPTER_H_
+#define DES_CRYPTER_H_
+
+typedef struct des_crypter_t des_crypter_t;
+
+#include <crypto/crypters/crypter.h>
+
+
+/**
+ * Class implementing the DES and 3DES encryption algorithms.
+ */
+struct des_crypter_t {
+
+ /**
+ * The crypter_t interface.
+ */
+ crypter_t crypter_interface;
+};
+
+/**
+ * Constructor to create des_crypter_t objects.
+ *
+ * @param algo ENCR_DES for single DES, ENCR_3DES for triple DES
+ * @return des_crypter_t object, NULL if algo not supported
+ */
+des_crypter_t *des_crypter_create(encryption_algorithm_t algo);
+
+
+#endif /* DES_CRYPTER_H_ @}*/
diff --git a/src/libstrongswan/plugins/des/des_plugin.c b/src/libstrongswan/plugins/des/des_plugin.c
new file mode 100644
index 000000000..c32096ad0
--- /dev/null
+++ b/src/libstrongswan/plugins/des/des_plugin.c
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2008 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.
+ *
+ * $Id: des_plugin.c 3488 2008-02-21 15:10:02Z martin $
+ */
+
+#include "des_plugin.h"
+
+#include <library.h>
+#include "des_crypter.h"
+
+typedef struct private_des_plugin_t private_des_plugin_t;
+
+/**
+ * private data of des_plugin
+ */
+struct private_des_plugin_t {
+
+ /**
+ * public functions
+ */
+ des_plugin_t public;
+};
+
+/**
+ * Implementation of des_plugin_t.destroy
+ */
+static void destroy(private_des_plugin_t *this)
+{
+ lib->crypto->remove_crypter(lib->crypto,
+ (crypter_constructor_t)des_crypter_create);
+ free(this);
+}
+
+/*
+ * see header file
+ */
+plugin_t *plugin_create()
+{
+ private_des_plugin_t *this = malloc_thing(private_des_plugin_t);
+
+ this->public.plugin.destroy = (void(*)(plugin_t*))destroy;
+
+ lib->crypto->add_crypter(lib->crypto, ENCR_DES,
+ (crypter_constructor_t)des_crypter_create);
+ lib->crypto->add_crypter(lib->crypto, ENCR_3DES,
+ (crypter_constructor_t)des_crypter_create);
+
+ return &this->public.plugin;
+}
+
diff --git a/src/libstrongswan/plugins/des/des_plugin.h b/src/libstrongswan/plugins/des/des_plugin.h
new file mode 100644
index 000000000..8cabd082b
--- /dev/null
+++ b/src/libstrongswan/plugins/des/des_plugin.h
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2008 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.
+ */
+
+/**
+ * @defgroup des_p des
+ * @ingroup plugins
+ *
+ * @defgroup des_plugin des_plugin
+ * @{ @ingroup des_p
+ */
+
+#ifndef DES_PLUGIN_H_
+#define DES_PLUGIN_H_
+
+#include <plugins/plugin.h>
+
+typedef struct des_plugin_t des_plugin_t;
+
+/**
+ * Plugin implementing DES based algorithms in software.
+ */
+struct des_plugin_t {
+
+ /**
+ * implements plugin interface
+ */
+ plugin_t plugin;
+};
+
+/**
+ * Create a des_plugin instance.
+ */
+plugin_t *plugin_create();
+
+#endif /* DES_PLUGIN_H_ @}*/
diff --git a/src/libstrongswan/plugins/fips_prf/Makefile.am b/src/libstrongswan/plugins/fips_prf/Makefile.am
new file mode 100644
index 000000000..73f28825a
--- /dev/null
+++ b/src/libstrongswan/plugins/fips_prf/Makefile.am
@@ -0,0 +1,10 @@
+
+INCLUDES = -I$(top_srcdir)/src/libstrongswan
+
+AM_CFLAGS = -rdynamic
+
+plugin_LTLIBRARIES = libstrongswan-fips-prf.la
+
+libstrongswan_fips_prf_la_SOURCES = fips_prf_plugin.h fips_prf_plugin.c fips_prf.c fips_prf.h
+libstrongswan_fips_prf_la_LDFLAGS = -module
+
diff --git a/src/libstrongswan/plugins/fips_prf/Makefile.in b/src/libstrongswan/plugins/fips_prf/Makefile.in
new file mode 100644
index 000000000..fa51b0db5
--- /dev/null
+++ b/src/libstrongswan/plugins/fips_prf/Makefile.in
@@ -0,0 +1,496 @@
+# Makefile.in generated by automake 1.10.1 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+VPATH = @srcdir@
+pkgdatadir = $(datadir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+subdir = src/libstrongswan/plugins/fips_prf
+DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/configure.in
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+mkinstalldirs = $(install_sh) -d
+CONFIG_CLEAN_FILES =
+am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
+am__vpath_adj = case $$p in \
+ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
+ *) f=$$p;; \
+ esac;
+am__strip_dir = `echo $$p | sed -e 's|^.*/||'`;
+am__installdirs = "$(DESTDIR)$(plugindir)"
+pluginLTLIBRARIES_INSTALL = $(INSTALL)
+LTLIBRARIES = $(plugin_LTLIBRARIES)
+libstrongswan_fips_prf_la_LIBADD =
+am_libstrongswan_fips_prf_la_OBJECTS = fips_prf_plugin.lo fips_prf.lo
+libstrongswan_fips_prf_la_OBJECTS = \
+ $(am_libstrongswan_fips_prf_la_OBJECTS)
+libstrongswan_fips_prf_la_LINK = $(LIBTOOL) --tag=CC \
+ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \
+ $(AM_CFLAGS) $(CFLAGS) $(libstrongswan_fips_prf_la_LDFLAGS) \
+ $(LDFLAGS) -o $@
+DEFAULT_INCLUDES = -I.@am__isrc@
+depcomp = $(SHELL) $(top_srcdir)/depcomp
+am__depfiles_maybe = depfiles
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+ --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
+ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+CCLD = $(CC)
+LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+ --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \
+ $(LDFLAGS) -o $@
+SOURCES = $(libstrongswan_fips_prf_la_SOURCES)
+DIST_SOURCES = $(libstrongswan_fips_prf_la_SOURCES)
+ETAGS = etags
+CTAGS = ctags
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+AMTAR = @AMTAR@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CXX = @CXX@
+CXXCPP = @CXXCPP@
+CXXDEPMODE = @CXXDEPMODE@
+CXXFLAGS = @CXXFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DSYMUTIL = @DSYMUTIL@
+ECHO = @ECHO@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+F77 = @F77@
+FFLAGS = @FFLAGS@
+GPERF = @GPERF@
+GREP = @GREP@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+IPSEC_ROUTING_TABLE = @IPSEC_ROUTING_TABLE@
+IPSEC_ROUTING_TABLE_PRIO = @IPSEC_ROUTING_TABLE_PRIO@
+LDFLAGS = @LDFLAGS@
+LEX = @LEX@
+LEXLIB = @LEXLIB@
+LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LINUX_HEADERS = @LINUX_HEADERS@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+MAKEINFO = @MAKEINFO@
+MKDIR_P = @MKDIR_P@
+NMEDIT = @NMEDIT@
+OBJEXT = @OBJEXT@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PERL = @PERL@
+PKG_CONFIG = @PKG_CONFIG@
+RANLIB = @RANLIB@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRIP = @STRIP@
+VERSION = @VERSION@
+YACC = @YACC@
+YFLAGS = @YFLAGS@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_CXX = @ac_ct_CXX@
+ac_ct_F77 = @ac_ct_F77@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+confdir = @confdir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+gtk_CFLAGS = @gtk_CFLAGS@
+gtk_LIBS = @gtk_LIBS@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+ipsecdir = @ipsecdir@
+ipsecgroup = @ipsecgroup@
+ipsecuser = @ipsecuser@
+libdir = @libdir@
+libexecdir = @libexecdir@
+libstrongswan_plugins = @libstrongswan_plugins@
+linuxdir = @linuxdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+piddir = @piddir@
+plugindir = @plugindir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+resolv_conf = @resolv_conf@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+simreader = @simreader@
+srcdir = @srcdir@
+strongswan_conf = @strongswan_conf@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+xml_CFLAGS = @xml_CFLAGS@
+xml_LIBS = @xml_LIBS@
+INCLUDES = -I$(top_srcdir)/src/libstrongswan
+AM_CFLAGS = -rdynamic
+plugin_LTLIBRARIES = libstrongswan-fips-prf.la
+libstrongswan_fips_prf_la_SOURCES = fips_prf_plugin.h fips_prf_plugin.c fips_prf.c fips_prf.h
+libstrongswan_fips_prf_la_LDFLAGS = -module
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .c .lo .o .obj
+$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \
+ && exit 0; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/libstrongswan/plugins/fips_prf/Makefile'; \
+ cd $(top_srcdir) && \
+ $(AUTOMAKE) --gnu src/libstrongswan/plugins/fips_prf/Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+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) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(pluginLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) '$$p' '$(DESTDIR)$(plugindir)/$$f'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(pluginLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) "$$p" "$(DESTDIR)$(plugindir)/$$f"; \
+ else :; fi; \
+ done
+
+uninstall-pluginLTLIBRARIES:
+ @$(NORMAL_UNINSTALL)
+ @list='$(plugin_LTLIBRARIES)'; for p in $$list; do \
+ p=$(am__strip_dir) \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(plugindir)/$$p'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(plugindir)/$$p"; \
+ 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
+libstrongswan-fips-prf.la: $(libstrongswan_fips_prf_la_OBJECTS) $(libstrongswan_fips_prf_la_DEPENDENCIES)
+ $(libstrongswan_fips_prf_la_LINK) -rpath $(plugindir) $(libstrongswan_fips_prf_la_OBJECTS) $(libstrongswan_fips_prf_la_LIBADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fips_prf.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fips_prf_plugin.Plo@am__quote@
+
+.c.o:
+@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(COMPILE) -c $<
+
+.c.obj:
+@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'`
+
+.c.lo:
+@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $<
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+
+ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonemtpy = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ mkid -fID $$unique
+tags: TAGS
+
+TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ tags=; \
+ here=`pwd`; \
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \
+ test -n "$$unique" || unique=$$empty_fix; \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ $$tags $$unique; \
+ fi
+ctags: CTAGS
+CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ tags=; \
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ test -z "$(CTAGS_ARGS)$$tags$$unique" \
+ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+ $$tags $$unique
+
+GTAGS:
+ here=`$(am__cd) $(top_builddir) && pwd` \
+ && cd $(top_srcdir) \
+ && gtags -i $(GTAGS_ARGS) $$here
+
+distclean-tags:
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+distdir: $(DISTFILES)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ list='$(DISTFILES)'; \
+ dist_files=`for file in $$list; do echo $$file; done | \
+ sed -e "s|^$$srcdirstrip/||;t" \
+ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+ case $$dist_files in \
+ */*) $(MKDIR_P) `echo "$$dist_files" | \
+ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+ sort -u` ;; \
+ esac; \
+ for file in $$dist_files; do \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ if test -d $$d/$$file; then \
+ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
+ fi; \
+ cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
+ else \
+ test -f $(distdir)/$$file \
+ || cp -p $$d/$$file $(distdir)/$$file \
+ || exit 1; \
+ fi; \
+ done
+check-am: all-am
+check: check-am
+all-am: Makefile $(LTLIBRARIES)
+installdirs:
+ for dir in "$(DESTDIR)$(plugindir)"; do \
+ test -z "$$dir" || $(MKDIR_P) "$$dir"; \
+ done
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ `test -z '$(STRIP)' || \
+ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+clean: clean-am
+
+clean-am: clean-generic clean-libtool clean-pluginLTLIBRARIES \
+ mostlyclean-am
+
+distclean: distclean-am
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+ distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+info: info-am
+
+info-am:
+
+install-data-am: install-pluginLTLIBRARIES
+
+install-dvi: install-dvi-am
+
+install-exec-am:
+
+install-html: install-html-am
+
+install-info: install-info-am
+
+install-man:
+
+install-pdf: install-pdf-am
+
+install-ps: install-ps-am
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic \
+ mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am: uninstall-pluginLTLIBRARIES
+
+.MAKE: install-am install-strip
+
+.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \
+ clean-libtool clean-pluginLTLIBRARIES ctags distclean \
+ distclean-compile distclean-generic distclean-libtool \
+ distclean-tags distdir dvi dvi-am html html-am info info-am \
+ install install-am install-data install-data-am install-dvi \
+ install-dvi-am install-exec install-exec-am install-html \
+ install-html-am install-info install-info-am install-man \
+ install-pdf install-pdf-am install-pluginLTLIBRARIES \
+ install-ps install-ps-am install-strip installcheck \
+ installcheck-am installdirs maintainer-clean \
+ maintainer-clean-generic mostlyclean mostlyclean-compile \
+ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
+ tags uninstall uninstall-am uninstall-pluginLTLIBRARIES
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/src/libstrongswan/plugins/fips_prf/fips_prf.c b/src/libstrongswan/plugins/fips_prf/fips_prf.c
new file mode 100644
index 000000000..df3d130a9
--- /dev/null
+++ b/src/libstrongswan/plugins/fips_prf/fips_prf.c
@@ -0,0 +1,252 @@
+/*
+ * Copyright (C) 2006 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.
+ *
+ * $Id: fips_prf.c 3619 2008-03-19 14:02:52Z martin $
+ */
+
+#include "fips_prf.h"
+
+#include <arpa/inet.h>
+
+#include <debug.h>
+
+typedef struct private_fips_prf_t private_fips_prf_t;
+
+/**
+ * Private data of a fips_prf_t object.
+ */
+struct private_fips_prf_t {
+ /**
+ * Public fips_prf_t interface.
+ */
+ fips_prf_t public;
+
+ /**
+ * key of prf function, "b" long
+ */
+ u_int8_t *key;
+
+ /**
+ * size of "b" in bytes
+ */
+ size_t b;
+
+ /**
+ * Keyed SHA1 prf: It does not use SHA1Final operation
+ */
+ prf_t *keyed_prf;
+
+ /**
+ * G function, either SHA1 or DES
+ */
+ void (*g)(private_fips_prf_t *this, chunk_t c, u_int8_t res[]);
+};
+
+/**
+ * sum = (a + b) mod 2 ^ (length * 8)
+ */
+static void add_mod(size_t length, u_int8_t a[], u_int8_t b[], u_int8_t sum[])
+{
+ int i, c = 0;
+
+ for(i = length - 1; i >= 0; i--)
+ {
+ u_int32_t tmp;
+
+ tmp = a[i] + b[i] + c;
+ sum[i] = 0xff & tmp;
+ c = tmp >> 8;
+ }
+}
+
+/**
+ * calculate "chunk mod 2^(length*8)" and save it into buffer
+ */
+static void chunk_mod(size_t length, chunk_t chunk, u_int8_t buffer[])
+{
+ if (chunk.len < length)
+ {
+ /* apply seed as least significant bits, others are zero */
+ memset(buffer, 0, length - chunk.len);
+ memcpy(buffer + length - chunk.len, chunk.ptr, chunk.len);
+ }
+ else
+ {
+ /* use least significant bytes from seed, as we use mod 2^b */
+ memcpy(buffer, chunk.ptr + chunk.len - length, length);
+ }
+}
+
+/**
+ * Implementation of prf_t.get_bytes.
+ *
+ * Test vector:
+ *
+ * key:
+ * 0xbd, 0x02, 0x9b, 0xbe, 0x7f, 0x51, 0x96, 0x0b,
+ * 0xcf, 0x9e, 0xdb, 0x2b, 0x61, 0xf0, 0x6f, 0x0f,
+ * 0xeb, 0x5a, 0x38, 0xb6
+ *
+ * seed:
+ * 0x00
+ *
+ * result:
+ * 0x20, 0x70, 0xb3, 0x22, 0x3d, 0xba, 0x37, 0x2f,
+ * 0xde, 0x1c, 0x0f, 0xfc, 0x7b, 0x2e, 0x3b, 0x49,
+ * 0x8b, 0x26, 0x06, 0x14, 0x3c, 0x6c, 0x18, 0xba,
+ * 0xcb, 0x0f, 0x6c, 0x55, 0xba, 0xbb, 0x13, 0x78,
+ * 0x8e, 0x20, 0xd7, 0x37, 0xa3, 0x27, 0x51, 0x16
+ */
+static void get_bytes(private_fips_prf_t *this, chunk_t seed, u_int8_t w[])
+{
+ int i;
+ u_int8_t xval[this->b];
+ u_int8_t xseed[this->b];
+ u_int8_t sum[this->b];
+ u_int8_t *xkey = this->key;
+ u_int8_t one[this->b];
+ chunk_t xval_chunk = chunk_from_buf(xval);
+
+ memset(one, 0, this->b);
+ one[this->b - 1] = 0x01;
+
+ /* 3.1 */
+ chunk_mod(this->b, seed, xseed);
+
+ /* 3.2 */
+ for (i = 0; i < 2; i++) /* twice */
+ {
+ /* a. XVAL = (XKEY + XSEED j) mod 2^b */
+ add_mod(this->b, xkey, xseed, xval);
+ DBG3("XVAL %b", xval, this->b);
+ /* b. wi = G(t, XVAL ) */
+ this->g(this, xval_chunk, &w[i * this->b]);
+ DBG3("w[%d] %b", i, &w[i * this->b], this->b);
+ /* c. XKEY = (1 + XKEY + wi) mod 2b */
+ add_mod(this->b, xkey, &w[i * this->b], sum);
+ add_mod(this->b, sum, one, xkey);
+ DBG3("XKEY %b", xkey, this->b);
+ }
+
+ /* 3.3 done already, mod q not used */
+}
+
+/**
+ * Implementation of prf_t.get_block_size.
+ */
+static size_t get_block_size(private_fips_prf_t *this)
+{
+ return 2 * this->b;
+}
+/**
+ * Implementation of prf_t.allocate_bytes.
+ */
+static void allocate_bytes(private_fips_prf_t *this, chunk_t seed, chunk_t *chunk)
+{
+ *chunk = chunk_alloc(get_block_size(this));
+ get_bytes(this, seed, chunk->ptr);
+}
+
+/**
+ * Implementation of prf_t.get_key_size.
+ */
+static size_t get_key_size(private_fips_prf_t *this)
+{
+ return this->b;
+}
+
+/**
+ * Implementation of prf_t.set_key.
+ */
+static void set_key(private_fips_prf_t *this, chunk_t key)
+{
+ /* save key as "key mod 2^b" */
+ chunk_mod(this->b, key, this->key);
+}
+
+/**
+ * Implementation of the G() function based on SHA1
+ */
+void g_sha1(private_fips_prf_t *this, chunk_t c, u_int8_t res[])
+{
+ u_int8_t buf[64];
+
+ if (c.len < sizeof(buf))
+ {
+ /* pad c with zeros */
+ memset(buf, 0, sizeof(buf));
+ memcpy(buf, c.ptr, c.len);
+ c.ptr = buf;
+ c.len = sizeof(buf);
+ }
+ else
+ {
+ /* not more than 512 bits can be G()-ed */
+ c.len = sizeof(buf);
+ }
+
+ /* use the keyed hasher, but use an empty key to use SHA1 IV */
+ this->keyed_prf->set_key(this->keyed_prf, chunk_empty);
+ this->keyed_prf->get_bytes(this->keyed_prf, c, res);
+}
+
+/**
+ * Implementation of prf_t.destroy.
+ */
+static void destroy(private_fips_prf_t *this)
+{
+ this->keyed_prf->destroy(this->keyed_prf);
+ free(this->key);
+ free(this);
+}
+
+/*
+ * Described in header.
+ */
+fips_prf_t *fips_prf_create(pseudo_random_function_t algo)
+{
+ private_fips_prf_t *this = malloc_thing(private_fips_prf_t);
+
+ this->public.prf_interface.get_bytes = (void (*) (prf_t *,chunk_t,u_int8_t*))get_bytes;
+ this->public.prf_interface.allocate_bytes = (void (*) (prf_t*,chunk_t,chunk_t*))allocate_bytes;
+ this->public.prf_interface.get_block_size = (size_t (*) (prf_t*))get_block_size;
+ this->public.prf_interface.get_key_size = (size_t (*) (prf_t*))get_key_size;
+ this->public.prf_interface.set_key = (void (*) (prf_t *,chunk_t))set_key;
+ this->public.prf_interface.destroy = (void (*) (prf_t *))destroy;
+
+ switch (algo)
+ {
+ case PRF_FIPS_SHA1_160:
+ {
+ this->g = g_sha1;
+ this->b = 20;
+ this->keyed_prf = lib->crypto->create_prf(lib->crypto, PRF_KEYED_SHA1);
+ if (this->keyed_prf == NULL)
+ {
+ free(this);
+ return NULL;
+ }
+ break;
+ }
+ case PRF_FIPS_DES:
+ /* not implemented yet */
+ default:
+ free(this);
+ return NULL;
+ }
+ this->key = malloc(this->b);
+
+ return &this->public;
+}
+
diff --git a/src/libstrongswan/plugins/fips_prf/fips_prf.h b/src/libstrongswan/plugins/fips_prf/fips_prf.h
new file mode 100644
index 000000000..3fead6b9b
--- /dev/null
+++ b/src/libstrongswan/plugins/fips_prf/fips_prf.h
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2006-2008 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.
+ */
+
+/**
+ * @defgroup fips_prf fips_prf
+ * @{ @ingroup fips_prf_p
+ */
+
+#ifndef FIPS_PRF_H_
+#define FIPS_PRF_H_
+
+typedef struct fips_prf_t fips_prf_t;
+
+#include <library.h>
+#include <crypto/prfs/prf.h>
+#include <crypto/hashers/hasher.h>
+
+/**
+ * Implementation of prf_t using the FIPS 186-2-change1 standard.
+ *
+ * FIPS defines a "General Purpose Random Number Generator" (Revised
+ * Algorithm for Computing m values of x (Appendix 3.1 of FIPS 186-2)). This
+ * implementation is not intended for private key generation and therefore does
+ * not include the "mod q" operation (see FIPS 186-2-change1 p74).
+ * The FIPS PRF is stateful; the key changes every time when bytes are acquired.
+ */
+struct fips_prf_t {
+
+ /**
+ * Generic prf_t interface for this fips_prf_t class.
+ */
+ prf_t prf_interface;
+};
+
+/**
+ * Creates a new fips_prf_t object.
+ *
+ * FIPS 186-2 defines G() functions used in the PRF function. It can
+ * be implemented either based on SHA1 or DES.
+ * The G() function is selected using the algo parameter.
+ *
+ * @param algo specific FIPS PRF implementation, specifies G() function
+ * @return fips_prf_t object, NULL if not supported.
+ */
+fips_prf_t *fips_prf_create(pseudo_random_function_t algo);
+
+#endif /* FIPS_PRF_H_ @}*/
diff --git a/src/libstrongswan/plugins/fips_prf/fips_prf_plugin.c b/src/libstrongswan/plugins/fips_prf/fips_prf_plugin.c
new file mode 100644
index 000000000..60fce8632
--- /dev/null
+++ b/src/libstrongswan/plugins/fips_prf/fips_prf_plugin.c
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2008 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.
+ *
+ * $Id: fips_prf_plugin.c 3488 2008-02-21 15:10:02Z martin $
+ */
+
+#include "fips_prf_plugin.h"
+
+#include <library.h>
+#include "fips_prf.h"
+
+typedef struct private_fips_prf_plugin_t private_fips_prf_plugin_t;
+
+/**
+ * private data of fips_prf_plugin
+ */
+struct private_fips_prf_plugin_t {
+
+ /**
+ * public functions
+ */
+ fips_prf_plugin_t public;
+};
+
+/**
+ * Implementation of fips_prf_plugin_t.destroy
+ */
+static void destroy(private_fips_prf_plugin_t *this)
+{
+ lib->crypto->remove_prf(lib->crypto,
+ (prf_constructor_t)fips_prf_create);
+ free(this);
+}
+
+/*
+ * see header file
+ */
+plugin_t *plugin_create()
+{
+ private_fips_prf_plugin_t *this = malloc_thing(private_fips_prf_plugin_t);
+
+ this->public.plugin.destroy = (void(*)(plugin_t*))destroy;
+
+ lib->crypto->add_prf(lib->crypto, PRF_FIPS_SHA1_160,
+ (prf_constructor_t)fips_prf_create);
+
+ return &this->public.plugin;
+}
diff --git a/src/libstrongswan/plugins/fips_prf/fips_prf_plugin.h b/src/libstrongswan/plugins/fips_prf/fips_prf_plugin.h
new file mode 100644
index 000000000..6816eb66f
--- /dev/null
+++ b/src/libstrongswan/plugins/fips_prf/fips_prf_plugin.h
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2008 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.
+ */
+
+/**
+ * @defgroup fips_prf_p fips_prf
+ * @ingroup plugins
+ *
+ * @defgroup fips_prf_plugin fips_prf_plugin
+ * @{ @ingroup fips_prf_p
+ */
+
+#ifndef FIPS_PRF_PLUGIN_H_
+#define FIPS_PRF_PLUGIN_H_
+
+#include <plugins/plugin.h>
+
+typedef struct fips_prf_plugin_t fips_prf_plugin_t;
+
+/**
+ * Plugin implementing the fips_prf algorithm in software.
+ */
+struct fips_prf_plugin_t {
+
+ /**
+ * implements plugin interface
+ */
+ plugin_t plugin;
+};
+
+/**
+ * Create a fips_prf_plugin instance.
+ */
+plugin_t *plugin_create();
+
+#endif /* FIPS_PRF_PLUGIN_H_ @}*/
diff --git a/src/libstrongswan/plugins/gmp/Makefile.am b/src/libstrongswan/plugins/gmp/Makefile.am
new file mode 100644
index 000000000..f073b5d48
--- /dev/null
+++ b/src/libstrongswan/plugins/gmp/Makefile.am
@@ -0,0 +1,15 @@
+
+INCLUDES = -I$(top_srcdir)/src/libstrongswan
+
+AM_CFLAGS = -rdynamic
+
+plugin_LTLIBRARIES = libstrongswan-gmp.la
+
+libstrongswan_gmp_la_SOURCES = gmp_plugin.h gmp_plugin.c \
+ gmp_diffie_hellman.c gmp_diffie_hellman.h \
+ gmp_rsa_private_key.c gmp_rsa_private_key.h \
+ gmp_rsa_public_key.c gmp_rsa_public_key.h
+
+libstrongswan_gmp_la_LDFLAGS = -module
+libstrongswan_gmp_la_LIBADD = -lgmp
+
diff --git a/src/libstrongswan/plugins/gmp/Makefile.in b/src/libstrongswan/plugins/gmp/Makefile.in
new file mode 100644
index 000000000..1d9bfb88e
--- /dev/null
+++ b/src/libstrongswan/plugins/gmp/Makefile.in
@@ -0,0 +1,502 @@
+# Makefile.in generated by automake 1.10.1 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+VPATH = @srcdir@
+pkgdatadir = $(datadir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+subdir = src/libstrongswan/plugins/gmp
+DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/configure.in
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+mkinstalldirs = $(install_sh) -d
+CONFIG_CLEAN_FILES =
+am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
+am__vpath_adj = case $$p in \
+ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
+ *) f=$$p;; \
+ esac;
+am__strip_dir = `echo $$p | sed -e 's|^.*/||'`;
+am__installdirs = "$(DESTDIR)$(plugindir)"
+pluginLTLIBRARIES_INSTALL = $(INSTALL)
+LTLIBRARIES = $(plugin_LTLIBRARIES)
+libstrongswan_gmp_la_DEPENDENCIES =
+am_libstrongswan_gmp_la_OBJECTS = gmp_plugin.lo gmp_diffie_hellman.lo \
+ gmp_rsa_private_key.lo gmp_rsa_public_key.lo
+libstrongswan_gmp_la_OBJECTS = $(am_libstrongswan_gmp_la_OBJECTS)
+libstrongswan_gmp_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(libstrongswan_gmp_la_LDFLAGS) $(LDFLAGS) -o $@
+DEFAULT_INCLUDES = -I.@am__isrc@
+depcomp = $(SHELL) $(top_srcdir)/depcomp
+am__depfiles_maybe = depfiles
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+ --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
+ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+CCLD = $(CC)
+LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+ --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \
+ $(LDFLAGS) -o $@
+SOURCES = $(libstrongswan_gmp_la_SOURCES)
+DIST_SOURCES = $(libstrongswan_gmp_la_SOURCES)
+ETAGS = etags
+CTAGS = ctags
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+AMTAR = @AMTAR@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CXX = @CXX@
+CXXCPP = @CXXCPP@
+CXXDEPMODE = @CXXDEPMODE@
+CXXFLAGS = @CXXFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DSYMUTIL = @DSYMUTIL@
+ECHO = @ECHO@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+F77 = @F77@
+FFLAGS = @FFLAGS@
+GPERF = @GPERF@
+GREP = @GREP@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+IPSEC_ROUTING_TABLE = @IPSEC_ROUTING_TABLE@
+IPSEC_ROUTING_TABLE_PRIO = @IPSEC_ROUTING_TABLE_PRIO@
+LDFLAGS = @LDFLAGS@
+LEX = @LEX@
+LEXLIB = @LEXLIB@
+LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LINUX_HEADERS = @LINUX_HEADERS@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+MAKEINFO = @MAKEINFO@
+MKDIR_P = @MKDIR_P@
+NMEDIT = @NMEDIT@
+OBJEXT = @OBJEXT@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PERL = @PERL@
+PKG_CONFIG = @PKG_CONFIG@
+RANLIB = @RANLIB@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRIP = @STRIP@
+VERSION = @VERSION@
+YACC = @YACC@
+YFLAGS = @YFLAGS@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_CXX = @ac_ct_CXX@
+ac_ct_F77 = @ac_ct_F77@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+confdir = @confdir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+gtk_CFLAGS = @gtk_CFLAGS@
+gtk_LIBS = @gtk_LIBS@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+ipsecdir = @ipsecdir@
+ipsecgroup = @ipsecgroup@
+ipsecuser = @ipsecuser@
+libdir = @libdir@
+libexecdir = @libexecdir@
+libstrongswan_plugins = @libstrongswan_plugins@
+linuxdir = @linuxdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+piddir = @piddir@
+plugindir = @plugindir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+resolv_conf = @resolv_conf@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+simreader = @simreader@
+srcdir = @srcdir@
+strongswan_conf = @strongswan_conf@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+xml_CFLAGS = @xml_CFLAGS@
+xml_LIBS = @xml_LIBS@
+INCLUDES = -I$(top_srcdir)/src/libstrongswan
+AM_CFLAGS = -rdynamic
+plugin_LTLIBRARIES = libstrongswan-gmp.la
+libstrongswan_gmp_la_SOURCES = gmp_plugin.h gmp_plugin.c \
+ gmp_diffie_hellman.c gmp_diffie_hellman.h \
+ gmp_rsa_private_key.c gmp_rsa_private_key.h \
+ gmp_rsa_public_key.c gmp_rsa_public_key.h
+
+libstrongswan_gmp_la_LDFLAGS = -module
+libstrongswan_gmp_la_LIBADD = -lgmp
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .c .lo .o .obj
+$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \
+ && exit 0; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/libstrongswan/plugins/gmp/Makefile'; \
+ cd $(top_srcdir) && \
+ $(AUTOMAKE) --gnu src/libstrongswan/plugins/gmp/Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+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) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(pluginLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) '$$p' '$(DESTDIR)$(plugindir)/$$f'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(pluginLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) "$$p" "$(DESTDIR)$(plugindir)/$$f"; \
+ else :; fi; \
+ done
+
+uninstall-pluginLTLIBRARIES:
+ @$(NORMAL_UNINSTALL)
+ @list='$(plugin_LTLIBRARIES)'; for p in $$list; do \
+ p=$(am__strip_dir) \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(plugindir)/$$p'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(plugindir)/$$p"; \
+ 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
+libstrongswan-gmp.la: $(libstrongswan_gmp_la_OBJECTS) $(libstrongswan_gmp_la_DEPENDENCIES)
+ $(libstrongswan_gmp_la_LINK) -rpath $(plugindir) $(libstrongswan_gmp_la_OBJECTS) $(libstrongswan_gmp_la_LIBADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gmp_diffie_hellman.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gmp_plugin.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gmp_rsa_private_key.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gmp_rsa_public_key.Plo@am__quote@
+
+.c.o:
+@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(COMPILE) -c $<
+
+.c.obj:
+@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'`
+
+.c.lo:
+@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $<
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+
+ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonemtpy = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ mkid -fID $$unique
+tags: TAGS
+
+TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ tags=; \
+ here=`pwd`; \
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \
+ test -n "$$unique" || unique=$$empty_fix; \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ $$tags $$unique; \
+ fi
+ctags: CTAGS
+CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ tags=; \
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ test -z "$(CTAGS_ARGS)$$tags$$unique" \
+ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+ $$tags $$unique
+
+GTAGS:
+ here=`$(am__cd) $(top_builddir) && pwd` \
+ && cd $(top_srcdir) \
+ && gtags -i $(GTAGS_ARGS) $$here
+
+distclean-tags:
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+distdir: $(DISTFILES)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ list='$(DISTFILES)'; \
+ dist_files=`for file in $$list; do echo $$file; done | \
+ sed -e "s|^$$srcdirstrip/||;t" \
+ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+ case $$dist_files in \
+ */*) $(MKDIR_P) `echo "$$dist_files" | \
+ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+ sort -u` ;; \
+ esac; \
+ for file in $$dist_files; do \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ if test -d $$d/$$file; then \
+ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
+ fi; \
+ cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
+ else \
+ test -f $(distdir)/$$file \
+ || cp -p $$d/$$file $(distdir)/$$file \
+ || exit 1; \
+ fi; \
+ done
+check-am: all-am
+check: check-am
+all-am: Makefile $(LTLIBRARIES)
+installdirs:
+ for dir in "$(DESTDIR)$(plugindir)"; do \
+ test -z "$$dir" || $(MKDIR_P) "$$dir"; \
+ done
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ `test -z '$(STRIP)' || \
+ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+clean: clean-am
+
+clean-am: clean-generic clean-libtool clean-pluginLTLIBRARIES \
+ mostlyclean-am
+
+distclean: distclean-am
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+ distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+info: info-am
+
+info-am:
+
+install-data-am: install-pluginLTLIBRARIES
+
+install-dvi: install-dvi-am
+
+install-exec-am:
+
+install-html: install-html-am
+
+install-info: install-info-am
+
+install-man:
+
+install-pdf: install-pdf-am
+
+install-ps: install-ps-am
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic \
+ mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am: uninstall-pluginLTLIBRARIES
+
+.MAKE: install-am install-strip
+
+.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \
+ clean-libtool clean-pluginLTLIBRARIES ctags distclean \
+ distclean-compile distclean-generic distclean-libtool \
+ distclean-tags distdir dvi dvi-am html html-am info info-am \
+ install install-am install-data install-data-am install-dvi \
+ install-dvi-am install-exec install-exec-am install-html \
+ install-html-am install-info install-info-am install-man \
+ install-pdf install-pdf-am install-pluginLTLIBRARIES \
+ install-ps install-ps-am install-strip installcheck \
+ installcheck-am installdirs maintainer-clean \
+ maintainer-clean-generic mostlyclean mostlyclean-compile \
+ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
+ tags uninstall uninstall-am uninstall-pluginLTLIBRARIES
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/src/libstrongswan/plugins/gmp/gmp_diffie_hellman.c b/src/libstrongswan/plugins/gmp/gmp_diffie_hellman.c
new file mode 100644
index 000000000..3d9856b63
--- /dev/null
+++ b/src/libstrongswan/plugins/gmp/gmp_diffie_hellman.c
@@ -0,0 +1,567 @@
+/*
+ * Copyright (C) 1998-2002 D. Hugh Redelmeier.
+ * Copyright (C) 1999, 2000, 2001 Henry Spencer.
+ * Copyright (C) 2005-2008 Martin Willi
+ * Copyright (C) 2005 Jan Hutter
+ * 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.
+ *
+ * $Id: gmp_diffie_hellman.c 3806 2008-04-15 05:56:35Z martin $
+ */
+
+#include <gmp.h>
+
+#include "gmp_diffie_hellman.h"
+
+#include <debug.h>
+
+
+/**
+ * Modulus of Group 1 (MODP_768_BIT).
+ */
+static u_int8_t group1_modulus[] = {
+ 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xC9,0x0F,0xDA,0xA2,0x21,0x68,0xC2,0x34,
+ 0xC4,0xC6,0x62,0x8B,0x80 ,0xDC,0x1C,0xD1,0x29,0x02,0x4E,0x08,0x8A,0x67,0xCC,0x74,
+ 0x02,0x0B,0xBE,0xA6,0x3B,0x13,0x9B,0x22,0x51,0x4A,0x08,0x79,0x8E,0x34,0x04,0xDD,
+ 0xEF,0x95,0x19,0xB3,0xCD,0x3A,0x43,0x1B,0x30,0x2B,0x0A,0x6D,0xF2,0x5F,0x14,0x37,
+ 0x4F,0xE1,0x35,0x6D,0x6D,0x51,0xC2,0x45,0xE4,0x85,0xB5,0x76,0x62,0x5E,0x7E,0xC6,
+ 0xF4,0x4C,0x42,0xE9,0xA6,0x3A,0x36,0x20,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF
+};
+
+/**
+ * Modulus of Group 2 (MODP_1024_BIT).
+ */
+static u_int8_t group2_modulus[] = {
+ 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xC9,0x0F,0xDA,0xA2,0x21,0x68,0xC2,0x34,
+ 0xC4,0xC6,0x62,0x8B,0x80,0xDC,0x1C,0xD1,0x29,0x02,0x4E,0x08,0x8A,0x67,0xCC,0x74,
+ 0x02,0x0B,0xBE,0xA6,0x3B,0x13,0x9B,0x22,0x51,0x4A,0x08,0x79,0x8E,0x34,0x04,0xDD,
+ 0xEF,0x95,0x19,0xB3,0xCD,0x3A,0x43,0x1B,0x30,0x2B,0x0A,0x6D,0xF2,0x5F,0x14,0x37,
+ 0x4F,0xE1,0x35,0x6D,0x6D,0x51,0xC2,0x45,0xE4,0x85,0xB5,0x76,0x62,0x5E,0x7E,0xC6,
+ 0xF4,0x4C,0x42,0xE9,0xA6,0x37,0xED,0x6B,0x0B,0xFF,0x5C,0xB6,0xF4,0x06,0xB7,0xED,
+ 0xEE,0x38,0x6B,0xFB,0x5A,0x89,0x9F,0xA5,0xAE,0x9F,0x24,0x11,0x7C,0x4B,0x1F,0xE6,
+ 0x49,0x28,0x66,0x51,0xEC,0xE6,0x53,0x81,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF
+};
+
+/**
+ * Modulus of Group 5 (MODP_1536_BIT).
+ */
+static u_int8_t group5_modulus[] = {
+ 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xC9,0x0F,0xDA,0xA2,0x21,0x68,0xC2,0x34,
+ 0xC4,0xC6,0x62,0x8B,0x80,0xDC,0x1C,0xD1,0x29,0x02,0x4E,0x08,0x8A,0x67,0xCC,0x74,
+ 0x02,0x0B,0xBE,0xA6,0x3B,0x13,0x9B,0x22,0x51,0x4A,0x08,0x79,0x8E,0x34,0x04,0xDD,
+ 0xEF,0x95,0x19,0xB3,0xCD,0x3A,0x43,0x1B,0x30,0x2B,0x0A,0x6D,0xF2,0x5F,0x14,0x37,
+ 0x4F,0xE1,0x35,0x6D,0x6D,0x51,0xC2,0x45,0xE4,0x85,0xB5,0x76,0x62,0x5E,0x7E,0xC6,
+ 0xF4,0x4C,0x42,0xE9,0xA6,0x37,0xED,0x6B,0x0B,0xFF,0x5C,0xB6,0xF4,0x06,0xB7,0xED,
+ 0xEE,0x38,0x6B,0xFB,0x5A,0x89,0x9F,0xA5,0xAE,0x9F,0x24,0x11,0x7C,0x4B,0x1F,0xE6,
+ 0x49,0x28,0x66,0x51,0xEC,0xE4,0x5B,0x3D,0xC2,0x00,0x7C,0xB8,0xA1,0x63,0xBF,0x05,
+ 0x98,0xDA,0x48,0x36,0x1C,0x55,0xD3,0x9A,0x69,0x16,0x3F,0xA8,0xFD,0x24,0xCF,0x5F,
+ 0x83,0x65,0x5D,0x23,0xDC,0xA3,0xAD,0x96,0x1C,0x62,0xF3,0x56,0x20,0x85,0x52,0xBB,
+ 0x9E,0xD5,0x29,0x07,0x70,0x96,0x96,0x6D,0x67,0x0C,0x35,0x4E,0x4A,0xBC,0x98,0x04,
+ 0xF1,0x74,0x6C,0x08,0xCA,0x23,0x73,0x27,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF
+};
+/**
+ * Modulus of Group 14 (MODP_2048_BIT).
+ */
+static u_int8_t group14_modulus[] = {
+ 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xC9,0x0F,0xDA,0xA2,0x21,0x68,0xC2,0x34,
+ 0xC4,0xC6,0x62,0x8B,0x80,0xDC,0x1C,0xD1,0x29,0x02,0x4E,0x08,0x8A,0x67,0xCC,0x74,
+ 0x02,0x0B,0xBE,0xA6,0x3B,0x13,0x9B,0x22,0x51,0x4A,0x08,0x79,0x8E,0x34,0x04,0xDD,
+ 0xEF,0x95,0x19,0xB3,0xCD,0x3A,0x43,0x1B,0x30,0x2B,0x0A,0x6D,0xF2,0x5F,0x14,0x37,
+ 0x4F,0xE1,0x35,0x6D,0x6D,0x51,0xC2,0x45,0xE4,0x85,0xB5,0x76,0x62,0x5E,0x7E,0xC6,
+ 0xF4,0x4C,0x42,0xE9,0xA6,0x37,0xED,0x6B,0x0B,0xFF,0x5C,0xB6,0xF4,0x06,0xB7,0xED,
+ 0xEE,0x38,0x6B,0xFB,0x5A,0x89,0x9F,0xA5,0xAE,0x9F,0x24,0x11,0x7C,0x4B,0x1F,0xE6,
+ 0x49,0x28,0x66,0x51,0xEC,0xE4,0x5B,0x3D,0xC2,0x00,0x7C,0xB8,0xA1,0x63,0xBF,0x05,
+ 0x98,0xDA,0x48,0x36,0x1C,0x55,0xD3,0x9A,0x69,0x16,0x3F,0xA8,0xFD,0x24,0xCF,0x5F,
+ 0x83,0x65,0x5D,0x23,0xDC,0xA3,0xAD,0x96,0x1C,0x62,0xF3,0x56,0x20,0x85,0x52,0xBB,
+ 0x9E,0xD5,0x29,0x07,0x70,0x96,0x96,0x6D,0x67,0x0C,0x35,0x4E,0x4A,0xBC,0x98,0x04,
+ 0xF1,0x74,0x6C,0x08,0xCA,0x18,0x21,0x7C,0x32,0x90,0x5E,0x46,0x2E,0x36,0xCE,0x3B,
+ 0xE3,0x9E,0x77,0x2C,0x18,0x0E,0x86,0x03,0x9B,0x27,0x83,0xA2,0xEC,0x07,0xA2,0x8F,
+ 0xB5,0xC5,0x5D,0xF0,0x6F,0x4C,0x52,0xC9,0xDE,0x2B,0xCB,0xF6,0x95,0x58,0x17,0x18,
+ 0x39,0x95,0x49,0x7C,0xEA,0x95,0x6A,0xE5,0x15,0xD2,0x26,0x18,0x98,0xFA,0x05,0x10,
+ 0x15,0x72,0x8E,0x5A,0x8A,0xAC,0xAA,0x68,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF
+};
+
+/**
+ * Modulus of Group 15 (MODP_3072_BIT).
+ */
+static u_int8_t group15_modulus[] = {
+ 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xC9,0x0F,0xDA,0xA2,0x21,0x68,0xC2,0x34,
+ 0xC4,0xC6,0x62,0x8B,0x80,0xDC,0x1C,0xD1,0x29,0x02,0x4E,0x08,0x8A,0x67,0xCC,0x74,
+ 0x02,0x0B,0xBE,0xA6,0x3B,0x13,0x9B,0x22,0x51,0x4A,0x08,0x79,0x8E,0x34,0x04,0xDD,
+ 0xEF,0x95,0x19,0xB3,0xCD,0x3A,0x43,0x1B,0x30,0x2B,0x0A,0x6D,0xF2,0x5F,0x14,0x37,
+ 0x4F,0xE1,0x35,0x6D,0x6D,0x51,0xC2,0x45,0xE4,0x85,0xB5,0x76,0x62,0x5E,0x7E,0xC6,
+ 0xF4,0x4C,0x42,0xE9,0xA6,0x37,0xED,0x6B,0x0B,0xFF,0x5C,0xB6,0xF4,0x06,0xB7,0xED,
+ 0xEE,0x38,0x6B,0xFB,0x5A,0x89,0x9F,0xA5,0xAE,0x9F,0x24,0x11,0x7C,0x4B,0x1F,0xE6,
+ 0x49,0x28,0x66,0x51,0xEC,0xE4,0x5B,0x3D,0xC2,0x00,0x7C,0xB8,0xA1,0x63,0xBF,0x05,
+ 0x98,0xDA,0x48,0x36,0x1C,0x55,0xD3,0x9A,0x69,0x16,0x3F,0xA8,0xFD,0x24,0xCF,0x5F,
+ 0x83,0x65,0x5D,0x23,0xDC,0xA3,0xAD,0x96,0x1C,0x62,0xF3,0x56,0x20,0x85,0x52,0xBB,
+ 0x9E,0xD5,0x29,0x07,0x70,0x96,0x96,0x6D,0x67,0x0C,0x35,0x4E,0x4A,0xBC,0x98,0x04,
+ 0xF1,0x74,0x6C,0x08,0xCA,0x18,0x21,0x7C,0x32,0x90,0x5E,0x46,0x2E,0x36,0xCE,0x3B,
+ 0xE3,0x9E,0x77,0x2C,0x18,0x0E,0x86,0x03,0x9B,0x27,0x83,0xA2,0xEC,0x07,0xA2,0x8F,
+ 0xB5,0xC5,0x5D,0xF0,0x6F,0x4C,0x52,0xC9,0xDE,0x2B,0xCB,0xF6,0x95,0x58,0x17,0x18,
+ 0x39,0x95,0x49,0x7C,0xEA,0x95,0x6A,0xE5,0x15,0xD2,0x26,0x18,0x98,0xFA,0x05,0x10,
+ 0x15,0x72,0x8E,0x5A,0x8A,0xAA,0xC4,0x2D,0xAD,0x33,0x17,0x0D,0x04,0x50,0x7A,0x33,
+ 0xA8,0x55,0x21,0xAB,0xDF,0x1C,0xBA,0x64,0xEC,0xFB,0x85,0x04,0x58,0xDB,0xEF,0x0A,
+ 0x8A,0xEA,0x71,0x57,0x5D,0x06,0x0C,0x7D,0xB3,0x97,0x0F,0x85,0xA6,0xE1,0xE4,0xC7,
+ 0xAB,0xF5,0xAE,0x8C,0xDB,0x09,0x33,0xD7,0x1E,0x8C,0x94,0xE0,0x4A,0x25,0x61,0x9D,
+ 0xCE,0xE3,0xD2,0x26,0x1A,0xD2,0xEE,0x6B,0xF1,0x2F,0xFA,0x06,0xD9,0x8A,0x08,0x64,
+ 0xD8,0x76,0x02,0x73,0x3E,0xC8,0x6A,0x64,0x52,0x1F,0x2B,0x18,0x17,0x7B,0x20,0x0C,
+ 0xBB,0xE1,0x17,0x57,0x7A,0x61,0x5D,0x6C,0x77,0x09,0x88,0xC0,0xBA,0xD9,0x46,0xE2,
+ 0x08,0xE2,0x4F,0xA0,0x74,0xE5,0xAB,0x31,0x43,0xDB,0x5B,0xFC,0xE0,0xFD,0x10,0x8E,
+ 0x4B,0x82,0xD1,0x20,0xA9,0x3A,0xD2,0xCA,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF
+};
+
+/**
+ * Modulus of Group 16 (MODP_4096_BIT).
+ */
+static u_int8_t group16_modulus[] = {
+ 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xC9,0x0F,0xDA,0xA2,0x21,0x68,0xC2,0x34,
+ 0xC4,0xC6,0x62,0x8B,0x80,0xDC,0x1C,0xD1,0x29,0x02,0x4E,0x08,0x8A,0x67,0xCC,0x74,
+ 0x02,0x0B,0xBE,0xA6,0x3B,0x13,0x9B,0x22,0x51,0x4A,0x08,0x79,0x8E,0x34,0x04,0xDD,
+ 0xEF,0x95,0x19,0xB3,0xCD,0x3A,0x43,0x1B,0x30,0x2B,0x0A,0x6D,0xF2,0x5F,0x14,0x37,
+ 0x4F,0xE1,0x35,0x6D,0x6D,0x51,0xC2,0x45,0xE4,0x85,0xB5,0x76,0x62,0x5E,0x7E,0xC6,
+ 0xF4,0x4C,0x42,0xE9,0xA6,0x37,0xED,0x6B,0x0B,0xFF,0x5C,0xB6,0xF4,0x06,0xB7,0xED,
+ 0xEE,0x38,0x6B,0xFB,0x5A,0x89,0x9F,0xA5,0xAE,0x9F,0x24,0x11,0x7C,0x4B,0x1F,0xE6,
+ 0x49,0x28,0x66,0x51,0xEC,0xE4,0x5B,0x3D,0xC2,0x00,0x7C,0xB8,0xA1,0x63,0xBF,0x05,
+ 0x98,0xDA,0x48,0x36,0x1C,0x55,0xD3,0x9A,0x69,0x16,0x3F,0xA8,0xFD,0x24,0xCF,0x5F,
+ 0x83,0x65,0x5D,0x23,0xDC,0xA3,0xAD,0x96,0x1C,0x62,0xF3,0x56,0x20,0x85,0x52,0xBB,
+ 0x9E,0xD5,0x29,0x07,0x70,0x96,0x96,0x6D,0x67,0x0C,0x35,0x4E,0x4A,0xBC,0x98,0x04,
+ 0xF1,0x74,0x6C,0x08,0xCA,0x18,0x21,0x7C,0x32,0x90,0x5E,0x46,0x2E,0x36,0xCE,0x3B,
+ 0xE3,0x9E,0x77,0x2C,0x18,0x0E,0x86,0x03,0x9B,0x27,0x83,0xA2,0xEC,0x07,0xA2,0x8F,
+ 0xB5,0xC5,0x5D,0xF0,0x6F,0x4C,0x52,0xC9,0xDE,0x2B,0xCB,0xF6,0x95,0x58,0x17,0x18,
+ 0x39,0x95,0x49,0x7C,0xEA,0x95,0x6A,0xE5,0x15,0xD2,0x26,0x18,0x98,0xFA,0x05,0x10,
+ 0x15,0x72,0x8E,0x5A,0x8A,0xAA,0xC4,0x2D,0xAD,0x33,0x17,0x0D,0x04,0x50,0x7A,0x33,
+ 0xA8,0x55,0x21,0xAB,0xDF,0x1C,0xBA,0x64,0xEC,0xFB,0x85,0x04,0x58,0xDB,0xEF,0x0A,
+ 0x8A,0xEA,0x71,0x57,0x5D,0x06,0x0C,0x7D,0xB3,0x97,0x0F,0x85,0xA6,0xE1,0xE4,0xC7,
+ 0xAB,0xF5,0xAE,0x8C,0xDB,0x09,0x33,0xD7,0x1E,0x8C,0x94,0xE0,0x4A,0x25,0x61,0x9D,
+ 0xCE,0xE3,0xD2,0x26,0x1A,0xD2,0xEE,0x6B,0xF1,0x2F,0xFA,0x06,0xD9,0x8A,0x08,0x64,
+ 0xD8,0x76,0x02,0x73,0x3E,0xC8,0x6A,0x64,0x52,0x1F,0x2B,0x18,0x17,0x7B,0x20,0x0C,
+ 0xBB,0xE1,0x17,0x57,0x7A,0x61,0x5D,0x6C,0x77,0x09,0x88,0xC0,0xBA,0xD9,0x46,0xE2,
+ 0x08,0xE2,0x4F,0xA0,0x74,0xE5,0xAB,0x31,0x43,0xDB,0x5B,0xFC,0xE0,0xFD,0x10,0x8E,
+ 0x4B,0x82,0xD1,0x20,0xA9,0x21,0x08,0x01,0x1A,0x72,0x3C,0x12,0xA7,0x87,0xE6,0xD7,
+ 0x88,0x71,0x9A,0x10,0xBD,0xBA,0x5B,0x26,0x99,0xC3,0x27,0x18,0x6A,0xF4,0xE2,0x3C,
+ 0x1A,0x94,0x68,0x34,0xB6,0x15,0x0B,0xDA,0x25,0x83,0xE9,0xCA,0x2A,0xD4,0x4C,0xE8,
+ 0xDB,0xBB,0xC2,0xDB,0x04,0xDE,0x8E,0xF9,0x2E,0x8E,0xFC,0x14,0x1F,0xBE,0xCA,0xA6,
+ 0x28,0x7C,0x59,0x47,0x4E,0x6B,0xC0,0x5D,0x99,0xB2,0x96,0x4F,0xA0,0x90,0xC3,0xA2,
+ 0x23,0x3B,0xA1,0x86,0x51,0x5B,0xE7,0xED,0x1F,0x61,0x29,0x70,0xCE,0xE2,0xD7,0xAF,
+ 0xB8,0x1B,0xDD,0x76,0x21,0x70,0x48,0x1C,0xD0,0x06,0x91,0x27,0xD5,0xB0,0x5A,0xA9,
+ 0x93,0xB4,0xEA,0x98,0x8D,0x8F,0xDD,0xC1,0x86,0xFF,0xB7,0xDC,0x90,0xA6,0xC0,0x8F,
+ 0x4D,0xF4,0x35,0xC9,0x34,0x06,0x31,0x99,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF
+};
+
+/**
+ * Modulus of Group 17 (MODP_6144_BIT).
+ */
+static u_int8_t group17_modulus[] = {
+ 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xC9,0x0F,0xDA,0xA2,0x21,0x68,0xC2,0x34,
+ 0xC4,0xC6,0x62,0x8B,0x80,0xDC,0x1C,0xD1,0x29,0x02,0x4E,0x08,0x8A,0x67,0xCC,0x74,
+ 0x02,0x0B,0xBE,0xA6,0x3B,0x13,0x9B,0x22,0x51,0x4A,0x08,0x79,0x8E,0x34,0x04,0xDD,
+ 0xEF,0x95,0x19,0xB3,0xCD,0x3A,0x43,0x1B,0x30,0x2B,0x0A,0x6D,0xF2,0x5F,0x14,0x37,
+ 0x4F,0xE1,0x35,0x6D,0x6D,0x51,0xC2,0x45,0xE4,0x85,0xB5,0x76,0x62,0x5E,0x7E,0xC6,
+ 0xF4,0x4C,0x42,0xE9,0xA6,0x37,0xED,0x6B,0x0B,0xFF,0x5C,0xB6,0xF4,0x06,0xB7,0xED,
+ 0xEE,0x38,0x6B,0xFB,0x5A,0x89,0x9F,0xA5,0xAE,0x9F,0x24,0x11,0x7C,0x4B,0x1F,0xE6,
+ 0x49,0x28,0x66,0x51,0xEC,0xE4,0x5B,0x3D,0xC2,0x00,0x7C,0xB8,0xA1,0x63,0xBF,0x05,
+ 0x98,0xDA,0x48,0x36,0x1C,0x55,0xD3,0x9A,0x69,0x16,0x3F,0xA8,0xFD,0x24,0xCF,0x5F,
+ 0x83,0x65,0x5D,0x23,0xDC,0xA3,0xAD,0x96,0x1C,0x62,0xF3,0x56,0x20,0x85,0x52,0xBB,
+ 0x9E,0xD5,0x29,0x07,0x70,0x96,0x96,0x6D,0x67,0x0C,0x35,0x4E,0x4A,0xBC,0x98,0x04,
+ 0xF1,0x74,0x6C,0x08,0xCA,0x18,0x21,0x7C,0x32,0x90,0x5E,0x46,0x2E,0x36,0xCE,0x3B,
+ 0xE3,0x9E,0x77,0x2C,0x18,0x0E,0x86,0x03,0x9B,0x27,0x83,0xA2,0xEC,0x07,0xA2,0x8F,
+ 0xB5,0xC5,0x5D,0xF0,0x6F,0x4C,0x52,0xC9,0xDE,0x2B,0xCB,0xF6,0x95,0x58,0x17,0x18,
+ 0x39,0x95,0x49,0x7C,0xEA,0x95,0x6A,0xE5,0x15,0xD2,0x26,0x18,0x98,0xFA,0x05,0x10,
+ 0x15,0x72,0x8E,0x5A,0x8A,0xAA,0xC4,0x2D,0xAD,0x33,0x17,0x0D,0x04,0x50,0x7A,0x33,
+ 0xA8,0x55,0x21,0xAB,0xDF,0x1C,0xBA,0x64,0xEC,0xFB,0x85,0x04,0x58,0xDB,0xEF,0x0A,
+ 0x8A,0xEA,0x71,0x57,0x5D,0x06,0x0C,0x7D,0xB3,0x97,0x0F,0x85,0xA6,0xE1,0xE4,0xC7,
+ 0xAB,0xF5,0xAE,0x8C,0xDB,0x09,0x33,0xD7,0x1E,0x8C,0x94,0xE0,0x4A,0x25,0x61,0x9D,
+ 0xCE,0xE3,0xD2,0x26,0x1A,0xD2,0xEE,0x6B,0xF1,0x2F,0xFA,0x06,0xD9,0x8A,0x08,0x64,
+ 0xD8,0x76,0x02,0x73,0x3E,0xC8,0x6A,0x64,0x52,0x1F,0x2B,0x18,0x17,0x7B,0x20,0x0C,
+ 0xBB,0xE1,0x17,0x57,0x7A,0x61,0x5D,0x6C,0x77,0x09,0x88,0xC0,0xBA,0xD9,0x46,0xE2,
+ 0x08,0xE2,0x4F,0xA0,0x74,0xE5,0xAB,0x31,0x43,0xDB,0x5B,0xFC,0xE0,0xFD,0x10,0x8E,
+ 0x4B,0x82,0xD1,0x20,0xA9,0x21,0x08,0x01,0x1A,0x72,0x3C,0x12,0xA7,0x87,0xE6,0xD7,
+ 0x88,0x71,0x9A,0x10,0xBD,0xBA,0x5B,0x26,0x99,0xC3,0x27,0x18,0x6A,0xF4,0xE2,0x3C,
+ 0x1A,0x94,0x68,0x34,0xB6,0x15,0x0B,0xDA,0x25,0x83,0xE9,0xCA,0x2A,0xD4,0x4C,0xE8,
+ 0xDB,0xBB,0xC2,0xDB,0x04,0xDE,0x8E,0xF9,0x2E,0x8E,0xFC,0x14,0x1F,0xBE,0xCA,0xA6,
+ 0x28,0x7C,0x59,0x47,0x4E,0x6B,0xC0,0x5D,0x99,0xB2,0x96,0x4F,0xA0,0x90,0xC3,0xA2,
+ 0x23,0x3B,0xA1,0x86,0x51,0x5B,0xE7,0xED,0x1F,0x61,0x29,0x70,0xCE,0xE2,0xD7,0xAF,
+ 0xB8,0x1B,0xDD,0x76,0x21,0x70,0x48,0x1C,0xD0,0x06,0x91,0x27,0xD5,0xB0,0x5A,0xA9,
+ 0x93,0xB4,0xEA,0x98,0x8D,0x8F,0xDD,0xC1,0x86,0xFF,0xB7,0xDC,0x90,0xA6,0xC0,0x8F,
+ 0x4D,0xF4,0x35,0xC9,0x34,0x02,0x84,0x92,0x36,0xC3,0xFA,0xB4,0xD2,0x7C,0x70,0x26,
+ 0xC1,0xD4,0xDC,0xB2,0x60,0x26,0x46,0xDE,0xC9,0x75,0x1E,0x76,0x3D,0xBA,0x37,0xBD,
+ 0xF8,0xFF,0x94,0x06,0xAD,0x9E,0x53,0x0E,0xE5,0xDB,0x38,0x2F,0x41,0x30,0x01,0xAE,
+ 0xB0,0x6A,0x53,0xED,0x90,0x27,0xD8,0x31,0x17,0x97,0x27,0xB0,0x86,0x5A,0x89,0x18,
+ 0xDA,0x3E,0xDB,0xEB,0xCF,0x9B,0x14,0xED,0x44,0xCE,0x6C,0xBA,0xCE,0xD4,0xBB,0x1B,
+ 0xDB,0x7F,0x14,0x47,0xE6,0xCC,0x25,0x4B,0x33,0x20,0x51,0x51,0x2B,0xD7,0xAF,0x42,
+ 0x6F,0xB8,0xF4,0x01,0x37,0x8C,0xD2,0xBF,0x59,0x83,0xCA,0x01,0xC6,0x4B,0x92,0xEC,
+ 0xF0,0x32,0xEA,0x15,0xD1,0x72,0x1D,0x03,0xF4,0x82,0xD7,0xCE,0x6E,0x74,0xFE,0xF6,
+ 0xD5,0x5E,0x70,0x2F,0x46,0x98,0x0C,0x82,0xB5,0xA8,0x40,0x31,0x90,0x0B,0x1C,0x9E,
+ 0x59,0xE7,0xC9,0x7F,0xBE,0xC7,0xE8,0xF3,0x23,0xA9,0x7A,0x7E,0x36,0xCC,0x88,0xBE,
+ 0x0F,0x1D,0x45,0xB7,0xFF,0x58,0x5A,0xC5,0x4B,0xD4,0x07,0xB2,0x2B,0x41,0x54,0xAA,
+ 0xCC,0x8F,0x6D,0x7E,0xBF,0x48,0xE1,0xD8,0x14,0xCC,0x5E,0xD2,0x0F,0x80,0x37,0xE0,
+ 0xA7,0x97,0x15,0xEE,0xF2,0x9B,0xE3,0x28,0x06,0xA1,0xD5,0x8B,0xB7,0xC5,0xDA,0x76,
+ 0xF5,0x50,0xAA,0x3D,0x8A,0x1F,0xBF,0xF0,0xEB,0x19,0xCC,0xB1,0xA3,0x13,0xD5,0x5C,
+ 0xDA,0x56,0xC9,0xEC,0x2E,0xF2,0x96,0x32,0x38,0x7F,0xE8,0xD7,0x6E,0x3C,0x04,0x68,
+ 0x04,0x3E,0x8F,0x66,0x3F,0x48,0x60,0xEE,0x12,0xBF,0x2D,0x5B,0x0B,0x74,0x74,0xD6,
+ 0xE6,0x94,0xF9,0x1E,0x6D,0xCC,0x40,0x24,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF
+};
+
+/**
+ * Modulus of Group 18 (MODP_8192_BIT).
+ */
+static u_int8_t group18_modulus[] = {
+ 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xC9,0x0F,0xDA,0xA2,0x21,0x68,0xC2,0x34,
+ 0xC4,0xC6,0x62,0x8B,0x80,0xDC,0x1C,0xD1,0x29,0x02,0x4E,0x08,0x8A,0x67,0xCC,0x74,
+ 0x02,0x0B,0xBE,0xA6,0x3B,0x13,0x9B,0x22,0x51,0x4A,0x08,0x79,0x8E,0x34,0x04,0xDD,
+ 0xEF,0x95,0x19,0xB3,0xCD,0x3A,0x43,0x1B,0x30,0x2B,0x0A,0x6D,0xF2,0x5F,0x14,0x37,
+ 0x4F,0xE1,0x35,0x6D,0x6D,0x51,0xC2,0x45,0xE4,0x85,0xB5,0x76,0x62,0x5E,0x7E,0xC6,
+ 0xF4,0x4C,0x42,0xE9,0xA6,0x37,0xED,0x6B,0x0B,0xFF,0x5C,0xB6,0xF4,0x06,0xB7,0xED,
+ 0xEE,0x38,0x6B,0xFB,0x5A,0x89,0x9F,0xA5,0xAE,0x9F,0x24,0x11,0x7C,0x4B,0x1F,0xE6,
+ 0x49,0x28,0x66,0x51,0xEC,0xE4,0x5B,0x3D,0xC2,0x00,0x7C,0xB8,0xA1,0x63,0xBF,0x05,
+ 0x98,0xDA,0x48,0x36,0x1C,0x55,0xD3,0x9A,0x69,0x16,0x3F,0xA8,0xFD,0x24,0xCF,0x5F,
+ 0x83,0x65,0x5D,0x23,0xDC,0xA3,0xAD,0x96,0x1C,0x62,0xF3,0x56,0x20,0x85,0x52,0xBB,
+ 0x9E,0xD5,0x29,0x07,0x70,0x96,0x96,0x6D,0x67,0x0C,0x35,0x4E,0x4A,0xBC,0x98,0x04,
+ 0xF1,0x74,0x6C,0x08,0xCA,0x18,0x21,0x7C,0x32,0x90,0x5E,0x46,0x2E,0x36,0xCE,0x3B,
+ 0xE3,0x9E,0x77,0x2C,0x18,0x0E,0x86,0x03,0x9B,0x27,0x83,0xA2,0xEC,0x07,0xA2,0x8F,
+ 0xB5,0xC5,0x5D,0xF0,0x6F,0x4C,0x52,0xC9,0xDE,0x2B,0xCB,0xF6,0x95,0x58,0x17,0x18,
+ 0x39,0x95,0x49,0x7C,0xEA,0x95,0x6A,0xE5,0x15,0xD2,0x26,0x18,0x98,0xFA,0x05,0x10,
+ 0x15,0x72,0x8E,0x5A,0x8A,0xAA,0xC4,0x2D,0xAD,0x33,0x17,0x0D,0x04,0x50,0x7A,0x33,
+ 0xA8,0x55,0x21,0xAB,0xDF,0x1C,0xBA,0x64,0xEC,0xFB,0x85,0x04,0x58,0xDB,0xEF,0x0A,
+ 0x8A,0xEA,0x71,0x57,0x5D,0x06,0x0C,0x7D,0xB3,0x97,0x0F,0x85,0xA6,0xE1,0xE4,0xC7,
+ 0xAB,0xF5,0xAE,0x8C,0xDB,0x09,0x33,0xD7,0x1E,0x8C,0x94,0xE0,0x4A,0x25,0x61,0x9D,
+ 0xCE,0xE3,0xD2,0x26,0x1A,0xD2,0xEE,0x6B,0xF1,0x2F,0xFA,0x06,0xD9,0x8A,0x08,0x64,
+ 0xD8,0x76,0x02,0x73,0x3E,0xC8,0x6A,0x64,0x52,0x1F,0x2B,0x18,0x17,0x7B,0x20,0x0C,
+ 0xBB,0xE1,0x17,0x57,0x7A,0x61,0x5D,0x6C,0x77,0x09,0x88,0xC0,0xBA,0xD9,0x46,0xE2,
+ 0x08,0xE2,0x4F,0xA0,0x74,0xE5,0xAB,0x31,0x43,0xDB,0x5B,0xFC,0xE0,0xFD,0x10,0x8E,
+ 0x4B,0x82,0xD1,0x20,0xA9,0x21,0x08,0x01,0x1A,0x72,0x3C,0x12,0xA7,0x87,0xE6,0xD7,
+ 0x88,0x71,0x9A,0x10,0xBD,0xBA,0x5B,0x26,0x99,0xC3,0x27,0x18,0x6A,0xF4,0xE2,0x3C,
+ 0x1A,0x94,0x68,0x34,0xB6,0x15,0x0B,0xDA,0x25,0x83,0xE9,0xCA,0x2A,0xD4,0x4C,0xE8,
+ 0xDB,0xBB,0xC2,0xDB,0x04,0xDE,0x8E,0xF9,0x2E,0x8E,0xFC,0x14,0x1F,0xBE,0xCA,0xA6,
+ 0x28,0x7C,0x59,0x47,0x4E,0x6B,0xC0,0x5D,0x99,0xB2,0x96,0x4F,0xA0,0x90,0xC3,0xA2,
+ 0x23,0x3B,0xA1,0x86,0x51,0x5B,0xE7,0xED,0x1F,0x61,0x29,0x70,0xCE,0xE2,0xD7,0xAF,
+ 0xB8,0x1B,0xDD,0x76,0x21,0x70,0x48,0x1C,0xD0,0x06,0x91,0x27,0xD5,0xB0,0x5A,0xA9,
+ 0x93,0xB4,0xEA,0x98,0x8D,0x8F,0xDD,0xC1,0x86,0xFF,0xB7,0xDC,0x90,0xA6,0xC0,0x8F,
+ 0x4D,0xF4,0x35,0xC9,0x34,0x02,0x84,0x92,0x36,0xC3,0xFA,0xB4,0xD2,0x7C,0x70,0x26,
+ 0xC1,0xD4,0xDC,0xB2,0x60,0x26,0x46,0xDE,0xC9,0x75,0x1E,0x76,0x3D,0xBA,0x37,0xBD,
+ 0xF8,0xFF,0x94,0x06,0xAD,0x9E,0x53,0x0E,0xE5,0xDB,0x38,0x2F,0x41,0x30,0x01,0xAE,
+ 0xB0,0x6A,0x53,0xED,0x90,0x27,0xD8,0x31,0x17,0x97,0x27,0xB0,0x86,0x5A,0x89,0x18,
+ 0xDA,0x3E,0xDB,0xEB,0xCF,0x9B,0x14,0xED,0x44,0xCE,0x6C,0xBA,0xCE,0xD4,0xBB,0x1B,
+ 0xDB,0x7F,0x14,0x47,0xE6,0xCC,0x25,0x4B,0x33,0x20,0x51,0x51,0x2B,0xD7,0xAF,0x42,
+ 0x6F,0xB8,0xF4,0x01,0x37,0x8C,0xD2,0xBF,0x59,0x83,0xCA,0x01,0xC6,0x4B,0x92,0xEC,
+ 0xF0,0x32,0xEA,0x15,0xD1,0x72,0x1D,0x03,0xF4,0x82,0xD7,0xCE,0x6E,0x74,0xFE,0xF6,
+ 0xD5,0x5E,0x70,0x2F,0x46,0x98,0x0C,0x82,0xB5,0xA8,0x40,0x31,0x90,0x0B,0x1C,0x9E,
+ 0x59,0xE7,0xC9,0x7F,0xBE,0xC7,0xE8,0xF3,0x23,0xA9,0x7A,0x7E,0x36,0xCC,0x88,0xBE,
+ 0x0F,0x1D,0x45,0xB7,0xFF,0x58,0x5A,0xC5,0x4B,0xD4,0x07,0xB2,0x2B,0x41,0x54,0xAA,
+ 0xCC,0x8F,0x6D,0x7E,0xBF,0x48,0xE1,0xD8,0x14,0xCC,0x5E,0xD2,0x0F,0x80,0x37,0xE0,
+ 0xA7,0x97,0x15,0xEE,0xF2,0x9B,0xE3,0x28,0x06,0xA1,0xD5,0x8B,0xB7,0xC5,0xDA,0x76,
+ 0xF5,0x50,0xAA,0x3D,0x8A,0x1F,0xBF,0xF0,0xEB,0x19,0xCC,0xB1,0xA3,0x13,0xD5,0x5C,
+ 0xDA,0x56,0xC9,0xEC,0x2E,0xF2,0x96,0x32,0x38,0x7F,0xE8,0xD7,0x6E,0x3C,0x04,0x68,
+ 0x04,0x3E,0x8F,0x66,0x3F,0x48,0x60,0xEE,0x12,0xBF,0x2D,0x5B,0x0B,0x74,0x74,0xD6,
+ 0xE6,0x94,0xF9,0x1E,0x6D,0xBE,0x11,0x59,0x74,0xA3,0x92,0x6F,0x12,0xFE,0xE5,0xE4,
+ 0x38,0x77,0x7C,0xB6,0xA9,0x32,0xDF,0x8C,0xD8,0xBE,0xC4,0xD0,0x73,0xB9,0x31,0xBA,
+ 0x3B,0xC8,0x32,0xB6,0x8D,0x9D,0xD3,0x00,0x74,0x1F,0xA7,0xBF,0x8A,0xFC,0x47,0xED,
+ 0x25,0x76,0xF6,0x93,0x6B,0xA4,0x24,0x66,0x3A,0xAB,0x63,0x9C,0x5A,0xE4,0xF5,0x68,
+ 0x34,0x23,0xB4,0x74,0x2B,0xF1,0xC9,0x78,0x23,0x8F,0x16,0xCB,0xE3,0x9D,0x65,0x2D,
+ 0xE3,0xFD,0xB8,0xBE,0xFC,0x84,0x8A,0xD9,0x22,0x22,0x2E,0x04,0xA4,0x03,0x7C,0x07,
+ 0x13,0xEB,0x57,0xA8,0x1A,0x23,0xF0,0xC7,0x34,0x73,0xFC,0x64,0x6C,0xEA,0x30,0x6B,
+ 0x4B,0xCB,0xC8,0x86,0x2F,0x83,0x85,0xDD,0xFA,0x9D,0x4B,0x7F,0xA2,0xC0,0x87,0xE8,
+ 0x79,0x68,0x33,0x03,0xED,0x5B,0xDD,0x3A,0x06,0x2B,0x3C,0xF5,0xB3,0xA2,0x78,0xA6,
+ 0x6D,0x2A,0x13,0xF8,0x3F,0x44,0xF8,0x2D,0xDF,0x31,0x0E,0xE0,0x74,0xAB,0x6A,0x36,
+ 0x45,0x97,0xE8,0x99,0xA0,0x25,0x5D,0xC1,0x64,0xF3,0x1C,0xC5,0x08,0x46,0x85,0x1D,
+ 0xF9,0xAB,0x48,0x19,0x5D,0xED,0x7E,0xA1,0xB1,0xD5,0x10,0xBD,0x7E,0xE7,0x4D,0x73,
+ 0xFA,0xF3,0x6B,0xC3,0x1E,0xCF,0xA2,0x68,0x35,0x90,0x46,0xF4,0xEB,0x87,0x9F,0x92,
+ 0x40,0x09,0x43,0x8B,0x48,0x1C,0x6C,0xD7,0x88,0x9A,0x00,0x2E,0xD5,0xEE,0x38,0x2B,
+ 0xC9,0x19,0x0D,0xA6,0xFC,0x02,0x6E,0x47,0x95,0x58,0xE4,0x47,0x56,0x77,0xE9,0xAA,
+ 0x9E,0x30,0x50,0xE2,0x76,0x56,0x94,0xDF,0xC8,0x1F,0x56,0xE8,0x80,0xB9,0x6E,0x71,
+ 0x60,0xC9,0x80,0xDD,0x98,0xED,0xD3,0xDF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
+};
+
+typedef struct modulus_entry_t modulus_entry_t;
+
+/**
+ * Entry of the modulus list.
+ */
+struct modulus_entry_t {
+ /**
+ * Group number as it is defined in file transform_substructure.h.
+ */
+ diffie_hellman_group_t group;
+
+ /**
+ * Pointer to first byte of modulus (network order).
+ */
+ u_int8_t *modulus;
+
+ /*
+ * Length of modulus in bytes.
+ */
+ size_t modulus_len;
+
+ /*
+ * Generator value.
+ */
+ u_int16_t generator;
+};
+
+/**
+ * All supported modulus values.
+ */
+static modulus_entry_t modulus_entries[] = {
+ {MODP_768_BIT, group1_modulus, sizeof(group1_modulus), 2},
+ {MODP_1024_BIT, group2_modulus, sizeof(group2_modulus), 2},
+ {MODP_1536_BIT, group5_modulus, sizeof(group5_modulus), 2},
+ {MODP_2048_BIT, group14_modulus, sizeof(group14_modulus), 2},
+ {MODP_3072_BIT, group15_modulus, sizeof(group15_modulus), 2},
+ {MODP_4096_BIT, group16_modulus, sizeof(group16_modulus), 2},
+ {MODP_6144_BIT, group17_modulus, sizeof(group17_modulus), 2},
+ {MODP_8192_BIT, group18_modulus, sizeof(group18_modulus), 2},
+};
+
+typedef struct private_gmp_diffie_hellman_t private_gmp_diffie_hellman_t;
+
+/**
+ * Private data of an gmp_diffie_hellman_t object.
+ */
+struct private_gmp_diffie_hellman_t {
+ /**
+ * Public gmp_diffie_hellman_t interface.
+ */
+ gmp_diffie_hellman_t public;
+
+ /**
+ * Diffie Hellman group number.
+ */
+ u_int16_t group;
+
+ /*
+ * Generator value.
+ */
+ mpz_t g;
+
+ /**
+ * My private value.
+ */
+ mpz_t xa;
+
+ /**
+ * My public value.
+ */
+ mpz_t ya;
+
+ /**
+ * Other public value.
+ */
+ mpz_t yb;
+
+ /**
+ * Shared secret.
+ */
+ mpz_t zz;
+
+ /**
+ * Modulus.
+ */
+ mpz_t p;
+
+ /**
+ * Modulus length.
+ */
+ size_t p_len;
+
+ /**
+ * True if shared secret is computed and stored in my_public_value.
+ */
+ bool computed;
+};
+
+/**
+ * Implementation of gmp_diffie_hellman_t.set_other_public_value.
+ */
+static void set_other_public_value(private_gmp_diffie_hellman_t *this, chunk_t value)
+{
+ mpz_t p_min_1;
+
+ mpz_init(p_min_1);
+ mpz_sub_ui(p_min_1, this->p, 1);
+
+ mpz_import(this->yb, value.len, 1, 1, 1, 0, value.ptr);
+
+ /* check public value:
+ * 1. 0 or 1 is invalid as 0^a = 0 and 1^a = 1
+ * 2. a public value larger or equal the modulus is invalid */
+ if (mpz_cmp_ui(this->yb, 1) > 0 ||
+ mpz_cmp(this->yb, p_min_1) < 0)
+ {
+#ifdef EXTENDED_DH_TEST
+ /* 3. test if y ^ q mod p = 1, where q = (p - 1)/2. */
+ mpz_t q, one;
+
+ mpz_init(q);
+ mpz_init(one);
+ mpz_fdiv_q_2exp(q, p_min_1, 1);
+ mpz_powm(one, this->yb, q, this->p);
+ mpz_clear(q);
+ if (mpz_cmp_ui(one, 1) == 0)
+ {
+ mpz_powm(this->zz, this->yb, this->xa, this->p);
+ this->computed = TRUE;
+ }
+ else
+ {
+ DBG1("public DH value verification failed: y ^ q mod p != 1");
+ }
+ mpz_clear(one);
+#else
+ mpz_powm(this->zz, this->yb, this->xa, this->p);
+ this->computed = TRUE;
+#endif
+ }
+ else
+ {
+ DBG1("public DH value verification failed: y < 2 || y > p - 1 ");
+ }
+ mpz_clear(p_min_1);
+}
+
+/**
+ * Implementation of gmp_diffie_hellman_t.get_other_public_value.
+ */
+static status_t get_other_public_value(private_gmp_diffie_hellman_t *this,
+ chunk_t *value)
+{
+ if (!this->computed)
+ {
+ return FAILED;
+ }
+ value->len = this->p_len;
+ value->ptr = mpz_export(NULL, NULL, 1, value->len, 1, 0, this->yb);
+ return SUCCESS;
+}
+
+/**
+ * Implementation of gmp_diffie_hellman_t.get_my_public_value.
+ */
+static void get_my_public_value(private_gmp_diffie_hellman_t *this,chunk_t *value)
+{
+ value->len = this->p_len;
+ value->ptr = mpz_export(NULL, NULL, 1, value->len, 1, 0, this->ya);
+}
+
+/**
+ * Implementation of gmp_diffie_hellman_t.get_shared_secret.
+ */
+static status_t get_shared_secret(private_gmp_diffie_hellman_t *this, chunk_t *secret)
+{
+ if (!this->computed)
+ {
+ return FAILED;
+ }
+ secret->len = this->p_len;
+ secret->ptr = mpz_export(NULL, NULL, 1, secret->len, 1, 0, this->zz);
+ return SUCCESS;
+}
+
+/**
+ * Implementation of gmp_diffie_hellman_t.get_dh_group.
+ */
+static diffie_hellman_group_t get_dh_group(private_gmp_diffie_hellman_t *this)
+{
+ return this->group;
+}
+
+/**
+ * Lookup the modulus in modulo table
+ */
+static status_t set_modulus(private_gmp_diffie_hellman_t *this)
+{
+ int i;
+ status_t status = NOT_FOUND;
+
+ for (i = 0; i < (sizeof(modulus_entries) / sizeof(modulus_entry_t)); i++)
+ {
+ if (modulus_entries[i].group == this->group)
+ {
+ chunk_t chunk;
+ chunk.ptr = modulus_entries[i].modulus;
+ chunk.len = modulus_entries[i].modulus_len;
+ mpz_import(this->p, chunk.len, 1, 1, 1, 0, chunk.ptr);
+ this->p_len = chunk.len;
+ mpz_set_ui(this->g, modulus_entries[i].generator);
+ status = SUCCESS;
+ break;
+ }
+ }
+ return status;
+}
+
+/**
+ * Implementation of gmp_diffie_hellman_t.destroy.
+ */
+static void destroy(private_gmp_diffie_hellman_t *this)
+{
+ mpz_clear(this->p);
+ mpz_clear(this->xa);
+ mpz_clear(this->ya);
+ mpz_clear(this->yb);
+ mpz_clear(this->zz);
+ mpz_clear(this->g);
+ free(this);
+}
+
+/*
+ * Described in header.
+ */
+gmp_diffie_hellman_t *gmp_diffie_hellman_create(diffie_hellman_group_t group)
+{
+ private_gmp_diffie_hellman_t *this = malloc_thing(private_gmp_diffie_hellman_t);
+ rng_t *rng;
+ chunk_t random;
+
+ /* public functions */
+ this->public.dh.get_shared_secret = (status_t (*)(diffie_hellman_t *, chunk_t *)) get_shared_secret;
+ this->public.dh.set_other_public_value = (void (*)(diffie_hellman_t *, chunk_t )) set_other_public_value;
+ this->public.dh.get_other_public_value = (status_t (*)(diffie_hellman_t *, chunk_t *)) get_other_public_value;
+ this->public.dh.get_my_public_value = (void (*)(diffie_hellman_t *, chunk_t *)) get_my_public_value;
+ this->public.dh.get_dh_group = (diffie_hellman_group_t (*)(diffie_hellman_t *)) get_dh_group;
+ this->public.dh.destroy = (void (*)(diffie_hellman_t *)) destroy;
+
+ /* private variables */
+ this->group = group;
+ mpz_init(this->p);
+ mpz_init(this->yb);
+ mpz_init(this->ya);
+ mpz_init(this->xa);
+ mpz_init(this->zz);
+ mpz_init(this->g);
+
+ this->computed = FALSE;
+
+ /* find a modulus according to group */
+ if (set_modulus(this) != SUCCESS)
+ {
+ destroy(this);
+ return NULL;
+ }
+ rng = lib->crypto->create_rng(lib->crypto, RNG_STRONG);
+ if (!rng)
+ {
+ DBG1("no RNG found for quality %N", rng_quality_names, RNG_STRONG);
+ destroy(this);
+ return NULL;
+ }
+ rng->allocate_bytes(rng, this->p_len, &random);
+ rng->destroy(rng);
+ mpz_import(this->xa, random.len, 1, 1, 1, 0, random.ptr);
+ chunk_free(&random);
+
+ mpz_powm(this->ya, this->g, this->xa, this->p);
+
+ return &this->public;
+}
+
diff --git a/src/libstrongswan/plugins/gmp/gmp_diffie_hellman.h b/src/libstrongswan/plugins/gmp/gmp_diffie_hellman.h
new file mode 100644
index 000000000..e2d4d6851
--- /dev/null
+++ b/src/libstrongswan/plugins/gmp/gmp_diffie_hellman.h
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2005-2007 Martin Willi
+ * Copyright (C) 2005 Jan Hutter
+ * Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+/**
+ * @defgroup gmp_diffie_hellman gmp_diffie_hellman
+ * @{ @ingroup gmp_p
+ */
+
+#ifndef GMP_DIFFIE_HELLMAN_H_
+#define GMP_DIFFIE_HELLMAN_H_
+
+typedef struct gmp_diffie_hellman_t gmp_diffie_hellman_t;
+
+#include <library.h>
+
+/**
+ * Implementation of the Diffie-Hellman algorithm, as in RFC2631. Uses libgmp.
+ */
+struct gmp_diffie_hellman_t {
+
+ /**
+ * Implements diffie_hellman_t interface.
+ */
+ diffie_hellman_t dh;
+};
+
+/**
+ * Creates a new gmp_diffie_hellman_t object.
+ *
+ * @param group Diffie Hellman group number to use
+ * @return gmp_diffie_hellman_t object, NULL if not supported
+ */
+gmp_diffie_hellman_t *gmp_diffie_hellman_create(diffie_hellman_group_t group);
+
+#endif /*GMP_DIFFIE_HELLMAN_H_ @}*/
+
diff --git a/src/libstrongswan/plugins/gmp/gmp_plugin.c b/src/libstrongswan/plugins/gmp/gmp_plugin.c
new file mode 100644
index 000000000..56fb0ddd8
--- /dev/null
+++ b/src/libstrongswan/plugins/gmp/gmp_plugin.c
@@ -0,0 +1,85 @@
+/*
+ * Copyright (C) 2008 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.
+ *
+ * $Id: gmp_plugin.c 3962 2008-05-15 12:39:35Z tobias $
+ */
+
+#include "gmp_plugin.h"
+
+#include <library.h>
+#include "gmp_diffie_hellman.h"
+#include "gmp_rsa_private_key.h"
+#include "gmp_rsa_public_key.h"
+
+typedef struct private_gmp_plugin_t private_gmp_plugin_t;
+
+/**
+ * private data of gmp_plugin
+ */
+struct private_gmp_plugin_t {
+
+ /**
+ * public functions
+ */
+ gmp_plugin_t public;
+};
+
+/**
+ * Implementation of gmp_plugin_t.gmptroy
+ */
+static void destroy(private_gmp_plugin_t *this)
+{
+ lib->crypto->remove_dh(lib->crypto,
+ (dh_constructor_t)gmp_diffie_hellman_create);
+ lib->creds->remove_builder(lib->creds,
+ (builder_constructor_t)gmp_rsa_private_key_builder);
+ lib->creds->remove_builder(lib->creds,
+ (builder_constructor_t)gmp_rsa_public_key_builder);
+ free(this);
+}
+
+/*
+ * see header file
+ */
+plugin_t *plugin_create()
+{
+ private_gmp_plugin_t *this = malloc_thing(private_gmp_plugin_t);
+
+ this->public.plugin.destroy = (void(*)(plugin_t*))destroy;
+
+ lib->crypto->add_dh(lib->crypto, MODP_768_BIT,
+ (dh_constructor_t)gmp_diffie_hellman_create);
+ lib->crypto->add_dh(lib->crypto, MODP_1024_BIT,
+ (dh_constructor_t)gmp_diffie_hellman_create);
+ lib->crypto->add_dh(lib->crypto, MODP_1536_BIT,
+ (dh_constructor_t)gmp_diffie_hellman_create);
+ lib->crypto->add_dh(lib->crypto, MODP_2048_BIT,
+ (dh_constructor_t)gmp_diffie_hellman_create);
+ lib->crypto->add_dh(lib->crypto, MODP_3072_BIT,
+ (dh_constructor_t)gmp_diffie_hellman_create);
+ lib->crypto->add_dh(lib->crypto, MODP_4096_BIT,
+ (dh_constructor_t)gmp_diffie_hellman_create);
+ lib->crypto->add_dh(lib->crypto, MODP_6144_BIT,
+ (dh_constructor_t)gmp_diffie_hellman_create);
+ lib->crypto->add_dh(lib->crypto, MODP_8192_BIT,
+ (dh_constructor_t)gmp_diffie_hellman_create);
+
+ lib->creds->add_builder(lib->creds, CRED_PRIVATE_KEY, KEY_RSA,
+ (builder_constructor_t)gmp_rsa_private_key_builder);
+ lib->creds->add_builder(lib->creds, CRED_PUBLIC_KEY, KEY_RSA,
+ (builder_constructor_t)gmp_rsa_public_key_builder);
+
+ return &this->public.plugin;
+}
+
diff --git a/src/libstrongswan/plugins/gmp/gmp_plugin.h b/src/libstrongswan/plugins/gmp/gmp_plugin.h
new file mode 100644
index 000000000..a853064b7
--- /dev/null
+++ b/src/libstrongswan/plugins/gmp/gmp_plugin.h
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2008 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.
+ */
+
+/**
+ * @defgroup gmp_p gmp
+ * @ingroup plugins
+ *
+ * @defgroup gmp_plugin gmp_plugin
+ * @{ @ingroup gmp_p
+ */
+
+#ifndef GMP_PLUGIN_H_
+#define GMP_PLUGIN_H_
+
+#include <plugins/plugin.h>
+
+typedef struct gmp_plugin_t gmp_plugin_t;
+
+/**
+ * Plugin implementing asymmetric crypto algorithms using the GNU MP library.
+ */
+struct gmp_plugin_t {
+
+ /**
+ * implements plugin interface
+ */
+ plugin_t plugin;
+};
+
+/**
+ * Create a gmp_plugin instance.
+ */
+plugin_t *plugin_create();
+
+#endif /* GMP_PLUGIN_H_ @}*/
diff --git a/src/libstrongswan/plugins/gmp/gmp_rsa_private_key.c b/src/libstrongswan/plugins/gmp/gmp_rsa_private_key.c
new file mode 100644
index 000000000..cd951f0e4
--- /dev/null
+++ b/src/libstrongswan/plugins/gmp/gmp_rsa_private_key.c
@@ -0,0 +1,842 @@
+/*
+ * Copyright (C) 2005-2008 Martin Willi
+ * Copyright (C) 2005 Jan Hutter
+ * 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.
+ *
+ * $Id: gmp_rsa_private_key.c 4014 2008-05-23 19:23:04Z andreas $
+ */
+
+#include <gmp.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <string.h>
+
+#include "gmp_rsa_private_key.h"
+#include "gmp_rsa_public_key.h"
+
+#include <debug.h>
+#include <asn1/oid.h>
+#include <asn1/asn1.h>
+#include <asn1/asn1_parser.h>
+
+/**
+ * Public exponent to use for key generation.
+ */
+#define PUBLIC_EXPONENT 0x10001
+
+typedef struct private_gmp_rsa_private_key_t private_gmp_rsa_private_key_t;
+
+/**
+ * Private data of a gmp_rsa_private_key_t object.
+ */
+struct private_gmp_rsa_private_key_t {
+ /**
+ * Public interface for this signer.
+ */
+ gmp_rsa_private_key_t public;
+
+ /**
+ * Version of key, as encoded in PKCS#1
+ */
+ u_int version;
+
+ /**
+ * Public modulus.
+ */
+ mpz_t n;
+
+ /**
+ * Public exponent.
+ */
+ mpz_t e;
+
+ /**
+ * Private prime 1.
+ */
+ mpz_t p;
+
+ /**
+ * Private Prime 2.
+ */
+ mpz_t q;
+
+ /**
+ * Private exponent.
+ */
+ mpz_t d;
+
+ /**
+ * Private exponent 1.
+ */
+ mpz_t exp1;
+
+ /**
+ * Private exponent 2.
+ */
+ mpz_t exp2;
+
+ /**
+ * Private coefficient.
+ */
+ mpz_t coeff;
+
+ /**
+ * Keysize in bytes.
+ */
+ size_t k;
+
+ /**
+ * Keyid formed as a SHA-1 hash of a publicKey object
+ */
+ identification_t* keyid;
+
+ /**
+ * Keyid formed as a SHA-1 hash of a publicKeyInfo object
+ */
+ identification_t* keyid_info;
+
+ /**
+ * reference count
+ */
+ refcount_t ref;
+};
+
+/**
+ * shared functions, implemented in gmp_rsa_public_key.c
+ */
+bool gmp_rsa_public_key_build_id(mpz_t n, mpz_t e, identification_t **keyid,
+ identification_t **keyid_info);
+gmp_rsa_public_key_t *gmp_rsa_public_key_create_from_n_e(mpz_t n, mpz_t e);
+
+/**
+ * Auxiliary function overwriting private key material with zero bytes
+ */
+static void mpz_clear_randomized(mpz_t z)
+{
+ size_t len = mpz_size(z) * GMP_LIMB_BITS / BITS_PER_BYTE;
+ u_int8_t *random = alloca(len);
+
+ memset(random, 0, len);
+ /* overwrite mpz_t with zero bytes before clearing it */
+ mpz_import(z, len, 1, 1, 1, 0, random);
+ mpz_clear(z);
+}
+
+/**
+ * Create a mpz prime of at least prime_size
+ */
+static status_t compute_prime(private_gmp_rsa_private_key_t *this,
+ size_t prime_size, mpz_t *prime)
+{
+ rng_t *rng;
+ chunk_t random_bytes;
+
+ rng = lib->crypto->create_rng(lib->crypto, RNG_REAL);
+ if (!rng)
+ {
+ DBG1("no RNG of quality %N found", rng_quality_names, RNG_REAL);
+ return FAILED;
+ }
+
+ mpz_init(*prime);
+ do
+ {
+ rng->allocate_bytes(rng, prime_size, &random_bytes);
+ /* make sure most significant bit is set */
+ random_bytes.ptr[0] = random_bytes.ptr[0] | 0x80;
+
+ mpz_import(*prime, random_bytes.len, 1, 1, 1, 0, random_bytes.ptr);
+ mpz_nextprime (*prime, *prime);
+ chunk_clear(&random_bytes);
+ }
+ /* check if it isn't too large */
+ while (((mpz_sizeinbase(*prime, 2) + 7) / 8) > prime_size);
+
+ rng->destroy(rng);
+ return SUCCESS;
+}
+
+/**
+ * PKCS#1 RSADP function
+ */
+static chunk_t rsadp(private_gmp_rsa_private_key_t *this, chunk_t data)
+{
+ mpz_t t1, t2;
+ chunk_t decrypted;
+
+ mpz_init(t1);
+ mpz_init(t2);
+
+ mpz_import(t1, data.len, 1, 1, 1, 0, data.ptr);
+
+ mpz_powm(t2, t1, this->exp1, this->p); /* m1 = c^dP mod p */
+ mpz_powm(t1, t1, this->exp2, this->q); /* m2 = c^dQ mod Q */
+ mpz_sub(t2, t2, t1); /* h = qInv (m1 - m2) mod p */
+ mpz_mod(t2, t2, this->p);
+ mpz_mul(t2, t2, this->coeff);
+ mpz_mod(t2, t2, this->p);
+
+ mpz_mul(t2, t2, this->q); /* m = m2 + h q */
+ mpz_add(t1, t1, t2);
+
+ decrypted.len = this->k;
+ decrypted.ptr = mpz_export(NULL, NULL, 1, decrypted.len, 1, 0, t1);
+
+ mpz_clear_randomized(t1);
+ mpz_clear_randomized(t2);
+
+ return decrypted;
+}
+
+/**
+ * PKCS#1 RSASP1 function
+ */
+static chunk_t rsasp1(private_gmp_rsa_private_key_t *this, chunk_t data)
+{
+ return rsadp(this, data);
+}
+
+/**
+ * Implementation of gmp_rsa_private_key_t.build_emsa_pkcs1_signature.
+ */
+static bool build_emsa_pkcs1_signature(private_gmp_rsa_private_key_t *this,
+ hash_algorithm_t hash_algorithm,
+ chunk_t data, chunk_t *signature)
+{
+ hasher_t *hasher;
+ chunk_t em, digestInfo, hash;
+ int hash_oid = hasher_algorithm_to_oid(hash_algorithm);
+
+ if (hash_oid == OID_UNKNOWN)
+ {
+ return FALSE;
+ }
+
+ /* get hasher */
+ hasher = lib->crypto->create_hasher(lib->crypto, hash_algorithm);
+ if (hasher == NULL)
+ {
+ return FALSE;
+ }
+
+ /* build hash */
+ hasher->allocate_hash(hasher, data, &hash);
+ hasher->destroy(hasher);
+
+ /* build DER-encoded digestInfo */
+ digestInfo = asn1_wrap(ASN1_SEQUENCE, "cm",
+ asn1_algorithmIdentifier(hash_oid),
+ asn1_simple_object(ASN1_OCTET_STRING, hash)
+ );
+ chunk_free(&hash);
+
+ /* build chunk to rsa-decrypt:
+ * EM = 0x00 || 0x01 || PS || 0x00 || T.
+ * PS = 0xFF padding, with length to fill em
+ * T = encoded_hash
+ */
+ em.len = this->k;
+ em.ptr = malloc(em.len);
+
+ /* fill em with padding */
+ memset(em.ptr, 0xFF, em.len);
+ /* set magic bytes */
+ *(em.ptr) = 0x00;
+ *(em.ptr+1) = 0x01;
+ *(em.ptr + em.len - digestInfo.len - 1) = 0x00;
+ /* set DER-encoded hash */
+ memcpy(em.ptr + em.len - digestInfo.len, digestInfo.ptr, digestInfo.len);
+
+ /* build signature */
+ *signature = rsasp1(this, em);
+
+ free(digestInfo.ptr);
+ free(em.ptr);
+
+ return TRUE;
+}
+
+/**
+ * Implementation of gmp_rsa_private_key.destroy.
+ */
+static key_type_t get_type(private_gmp_rsa_private_key_t *this)
+{
+ return KEY_RSA;
+}
+
+/**
+ * Implementation of gmp_rsa_private_key.destroy.
+ */
+static bool sign(private_gmp_rsa_private_key_t *this, signature_scheme_t scheme,
+ chunk_t data, chunk_t *signature)
+{
+ switch (scheme)
+ {
+ case SIGN_DEFAULT:
+ /* default is EMSA-PKCS1 using SHA1 */
+ case SIGN_RSA_EMSA_PKCS1_SHA1:
+ return build_emsa_pkcs1_signature(this, HASH_SHA1, data, signature);
+ case SIGN_RSA_EMSA_PKCS1_SHA256:
+ return build_emsa_pkcs1_signature(this, HASH_SHA256, data, signature);
+ case SIGN_RSA_EMSA_PKCS1_SHA384:
+ return build_emsa_pkcs1_signature(this, HASH_SHA384, data, signature);
+ case SIGN_RSA_EMSA_PKCS1_SHA512:
+ return build_emsa_pkcs1_signature(this, HASH_SHA512, data, signature);
+ case SIGN_RSA_EMSA_PKCS1_MD5:
+ return build_emsa_pkcs1_signature(this, HASH_MD5, data, signature);
+ default:
+ DBG1("signature scheme %N not supported in RSA",
+ signature_scheme_names, scheme);
+ return FALSE;
+ }
+}
+
+/**
+ * Implementation of gmp_rsa_private_key.destroy.
+ */
+static bool decrypt(private_gmp_rsa_private_key_t *this,
+ chunk_t crypto, chunk_t *plain)
+{
+ DBG1("RSA private key decryption not implemented");
+ return FALSE;
+}
+
+/**
+ * Implementation of gmp_rsa_private_key.destroy.
+ */
+static size_t get_keysize(private_gmp_rsa_private_key_t *this)
+{
+ return this->k;
+}
+
+/**
+ * Implementation of gmp_rsa_private_key.destroy.
+ */
+static identification_t* get_id(private_gmp_rsa_private_key_t *this,
+ id_type_t type)
+{
+ switch (type)
+ {
+ case ID_PUBKEY_INFO_SHA1:
+ return this->keyid_info;
+ case ID_PUBKEY_SHA1:
+ return this->keyid;
+ default:
+ return NULL;
+ }
+}
+
+/**
+ * Implementation of gmp_rsa_private_key.get_public_key.
+ */
+static gmp_rsa_public_key_t* get_public_key(private_gmp_rsa_private_key_t *this)
+{
+ return gmp_rsa_public_key_create_from_n_e(this->n, this->e);
+}
+
+/**
+ * Implementation of gmp_rsa_private_key.destroy.
+ */
+static bool belongs_to(private_gmp_rsa_private_key_t *this, public_key_t *public)
+{
+ identification_t *keyid;
+
+ if (public->get_type(public) != KEY_RSA)
+ {
+ return FALSE;
+ }
+ keyid = public->get_id(public, ID_PUBKEY_SHA1);
+ if (keyid && keyid->equals(keyid, this->keyid))
+ {
+ return TRUE;
+ }
+ keyid = public->get_id(public, ID_PUBKEY_INFO_SHA1);
+ if (keyid && keyid->equals(keyid, this->keyid_info))
+ {
+ return TRUE;
+ }
+ return FALSE;
+}
+
+/**
+ * convert a MP integer into a DER coded ASN.1 object
+ */
+chunk_t gmp_mpz_to_asn1(const mpz_t value)
+{
+ chunk_t n;
+
+ n.len = 1 + mpz_sizeinbase(value, 2) / 8; /* size in bytes */
+ n.ptr = mpz_export(NULL, NULL, 1, n.len, 1, 0, value);
+ if (n.ptr == NULL)
+ { /* if we have zero in "value", gmp returns NULL */
+ n.len = 0;
+ }
+ return asn1_wrap(ASN1_INTEGER, "m", n);
+}
+
+/**
+ * Implementation of private_key_t.get_encoding.
+ */
+static chunk_t get_encoding(private_gmp_rsa_private_key_t *this)
+{
+ return asn1_wrap(ASN1_SEQUENCE, "cmmmmmmmm",
+ ASN1_INTEGER_0,
+ gmp_mpz_to_asn1(this->n),
+ gmp_mpz_to_asn1(this->e),
+ gmp_mpz_to_asn1(this->d),
+ gmp_mpz_to_asn1(this->p),
+ gmp_mpz_to_asn1(this->q),
+ gmp_mpz_to_asn1(this->exp1),
+ gmp_mpz_to_asn1(this->exp2),
+ gmp_mpz_to_asn1(this->coeff));
+}
+
+/**
+ * Implementation of gmp_rsa_private_key.destroy.
+ */
+static private_gmp_rsa_private_key_t* get_ref(private_gmp_rsa_private_key_t *this)
+{
+ ref_get(&this->ref);
+ return this;
+
+}
+
+/**
+ * Implementation of gmp_rsa_private_key.destroy.
+ */
+static void destroy(private_gmp_rsa_private_key_t *this)
+{
+ if (ref_put(&this->ref))
+ {
+ mpz_clear_randomized(this->n);
+ mpz_clear_randomized(this->e);
+ mpz_clear_randomized(this->p);
+ mpz_clear_randomized(this->q);
+ mpz_clear_randomized(this->d);
+ mpz_clear_randomized(this->exp1);
+ mpz_clear_randomized(this->exp2);
+ mpz_clear_randomized(this->coeff);
+ DESTROY_IF(this->keyid);
+ DESTROY_IF(this->keyid_info);
+ free(this);
+ }
+}
+
+/**
+ * Check the loaded key if it is valid and usable
+ */
+static status_t check(private_gmp_rsa_private_key_t *this)
+{
+ mpz_t t, u, q1;
+ status_t status = SUCCESS;
+
+ /* PKCS#1 1.5 section 6 requires modulus to have at least 12 octets.
+ * We actually require more (for security).
+ */
+ if (this->k < 512/8)
+ {
+ DBG1("key shorter than 512 bits");
+ return FAILED;
+ }
+
+ /* we picked a max modulus size to simplify buffer allocation */
+ if (this->k > 8192/8)
+ {
+ DBG1("key larger than 8192 bits");
+ return FAILED;
+ }
+
+ mpz_init(t);
+ mpz_init(u);
+ mpz_init(q1);
+
+ /* check that n == p * q */
+ mpz_mul(u, this->p, this->q);
+ if (mpz_cmp(u, this->n) != 0)
+ {
+ status = FAILED;
+ }
+
+ /* check that e divides neither p-1 nor q-1 */
+ mpz_sub_ui(t, this->p, 1);
+ mpz_mod(t, t, this->e);
+ if (mpz_cmp_ui(t, 0) == 0)
+ {
+ status = FAILED;
+ }
+
+ mpz_sub_ui(t, this->q, 1);
+ mpz_mod(t, t, this->e);
+ if (mpz_cmp_ui(t, 0) == 0)
+ {
+ status = FAILED;
+ }
+
+ /* check that d is e^-1 (mod lcm(p-1, q-1)) */
+ /* see PKCS#1v2, aka RFC 2437, for the "lcm" */
+ mpz_sub_ui(q1, this->q, 1);
+ mpz_sub_ui(u, this->p, 1);
+ mpz_gcd(t, u, q1); /* t := gcd(p-1, q-1) */
+ mpz_mul(u, u, q1); /* u := (p-1) * (q-1) */
+ mpz_divexact(u, u, t); /* u := lcm(p-1, q-1) */
+
+ mpz_mul(t, this->d, this->e);
+ mpz_mod(t, t, u);
+ if (mpz_cmp_ui(t, 1) != 0)
+ {
+ status = FAILED;
+ }
+
+ /* check that exp1 is d mod (p-1) */
+ mpz_sub_ui(u, this->p, 1);
+ mpz_mod(t, this->d, u);
+ if (mpz_cmp(t, this->exp1) != 0)
+ {
+ status = FAILED;
+ }
+
+ /* check that exp2 is d mod (q-1) */
+ mpz_sub_ui(u, this->q, 1);
+ mpz_mod(t, this->d, u);
+ if (mpz_cmp(t, this->exp2) != 0)
+ {
+ status = FAILED;
+ }
+
+ /* check that coeff is (q^-1) mod p */
+ mpz_mul(t, this->coeff, this->q);
+ mpz_mod(t, t, this->p);
+ if (mpz_cmp_ui(t, 1) != 0)
+ {
+ status = FAILED;
+ }
+
+ mpz_clear_randomized(t);
+ mpz_clear_randomized(u);
+ mpz_clear_randomized(q1);
+ if (status != SUCCESS)
+ {
+ DBG1("key integrity tests failed");
+ }
+ return status;
+}
+
+/**
+ * Internal generic constructor
+ */
+static private_gmp_rsa_private_key_t *gmp_rsa_private_key_create_empty(void)
+{
+ private_gmp_rsa_private_key_t *this = malloc_thing(private_gmp_rsa_private_key_t);
+
+ this->public.interface.get_type = (key_type_t (*)(private_key_t *this))get_type;
+ this->public.interface.sign = (bool (*)(private_key_t *this, signature_scheme_t scheme, chunk_t data, chunk_t *signature))sign;
+ this->public.interface.decrypt = (bool (*)(private_key_t *this, chunk_t crypto, chunk_t *plain))decrypt;
+ this->public.interface.get_keysize = (size_t (*) (private_key_t *this))get_keysize;
+ this->public.interface.get_id = (identification_t* (*) (private_key_t *this,id_type_t))get_id;
+ this->public.interface.get_public_key = (public_key_t* (*)(private_key_t *this))get_public_key;
+ this->public.interface.belongs_to = (bool (*) (private_key_t *this, public_key_t *public))belongs_to;
+ this->public.interface.get_encoding = (chunk_t(*)(private_key_t*))get_encoding;
+ this->public.interface.get_ref = (private_key_t* (*)(private_key_t *this))get_ref;
+ this->public.interface.destroy = (void (*)(private_key_t *this))destroy;
+
+ this->keyid = NULL;
+ this->keyid_info = NULL;
+ this->ref = 1;
+
+ return this;
+}
+
+/**
+ * Generate an RSA key of specified key size
+ */
+static gmp_rsa_private_key_t *generate(size_t key_size)
+{
+ mpz_t p, q, n, e, d, exp1, exp2, coeff;
+ mpz_t m, q1, t;
+ private_gmp_rsa_private_key_t *this = gmp_rsa_private_key_create_empty();
+
+ key_size = key_size / 8;
+
+ /* Get values of primes p and q */
+ if (compute_prime(this, key_size/2, &p) != SUCCESS)
+ {
+ free(this);
+ return NULL;
+ }
+ if (compute_prime(this, key_size/2, &q) != SUCCESS)
+ {
+ mpz_clear(p);
+ free(this);
+ return NULL;
+ }
+
+ mpz_init(t);
+ mpz_init(n);
+ mpz_init(d);
+ mpz_init(exp1);
+ mpz_init(exp2);
+ mpz_init(coeff);
+
+ /* Swapping Primes so p is larger then q */
+ if (mpz_cmp(p, q) < 0)
+ {
+ mpz_swap(p, q);
+ }
+
+ mpz_mul(n, p, q); /* n = p*q */
+ mpz_init_set_ui(e, PUBLIC_EXPONENT); /* assign public exponent */
+ mpz_init_set(m, p); /* m = p */
+ mpz_sub_ui(m, m, 1); /* m = m -1 */
+ mpz_init_set(q1, q); /* q1 = q */
+ mpz_sub_ui(q1, q1, 1); /* q1 = q1 -1 */
+ mpz_gcd(t, m, q1); /* t = gcd(p-1, q-1) */
+ mpz_mul(m, m, q1); /* m = (p-1)*(q-1) */
+ mpz_divexact(m, m, t); /* m = m / t */
+ mpz_gcd(t, m, e); /* t = gcd(m, e) */
+
+ mpz_invert(d, e, m); /* e has an inverse mod m */
+ if (mpz_cmp_ui(d, 0) < 0) /* make sure d is positive */
+ {
+ mpz_add(d, d, m);
+ }
+ mpz_sub_ui(t, p, 1); /* t = p-1 */
+ mpz_mod(exp1, d, t); /* exp1 = d mod p-1 */
+ mpz_sub_ui(t, q, 1); /* t = q-1 */
+ mpz_mod(exp2, d, t); /* exp2 = d mod q-1 */
+
+ mpz_invert(coeff, q, p); /* coeff = q^-1 mod p */
+ if (mpz_cmp_ui(coeff, 0) < 0) /* make coeff d is positive */
+ {
+ mpz_add(coeff, coeff, p);
+ }
+
+ mpz_clear_randomized(q1);
+ mpz_clear_randomized(m);
+ mpz_clear_randomized(t);
+
+ /* apply values */
+ *(this->p) = *p;
+ *(this->q) = *q;
+ *(this->n) = *n;
+ *(this->e) = *e;
+ *(this->d) = *d;
+ *(this->exp1) = *exp1;
+ *(this->exp2) = *exp2;
+ *(this->coeff) = *coeff;
+
+ /* set key size in bytes */
+ this->k = key_size;
+
+ return &this->public;
+}
+
+/**
+ * ASN.1 definition of a PKCS#1 RSA private key
+ */
+static const asn1Object_t privkeyObjects[] = {
+ { 0, "RSAPrivateKey", ASN1_SEQUENCE, ASN1_NONE }, /* 0 */
+ { 1, "version", ASN1_INTEGER, ASN1_BODY }, /* 1 */
+ { 1, "modulus", ASN1_INTEGER, ASN1_BODY }, /* 2 */
+ { 1, "publicExponent", ASN1_INTEGER, ASN1_BODY }, /* 3 */
+ { 1, "privateExponent", ASN1_INTEGER, ASN1_BODY }, /* 4 */
+ { 1, "prime1", ASN1_INTEGER, ASN1_BODY }, /* 5 */
+ { 1, "prime2", ASN1_INTEGER, ASN1_BODY }, /* 6 */
+ { 1, "exponent1", ASN1_INTEGER, ASN1_BODY }, /* 7 */
+ { 1, "exponent2", ASN1_INTEGER, ASN1_BODY }, /* 8 */
+ { 1, "coefficient", ASN1_INTEGER, ASN1_BODY }, /* 9 */
+ { 1, "otherPrimeInfos", ASN1_SEQUENCE, ASN1_OPT |
+ ASN1_LOOP }, /* 10 */
+ { 2, "otherPrimeInfo", ASN1_SEQUENCE, ASN1_NONE }, /* 11 */
+ { 3, "prime", ASN1_INTEGER, ASN1_BODY }, /* 12 */
+ { 3, "exponent", ASN1_INTEGER, ASN1_BODY }, /* 13 */
+ { 3, "coefficient", ASN1_INTEGER, ASN1_BODY }, /* 14 */
+ { 1, "end opt or loop", ASN1_EOC, ASN1_END }, /* 15 */
+ { 0, "exit", ASN1_EOC, ASN1_EXIT }
+};
+#define PRIV_KEY_VERSION 1
+#define PRIV_KEY_MODULUS 2
+#define PRIV_KEY_PUB_EXP 3
+#define PRIV_KEY_PRIV_EXP 4
+#define PRIV_KEY_PRIME1 5
+#define PRIV_KEY_PRIME2 6
+#define PRIV_KEY_EXP1 7
+#define PRIV_KEY_EXP2 8
+#define PRIV_KEY_COEFF 9
+
+/**
+ * load private key from a ASN1 encoded blob
+ */
+static gmp_rsa_private_key_t *load(chunk_t blob)
+{
+ asn1_parser_t *parser;
+ chunk_t object;
+ int objectID ;
+ bool success = FALSE;
+
+ private_gmp_rsa_private_key_t *this = gmp_rsa_private_key_create_empty();
+
+ mpz_init(this->n);
+ mpz_init(this->e);
+ mpz_init(this->p);
+ mpz_init(this->q);
+ mpz_init(this->d);
+ mpz_init(this->exp1);
+ mpz_init(this->exp2);
+ mpz_init(this->coeff);
+
+ parser = asn1_parser_create(privkeyObjects, blob);
+ parser->set_flags(parser, FALSE, TRUE);
+
+ while (parser->iterate(parser, &objectID, &object))
+ {
+ switch (objectID)
+ {
+ case PRIV_KEY_VERSION:
+ if (object.len > 0 && *object.ptr != 0)
+ {
+ goto end;
+ }
+ break;
+ case PRIV_KEY_MODULUS:
+ mpz_import(this->n, object.len, 1, 1, 1, 0, object.ptr);
+ break;
+ case PRIV_KEY_PUB_EXP:
+ mpz_import(this->e, object.len, 1, 1, 1, 0, object.ptr);
+ break;
+ case PRIV_KEY_PRIV_EXP:
+ mpz_import(this->d, object.len, 1, 1, 1, 0, object.ptr);
+ break;
+ case PRIV_KEY_PRIME1:
+ mpz_import(this->p, object.len, 1, 1, 1, 0, object.ptr);
+ break;
+ case PRIV_KEY_PRIME2:
+ mpz_import(this->q, object.len, 1, 1, 1, 0, object.ptr);
+ break;
+ case PRIV_KEY_EXP1:
+ mpz_import(this->exp1, object.len, 1, 1, 1, 0, object.ptr);
+ break;
+ case PRIV_KEY_EXP2:
+ mpz_import(this->exp2, object.len, 1, 1, 1, 0, object.ptr);
+ break;
+ case PRIV_KEY_COEFF:
+ mpz_import(this->coeff, object.len, 1, 1, 1, 0, object.ptr);
+ break;
+ }
+ }
+ success = parser->success(parser);
+
+end:
+ parser->destroy(parser);
+ chunk_clear(&blob);
+
+ if (!success)
+ {
+ destroy(this);
+ return NULL;
+ }
+
+ this->k = (mpz_sizeinbase(this->n, 2) + 7) / BITS_PER_BYTE;
+
+ if (!gmp_rsa_public_key_build_id(this->n, this->e,
+ &this->keyid, &this->keyid_info))
+ {
+ destroy(this);
+ return NULL;
+ }
+
+ if (check(this) != SUCCESS)
+ {
+ destroy(this);
+ return NULL;
+ }
+ return &this->public;
+}
+
+typedef struct private_builder_t private_builder_t;
+/**
+ * Builder implementation for key loading/generation
+ */
+struct private_builder_t {
+ /** implements the builder interface */
+ builder_t public;
+ /** loaded/generated private key */
+ gmp_rsa_private_key_t *key;
+};
+
+/**
+ * Implementation of builder_t.build
+ */
+static gmp_rsa_private_key_t *build(private_builder_t *this)
+{
+ gmp_rsa_private_key_t *key = this->key;
+
+ free(this);
+ return key;
+}
+
+/**
+ * Implementation of builder_t.add
+ */
+static void add(private_builder_t *this, builder_part_t part, ...)
+{
+ va_list args;
+
+ if (this->key)
+ {
+ DBG1("ignoring surplus build part %N", builder_part_names, part);
+ return;
+ }
+
+ switch (part)
+ {
+ case BUILD_BLOB_ASN1_DER:
+ {
+ va_start(args, part);
+ this->key = load(va_arg(args, chunk_t));
+ va_end(args);
+ break;
+ }
+ case BUILD_KEY_SIZE:
+ {
+ va_start(args, part);
+ this->key = generate(va_arg(args, u_int));
+ va_end(args);
+ break;
+ }
+ default:
+ DBG1("ignoring unsupported build part %N", builder_part_names, part);
+ break;
+ }
+}
+
+/**
+ * Builder construction function
+ */
+builder_t *gmp_rsa_private_key_builder(key_type_t type)
+{
+ private_builder_t *this;
+
+ if (type != KEY_RSA)
+ {
+ return NULL;
+ }
+
+ this = malloc_thing(private_builder_t);
+
+ this->key = NULL;
+ this->public.add = (void(*)(builder_t *this, builder_part_t part, ...))add;
+ this->public.build = (void*(*)(builder_t *this))build;
+
+ return &this->public;
+}
+
diff --git a/src/libstrongswan/plugins/gmp/gmp_rsa_private_key.h b/src/libstrongswan/plugins/gmp/gmp_rsa_private_key.h
new file mode 100644
index 000000000..6f59b2ad2
--- /dev/null
+++ b/src/libstrongswan/plugins/gmp/gmp_rsa_private_key.h
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2005-2008 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.
+ */
+
+/**
+ * @defgroup gmp_rsa_private_key gmp_rsa_private_key
+ * @{ @ingroup gmp_p
+ */
+
+#ifndef GMP_RSA_PRIVATE_KEY_H_
+#define GMP_RSA_PRIVATE_KEY_H_
+
+#include <credentials/keys/private_key.h>
+
+typedef struct gmp_rsa_private_key_t gmp_rsa_private_key_t;
+
+/**
+ * Private_key_t implementation of RSA algorithm using libgmp.
+ */
+struct gmp_rsa_private_key_t {
+
+ /**
+ * Implements private_key_t interface
+ */
+ private_key_t interface;
+};
+
+/**
+ * Create the builder for a private key.
+ *
+ * @param type type of the key, must be KEY_RSA
+ * @return builder instance
+ */
+builder_t *gmp_rsa_private_key_builder(key_type_t type);
+
+#endif /*GMP_RSA_PRIVATE_KEY_H_ @}*/
+
diff --git a/src/libstrongswan/plugins/gmp/gmp_rsa_public_key.c b/src/libstrongswan/plugins/gmp/gmp_rsa_public_key.c
new file mode 100644
index 000000000..e4f898ecc
--- /dev/null
+++ b/src/libstrongswan/plugins/gmp/gmp_rsa_public_key.c
@@ -0,0 +1,587 @@
+/*
+ * Copyright (C) 2005-2008 Martin Willi
+ * Copyright (C) 2005 Jan Hutter
+ * 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.
+ *
+ * $Id: gmp_rsa_public_key.c 3988 2008-05-21 13:01:58Z martin $
+ */
+
+#include <gmp.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "gmp_rsa_public_key.h"
+
+#include <debug.h>
+#include <asn1/oid.h>
+#include <asn1/asn1.h>
+#include <asn1/asn1_parser.h>
+#include <asn1/pem.h>
+#include <crypto/hashers/hasher.h>
+
+/**
+ * defined in gmp_rsa_private_key.c
+ */
+extern chunk_t gmp_mpz_to_asn1(const mpz_t value);
+
+typedef struct private_gmp_rsa_public_key_t private_gmp_rsa_public_key_t;
+
+/**
+ * Private data structure with signing context.
+ */
+struct private_gmp_rsa_public_key_t {
+ /**
+ * Public interface for this signer.
+ */
+ gmp_rsa_public_key_t public;
+
+ /**
+ * Public modulus.
+ */
+ mpz_t n;
+
+ /**
+ * Public exponent.
+ */
+ mpz_t e;
+
+ /**
+ * Keysize in bytes.
+ */
+ size_t k;
+
+ /**
+ * Keyid formed as a SHA-1 hash of a publicKeyInfo object
+ */
+ identification_t *keyid_info;
+
+ /**
+ * Keyid formed as a SHA-1 hash of a publicKey object
+ */
+ identification_t *keyid;
+
+ /**
+ * reference counter
+ */
+ refcount_t ref;
+};
+
+/**
+ * RSAEP algorithm specified in PKCS#1.
+ */
+static chunk_t rsaep(private_gmp_rsa_public_key_t *this, chunk_t data)
+{
+ mpz_t m, c;
+ chunk_t encrypted;
+
+ mpz_init(c);
+ mpz_init(m);
+
+ mpz_import(m, data.len, 1, 1, 1, 0, data.ptr);
+
+ mpz_powm(c, m, this->e, this->n);
+
+ encrypted.len = this->k;
+ encrypted.ptr = mpz_export(NULL, NULL, 1, encrypted.len, 1, 0, c);
+
+ mpz_clear(c);
+ mpz_clear(m);
+
+ return encrypted;
+}
+
+/**
+ * RSAVP1 algorithm specified in PKCS#1.
+ */
+static chunk_t rsavp1(private_gmp_rsa_public_key_t *this, chunk_t data)
+{
+ return rsaep(this, data);
+}
+
+/**
+ * ASN.1 definition of digestInfo
+ */
+static const asn1Object_t digestInfoObjects[] = {
+ { 0, "digestInfo", ASN1_SEQUENCE, ASN1_OBJ }, /* 0 */
+ { 1, "digestAlgorithm", ASN1_EOC, ASN1_RAW }, /* 1 */
+ { 1, "digest", ASN1_OCTET_STRING, ASN1_BODY }, /* 2 */
+ { 0, "exit", ASN1_EOC, ASN1_EXIT }
+};
+#define DIGEST_INFO 0
+#define DIGEST_INFO_ALGORITHM 1
+#define DIGEST_INFO_DIGEST 2
+
+/**
+ * Verification of an EMPSA PKCS1 signature described in PKCS#1
+ */
+static bool verify_emsa_pkcs1_signature(private_gmp_rsa_public_key_t *this,
+ hash_algorithm_t algorithm,
+ chunk_t data, chunk_t signature)
+{
+ chunk_t em_ori, em;
+ bool success = FALSE;
+
+ /* remove any preceding 0-bytes from signature */
+ while (signature.len && *(signature.ptr) == 0x00)
+ {
+ signature.len -= 1;
+ signature.ptr++;
+ }
+
+ if (signature.len > this->k)
+ {
+ return INVALID_ARG;
+ }
+
+ /* unpack signature */
+ em_ori = em = rsavp1(this, signature);
+
+ /* result should look like this:
+ * EM = 0x00 || 0x01 || PS || 0x00 || T.
+ * PS = 0xFF padding, with length to fill em
+ * T = oid || hash
+ */
+
+ /* check magic bytes */
+ if (*(em.ptr) != 0x00 || *(em.ptr+1) != 0x01)
+ {
+ goto end;
+ }
+ em.ptr += 2;
+ em.len -= 2;
+
+ /* find magic 0x00 */
+ while (em.len > 0)
+ {
+ if (*em.ptr == 0x00)
+ {
+ /* found magic byte, stop */
+ em.ptr++;
+ em.len--;
+ break;
+ }
+ else if (*em.ptr != 0xFF)
+ {
+ /* bad padding, decryption failed ?!*/
+ goto end;
+ }
+ em.ptr++;
+ em.len--;
+ }
+
+ if (em.len == 0)
+ {
+ /* no digestInfo found */
+ goto end;
+ }
+
+ /* parse ASN.1-based digestInfo */
+ {
+ asn1_parser_t *parser;
+ chunk_t object;
+ int objectID;
+ hash_algorithm_t hash_algorithm = HASH_UNKNOWN;
+
+ parser = asn1_parser_create(digestInfoObjects, em);
+
+ while (parser->iterate(parser, &objectID, &object))
+ {
+ switch (objectID)
+ {
+ case DIGEST_INFO:
+ {
+ if (em.len > object.len)
+ {
+ DBG1("digestInfo field in signature is followed by %u surplus bytes",
+ em.len - object.len);
+ goto end_parser;
+ }
+ break;
+ }
+ case DIGEST_INFO_ALGORITHM:
+ {
+ int hash_oid = asn1_parse_algorithmIdentifier(object,
+ parser->get_level(parser)+1, NULL);
+
+ hash_algorithm = hasher_algorithm_from_oid(hash_oid);
+ if (hash_algorithm == HASH_UNKNOWN ||
+ (algorithm != HASH_UNKNOWN && hash_algorithm != algorithm))
+ {
+ DBG1("expected hash algorithm %N, but found %N (OID: %#B)",
+ hash_algorithm_names, algorithm,
+ hash_algorithm_names, hash_algorithm, &object);
+ goto end_parser;
+ }
+ break;
+ }
+ case DIGEST_INFO_DIGEST:
+ {
+ chunk_t hash;
+ hasher_t *hasher;
+
+ hasher = lib->crypto->create_hasher(lib->crypto, hash_algorithm);
+ if (hasher == NULL)
+ {
+ DBG1("hash algorithm %N not supported",
+ hash_algorithm_names, hash_algorithm);
+ goto end_parser;
+ }
+
+ if (object.len != hasher->get_hash_size(hasher))
+ {
+ DBG1("hash size in signature is %u bytes instead of %u "
+ "bytes", object.len, hasher->get_hash_size(hasher));
+ hasher->destroy(hasher);
+ goto end_parser;
+ }
+
+ /* build our own hash and compare */
+ hasher->allocate_hash(hasher, data, &hash);
+ hasher->destroy(hasher);
+ success = memeq(object.ptr, hash.ptr, hash.len);
+ free(hash.ptr);
+ break;
+ }
+ default:
+ break;
+ }
+ }
+
+end_parser:
+ success &= parser->success(parser);
+ parser->destroy(parser);
+ }
+
+end:
+ free(em_ori.ptr);
+ return success;
+}
+
+/**
+ * Implementation of public_key_t.get_type.
+ */
+static key_type_t get_type(private_gmp_rsa_public_key_t *this)
+{
+ return KEY_RSA;
+}
+
+/**
+ * Implementation of public_key_t.verify.
+ */
+static bool verify(private_gmp_rsa_public_key_t *this, signature_scheme_t scheme,
+ chunk_t data, chunk_t signature)
+{
+ switch (scheme)
+ {
+ case SIGN_DEFAULT: /* default is EMSA-PKCS1 using included OID */
+ return verify_emsa_pkcs1_signature(this, HASH_UNKNOWN, data, signature);
+ case SIGN_RSA_EMSA_PKCS1_MD5:
+ return verify_emsa_pkcs1_signature(this, HASH_MD5, data, signature);
+ case SIGN_RSA_EMSA_PKCS1_SHA1:
+ return verify_emsa_pkcs1_signature(this, HASH_SHA1, data, signature);
+ case SIGN_RSA_EMSA_PKCS1_SHA256:
+ return verify_emsa_pkcs1_signature(this, HASH_SHA256, data, signature);
+ case SIGN_RSA_EMSA_PKCS1_SHA384:
+ return verify_emsa_pkcs1_signature(this, HASH_SHA384, data, signature);
+ case SIGN_RSA_EMSA_PKCS1_SHA512:
+ return verify_emsa_pkcs1_signature(this, HASH_SHA512, data, signature);
+ default:
+ DBG1("signature scheme %N not supported in RSA",
+ signature_scheme_names, scheme);
+ return FALSE;
+ }
+}
+
+/**
+ * Implementation of public_key_t.get_keysize.
+ */
+static bool encrypt(private_gmp_rsa_public_key_t *this, chunk_t crypto, chunk_t *plain)
+{
+ DBG1("RSA public key encryption not implemented");
+ return FALSE;
+}
+
+/**
+ * Implementation of public_key_t.get_keysize.
+ */
+static size_t get_keysize(private_gmp_rsa_public_key_t *this)
+{
+ return this->k;
+}
+
+/**
+ * Implementation of public_key_t.get_id.
+ */
+static identification_t *get_id(private_gmp_rsa_public_key_t *this,
+ id_type_t type)
+{
+ switch (type)
+ {
+ case ID_PUBKEY_INFO_SHA1:
+ return this->keyid_info;
+ case ID_PUBKEY_SHA1:
+ return this->keyid;
+ default:
+ return NULL;
+ }
+}
+
+/*
+ * Implementation of public_key_t.get_encoding.
+ */
+static chunk_t get_encoding(private_gmp_rsa_public_key_t *this)
+{
+ return asn1_wrap(ASN1_SEQUENCE, "mm",
+ gmp_mpz_to_asn1(this->n),
+ gmp_mpz_to_asn1(this->e));
+}
+
+/**
+ * Implementation of public_key_t.get_ref.
+ */
+static private_gmp_rsa_public_key_t* get_ref(private_gmp_rsa_public_key_t *this)
+{
+ ref_get(&this->ref);
+ return this;
+}
+
+/**
+ * Implementation of gmp_rsa_public_key.destroy.
+ */
+static void destroy(private_gmp_rsa_public_key_t *this)
+{
+ if (ref_put(&this->ref))
+ {
+ mpz_clear(this->n);
+ mpz_clear(this->e);
+ DESTROY_IF(this->keyid);
+ DESTROY_IF(this->keyid_info);
+ free(this);
+ }
+}
+
+/**
+ * Generic private constructor
+ */
+static private_gmp_rsa_public_key_t *gmp_rsa_public_key_create_empty()
+{
+ private_gmp_rsa_public_key_t *this = malloc_thing(private_gmp_rsa_public_key_t);
+
+ this->public.interface.get_type = (key_type_t (*)(public_key_t *this))get_type;
+ this->public.interface.verify = (bool (*)(public_key_t *this, signature_scheme_t scheme, chunk_t data, chunk_t signature))verify;
+ this->public.interface.encrypt = (bool (*)(public_key_t *this, chunk_t crypto, chunk_t *plain))encrypt;
+ this->public.interface.get_keysize = (size_t (*) (public_key_t *this))get_keysize;
+ this->public.interface.get_id = (identification_t* (*) (public_key_t *this,id_type_t))get_id;
+ this->public.interface.get_encoding = (chunk_t(*)(public_key_t*))get_encoding;
+ this->public.interface.get_ref = (public_key_t* (*)(public_key_t *this))get_ref;
+ this->public.interface.destroy = (void (*)(public_key_t *this))destroy;
+
+ this->keyid = NULL;
+ this->keyid_info = NULL;
+ this->ref = 1;
+
+ return this;
+}
+
+/**
+ * Build the RSA key identifier from n and e using SHA1 hashed publicKey(Info).
+ * Also used in rsa_private_key.c.
+ */
+bool gmp_rsa_public_key_build_id(mpz_t n, mpz_t e, identification_t **keyid,
+ identification_t **keyid_info)
+{
+ chunk_t publicKeyInfo, publicKey, hash;
+ hasher_t *hasher;
+
+ hasher = lib->crypto->create_hasher(lib->crypto, HASH_SHA1);
+ if (hasher == NULL)
+ {
+ DBG1("SHA1 hash algorithm not supported, unable to use RSA");
+ return FALSE;
+ }
+ publicKey = asn1_wrap(ASN1_SEQUENCE, "mm",
+ gmp_mpz_to_asn1(n),
+ gmp_mpz_to_asn1(e));
+ hasher->allocate_hash(hasher, publicKey, &hash);
+ *keyid = identification_create_from_encoding(ID_PUBKEY_SHA1, hash);
+ chunk_free(&hash);
+
+ publicKeyInfo = asn1_wrap(ASN1_SEQUENCE, "cm",
+ asn1_algorithmIdentifier(OID_RSA_ENCRYPTION),
+ asn1_bitstring("m", publicKey));
+ hasher->allocate_hash(hasher, publicKeyInfo, &hash);
+ *keyid_info = identification_create_from_encoding(ID_PUBKEY_INFO_SHA1, hash);
+ chunk_free(&hash);
+
+ hasher->destroy(hasher);
+ chunk_free(&publicKeyInfo);
+
+ return TRUE;
+}
+
+/**
+ * Create a public key from mpz values, used in gmp_rsa_private_key
+ */
+gmp_rsa_public_key_t *gmp_rsa_public_key_create_from_n_e(mpz_t n, mpz_t e)
+{
+ private_gmp_rsa_public_key_t *this = gmp_rsa_public_key_create_empty();
+
+ mpz_init_set(this->n, n);
+ mpz_init_set(this->e, e);
+
+ this->k = (mpz_sizeinbase(this->n, 2) + 7) / 8;
+ if (!gmp_rsa_public_key_build_id(this->n, this->e,
+ &this->keyid, &this->keyid_info))
+ {
+ destroy(this);
+ return NULL;
+ }
+ return &this->public;
+}
+
+/**
+ * ASN.1 definition of RSApublicKey
+ */
+static const asn1Object_t pubkeyObjects[] = {
+ { 0, "RSAPublicKey", ASN1_SEQUENCE, ASN1_OBJ }, /* 0 */
+ { 1, "modulus", ASN1_INTEGER, ASN1_BODY }, /* 1 */
+ { 1, "publicExponent", ASN1_INTEGER, ASN1_BODY }, /* 2 */
+ { 0, "exit", ASN1_EOC, ASN1_EXIT }
+};
+#define PUB_KEY_RSA_PUBLIC_KEY 0
+#define PUB_KEY_MODULUS 1
+#define PUB_KEY_EXPONENT 2
+
+/**
+ * Load a public key from an ASN1 encoded blob
+ */
+static gmp_rsa_public_key_t *load(chunk_t blob)
+{
+ asn1_parser_t *parser;
+ chunk_t object;
+ int objectID;
+ bool success = FALSE;
+
+ private_gmp_rsa_public_key_t *this = gmp_rsa_public_key_create_empty();
+
+ mpz_init(this->n);
+ mpz_init(this->e);
+
+ parser = asn1_parser_create(pubkeyObjects, blob);
+
+ while (parser->iterate(parser, &objectID, &object))
+ {
+ switch (objectID)
+ {
+ case PUB_KEY_MODULUS:
+ mpz_import(this->n, object.len, 1, 1, 1, 0, object.ptr);
+ break;
+ case PUB_KEY_EXPONENT:
+ mpz_import(this->e, object.len, 1, 1, 1, 0, object.ptr);
+ break;
+ }
+ }
+ success = parser->success(parser);
+ free(blob.ptr);
+ parser->destroy(parser);
+
+ if (!success)
+ {
+ destroy(this);
+ return NULL;
+ }
+
+ this->k = (mpz_sizeinbase(this->n, 2) + 7) / 8;
+
+ if (!gmp_rsa_public_key_build_id(this->n, this->e,
+ &this->keyid, &this->keyid_info))
+ {
+ destroy(this);
+ return NULL;
+ }
+ return &this->public;
+}
+
+typedef struct private_builder_t private_builder_t;
+/**
+ * Builder implementation for key loading
+ */
+struct private_builder_t {
+ /** implements the builder interface */
+ builder_t public;
+ /** loaded public key */
+ gmp_rsa_public_key_t *key;
+};
+
+/**
+ * Implementation of builder_t.build
+ */
+static gmp_rsa_public_key_t *build(private_builder_t *this)
+{
+ gmp_rsa_public_key_t *key = this->key;
+
+ free(this);
+ return key;
+}
+
+/**
+ * Implementation of builder_t.add
+ */
+static void add(private_builder_t *this, builder_part_t part, ...)
+{
+ va_list args;
+
+ if (this->key)
+ {
+ DBG1("ignoring surplus build part %N", builder_part_names, part);
+ return;
+ }
+
+ switch (part)
+ {
+ case BUILD_BLOB_ASN1_DER:
+ {
+ va_start(args, part);
+ this->key = load(va_arg(args, chunk_t));
+ va_end(args);
+ break;
+ }
+ default:
+ DBG1("ignoring unsupported build part %N", builder_part_names, part);
+ break;
+ }
+}
+
+/**
+ * Builder construction function
+ */
+builder_t *gmp_rsa_public_key_builder(key_type_t type)
+{
+ private_builder_t *this;
+
+ if (type != KEY_RSA)
+ {
+ return NULL;
+ }
+
+ this = malloc_thing(private_builder_t);
+
+ this->key = NULL;
+ this->public.add = (void(*)(builder_t *this, builder_part_t part, ...))add;
+ this->public.build = (void*(*)(builder_t *this))build;
+
+ return &this->public;
+}
+
diff --git a/src/libstrongswan/plugins/gmp/gmp_rsa_public_key.h b/src/libstrongswan/plugins/gmp/gmp_rsa_public_key.h
new file mode 100644
index 000000000..2e502b7e6
--- /dev/null
+++ b/src/libstrongswan/plugins/gmp/gmp_rsa_public_key.h
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2005-2008 Martin Willi
+ * Copyright (C) 2005 Jan Hutter
+ * 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.
+ *
+ * $Id: gmp_rsa_public_key.h 3721 2008-04-01 14:51:31Z martin $
+ */
+
+/**
+ * @defgroup gmp_rsa_public_key gmp_rsa_public_key
+ * @{ @ingroup gmp_p
+ */
+
+#ifndef GMP_RSA_PUBLIC_KEY_H_
+#define GMP_RSA_PUBLIC_KEY_H_
+
+typedef struct gmp_rsa_public_key_t gmp_rsa_public_key_t;
+
+#include <credentials/keys/public_key.h>
+
+/**
+ * public_key_t implementation of RSA algorithm using libgmp.
+ */
+struct gmp_rsa_public_key_t {
+
+ /**
+ * Implements the public_key_t interface
+ */
+ public_key_t interface;
+};
+
+/**
+ * Create the builder for a public key.
+ *
+ * @param type type of the key, must be KEY_RSA
+ * @return builder instance
+ */
+builder_t *gmp_rsa_public_key_builder(key_type_t type);
+
+#endif /*GMP_RSA_PUBLIC_KEY_H_ @}*/
diff --git a/src/libstrongswan/plugins/hmac/Makefile.am b/src/libstrongswan/plugins/hmac/Makefile.am
new file mode 100644
index 000000000..89e0638f3
--- /dev/null
+++ b/src/libstrongswan/plugins/hmac/Makefile.am
@@ -0,0 +1,11 @@
+
+INCLUDES = -I$(top_srcdir)/src/libstrongswan
+
+AM_CFLAGS = -rdynamic
+
+plugin_LTLIBRARIES = libstrongswan-hmac.la
+
+libstrongswan_hmac_la_SOURCES = hmac_plugin.h hmac_plugin.c hmac.h hmac.c \
+ hmac_prf.h hmac_prf.c hmac_signer.h hmac_signer.c
+libstrongswan_hmac_la_LDFLAGS = -module
+
diff --git a/src/libstrongswan/plugins/hmac/Makefile.in b/src/libstrongswan/plugins/hmac/Makefile.in
new file mode 100644
index 000000000..b6e851cd4
--- /dev/null
+++ b/src/libstrongswan/plugins/hmac/Makefile.in
@@ -0,0 +1,499 @@
+# Makefile.in generated by automake 1.10.1 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+VPATH = @srcdir@
+pkgdatadir = $(datadir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+subdir = src/libstrongswan/plugins/hmac
+DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/configure.in
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+mkinstalldirs = $(install_sh) -d
+CONFIG_CLEAN_FILES =
+am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
+am__vpath_adj = case $$p in \
+ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
+ *) f=$$p;; \
+ esac;
+am__strip_dir = `echo $$p | sed -e 's|^.*/||'`;
+am__installdirs = "$(DESTDIR)$(plugindir)"
+pluginLTLIBRARIES_INSTALL = $(INSTALL)
+LTLIBRARIES = $(plugin_LTLIBRARIES)
+libstrongswan_hmac_la_LIBADD =
+am_libstrongswan_hmac_la_OBJECTS = hmac_plugin.lo hmac.lo hmac_prf.lo \
+ hmac_signer.lo
+libstrongswan_hmac_la_OBJECTS = $(am_libstrongswan_hmac_la_OBJECTS)
+libstrongswan_hmac_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(libstrongswan_hmac_la_LDFLAGS) $(LDFLAGS) -o $@
+DEFAULT_INCLUDES = -I.@am__isrc@
+depcomp = $(SHELL) $(top_srcdir)/depcomp
+am__depfiles_maybe = depfiles
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+ --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
+ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+CCLD = $(CC)
+LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+ --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \
+ $(LDFLAGS) -o $@
+SOURCES = $(libstrongswan_hmac_la_SOURCES)
+DIST_SOURCES = $(libstrongswan_hmac_la_SOURCES)
+ETAGS = etags
+CTAGS = ctags
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+AMTAR = @AMTAR@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CXX = @CXX@
+CXXCPP = @CXXCPP@
+CXXDEPMODE = @CXXDEPMODE@
+CXXFLAGS = @CXXFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DSYMUTIL = @DSYMUTIL@
+ECHO = @ECHO@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+F77 = @F77@
+FFLAGS = @FFLAGS@
+GPERF = @GPERF@
+GREP = @GREP@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+IPSEC_ROUTING_TABLE = @IPSEC_ROUTING_TABLE@
+IPSEC_ROUTING_TABLE_PRIO = @IPSEC_ROUTING_TABLE_PRIO@
+LDFLAGS = @LDFLAGS@
+LEX = @LEX@
+LEXLIB = @LEXLIB@
+LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LINUX_HEADERS = @LINUX_HEADERS@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+MAKEINFO = @MAKEINFO@
+MKDIR_P = @MKDIR_P@
+NMEDIT = @NMEDIT@
+OBJEXT = @OBJEXT@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PERL = @PERL@
+PKG_CONFIG = @PKG_CONFIG@
+RANLIB = @RANLIB@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRIP = @STRIP@
+VERSION = @VERSION@
+YACC = @YACC@
+YFLAGS = @YFLAGS@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_CXX = @ac_ct_CXX@
+ac_ct_F77 = @ac_ct_F77@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+confdir = @confdir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+gtk_CFLAGS = @gtk_CFLAGS@
+gtk_LIBS = @gtk_LIBS@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+ipsecdir = @ipsecdir@
+ipsecgroup = @ipsecgroup@
+ipsecuser = @ipsecuser@
+libdir = @libdir@
+libexecdir = @libexecdir@
+libstrongswan_plugins = @libstrongswan_plugins@
+linuxdir = @linuxdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+piddir = @piddir@
+plugindir = @plugindir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+resolv_conf = @resolv_conf@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+simreader = @simreader@
+srcdir = @srcdir@
+strongswan_conf = @strongswan_conf@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+xml_CFLAGS = @xml_CFLAGS@
+xml_LIBS = @xml_LIBS@
+INCLUDES = -I$(top_srcdir)/src/libstrongswan
+AM_CFLAGS = -rdynamic
+plugin_LTLIBRARIES = libstrongswan-hmac.la
+libstrongswan_hmac_la_SOURCES = hmac_plugin.h hmac_plugin.c hmac.h hmac.c \
+ hmac_prf.h hmac_prf.c hmac_signer.h hmac_signer.c
+
+libstrongswan_hmac_la_LDFLAGS = -module
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .c .lo .o .obj
+$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \
+ && exit 0; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/libstrongswan/plugins/hmac/Makefile'; \
+ cd $(top_srcdir) && \
+ $(AUTOMAKE) --gnu src/libstrongswan/plugins/hmac/Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+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) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(pluginLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) '$$p' '$(DESTDIR)$(plugindir)/$$f'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(pluginLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) "$$p" "$(DESTDIR)$(plugindir)/$$f"; \
+ else :; fi; \
+ done
+
+uninstall-pluginLTLIBRARIES:
+ @$(NORMAL_UNINSTALL)
+ @list='$(plugin_LTLIBRARIES)'; for p in $$list; do \
+ p=$(am__strip_dir) \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(plugindir)/$$p'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(plugindir)/$$p"; \
+ 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
+libstrongswan-hmac.la: $(libstrongswan_hmac_la_OBJECTS) $(libstrongswan_hmac_la_DEPENDENCIES)
+ $(libstrongswan_hmac_la_LINK) -rpath $(plugindir) $(libstrongswan_hmac_la_OBJECTS) $(libstrongswan_hmac_la_LIBADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hmac.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hmac_plugin.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hmac_prf.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hmac_signer.Plo@am__quote@
+
+.c.o:
+@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(COMPILE) -c $<
+
+.c.obj:
+@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'`
+
+.c.lo:
+@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $<
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+
+ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonemtpy = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ mkid -fID $$unique
+tags: TAGS
+
+TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ tags=; \
+ here=`pwd`; \
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \
+ test -n "$$unique" || unique=$$empty_fix; \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ $$tags $$unique; \
+ fi
+ctags: CTAGS
+CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ tags=; \
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ test -z "$(CTAGS_ARGS)$$tags$$unique" \
+ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+ $$tags $$unique
+
+GTAGS:
+ here=`$(am__cd) $(top_builddir) && pwd` \
+ && cd $(top_srcdir) \
+ && gtags -i $(GTAGS_ARGS) $$here
+
+distclean-tags:
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+distdir: $(DISTFILES)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ list='$(DISTFILES)'; \
+ dist_files=`for file in $$list; do echo $$file; done | \
+ sed -e "s|^$$srcdirstrip/||;t" \
+ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+ case $$dist_files in \
+ */*) $(MKDIR_P) `echo "$$dist_files" | \
+ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+ sort -u` ;; \
+ esac; \
+ for file in $$dist_files; do \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ if test -d $$d/$$file; then \
+ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
+ fi; \
+ cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
+ else \
+ test -f $(distdir)/$$file \
+ || cp -p $$d/$$file $(distdir)/$$file \
+ || exit 1; \
+ fi; \
+ done
+check-am: all-am
+check: check-am
+all-am: Makefile $(LTLIBRARIES)
+installdirs:
+ for dir in "$(DESTDIR)$(plugindir)"; do \
+ test -z "$$dir" || $(MKDIR_P) "$$dir"; \
+ done
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ `test -z '$(STRIP)' || \
+ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+clean: clean-am
+
+clean-am: clean-generic clean-libtool clean-pluginLTLIBRARIES \
+ mostlyclean-am
+
+distclean: distclean-am
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+ distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+info: info-am
+
+info-am:
+
+install-data-am: install-pluginLTLIBRARIES
+
+install-dvi: install-dvi-am
+
+install-exec-am:
+
+install-html: install-html-am
+
+install-info: install-info-am
+
+install-man:
+
+install-pdf: install-pdf-am
+
+install-ps: install-ps-am
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic \
+ mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am: uninstall-pluginLTLIBRARIES
+
+.MAKE: install-am install-strip
+
+.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \
+ clean-libtool clean-pluginLTLIBRARIES ctags distclean \
+ distclean-compile distclean-generic distclean-libtool \
+ distclean-tags distdir dvi dvi-am html html-am info info-am \
+ install install-am install-data install-data-am install-dvi \
+ install-dvi-am install-exec install-exec-am install-html \
+ install-html-am install-info install-info-am install-man \
+ install-pdf install-pdf-am install-pluginLTLIBRARIES \
+ install-ps install-ps-am install-strip installcheck \
+ installcheck-am installdirs maintainer-clean \
+ maintainer-clean-generic mostlyclean mostlyclean-compile \
+ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
+ tags uninstall uninstall-am uninstall-pluginLTLIBRARIES
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/src/libstrongswan/plugins/hmac/hmac.c b/src/libstrongswan/plugins/hmac/hmac.c
new file mode 100644
index 000000000..b2f99bdc3
--- /dev/null
+++ b/src/libstrongswan/plugins/hmac/hmac.c
@@ -0,0 +1,214 @@
+/*
+ * 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
+ * under the terms of the GNU General hmac 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 hmac License
+ * for more details.
+ *
+ * $Id: hmac.c 3488 2008-02-21 15:10:02Z martin $
+ */
+
+#include <string.h>
+
+#include "hmac.h"
+
+
+typedef struct private_hmac_t private_hmac_t;
+
+/**
+ * Private data of a hmac_t object.
+ *
+ * The variable names are the same as in the RFC.
+ */
+struct private_hmac_t {
+ /**
+ * Public hmac_t interface.
+ */
+ hmac_t hmac;
+
+ /**
+ * Block size, as in RFC.
+ */
+ u_int8_t b;
+
+ /**
+ * Hash function.
+ */
+ hasher_t *h;
+
+ /**
+ * Previously xor'ed key using opad.
+ */
+ chunk_t opaded_key;
+
+ /**
+ * Previously xor'ed key using ipad.
+ */
+ chunk_t ipaded_key;
+};
+
+/**
+ * Implementation of hmac_t.get_mac.
+ */
+static void get_mac(private_hmac_t *this, chunk_t data, u_int8_t *out)
+{
+ /* H(K XOR opad, H(K XOR ipad, text))
+ *
+ * if out is NULL, we append text to the inner hash.
+ * else, we complete the inner and do the outer.
+ *
+ */
+
+ u_int8_t buffer[this->h->get_hash_size(this->h)];
+ chunk_t inner;
+
+ if (out == NULL)
+ {
+ /* append data to inner */
+ this->h->get_hash(this->h, data, NULL);
+ }
+ else
+ {
+ /* append and do outer hash */
+ inner.ptr = buffer;
+ inner.len = this->h->get_hash_size(this->h);
+
+ /* complete inner */
+ this->h->get_hash(this->h, data, buffer);
+
+ /* do outer */
+ this->h->get_hash(this->h, this->opaded_key, NULL);
+ this->h->get_hash(this->h, inner, out);
+
+ /* reinit for next call */
+ this->h->get_hash(this->h, this->ipaded_key, NULL);
+ }
+}
+
+/**
+ * Implementation of hmac_t.allocate_mac.
+ */
+static void allocate_mac(private_hmac_t *this, chunk_t data, chunk_t *out)
+{
+ /* allocate space and use get_mac */
+ if (out == NULL)
+ {
+ /* append mode */
+ this->hmac.get_mac(&(this->hmac), data, NULL);
+ }
+ else
+ {
+ out->len = this->h->get_hash_size(this->h);
+ out->ptr = malloc(out->len);
+ this->hmac.get_mac(&(this->hmac), data, out->ptr);
+ }
+}
+
+/**
+ * Implementation of hmac_t.get_block_size.
+ */
+static size_t get_block_size(private_hmac_t *this)
+{
+ return this->h->get_hash_size(this->h);
+}
+
+/**
+ * Implementation of hmac_t.set_key.
+ */
+static void set_key(private_hmac_t *this, chunk_t key)
+{
+ int i;
+ u_int8_t buffer[this->b];
+
+ memset(buffer, 0, this->b);
+
+ if (key.len > this->b)
+ {
+ /* if key is too long, it will be hashed */
+ this->h->get_hash(this->h, key, buffer);
+ }
+ else
+ {
+ /* if not, just copy it in our pre-padded k */
+ memcpy(buffer, key.ptr, key.len);
+ }
+
+ /* apply ipad and opad to key */
+ for (i = 0; i < this->b; i++)
+ {
+ this->ipaded_key.ptr[i] = buffer[i] ^ 0x36;
+ this->opaded_key.ptr[i] = buffer[i] ^ 0x5C;
+ }
+
+ /* begin hashing of inner pad */
+ this->h->reset(this->h);
+ this->h->get_hash(this->h, this->ipaded_key, NULL);
+}
+
+/**
+ * Implementation of hmac_t.destroy.
+ */
+static void destroy(private_hmac_t *this)
+{
+ this->h->destroy(this->h);
+ free(this->opaded_key.ptr);
+ free(this->ipaded_key.ptr);
+ free(this);
+}
+
+/*
+ * Described in header
+ */
+hmac_t *hmac_create(hash_algorithm_t hash_algorithm)
+{
+ private_hmac_t *this = malloc_thing(private_hmac_t);
+
+ /* set hmac_t methods */
+ this->hmac.get_mac = (void (*)(hmac_t *,chunk_t,u_int8_t*))get_mac;
+ this->hmac.allocate_mac = (void (*)(hmac_t *,chunk_t,chunk_t*))allocate_mac;
+ this->hmac.get_block_size = (size_t (*)(hmac_t *))get_block_size;
+ this->hmac.set_key = (void (*)(hmac_t *,chunk_t))set_key;
+ this->hmac.destroy = (void (*)(hmac_t *))destroy;
+
+ /* set b, according to hasher */
+ switch (hash_algorithm)
+ {
+ case HASH_SHA1:
+ case HASH_MD5:
+ case HASH_SHA256:
+ this->b = 64;
+ break;
+ case HASH_SHA384:
+ case HASH_SHA512:
+ this->b = 128;
+ break;
+ default:
+ free(this);
+ return NULL;
+ }
+
+ /* build the hasher */
+ this->h = lib->crypto->create_hasher(lib->crypto, hash_algorithm);
+ if (this->h == NULL)
+ {
+ free(this);
+ return NULL;
+ }
+
+ /* build ipad and opad */
+ this->opaded_key.ptr = malloc(this->b);
+ this->opaded_key.len = this->b;
+
+ this->ipaded_key.ptr = malloc(this->b);
+ this->ipaded_key.len = this->b;
+
+ return &(this->hmac);
+}
diff --git a/src/libstrongswan/plugins/hmac/hmac.h b/src/libstrongswan/plugins/hmac/hmac.h
new file mode 100644
index 000000000..5f266e133
--- /dev/null
+++ b/src/libstrongswan/plugins/hmac/hmac.h
@@ -0,0 +1,93 @@
+/*
+ * Copyright (C) 2005-2008 Martin Willi
+ * Copyright (C) 2005 Jan Hutter
+ * Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+/**
+ * @defgroup hmac hmac
+ * @{ @ingroup hmac_p
+ */
+
+#ifndef HMAC_H_
+#define HMAC_H_
+
+typedef struct hmac_t hmac_t;
+
+#include <crypto/hashers/hasher.h>
+
+/**
+ * Message authentication using hash functions.
+ *
+ * This class implements the message authenticaion algorithm
+ * described in RFC2104. It uses a hash function, wich must
+ * be implemented as a hasher_t class.
+ */
+struct hmac_t {
+ /**
+ * Generate message authentication code.
+ *
+ * If buffer is NULL, no result is given back. A next call will
+ * append the data to already supplied data. If buffer is not NULL,
+ * the mac of all apended data is calculated, returned and the
+ * state of the hmac_t is reseted.
+ *
+ * @param data chunk of data to authenticate
+ * @param buffer pointer where the generated bytes will be written
+ */
+ void (*get_mac) (hmac_t *this, chunk_t data, u_int8_t *buffer);
+
+ /**
+ * Generates message authentication code and allocate space for them.
+ *
+ * If chunk is NULL, no result is given back. A next call will
+ * append the data to already supplied. If chunk is not NULL,
+ * the mac of all apended data is calculated, returned and the
+ * state of the hmac_t reset;
+ *
+ * @param data chunk of data to authenticate
+ * @param chunk chunk which will hold generated bytes
+ */
+ void (*allocate_mac) (hmac_t *this, chunk_t data, chunk_t *chunk);
+
+ /**
+ * Get the block size of this hmac_t object.
+ *
+ * @return block size in bytes
+ */
+ size_t (*get_block_size) (hmac_t *this);
+
+ /**
+ * Set the key for this hmac_t object.
+ *
+ * Any key length is accepted.
+ *
+ * @param key key to set
+ */
+ void (*set_key) (hmac_t *this, chunk_t key);
+
+ /**
+ * Destroys a hmac_t object.
+ */
+ void (*destroy) (hmac_t *this);
+};
+
+/**
+ * Creates a new hmac_t object.
+ *
+ * @param hash_algorithm hash algorithm to use
+ * @return hmac_t object, NULL if not supported
+ */
+hmac_t *hmac_create(hash_algorithm_t hash_algorithm);
+
+#endif /*HMAC_H_ @}*/
diff --git a/src/libstrongswan/plugins/hmac/hmac_plugin.c b/src/libstrongswan/plugins/hmac/hmac_plugin.c
new file mode 100644
index 000000000..bfa2df35f
--- /dev/null
+++ b/src/libstrongswan/plugins/hmac/hmac_plugin.c
@@ -0,0 +1,84 @@
+/*
+ * Copyright (C) 2008 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.
+ *
+ * $Id: hmac_plugin.c 3488 2008-02-21 15:10:02Z martin $
+ */
+
+#include "hmac_plugin.h"
+
+#include <library.h>
+#include "hmac_signer.h"
+#include "hmac_prf.h"
+
+typedef struct private_hmac_plugin_t private_hmac_plugin_t;
+
+/**
+ * private data of hmac_plugin
+ */
+struct private_hmac_plugin_t {
+
+ /**
+ * public functions
+ */
+ hmac_plugin_t public;
+};
+
+/**
+ * Implementation of hmac_plugin_t.hmactroy
+ */
+static void destroy(private_hmac_plugin_t *this)
+{
+ lib->crypto->remove_prf(lib->crypto,
+ (prf_constructor_t)hmac_prf_create);
+ lib->crypto->remove_signer(lib->crypto,
+ (signer_constructor_t)hmac_signer_create);
+ free(this);
+}
+
+/*
+ * see header file
+ */
+plugin_t *plugin_create()
+{
+ private_hmac_plugin_t *this = malloc_thing(private_hmac_plugin_t);
+
+ this->public.plugin.destroy = (void(*)(plugin_t*))destroy;
+
+ lib->crypto->add_prf(lib->crypto, PRF_HMAC_MD5,
+ (prf_constructor_t)hmac_prf_create);
+ lib->crypto->add_prf(lib->crypto, PRF_HMAC_SHA1,
+ (prf_constructor_t)hmac_prf_create);
+ lib->crypto->add_prf(lib->crypto, PRF_HMAC_SHA2_256,
+ (prf_constructor_t)hmac_prf_create);
+ lib->crypto->add_prf(lib->crypto, PRF_HMAC_SHA2_384,
+ (prf_constructor_t)hmac_prf_create);
+ lib->crypto->add_prf(lib->crypto, PRF_HMAC_SHA2_512,
+ (prf_constructor_t)hmac_prf_create);
+
+ lib->crypto->add_signer(lib->crypto, AUTH_HMAC_MD5_96,
+ (signer_constructor_t)hmac_signer_create);
+ lib->crypto->add_signer(lib->crypto, AUTH_HMAC_SHA1_96,
+ (signer_constructor_t)hmac_signer_create);
+ lib->crypto->add_signer(lib->crypto, AUTH_HMAC_SHA1_128,
+ (signer_constructor_t)hmac_signer_create);
+ lib->crypto->add_signer(lib->crypto, AUTH_HMAC_SHA2_256_128,
+ (signer_constructor_t)hmac_signer_create);
+ lib->crypto->add_signer(lib->crypto, AUTH_HMAC_SHA2_384_192,
+ (signer_constructor_t)hmac_signer_create);
+ lib->crypto->add_signer(lib->crypto, AUTH_HMAC_SHA2_512_256,
+ (signer_constructor_t)hmac_signer_create);
+
+ return &this->public.plugin;
+}
+
diff --git a/src/libstrongswan/plugins/hmac/hmac_plugin.h b/src/libstrongswan/plugins/hmac/hmac_plugin.h
new file mode 100644
index 000000000..55ba0b5f4
--- /dev/null
+++ b/src/libstrongswan/plugins/hmac/hmac_plugin.h
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2008 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.
+ */
+
+/**
+ * @defgroup hmac_p hmac
+ * @ingroup plugins
+ *
+ * @defgroup hmac_plugin hmac_plugin
+ * @{ @ingroup hmac_p
+ */
+
+#ifndef HMAC_PLUGIN_H_
+#define HMAC_PLUGIN_H_
+
+#include <plugins/plugin.h>
+
+typedef struct hmac_plugin_t hmac_plugin_t;
+
+/**
+ * Plugin implementing HMAC algorithm to prvoide hash based PRF and signers.
+ */
+struct hmac_plugin_t {
+
+ /**
+ * implements plugin interface
+ */
+ plugin_t plugin;
+};
+
+/**
+ * Create a hmac_plugin instance.
+ */
+plugin_t *plugin_create();
+
+#endif /* HMAC_PLUGIN_H_ @}*/
diff --git a/src/libstrongswan/plugins/hmac/hmac_prf.c b/src/libstrongswan/plugins/hmac/hmac_prf.c
new file mode 100644
index 000000000..8d843bc5a
--- /dev/null
+++ b/src/libstrongswan/plugins/hmac/hmac_prf.c
@@ -0,0 +1,137 @@
+/*
+ * 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
+ * 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.
+ *
+ * $Id: hmac_prf.c 3488 2008-02-21 15:10:02Z martin $
+ */
+
+#include "hmac_prf.h"
+
+#include "hmac.h"
+
+
+typedef struct private_hmac_prf_t private_hmac_prf_t;
+
+/**
+ * Private data of a hma_prf_t object.
+ */
+struct private_hmac_prf_t {
+ /**
+ * Public hmac_prf_t interface.
+ */
+ hmac_prf_t public;
+
+ /**
+ * Hmac to use for generation.
+ */
+ hmac_t *hmac;
+};
+
+/**
+ * Implementation of prf_t.get_bytes.
+ */
+static void get_bytes(private_hmac_prf_t *this, chunk_t seed, u_int8_t *buffer)
+{
+ this->hmac->get_mac(this->hmac, seed, buffer);
+}
+
+/**
+ * Implementation of prf_t.allocate_bytes.
+ */
+static void allocate_bytes(private_hmac_prf_t *this, chunk_t seed, chunk_t *chunk)
+{
+ this->hmac->allocate_mac(this->hmac, seed, chunk);
+}
+
+/**
+ * Implementation of prf_t.get_block_size.
+ */
+static size_t get_block_size(private_hmac_prf_t *this)
+{
+ return this->hmac->get_block_size(this->hmac);
+}
+
+/**
+ * Implementation of prf_t.get_block_size.
+ */
+static size_t get_key_size(private_hmac_prf_t *this)
+{
+ /* for HMAC prfs, IKEv2 uses block size as key size */
+ return this->hmac->get_block_size(this->hmac);
+}
+
+/**
+ * Implementation of prf_t.set_key.
+ */
+static void set_key(private_hmac_prf_t *this, chunk_t key)
+{
+ this->hmac->set_key(this->hmac, key);
+}
+
+/**
+ * Implementation of prf_t.destroy.
+ */
+static void destroy(private_hmac_prf_t *this)
+{
+ this->hmac->destroy(this->hmac);
+ free(this);
+}
+
+/*
+ * Described in header.
+ */
+hmac_prf_t *hmac_prf_create(pseudo_random_function_t algo)
+{
+ private_hmac_prf_t *this;
+ hash_algorithm_t hash;
+
+ switch (algo)
+ {
+ case PRF_HMAC_SHA1:
+ hash = HASH_SHA1;
+ break;
+ case PRF_HMAC_MD5:
+ hash = HASH_MD5;
+ break;
+ case PRF_HMAC_SHA2_256:
+ hash = HASH_SHA256;
+ break;
+ case PRF_HMAC_SHA2_384:
+ hash = HASH_SHA384;
+ break;
+ case PRF_HMAC_SHA2_512:
+ hash = HASH_SHA512;
+ break;
+ default:
+ return NULL;
+ }
+
+ this = malloc_thing(private_hmac_prf_t);
+ this->hmac = hmac_create(hash);
+ if (this->hmac == NULL)
+ {
+ free(this);
+ return NULL;
+ }
+
+ this->public.prf_interface.get_bytes = (void (*) (prf_t *,chunk_t,u_int8_t*))get_bytes;
+ this->public.prf_interface.allocate_bytes = (void (*) (prf_t*,chunk_t,chunk_t*))allocate_bytes;
+ this->public.prf_interface.get_block_size = (size_t (*) (prf_t*))get_block_size;
+ this->public.prf_interface.get_key_size = (size_t (*) (prf_t*))get_key_size;
+ this->public.prf_interface.set_key = (void (*) (prf_t *,chunk_t))set_key;
+ this->public.prf_interface.destroy = (void (*) (prf_t *))destroy;
+
+ return &(this->public);
+}
+
diff --git a/src/libstrongswan/plugins/hmac/hmac_prf.h b/src/libstrongswan/plugins/hmac/hmac_prf.h
new file mode 100644
index 000000000..46d05f03a
--- /dev/null
+++ b/src/libstrongswan/plugins/hmac/hmac_prf.h
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2008 Martin Willi
+ * Copyright (C) 2005 Jan Hutter
+ * Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+/**
+ * @defgroup hmac_prf hmac_prf
+ * @{ @ingroup hmac_p
+ */
+
+#ifndef PRF_HMAC_H_
+#define PRF_HMAC_H_
+
+typedef struct hmac_prf_t hmac_prf_t;
+
+#include <crypto/prfs/prf.h>
+
+/**
+ * Implementation of prf_t interface using the HMAC algorithm.
+ *
+ * This simply wraps a hmac_t in a prf_t. More a question of
+ * interface matching.
+ */
+struct hmac_prf_t {
+
+ /**
+ * Generic prf_t interface for this hmac_prf_t class.
+ */
+ prf_t prf_interface;
+};
+
+/**
+ * Creates a new hmac_prf_t object.
+ *
+ * @param algo algorithm to implement
+ * @return hmac_prf_t object, NULL if hash not supported
+ */
+hmac_prf_t *hmac_prf_create(pseudo_random_function_t algo);
+
+#endif /*PRF_HMAC_SHA1_H_ @}*/
diff --git a/src/libstrongswan/plugins/hmac/hmac_signer.c b/src/libstrongswan/plugins/hmac/hmac_signer.c
new file mode 100644
index 000000000..cdfc819f1
--- /dev/null
+++ b/src/libstrongswan/plugins/hmac/hmac_signer.c
@@ -0,0 +1,199 @@
+/*
+ * Copyright (C) 2005-2008 Martin Willi
+ * Copyright (C) 2005 Jan Hutter
+ * 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.
+ *
+ * $Id: hmac_signer.c 3488 2008-02-21 15:10:02Z martin $
+ */
+
+#include <string.h>
+
+#include "hmac_signer.h"
+#include "hmac.h"
+
+typedef struct private_hmac_signer_t private_hmac_signer_t;
+
+/**
+ * Private data structure with signing context.
+ */
+struct private_hmac_signer_t {
+ /**
+ * Public interface of hmac_signer_t.
+ */
+ hmac_signer_t public;
+
+ /**
+ * Assigned hmac function.
+ */
+ hmac_t *hmac;
+
+ /**
+ * Block size (truncation of HMAC Hash)
+ */
+ size_t block_size;
+};
+
+/**
+ * Implementation of signer_t.get_signature.
+ */
+static void get_signature(private_hmac_signer_t *this,
+ chunk_t data, u_int8_t *buffer)
+{
+ if (buffer == NULL)
+ { /* append mode */
+ this->hmac->get_mac(this->hmac, data, NULL);
+ }
+ else
+ {
+ u_int8_t mac[this->hmac->get_block_size(this->hmac)];
+
+ this->hmac->get_mac(this->hmac, data, mac);
+ memcpy(buffer, mac, this->block_size);
+ }
+}
+
+/**
+ * Implementation of signer_t.allocate_signature.
+ */
+static void allocate_signature (private_hmac_signer_t *this,
+ chunk_t data, chunk_t *chunk)
+{
+ if (chunk == NULL)
+ { /* append mode */
+ this->hmac->get_mac(this->hmac, data, NULL);
+ }
+ else
+ {
+ u_int8_t mac[this->hmac->get_block_size(this->hmac)];
+
+ this->hmac->get_mac(this->hmac, data, mac);
+
+ chunk->ptr = malloc(this->block_size);
+ chunk->len = this->block_size;
+
+ memcpy(chunk->ptr, mac, this->block_size);
+ }
+}
+
+/**
+ * Implementation of signer_t.verify_signature.
+ */
+static bool verify_signature(private_hmac_signer_t *this,
+ chunk_t data, chunk_t signature)
+{
+ u_int8_t mac[this->hmac->get_block_size(this->hmac)];
+
+ this->hmac->get_mac(this->hmac, data, mac);
+
+ if (signature.len != this->block_size)
+ {
+ return FALSE;
+ }
+ return memeq(signature.ptr, mac, this->block_size);
+}
+
+/**
+ * Implementation of signer_t.get_key_size.
+ */
+static size_t get_key_size(private_hmac_signer_t *this)
+{
+ return this->hmac->get_block_size(this->hmac);
+}
+
+/**
+ * Implementation of signer_t.get_block_size.
+ */
+static size_t get_block_size(private_hmac_signer_t *this)
+{
+ return this->block_size;
+}
+
+/**
+ * Implementation of signer_t.set_key.
+ */
+static void set_key(private_hmac_signer_t *this, chunk_t key)
+{
+ this->hmac->set_key(this->hmac, key);
+}
+
+/**
+ * Implementation of signer_t.destroy.
+ */
+static status_t destroy(private_hmac_signer_t *this)
+{
+ this->hmac->destroy(this->hmac);
+ free(this);
+ return SUCCESS;
+}
+
+/*
+ * Described in header
+ */
+hmac_signer_t *hmac_signer_create(integrity_algorithm_t algo)
+{
+ private_hmac_signer_t *this;
+ size_t trunc;
+ hash_algorithm_t hash;
+
+ switch (algo)
+ {
+ case AUTH_HMAC_SHA1_96:
+ hash = HASH_SHA1;
+ trunc = 12;
+ break;
+ case AUTH_HMAC_SHA1_128:
+ hash = HASH_SHA1;
+ trunc = 16;
+ break;
+ case AUTH_HMAC_MD5_96:
+ hash = HASH_MD5;
+ trunc = 12;
+ break;
+ case AUTH_HMAC_SHA2_256_128:
+ hash = HASH_SHA256;
+ trunc = 16;
+ break;
+ case AUTH_HMAC_SHA2_384_192:
+ hash = HASH_SHA384;
+ trunc = 24;
+ break;
+ case AUTH_HMAC_SHA2_512_256:
+ hash = HASH_SHA512;
+ trunc = 32;
+ break;
+ default:
+ return NULL;
+ }
+
+ this = malloc_thing(private_hmac_signer_t);
+ this->hmac = hmac_create(hash);
+ if (this->hmac == NULL)
+ {
+ free(this);
+ return NULL;
+ }
+ /* prevent invalid truncation */
+ this->block_size = min(trunc, this->hmac->get_block_size(this->hmac));
+
+ /* interface functions */
+ this->public.signer_interface.get_signature = (void (*) (signer_t*, chunk_t, u_int8_t*))get_signature;
+ this->public.signer_interface.allocate_signature = (void (*) (signer_t*, chunk_t, chunk_t*))allocate_signature;
+ this->public.signer_interface.verify_signature = (bool (*) (signer_t*, chunk_t, chunk_t))verify_signature;
+ this->public.signer_interface.get_key_size = (size_t (*) (signer_t*))get_key_size;
+ this->public.signer_interface.get_block_size = (size_t (*) (signer_t*))get_block_size;
+ this->public.signer_interface.set_key = (void (*) (signer_t*,chunk_t))set_key;
+ this->public.signer_interface.destroy = (void (*) (signer_t*))destroy;
+
+ return &(this->public);
+}
+
diff --git a/src/libstrongswan/plugins/hmac/hmac_signer.h b/src/libstrongswan/plugins/hmac/hmac_signer.h
new file mode 100644
index 000000000..969f482e7
--- /dev/null
+++ b/src/libstrongswan/plugins/hmac/hmac_signer.h
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2005-2008 Martin Willi
+ * Copyright (C) 2005 Jan Hutter
+ * Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+/**
+ * @defgroup hmac_signer hmac_signer
+ * @{ @ingroup hmac_p
+ */
+
+#ifndef HMAC_SIGNER_H_
+#define HMAC_SIGNER_H_
+
+typedef struct hmac_signer_t hmac_signer_t;
+
+#include <crypto/signers/signer.h>
+
+/**
+ * Implementation of signer_t interface using HMAC.
+ *
+ * HMAC uses a standard hash function implemented in a hasher_t to build a MAC.
+ */
+struct hmac_signer_t {
+
+ /**
+ * generic signer_t interface for this signer
+ */
+ signer_t signer_interface;
+};
+
+/**
+ * Creates a new hmac_signer_t.
+ *
+ * HMAC signatures are often truncated to shorten them to a more usable, but
+ * still secure enough length.
+ * Block size must be equal or smaller then the hash algorithms
+ * hash.
+ *
+ * @param algo algorithm to implement
+ * @return hmac_signer_t, NULL if not supported
+ */
+hmac_signer_t *hmac_signer_create(integrity_algorithm_t algo);
+
+#endif /*HMAC_SIGNER_H_ @}*/
diff --git a/src/libstrongswan/plugins/ldap/Makefile.am b/src/libstrongswan/plugins/ldap/Makefile.am
new file mode 100644
index 000000000..ac6b4be00
--- /dev/null
+++ b/src/libstrongswan/plugins/ldap/Makefile.am
@@ -0,0 +1,11 @@
+
+INCLUDES = -I$(top_srcdir)/src/libstrongswan
+
+AM_CFLAGS = -rdynamic
+
+plugin_LTLIBRARIES = libstrongswan-ldap.la
+
+libstrongswan_ldap_la_SOURCES = ldap_plugin.h ldap_plugin.c ldap_fetcher.h ldap_fetcher.c
+libstrongswan_ldap_la_LDFLAGS = -module
+libstrongswan_ldap_la_LIBADD = -lldap -llber
+
diff --git a/src/libstrongswan/plugins/ldap/Makefile.in b/src/libstrongswan/plugins/ldap/Makefile.in
new file mode 100644
index 000000000..8c28f1307
--- /dev/null
+++ b/src/libstrongswan/plugins/ldap/Makefile.in
@@ -0,0 +1,495 @@
+# Makefile.in generated by automake 1.10.1 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+VPATH = @srcdir@
+pkgdatadir = $(datadir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+subdir = src/libstrongswan/plugins/ldap
+DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/configure.in
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+mkinstalldirs = $(install_sh) -d
+CONFIG_CLEAN_FILES =
+am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
+am__vpath_adj = case $$p in \
+ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
+ *) f=$$p;; \
+ esac;
+am__strip_dir = `echo $$p | sed -e 's|^.*/||'`;
+am__installdirs = "$(DESTDIR)$(plugindir)"
+pluginLTLIBRARIES_INSTALL = $(INSTALL)
+LTLIBRARIES = $(plugin_LTLIBRARIES)
+libstrongswan_ldap_la_DEPENDENCIES =
+am_libstrongswan_ldap_la_OBJECTS = ldap_plugin.lo ldap_fetcher.lo
+libstrongswan_ldap_la_OBJECTS = $(am_libstrongswan_ldap_la_OBJECTS)
+libstrongswan_ldap_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(libstrongswan_ldap_la_LDFLAGS) $(LDFLAGS) -o $@
+DEFAULT_INCLUDES = -I.@am__isrc@
+depcomp = $(SHELL) $(top_srcdir)/depcomp
+am__depfiles_maybe = depfiles
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+ --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
+ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+CCLD = $(CC)
+LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+ --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \
+ $(LDFLAGS) -o $@
+SOURCES = $(libstrongswan_ldap_la_SOURCES)
+DIST_SOURCES = $(libstrongswan_ldap_la_SOURCES)
+ETAGS = etags
+CTAGS = ctags
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+AMTAR = @AMTAR@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CXX = @CXX@
+CXXCPP = @CXXCPP@
+CXXDEPMODE = @CXXDEPMODE@
+CXXFLAGS = @CXXFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DSYMUTIL = @DSYMUTIL@
+ECHO = @ECHO@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+F77 = @F77@
+FFLAGS = @FFLAGS@
+GPERF = @GPERF@
+GREP = @GREP@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+IPSEC_ROUTING_TABLE = @IPSEC_ROUTING_TABLE@
+IPSEC_ROUTING_TABLE_PRIO = @IPSEC_ROUTING_TABLE_PRIO@
+LDFLAGS = @LDFLAGS@
+LEX = @LEX@
+LEXLIB = @LEXLIB@
+LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LINUX_HEADERS = @LINUX_HEADERS@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+MAKEINFO = @MAKEINFO@
+MKDIR_P = @MKDIR_P@
+NMEDIT = @NMEDIT@
+OBJEXT = @OBJEXT@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PERL = @PERL@
+PKG_CONFIG = @PKG_CONFIG@
+RANLIB = @RANLIB@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRIP = @STRIP@
+VERSION = @VERSION@
+YACC = @YACC@
+YFLAGS = @YFLAGS@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_CXX = @ac_ct_CXX@
+ac_ct_F77 = @ac_ct_F77@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+confdir = @confdir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+gtk_CFLAGS = @gtk_CFLAGS@
+gtk_LIBS = @gtk_LIBS@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+ipsecdir = @ipsecdir@
+ipsecgroup = @ipsecgroup@
+ipsecuser = @ipsecuser@
+libdir = @libdir@
+libexecdir = @libexecdir@
+libstrongswan_plugins = @libstrongswan_plugins@
+linuxdir = @linuxdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+piddir = @piddir@
+plugindir = @plugindir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+resolv_conf = @resolv_conf@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+simreader = @simreader@
+srcdir = @srcdir@
+strongswan_conf = @strongswan_conf@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+xml_CFLAGS = @xml_CFLAGS@
+xml_LIBS = @xml_LIBS@
+INCLUDES = -I$(top_srcdir)/src/libstrongswan
+AM_CFLAGS = -rdynamic
+plugin_LTLIBRARIES = libstrongswan-ldap.la
+libstrongswan_ldap_la_SOURCES = ldap_plugin.h ldap_plugin.c ldap_fetcher.h ldap_fetcher.c
+libstrongswan_ldap_la_LDFLAGS = -module
+libstrongswan_ldap_la_LIBADD = -lldap -llber
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .c .lo .o .obj
+$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \
+ && exit 0; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/libstrongswan/plugins/ldap/Makefile'; \
+ cd $(top_srcdir) && \
+ $(AUTOMAKE) --gnu src/libstrongswan/plugins/ldap/Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+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) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(pluginLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) '$$p' '$(DESTDIR)$(plugindir)/$$f'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(pluginLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) "$$p" "$(DESTDIR)$(plugindir)/$$f"; \
+ else :; fi; \
+ done
+
+uninstall-pluginLTLIBRARIES:
+ @$(NORMAL_UNINSTALL)
+ @list='$(plugin_LTLIBRARIES)'; for p in $$list; do \
+ p=$(am__strip_dir) \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(plugindir)/$$p'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(plugindir)/$$p"; \
+ 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
+libstrongswan-ldap.la: $(libstrongswan_ldap_la_OBJECTS) $(libstrongswan_ldap_la_DEPENDENCIES)
+ $(libstrongswan_ldap_la_LINK) -rpath $(plugindir) $(libstrongswan_ldap_la_OBJECTS) $(libstrongswan_ldap_la_LIBADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ldap_fetcher.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ldap_plugin.Plo@am__quote@
+
+.c.o:
+@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(COMPILE) -c $<
+
+.c.obj:
+@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'`
+
+.c.lo:
+@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $<
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+
+ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonemtpy = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ mkid -fID $$unique
+tags: TAGS
+
+TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ tags=; \
+ here=`pwd`; \
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \
+ test -n "$$unique" || unique=$$empty_fix; \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ $$tags $$unique; \
+ fi
+ctags: CTAGS
+CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ tags=; \
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ test -z "$(CTAGS_ARGS)$$tags$$unique" \
+ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+ $$tags $$unique
+
+GTAGS:
+ here=`$(am__cd) $(top_builddir) && pwd` \
+ && cd $(top_srcdir) \
+ && gtags -i $(GTAGS_ARGS) $$here
+
+distclean-tags:
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+distdir: $(DISTFILES)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ list='$(DISTFILES)'; \
+ dist_files=`for file in $$list; do echo $$file; done | \
+ sed -e "s|^$$srcdirstrip/||;t" \
+ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+ case $$dist_files in \
+ */*) $(MKDIR_P) `echo "$$dist_files" | \
+ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+ sort -u` ;; \
+ esac; \
+ for file in $$dist_files; do \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ if test -d $$d/$$file; then \
+ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
+ fi; \
+ cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
+ else \
+ test -f $(distdir)/$$file \
+ || cp -p $$d/$$file $(distdir)/$$file \
+ || exit 1; \
+ fi; \
+ done
+check-am: all-am
+check: check-am
+all-am: Makefile $(LTLIBRARIES)
+installdirs:
+ for dir in "$(DESTDIR)$(plugindir)"; do \
+ test -z "$$dir" || $(MKDIR_P) "$$dir"; \
+ done
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ `test -z '$(STRIP)' || \
+ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+clean: clean-am
+
+clean-am: clean-generic clean-libtool clean-pluginLTLIBRARIES \
+ mostlyclean-am
+
+distclean: distclean-am
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+ distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+info: info-am
+
+info-am:
+
+install-data-am: install-pluginLTLIBRARIES
+
+install-dvi: install-dvi-am
+
+install-exec-am:
+
+install-html: install-html-am
+
+install-info: install-info-am
+
+install-man:
+
+install-pdf: install-pdf-am
+
+install-ps: install-ps-am
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic \
+ mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am: uninstall-pluginLTLIBRARIES
+
+.MAKE: install-am install-strip
+
+.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \
+ clean-libtool clean-pluginLTLIBRARIES ctags distclean \
+ distclean-compile distclean-generic distclean-libtool \
+ distclean-tags distdir dvi dvi-am html html-am info info-am \
+ install install-am install-data install-data-am install-dvi \
+ install-dvi-am install-exec install-exec-am install-html \
+ install-html-am install-info install-info-am install-man \
+ install-pdf install-pdf-am install-pluginLTLIBRARIES \
+ install-ps install-ps-am install-strip installcheck \
+ installcheck-am installdirs maintainer-clean \
+ maintainer-clean-generic mostlyclean mostlyclean-compile \
+ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
+ tags uninstall uninstall-am uninstall-pluginLTLIBRARIES
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/src/libstrongswan/plugins/ldap/ldap_fetcher.c b/src/libstrongswan/plugins/ldap/ldap_fetcher.c
new file mode 100644
index 000000000..8e55b800e
--- /dev/null
+++ b/src/libstrongswan/plugins/ldap/ldap_fetcher.c
@@ -0,0 +1,213 @@
+/*
+ * Copyright (C) 2008 Martin Willi
+ * Copyright (C) 2007 Andreas Steffen
+ * Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * $Id: ldap_fetcher.c 3693 2008-03-28 22:44:45Z andreas $
+ */
+
+#ifndef LDAP_DEPRECATED
+#define LDAP_DEPRECATED 1
+#endif /* LDAP_DEPRECATED */
+#include <ldap.h>
+
+#include <errno.h>
+
+#include <library.h>
+#include <debug.h>
+
+#include "ldap_fetcher.h"
+
+#define DEFAULT_TIMEOUT 10
+
+typedef struct private_ldap_fetcher_t private_ldap_fetcher_t;
+
+/**
+ * Private Data of a ldap_fetcher_t object.
+ */
+struct private_ldap_fetcher_t {
+ /**
+ * Public data
+ */
+ ldap_fetcher_t public;
+
+ /**
+ * timeout to use for fetches
+ */
+ u_int timeout;
+};
+
+/**
+ * Parses the result returned by an ldap query
+ */
+static bool parse(LDAP *ldap, LDAPMessage *result, chunk_t *response)
+{
+ LDAPMessage *entry = ldap_first_entry(ldap, result);
+ bool success = FALSE;
+
+ if (entry)
+ {
+ BerElement *ber = NULL;
+ char *attr;
+
+ attr = ldap_first_attribute(ldap, entry, &ber);
+ if (attr)
+ {
+ struct berval **values = ldap_get_values_len(ldap, entry, attr);
+
+ if (values)
+ {
+ if (values[0])
+ {
+ *response = chunk_alloc(values[0]->bv_len);
+ memcpy(response->ptr, values[0]->bv_val, response->len);
+ success = TRUE;
+ }
+ else
+ {
+ DBG1("LDAP response contains no values");
+ }
+ ldap_value_free_len(values);
+ }
+ else
+ {
+ DBG1("getting LDAP values failed: %s",
+ ldap_err2string(ldap_result2error(ldap, entry, 0)));
+ }
+ ldap_memfree(attr);
+ }
+ else
+ {
+ DBG1("finding LDAP attributes failed: %s",
+ ldap_err2string(ldap_result2error(ldap, entry, 0)));
+ }
+ ber_free(ber, 0);
+ }
+ else
+ {
+ DBG1("finding first LDAP entry failed: %s",
+ ldap_err2string(ldap_result2error(ldap, entry, 0)));
+ }
+ return success;
+}
+
+
+static status_t fetch(private_ldap_fetcher_t *this, char *url,
+ chunk_t *result, va_list args)
+{
+ LDAP *ldap;
+ LDAPURLDesc *lurl;
+ LDAPMessage *msg;
+ int res;
+ int ldap_version = LDAP_VERSION3;
+ struct timeval timeout;
+ status_t status = FAILED;
+
+ if (!strneq(url, "ldap", 4))
+ {
+ return NOT_SUPPORTED;
+ }
+ if (ldap_url_parse(url, &lurl) != LDAP_SUCCESS)
+ {
+ return NOT_SUPPORTED;
+ }
+ ldap = ldap_init(lurl->lud_host, lurl->lud_port);
+ if (ldap == NULL)
+ {
+ DBG1("LDAP initialization failed: %s", strerror(errno));
+ ldap_free_urldesc(lurl);
+ return FAILED;
+ }
+
+ timeout.tv_sec = this->timeout;
+ timeout.tv_usec = 0;
+
+ ldap_set_option(ldap, LDAP_OPT_PROTOCOL_VERSION, &ldap_version);
+ ldap_set_option(ldap, LDAP_OPT_NETWORK_TIMEOUT, &timeout);
+
+ DBG2("sending LDAP request to '%s'...", url);
+
+ res = ldap_simple_bind_s(ldap, NULL, NULL);
+ if (res == LDAP_SUCCESS)
+ {
+ res = ldap_search_st(ldap, lurl->lud_dn, lurl->lud_scope,
+ lurl->lud_filter, lurl->lud_attrs,
+ 0, &timeout, &msg);
+
+ if (res == LDAP_SUCCESS)
+ {
+ if (parse(ldap, msg, result))
+ {
+ status = SUCCESS;
+ }
+ ldap_msgfree(msg);
+ }
+ else
+ {
+ DBG1("LDAP search failed: %s", ldap_err2string(res));
+ }
+ }
+ else
+ {
+ DBG1("LDAP bind to '%s' failed: %s", url, ldap_err2string(res));
+ }
+ ldap_unbind_s(ldap);
+ ldap_free_urldesc(lurl);
+ return status;
+}
+
+
+/**
+ * Implementation of fetcher_t.set_option.
+ */
+static bool set_option(private_ldap_fetcher_t *this, fetcher_option_t option, ...)
+{
+ va_list args;
+
+ va_start(args, option);
+ switch (option)
+ {
+ case FETCH_TIMEOUT:
+ {
+ this->timeout = va_arg(args, u_int);
+ return TRUE;
+ }
+ default:
+ return FALSE;
+ }
+}
+
+/**
+ * Implements ldap_fetcher_t.destroy
+ */
+static void destroy(private_ldap_fetcher_t *this)
+{
+ free(this);
+}
+
+/*
+ * Described in header.
+ */
+ldap_fetcher_t *ldap_fetcher_create()
+{
+ private_ldap_fetcher_t *this = malloc_thing(private_ldap_fetcher_t);
+
+ this->public.interface.fetch = (status_t(*)(fetcher_t*,char*,chunk_t*))fetch;
+ this->public.interface.set_option = (bool(*)(fetcher_t*, fetcher_option_t option, ...))set_option;
+ this->public.interface.destroy = (void (*)(fetcher_t*))destroy;
+
+ this->timeout = DEFAULT_TIMEOUT;
+
+ return &this->public;
+}
+
diff --git a/src/libstrongswan/plugins/ldap/ldap_fetcher.h b/src/libstrongswan/plugins/ldap/ldap_fetcher.h
new file mode 100644
index 000000000..bde60c799
--- /dev/null
+++ b/src/libstrongswan/plugins/ldap/ldap_fetcher.h
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2008 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.
+ */
+
+/**
+ * @defgroup ldap_fetcher ldap_fetcher
+ * @{ @ingroup ldap_p
+ */
+
+#ifndef LDAP_FETCHER_H_
+#define LDAP_FETCHER_H_
+
+typedef struct ldap_fetcher_t ldap_fetcher_t;
+
+/**
+ * Fetcher implementation using OpenLDAP.
+ */
+struct ldap_fetcher_t {
+
+ /**
+ * Implements fetcher interface
+ */
+ fetcher_t interface;
+};
+
+/**
+ * Create a ldap_fetcher instance.
+ */
+ldap_fetcher_t *ldap_fetcher_create();
+
+#endif /* LDAP_FETCHER_H_ @}*/
diff --git a/src/libstrongswan/plugins/ldap/ldap_plugin.c b/src/libstrongswan/plugins/ldap/ldap_plugin.c
new file mode 100644
index 000000000..0925cb395
--- /dev/null
+++ b/src/libstrongswan/plugins/ldap/ldap_plugin.c
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2008 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.
+ *
+ * $Id: ldap_plugin.c 3529 2008-03-05 15:26:24Z martin $
+ */
+
+#include "ldap_plugin.h"
+
+#include <library.h>
+#include "ldap_fetcher.h"
+
+typedef struct private_ldap_plugin_t private_ldap_plugin_t;
+
+/**
+ * private data of ldap_plugin
+ */
+struct private_ldap_plugin_t {
+
+ /**
+ * public functions
+ */
+ ldap_plugin_t public;
+};
+
+/**
+ * Implementation of ldap_plugin_t.destroy
+ */
+static void destroy(private_ldap_plugin_t *this)
+{
+ lib->fetcher->remove_fetcher(lib->fetcher,
+ (fetcher_constructor_t)ldap_fetcher_create);
+ free(this);
+}
+
+/*
+ * see header file
+ */
+plugin_t *plugin_create()
+{
+ private_ldap_plugin_t *this = malloc_thing(private_ldap_plugin_t);
+
+ this->public.plugin.destroy = (void(*)(plugin_t*))destroy;
+
+ lib->fetcher->add_fetcher(lib->fetcher,
+ (fetcher_constructor_t)ldap_fetcher_create, "ldap://");
+ lib->fetcher->add_fetcher(lib->fetcher,
+ (fetcher_constructor_t)ldap_fetcher_create, "ldaps://");
+
+ return &this->public.plugin;
+}
+
diff --git a/src/libstrongswan/plugins/ldap/ldap_plugin.h b/src/libstrongswan/plugins/ldap/ldap_plugin.h
new file mode 100644
index 000000000..7b2bb3232
--- /dev/null
+++ b/src/libstrongswan/plugins/ldap/ldap_plugin.h
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2008 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.
+ */
+
+/**
+ * @defgroup ldap_p ldap
+ * @ingroup plugins
+ *
+ * @defgroup ldap_plugin ldap_plugin
+ * @{ @ingroup ldap_p
+ */
+
+#ifndef LDAP_PLUGIN_H_
+#define LDAP_PLUGIN_H_
+
+#include <plugins/plugin.h>
+
+typedef struct ldap_plugin_t ldap_plugin_t;
+
+/**
+ * Plugin implementing LDAP fetcher using OpenLDAP.
+ */
+struct ldap_plugin_t {
+
+ /**
+ * implements plugin interface
+ */
+ plugin_t plugin;
+};
+
+/**
+ * Create a ldap_plugin instance.
+ */
+plugin_t *plugin_create();
+
+#endif /* LDAP_PLUGIN_H_ @}*/
diff --git a/src/libstrongswan/plugins/md5/Makefile.am b/src/libstrongswan/plugins/md5/Makefile.am
new file mode 100644
index 000000000..0a9c5cbf4
--- /dev/null
+++ b/src/libstrongswan/plugins/md5/Makefile.am
@@ -0,0 +1,10 @@
+
+INCLUDES = -I$(top_srcdir)/src/libstrongswan
+
+AM_CFLAGS = -rdynamic
+
+plugin_LTLIBRARIES = libstrongswan-md5.la
+
+libstrongswan_md5_la_SOURCES = md5_plugin.h md5_plugin.c md5_hasher.c md5_hasher.h
+libstrongswan_md5_la_LDFLAGS = -module
+
diff --git a/src/libstrongswan/plugins/md5/Makefile.in b/src/libstrongswan/plugins/md5/Makefile.in
new file mode 100644
index 000000000..6a4b2a78b
--- /dev/null
+++ b/src/libstrongswan/plugins/md5/Makefile.in
@@ -0,0 +1,494 @@
+# Makefile.in generated by automake 1.10.1 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+VPATH = @srcdir@
+pkgdatadir = $(datadir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+subdir = src/libstrongswan/plugins/md5
+DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/configure.in
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+mkinstalldirs = $(install_sh) -d
+CONFIG_CLEAN_FILES =
+am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
+am__vpath_adj = case $$p in \
+ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
+ *) f=$$p;; \
+ esac;
+am__strip_dir = `echo $$p | sed -e 's|^.*/||'`;
+am__installdirs = "$(DESTDIR)$(plugindir)"
+pluginLTLIBRARIES_INSTALL = $(INSTALL)
+LTLIBRARIES = $(plugin_LTLIBRARIES)
+libstrongswan_md5_la_LIBADD =
+am_libstrongswan_md5_la_OBJECTS = md5_plugin.lo md5_hasher.lo
+libstrongswan_md5_la_OBJECTS = $(am_libstrongswan_md5_la_OBJECTS)
+libstrongswan_md5_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(libstrongswan_md5_la_LDFLAGS) $(LDFLAGS) -o $@
+DEFAULT_INCLUDES = -I.@am__isrc@
+depcomp = $(SHELL) $(top_srcdir)/depcomp
+am__depfiles_maybe = depfiles
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+ --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
+ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+CCLD = $(CC)
+LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+ --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \
+ $(LDFLAGS) -o $@
+SOURCES = $(libstrongswan_md5_la_SOURCES)
+DIST_SOURCES = $(libstrongswan_md5_la_SOURCES)
+ETAGS = etags
+CTAGS = ctags
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+AMTAR = @AMTAR@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CXX = @CXX@
+CXXCPP = @CXXCPP@
+CXXDEPMODE = @CXXDEPMODE@
+CXXFLAGS = @CXXFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DSYMUTIL = @DSYMUTIL@
+ECHO = @ECHO@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+F77 = @F77@
+FFLAGS = @FFLAGS@
+GPERF = @GPERF@
+GREP = @GREP@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+IPSEC_ROUTING_TABLE = @IPSEC_ROUTING_TABLE@
+IPSEC_ROUTING_TABLE_PRIO = @IPSEC_ROUTING_TABLE_PRIO@
+LDFLAGS = @LDFLAGS@
+LEX = @LEX@
+LEXLIB = @LEXLIB@
+LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LINUX_HEADERS = @LINUX_HEADERS@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+MAKEINFO = @MAKEINFO@
+MKDIR_P = @MKDIR_P@
+NMEDIT = @NMEDIT@
+OBJEXT = @OBJEXT@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PERL = @PERL@
+PKG_CONFIG = @PKG_CONFIG@
+RANLIB = @RANLIB@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRIP = @STRIP@
+VERSION = @VERSION@
+YACC = @YACC@
+YFLAGS = @YFLAGS@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_CXX = @ac_ct_CXX@
+ac_ct_F77 = @ac_ct_F77@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+confdir = @confdir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+gtk_CFLAGS = @gtk_CFLAGS@
+gtk_LIBS = @gtk_LIBS@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+ipsecdir = @ipsecdir@
+ipsecgroup = @ipsecgroup@
+ipsecuser = @ipsecuser@
+libdir = @libdir@
+libexecdir = @libexecdir@
+libstrongswan_plugins = @libstrongswan_plugins@
+linuxdir = @linuxdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+piddir = @piddir@
+plugindir = @plugindir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+resolv_conf = @resolv_conf@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+simreader = @simreader@
+srcdir = @srcdir@
+strongswan_conf = @strongswan_conf@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+xml_CFLAGS = @xml_CFLAGS@
+xml_LIBS = @xml_LIBS@
+INCLUDES = -I$(top_srcdir)/src/libstrongswan
+AM_CFLAGS = -rdynamic
+plugin_LTLIBRARIES = libstrongswan-md5.la
+libstrongswan_md5_la_SOURCES = md5_plugin.h md5_plugin.c md5_hasher.c md5_hasher.h
+libstrongswan_md5_la_LDFLAGS = -module
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .c .lo .o .obj
+$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \
+ && exit 0; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/libstrongswan/plugins/md5/Makefile'; \
+ cd $(top_srcdir) && \
+ $(AUTOMAKE) --gnu src/libstrongswan/plugins/md5/Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+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) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(pluginLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) '$$p' '$(DESTDIR)$(plugindir)/$$f'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(pluginLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) "$$p" "$(DESTDIR)$(plugindir)/$$f"; \
+ else :; fi; \
+ done
+
+uninstall-pluginLTLIBRARIES:
+ @$(NORMAL_UNINSTALL)
+ @list='$(plugin_LTLIBRARIES)'; for p in $$list; do \
+ p=$(am__strip_dir) \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(plugindir)/$$p'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(plugindir)/$$p"; \
+ 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
+libstrongswan-md5.la: $(libstrongswan_md5_la_OBJECTS) $(libstrongswan_md5_la_DEPENDENCIES)
+ $(libstrongswan_md5_la_LINK) -rpath $(plugindir) $(libstrongswan_md5_la_OBJECTS) $(libstrongswan_md5_la_LIBADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/md5_hasher.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/md5_plugin.Plo@am__quote@
+
+.c.o:
+@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(COMPILE) -c $<
+
+.c.obj:
+@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'`
+
+.c.lo:
+@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $<
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+
+ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonemtpy = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ mkid -fID $$unique
+tags: TAGS
+
+TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ tags=; \
+ here=`pwd`; \
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \
+ test -n "$$unique" || unique=$$empty_fix; \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ $$tags $$unique; \
+ fi
+ctags: CTAGS
+CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ tags=; \
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ test -z "$(CTAGS_ARGS)$$tags$$unique" \
+ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+ $$tags $$unique
+
+GTAGS:
+ here=`$(am__cd) $(top_builddir) && pwd` \
+ && cd $(top_srcdir) \
+ && gtags -i $(GTAGS_ARGS) $$here
+
+distclean-tags:
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+distdir: $(DISTFILES)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ list='$(DISTFILES)'; \
+ dist_files=`for file in $$list; do echo $$file; done | \
+ sed -e "s|^$$srcdirstrip/||;t" \
+ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+ case $$dist_files in \
+ */*) $(MKDIR_P) `echo "$$dist_files" | \
+ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+ sort -u` ;; \
+ esac; \
+ for file in $$dist_files; do \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ if test -d $$d/$$file; then \
+ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
+ fi; \
+ cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
+ else \
+ test -f $(distdir)/$$file \
+ || cp -p $$d/$$file $(distdir)/$$file \
+ || exit 1; \
+ fi; \
+ done
+check-am: all-am
+check: check-am
+all-am: Makefile $(LTLIBRARIES)
+installdirs:
+ for dir in "$(DESTDIR)$(plugindir)"; do \
+ test -z "$$dir" || $(MKDIR_P) "$$dir"; \
+ done
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ `test -z '$(STRIP)' || \
+ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+clean: clean-am
+
+clean-am: clean-generic clean-libtool clean-pluginLTLIBRARIES \
+ mostlyclean-am
+
+distclean: distclean-am
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+ distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+info: info-am
+
+info-am:
+
+install-data-am: install-pluginLTLIBRARIES
+
+install-dvi: install-dvi-am
+
+install-exec-am:
+
+install-html: install-html-am
+
+install-info: install-info-am
+
+install-man:
+
+install-pdf: install-pdf-am
+
+install-ps: install-ps-am
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic \
+ mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am: uninstall-pluginLTLIBRARIES
+
+.MAKE: install-am install-strip
+
+.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \
+ clean-libtool clean-pluginLTLIBRARIES ctags distclean \
+ distclean-compile distclean-generic distclean-libtool \
+ distclean-tags distdir dvi dvi-am html html-am info info-am \
+ install install-am install-data install-data-am install-dvi \
+ install-dvi-am install-exec install-exec-am install-html \
+ install-html-am install-info install-info-am install-man \
+ install-pdf install-pdf-am install-pluginLTLIBRARIES \
+ install-ps install-ps-am install-strip installcheck \
+ installcheck-am installdirs maintainer-clean \
+ maintainer-clean-generic mostlyclean mostlyclean-compile \
+ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
+ tags uninstall uninstall-am uninstall-pluginLTLIBRARIES
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/src/libstrongswan/plugins/md5/md5_hasher.c b/src/libstrongswan/plugins/md5/md5_hasher.c
new file mode 100644
index 000000000..2354139bb
--- /dev/null
+++ b/src/libstrongswan/plugins/md5/md5_hasher.c
@@ -0,0 +1,392 @@
+/*
+ * Copyright (C) 2005-2006 Martin Willi
+ * Copyright (C) 2005 Jan Hutter
+ * Hochschule fuer Technik Rapperswil
+ * Copyright (C) 1991-1992, RSA Data Security, Inc. Created 1991.
+ * All rights reserved.
+ *
+ * Derived from the RSA Data Security, Inc. MD5 Message-Digest Algorithm.
+ * Ported to fulfill hasher_t interface.
+ *
+ * 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.
+ *
+ * $Id: md5_hasher.c 3488 2008-02-21 15:10:02Z martin $
+ */
+
+#include <string.h>
+
+#include "md5_hasher.h"
+
+
+/* Constants for MD5Transform routine. */
+#define S11 7
+#define S12 12
+#define S13 17
+#define S14 22
+#define S21 5
+#define S22 9
+#define S23 14
+#define S24 20
+#define S31 4
+#define S32 11
+#define S33 16
+#define S34 23
+#define S41 6
+#define S42 10
+#define S43 15
+#define S44 21
+
+static u_int8_t PADDING[64] = {
+ 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+};
+
+/*
+ * ugly macro stuff
+ */
+/* F, G, H and I are basic MD5 functions.
+ */
+#define F(x, y, z) (((x) & (y)) | ((~x) & (z)))
+#define G(x, y, z) (((x) & (z)) | ((y) & (~z)))
+#define H(x, y, z) ((x) ^ (y) ^ (z))
+#define I(x, y, z) ((y) ^ ((x) | (~z)))
+
+/* ROTATE_LEFT rotates x left n bits.
+ */
+#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n))))
+
+/* FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4.
+Rotation is separate from addition to prevent recomputation.
+ */
+#define FF(a, b, c, d, x, s, ac) { \
+ (a) += F ((b), (c), (d)) + (x) + (u_int32_t)(ac); \
+ (a) = ROTATE_LEFT ((a), (s)); \
+ (a) += (b); \
+ }
+#define GG(a, b, c, d, x, s, ac) { \
+ (a) += G ((b), (c), (d)) + (x) + (u_int32_t)(ac); \
+ (a) = ROTATE_LEFT ((a), (s)); \
+ (a) += (b); \
+ }
+#define HH(a, b, c, d, x, s, ac) { \
+ (a) += H ((b), (c), (d)) + (x) + (u_int32_t)(ac); \
+ (a) = ROTATE_LEFT ((a), (s)); \
+ (a) += (b); \
+ }
+#define II(a, b, c, d, x, s, ac) { \
+ (a) += I ((b), (c), (d)) + (x) + (u_int32_t)(ac); \
+ (a) = ROTATE_LEFT ((a), (s)); \
+ (a) += (b); \
+ }
+
+
+
+typedef struct private_md5_hasher_t private_md5_hasher_t;
+
+/**
+ * Private data structure with hasing context.
+ */
+struct private_md5_hasher_t {
+ /**
+ * Public interface for this hasher.
+ */
+ md5_hasher_t public;
+
+ /*
+ * State of the hasher.
+ */
+ u_int32_t state[5];
+ u_int32_t count[2];
+ u_int8_t buffer[64];
+};
+
+
+#if BYTE_ORDER != LITTLE_ENDIAN
+
+/* Encodes input (u_int32_t) into output (u_int8_t). Assumes len is
+ * a multiple of 4.
+ */
+static void Encode (u_int8_t *output, u_int32_t *input, size_t len)
+{
+ size_t i, j;
+
+ for (i = 0, j = 0; j < len; i++, j += 4)
+ {
+ output[j] = (u_int8_t)(input[i] & 0xff);
+ output[j+1] = (u_int8_t)((input[i] >> 8) & 0xff);
+ output[j+2] = (u_int8_t)((input[i] >> 16) & 0xff);
+ output[j+3] = (u_int8_t)((input[i] >> 24) & 0xff);
+ }
+}
+
+/* Decodes input (u_int8_t) into output (u_int32_t). Assumes len is
+ * a multiple of 4.
+ */
+static void Decode(u_int32_t *output, u_int8_t *input, size_t len)
+{
+ size_t i, j;
+
+ for (i = 0, j = 0; j < len; i++, j += 4)
+ {
+ output[i] = ((u_int32_t)input[j]) | (((u_int32_t)input[j+1]) << 8) |
+ (((u_int32_t)input[j+2]) << 16) | (((u_int32_t)input[j+3]) << 24);
+ }
+}
+
+#elif BYTE_ORDER == LITTLE_ENDIAN
+ #define Encode memcpy
+ #define Decode memcpy
+#endif
+
+/* MD5 basic transformation. Transforms state based on block.
+ */
+static void MD5Transform(u_int32_t state[4], u_int8_t block[64])
+{
+ u_int32_t a = state[0], b = state[1], c = state[2], d = state[3], x[16];
+
+ Decode(x, block, 64);
+
+ /* Round 1 */
+ FF (a, b, c, d, x[ 0], S11, 0xd76aa478); /* 1 */
+ FF (d, a, b, c, x[ 1], S12, 0xe8c7b756); /* 2 */
+ FF (c, d, a, b, x[ 2], S13, 0x242070db); /* 3 */
+ FF (b, c, d, a, x[ 3], S14, 0xc1bdceee); /* 4 */
+ FF (a, b, c, d, x[ 4], S11, 0xf57c0faf); /* 5 */
+ FF (d, a, b, c, x[ 5], S12, 0x4787c62a); /* 6 */
+ FF (c, d, a, b, x[ 6], S13, 0xa8304613); /* 7 */
+ FF (b, c, d, a, x[ 7], S14, 0xfd469501); /* 8 */
+ FF (a, b, c, d, x[ 8], S11, 0x698098d8); /* 9 */
+ FF (d, a, b, c, x[ 9], S12, 0x8b44f7af); /* 10 */
+ FF (c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */
+ FF (b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */
+ FF (a, b, c, d, x[12], S11, 0x6b901122); /* 13 */
+ FF (d, a, b, c, x[13], S12, 0xfd987193); /* 14 */
+ FF (c, d, a, b, x[14], S13, 0xa679438e); /* 15 */
+ FF (b, c, d, a, x[15], S14, 0x49b40821); /* 16 */
+
+ /* Round 2 */
+ GG (a, b, c, d, x[ 1], S21, 0xf61e2562); /* 17 */
+ GG (d, a, b, c, x[ 6], S22, 0xc040b340); /* 18 */
+ GG (c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */
+ GG (b, c, d, a, x[ 0], S24, 0xe9b6c7aa); /* 20 */
+ GG (a, b, c, d, x[ 5], S21, 0xd62f105d); /* 21 */
+ GG (d, a, b, c, x[10], S22, 0x2441453); /* 22 */
+ GG (c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */
+ GG (b, c, d, a, x[ 4], S24, 0xe7d3fbc8); /* 24 */
+ GG (a, b, c, d, x[ 9], S21, 0x21e1cde6); /* 25 */
+ GG (d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */
+ GG (c, d, a, b, x[ 3], S23, 0xf4d50d87); /* 27 */
+ GG (b, c, d, a, x[ 8], S24, 0x455a14ed); /* 28 */
+ GG (a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */
+ GG (d, a, b, c, x[ 2], S22, 0xfcefa3f8); /* 30 */
+ GG (c, d, a, b, x[ 7], S23, 0x676f02d9); /* 31 */
+ GG (b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 */
+
+ /* Round 3 */
+ HH (a, b, c, d, x[ 5], S31, 0xfffa3942); /* 33 */
+ HH (d, a, b, c, x[ 8], S32, 0x8771f681); /* 34 */
+ HH (c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */
+ HH (b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */
+ HH (a, b, c, d, x[ 1], S31, 0xa4beea44); /* 37 */
+ HH (d, a, b, c, x[ 4], S32, 0x4bdecfa9); /* 38 */
+ HH (c, d, a, b, x[ 7], S33, 0xf6bb4b60); /* 39 */
+ HH (b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */
+ HH (a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */
+ HH (d, a, b, c, x[ 0], S32, 0xeaa127fa); /* 42 */
+ HH (c, d, a, b, x[ 3], S33, 0xd4ef3085); /* 43 */
+ HH (b, c, d, a, x[ 6], S34, 0x4881d05); /* 44 */
+ HH (a, b, c, d, x[ 9], S31, 0xd9d4d039); /* 45 */
+ HH (d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */
+ HH (c, d, a, b, x[15], S33, 0x1fa27cf8); /* 47 */
+ HH (b, c, d, a, x[ 2], S34, 0xc4ac5665); /* 48 */
+
+ /* Round 4 */
+ II (a, b, c, d, x[ 0], S41, 0xf4292244); /* 49 */
+ II (d, a, b, c, x[ 7], S42, 0x432aff97); /* 50 */
+ II (c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */
+ II (b, c, d, a, x[ 5], S44, 0xfc93a039); /* 52 */
+ II (a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */
+ II (d, a, b, c, x[ 3], S42, 0x8f0ccc92); /* 54 */
+ II (c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */
+ II (b, c, d, a, x[ 1], S44, 0x85845dd1); /* 56 */
+ II (a, b, c, d, x[ 8], S41, 0x6fa87e4f); /* 57 */
+ II (d, a, b, c, x[15], S42, 0xfe2ce6e0); /* 58 */
+ II (c, d, a, b, x[ 6], S43, 0xa3014314); /* 59 */
+ II (b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */
+ II (a, b, c, d, x[ 4], S41, 0xf7537e82); /* 61 */
+ II (d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */
+ II (c, d, a, b, x[ 2], S43, 0x2ad7d2bb); /* 63 */
+ II (b, c, d, a, x[ 9], S44, 0xeb86d391); /* 64 */
+
+ state[0] += a;
+ state[1] += b;
+ state[2] += c;
+ state[3] += d;
+}
+
+/* MD5 block update operation. Continues an MD5 message-digest
+ * operation, processing another message block, and updating the
+ * context.
+ */
+static void MD5Update(private_md5_hasher_t *this, u_int8_t *input, size_t inputLen)
+{
+ u_int32_t i;
+ size_t index, partLen;
+
+ /* Compute number of bytes mod 64 */
+ index = (u_int8_t)((this->count[0] >> 3) & 0x3F);
+
+ /* Update number of bits */
+ if ((this->count[0] += (inputLen << 3)) < (inputLen << 3))
+ {
+ this->count[1]++;
+ }
+ this->count[1] += (inputLen >> 29);
+
+ partLen = 64 - index;
+
+ /* Transform as many times as possible. */
+ if (inputLen >= partLen)
+ {
+ memcpy(&this->buffer[index], input, partLen);
+ MD5Transform (this->state, this->buffer);
+
+ for (i = partLen; i + 63 < inputLen; i += 64)
+ {
+ MD5Transform (this->state, &input[i]);
+ }
+ index = 0;
+ }
+ else
+ {
+ i = 0;
+ }
+
+ /* Buffer remaining input */
+ memcpy(&this->buffer[index], &input[i], inputLen-i);
+}
+
+/* MD5 finalization. Ends an MD5 message-digest operation, writing the
+ * the message digest and zeroizing the context.
+ */
+static void MD5Final (private_md5_hasher_t *this, u_int8_t digest[16])
+{
+ u_int8_t bits[8];
+ size_t index, padLen;
+
+ /* Save number of bits */
+ Encode (bits, this->count, 8);
+
+ /* Pad out to 56 mod 64. */
+ index = (size_t)((this->count[0] >> 3) & 0x3f);
+ padLen = (index < 56) ? (56 - index) : (120 - index);
+ MD5Update (this, PADDING, padLen);
+
+ /* Append length (before padding) */
+ MD5Update (this, bits, 8);
+
+ if (digest != NULL) /* Bill Simpson's padding */
+ {
+ /* store state in digest */
+ Encode (digest, this->state, 16);
+ }
+}
+
+
+
+/**
+ * Implementation of hasher_t.get_hash.
+ */
+static void get_hash(private_md5_hasher_t *this, chunk_t chunk, u_int8_t *buffer)
+{
+ MD5Update(this, chunk.ptr, chunk.len);
+ if (buffer != NULL)
+ {
+ MD5Final(this, buffer);
+ this->public.hasher_interface.reset(&(this->public.hasher_interface));
+ }
+}
+
+
+/**
+ * Implementation of hasher_t.allocate_hash.
+ */
+static void allocate_hash(private_md5_hasher_t *this, chunk_t chunk, chunk_t *hash)
+{
+ chunk_t allocated_hash;
+
+ MD5Update(this, chunk.ptr, chunk.len);
+ if (hash != NULL)
+ {
+ allocated_hash.ptr = malloc(HASH_SIZE_MD5);
+ allocated_hash.len = HASH_SIZE_MD5;
+
+ MD5Final(this, allocated_hash.ptr);
+ this->public.hasher_interface.reset(&(this->public.hasher_interface));
+
+ *hash = allocated_hash;
+ }
+}
+
+/**
+ * Implementation of hasher_t.get_hash_size.
+ */
+static size_t get_hash_size(private_md5_hasher_t *this)
+{
+ return HASH_SIZE_MD5;
+}
+
+/**
+ * Implementation of hasher_t.reset.
+ */
+static void reset(private_md5_hasher_t *this)
+{
+ this->state[0] = 0x67452301;
+ this->state[1] = 0xefcdab89;
+ this->state[2] = 0x98badcfe;
+ this->state[3] = 0x10325476;
+ this->count[0] = 0;
+ this->count[1] = 0;
+}
+
+/**
+ * Implementation of hasher_t.destroy.
+ */
+static void destroy(private_md5_hasher_t *this)
+{
+ free(this);
+}
+
+/*
+ * Described in header.
+ */
+md5_hasher_t *md5_hasher_create(hash_algorithm_t algo)
+{
+ private_md5_hasher_t *this;
+
+ if (algo != HASH_MD5)
+ {
+ return NULL;
+ }
+ this = malloc_thing(private_md5_hasher_t);
+
+ this->public.hasher_interface.get_hash = (void (*) (hasher_t*, chunk_t, u_int8_t*))get_hash;
+ this->public.hasher_interface.allocate_hash = (void (*) (hasher_t*, chunk_t, chunk_t*))allocate_hash;
+ this->public.hasher_interface.get_hash_size = (size_t (*) (hasher_t*))get_hash_size;
+ this->public.hasher_interface.reset = (void (*) (hasher_t*))reset;
+ this->public.hasher_interface.destroy = (void (*) (hasher_t*))destroy;
+
+ /* initialize */
+ reset(this);
+
+ return &(this->public);
+}
diff --git a/src/libstrongswan/plugins/md5/md5_hasher.h b/src/libstrongswan/plugins/md5/md5_hasher.h
new file mode 100644
index 000000000..d4a0417ab
--- /dev/null
+++ b/src/libstrongswan/plugins/md5/md5_hasher.h
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2008 Martin Willi
+ * Copyright (C) 2005 Jan Hutter
+ * Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+/**
+ * @defgroup md5_hasher md5_hasher
+ * @{ @ingroup md5_p
+ */
+
+#ifndef MD5_HASHER_H_
+#define MD5_HASHER_H_
+
+typedef struct md5_hasher_t md5_hasher_t;
+
+#include <crypto/hashers/hasher.h>
+
+/**
+ * Implementation of hasher_t interface using the MD5 algorithm.
+ */
+struct md5_hasher_t {
+
+ /**
+ * Generic hasher_t interface for this hasher.
+ */
+ hasher_t hasher_interface;
+};
+
+/**
+ * Creates a new md5_hasher_t.
+ *
+ * @param algo hash algorithm, must be HASH_MD5
+ * @return md5_hasher_t object, NULL if not supported
+ */
+md5_hasher_t *md5_hasher_create(hash_algorithm_t algo);
+
+#endif /*MD5_HASHER_H_@}*/
diff --git a/src/libstrongswan/plugins/md5/md5_plugin.c b/src/libstrongswan/plugins/md5/md5_plugin.c
new file mode 100644
index 000000000..c1c9a0805
--- /dev/null
+++ b/src/libstrongswan/plugins/md5/md5_plugin.c
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2008 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.
+ *
+ * $Id: md5_plugin.c 3488 2008-02-21 15:10:02Z martin $
+ */
+
+#include "md5_plugin.h"
+
+#include <library.h>
+#include "md5_hasher.h"
+
+typedef struct private_md5_plugin_t private_md5_plugin_t;
+
+/**
+ * private data of md5_plugin
+ */
+struct private_md5_plugin_t {
+
+ /**
+ * public functions
+ */
+ md5_plugin_t public;
+};
+
+/**
+ * Implementation of md5_plugin_t.destroy
+ */
+static void destroy(private_md5_plugin_t *this)
+{
+ lib->crypto->remove_hasher(lib->crypto,
+ (hasher_constructor_t)md5_hasher_create);
+ free(this);
+}
+
+/*
+ * see header file
+ */
+plugin_t *plugin_create()
+{
+ private_md5_plugin_t *this = malloc_thing(private_md5_plugin_t);
+
+ this->public.plugin.destroy = (void(*)(plugin_t*))destroy;
+
+ lib->crypto->add_hasher(lib->crypto, HASH_MD5,
+ (hasher_constructor_t)md5_hasher_create);
+
+ return &this->public.plugin;
+}
+
diff --git a/src/libstrongswan/plugins/md5/md5_plugin.h b/src/libstrongswan/plugins/md5/md5_plugin.h
new file mode 100644
index 000000000..e8e8dd535
--- /dev/null
+++ b/src/libstrongswan/plugins/md5/md5_plugin.h
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2008 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.
+ */
+
+/**
+ * @defgroup md5_p md5
+ * @ingroup plugins
+ *
+ * @defgroup md5_plugin md5_plugin
+ * @{ @ingroup md5_p
+ */
+
+#ifndef MD5_PLUGIN_H_
+#define MD5_PLUGIN_H_
+
+#include <plugins/plugin.h>
+
+typedef struct md5_plugin_t md5_plugin_t;
+
+/**
+ * Plugin implementing the MD5 hash algorithm in software.
+ */
+struct md5_plugin_t {
+
+ /**
+ * implements plugin interface
+ */
+ plugin_t plugin;
+};
+
+/**
+ * Create a md5_plugin instance.
+ */
+plugin_t *plugin_create();
+
+#endif /* MD5_PLUGIN_H_ @}*/
diff --git a/src/libstrongswan/plugins/mysql/Makefile.am b/src/libstrongswan/plugins/mysql/Makefile.am
new file mode 100644
index 000000000..ec94b8fda
--- /dev/null
+++ b/src/libstrongswan/plugins/mysql/Makefile.am
@@ -0,0 +1,12 @@
+
+INCLUDES = -I$(top_srcdir)/src/libstrongswan
+
+AM_CFLAGS = -rdynamic
+
+plugin_LTLIBRARIES = libstrongswan-mysql.la
+
+libstrongswan_mysql_la_SOURCES = mysql_plugin.h mysql_plugin.c \
+ mysql_database.h mysql_database.c
+libstrongswan_mysql_la_LDFLAGS = -module
+libstrongswan_mysql_la_LIBADD = -lmysqlclient_r
+
diff --git a/src/libstrongswan/plugins/mysql/Makefile.in b/src/libstrongswan/plugins/mysql/Makefile.in
new file mode 100644
index 000000000..6de9dc13d
--- /dev/null
+++ b/src/libstrongswan/plugins/mysql/Makefile.in
@@ -0,0 +1,497 @@
+# Makefile.in generated by automake 1.10.1 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+VPATH = @srcdir@
+pkgdatadir = $(datadir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+subdir = src/libstrongswan/plugins/mysql
+DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/configure.in
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+mkinstalldirs = $(install_sh) -d
+CONFIG_CLEAN_FILES =
+am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
+am__vpath_adj = case $$p in \
+ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
+ *) f=$$p;; \
+ esac;
+am__strip_dir = `echo $$p | sed -e 's|^.*/||'`;
+am__installdirs = "$(DESTDIR)$(plugindir)"
+pluginLTLIBRARIES_INSTALL = $(INSTALL)
+LTLIBRARIES = $(plugin_LTLIBRARIES)
+libstrongswan_mysql_la_DEPENDENCIES =
+am_libstrongswan_mysql_la_OBJECTS = mysql_plugin.lo mysql_database.lo
+libstrongswan_mysql_la_OBJECTS = $(am_libstrongswan_mysql_la_OBJECTS)
+libstrongswan_mysql_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(libstrongswan_mysql_la_LDFLAGS) $(LDFLAGS) -o $@
+DEFAULT_INCLUDES = -I.@am__isrc@
+depcomp = $(SHELL) $(top_srcdir)/depcomp
+am__depfiles_maybe = depfiles
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+ --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
+ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+CCLD = $(CC)
+LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+ --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \
+ $(LDFLAGS) -o $@
+SOURCES = $(libstrongswan_mysql_la_SOURCES)
+DIST_SOURCES = $(libstrongswan_mysql_la_SOURCES)
+ETAGS = etags
+CTAGS = ctags
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+AMTAR = @AMTAR@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CXX = @CXX@
+CXXCPP = @CXXCPP@
+CXXDEPMODE = @CXXDEPMODE@
+CXXFLAGS = @CXXFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DSYMUTIL = @DSYMUTIL@
+ECHO = @ECHO@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+F77 = @F77@
+FFLAGS = @FFLAGS@
+GPERF = @GPERF@
+GREP = @GREP@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+IPSEC_ROUTING_TABLE = @IPSEC_ROUTING_TABLE@
+IPSEC_ROUTING_TABLE_PRIO = @IPSEC_ROUTING_TABLE_PRIO@
+LDFLAGS = @LDFLAGS@
+LEX = @LEX@
+LEXLIB = @LEXLIB@
+LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LINUX_HEADERS = @LINUX_HEADERS@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+MAKEINFO = @MAKEINFO@
+MKDIR_P = @MKDIR_P@
+NMEDIT = @NMEDIT@
+OBJEXT = @OBJEXT@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PERL = @PERL@
+PKG_CONFIG = @PKG_CONFIG@
+RANLIB = @RANLIB@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRIP = @STRIP@
+VERSION = @VERSION@
+YACC = @YACC@
+YFLAGS = @YFLAGS@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_CXX = @ac_ct_CXX@
+ac_ct_F77 = @ac_ct_F77@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+confdir = @confdir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+gtk_CFLAGS = @gtk_CFLAGS@
+gtk_LIBS = @gtk_LIBS@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+ipsecdir = @ipsecdir@
+ipsecgroup = @ipsecgroup@
+ipsecuser = @ipsecuser@
+libdir = @libdir@
+libexecdir = @libexecdir@
+libstrongswan_plugins = @libstrongswan_plugins@
+linuxdir = @linuxdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+piddir = @piddir@
+plugindir = @plugindir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+resolv_conf = @resolv_conf@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+simreader = @simreader@
+srcdir = @srcdir@
+strongswan_conf = @strongswan_conf@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+xml_CFLAGS = @xml_CFLAGS@
+xml_LIBS = @xml_LIBS@
+INCLUDES = -I$(top_srcdir)/src/libstrongswan
+AM_CFLAGS = -rdynamic
+plugin_LTLIBRARIES = libstrongswan-mysql.la
+libstrongswan_mysql_la_SOURCES = mysql_plugin.h mysql_plugin.c \
+ mysql_database.h mysql_database.c
+
+libstrongswan_mysql_la_LDFLAGS = -module
+libstrongswan_mysql_la_LIBADD = -lmysqlclient_r
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .c .lo .o .obj
+$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \
+ && exit 0; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/libstrongswan/plugins/mysql/Makefile'; \
+ cd $(top_srcdir) && \
+ $(AUTOMAKE) --gnu src/libstrongswan/plugins/mysql/Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+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) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(pluginLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) '$$p' '$(DESTDIR)$(plugindir)/$$f'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(pluginLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) "$$p" "$(DESTDIR)$(plugindir)/$$f"; \
+ else :; fi; \
+ done
+
+uninstall-pluginLTLIBRARIES:
+ @$(NORMAL_UNINSTALL)
+ @list='$(plugin_LTLIBRARIES)'; for p in $$list; do \
+ p=$(am__strip_dir) \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(plugindir)/$$p'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(plugindir)/$$p"; \
+ 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
+libstrongswan-mysql.la: $(libstrongswan_mysql_la_OBJECTS) $(libstrongswan_mysql_la_DEPENDENCIES)
+ $(libstrongswan_mysql_la_LINK) -rpath $(plugindir) $(libstrongswan_mysql_la_OBJECTS) $(libstrongswan_mysql_la_LIBADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mysql_database.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mysql_plugin.Plo@am__quote@
+
+.c.o:
+@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(COMPILE) -c $<
+
+.c.obj:
+@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'`
+
+.c.lo:
+@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $<
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+
+ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonemtpy = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ mkid -fID $$unique
+tags: TAGS
+
+TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ tags=; \
+ here=`pwd`; \
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \
+ test -n "$$unique" || unique=$$empty_fix; \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ $$tags $$unique; \
+ fi
+ctags: CTAGS
+CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ tags=; \
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ test -z "$(CTAGS_ARGS)$$tags$$unique" \
+ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+ $$tags $$unique
+
+GTAGS:
+ here=`$(am__cd) $(top_builddir) && pwd` \
+ && cd $(top_srcdir) \
+ && gtags -i $(GTAGS_ARGS) $$here
+
+distclean-tags:
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+distdir: $(DISTFILES)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ list='$(DISTFILES)'; \
+ dist_files=`for file in $$list; do echo $$file; done | \
+ sed -e "s|^$$srcdirstrip/||;t" \
+ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+ case $$dist_files in \
+ */*) $(MKDIR_P) `echo "$$dist_files" | \
+ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+ sort -u` ;; \
+ esac; \
+ for file in $$dist_files; do \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ if test -d $$d/$$file; then \
+ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
+ fi; \
+ cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
+ else \
+ test -f $(distdir)/$$file \
+ || cp -p $$d/$$file $(distdir)/$$file \
+ || exit 1; \
+ fi; \
+ done
+check-am: all-am
+check: check-am
+all-am: Makefile $(LTLIBRARIES)
+installdirs:
+ for dir in "$(DESTDIR)$(plugindir)"; do \
+ test -z "$$dir" || $(MKDIR_P) "$$dir"; \
+ done
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ `test -z '$(STRIP)' || \
+ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+clean: clean-am
+
+clean-am: clean-generic clean-libtool clean-pluginLTLIBRARIES \
+ mostlyclean-am
+
+distclean: distclean-am
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+ distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+info: info-am
+
+info-am:
+
+install-data-am: install-pluginLTLIBRARIES
+
+install-dvi: install-dvi-am
+
+install-exec-am:
+
+install-html: install-html-am
+
+install-info: install-info-am
+
+install-man:
+
+install-pdf: install-pdf-am
+
+install-ps: install-ps-am
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic \
+ mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am: uninstall-pluginLTLIBRARIES
+
+.MAKE: install-am install-strip
+
+.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \
+ clean-libtool clean-pluginLTLIBRARIES ctags distclean \
+ distclean-compile distclean-generic distclean-libtool \
+ distclean-tags distdir dvi dvi-am html html-am info info-am \
+ install install-am install-data install-data-am install-dvi \
+ install-dvi-am install-exec install-exec-am install-html \
+ install-html-am install-info install-info-am install-man \
+ install-pdf install-pdf-am install-pluginLTLIBRARIES \
+ install-ps install-ps-am install-strip installcheck \
+ installcheck-am installdirs maintainer-clean \
+ maintainer-clean-generic mostlyclean mostlyclean-compile \
+ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
+ tags uninstall uninstall-am uninstall-pluginLTLIBRARIES
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/src/libstrongswan/plugins/mysql/mysql_database.c b/src/libstrongswan/plugins/mysql/mysql_database.c
new file mode 100644
index 000000000..58202c5ae
--- /dev/null
+++ b/src/libstrongswan/plugins/mysql/mysql_database.c
@@ -0,0 +1,695 @@
+/*
+ * 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.
+ *
+ * $Id: mysql_database.c 4111 2008-06-26 07:31:52Z martin $
+ */
+
+#define _GNU_SOURCE
+#include <string.h>
+#include <pthread.h>
+#include <mysql/mysql.h>
+
+#include "mysql_database.h"
+
+#include <debug.h>
+#include <utils/mutex.h>
+#include <utils/linked_list.h>
+
+/* Older mysql.h headers do not define it, but we need it. It is not returned
+ * in in MySQL 4 by default, but by MySQL 5. To avoid this problem, we catch
+ * it in all cases. */
+#ifndef MYSQL_DATA_TRUNCATED
+#define MYSQL_DATA_TRUNCATED 101
+#endif
+
+typedef struct private_mysql_database_t private_mysql_database_t;
+
+/**
+ * private data of mysql_database
+ */
+struct private_mysql_database_t {
+
+ /**
+ * public functions
+ */
+ mysql_database_t public;
+
+ /**
+ * connection pool, contains conn_t
+ */
+ linked_list_t *pool;
+
+ /**
+ * mutex to lock pool
+ */
+ mutex_t *mutex;
+
+ /**
+ * hostname to connect to
+ */
+ char *host;
+
+ /**
+ * username to use
+ */
+ char *username;
+
+ /**
+ * password
+ */
+ char *password;
+
+ /**
+ * database name
+ */
+ char *database;
+
+ /**
+ * tcp port
+ */
+ int port;
+};
+
+typedef struct conn_t conn_t;
+
+/**
+ * connection pool entry
+ */
+struct conn_t {
+
+ /**
+ * MySQL database connection
+ */
+ MYSQL *mysql;
+
+ /**
+ * connection in use?
+ */
+ bool in_use;
+};
+
+/**
+ * Release a mysql connection
+ */
+static void conn_release(conn_t *conn)
+{
+ conn->in_use = FALSE;
+}
+/**
+ * thread specific initialization flag
+ */
+pthread_key_t initialized;
+
+/**
+ * Initialize a thread for mysql usage
+ */
+static void thread_initialize()
+{
+ if (pthread_getspecific(initialized) == NULL)
+ {
+ pthread_setspecific(initialized, (void*)TRUE);
+ mysql_thread_init();
+ }
+}
+
+/**
+ * mysql library initialization function
+ */
+bool mysql_database_init()
+{
+ if (mysql_library_init(0, NULL, NULL))
+ {
+ return FALSE;
+ }
+ if (pthread_key_create(&initialized, (void*)mysql_thread_end))
+ {
+ mysql_library_end();
+ return FALSE;
+ }
+ return TRUE;
+}
+
+/**
+ * mysql library cleanup function
+ */
+void mysql_database_deinit()
+{
+ pthread_key_delete(initialized);
+ mysql_thread_end();
+ /* mysql_library_end(); would be the clean way, however, it hangs... */
+}
+
+/**
+ * Destroy a mysql connection
+ */
+static void conn_destroy(conn_t *this)
+{
+ mysql_close(this->mysql);
+ free(this);
+}
+
+/**
+ * Acquire/Reuse a mysql connection
+ */
+static conn_t *conn_get(private_mysql_database_t *this)
+{
+ conn_t *current, *found = NULL;
+ enumerator_t *enumerator;
+
+ thread_initialize();
+
+ while (TRUE)
+ {
+ this->mutex->lock(this->mutex);
+ enumerator = this->pool->create_enumerator(this->pool);
+ while (enumerator->enumerate(enumerator, &current))
+ {
+ if (!current->in_use)
+ {
+ found = current;
+ found->in_use = TRUE;
+ break;
+ }
+ }
+ enumerator->destroy(enumerator);
+ this->mutex->unlock(this->mutex);
+ if (found)
+ { /* check connection if found, release if ping fails */
+ if (mysql_ping(found->mysql) == 0)
+ {
+ break;
+ }
+ this->mutex->lock(this->mutex);
+ this->pool->remove(this->pool, found, NULL);
+ this->mutex->unlock(this->mutex);
+ conn_destroy(found);
+ found = NULL;
+ continue;
+ }
+ break;
+ }
+ if (found == NULL)
+ {
+ found = malloc_thing(conn_t);
+ found->in_use = TRUE;
+ found->mysql = mysql_init(NULL);
+ if (!mysql_real_connect(found->mysql, this->host, this->username,
+ this->password, this->database, this->port,
+ NULL, 0))
+ {
+ DBG1("connecting to mysql://%s:***@%s:%d/%s failed: %s",
+ this->username, this->host, this->port, this->database,
+ mysql_error(found->mysql));
+ conn_destroy(found);
+ found = NULL;
+ }
+ else
+ {
+ this->mutex->lock(this->mutex);
+ this->pool->insert_last(this->pool, found);
+ DBG2("increased MySQL connection pool size to %d",
+ this->pool->get_count(this->pool));
+ this->mutex->unlock(this->mutex);
+ }
+ }
+ return found;
+}
+
+/**
+ * Create and run a MySQL stmt using a sql string and args
+ */
+static MYSQL_STMT* run(MYSQL *mysql, char *sql, va_list *args)
+{
+ MYSQL_STMT *stmt;
+ int params;
+
+ stmt = mysql_stmt_init(mysql);
+ if (stmt == NULL)
+ {
+ DBG1("creating MySQL statement failed: %s", mysql_error(mysql));
+ return NULL;
+ }
+ if (mysql_stmt_prepare(stmt, sql, strlen(sql)))
+ {
+ DBG1("preparing MySQL statement failed: %s", mysql_stmt_error(stmt));
+ mysql_stmt_close(stmt);
+ return NULL;
+ }
+ params = mysql_stmt_param_count(stmt);
+ if (params > 0)
+ {
+ int i;
+ MYSQL_BIND *bind;
+
+ bind = alloca(sizeof(MYSQL_BIND) * params);
+ memset(bind, 0, sizeof(MYSQL_BIND) * params);
+
+ for (i = 0; i < params; i++)
+ {
+ switch (va_arg(*args, db_type_t))
+ {
+ case DB_INT:
+ {
+ bind[i].buffer_type = MYSQL_TYPE_LONG;
+ bind[i].buffer = (char*)alloca(sizeof(int));
+ *(int*)bind[i].buffer = va_arg(*args, int);
+ bind[i].buffer_length = sizeof(int);
+ break;
+ }
+ case DB_UINT:
+ {
+ bind[i].buffer_type = MYSQL_TYPE_LONG;
+ bind[i].buffer = (char*)alloca(sizeof(u_int));
+ *(u_int*)bind[i].buffer = va_arg(*args, u_int);
+ bind[i].buffer_length = sizeof(u_int);
+ bind[i].is_unsigned = TRUE;
+ break;
+ }
+ case DB_TEXT:
+ {
+ bind[i].buffer_type = MYSQL_TYPE_STRING;;
+ bind[i].buffer = va_arg(*args, char*);
+ if (bind[i].buffer)
+ {
+ bind[i].buffer_length = strlen(bind[i].buffer);
+ }
+ break;
+ }
+ case DB_BLOB:
+ {
+ chunk_t chunk = va_arg(*args, chunk_t);
+ bind[i].buffer_type = MYSQL_TYPE_BLOB;
+ bind[i].buffer = chunk.ptr;
+ bind[i].buffer_length = chunk.len;
+ break;
+ }
+ case DB_DOUBLE:
+ {
+ bind[i].buffer_type = MYSQL_TYPE_DOUBLE;
+ bind[i].buffer = (char*)alloca(sizeof(double));
+ *(double*)bind[i].buffer = va_arg(*args, double);
+ bind[i].buffer_length = sizeof(double);
+ break;
+ }
+ case DB_NULL:
+ {
+ bind[i].buffer_type = MYSQL_TYPE_NULL;
+ break;
+ }
+ default:
+ DBG1("invalid data type supplied");
+ mysql_stmt_close(stmt);
+ return NULL;
+ }
+ }
+ if (mysql_stmt_bind_param(stmt, bind))
+ {
+ DBG1("binding MySQL param failed: %s", mysql_stmt_error(stmt));
+ mysql_stmt_close(stmt);
+ return NULL;
+ }
+ }
+ if (mysql_stmt_execute(stmt))
+ {
+ DBG1("executing MySQL statement failed: %s", mysql_stmt_error(stmt));
+ mysql_stmt_close(stmt);
+ return NULL;
+ }
+ return stmt;
+}
+
+typedef struct {
+ /** implements enumerator_t */
+ enumerator_t public;
+ /** associated MySQL statement */
+ MYSQL_STMT *stmt;
+ /** result bindings */
+ MYSQL_BIND *bind;
+ /** pooled connection handle */
+ conn_t *conn;
+ /** value for INT, UINT, double */
+ union {
+ void *p_void;;
+ int *p_int;
+ u_int *p_uint;
+ double *p_double;
+ } val;
+ /* length for TEXT and BLOB */
+ unsigned long *length;
+} mysql_enumerator_t;
+
+/**
+ * create a mysql enumerator
+ */
+static void mysql_enumerator_destroy(mysql_enumerator_t *this)
+{
+ int columns, i;
+
+ columns = mysql_stmt_field_count(this->stmt);
+
+ for (i = 0; i < columns; i++)
+ {
+ switch (this->bind[i].buffer_type)
+ {
+ case MYSQL_TYPE_STRING:
+ case MYSQL_TYPE_BLOB:
+ {
+ free(this->bind[i].buffer);
+ break;
+ }
+ default:
+ break;
+ }
+ }
+ mysql_stmt_close(this->stmt);
+ conn_release(this->conn);
+ free(this->bind);
+ free(this->val.p_void);
+ free(this->length);
+ free(this);
+}
+
+/**
+ * Implementation of database.query().enumerate
+ */
+static bool mysql_enumerator_enumerate(mysql_enumerator_t *this, ...)
+{
+ int i, columns;
+ va_list args;
+
+ columns = mysql_stmt_field_count(this->stmt);
+
+ /* free/reset data set of previous call */
+ for (i = 0; i < columns; i++)
+ {
+ switch (this->bind[i].buffer_type)
+ {
+ case MYSQL_TYPE_STRING:
+ case MYSQL_TYPE_BLOB:
+ {
+ free(this->bind[i].buffer);
+ this->bind[i].buffer = NULL;
+ this->bind[i].buffer_length = 0;
+ this->bind[i].length = &this->length[i];
+ this->length[i] = 0;
+ break;
+ }
+ default:
+ break;
+ }
+ }
+
+ switch (mysql_stmt_fetch(this->stmt))
+ {
+ case 0:
+ case MYSQL_DATA_TRUNCATED:
+ break;
+ case MYSQL_NO_DATA:
+ return FALSE;
+ default:
+ DBG1("fetching MySQL row failed: %s", mysql_stmt_error(this->stmt));
+ return FALSE;
+ }
+
+ va_start(args, this);
+ for (i = 0; i < columns; i++)
+ {
+ switch (this->bind[i].buffer_type)
+ {
+ case MYSQL_TYPE_LONG:
+ {
+ if (this->bind[i].is_unsigned)
+ {
+ u_int *value = va_arg(args, u_int*);
+ *value = this->val.p_uint[i];
+ }
+ else
+ {
+ int *value = va_arg(args, int*);
+ *value = this->val.p_int[i];
+ }
+ break;
+ }
+ case MYSQL_TYPE_STRING:
+ {
+ char **value = va_arg(args, char**);
+ this->bind[i].buffer = malloc(this->length[i]+1);
+ this->bind[i].buffer_length = this->length[i];
+ *value = this->bind[i].buffer;
+ mysql_stmt_fetch_column(this->stmt, &this->bind[i], i, 0);
+ ((char*)this->bind[i].buffer)[this->length[i]] = '\0';
+ break;
+ }
+ case MYSQL_TYPE_BLOB:
+ {
+ chunk_t *value = va_arg(args, chunk_t*);
+ this->bind[i].buffer = malloc(this->length[i]);
+ this->bind[i].buffer_length = this->length[i];
+ value->ptr = this->bind[i].buffer;
+ value->len = this->length[i];
+ mysql_stmt_fetch_column(this->stmt, &this->bind[i], i, 0);
+ break;
+ }
+ case MYSQL_TYPE_DOUBLE:
+ {
+ double *value = va_arg(args, double*);
+ *value = this->val.p_double[i];
+ break;
+ }
+ default:
+ break;
+ }
+ }
+ return TRUE;
+}
+
+/**
+ * Implementation of database_t.query.
+ */
+static enumerator_t* query(private_mysql_database_t *this, char *sql, ...)
+{
+ MYSQL_STMT *stmt;
+ va_list args;
+ mysql_enumerator_t *enumerator = NULL;
+ conn_t *conn;
+
+ conn = conn_get(this);
+ if (!conn)
+ {
+ return NULL;
+ }
+
+ va_start(args, sql);
+ stmt = run(conn->mysql, sql, &args);
+ if (stmt)
+ {
+ int columns, i;
+
+ enumerator = malloc_thing(mysql_enumerator_t);
+ enumerator->public.enumerate = (void*)mysql_enumerator_enumerate;
+ enumerator->public.destroy = (void*)mysql_enumerator_destroy;
+ enumerator->stmt = stmt;
+ enumerator->conn = conn;
+ columns = mysql_stmt_field_count(stmt);
+ enumerator->bind = calloc(columns, sizeof(MYSQL_BIND));
+ enumerator->length = calloc(columns, sizeof(unsigned long));
+ enumerator->val.p_void = calloc(columns, sizeof(enumerator->val));
+ for (i = 0; i < columns; i++)
+ {
+ switch (va_arg(args, db_type_t))
+ {
+ case DB_INT:
+ {
+ enumerator->bind[i].buffer_type = MYSQL_TYPE_LONG;
+ enumerator->bind[i].buffer = (char*)&enumerator->val.p_int[i];
+ break;
+ }
+ case DB_UINT:
+ {
+ enumerator->bind[i].buffer_type = MYSQL_TYPE_LONG;
+ enumerator->bind[i].buffer = (char*)&enumerator->val.p_uint[i];
+ enumerator->bind[i].is_unsigned = TRUE;
+ break;
+ }
+ case DB_TEXT:
+ {
+ enumerator->bind[i].buffer_type = MYSQL_TYPE_STRING;
+ enumerator->bind[i].length = &enumerator->length[i];
+ break;
+ }
+ case DB_BLOB:
+ {
+ enumerator->bind[i].buffer_type = MYSQL_TYPE_BLOB;
+ enumerator->bind[i].length = &enumerator->length[i];
+ break;
+ }
+ case DB_DOUBLE:
+ {
+ enumerator->bind[i].buffer_type = MYSQL_TYPE_DOUBLE;
+ enumerator->bind[i].buffer = (char*)&enumerator->val.p_double[i];
+ break;
+ }
+ default:
+ DBG1("invalid result data type supplied");
+ mysql_enumerator_destroy(enumerator);
+ va_end(args);
+ return NULL;
+ }
+ }
+ if (mysql_stmt_bind_result(stmt, enumerator->bind))
+ {
+ DBG1("binding MySQL result failed: %s", mysql_stmt_error(stmt));
+ mysql_enumerator_destroy(enumerator);
+ enumerator = NULL;
+ }
+ }
+ else
+ {
+ conn_release(conn);
+ }
+ va_end(args);
+ return (enumerator_t*)enumerator;
+}
+
+/**
+ * Implementation of database_t.execute.
+ */
+static int execute(private_mysql_database_t *this, int *rowid, char *sql, ...)
+{
+ MYSQL_STMT *stmt;
+ va_list args;
+ conn_t *conn;
+ int affected = -1;
+
+ conn = conn_get(this);
+ if (!conn)
+ {
+ return -1;
+ }
+ va_start(args, sql);
+ stmt = run(conn->mysql, sql, &args);
+ if (stmt)
+ {
+ if (rowid)
+ {
+ *rowid = mysql_stmt_insert_id(stmt);
+ }
+ affected = mysql_stmt_affected_rows(stmt);
+ mysql_stmt_close(stmt);
+ }
+ va_end(args);
+ conn_release(conn);
+ return affected;
+}
+
+/**
+ * Implementation of database_t.destroy
+ */
+static void destroy(private_mysql_database_t *this)
+{
+ this->pool->destroy_function(this->pool, (void*)conn_destroy);
+ this->mutex->destroy(this->mutex);
+ free(this->host);
+ free(this->username);
+ free(this->password);
+ free(this->database);
+ free(this);
+}
+
+static bool parse_uri(private_mysql_database_t *this, char *uri)
+{
+ char *username, *password, *host, *port = "0", *database, *pos;
+
+ /**
+ * parse mysql://username:pass@host:port/database uri
+ */
+ username = strdupa(uri + 8);
+ pos = strchr(username, ':');
+ if (pos)
+ {
+ *pos = '\0';
+ password = pos + 1;
+ pos = strrchr(password, '@');
+ if (pos)
+ {
+ *pos = '\0';
+ host = pos + 1;
+ pos = strrchr(host, ':');
+ if (pos)
+ {
+ *pos = '\0';
+ port = pos + 1;
+ pos = strchr(port, '/');
+ }
+ else
+ {
+ pos = strchr(host, '/');
+ }
+ if (pos)
+ {
+ *pos = '\0';
+ database = pos + 1;
+
+ this->host = strdup(host);
+ this->username = strdup(username);
+ this->password = strdup(password);
+ this->database = strdup(database);
+ this->port = atoi(port);
+ return TRUE;
+ }
+ }
+ }
+ DBG1("parsing MySQL database uri '%s' failed", uri);
+ return FALSE;
+}
+
+
+/*
+ * see header file
+ */
+mysql_database_t *mysql_database_create(char *uri)
+{
+ conn_t *conn;
+ private_mysql_database_t *this;
+
+ if (!strneq(uri, "mysql://", 8))
+ {
+ return NULL;
+ }
+
+ this = malloc_thing(private_mysql_database_t);
+
+ this->public.db.query = (enumerator_t* (*)(database_t *this, char *sql, ...))query;
+ this->public.db.execute = (int (*)(database_t *this, int *rowid, char *sql, ...))execute;
+ this->public.db.destroy = (void(*)(database_t*))destroy;
+
+ if (!parse_uri(this, uri))
+ {
+ free(this);
+ return NULL;
+ }
+ this->mutex = mutex_create(MUTEX_DEFAULT);
+ this->pool = linked_list_create();
+
+ /* check connectivity */
+ conn = conn_get(this);
+ if (!conn)
+ {
+ destroy(this);
+ return NULL;
+ }
+ conn_release(conn);
+ return &this->public;
+}
+
diff --git a/src/libstrongswan/plugins/mysql/mysql_database.h b/src/libstrongswan/plugins/mysql/mysql_database.h
new file mode 100644
index 000000000..d04aa79fa
--- /dev/null
+++ b/src/libstrongswan/plugins/mysql/mysql_database.h
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2007-2008 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.
+ */
+
+/**
+ * @defgroup mysql_database mysql_database
+ * @{ @ingroup mysql_p
+ */
+
+#ifndef MYSQL_DATABASE_H_
+#define MYSQL_DATABASE_H_
+
+#include <database/database.h>
+
+typedef struct mysql_database_t mysql_database_t;
+
+/**
+ * MySQL databse_t implementation.
+ */
+struct mysql_database_t {
+
+ /**
+ * Implements database_t
+ */
+ database_t db;
+};
+
+/**
+ * Create a mysql_database instance.
+ *
+ * @param uri connection URI, mysql://user:pass@host:port/database
+ */
+mysql_database_t *mysql_database_create(char *uri);
+
+/**
+ * MySQL client library initialization function
+ *
+ * @return FALSE if initialization failed
+ */
+bool mysql_database_init();
+
+/**
+ * Mysql client library cleanup function
+ */
+void mysql_database_deinit();
+
+#endif /* MYSQL_DATABASE_H_ @}*/
diff --git a/src/libstrongswan/plugins/mysql/mysql_plugin.c b/src/libstrongswan/plugins/mysql/mysql_plugin.c
new file mode 100644
index 000000000..29348ac14
--- /dev/null
+++ b/src/libstrongswan/plugins/mysql/mysql_plugin.c
@@ -0,0 +1,69 @@
+/*
+ * Copyright (C) 2008 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.
+ *
+ * $Id: mysql_plugin.c 3488 2008-02-21 15:10:02Z martin $
+ */
+
+#include "mysql_plugin.h"
+
+#include <library.h>
+#include <debug.h>
+#include "mysql_database.h"
+
+typedef struct private_mysql_plugin_t private_mysql_plugin_t;
+
+/**
+ * private data of mysql_plugin
+ */
+struct private_mysql_plugin_t {
+
+ /**
+ * public functions
+ */
+ mysql_plugin_t public;
+};
+
+/**
+ * Implementation of plugin_t.destroy
+ */
+static void destroy(private_mysql_plugin_t *this)
+{
+ lib->db->remove_database(lib->db,
+ (database_constructor_t)mysql_database_create);
+ mysql_database_deinit();
+ free(this);
+}
+
+/*
+ * see header file
+ */
+plugin_t *plugin_create()
+{
+ private_mysql_plugin_t *this;
+
+ if (!mysql_database_init())
+ {
+ DBG1("MySQL client library initialization failed");
+ return NULL;
+ }
+
+ this = malloc_thing(private_mysql_plugin_t);
+ this->public.plugin.destroy = (void(*)(plugin_t*))destroy;
+
+ lib->db->add_database(lib->db,
+ (database_constructor_t)mysql_database_create);
+
+ return &this->public.plugin;
+}
+
diff --git a/src/libstrongswan/plugins/mysql/mysql_plugin.h b/src/libstrongswan/plugins/mysql/mysql_plugin.h
new file mode 100644
index 000000000..dbcabaafe
--- /dev/null
+++ b/src/libstrongswan/plugins/mysql/mysql_plugin.h
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2008 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.
+ */
+
+/**
+ * @defgroup mysql_p mysql
+ * @ingroup plugins
+ *
+ * @defgroup mysql_plugin mysql_plugin
+ * @{ @ingroup mysql_p
+ */
+
+#ifndef MYSQL_PLUGIN_H_
+#define MYSQL_PLUGIN_H_
+
+#include <plugins/plugin.h>
+
+typedef struct mysql_plugin_t mysql_plugin_t;
+
+/**
+ * Plugin implementing mysql database connectivity.
+ */
+struct mysql_plugin_t {
+
+ /**
+ * implements plugin interface
+ */
+ plugin_t plugin;
+};
+
+/**
+ * Create a mysql_plugin instance.
+ */
+plugin_t *plugin_create();
+
+#endif /* MYSQL_PLUGIN_H_ @}*/
diff --git a/src/libstrongswan/plugins/openssl/Makefile.am b/src/libstrongswan/plugins/openssl/Makefile.am
new file mode 100644
index 000000000..f331a78eb
--- /dev/null
+++ b/src/libstrongswan/plugins/openssl/Makefile.am
@@ -0,0 +1,21 @@
+
+INCLUDES = -I$(top_srcdir)/src/libstrongswan
+
+AM_CFLAGS = -rdynamic
+
+plugin_LTLIBRARIES = libstrongswan-openssl.la
+
+libstrongswan_openssl_la_SOURCES = openssl_plugin.h openssl_plugin.c \
+ openssl_util.c openssl_util.h \
+ openssl_crypter.c openssl_crypter.h \
+ openssl_hasher.c openssl_hasher.h \
+ openssl_diffie_hellman.c openssl_diffie_hellman.h \
+ openssl_rsa_private_key.c openssl_rsa_private_key.h \
+ openssl_rsa_public_key.c openssl_rsa_public_key.h \
+ openssl_ec_diffie_hellman.c openssl_ec_diffie_hellman.h \
+ openssl_ec_private_key.c openssl_ec_private_key.h \
+ openssl_ec_public_key.c openssl_ec_public_key.h
+
+libstrongswan_openssl_la_LDFLAGS = -module
+libstrongswan_openssl_la_LIBADD = -lcrypto
+
diff --git a/src/libstrongswan/plugins/openssl/Makefile.in b/src/libstrongswan/plugins/openssl/Makefile.in
new file mode 100644
index 000000000..f83b0ce38
--- /dev/null
+++ b/src/libstrongswan/plugins/openssl/Makefile.in
@@ -0,0 +1,518 @@
+# Makefile.in generated by automake 1.10.1 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+VPATH = @srcdir@
+pkgdatadir = $(datadir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+subdir = src/libstrongswan/plugins/openssl
+DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/configure.in
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+mkinstalldirs = $(install_sh) -d
+CONFIG_CLEAN_FILES =
+am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
+am__vpath_adj = case $$p in \
+ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
+ *) f=$$p;; \
+ esac;
+am__strip_dir = `echo $$p | sed -e 's|^.*/||'`;
+am__installdirs = "$(DESTDIR)$(plugindir)"
+pluginLTLIBRARIES_INSTALL = $(INSTALL)
+LTLIBRARIES = $(plugin_LTLIBRARIES)
+libstrongswan_openssl_la_DEPENDENCIES =
+am_libstrongswan_openssl_la_OBJECTS = openssl_plugin.lo \
+ openssl_util.lo openssl_crypter.lo openssl_hasher.lo \
+ openssl_diffie_hellman.lo openssl_rsa_private_key.lo \
+ openssl_rsa_public_key.lo openssl_ec_diffie_hellman.lo \
+ openssl_ec_private_key.lo openssl_ec_public_key.lo
+libstrongswan_openssl_la_OBJECTS = \
+ $(am_libstrongswan_openssl_la_OBJECTS)
+libstrongswan_openssl_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(libstrongswan_openssl_la_LDFLAGS) $(LDFLAGS) -o $@
+DEFAULT_INCLUDES = -I.@am__isrc@
+depcomp = $(SHELL) $(top_srcdir)/depcomp
+am__depfiles_maybe = depfiles
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+ --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
+ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+CCLD = $(CC)
+LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+ --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \
+ $(LDFLAGS) -o $@
+SOURCES = $(libstrongswan_openssl_la_SOURCES)
+DIST_SOURCES = $(libstrongswan_openssl_la_SOURCES)
+ETAGS = etags
+CTAGS = ctags
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+AMTAR = @AMTAR@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CXX = @CXX@
+CXXCPP = @CXXCPP@
+CXXDEPMODE = @CXXDEPMODE@
+CXXFLAGS = @CXXFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DSYMUTIL = @DSYMUTIL@
+ECHO = @ECHO@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+F77 = @F77@
+FFLAGS = @FFLAGS@
+GPERF = @GPERF@
+GREP = @GREP@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+IPSEC_ROUTING_TABLE = @IPSEC_ROUTING_TABLE@
+IPSEC_ROUTING_TABLE_PRIO = @IPSEC_ROUTING_TABLE_PRIO@
+LDFLAGS = @LDFLAGS@
+LEX = @LEX@
+LEXLIB = @LEXLIB@
+LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LINUX_HEADERS = @LINUX_HEADERS@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+MAKEINFO = @MAKEINFO@
+MKDIR_P = @MKDIR_P@
+NMEDIT = @NMEDIT@
+OBJEXT = @OBJEXT@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PERL = @PERL@
+PKG_CONFIG = @PKG_CONFIG@
+RANLIB = @RANLIB@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRIP = @STRIP@
+VERSION = @VERSION@
+YACC = @YACC@
+YFLAGS = @YFLAGS@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_CXX = @ac_ct_CXX@
+ac_ct_F77 = @ac_ct_F77@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+confdir = @confdir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+gtk_CFLAGS = @gtk_CFLAGS@
+gtk_LIBS = @gtk_LIBS@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+ipsecdir = @ipsecdir@
+ipsecgroup = @ipsecgroup@
+ipsecuser = @ipsecuser@
+libdir = @libdir@
+libexecdir = @libexecdir@
+libstrongswan_plugins = @libstrongswan_plugins@
+linuxdir = @linuxdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+piddir = @piddir@
+plugindir = @plugindir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+resolv_conf = @resolv_conf@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+simreader = @simreader@
+srcdir = @srcdir@
+strongswan_conf = @strongswan_conf@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+xml_CFLAGS = @xml_CFLAGS@
+xml_LIBS = @xml_LIBS@
+INCLUDES = -I$(top_srcdir)/src/libstrongswan
+AM_CFLAGS = -rdynamic
+plugin_LTLIBRARIES = libstrongswan-openssl.la
+libstrongswan_openssl_la_SOURCES = openssl_plugin.h openssl_plugin.c \
+ openssl_util.c openssl_util.h \
+ openssl_crypter.c openssl_crypter.h \
+ openssl_hasher.c openssl_hasher.h \
+ openssl_diffie_hellman.c openssl_diffie_hellman.h \
+ openssl_rsa_private_key.c openssl_rsa_private_key.h \
+ openssl_rsa_public_key.c openssl_rsa_public_key.h \
+ openssl_ec_diffie_hellman.c openssl_ec_diffie_hellman.h \
+ openssl_ec_private_key.c openssl_ec_private_key.h \
+ openssl_ec_public_key.c openssl_ec_public_key.h
+
+libstrongswan_openssl_la_LDFLAGS = -module
+libstrongswan_openssl_la_LIBADD = -lcrypto
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .c .lo .o .obj
+$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \
+ && exit 0; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/libstrongswan/plugins/openssl/Makefile'; \
+ cd $(top_srcdir) && \
+ $(AUTOMAKE) --gnu src/libstrongswan/plugins/openssl/Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+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) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(pluginLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) '$$p' '$(DESTDIR)$(plugindir)/$$f'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(pluginLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) "$$p" "$(DESTDIR)$(plugindir)/$$f"; \
+ else :; fi; \
+ done
+
+uninstall-pluginLTLIBRARIES:
+ @$(NORMAL_UNINSTALL)
+ @list='$(plugin_LTLIBRARIES)'; for p in $$list; do \
+ p=$(am__strip_dir) \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(plugindir)/$$p'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(plugindir)/$$p"; \
+ 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
+libstrongswan-openssl.la: $(libstrongswan_openssl_la_OBJECTS) $(libstrongswan_openssl_la_DEPENDENCIES)
+ $(libstrongswan_openssl_la_LINK) -rpath $(plugindir) $(libstrongswan_openssl_la_OBJECTS) $(libstrongswan_openssl_la_LIBADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/openssl_crypter.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/openssl_diffie_hellman.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/openssl_ec_diffie_hellman.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/openssl_ec_private_key.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/openssl_ec_public_key.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/openssl_hasher.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/openssl_plugin.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/openssl_rsa_private_key.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/openssl_rsa_public_key.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/openssl_util.Plo@am__quote@
+
+.c.o:
+@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(COMPILE) -c $<
+
+.c.obj:
+@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'`
+
+.c.lo:
+@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $<
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+
+ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonemtpy = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ mkid -fID $$unique
+tags: TAGS
+
+TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ tags=; \
+ here=`pwd`; \
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \
+ test -n "$$unique" || unique=$$empty_fix; \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ $$tags $$unique; \
+ fi
+ctags: CTAGS
+CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ tags=; \
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ test -z "$(CTAGS_ARGS)$$tags$$unique" \
+ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+ $$tags $$unique
+
+GTAGS:
+ here=`$(am__cd) $(top_builddir) && pwd` \
+ && cd $(top_srcdir) \
+ && gtags -i $(GTAGS_ARGS) $$here
+
+distclean-tags:
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+distdir: $(DISTFILES)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ list='$(DISTFILES)'; \
+ dist_files=`for file in $$list; do echo $$file; done | \
+ sed -e "s|^$$srcdirstrip/||;t" \
+ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+ case $$dist_files in \
+ */*) $(MKDIR_P) `echo "$$dist_files" | \
+ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+ sort -u` ;; \
+ esac; \
+ for file in $$dist_files; do \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ if test -d $$d/$$file; then \
+ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
+ fi; \
+ cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
+ else \
+ test -f $(distdir)/$$file \
+ || cp -p $$d/$$file $(distdir)/$$file \
+ || exit 1; \
+ fi; \
+ done
+check-am: all-am
+check: check-am
+all-am: Makefile $(LTLIBRARIES)
+installdirs:
+ for dir in "$(DESTDIR)$(plugindir)"; do \
+ test -z "$$dir" || $(MKDIR_P) "$$dir"; \
+ done
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ `test -z '$(STRIP)' || \
+ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+clean: clean-am
+
+clean-am: clean-generic clean-libtool clean-pluginLTLIBRARIES \
+ mostlyclean-am
+
+distclean: distclean-am
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+ distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+info: info-am
+
+info-am:
+
+install-data-am: install-pluginLTLIBRARIES
+
+install-dvi: install-dvi-am
+
+install-exec-am:
+
+install-html: install-html-am
+
+install-info: install-info-am
+
+install-man:
+
+install-pdf: install-pdf-am
+
+install-ps: install-ps-am
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic \
+ mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am: uninstall-pluginLTLIBRARIES
+
+.MAKE: install-am install-strip
+
+.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \
+ clean-libtool clean-pluginLTLIBRARIES ctags distclean \
+ distclean-compile distclean-generic distclean-libtool \
+ distclean-tags distdir dvi dvi-am html html-am info info-am \
+ install install-am install-data install-data-am install-dvi \
+ install-dvi-am install-exec install-exec-am install-html \
+ install-html-am install-info install-info-am install-man \
+ install-pdf install-pdf-am install-pluginLTLIBRARIES \
+ install-ps install-ps-am install-strip installcheck \
+ installcheck-am installdirs maintainer-clean \
+ maintainer-clean-generic mostlyclean mostlyclean-compile \
+ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
+ tags uninstall uninstall-am uninstall-pluginLTLIBRARIES
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/src/libstrongswan/plugins/openssl/openssl_crypter.c b/src/libstrongswan/plugins/openssl/openssl_crypter.c
new file mode 100644
index 000000000..e59c4d615
--- /dev/null
+++ b/src/libstrongswan/plugins/openssl/openssl_crypter.c
@@ -0,0 +1,258 @@
+/*
+ * Copyright (C) 2008 Tobias Brunner
+ * 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.
+ *
+ * $Id: openssl_crypter.c 4020 2008-05-28 12:20:38Z andreas $
+ */
+
+#include "openssl_crypter.h"
+
+#include <openssl/evp.h>
+
+typedef struct private_openssl_crypter_t private_openssl_crypter_t;
+
+/**
+ * Private data of openssl_crypter_t
+ */
+struct private_openssl_crypter_t {
+
+ /**
+ * Public part of this class.
+ */
+ openssl_crypter_t public;
+
+ /*
+ * the key
+ */
+ chunk_t key;
+
+ /*
+ * the cipher to use
+ */
+ const EVP_CIPHER *cipher;
+};
+
+/**
+ * Mapping from the algorithms defined in IKEv2 to
+ * OpenSSL algorithm names and their key length
+ */
+typedef struct {
+ /**
+ * Identifier specified in IKEv2
+ */
+ int ikev2_id;
+
+ /**
+ * Name of the algorithm, as used in OpenSSL
+ */
+ char *name;
+
+ /**
+ * Minimum valid key length in bytes
+ */
+ size_t key_size_min;
+
+ /**
+ * Maximum valid key length in bytes
+ */
+ size_t key_size_max;
+} openssl_algorithm_t;
+
+#define END_OF_LIST -1
+
+/**
+ * Algorithms for encryption
+ */
+static openssl_algorithm_t encryption_algs[] = {
+/* {ENCR_DES_IV64, "***", 0, 0}, */
+ {ENCR_DES, "des", 8, 8}, /* 64 bits */
+ {ENCR_3DES, "des3", 24, 24}, /* 192 bits */
+ {ENCR_RC5, "rc5", 5, 255}, /* 40 to 2040 bits, RFC 2451 */
+ {ENCR_IDEA, "idea", 16, 16}, /* 128 bits, RFC 2451 */
+ {ENCR_CAST, "cast", 5, 16}, /* 40 to 128 bits, RFC 2451 */
+ {ENCR_BLOWFISH, "blowfish", 5, 56}, /* 40 to 448 bits, RFC 2451 */
+/* {ENCR_3IDEA, "***", 0, 0}, */
+/* {ENCR_DES_IV32, "***", 0, 0}, */
+/* {ENCR_NULL, "***", 0, 0}, */ /* handled separately */
+/* {ENCR_AES_CBC, "***", 0, 0}, */ /* handled separately */
+/* {ENCR_AES_CTR, "***", 0, 0}, */ /* disabled in evp.h */
+ {END_OF_LIST, NULL, 0, 0},
+};
+
+/**
+ * Look up an OpenSSL algorithm name and validate its key size
+ */
+static char* lookup_algorithm(openssl_algorithm_t *openssl_algo,
+ u_int16_t ikev2_algo, size_t *key_size)
+{
+ while (openssl_algo->ikev2_id != END_OF_LIST)
+ {
+ if (ikev2_algo == openssl_algo->ikev2_id)
+ {
+ /* set the key size if it is not set */
+ if (*key_size == 0 &&
+ (openssl_algo->key_size_min == openssl_algo->key_size_max))
+ {
+ *key_size = openssl_algo->key_size_min;
+ }
+
+ /* validate key size */
+ if (*key_size < openssl_algo->key_size_min ||
+ *key_size > openssl_algo->key_size_max)
+ {
+ return NULL;
+ }
+ return openssl_algo->name;
+ }
+ openssl_algo++;
+ }
+ return NULL;
+}
+
+static void crypt(private_openssl_crypter_t *this, chunk_t data,
+ chunk_t iv, chunk_t *dst, int enc)
+{
+ int len;
+ u_char *out;
+
+ out = data.ptr;
+ if (dst)
+ {
+ *dst = chunk_alloc(data.len);
+ out = dst->ptr;
+ }
+ EVP_CIPHER_CTX ctx;
+ EVP_CIPHER_CTX_init(&ctx);
+ EVP_CipherInit_ex(&ctx, this->cipher, NULL, this->key.ptr, iv.ptr, enc);
+ EVP_CIPHER_CTX_set_padding(&ctx, 0); /* disable padding */
+ EVP_CipherUpdate(&ctx, out, &len, data.ptr, data.len);
+ EVP_CipherFinal_ex(&ctx, out, &len); /* since padding is disabled this does nothing */
+ EVP_CIPHER_CTX_cleanup(&ctx);
+}
+
+/**
+ * Implementation of crypter_t.decrypt.
+ */
+static void decrypt(private_openssl_crypter_t *this, chunk_t data,
+ chunk_t iv, chunk_t *dst)
+{
+ crypt(this, data, iv, dst, 0);
+}
+
+
+/**
+ * Implementation of crypter_t.encrypt.
+ */
+static void encrypt (private_openssl_crypter_t *this, chunk_t data,
+ chunk_t iv, chunk_t *dst)
+{
+ crypt(this, data, iv, dst, 1);
+}
+
+/**
+ * Implementation of crypter_t.get_block_size.
+ */
+static size_t get_block_size(private_openssl_crypter_t *this)
+{
+ return this->cipher->block_size;
+}
+
+/**
+ * Implementation of crypter_t.get_key_size.
+ */
+static size_t get_key_size(private_openssl_crypter_t *this)
+{
+ return this->key.len;
+}
+
+/**
+ * Implementation of crypter_t.set_key.
+ */
+static void set_key(private_openssl_crypter_t *this, chunk_t key)
+{
+ memcpy(this->key.ptr, key.ptr, min(key.len, this->key.len));
+}
+
+/**
+ * Implementation of crypter_t.destroy.
+ */
+static void destroy (private_openssl_crypter_t *this)
+{
+ free(this->key.ptr);
+ free(this);
+}
+
+/*
+ * Described in header
+ */
+openssl_crypter_t *openssl_crypter_create(encryption_algorithm_t algo,
+ size_t key_size)
+{
+ private_openssl_crypter_t *this;
+
+ this = malloc_thing(private_openssl_crypter_t);
+
+ switch (algo)
+ {
+ case ENCR_NULL:
+ this->cipher = EVP_enc_null();
+ break;
+ case ENCR_AES_CBC:
+ switch (key_size)
+ {
+ case 16: /* AES 128 */
+ this->cipher = EVP_get_cipherbyname("aes128");
+ break;
+ case 24: /* AES-192 */
+ this->cipher = EVP_get_cipherbyname("aes192");
+ break;
+ case 32: /* AES-256 */
+ this->cipher = EVP_get_cipherbyname("aes256");
+ break;
+ default:
+ free(this);
+ return NULL;
+ }
+ break;
+ default:
+ {
+ char* name = lookup_algorithm(encryption_algs, algo, &key_size);
+ if (!name)
+ {
+ /* algo unavailable or key_size invalid */
+ free(this);
+ return NULL;
+ }
+ this->cipher = EVP_get_cipherbyname(name);
+ break;
+ }
+ }
+
+ if (!this->cipher)
+ {
+ /* OpenSSL does not support the requested algo */
+ free(this);
+ return NULL;
+ }
+
+ this->key = chunk_alloc(key_size);
+
+ this->public.crypter_interface.encrypt = (void (*) (crypter_t *, chunk_t,chunk_t, chunk_t *)) encrypt;
+ this->public.crypter_interface.decrypt = (void (*) (crypter_t *, chunk_t , chunk_t, chunk_t *)) decrypt;
+ this->public.crypter_interface.get_block_size = (size_t (*) (crypter_t *)) get_block_size;
+ this->public.crypter_interface.get_key_size = (size_t (*) (crypter_t *)) get_key_size;
+ this->public.crypter_interface.set_key = (void (*) (crypter_t *,chunk_t)) set_key;
+ this->public.crypter_interface.destroy = (void (*) (crypter_t *)) destroy;
+
+ return &this->public;
+}
diff --git a/src/libstrongswan/plugins/openssl/openssl_crypter.h b/src/libstrongswan/plugins/openssl/openssl_crypter.h
new file mode 100644
index 000000000..f80d0dec6
--- /dev/null
+++ b/src/libstrongswan/plugins/openssl/openssl_crypter.h
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2008 Tobias Brunner
+ * 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.
+ *
+ * $Id: openssl_crypter.h 4000 2008-05-22 12:13:10Z tobias $
+ */
+
+/**
+ * @defgroup openssl_crypter openssl_crypter
+ * @{ @ingroup openssl_p
+ */
+
+#ifndef OPENSSL_CRYPTER_H_
+#define OPENSSL_CRYPTER_H_
+
+typedef struct openssl_crypter_t openssl_crypter_t;
+
+#include <crypto/crypters/crypter.h>
+
+/**
+ * Implementation of crypters using OpenSSL.
+ */
+struct openssl_crypter_t {
+
+ /**
+ * The crypter_t interface.
+ */
+ crypter_t crypter_interface;
+};
+
+/**
+ * Constructor to create openssl_crypter_t.
+ *
+ * @param algo algorithm to implement
+ * @param key_size key size in bytes
+ * @return openssl_crypter_t, NULL if not supported
+ */
+openssl_crypter_t *openssl_crypter_create(encryption_algorithm_t algo,
+ size_t key_size);
+
+#endif /* OPENSSL_CRYPTER_H_ @}*/
diff --git a/src/libstrongswan/plugins/openssl/openssl_diffie_hellman.c b/src/libstrongswan/plugins/openssl/openssl_diffie_hellman.c
new file mode 100644
index 000000000..95c079b0b
--- /dev/null
+++ b/src/libstrongswan/plugins/openssl/openssl_diffie_hellman.c
@@ -0,0 +1,242 @@
+/*
+ * Copyright (C) 2008 Tobias Brunner
+ * 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.
+ *
+ * $Id: openssl_diffie_hellman.c 3896 2008-04-29 15:42:34Z tobias $
+ */
+
+#include <openssl/dh.h>
+
+#include "openssl_diffie_hellman.h"
+
+#include <debug.h>
+
+typedef struct modulus_entry_t modulus_entry_t;
+
+/**
+ * Entry of the modulus list.
+ */
+struct modulus_entry_t {
+ /**
+ * Group number as it is defined in file transform_substructure.h.
+ */
+ diffie_hellman_group_t group;
+
+ /**
+ * Pointer to the function to get the modulus.
+ */
+ BIGNUM *(*get_prime)(BIGNUM *bn);
+
+ /*
+ * Generator value.
+ */
+ u_int16_t generator;
+};
+
+/**
+ * All supported modulus values.
+ */
+static modulus_entry_t modulus_entries[] = {
+ {MODP_768_BIT, get_rfc2409_prime_768, 2},
+ {MODP_1024_BIT, get_rfc2409_prime_1024, 2},
+ {MODP_1536_BIT, get_rfc3526_prime_1536, 2},
+ {MODP_2048_BIT, get_rfc3526_prime_2048, 2},
+ {MODP_3072_BIT, get_rfc3526_prime_3072, 2},
+ {MODP_4096_BIT, get_rfc3526_prime_4096, 2},
+ {MODP_6144_BIT, get_rfc3526_prime_6144, 2},
+ {MODP_8192_BIT, get_rfc3526_prime_8192, 2},
+};
+
+typedef struct private_openssl_diffie_hellman_t private_openssl_diffie_hellman_t;
+
+/**
+ * Private data of an openssl_diffie_hellman_t object.
+ */
+struct private_openssl_diffie_hellman_t {
+ /**
+ * Public openssl_diffie_hellman_t interface.
+ */
+ openssl_diffie_hellman_t public;
+
+ /**
+ * Diffie Hellman group number.
+ */
+ u_int16_t group;
+
+ /**
+ * Diffie Hellman object
+ */
+ DH *dh;
+
+ /**
+ * Other public value
+ */
+ BIGNUM *pub_key;
+
+ /**
+ * Shared secret
+ */
+ chunk_t shared_secret;
+
+ /**
+ * True if shared secret is computed
+ */
+ bool computed;
+};
+
+/**
+ * Convert a BIGNUM to a chunk
+ */
+static void bn2chunk(BIGNUM *bn, chunk_t *chunk)
+{
+ chunk->len = BN_num_bytes(bn);
+ chunk->ptr = malloc(chunk->len);
+ BN_bn2bin(bn, chunk->ptr);
+}
+
+/**
+ * Implementation of openssl_diffie_hellman_t.set_other_public_value.
+ */
+static void set_other_public_value(private_openssl_diffie_hellman_t *this, chunk_t value)
+{
+ int len;
+ BN_bin2bn(value.ptr, value.len, this->pub_key);
+
+ len = DH_size(this->dh);
+ chunk_free(&this->shared_secret);
+ this->shared_secret = chunk_alloc(len);
+
+ if (DH_compute_key(this->shared_secret.ptr, this->pub_key, this->dh) < 0) {
+ DBG1("DH shared secret computation failed");
+ return;
+ }
+
+ this->computed = TRUE;
+}
+
+/**
+ * Implementation of openssl_diffie_hellman_t.get_other_public_value.
+ */
+static status_t get_other_public_value(private_openssl_diffie_hellman_t *this,
+ chunk_t *value)
+{
+ if (!this->computed)
+ {
+ return FAILED;
+ }
+ bn2chunk(this->pub_key, value);
+ return SUCCESS;
+}
+
+/**
+ * Implementation of openssl_diffie_hellman_t.get_my_public_value.
+ */
+static void get_my_public_value(private_openssl_diffie_hellman_t *this,chunk_t *value)
+{
+ bn2chunk(this->dh->pub_key, value);
+}
+
+/**
+ * Implementation of openssl_diffie_hellman_t.get_shared_secret.
+ */
+static status_t get_shared_secret(private_openssl_diffie_hellman_t *this, chunk_t *secret)
+{
+ if (!this->computed)
+ {
+ return FAILED;
+ }
+ *secret = chunk_clone(this->shared_secret);
+ return SUCCESS;
+}
+
+/**
+ * Implementation of openssl_diffie_hellman_t.get_dh_group.
+ */
+static diffie_hellman_group_t get_dh_group(private_openssl_diffie_hellman_t *this)
+{
+ return this->group;
+}
+
+/**
+ * Lookup the modulus in modulo table
+ */
+static status_t set_modulus(private_openssl_diffie_hellman_t *this)
+{
+ int i;
+ for (i = 0; i < (sizeof(modulus_entries) / sizeof(modulus_entry_t)); i++)
+ {
+ if (modulus_entries[i].group == this->group)
+ {
+ this->dh->p = modulus_entries[i].get_prime(NULL);
+ this->dh->g = BN_new();
+ BN_set_word(this->dh->g, modulus_entries[i].generator);
+ return SUCCESS;
+ }
+ }
+ return NOT_FOUND;
+}
+
+/**
+ * Implementation of openssl_diffie_hellman_t.destroy.
+ */
+static void destroy(private_openssl_diffie_hellman_t *this)
+{
+ BN_clear_free(this->pub_key);
+ DH_free(this->dh);
+ chunk_free(&this->shared_secret);
+ free(this);
+}
+
+/*
+ * Described in header.
+ */
+openssl_diffie_hellman_t *openssl_diffie_hellman_create(diffie_hellman_group_t group)
+{
+ private_openssl_diffie_hellman_t *this = malloc_thing(private_openssl_diffie_hellman_t);
+
+ this->public.dh.get_shared_secret = (status_t (*)(diffie_hellman_t *, chunk_t *)) get_shared_secret;
+ this->public.dh.set_other_public_value = (void (*)(diffie_hellman_t *, chunk_t )) set_other_public_value;
+ this->public.dh.get_other_public_value = (status_t (*)(diffie_hellman_t *, chunk_t *)) get_other_public_value;
+ this->public.dh.get_my_public_value = (void (*)(diffie_hellman_t *, chunk_t *)) get_my_public_value;
+ this->public.dh.get_dh_group = (diffie_hellman_group_t (*)(diffie_hellman_t *)) get_dh_group;
+ this->public.dh.destroy = (void (*)(diffie_hellman_t *)) destroy;
+
+ this->dh = DH_new();
+ if (!this->dh)
+ {
+ free(this);
+ return NULL;
+ }
+
+ this->group = group;
+ this->computed = FALSE;
+
+ this->pub_key = BN_new();
+ this->shared_secret = chunk_empty;
+
+ /* find a modulus according to group */
+ if (set_modulus(this) != SUCCESS)
+ {
+ destroy(this);
+ return NULL;
+ }
+
+ /* generate my public and private values */
+ if (!DH_generate_key(this->dh))
+ {
+ destroy(this);
+ return NULL;
+ }
+
+ return &this->public;
+}
diff --git a/src/libstrongswan/plugins/openssl/openssl_diffie_hellman.h b/src/libstrongswan/plugins/openssl/openssl_diffie_hellman.h
new file mode 100644
index 000000000..c72b4aab0
--- /dev/null
+++ b/src/libstrongswan/plugins/openssl/openssl_diffie_hellman.h
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2008 Tobias Brunner
+ * 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.
+ *
+ * $Id: openssl_diffie_hellman.h 4000 2008-05-22 12:13:10Z tobias $
+ */
+
+/**
+ * @defgroup openssl_diffie_hellman openssl_diffie_hellman
+ * @{ @ingroup openssl_p
+ */
+
+#ifndef OPENSSL_DIFFIE_HELLMAN_H_
+#define OPENSSL_DIFFIE_HELLMAN_H_
+
+typedef struct openssl_diffie_hellman_t openssl_diffie_hellman_t;
+
+#include <library.h>
+
+/**
+ * Implementation of the Diffie-Hellman algorithm using OpenSSL.
+ */
+struct openssl_diffie_hellman_t {
+
+ /**
+ * Implements diffie_hellman_t interface.
+ */
+ diffie_hellman_t dh;
+};
+
+/**
+ * Creates a new openssl_diffie_hellman_t object.
+ *
+ * @param group Diffie Hellman group number to use
+ * @return openssl_diffie_hellman_t object, NULL if not supported
+ */
+openssl_diffie_hellman_t *openssl_diffie_hellman_create(diffie_hellman_group_t group);
+
+#endif /*OPENSSL_DIFFIE_HELLMAN_H_ @}*/
+
diff --git a/src/libstrongswan/plugins/openssl/openssl_ec_diffie_hellman.c b/src/libstrongswan/plugins/openssl/openssl_ec_diffie_hellman.c
new file mode 100644
index 000000000..9d2bd44cd
--- /dev/null
+++ b/src/libstrongswan/plugins/openssl/openssl_ec_diffie_hellman.c
@@ -0,0 +1,342 @@
+/*
+ * Copyright (C) 2008 Tobias Brunner
+ * 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.
+ *
+ * $Id: openssl_ec_diffie_hellman.c 4052 2008-06-10 09:19:18Z tobias $
+ */
+
+#include <openssl/ec.h>
+#include <openssl/objects.h>
+
+#include "openssl_ec_diffie_hellman.h"
+#include "openssl_util.h"
+
+#include <debug.h>
+
+typedef struct private_openssl_ec_diffie_hellman_t private_openssl_ec_diffie_hellman_t;
+
+/**
+ * Private data of an openssl_ec_diffie_hellman_t object.
+ */
+struct private_openssl_ec_diffie_hellman_t {
+ /**
+ * Public openssl_ec_diffie_hellman_t interface.
+ */
+ openssl_ec_diffie_hellman_t public;
+
+ /**
+ * Diffie Hellman group number.
+ */
+ u_int16_t group;
+
+ /**
+ * EC private (public) key
+ */
+ EC_KEY *key;
+
+ /**
+ * EC group
+ */
+ const EC_GROUP *ec_group;
+
+ /**
+ * Other public key
+ */
+ EC_POINT *pub_key;
+
+ /**
+ * Shared secret
+ */
+ chunk_t shared_secret;
+
+ /**
+ * True if shared secret is computed
+ */
+ bool computed;
+};
+
+/**
+ * Convert a chunk to an EC_POINT (which must already exist). The x and y
+ * coordinates of the point have to be concatenated in the chunk.
+ */
+static bool chunk2ecp(const EC_GROUP *group, chunk_t chunk, EC_POINT *point)
+{
+ BN_CTX *ctx;
+ BIGNUM *x, *y;
+ bool ret = FALSE;
+
+ ctx = BN_CTX_new();
+ if (!ctx)
+ {
+ return FALSE;
+ }
+
+ BN_CTX_start(ctx);
+ x = BN_CTX_get(ctx);
+ y = BN_CTX_get(ctx);
+ if (!x || !y)
+ {
+ goto error;
+ }
+
+ if (!openssl_bn_split(chunk, x, y))
+ {
+ goto error;
+ }
+
+ if (!EC_POINT_set_affine_coordinates_GFp(group, point, x, y, ctx))
+ {
+ goto error;
+ }
+
+ ret = TRUE;
+error:
+ BN_CTX_end(ctx);
+ BN_CTX_free(ctx);
+ return ret;
+}
+
+/**
+ * Convert an EC_POINT to a chunk by concatenating the x and y coordinates of
+ * the point. This function allocates memory for the chunk.
+ */
+static bool ecp2chunk(const EC_GROUP *group, const EC_POINT *point, chunk_t *chunk)
+{
+ BN_CTX *ctx;
+ BIGNUM *x, *y;
+ bool ret = FALSE;
+
+ ctx = BN_CTX_new();
+ if (!ctx)
+ {
+ return FALSE;
+ }
+
+ BN_CTX_start(ctx);
+ x = BN_CTX_get(ctx);
+ y = BN_CTX_get(ctx);
+ if (!x || !y)
+ {
+ goto error;
+ }
+
+ if (!EC_POINT_get_affine_coordinates_GFp(group, point, x, y, ctx))
+ {
+ goto error;
+ }
+
+ if (!openssl_bn_cat(EC_FIELD_ELEMENT_LEN(group), x, y, chunk))
+ {
+ goto error;
+ }
+
+ ret = TRUE;
+error:
+ BN_CTX_end(ctx);
+ BN_CTX_free(ctx);
+ return ret;
+}
+
+/**
+ * Compute the shared secret.
+ *
+ * We cannot use the function ECDH_compute_key() because that returns only the
+ * x coordinate of the shared secret point (which is defined, for instance, in
+ * 'NIST SP 800-56A').
+ * However, we need both coordinates as RFC 4753 says: "The Diffie-Hellman
+ * public value is obtained by concatenating the x and y values. The format
+ * of the Diffie-Hellman shared secret value is the same as that of the
+ * Diffie-Hellman public value."
+ */
+static bool compute_shared_key(private_openssl_ec_diffie_hellman_t *this, chunk_t *shared_secret)
+{
+ const BIGNUM *priv_key;
+ EC_POINT *secret = NULL;
+ bool ret = FALSE;
+
+ priv_key = EC_KEY_get0_private_key(this->key);
+ if (!priv_key)
+ {
+ goto error;
+ }
+
+ secret = EC_POINT_new(this->ec_group);
+ if (!secret)
+ {
+ goto error;
+ }
+
+ if (!EC_POINT_mul(this->ec_group, secret, NULL, this->pub_key, priv_key, NULL))
+ {
+ goto error;
+ }
+
+ if (!ecp2chunk(this->ec_group, secret, shared_secret))
+ {
+ goto error;
+ }
+
+ ret = TRUE;
+error:
+ if (secret)
+ {
+ EC_POINT_clear_free(secret);
+ }
+ return ret;
+}
+
+/**
+ * Implementation of openssl_ec_diffie_hellman_t.set_other_public_value.
+ */
+static void set_other_public_value(private_openssl_ec_diffie_hellman_t *this, chunk_t value)
+{
+ if (!chunk2ecp(this->ec_group, value, this->pub_key))
+ {
+ DBG1("ECDH public value is malformed");
+ return;
+ }
+
+ chunk_free(&this->shared_secret);
+
+ if (!compute_shared_key(this, &this->shared_secret)) {
+ DBG1("ECDH shared secret computation failed");
+ return;
+ }
+
+ this->computed = TRUE;
+}
+
+/**
+ * Implementation of openssl_ec_diffie_hellman_t.get_other_public_value.
+ */
+static status_t get_other_public_value(private_openssl_ec_diffie_hellman_t *this,
+ chunk_t *value)
+{
+ if (!this->computed)
+ {
+ return FAILED;
+ }
+
+ if (!ecp2chunk(this->ec_group, this->pub_key, value))
+ {
+ return FAILED;
+ }
+ return SUCCESS;
+}
+
+/**
+ * Implementation of openssl_ec_diffie_hellman_t.get_my_public_value.
+ */
+static void get_my_public_value(private_openssl_ec_diffie_hellman_t *this,chunk_t *value)
+{
+ ecp2chunk(this->ec_group, EC_KEY_get0_public_key(this->key), value);
+}
+
+/**
+ * Implementation of openssl_ec_diffie_hellman_t.get_shared_secret.
+ */
+static status_t get_shared_secret(private_openssl_ec_diffie_hellman_t *this, chunk_t *secret)
+{
+ if (!this->computed)
+ {
+ return FAILED;
+ }
+ *secret = chunk_clone(this->shared_secret);
+ return SUCCESS;
+}
+
+/**
+ * Implementation of openssl_ec_diffie_hellman_t.get_dh_group.
+ */
+static diffie_hellman_group_t get_dh_group(private_openssl_ec_diffie_hellman_t *this)
+{
+ return this->group;
+}
+
+/**
+ * Implementation of openssl_ec_diffie_hellman_t.destroy.
+ */
+static void destroy(private_openssl_ec_diffie_hellman_t *this)
+{
+ EC_POINT_clear_free(this->pub_key);
+ EC_KEY_free(this->key);
+ chunk_free(&this->shared_secret);
+ free(this);
+}
+
+/*
+ * Described in header.
+ */
+openssl_ec_diffie_hellman_t *openssl_ec_diffie_hellman_create(diffie_hellman_group_t group)
+{
+ private_openssl_ec_diffie_hellman_t *this = malloc_thing(private_openssl_ec_diffie_hellman_t);
+
+ this->public.dh.get_shared_secret = (status_t (*)(diffie_hellman_t *, chunk_t *)) get_shared_secret;
+ this->public.dh.set_other_public_value = (void (*)(diffie_hellman_t *, chunk_t )) set_other_public_value;
+ this->public.dh.get_other_public_value = (status_t (*)(diffie_hellman_t *, chunk_t *)) get_other_public_value;
+ this->public.dh.get_my_public_value = (void (*)(diffie_hellman_t *, chunk_t *)) get_my_public_value;
+ this->public.dh.get_dh_group = (diffie_hellman_group_t (*)(diffie_hellman_t *)) get_dh_group;
+ this->public.dh.destroy = (void (*)(diffie_hellman_t *)) destroy;
+
+ switch (group)
+ {
+ case ECP_192_BIT:
+ this->key = EC_KEY_new_by_curve_name(NID_X9_62_prime192v1);
+ break;
+ case ECP_224_BIT:
+ this->key = EC_KEY_new_by_curve_name(NID_secp224r1);
+ break;
+ case ECP_256_BIT:
+ this->key = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1);
+ break;
+ case ECP_384_BIT:
+ this->key = EC_KEY_new_by_curve_name(NID_secp384r1);
+ break;
+ case ECP_521_BIT:
+ this->key = EC_KEY_new_by_curve_name(NID_secp521r1);
+ break;
+ default:
+ this->key = NULL;
+ break;
+ }
+
+ if (!this->key)
+ {
+ free(this);
+ return NULL;
+ }
+
+ /* caching the EC group */
+ this->ec_group = EC_KEY_get0_group(this->key);
+
+ this->pub_key = EC_POINT_new(this->ec_group);
+ if (!this->pub_key)
+ {
+ free(this);
+ return NULL;
+ }
+
+ /* generate an EC private (public) key */
+ if (!EC_KEY_generate_key(this->key))
+ {
+ free(this);
+ return NULL;
+ }
+
+ this->group = group;
+ this->computed = FALSE;
+
+ this->shared_secret = chunk_empty;
+
+ return &this->public;
+}
diff --git a/src/libstrongswan/plugins/openssl/openssl_ec_diffie_hellman.h b/src/libstrongswan/plugins/openssl/openssl_ec_diffie_hellman.h
new file mode 100644
index 000000000..e89f1cbd7
--- /dev/null
+++ b/src/libstrongswan/plugins/openssl/openssl_ec_diffie_hellman.h
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2008 Tobias Brunner
+ * 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.
+ *
+ * $Id: openssl_ec_diffie_hellman.h 4000 2008-05-22 12:13:10Z tobias $
+ */
+
+/**
+ * @defgroup openssl_ec_diffie_hellman openssl_ec_diffie_hellman
+ * @{ @ingroup openssl_p
+ */
+
+#ifndef OPENSSL_EC_DIFFIE_HELLMAN_H_
+#define OPENSSL_EC_DIFFIE_HELLMAN_H_
+
+typedef struct openssl_ec_diffie_hellman_t openssl_ec_diffie_hellman_t;
+
+#include <library.h>
+
+/**
+ * Implementation of the EC Diffie-Hellman algorithm using OpenSSL.
+ */
+struct openssl_ec_diffie_hellman_t {
+
+ /**
+ * Implements diffie_hellman_t interface.
+ */
+ diffie_hellman_t dh;
+};
+
+/**
+ * Creates a new openssl_ec_diffie_hellman_t object.
+ *
+ * @param group EC Diffie Hellman group number to use
+ * @return openssl_ec_diffie_hellman_t object, NULL if not supported
+ */
+openssl_ec_diffie_hellman_t *openssl_ec_diffie_hellman_create(diffie_hellman_group_t group);
+
+#endif /*OPENSSL_EC_DIFFIE_HELLMAN_H_ @}*/
+
diff --git a/src/libstrongswan/plugins/openssl/openssl_ec_private_key.c b/src/libstrongswan/plugins/openssl/openssl_ec_private_key.c
new file mode 100644
index 000000000..9f7df4bca
--- /dev/null
+++ b/src/libstrongswan/plugins/openssl/openssl_ec_private_key.c
@@ -0,0 +1,445 @@
+/*
+ * Copyright (C) 2008 Tobias Brunner
+ * 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.
+ *
+ * $Id: openssl_ec_private_key.c 4051 2008-06-10 09:08:27Z tobias $
+ */
+
+#include "openssl_ec_private_key.h"
+#include "openssl_ec_public_key.h"
+#include "openssl_util.h"
+
+#include <debug.h>
+
+#include <openssl/evp.h>
+#include <openssl/ecdsa.h>
+
+typedef struct private_openssl_ec_private_key_t private_openssl_ec_private_key_t;
+
+/**
+ * Private data of a openssl_ec_private_key_t object.
+ */
+struct private_openssl_ec_private_key_t {
+ /**
+ * Public interface for this signer.
+ */
+ openssl_ec_private_key_t public;
+
+ /**
+ * EC key object
+ */
+ EC_KEY *ec;
+
+ /**
+ * Keyid formed as a SHA-1 hash of a privateKey object
+ */
+ identification_t* keyid;
+
+ /**
+ * Keyid formed as a SHA-1 hash of a privateKeyInfo object
+ */
+ identification_t* keyid_info;
+
+ /**
+ * reference count
+ */
+ refcount_t ref;
+};
+
+/**
+ * Mapping from the signature scheme defined in (RFC 4754) to the elliptic
+ * curve and the hash algorithm
+ */
+typedef struct {
+ /**
+ * Scheme specified in RFC 4754
+ */
+ int scheme;
+
+ /**
+ * NID of the hash
+ */
+ int hash;
+
+ /**
+ * NID of the curve
+ */
+ int curve;
+} openssl_ecdsa_scheme_t;
+
+#define END_OF_LIST -1
+
+/**
+ * Signature schemes
+ */
+static openssl_ecdsa_scheme_t ecdsa_schemes[] = {
+ {SIGN_ECDSA_256, NID_sha256, NID_X9_62_prime256v1},
+ {SIGN_ECDSA_384, NID_sha384, NID_secp384r1},
+ {SIGN_ECDSA_521, NID_sha512, NID_secp521r1},
+ {END_OF_LIST, 0, 0},
+};
+
+/**
+ * Look up the hash and curve of a signature scheme
+ */
+static bool lookup_scheme(int scheme, int *hash, int *curve)
+{
+ openssl_ecdsa_scheme_t *ecdsa_scheme = ecdsa_schemes;
+ while (ecdsa_scheme->scheme != END_OF_LIST)
+ {
+ if (scheme == ecdsa_scheme->scheme)
+ {
+ *hash = ecdsa_scheme->hash;
+ *curve = ecdsa_scheme->curve;
+ return TRUE;
+ }
+ ecdsa_scheme++;
+ }
+ return FALSE;
+}
+
+/**
+ * shared functions, implemented in openssl_ec_public_key.c
+ */
+bool openssl_ec_public_key_build_id(EC_KEY *ec, identification_t **keyid,
+ identification_t **keyid_info);
+
+openssl_ec_public_key_t *openssl_ec_public_key_create_from_private_key(EC_KEY *ec);
+
+
+/**
+ * Convert an ECDSA_SIG to a chunk by concatenating r and s.
+ * This function allocates memory for the chunk.
+ */
+static bool sig2chunk(const EC_GROUP *group, ECDSA_SIG *sig, chunk_t *chunk)
+{
+ return openssl_bn_cat(EC_FIELD_ELEMENT_LEN(group), sig->r, sig->s, chunk);
+}
+
+/**
+ * Build the signature
+ */
+static bool build_signature(private_openssl_ec_private_key_t *this,
+ int hash_type, chunk_t data, chunk_t *signature)
+{
+ chunk_t hash = chunk_empty;
+ ECDSA_SIG *sig;
+ bool ret = FALSE;
+
+ if (!openssl_hash_chunk(hash_type, data, &hash))
+ {
+ return FALSE;
+ }
+
+ sig = ECDSA_do_sign(hash.ptr, hash.len, this->ec);
+ if (!sig)
+ {
+ goto error;
+ }
+
+ if (!sig2chunk(EC_KEY_get0_group(this->ec), sig, signature))
+ {
+ goto error;
+ }
+
+ ret = TRUE;
+error:
+ chunk_free(&hash);
+ if (sig)
+ {
+ ECDSA_SIG_free(sig);
+ }
+ return ret;
+}
+
+/**
+ * Implementation of private_key_t.get_type.
+ */
+static key_type_t get_type(private_openssl_ec_private_key_t *this)
+{
+ return KEY_ECDSA;
+}
+
+/**
+ * Implementation of private_key_t.sign.
+ */
+static bool sign(private_openssl_ec_private_key_t *this, signature_scheme_t scheme,
+ chunk_t data, chunk_t *signature)
+{
+ EC_GROUP *req_group;
+ const EC_GROUP *my_group;
+ int hash, curve;
+
+ if (!lookup_scheme(scheme, &hash, &curve))
+ {
+ DBG1("signature scheme %N not supported in EC",
+ signature_scheme_names, scheme);
+ return FALSE;
+ }
+
+ req_group = EC_GROUP_new_by_curve_name(curve);
+ if (!req_group)
+ {
+ DBG1("signature scheme %N not supported in EC (required curve not supported)",
+ signature_scheme_names, scheme);
+ return FALSE;
+ }
+
+ my_group = EC_KEY_get0_group(this->ec);
+ if (EC_GROUP_cmp(my_group, req_group, NULL) != 0)
+ {
+ DBG1("signature scheme %N not supported by private key",
+ signature_scheme_names, scheme);
+ return FALSE;
+ }
+
+ EC_GROUP_free(req_group);
+
+ return build_signature(this, hash, data, signature);
+}
+
+/**
+ * Implementation of private_key_t.destroy.
+ */
+static bool decrypt(private_openssl_ec_private_key_t *this,
+ chunk_t crypto, chunk_t *plain)
+{
+ DBG1("EC private key decryption not implemented");
+ return FALSE;
+}
+
+/**
+ * Implementation of private_key_t.get_keysize.
+ */
+static size_t get_keysize(private_openssl_ec_private_key_t *this)
+{
+ return EC_FIELD_ELEMENT_LEN(EC_KEY_get0_group(this->ec));
+}
+
+/**
+ * Implementation of private_key_t.get_id.
+ */
+static identification_t* get_id(private_openssl_ec_private_key_t *this,
+ id_type_t type)
+{
+ switch (type)
+ {
+ case ID_PUBKEY_INFO_SHA1:
+ return this->keyid_info;
+ case ID_PUBKEY_SHA1:
+ return this->keyid;
+ default:
+ return NULL;
+ }
+}
+
+/**
+ * Implementation of private_key_t.get_public_key.
+ */
+static openssl_ec_public_key_t* get_public_key(private_openssl_ec_private_key_t *this)
+{
+ return openssl_ec_public_key_create_from_private_key(this->ec);
+}
+
+/**
+ * Implementation of private_key_t.belongs_to.
+ */
+static bool belongs_to(private_openssl_ec_private_key_t *this, public_key_t *public)
+{
+ identification_t *keyid;
+
+ if (public->get_type(public) != KEY_ECDSA)
+ {
+ return FALSE;
+ }
+ keyid = public->get_id(public, ID_PUBKEY_SHA1);
+ if (keyid && keyid->equals(keyid, this->keyid))
+ {
+ return TRUE;
+ }
+ keyid = public->get_id(public, ID_PUBKEY_INFO_SHA1);
+ if (keyid && keyid->equals(keyid, this->keyid_info))
+ {
+ return TRUE;
+ }
+ return FALSE;
+}
+
+/**
+ * Implementation of private_key_t.get_encoding.
+ */
+static chunk_t get_encoding(private_openssl_ec_private_key_t *this)
+{
+ chunk_t enc = chunk_alloc(i2d_ECPrivateKey(this->ec, NULL));
+ u_char *p = enc.ptr;
+ i2d_ECPrivateKey(this->ec, &p);
+ return enc;
+}
+
+/**
+ * Implementation of private_key_t.get_ref.
+ */
+static private_openssl_ec_private_key_t* get_ref(private_openssl_ec_private_key_t *this)
+{
+ ref_get(&this->ref);
+ return this;
+
+}
+
+/**
+ * Implementation of private_key_t.destroy.
+ */
+static void destroy(private_openssl_ec_private_key_t *this)
+{
+ if (ref_put(&this->ref))
+ {
+ if (this->ec)
+ {
+ EC_KEY_free(this->ec);
+ }
+ DESTROY_IF(this->keyid);
+ DESTROY_IF(this->keyid_info);
+ free(this);
+ }
+}
+
+/**
+ * Internal generic constructor
+ */
+static private_openssl_ec_private_key_t *openssl_ec_private_key_create_empty(void)
+{
+ private_openssl_ec_private_key_t *this = malloc_thing(private_openssl_ec_private_key_t);
+
+ this->public.interface.get_type = (key_type_t (*)(private_key_t *this))get_type;
+ this->public.interface.sign = (bool (*)(private_key_t *this, signature_scheme_t scheme, chunk_t data, chunk_t *signature))sign;
+ this->public.interface.decrypt = (bool (*)(private_key_t *this, chunk_t crypto, chunk_t *plain))decrypt;
+ this->public.interface.get_keysize = (size_t (*) (private_key_t *this))get_keysize;
+ this->public.interface.get_id = (identification_t* (*) (private_key_t *this,id_type_t))get_id;
+ this->public.interface.get_public_key = (public_key_t* (*)(private_key_t *this))get_public_key;
+ this->public.interface.belongs_to = (bool (*) (private_key_t *this, public_key_t *public))belongs_to;
+ this->public.interface.get_encoding = (chunk_t(*)(private_key_t*))get_encoding;
+ this->public.interface.get_ref = (private_key_t* (*)(private_key_t *this))get_ref;
+ this->public.interface.destroy = (void (*)(private_key_t *this))destroy;
+
+ this->ec = NULL;
+ this->keyid = NULL;
+ this->keyid_info = NULL;
+ this->ref = 1;
+
+ return this;
+}
+
+/**
+ * load private key from an ASN1 encoded blob
+ */
+static openssl_ec_private_key_t *load(chunk_t blob)
+{
+ u_char *p = blob.ptr;
+ private_openssl_ec_private_key_t *this = openssl_ec_private_key_create_empty();
+
+ this->ec = d2i_ECPrivateKey(NULL, (const u_char**)&p, blob.len);
+
+ chunk_clear(&blob);
+
+ if (!this->ec)
+ {
+ destroy(this);
+ return NULL;
+ }
+
+ if (!openssl_ec_public_key_build_id(this->ec, &this->keyid, &this->keyid_info))
+ {
+ destroy(this);
+ return NULL;
+ }
+
+ if (!EC_KEY_check_key(this->ec))
+ {
+ destroy(this);
+ return NULL;
+ }
+
+ return &this->public;
+}
+
+typedef struct private_builder_t private_builder_t;
+/**
+ * Builder implementation for key loading/generation
+ */
+struct private_builder_t {
+ /** implements the builder interface */
+ builder_t public;
+ /** loaded/generated private key */
+ openssl_ec_private_key_t *key;
+};
+
+/**
+ * Implementation of builder_t.build
+ */
+static openssl_ec_private_key_t *build(private_builder_t *this)
+{
+ openssl_ec_private_key_t *key = this->key;
+
+ free(this);
+ return key;
+}
+
+/**
+ * Implementation of builder_t.add
+ */
+static void add(private_builder_t *this, builder_part_t part, ...)
+{
+ va_list args;
+
+ if (this->key)
+ {
+ DBG1("ignoring surplus build part %N", builder_part_names, part);
+ return;
+ }
+
+ switch (part)
+ {
+ case BUILD_BLOB_ASN1_DER:
+ {
+ va_start(args, part);
+ this->key = load(va_arg(args, chunk_t));
+ va_end(args);
+ break;
+ }
+ default:
+ DBG1("ignoring unsupported build part %N", builder_part_names, part);
+ break;
+ }
+}
+
+/**
+ * Builder construction function
+ */
+builder_t *openssl_ec_private_key_builder(key_type_t type)
+{
+ private_builder_t *this;
+
+ if (type != KEY_ECDSA)
+ {
+ return NULL;
+ }
+
+ this = malloc_thing(private_builder_t);
+
+ this->key = NULL;
+ this->public.add = (void(*)(builder_t *this, builder_part_t part, ...))add;
+ this->public.build = (void*(*)(builder_t *this))build;
+
+ return &this->public;
+}
+
diff --git a/src/libstrongswan/plugins/openssl/openssl_ec_private_key.h b/src/libstrongswan/plugins/openssl/openssl_ec_private_key.h
new file mode 100644
index 000000000..629fc9574
--- /dev/null
+++ b/src/libstrongswan/plugins/openssl/openssl_ec_private_key.h
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2008 Tobias Brunner
+ * 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.
+ *
+ * $Id: openssl_ec_private_key.h 4051 2008-06-10 09:08:27Z tobias $
+ */
+
+/**
+ * @defgroup openssl_ec_private_key openssl_ec_private_key
+ * @{ @ingroup openssl_p
+ */
+
+#ifndef OPENSSL_EC_PRIVATE_KEY_H_
+#define OPENSSL_EC_PRIVATE_KEY_H_
+
+#include <credentials/keys/private_key.h>
+
+typedef struct openssl_ec_private_key_t openssl_ec_private_key_t;
+
+/**
+ * private_key_t implementation of ECDSA using OpenSSL.
+ */
+struct openssl_ec_private_key_t {
+
+ /**
+ * Implements private_key_t interface
+ */
+ private_key_t interface;
+};
+
+/**
+ * Create the builder for a private key.
+ *
+ * @param type type of the key, must be KEY_ECDSA
+ * @return builder instance
+ */
+builder_t *openssl_ec_private_key_builder(key_type_t type);
+
+#endif /*OPENSSL_EC_PRIVATE_KEY_H_ @}*/
diff --git a/src/libstrongswan/plugins/openssl/openssl_ec_public_key.c b/src/libstrongswan/plugins/openssl/openssl_ec_public_key.c
new file mode 100644
index 000000000..2056575ba
--- /dev/null
+++ b/src/libstrongswan/plugins/openssl/openssl_ec_public_key.c
@@ -0,0 +1,447 @@
+/*
+ * Copyright (C) 2008 Tobias Brunner
+ * 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.
+ *
+ * $Id: openssl_ec_public_key.c 4051 2008-06-10 09:08:27Z tobias $
+ */
+
+#include "openssl_ec_public_key.h"
+#include "openssl_util.h"
+
+#include <debug.h>
+
+#include <openssl/evp.h>
+#include <openssl/ecdsa.h>
+#include <openssl/x509.h>
+
+typedef struct private_openssl_ec_public_key_t private_openssl_ec_public_key_t;
+
+/**
+ * Private data structure with signing context.
+ */
+struct private_openssl_ec_public_key_t {
+ /**
+ * Public interface for this signer.
+ */
+ openssl_ec_public_key_t public;
+
+ /**
+ * EC key object
+ */
+ EC_KEY *ec;
+
+ /**
+ * Keyid formed as a SHA-1 hash of a publicKeyInfo object
+ */
+ identification_t *keyid_info;
+
+ /**
+ * Keyid formed as a SHA-1 hash of a publicKey object
+ */
+ identification_t *keyid;
+
+ /**
+ * reference counter
+ */
+ refcount_t ref;
+};
+
+/**
+ * Convert a chunk to an ECDSA_SIG (which must already exist). r and s
+ * of the signature have to be concatenated in the chunk.
+ */
+static bool chunk2sig(const EC_GROUP *group, chunk_t chunk, ECDSA_SIG *sig)
+{
+ return openssl_bn_split(chunk, sig->r, sig->s);
+}
+
+/**
+ * Verification of a signature as in RFC 4754
+ */
+static bool verify_signature(private_openssl_ec_public_key_t *this,
+ int hash_type, chunk_t data, chunk_t signature)
+{
+ chunk_t hash = chunk_empty;
+ ECDSA_SIG *sig;
+ bool valid = FALSE;
+
+ if (!openssl_hash_chunk(hash_type, data, &hash))
+ {
+ return FALSE;
+ }
+
+ sig = ECDSA_SIG_new();
+ if (!sig)
+ {
+ goto error;
+ }
+
+ if (!chunk2sig(EC_KEY_get0_group(this->ec), signature, sig))
+ {
+ goto error;
+ }
+
+ valid = (ECDSA_do_verify(hash.ptr, hash.len, sig, this->ec) == 1);
+
+error:
+ if (sig)
+ {
+ ECDSA_SIG_free(sig);
+ }
+ chunk_free(&hash);
+ return valid;
+}
+
+
+/**
+ * Verification of the default signature using SHA-1
+ */
+static bool verify_default_signature(private_openssl_ec_public_key_t *this,
+ chunk_t data, chunk_t signature)
+{
+ bool valid = FALSE;
+ chunk_t hash = chunk_empty;
+ u_char *p;
+ ECDSA_SIG *sig;
+
+ /* remove any preceding 0-bytes from signature */
+ while (signature.len && *(signature.ptr) == 0x00)
+ {
+ signature.len -= 1;
+ signature.ptr++;
+ }
+
+ p = signature.ptr;
+ sig = d2i_ECDSA_SIG(NULL, (const u_char**)&p, signature.len);
+ if (!sig)
+ {
+ return FALSE;
+ }
+
+ if (!openssl_hash_chunk(NID_sha1, data, &hash))
+ {
+ goto error;
+ }
+
+ valid = (ECDSA_do_verify(hash.ptr, hash.len, sig, this->ec) == 1);
+
+error:
+ if (sig)
+ {
+ ECDSA_SIG_free(sig);
+ }
+ chunk_free(&hash);
+ return valid;
+}
+
+/**
+ * Implementation of public_key_t.get_type.
+ */
+static key_type_t get_type(private_openssl_ec_public_key_t *this)
+{
+ return KEY_ECDSA;
+}
+
+/**
+ * Implementation of public_key_t.verify.
+ */
+static bool verify(private_openssl_ec_public_key_t *this, signature_scheme_t scheme,
+ chunk_t data, chunk_t signature)
+{
+ switch (scheme)
+ {
+ case SIGN_ECDSA_WITH_SHA1:
+ return verify_default_signature(this, data, signature);
+ case SIGN_ECDSA_256:
+ return verify_signature(this, NID_sha256, data, signature);
+ case SIGN_ECDSA_384:
+ return verify_signature(this, NID_sha384, data, signature);
+ case SIGN_ECDSA_521:
+ return verify_signature(this, NID_sha512, data, signature);
+ default:
+ DBG1("signature scheme %N not supported in EC",
+ signature_scheme_names, scheme);
+ return FALSE;
+ }
+}
+
+/**
+ * Implementation of public_key_t.get_keysize.
+ */
+static bool encrypt(private_openssl_ec_public_key_t *this, chunk_t crypto, chunk_t *plain)
+{
+ DBG1("EC public key encryption not implemented");
+ return FALSE;
+}
+
+/**
+ * Implementation of public_key_t.get_keysize.
+ */
+static size_t get_keysize(private_openssl_ec_public_key_t *this)
+{
+ return EC_FIELD_ELEMENT_LEN(EC_KEY_get0_group(this->ec));
+}
+
+/**
+ * Implementation of public_key_t.get_id.
+ */
+static identification_t *get_id(private_openssl_ec_public_key_t *this,
+ id_type_t type)
+{
+ switch (type)
+ {
+ case ID_PUBKEY_INFO_SHA1:
+ return this->keyid_info;
+ case ID_PUBKEY_SHA1:
+ return this->keyid;
+ default:
+ return NULL;
+ }
+}
+
+/**
+ * Encodes the public key
+ */
+static chunk_t get_encoding_raw(EC_KEY *ec)
+{
+ /* since the points can be stored in three different forms this may not
+ * be correct for all cases */
+ const EC_GROUP *group = EC_KEY_get0_group(ec);
+ const EC_POINT *pub = EC_KEY_get0_public_key(ec);
+ chunk_t enc = chunk_alloc(EC_POINT_point2oct(group, pub,
+ POINT_CONVERSION_UNCOMPRESSED, NULL, 0, NULL));
+ EC_POINT_point2oct(group, pub, POINT_CONVERSION_UNCOMPRESSED,
+ enc.ptr, enc.len, NULL);
+ return enc;
+}
+
+/**
+ * Encodes the public key info (public key with ec parameters)
+ */
+static chunk_t get_encoding_full(EC_KEY *ec)
+{
+ chunk_t enc = chunk_alloc(i2d_EC_PUBKEY(ec, NULL));
+ u_char *p = enc.ptr;
+ i2d_EC_PUBKEY(ec, &p);
+ return enc;
+}
+
+/*
+ * Implementation of public_key_t.get_encoding.
+ */
+static chunk_t get_encoding(private_openssl_ec_public_key_t *this)
+{
+ return get_encoding_full(this->ec);
+}
+
+/**
+ * Implementation of public_key_t.get_ref.
+ */
+static private_openssl_ec_public_key_t* get_ref(private_openssl_ec_public_key_t *this)
+{
+ ref_get(&this->ref);
+ return this;
+}
+
+/**
+ * Implementation of openssl_ec_public_key.destroy.
+ */
+static void destroy(private_openssl_ec_public_key_t *this)
+{
+ if (ref_put(&this->ref))
+ {
+ if (this->ec)
+ {
+ EC_KEY_free(this->ec);
+ }
+ DESTROY_IF(this->keyid);
+ DESTROY_IF(this->keyid_info);
+ free(this);
+ }
+}
+
+/**
+ * Generic private constructor
+ */
+static private_openssl_ec_public_key_t *openssl_ec_public_key_create_empty()
+{
+ private_openssl_ec_public_key_t *this = malloc_thing(private_openssl_ec_public_key_t);
+
+ this->public.interface.get_type = (key_type_t (*)(public_key_t *this))get_type;
+ this->public.interface.verify = (bool (*)(public_key_t *this, signature_scheme_t scheme, chunk_t data, chunk_t signature))verify;
+ this->public.interface.encrypt = (bool (*)(public_key_t *this, chunk_t crypto, chunk_t *plain))encrypt;
+ this->public.interface.get_keysize = (size_t (*) (public_key_t *this))get_keysize;
+ this->public.interface.get_id = (identification_t* (*) (public_key_t *this,id_type_t))get_id;
+ this->public.interface.get_encoding = (chunk_t(*)(public_key_t*))get_encoding;
+ this->public.interface.get_ref = (public_key_t* (*)(public_key_t *this))get_ref;
+ this->public.interface.destroy = (void (*)(public_key_t *this))destroy;
+
+ this->ec = NULL;
+ this->keyid = NULL;
+ this->keyid_info = NULL;
+ this->ref = 1;
+
+ return this;
+}
+
+/**
+ * Build key identifier from the public key using SHA1 hashed publicKey(Info).
+ * Also used in openssl_ec_private_key.c.
+ */
+bool openssl_ec_public_key_build_id(EC_KEY *ec, identification_t **keyid,
+ identification_t **keyid_info)
+{
+ chunk_t publicKeyInfo, publicKey, hash;
+ hasher_t *hasher;
+
+ hasher = lib->crypto->create_hasher(lib->crypto, HASH_SHA1);
+ if (hasher == NULL)
+ {
+ DBG1("SHA1 hash algorithm not supported, unable to use EC");
+ return FALSE;
+ }
+
+ publicKey = get_encoding_raw(ec);
+
+ hasher->allocate_hash(hasher, publicKey, &hash);
+ *keyid = identification_create_from_encoding(ID_PUBKEY_SHA1, hash);
+ chunk_free(&hash);
+
+ publicKeyInfo = get_encoding_full(ec);
+
+ hasher->allocate_hash(hasher, publicKeyInfo, &hash);
+ *keyid_info = identification_create_from_encoding(ID_PUBKEY_INFO_SHA1, hash);
+ chunk_free(&hash);
+
+ hasher->destroy(hasher);
+ chunk_free(&publicKeyInfo);
+ chunk_free(&publicKey);
+
+ return TRUE;
+}
+
+/**
+ * Create a public key from BIGNUM values, used in openssl_ec_private_key.c
+ */
+openssl_ec_public_key_t *openssl_ec_public_key_create_from_private_key(EC_KEY *ec)
+{
+ private_openssl_ec_public_key_t *this = openssl_ec_public_key_create_empty();
+
+ this->ec = EC_KEY_new();
+ EC_KEY_set_public_key(this->ec, EC_KEY_get0_public_key(ec));
+
+ if (!openssl_ec_public_key_build_id(this->ec, &this->keyid, &this->keyid_info))
+ {
+ destroy(this);
+ return NULL;
+ }
+ return &this->public;
+}
+
+/**
+ * Load a public key from an ASN1 encoded blob
+ */
+static openssl_ec_public_key_t *load(chunk_t blob)
+{
+ u_char *p = blob.ptr;
+ private_openssl_ec_public_key_t *this = openssl_ec_public_key_create_empty();
+
+ this->ec = d2i_EC_PUBKEY(NULL, (const u_char**)&p, blob.len);
+
+ chunk_clear(&blob);
+
+ if (!this->ec)
+ {
+ destroy(this);
+ return NULL;
+ }
+
+ if (!openssl_ec_public_key_build_id(this->ec, &this->keyid, &this->keyid_info))
+ {
+ destroy(this);
+ return NULL;
+ }
+ return &this->public;
+}
+
+typedef struct private_builder_t private_builder_t;
+/**
+ * Builder implementation for key loading
+ */
+struct private_builder_t {
+ /** implements the builder interface */
+ builder_t public;
+ /** loaded public key */
+ openssl_ec_public_key_t *key;
+};
+
+/**
+ * Implementation of builder_t.build
+ */
+static openssl_ec_public_key_t *build(private_builder_t *this)
+{
+ openssl_ec_public_key_t *key = this->key;
+
+ free(this);
+ return key;
+}
+
+/**
+ * Implementation of builder_t.add
+ */
+static void add(private_builder_t *this, builder_part_t part, ...)
+{
+ va_list args;
+
+ if (this->key)
+ {
+ DBG1("ignoring surplus build part %N", builder_part_names, part);
+ return;
+ }
+
+ switch (part)
+ {
+ case BUILD_BLOB_ASN1_DER:
+ {
+ va_start(args, part);
+ this->key = load(va_arg(args, chunk_t));
+ va_end(args);
+ break;
+ }
+ default:
+ DBG1("ignoring unsupported build part %N", builder_part_names, part);
+ break;
+ }
+}
+
+/**
+ * Builder construction function
+ */
+builder_t *openssl_ec_public_key_builder(key_type_t type)
+{
+ private_builder_t *this;
+
+ if (type != KEY_ECDSA)
+ {
+ return NULL;
+ }
+
+ this = malloc_thing(private_builder_t);
+
+ this->key = NULL;
+ this->public.add = (void(*)(builder_t *this, builder_part_t part, ...))add;
+ this->public.build = (void*(*)(builder_t *this))build;
+
+ return &this->public;
+}
+
diff --git a/src/libstrongswan/plugins/openssl/openssl_ec_public_key.h b/src/libstrongswan/plugins/openssl/openssl_ec_public_key.h
new file mode 100644
index 000000000..92684402c
--- /dev/null
+++ b/src/libstrongswan/plugins/openssl/openssl_ec_public_key.h
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2008 Tobias Brunner
+ * 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.
+ *
+ * $Id: openssl_ec_public_key.h 4051 2008-06-10 09:08:27Z tobias $
+ */
+
+/**
+ * @defgroup openssl_ec_public_key openssl_ec_public_key
+ * @{ @ingroup openssl_p
+ */
+
+#ifndef OPENSSL_EC_PUBLIC_KEY_H_
+#define OPENSSL_EC_PUBLIC_KEY_H_
+
+typedef struct openssl_ec_public_key_t openssl_ec_public_key_t;
+
+#include <credentials/keys/public_key.h>
+
+/**
+ * public_key_t implementation of ECDSA using OpenSSL.
+ */
+struct openssl_ec_public_key_t {
+
+ /**
+ * Implements the public_key_t interface
+ */
+ public_key_t interface;
+};
+
+/**
+ * Create the builder for a public key.
+ *
+ * @param type type of the key, must be KEY_ECDSA
+ * @return builder instance
+ */
+builder_t *openssl_ec_public_key_builder(key_type_t type);
+
+#endif /*OPENSSL_EC_PUBLIC_KEY_H_ @}*/
diff --git a/src/libstrongswan/plugins/openssl/openssl_hasher.c b/src/libstrongswan/plugins/openssl/openssl_hasher.c
new file mode 100644
index 000000000..1275cdfb0
--- /dev/null
+++ b/src/libstrongswan/plugins/openssl/openssl_hasher.c
@@ -0,0 +1,185 @@
+/*
+ * Copyright (C) 2008 Tobias Brunner
+ * 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.
+ *
+ * $Id: openssl_hasher.c 3898 2008-04-30 09:23:13Z tobias $
+ */
+
+#include "openssl_hasher.h"
+
+#include <openssl/evp.h>
+
+typedef struct private_openssl_hasher_t private_openssl_hasher_t;
+
+/**
+ * Private data of openssl_hasher_t
+ */
+struct private_openssl_hasher_t {
+
+ /**
+ * Public part of this class.
+ */
+ openssl_hasher_t public;
+
+ /**
+ * the hasher to use
+ */
+ const EVP_MD *hasher;
+
+ /**
+ * the current digest context
+ */
+ EVP_MD_CTX *ctx;
+};
+
+/**
+ * Mapping from the algorithms defined in IKEv2 to
+ * OpenSSL algorithm names
+ */
+typedef struct {
+ /**
+ * Identifier specified in IKEv2
+ */
+ int ikev2_id;
+
+ /**
+ * Name of the algorithm, as used in OpenSSL
+ */
+ char *name;
+} openssl_algorithm_t;
+
+#define END_OF_LIST -1
+
+/**
+ * Algorithms for integrity
+ */
+static openssl_algorithm_t integrity_algs[] = {
+ {HASH_MD2, "md2"},
+ {HASH_MD5, "md5"},
+ {HASH_SHA1, "sha1"},
+ {HASH_SHA256, "sha256"},
+ {HASH_SHA384, "sha384"},
+ {HASH_SHA512, "sha512"},
+ {END_OF_LIST, NULL},
+};
+
+/**
+ * Look up an OpenSSL algorithm name
+ */
+static char* lookup_algorithm(openssl_algorithm_t *openssl_algo,
+ u_int16_t ikev2_algo)
+{
+ while (openssl_algo->ikev2_id != END_OF_LIST)
+ {
+ if (ikev2_algo == openssl_algo->ikev2_id)
+ {
+ return openssl_algo->name;
+ }
+ openssl_algo++;
+ }
+ return NULL;
+}
+
+/**
+ * Implementation of hasher_t.get_hash_size.
+ */
+static size_t get_hash_size(private_openssl_hasher_t *this)
+{
+ return this->hasher->md_size;
+}
+
+/**
+ * Implementation of hasher_t.reset.
+ */
+static void reset(private_openssl_hasher_t *this)
+{
+ EVP_DigestInit_ex(this->ctx, this->hasher, NULL);
+}
+
+/**
+ * Implementation of hasher_t.get_hash.
+ */
+static void get_hash(private_openssl_hasher_t *this, chunk_t chunk,
+ u_int8_t *hash)
+{
+ EVP_DigestUpdate(this->ctx, chunk.ptr, chunk.len);
+ if (hash)
+ {
+ EVP_DigestFinal_ex(this->ctx, hash, NULL);
+ reset(this);
+ }
+}
+
+/**
+ * Implementation of hasher_t.allocate_hash.
+ */
+static void allocate_hash(private_openssl_hasher_t *this, chunk_t chunk,
+ chunk_t *hash)
+{
+ if (hash)
+ {
+ *hash = chunk_alloc(get_hash_size(this));
+ get_hash(this, chunk, hash->ptr);
+ }
+ else
+ {
+ get_hash(this, chunk, NULL);
+ }
+}
+
+/**
+ * Implementation of hasher_t.destroy.
+ */
+static void destroy (private_openssl_hasher_t *this)
+{
+ EVP_MD_CTX_destroy(this->ctx);
+ free(this);
+}
+
+/*
+ * Described in header
+ */
+openssl_hasher_t *openssl_hasher_create(hash_algorithm_t algo)
+{
+ private_openssl_hasher_t *this;
+
+ char* name = lookup_algorithm(integrity_algs, algo);
+ if (!name)
+ {
+ /* algo unavailable */
+ return NULL;
+ }
+
+ this = malloc_thing(private_openssl_hasher_t);
+
+ this->hasher = EVP_get_digestbyname(name);
+ if (!this->hasher)
+ {
+ /* OpenSSL does not support the requested algo */
+ free(this);
+ return NULL;
+ }
+
+ this->public.hasher_interface.get_hash = (void (*) (hasher_t*, chunk_t, u_int8_t*))get_hash;
+ this->public.hasher_interface.allocate_hash = (void (*) (hasher_t*, chunk_t, chunk_t*))allocate_hash;
+ this->public.hasher_interface.get_hash_size = (size_t (*) (hasher_t*))get_hash_size;
+ this->public.hasher_interface.reset = (void (*) (hasher_t*))reset;
+ this->public.hasher_interface.destroy = (void (*) (hasher_t*))destroy;
+
+ this->ctx = EVP_MD_CTX_create();
+
+ /* initialization */
+ reset(this);
+
+ return &this->public;
+}
diff --git a/src/libstrongswan/plugins/openssl/openssl_hasher.h b/src/libstrongswan/plugins/openssl/openssl_hasher.h
new file mode 100644
index 000000000..f776e9fd4
--- /dev/null
+++ b/src/libstrongswan/plugins/openssl/openssl_hasher.h
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2008 Tobias Brunner
+ * 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.
+ *
+ * $Id: openssl_hasher.h 4000 2008-05-22 12:13:10Z tobias $
+ */
+
+/**
+ * @defgroup openssl_hasher openssl_hasher
+ * @{ @ingroup openssl_p
+ */
+
+#ifndef OPENSSL_HASHER_H_
+#define OPENSSL_HASHER_H_
+
+typedef struct openssl_hasher_t openssl_hasher_t;
+
+#include <crypto/hashers/hasher.h>
+
+/**
+ * Implementation of hashers using OpenSSL.
+ */
+struct openssl_hasher_t {
+
+ /**
+ * The hasher_t interface.
+ */
+ hasher_t hasher_interface;
+};
+
+/**
+ * Constructor to create openssl_hasher_t.
+ *
+ * @param algo algorithm
+ * @param key_size key size in bytes
+ * @return openssl_hasher_t, NULL if not supported
+ */
+openssl_hasher_t *openssl_hasher_create(hash_algorithm_t algo);
+
+#endif /* OPENSSL_HASHER_H_ @}*/
diff --git a/src/libstrongswan/plugins/openssl/openssl_plugin.c b/src/libstrongswan/plugins/openssl/openssl_plugin.c
new file mode 100644
index 000000000..7fdd7c224
--- /dev/null
+++ b/src/libstrongswan/plugins/openssl/openssl_plugin.c
@@ -0,0 +1,164 @@
+/*
+ * Copyright (C) 2008 Tobias Brunner
+ * 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.
+ *
+ * $Id: openssl_plugin.c 4107 2008-06-25 12:39:32Z tobias $
+ */
+
+#include <openssl/evp.h>
+#include <openssl/engine.h>
+
+#include "openssl_plugin.h"
+
+#include <library.h>
+#include "openssl_crypter.h"
+#include "openssl_hasher.h"
+#include "openssl_diffie_hellman.h"
+#include "openssl_ec_diffie_hellman.h"
+#include "openssl_rsa_private_key.h"
+#include "openssl_rsa_public_key.h"
+#include "openssl_ec_private_key.h"
+#include "openssl_ec_public_key.h"
+
+typedef struct private_openssl_plugin_t private_openssl_plugin_t;
+
+/**
+ * private data of openssl_plugin
+ */
+struct private_openssl_plugin_t {
+
+ /**
+ * public functions
+ */
+ openssl_plugin_t public;
+};
+
+/**
+ * Implementation of openssl_plugin_t.destroy
+ */
+static void destroy(private_openssl_plugin_t *this)
+{
+ lib->crypto->remove_crypter(lib->crypto,
+ (crypter_constructor_t)openssl_crypter_create);
+ lib->crypto->remove_hasher(lib->crypto,
+ (hasher_constructor_t)openssl_hasher_create);
+ lib->crypto->remove_dh(lib->crypto,
+ (dh_constructor_t)openssl_diffie_hellman_create);
+ lib->crypto->remove_dh(lib->crypto,
+ (dh_constructor_t)openssl_ec_diffie_hellman_create);
+ lib->creds->remove_builder(lib->creds,
+ (builder_constructor_t)openssl_rsa_private_key_builder);
+ lib->creds->remove_builder(lib->creds,
+ (builder_constructor_t)openssl_rsa_public_key_builder);
+ lib->creds->remove_builder(lib->creds,
+ (builder_constructor_t)openssl_ec_private_key_builder);
+ lib->creds->remove_builder(lib->creds,
+ (builder_constructor_t)openssl_ec_public_key_builder);
+
+ ENGINE_cleanup();
+ EVP_cleanup();
+
+ free(this);
+}
+
+/*
+ * see header file
+ */
+plugin_t *plugin_create()
+{
+ private_openssl_plugin_t *this = malloc_thing(private_openssl_plugin_t);
+
+ this->public.plugin.destroy = (void(*)(plugin_t*))destroy;
+
+ OpenSSL_add_all_algorithms();
+
+ /* activate support for hardware accelerators */
+ ENGINE_load_builtin_engines();
+ ENGINE_register_all_complete();
+
+ /* crypter */
+ lib->crypto->add_crypter(lib->crypto, ENCR_DES,
+ (crypter_constructor_t)openssl_crypter_create);
+ lib->crypto->add_crypter(lib->crypto, ENCR_3DES,
+ (crypter_constructor_t)openssl_crypter_create);
+ lib->crypto->add_crypter(lib->crypto, ENCR_RC5,
+ (crypter_constructor_t)openssl_crypter_create);
+ lib->crypto->add_crypter(lib->crypto, ENCR_IDEA,
+ (crypter_constructor_t)openssl_crypter_create);
+ lib->crypto->add_crypter(lib->crypto, ENCR_CAST,
+ (crypter_constructor_t)openssl_crypter_create);
+ lib->crypto->add_crypter(lib->crypto, ENCR_BLOWFISH,
+ (crypter_constructor_t)openssl_crypter_create);
+ lib->crypto->add_crypter(lib->crypto, ENCR_NULL,
+ (crypter_constructor_t)openssl_crypter_create);
+ lib->crypto->add_crypter(lib->crypto, ENCR_AES_CBC,
+ (crypter_constructor_t)openssl_crypter_create);
+
+ /* hasher */
+ lib->crypto->add_hasher(lib->crypto, HASH_SHA1,
+ (hasher_constructor_t)openssl_hasher_create);
+ lib->crypto->add_hasher(lib->crypto, HASH_MD2,
+ (hasher_constructor_t)openssl_hasher_create);
+ lib->crypto->add_hasher(lib->crypto, HASH_MD5,
+ (hasher_constructor_t)openssl_hasher_create);
+ lib->crypto->add_hasher(lib->crypto, HASH_SHA256,
+ (hasher_constructor_t)openssl_hasher_create);
+ lib->crypto->add_hasher(lib->crypto, HASH_SHA384,
+ (hasher_constructor_t)openssl_hasher_create);
+ lib->crypto->add_hasher(lib->crypto, HASH_SHA512,
+ (hasher_constructor_t)openssl_hasher_create);
+
+ /* diffie hellman */
+ lib->crypto->add_dh(lib->crypto, MODP_768_BIT,
+ (dh_constructor_t)openssl_diffie_hellman_create);
+ lib->crypto->add_dh(lib->crypto, MODP_1024_BIT,
+ (dh_constructor_t)openssl_diffie_hellman_create);
+ lib->crypto->add_dh(lib->crypto, MODP_1536_BIT,
+ (dh_constructor_t)openssl_diffie_hellman_create);
+ lib->crypto->add_dh(lib->crypto, MODP_2048_BIT,
+ (dh_constructor_t)openssl_diffie_hellman_create);
+ lib->crypto->add_dh(lib->crypto, MODP_3072_BIT,
+ (dh_constructor_t)openssl_diffie_hellman_create);
+ lib->crypto->add_dh(lib->crypto, MODP_4096_BIT,
+ (dh_constructor_t)openssl_diffie_hellman_create);
+ lib->crypto->add_dh(lib->crypto, MODP_6144_BIT,
+ (dh_constructor_t)openssl_diffie_hellman_create);
+ lib->crypto->add_dh(lib->crypto, MODP_8192_BIT,
+ (dh_constructor_t)openssl_diffie_hellman_create);
+
+ /* ec diffie hellman */
+ lib->crypto->add_dh(lib->crypto, ECP_192_BIT,
+ (dh_constructor_t)openssl_ec_diffie_hellman_create);
+ lib->crypto->add_dh(lib->crypto, ECP_224_BIT,
+ (dh_constructor_t)openssl_ec_diffie_hellman_create);
+ lib->crypto->add_dh(lib->crypto, ECP_256_BIT,
+ (dh_constructor_t)openssl_ec_diffie_hellman_create);
+ lib->crypto->add_dh(lib->crypto, ECP_384_BIT,
+ (dh_constructor_t)openssl_ec_diffie_hellman_create);
+ lib->crypto->add_dh(lib->crypto, ECP_521_BIT,
+ (dh_constructor_t)openssl_ec_diffie_hellman_create);
+
+ /* rsa */
+ lib->creds->add_builder(lib->creds, CRED_PRIVATE_KEY, KEY_RSA,
+ (builder_constructor_t)openssl_rsa_private_key_builder);
+ lib->creds->add_builder(lib->creds, CRED_PUBLIC_KEY, KEY_RSA,
+ (builder_constructor_t)openssl_rsa_public_key_builder);
+
+ /* ec */
+ lib->creds->add_builder(lib->creds, CRED_PRIVATE_KEY, KEY_ECDSA,
+ (builder_constructor_t)openssl_ec_private_key_builder);
+ lib->creds->add_builder(lib->creds, CRED_PUBLIC_KEY, KEY_ECDSA,
+ (builder_constructor_t)openssl_ec_public_key_builder);
+
+ return &this->public.plugin;
+}
diff --git a/src/libstrongswan/plugins/openssl/openssl_plugin.h b/src/libstrongswan/plugins/openssl/openssl_plugin.h
new file mode 100644
index 000000000..40f741dfa
--- /dev/null
+++ b/src/libstrongswan/plugins/openssl/openssl_plugin.h
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2008 Tobias Brunner
+ * 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.
+ *
+ * $Id: openssl_plugin.h 4000 2008-05-22 12:13:10Z tobias $
+ */
+
+/**
+ * @defgroup openssl_p openssl
+ * @ingroup plugins
+ *
+ * @defgroup openssl_plugin openssl_plugin
+ * @{ @ingroup openssl_p
+ */
+
+#ifndef OPENSSL_PLUGIN_H_
+#define OPENSSL_PLUGIN_H_
+
+#include <plugins/plugin.h>
+
+typedef struct openssl_plugin_t openssl_plugin_t;
+
+/**
+ * Plugin implementing crypto functions via the OpenSSL library
+ */
+struct openssl_plugin_t {
+
+ /**
+ * implements plugin interface
+ */
+ plugin_t plugin;
+};
+
+/**
+ * Create a openssl_plugin instance.
+ */
+plugin_t *plugin_create();
+
+#endif /* OPENSSL_PLUGIN_H_ @}*/
diff --git a/src/libstrongswan/plugins/openssl/openssl_rsa_private_key.c b/src/libstrongswan/plugins/openssl/openssl_rsa_private_key.c
new file mode 100644
index 000000000..7595eed3a
--- /dev/null
+++ b/src/libstrongswan/plugins/openssl/openssl_rsa_private_key.c
@@ -0,0 +1,422 @@
+/*
+ * Copyright (C) 2008 Tobias Brunner
+ * 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.
+ *
+ * $Id: openssl_rsa_private_key.c 3963 2008-05-15 12:41:06Z tobias $
+ */
+
+#include "openssl_rsa_private_key.h"
+#include "openssl_rsa_public_key.h"
+
+#include <debug.h>
+
+#include <openssl/evp.h>
+#include <openssl/rsa.h>
+
+/**
+ * Public exponent to use for key generation.
+ */
+#define PUBLIC_EXPONENT 0x10001
+
+typedef struct private_openssl_rsa_private_key_t private_openssl_rsa_private_key_t;
+
+/**
+ * Private data of a openssl_rsa_private_key_t object.
+ */
+struct private_openssl_rsa_private_key_t {
+ /**
+ * Public interface for this signer.
+ */
+ openssl_rsa_private_key_t public;
+
+ /**
+ * RSA object from OpenSSL
+ */
+ RSA *rsa;
+
+ /**
+ * Keyid formed as a SHA-1 hash of a privateKey object
+ */
+ identification_t* keyid;
+
+ /**
+ * Keyid formed as a SHA-1 hash of a privateKeyInfo object
+ */
+ identification_t* keyid_info;
+
+ /**
+ * reference count
+ */
+ refcount_t ref;
+};
+
+/**
+ * shared functions, implemented in openssl_rsa_public_key.c
+ */
+bool openssl_rsa_public_key_build_id(RSA *rsa, identification_t **keyid,
+ identification_t **keyid_info);
+
+
+openssl_rsa_public_key_t *openssl_rsa_public_key_create_from_n_e(BIGNUM *n, BIGNUM *e);
+
+
+/**
+ * Build an EMPSA PKCS1 signature described in PKCS#1
+ */
+static bool build_emsa_pkcs1_signature(private_openssl_rsa_private_key_t *this,
+ int type, chunk_t data, chunk_t *signature)
+{
+ bool success = FALSE;
+ const EVP_MD *hasher = EVP_get_digestbynid(type);
+ if (!hasher)
+ {
+ return FALSE;
+ }
+
+ EVP_MD_CTX *ctx = EVP_MD_CTX_create();
+ EVP_PKEY *key = EVP_PKEY_new();
+ if (!ctx || !key)
+ {
+ goto error;
+ }
+
+ if (!EVP_PKEY_set1_RSA(key, this->rsa))
+ {
+ goto error;
+ }
+
+ if (!EVP_SignInit_ex(ctx, hasher, NULL))
+ {
+ goto error;
+ }
+
+ if (!EVP_SignUpdate(ctx, data.ptr, data.len))
+ {
+ goto error;
+ }
+
+ *signature = chunk_alloc(RSA_size(this->rsa));
+
+ if (!EVP_SignFinal(ctx, signature->ptr, &signature->len, key))
+ {
+ goto error;
+ }
+
+ success = TRUE;
+
+error:
+ if (key)
+ {
+ EVP_PKEY_free(key);
+ }
+ if (ctx)
+ {
+ EVP_MD_CTX_destroy(ctx);
+ }
+ return success;
+}
+
+/**
+ * Implementation of openssl_rsa_private_key.destroy.
+ */
+static key_type_t get_type(private_openssl_rsa_private_key_t *this)
+{
+ return KEY_RSA;
+}
+
+/**
+ * Implementation of openssl_rsa_private_key.destroy.
+ */
+static bool sign(private_openssl_rsa_private_key_t *this, signature_scheme_t scheme,
+ chunk_t data, chunk_t *signature)
+{
+ switch (scheme)
+ {
+ case SIGN_DEFAULT:
+ /* default is EMSA-PKCS1 using SHA1 */
+ case SIGN_RSA_EMSA_PKCS1_SHA1:
+ return build_emsa_pkcs1_signature(this, NID_sha1, data, signature);
+ case SIGN_RSA_EMSA_PKCS1_SHA256:
+ return build_emsa_pkcs1_signature(this, NID_sha256, data, signature);
+ case SIGN_RSA_EMSA_PKCS1_SHA384:
+ return build_emsa_pkcs1_signature(this, NID_sha384, data, signature);
+ case SIGN_RSA_EMSA_PKCS1_SHA512:
+ return build_emsa_pkcs1_signature(this, NID_sha512, data, signature);
+ case SIGN_RSA_EMSA_PKCS1_MD5:
+ return build_emsa_pkcs1_signature(this, NID_md5, data, signature);
+ default:
+ DBG1("signature scheme %N not supported in RSA",
+ signature_scheme_names, scheme);
+ return FALSE;
+ }
+}
+
+/**
+ * Implementation of openssl_rsa_private_key.destroy.
+ */
+static bool decrypt(private_openssl_rsa_private_key_t *this,
+ chunk_t crypto, chunk_t *plain)
+{
+ DBG1("RSA private key decryption not implemented");
+ return FALSE;
+}
+
+/**
+ * Implementation of openssl_rsa_private_key.destroy.
+ */
+static size_t get_keysize(private_openssl_rsa_private_key_t *this)
+{
+ return RSA_size(this->rsa);
+}
+
+/**
+ * Implementation of openssl_rsa_private_key.destroy.
+ */
+static identification_t* get_id(private_openssl_rsa_private_key_t *this,
+ id_type_t type)
+{
+ switch (type)
+ {
+ case ID_PUBKEY_INFO_SHA1:
+ return this->keyid_info;
+ case ID_PUBKEY_SHA1:
+ return this->keyid;
+ default:
+ return NULL;
+ }
+}
+
+/**
+ * Implementation of openssl_rsa_private_key.destroy.
+ */
+static openssl_rsa_public_key_t* get_public_key(private_openssl_rsa_private_key_t *this)
+{
+ return openssl_rsa_public_key_create_from_n_e(this->rsa->n, this->rsa->e);
+}
+
+/**
+ * Implementation of openssl_rsa_private_key.destroy.
+ */
+static bool belongs_to(private_openssl_rsa_private_key_t *this, public_key_t *public)
+{
+ identification_t *keyid;
+
+ if (public->get_type(public) != KEY_RSA)
+ {
+ return FALSE;
+ }
+ keyid = public->get_id(public, ID_PUBKEY_SHA1);
+ if (keyid && keyid->equals(keyid, this->keyid))
+ {
+ return TRUE;
+ }
+ keyid = public->get_id(public, ID_PUBKEY_INFO_SHA1);
+ if (keyid && keyid->equals(keyid, this->keyid_info))
+ {
+ return TRUE;
+ }
+ return FALSE;
+}
+
+/**
+ * Implementation of private_key_t.get_encoding.
+ */
+static chunk_t get_encoding(private_openssl_rsa_private_key_t *this)
+{
+ chunk_t enc = chunk_alloc(i2d_RSAPrivateKey(this->rsa, NULL));
+ u_char *p = enc.ptr;
+ i2d_RSAPrivateKey(this->rsa, &p);
+ return enc;
+}
+
+/**
+ * Implementation of openssl_rsa_private_key.destroy.
+ */
+static private_openssl_rsa_private_key_t* get_ref(private_openssl_rsa_private_key_t *this)
+{
+ ref_get(&this->ref);
+ return this;
+
+}
+
+/**
+ * Implementation of openssl_rsa_private_key.destroy.
+ */
+static void destroy(private_openssl_rsa_private_key_t *this)
+{
+ if (ref_put(&this->ref))
+ {
+ if (this->rsa)
+ {
+ RSA_free(this->rsa);
+ }
+ DESTROY_IF(this->keyid);
+ DESTROY_IF(this->keyid_info);
+ free(this);
+ }
+}
+
+/**
+ * Internal generic constructor
+ */
+static private_openssl_rsa_private_key_t *openssl_rsa_private_key_create_empty(void)
+{
+ private_openssl_rsa_private_key_t *this = malloc_thing(private_openssl_rsa_private_key_t);
+
+ this->public.interface.get_type = (key_type_t (*)(private_key_t *this))get_type;
+ this->public.interface.sign = (bool (*)(private_key_t *this, signature_scheme_t scheme, chunk_t data, chunk_t *signature))sign;
+ this->public.interface.decrypt = (bool (*)(private_key_t *this, chunk_t crypto, chunk_t *plain))decrypt;
+ this->public.interface.get_keysize = (size_t (*) (private_key_t *this))get_keysize;
+ this->public.interface.get_id = (identification_t* (*) (private_key_t *this,id_type_t))get_id;
+ this->public.interface.get_public_key = (public_key_t* (*)(private_key_t *this))get_public_key;
+ this->public.interface.belongs_to = (bool (*) (private_key_t *this, public_key_t *public))belongs_to;
+ this->public.interface.get_encoding = (chunk_t(*)(private_key_t*))get_encoding;
+ this->public.interface.get_ref = (private_key_t* (*)(private_key_t *this))get_ref;
+ this->public.interface.destroy = (void (*)(private_key_t *this))destroy;
+
+ this->keyid = NULL;
+ this->keyid_info = NULL;
+ this->ref = 1;
+
+ return this;
+}
+
+/**
+ * Generate an RSA key of specified key size
+ */
+static openssl_rsa_private_key_t *generate(size_t key_size)
+{
+ private_openssl_rsa_private_key_t *this = openssl_rsa_private_key_create_empty();
+
+ this->rsa = RSA_generate_key(key_size, PUBLIC_EXPONENT, NULL, NULL);
+
+ if (!openssl_rsa_public_key_build_id(this->rsa, &this->keyid, &this->keyid_info))
+ {
+ destroy(this);
+ return NULL;
+ }
+
+ return &this->public;
+}
+
+/**
+ * load private key from an ASN1 encoded blob
+ */
+static openssl_rsa_private_key_t *load(chunk_t blob)
+{
+ u_char *p = blob.ptr;
+ private_openssl_rsa_private_key_t *this = openssl_rsa_private_key_create_empty();
+
+ this->rsa = d2i_RSAPrivateKey(NULL, (const u_char**)&p, blob.len);
+
+ chunk_clear(&blob);
+
+ if (!this->rsa)
+ {
+ destroy(this);
+ return NULL;
+ }
+
+ if (!openssl_rsa_public_key_build_id(this->rsa, &this->keyid, &this->keyid_info))
+ {
+ destroy(this);
+ return NULL;
+ }
+
+ if (!RSA_check_key(this->rsa))
+ {
+ destroy(this);
+ return NULL;
+ }
+
+ return &this->public;
+}
+
+typedef struct private_builder_t private_builder_t;
+/**
+ * Builder implementation for key loading/generation
+ */
+struct private_builder_t {
+ /** implements the builder interface */
+ builder_t public;
+ /** loaded/generated private key */
+ openssl_rsa_private_key_t *key;
+};
+
+/**
+ * Implementation of builder_t.build
+ */
+static openssl_rsa_private_key_t *build(private_builder_t *this)
+{
+ openssl_rsa_private_key_t *key = this->key;
+
+ free(this);
+ return key;
+}
+
+/**
+ * Implementation of builder_t.add
+ */
+static void add(private_builder_t *this, builder_part_t part, ...)
+{
+ va_list args;
+
+ if (this->key)
+ {
+ DBG1("ignoring surplus build part %N", builder_part_names, part);
+ return;
+ }
+
+ switch (part)
+ {
+ case BUILD_BLOB_ASN1_DER:
+ {
+ va_start(args, part);
+ this->key = load(va_arg(args, chunk_t));
+ va_end(args);
+ break;
+ }
+ case BUILD_KEY_SIZE:
+ {
+ va_start(args, part);
+ this->key = generate(va_arg(args, u_int));
+ va_end(args);
+ break;
+ }
+ default:
+ DBG1("ignoring unsupported build part %N", builder_part_names, part);
+ break;
+ }
+}
+
+/**
+ * Builder construction function
+ */
+builder_t *openssl_rsa_private_key_builder(key_type_t type)
+{
+ private_builder_t *this;
+
+ if (type != KEY_RSA)
+ {
+ return NULL;
+ }
+
+ this = malloc_thing(private_builder_t);
+
+ this->key = NULL;
+ this->public.add = (void(*)(builder_t *this, builder_part_t part, ...))add;
+ this->public.build = (void*(*)(builder_t *this))build;
+
+ return &this->public;
+}
+
diff --git a/src/libstrongswan/plugins/openssl/openssl_rsa_private_key.h b/src/libstrongswan/plugins/openssl/openssl_rsa_private_key.h
new file mode 100644
index 000000000..81d81b2db
--- /dev/null
+++ b/src/libstrongswan/plugins/openssl/openssl_rsa_private_key.h
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2008 Tobias Brunner
+ * 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.
+ *
+ * $Id: openssl_rsa_private_key.h 4000 2008-05-22 12:13:10Z tobias $
+ */
+
+/**
+ * @defgroup openssl_rsa_private_key openssl_rsa_private_key
+ * @{ @ingroup openssl_p
+ */
+
+#ifndef OPENSSL_RSA_PRIVATE_KEY_H_
+#define OPENSSL_RSA_PRIVATE_KEY_H_
+
+#include <credentials/keys/private_key.h>
+
+typedef struct openssl_rsa_private_key_t openssl_rsa_private_key_t;
+
+/**
+ * private_key_t implementation of RSA algorithm using OpenSSL.
+ */
+struct openssl_rsa_private_key_t {
+
+ /**
+ * Implements private_key_t interface
+ */
+ private_key_t interface;
+};
+
+/**
+ * Create the builder for a private key.
+ *
+ * @param type type of the key, must be KEY_RSA
+ * @return builder instance
+ */
+builder_t *openssl_rsa_private_key_builder(key_type_t type);
+
+#endif /*OPENSSL_RSA_PRIVATE_KEY_H_ @}*/
diff --git a/src/libstrongswan/plugins/openssl/openssl_rsa_public_key.c b/src/libstrongswan/plugins/openssl/openssl_rsa_public_key.c
new file mode 100644
index 000000000..755b86e96
--- /dev/null
+++ b/src/libstrongswan/plugins/openssl/openssl_rsa_public_key.c
@@ -0,0 +1,433 @@
+/*
+ * Copyright (C) 2008 Tobias Brunner
+ * 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.
+ *
+ * $Id: openssl_rsa_public_key.c 3963 2008-05-15 12:41:06Z tobias $
+ */
+
+#include "openssl_rsa_public_key.h"
+
+#include <debug.h>
+
+#include <openssl/evp.h>
+#include <openssl/rsa.h>
+#include <openssl/x509.h>
+
+typedef struct private_openssl_rsa_public_key_t private_openssl_rsa_public_key_t;
+
+/**
+ * Private data structure with signing context.
+ */
+struct private_openssl_rsa_public_key_t {
+ /**
+ * Public interface for this signer.
+ */
+ openssl_rsa_public_key_t public;
+
+ /**
+ * RSA object from OpenSSL
+ */
+ RSA *rsa;
+
+ /**
+ * Keyid formed as a SHA-1 hash of a publicKeyInfo object
+ */
+ identification_t *keyid_info;
+
+ /**
+ * Keyid formed as a SHA-1 hash of a publicKey object
+ */
+ identification_t *keyid;
+
+ /**
+ * reference counter
+ */
+ refcount_t ref;
+};
+
+/**
+ * Verification of an EMPSA PKCS1 signature described in PKCS#1
+ */
+static bool verify_emsa_pkcs1_signature(private_openssl_rsa_public_key_t *this,
+ int type, chunk_t data, chunk_t signature)
+{
+ bool valid = FALSE;
+ const EVP_MD *hasher = EVP_get_digestbynid(type);
+ if (!hasher)
+ {
+ return FALSE;
+ }
+
+ EVP_MD_CTX *ctx = EVP_MD_CTX_create();
+ EVP_PKEY *key = EVP_PKEY_new();
+ if (!ctx || !key)
+ {
+ goto error;
+ }
+
+ if (!EVP_PKEY_set1_RSA(key, this->rsa))
+ {
+ goto error;
+ }
+
+ if (!EVP_VerifyInit_ex(ctx, hasher, NULL))
+ {
+ goto error;
+ }
+
+ if (!EVP_VerifyUpdate(ctx, data.ptr, data.len))
+ {
+ goto error;
+ }
+
+ /* remove any preceding 0-bytes from signature */
+ while (signature.len && *(signature.ptr) == 0x00)
+ {
+ signature.len -= 1;
+ signature.ptr++;
+ }
+
+ valid = (EVP_VerifyFinal(ctx, signature.ptr, signature.len, key) == 1);
+
+error:
+ if (key)
+ {
+ EVP_PKEY_free(key);
+ }
+ if (ctx)
+ {
+ EVP_MD_CTX_destroy(ctx);
+ }
+ return valid;
+}
+
+/**
+ * Implementation of public_key_t.get_type.
+ */
+static key_type_t get_type(private_openssl_rsa_public_key_t *this)
+{
+ return KEY_RSA;
+}
+
+/**
+ * Implementation of public_key_t.verify.
+ */
+static bool verify(private_openssl_rsa_public_key_t *this, signature_scheme_t scheme,
+ chunk_t data, chunk_t signature)
+{
+ switch (scheme)
+ {
+ case SIGN_DEFAULT:
+ /* default is EMSA-PKCS1 using SHA1 */
+ case SIGN_RSA_EMSA_PKCS1_SHA1:
+ return verify_emsa_pkcs1_signature(this, NID_sha1, data, signature);
+ case SIGN_RSA_EMSA_PKCS1_SHA256:
+ return verify_emsa_pkcs1_signature(this, NID_sha256, data, signature);
+ case SIGN_RSA_EMSA_PKCS1_SHA384:
+ return verify_emsa_pkcs1_signature(this, NID_sha384, data, signature);
+ case SIGN_RSA_EMSA_PKCS1_SHA512:
+ return verify_emsa_pkcs1_signature(this, NID_sha512, data, signature);
+ case SIGN_RSA_EMSA_PKCS1_MD5:
+ return verify_emsa_pkcs1_signature(this, NID_md5, data, signature);
+ default:
+ DBG1("signature scheme %N not supported in RSA",
+ signature_scheme_names, scheme);
+ return FALSE;
+ }
+}
+
+/**
+ * Implementation of public_key_t.get_keysize.
+ */
+static bool encrypt(private_openssl_rsa_public_key_t *this, chunk_t crypto, chunk_t *plain)
+{
+ DBG1("RSA public key encryption not implemented");
+ return FALSE;
+}
+
+/**
+ * Implementation of public_key_t.get_keysize.
+ */
+static size_t get_keysize(private_openssl_rsa_public_key_t *this)
+{
+ return RSA_size(this->rsa);
+}
+
+/**
+ * Implementation of public_key_t.get_id.
+ */
+static identification_t *get_id(private_openssl_rsa_public_key_t *this,
+ id_type_t type)
+{
+ switch (type)
+ {
+ case ID_PUBKEY_INFO_SHA1:
+ return this->keyid_info;
+ case ID_PUBKEY_SHA1:
+ return this->keyid;
+ default:
+ return NULL;
+ }
+}
+
+/**
+ * Encodes the public key
+ */
+static chunk_t get_encoding_raw(RSA *rsa)
+{
+ chunk_t enc = chunk_alloc(i2d_RSAPublicKey(rsa, NULL));
+ u_char *p = enc.ptr;
+ i2d_RSAPublicKey(rsa, &p);
+ return enc;
+}
+
+/**
+ * Encodes the public key with the algorithm used
+ */
+static chunk_t get_encoding_with_algo(RSA *rsa)
+{
+ u_char *p;
+ chunk_t enc;
+ X509_PUBKEY *pubkey = X509_PUBKEY_new();
+
+ ASN1_OBJECT_free(pubkey->algor->algorithm);
+ pubkey->algor->algorithm = OBJ_nid2obj(NID_rsaEncryption);
+
+ if (pubkey->algor->parameter == NULL ||
+ pubkey->algor->parameter->type != V_ASN1_NULL)
+ {
+ ASN1_TYPE_free(pubkey->algor->parameter);
+ pubkey->algor->parameter = ASN1_TYPE_new();
+ pubkey->algor->parameter->type = V_ASN1_NULL;
+ }
+
+ enc = get_encoding_raw(rsa);
+ M_ASN1_BIT_STRING_set(pubkey->public_key, enc.ptr, enc.len);
+ chunk_free(&enc);
+
+ enc = chunk_alloc(i2d_X509_PUBKEY(pubkey, NULL));
+ p = enc.ptr;
+ i2d_X509_PUBKEY(pubkey, &p);
+ X509_PUBKEY_free(pubkey);
+ return enc;
+}
+
+/*
+ * Implementation of public_key_t.get_encoding.
+ */
+static chunk_t get_encoding(private_openssl_rsa_public_key_t *this)
+{
+ return get_encoding_raw(this->rsa);
+}
+
+/**
+ * Implementation of public_key_t.get_ref.
+ */
+static private_openssl_rsa_public_key_t* get_ref(private_openssl_rsa_public_key_t *this)
+{
+ ref_get(&this->ref);
+ return this;
+}
+
+/**
+ * Implementation of openssl_rsa_public_key.destroy.
+ */
+static void destroy(private_openssl_rsa_public_key_t *this)
+{
+ if (ref_put(&this->ref))
+ {
+ if (this->rsa)
+ {
+ RSA_free(this->rsa);
+ }
+ DESTROY_IF(this->keyid);
+ DESTROY_IF(this->keyid_info);
+ free(this);
+ }
+}
+
+/**
+ * Generic private constructor
+ */
+static private_openssl_rsa_public_key_t *openssl_rsa_public_key_create_empty()
+{
+ private_openssl_rsa_public_key_t *this = malloc_thing(private_openssl_rsa_public_key_t);
+
+ this->public.interface.get_type = (key_type_t (*)(public_key_t *this))get_type;
+ this->public.interface.verify = (bool (*)(public_key_t *this, signature_scheme_t scheme, chunk_t data, chunk_t signature))verify;
+ this->public.interface.encrypt = (bool (*)(public_key_t *this, chunk_t crypto, chunk_t *plain))encrypt;
+ this->public.interface.get_keysize = (size_t (*) (public_key_t *this))get_keysize;
+ this->public.interface.get_id = (identification_t* (*) (public_key_t *this,id_type_t))get_id;
+ this->public.interface.get_encoding = (chunk_t(*)(public_key_t*))get_encoding;
+ this->public.interface.get_ref = (public_key_t* (*)(public_key_t *this))get_ref;
+ this->public.interface.destroy = (void (*)(public_key_t *this))destroy;
+
+ this->keyid = NULL;
+ this->keyid_info = NULL;
+ this->ref = 1;
+
+ return this;
+}
+
+/**
+ * Build the RSA key identifier from n and e using SHA1 hashed publicKey(Info).
+ * Also used in openssl_rsa_private_key.c.
+ */
+bool openssl_rsa_public_key_build_id(RSA *rsa, identification_t **keyid,
+ identification_t **keyid_info)
+{
+ chunk_t publicKeyInfo, publicKey, hash;
+ hasher_t *hasher;
+
+ hasher = lib->crypto->create_hasher(lib->crypto, HASH_SHA1);
+ if (hasher == NULL)
+ {
+ DBG1("SHA1 hash algorithm not supported, unable to use RSA");
+ return FALSE;
+ }
+
+ publicKey = get_encoding_raw(rsa);
+
+ hasher->allocate_hash(hasher, publicKey, &hash);
+ *keyid = identification_create_from_encoding(ID_PUBKEY_SHA1, hash);
+ chunk_free(&hash);
+
+ publicKeyInfo = get_encoding_with_algo(rsa);
+
+ hasher->allocate_hash(hasher, publicKeyInfo, &hash);
+ *keyid_info = identification_create_from_encoding(ID_PUBKEY_INFO_SHA1, hash);
+ chunk_free(&hash);
+
+ hasher->destroy(hasher);
+ chunk_free(&publicKeyInfo);
+ chunk_free(&publicKey);
+
+ return TRUE;
+}
+
+/**
+ * Create a public key from BIGNUM values, used in openssl_rsa_private_key.c
+ */
+openssl_rsa_public_key_t *openssl_rsa_public_key_create_from_n_e(BIGNUM *n, BIGNUM *e)
+{
+ private_openssl_rsa_public_key_t *this = openssl_rsa_public_key_create_empty();
+
+ this->rsa = RSA_new();
+ this->rsa->n = BN_dup(n);
+ this->rsa->e = BN_dup(e);
+
+ if (!openssl_rsa_public_key_build_id(this->rsa, &this->keyid, &this->keyid_info))
+ {
+ destroy(this);
+ return NULL;
+ }
+ return &this->public;
+}
+
+/**
+ * Load a public key from an ASN1 encoded blob
+ */
+static openssl_rsa_public_key_t *load(chunk_t blob)
+{
+ u_char *p = blob.ptr;
+ private_openssl_rsa_public_key_t *this = openssl_rsa_public_key_create_empty();
+
+ this->rsa = d2i_RSAPublicKey(NULL, (const u_char**)&p, blob.len);
+
+ chunk_clear(&blob);
+
+ if (!this->rsa)
+ {
+ destroy(this);
+ return NULL;
+ }
+
+ if (!openssl_rsa_public_key_build_id(this->rsa, &this->keyid, &this->keyid_info))
+ {
+ destroy(this);
+ return NULL;
+ }
+ return &this->public;
+}
+
+typedef struct private_builder_t private_builder_t;
+/**
+ * Builder implementation for key loading
+ */
+struct private_builder_t {
+ /** implements the builder interface */
+ builder_t public;
+ /** loaded public key */
+ openssl_rsa_public_key_t *key;
+};
+
+/**
+ * Implementation of builder_t.build
+ */
+static openssl_rsa_public_key_t *build(private_builder_t *this)
+{
+ openssl_rsa_public_key_t *key = this->key;
+
+ free(this);
+ return key;
+}
+
+/**
+ * Implementation of builder_t.add
+ */
+static void add(private_builder_t *this, builder_part_t part, ...)
+{
+ va_list args;
+
+ if (this->key)
+ {
+ DBG1("ignoring surplus build part %N", builder_part_names, part);
+ return;
+ }
+
+ switch (part)
+ {
+ case BUILD_BLOB_ASN1_DER:
+ {
+ va_start(args, part);
+ this->key = load(va_arg(args, chunk_t));
+ va_end(args);
+ break;
+ }
+ default:
+ DBG1("ignoring unsupported build part %N", builder_part_names, part);
+ break;
+ }
+}
+
+/**
+ * Builder construction function
+ */
+builder_t *openssl_rsa_public_key_builder(key_type_t type)
+{
+ private_builder_t *this;
+
+ if (type != KEY_RSA)
+ {
+ return NULL;
+ }
+
+ this = malloc_thing(private_builder_t);
+
+ this->key = NULL;
+ this->public.add = (void(*)(builder_t *this, builder_part_t part, ...))add;
+ this->public.build = (void*(*)(builder_t *this))build;
+
+ return &this->public;
+}
+
diff --git a/src/libstrongswan/plugins/openssl/openssl_rsa_public_key.h b/src/libstrongswan/plugins/openssl/openssl_rsa_public_key.h
new file mode 100644
index 000000000..570fb69cb
--- /dev/null
+++ b/src/libstrongswan/plugins/openssl/openssl_rsa_public_key.h
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2008 Tobias Brunner
+ * 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.
+ *
+ * $Id: openssl_rsa_public_key.h 4000 2008-05-22 12:13:10Z tobias $
+ */
+
+/**
+ * @defgroup openssl_rsa_public_key openssl_rsa_public_key
+ * @{ @ingroup openssl_p
+ */
+
+#ifndef OPENSSL_RSA_PUBLIC_KEY_H_
+#define OPENSSL_RSA_PUBLIC_KEY_H_
+
+typedef struct openssl_rsa_public_key_t openssl_rsa_public_key_t;
+
+#include <credentials/keys/public_key.h>
+
+/**
+ * public_key_t implementation of RSA algorithm using OpenSSL.
+ */
+struct openssl_rsa_public_key_t {
+
+ /**
+ * Implements the public_key_t interface
+ */
+ public_key_t interface;
+};
+
+/**
+ * Create the builder for a public key.
+ *
+ * @param type type of the key, must be KEY_RSA
+ * @return builder instance
+ */
+builder_t *openssl_rsa_public_key_builder(key_type_t type);
+
+#endif /*OPENSSL_RSA_PUBLIC_KEY_H_ @}*/
diff --git a/src/libstrongswan/plugins/openssl/openssl_util.c b/src/libstrongswan/plugins/openssl/openssl_util.c
new file mode 100644
index 000000000..3c4f6595b
--- /dev/null
+++ b/src/libstrongswan/plugins/openssl/openssl_util.c
@@ -0,0 +1,120 @@
+/*
+ * Copyright (C) 2008 Tobias Brunner
+ * 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.
+ *
+ * $Id: openssl_util.c 4051 2008-06-10 09:08:27Z tobias $
+ */
+
+#include "openssl_util.h"
+
+#include <debug.h>
+
+#include <openssl/evp.h>
+
+/**
+ * Described in header.
+ */
+bool openssl_hash_chunk(int hash_type, chunk_t data, chunk_t *hash)
+{
+ EVP_MD_CTX *ctx;
+ bool ret = FALSE;
+ const EVP_MD *hasher = EVP_get_digestbynid(hash_type);
+ if (!hasher)
+ {
+ return FALSE;
+ }
+
+ ctx = EVP_MD_CTX_create();
+ if (!ctx)
+ {
+ goto error;
+ }
+
+ if (!EVP_DigestInit_ex(ctx, hasher, NULL))
+ {
+ goto error;
+ }
+
+ if (!EVP_DigestUpdate(ctx, data.ptr, data.len))
+ {
+ goto error;
+ }
+
+ *hash = chunk_alloc(hasher->md_size);
+ if (!EVP_DigestFinal_ex(ctx, hash->ptr, NULL))
+ {
+ chunk_free(hash);
+ goto error;
+ }
+
+ ret = TRUE;
+error:
+ if (ctx)
+ {
+ EVP_MD_CTX_destroy(ctx);
+ }
+ return ret;
+}
+
+/**
+ * Described in header.
+ */
+bool openssl_bn_cat(int len, BIGNUM *a, BIGNUM *b, chunk_t *chunk)
+{
+ int offset;
+
+ chunk->len = len * 2;
+ chunk->ptr = malloc(chunk->len);
+ memset(chunk->ptr, 0, chunk->len);
+
+ offset = len - BN_num_bytes(a);
+ if (!BN_bn2bin(a, chunk->ptr + offset))
+ {
+ goto error;
+ }
+
+ offset = len - BN_num_bytes(b);
+ if (!BN_bn2bin(b, chunk->ptr + len + offset))
+ {
+ goto error;
+ }
+
+ return TRUE;
+error:
+ chunk_free(chunk);
+ return FALSE;
+}
+
+
+/**
+ * Described in header.
+ */
+bool openssl_bn_split(chunk_t chunk, BIGNUM *a, BIGNUM *b)
+{
+ int len;
+
+ if ((chunk.len % 2) != 0)
+ {
+ return FALSE;
+ }
+
+ len = chunk.len / 2;
+
+ if (!BN_bin2bn(chunk.ptr, len, a) ||
+ !BN_bin2bn(chunk.ptr + len, len, b))
+ {
+ return FALSE;
+ }
+
+ return TRUE;
+}
diff --git a/src/libstrongswan/plugins/openssl/openssl_util.h b/src/libstrongswan/plugins/openssl/openssl_util.h
new file mode 100644
index 000000000..2dbd5054e
--- /dev/null
+++ b/src/libstrongswan/plugins/openssl/openssl_util.h
@@ -0,0 +1,70 @@
+/*
+ * Copyright (C) 2008 Tobias Brunner
+ * 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.
+ *
+ * $Id: openssl_util.h 4051 2008-06-10 09:08:27Z tobias $
+ */
+
+/**
+ * @defgroup openssl_util openssl_util
+ * @{ @ingroup openssl_p
+ */
+
+#ifndef OPENSSL_UTIL_H_
+#define OPENSSL_UTIL_H_
+
+#include <library.h>
+#include <openssl/bn.h>
+
+/**
+ * Returns the length in bytes of a field element
+ */
+#define EC_FIELD_ELEMENT_LEN(group) ((EC_GROUP_get_degree(group) + 7) / 8)
+
+/**
+ * Creates a hash of a given type of a chunk of data.
+ *
+ * Note: this function allocates memory for the hash
+ *
+ * @param hash_type NID of the hash
+ * @param data the chunk of data to hash
+ * @param hash chunk that contains the hash
+ * @return TRUE on success, FALSE otherwise
+ */
+bool openssl_hash_chunk(int hash_type, chunk_t data, chunk_t *hash);
+
+/**
+ * Concatenates two bignums into a chunk, thereby enfocing the length of
+ * a single BIGNUM, if necessary, by pre-pending it with zeros.
+ *
+ * Note: this function allocates memory for the chunk
+ *
+ * @param len the length of a single BIGNUM
+ * @param a first BIGNUM
+ * @param b second BIGNUM
+ * @param chunk resulting chunk
+ * @return TRUE on success, FALSE otherwise
+ */
+bool openssl_bn_cat(int len, BIGNUM *a, BIGNUM *b, chunk_t *chunk);
+
+/**
+ * Splits a chunk into two bignums of equal binary length.
+ *
+ * @param chunk a chunk that contains the two BIGNUMs
+ * @param a first BIGNUM
+ * @param b second BIGNUM
+ * @return TRUE on success, FALSE otherwise
+ */
+bool openssl_bn_split(chunk_t chunk, BIGNUM *a, BIGNUM *b);
+
+#endif /*OPENSSL_UTIL_H_ @}*/
diff --git a/src/libstrongswan/plugins/padlock/Makefile.am b/src/libstrongswan/plugins/padlock/Makefile.am
new file mode 100644
index 000000000..e2e76e9e6
--- /dev/null
+++ b/src/libstrongswan/plugins/padlock/Makefile.am
@@ -0,0 +1,12 @@
+
+INCLUDES = -I$(top_srcdir)/src/libstrongswan
+
+AM_CFLAGS = -rdynamic
+
+plugin_LTLIBRARIES = libstrongswan-padlock.la
+
+libstrongswan_padlock_la_SOURCES = padlock_plugin.h padlock_plugin.c \
+ padlock_aes_crypter.c padlock_aes_crypter.h \
+ padlock_sha1_hasher.c padlock_sha1_hasher.h
+libstrongswan_padlock_la_LDFLAGS = -module
+
diff --git a/src/libstrongswan/plugins/padlock/Makefile.in b/src/libstrongswan/plugins/padlock/Makefile.in
new file mode 100644
index 000000000..d96b2cf6d
--- /dev/null
+++ b/src/libstrongswan/plugins/padlock/Makefile.in
@@ -0,0 +1,500 @@
+# Makefile.in generated by automake 1.10.1 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+VPATH = @srcdir@
+pkgdatadir = $(datadir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+subdir = src/libstrongswan/plugins/padlock
+DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/configure.in
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+mkinstalldirs = $(install_sh) -d
+CONFIG_CLEAN_FILES =
+am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
+am__vpath_adj = case $$p in \
+ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
+ *) f=$$p;; \
+ esac;
+am__strip_dir = `echo $$p | sed -e 's|^.*/||'`;
+am__installdirs = "$(DESTDIR)$(plugindir)"
+pluginLTLIBRARIES_INSTALL = $(INSTALL)
+LTLIBRARIES = $(plugin_LTLIBRARIES)
+libstrongswan_padlock_la_LIBADD =
+am_libstrongswan_padlock_la_OBJECTS = padlock_plugin.lo \
+ padlock_aes_crypter.lo padlock_sha1_hasher.lo
+libstrongswan_padlock_la_OBJECTS = \
+ $(am_libstrongswan_padlock_la_OBJECTS)
+libstrongswan_padlock_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(libstrongswan_padlock_la_LDFLAGS) $(LDFLAGS) -o $@
+DEFAULT_INCLUDES = -I.@am__isrc@
+depcomp = $(SHELL) $(top_srcdir)/depcomp
+am__depfiles_maybe = depfiles
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+ --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
+ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+CCLD = $(CC)
+LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+ --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \
+ $(LDFLAGS) -o $@
+SOURCES = $(libstrongswan_padlock_la_SOURCES)
+DIST_SOURCES = $(libstrongswan_padlock_la_SOURCES)
+ETAGS = etags
+CTAGS = ctags
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+AMTAR = @AMTAR@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CXX = @CXX@
+CXXCPP = @CXXCPP@
+CXXDEPMODE = @CXXDEPMODE@
+CXXFLAGS = @CXXFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DSYMUTIL = @DSYMUTIL@
+ECHO = @ECHO@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+F77 = @F77@
+FFLAGS = @FFLAGS@
+GPERF = @GPERF@
+GREP = @GREP@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+IPSEC_ROUTING_TABLE = @IPSEC_ROUTING_TABLE@
+IPSEC_ROUTING_TABLE_PRIO = @IPSEC_ROUTING_TABLE_PRIO@
+LDFLAGS = @LDFLAGS@
+LEX = @LEX@
+LEXLIB = @LEXLIB@
+LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LINUX_HEADERS = @LINUX_HEADERS@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+MAKEINFO = @MAKEINFO@
+MKDIR_P = @MKDIR_P@
+NMEDIT = @NMEDIT@
+OBJEXT = @OBJEXT@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PERL = @PERL@
+PKG_CONFIG = @PKG_CONFIG@
+RANLIB = @RANLIB@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRIP = @STRIP@
+VERSION = @VERSION@
+YACC = @YACC@
+YFLAGS = @YFLAGS@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_CXX = @ac_ct_CXX@
+ac_ct_F77 = @ac_ct_F77@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+confdir = @confdir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+gtk_CFLAGS = @gtk_CFLAGS@
+gtk_LIBS = @gtk_LIBS@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+ipsecdir = @ipsecdir@
+ipsecgroup = @ipsecgroup@
+ipsecuser = @ipsecuser@
+libdir = @libdir@
+libexecdir = @libexecdir@
+libstrongswan_plugins = @libstrongswan_plugins@
+linuxdir = @linuxdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+piddir = @piddir@
+plugindir = @plugindir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+resolv_conf = @resolv_conf@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+simreader = @simreader@
+srcdir = @srcdir@
+strongswan_conf = @strongswan_conf@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+xml_CFLAGS = @xml_CFLAGS@
+xml_LIBS = @xml_LIBS@
+INCLUDES = -I$(top_srcdir)/src/libstrongswan
+AM_CFLAGS = -rdynamic
+plugin_LTLIBRARIES = libstrongswan-padlock.la
+libstrongswan_padlock_la_SOURCES = padlock_plugin.h padlock_plugin.c \
+ padlock_aes_crypter.c padlock_aes_crypter.h \
+ padlock_sha1_hasher.c padlock_sha1_hasher.h
+
+libstrongswan_padlock_la_LDFLAGS = -module
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .c .lo .o .obj
+$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \
+ && exit 0; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/libstrongswan/plugins/padlock/Makefile'; \
+ cd $(top_srcdir) && \
+ $(AUTOMAKE) --gnu src/libstrongswan/plugins/padlock/Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+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) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(pluginLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) '$$p' '$(DESTDIR)$(plugindir)/$$f'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(pluginLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) "$$p" "$(DESTDIR)$(plugindir)/$$f"; \
+ else :; fi; \
+ done
+
+uninstall-pluginLTLIBRARIES:
+ @$(NORMAL_UNINSTALL)
+ @list='$(plugin_LTLIBRARIES)'; for p in $$list; do \
+ p=$(am__strip_dir) \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(plugindir)/$$p'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(plugindir)/$$p"; \
+ 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
+libstrongswan-padlock.la: $(libstrongswan_padlock_la_OBJECTS) $(libstrongswan_padlock_la_DEPENDENCIES)
+ $(libstrongswan_padlock_la_LINK) -rpath $(plugindir) $(libstrongswan_padlock_la_OBJECTS) $(libstrongswan_padlock_la_LIBADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/padlock_aes_crypter.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/padlock_plugin.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/padlock_sha1_hasher.Plo@am__quote@
+
+.c.o:
+@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(COMPILE) -c $<
+
+.c.obj:
+@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'`
+
+.c.lo:
+@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $<
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+
+ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonemtpy = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ mkid -fID $$unique
+tags: TAGS
+
+TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ tags=; \
+ here=`pwd`; \
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \
+ test -n "$$unique" || unique=$$empty_fix; \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ $$tags $$unique; \
+ fi
+ctags: CTAGS
+CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ tags=; \
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ test -z "$(CTAGS_ARGS)$$tags$$unique" \
+ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+ $$tags $$unique
+
+GTAGS:
+ here=`$(am__cd) $(top_builddir) && pwd` \
+ && cd $(top_srcdir) \
+ && gtags -i $(GTAGS_ARGS) $$here
+
+distclean-tags:
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+distdir: $(DISTFILES)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ list='$(DISTFILES)'; \
+ dist_files=`for file in $$list; do echo $$file; done | \
+ sed -e "s|^$$srcdirstrip/||;t" \
+ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+ case $$dist_files in \
+ */*) $(MKDIR_P) `echo "$$dist_files" | \
+ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+ sort -u` ;; \
+ esac; \
+ for file in $$dist_files; do \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ if test -d $$d/$$file; then \
+ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
+ fi; \
+ cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
+ else \
+ test -f $(distdir)/$$file \
+ || cp -p $$d/$$file $(distdir)/$$file \
+ || exit 1; \
+ fi; \
+ done
+check-am: all-am
+check: check-am
+all-am: Makefile $(LTLIBRARIES)
+installdirs:
+ for dir in "$(DESTDIR)$(plugindir)"; do \
+ test -z "$$dir" || $(MKDIR_P) "$$dir"; \
+ done
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ `test -z '$(STRIP)' || \
+ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+clean: clean-am
+
+clean-am: clean-generic clean-libtool clean-pluginLTLIBRARIES \
+ mostlyclean-am
+
+distclean: distclean-am
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+ distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+info: info-am
+
+info-am:
+
+install-data-am: install-pluginLTLIBRARIES
+
+install-dvi: install-dvi-am
+
+install-exec-am:
+
+install-html: install-html-am
+
+install-info: install-info-am
+
+install-man:
+
+install-pdf: install-pdf-am
+
+install-ps: install-ps-am
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic \
+ mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am: uninstall-pluginLTLIBRARIES
+
+.MAKE: install-am install-strip
+
+.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \
+ clean-libtool clean-pluginLTLIBRARIES ctags distclean \
+ distclean-compile distclean-generic distclean-libtool \
+ distclean-tags distdir dvi dvi-am html html-am info info-am \
+ install install-am install-data install-data-am install-dvi \
+ install-dvi-am install-exec install-exec-am install-html \
+ install-html-am install-info install-info-am install-man \
+ install-pdf install-pdf-am install-pluginLTLIBRARIES \
+ install-ps install-ps-am install-strip installcheck \
+ installcheck-am installdirs maintainer-clean \
+ maintainer-clean-generic mostlyclean mostlyclean-compile \
+ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
+ tags uninstall uninstall-am uninstall-pluginLTLIBRARIES
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/src/libstrongswan/plugins/padlock/padlock_aes_crypter.c b/src/libstrongswan/plugins/padlock/padlock_aes_crypter.c
new file mode 100644
index 000000000..f6f9b3501
--- /dev/null
+++ b/src/libstrongswan/plugins/padlock/padlock_aes_crypter.c
@@ -0,0 +1,201 @@
+/*
+ * Copyright (C) 2008 Thomas Kallenberg
+ * Copyright (C) 2008 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.
+ *
+ * $Id$
+ */
+
+#include "padlock_aes_crypter.h"
+#include <stdio.h>
+
+#define AES_BLOCK_SIZE 16
+#define PADLOCK_ALIGN __attribute__ ((__aligned__(16)))
+
+typedef struct private_padlock_aes_crypter_t private_padlock_aes_crypter_t;
+
+/**
+ * Private data of padlock_aes_crypter_t
+ */
+struct private_padlock_aes_crypter_t {
+
+ /**
+ * Public part of this class.
+ */
+ padlock_aes_crypter_t public;
+
+ /*
+ * the key
+ */
+ chunk_t key;
+};
+
+/**
+ * Control word structure to pass to crypt operations
+ */
+typedef struct {
+ u_int __attribute__ ((__packed__))
+ rounds:4,
+ algo:3,
+ keygen:1,
+ interm:1,
+ encdec:1,
+ ksize:2;
+ /* microcode needs additional bytes for calculation */
+ u_char buf[124];
+} cword;
+
+/**
+ * Invoke the actual de/encryption
+ */
+static void padlock_crypt(void *key, void *ctrl, void *src, void *dst,
+ int count, void *iv)
+{
+ asm volatile(
+ "pushl %%eax\n pushl %%ebx\n pushl %%ecx\n"
+ "pushl %%edx\n pushl %%esi\n pushl %%edi\n"
+ "pushfl\n popfl\n"
+ "movl %0, %%eax\n"
+ "movl %1, %%ebx\n"
+ "movl %2, %%ecx\n"
+ "movl %3, %%edx\n"
+ "movl %4, %%esi\n"
+ "movl %5, %%edi\n"
+ "rep\n"
+ ".byte 0x0f, 0xa7, 0xd0\n"
+ "popl %%edi\n popl %%esi\n popl %%edx\n"
+ "popl %%ecx\n popl %%ebx\n popl %%eax\n"
+ :
+ : "m"(iv),"m"(key), "m"(count), "m"(ctrl), "m"(src), "m"(dst)
+ : "eax", "ecx", "edx", "esi", "edi");
+}
+
+/*
+ * Implementation of crypter_t.crypt
+ */
+static void crypt(private_padlock_aes_crypter_t *this, char *iv,
+ chunk_t src, chunk_t *dst, bool enc)
+{
+ cword cword PADLOCK_ALIGN;
+ u_char key_aligned[256] PADLOCK_ALIGN;
+ u_char iv_aligned[16] PADLOCK_ALIGN;
+
+ memset(&cword, 0, sizeof(cword));
+
+ /* set encryption/decryption flag */
+ cword.encdec = enc;
+ /* calculate rounds and key size */
+ cword.rounds = 10 + (this->key.len - 16) / 4;
+ cword.ksize = (this->key.len - 16) / 8;
+ /* enable autoalign */
+ cword.algo |= 2;
+
+ /* move data to aligned buffers */
+ memcpy(iv_aligned, iv, sizeof(iv_aligned));
+ memcpy(key_aligned, this->key.ptr, this->key.len);
+
+ *dst = chunk_alloc(src.len);
+ padlock_crypt(key_aligned, &cword, src.ptr, dst->ptr,
+ src.len / AES_BLOCK_SIZE, iv_aligned);
+}
+
+/**
+ * Implementation of crypter_t.decrypt.
+ */
+static void decrypt(private_padlock_aes_crypter_t *this, chunk_t data,
+ chunk_t iv, chunk_t *dst)
+{
+ crypt(this, iv.ptr, data, dst, TRUE);
+}
+
+
+/**
+ * Implementation of crypter_t.encrypt.
+ */
+static void encrypt (private_padlock_aes_crypter_t *this, chunk_t data,
+ chunk_t iv, chunk_t *dst)
+{
+ crypt(this, iv.ptr, data, dst, FALSE);
+}
+
+/**
+ * Implementation of crypter_t.get_block_size.
+ */
+static size_t get_block_size(private_padlock_aes_crypter_t *this)
+{
+ return AES_BLOCK_SIZE;
+}
+
+/**
+ * Implementation of crypter_t.get_key_size.
+ */
+static size_t get_key_size(private_padlock_aes_crypter_t *this)
+{
+ return this->key.len;
+}
+
+/**
+ * Implementation of crypter_t.set_key.
+ */
+static void set_key(private_padlock_aes_crypter_t *this, chunk_t key)
+{
+ memcpy(this->key.ptr, key.ptr, min(key.len, this->key.len));
+}
+
+/**
+ * Implementation of crypter_t.destroy and aes_crypter_t.destroy.
+ */
+static void destroy (private_padlock_aes_crypter_t *this)
+{
+ free(this->key.ptr);
+ free(this);
+}
+
+/*
+ * Described in header
+ */
+padlock_aes_crypter_t *padlock_aes_crypter_create(encryption_algorithm_t algo,
+ size_t key_size)
+{
+ private_padlock_aes_crypter_t *this;
+
+ if (algo != ENCR_AES_CBC)
+ {
+ return NULL;
+ }
+
+ this = malloc_thing(private_padlock_aes_crypter_t);
+
+ switch (key_size)
+ {
+ case 16: /* AES 128 */
+ break;
+ case 24: /* AES-192 */
+ case 32: /* AES-256 */
+ /* These need an expanded key, currently not supported, FALL */
+ default:
+ free(this);
+ return NULL;
+ }
+
+ this->key = chunk_alloc(key_size);
+
+ this->public.crypter_interface.encrypt = (void (*) (crypter_t *, chunk_t,chunk_t, chunk_t *)) encrypt;
+ this->public.crypter_interface.decrypt = (void (*) (crypter_t *, chunk_t , chunk_t, chunk_t *)) decrypt;
+ this->public.crypter_interface.get_block_size = (size_t (*) (crypter_t *)) get_block_size;
+ this->public.crypter_interface.get_key_size = (size_t (*) (crypter_t *)) get_key_size;
+ this->public.crypter_interface.set_key = (void (*) (crypter_t *,chunk_t)) set_key;
+ this->public.crypter_interface.destroy = (void (*) (crypter_t *)) destroy;
+
+ return &this->public;
+}
diff --git a/src/libstrongswan/plugins/padlock/padlock_aes_crypter.h b/src/libstrongswan/plugins/padlock/padlock_aes_crypter.h
new file mode 100644
index 000000000..e8b01633d
--- /dev/null
+++ b/src/libstrongswan/plugins/padlock/padlock_aes_crypter.h
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2008 Thomas Kallenberg
+ * Copyright (C) 2008 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.
+ */
+
+/**
+ * @defgroup padlock_aes_crypter padlock_aes_crypter
+ * @{ @ingroup padlock_p
+ */
+
+#ifndef PADLOCK_AES_CRYPTER_H_
+#define PADLOCK_AES_CRYPTER_H_
+
+typedef struct padlock_aes_crypter_t padlock_aes_crypter_t;
+
+#include <crypto/crypters/crypter.h>
+
+/**
+ * Implementation of AES-128 using VIA Padlock.
+ */
+struct padlock_aes_crypter_t {
+
+ /**
+ * The crypter_t interface.
+ */
+ crypter_t crypter_interface;
+};
+
+/**
+ * Constructor to create padlock_aes_crypter_t.
+ *
+ * @param key_size key size in bytes, currently supports only 16.
+ * @param algo algorithm to implement, must be ENCR_AES_CBC
+ * @return padlock_aes_crypter_t, NULL if not supported
+ */
+padlock_aes_crypter_t *padlock_aes_crypter_create(encryption_algorithm_t algo,
+ size_t key_size);
+
+#endif /* PADLOCK_AES_CRYPTER_H_ @}*/
diff --git a/src/libstrongswan/plugins/padlock/padlock_plugin.c b/src/libstrongswan/plugins/padlock/padlock_plugin.c
new file mode 100644
index 000000000..822acc4a2
--- /dev/null
+++ b/src/libstrongswan/plugins/padlock/padlock_plugin.c
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2008 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.
+ *
+ * $Id$
+ */
+
+#include "padlock_plugin.h"
+
+#include <library.h>
+#include "padlock_aes_crypter.h"
+#include "padlock_sha1_hasher.h"
+
+typedef struct private_padlock_plugin_t private_padlock_plugin_t;
+
+/**
+ * private data of aes_plugin
+ */
+struct private_padlock_plugin_t {
+
+ /**
+ * public functions
+ */
+ padlock_plugin_t public;
+};
+
+/**
+ * Implementation of aes_plugin_t.destroy
+ */
+static void destroy(private_padlock_plugin_t *this)
+{
+ lib->crypto->remove_crypter(lib->crypto,
+ (crypter_constructor_t)padlock_aes_crypter_create);
+ lib->crypto->remove_hasher(lib->crypto,
+ (hasher_constructor_t)padlock_sha1_hasher_create);
+ free(this);
+}
+
+/*
+ * see header file
+ */
+plugin_t *plugin_create()
+{
+ private_padlock_plugin_t *this = malloc_thing(private_padlock_plugin_t);
+
+ this->public.plugin.destroy = (void(*)(plugin_t*))destroy;
+
+ lib->crypto->add_crypter(lib->crypto, ENCR_AES_CBC,
+ (crypter_constructor_t)padlock_aes_crypter_create);
+ lib->crypto->add_hasher(lib->crypto, HASH_SHA1,
+ (hasher_constructor_t)padlock_sha1_hasher_create);
+
+ return &this->public.plugin;
+}
diff --git a/src/libstrongswan/plugins/padlock/padlock_plugin.h b/src/libstrongswan/plugins/padlock/padlock_plugin.h
new file mode 100644
index 000000000..7e013a5f7
--- /dev/null
+++ b/src/libstrongswan/plugins/padlock/padlock_plugin.h
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2008 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.
+ */
+
+/**
+ * @defgroup padlock_p padlock
+ * @ingroup plugins
+ *
+ * @defgroup padlock_plugin padlock_plugin
+ * @{ @ingroup padlock_p
+ */
+
+#ifndef PADLOCK_PLUGIN_H_
+#define PADLOCK_PLUGIN_H_
+
+#include <plugins/plugin.h>
+
+typedef struct padlock_plugin_t padlock_plugin_t;
+
+/**
+ * Plugin implementing VIA Padlock crypto functions
+ */
+struct padlock_plugin_t {
+
+ /**
+ * implements plugin interface
+ */
+ plugin_t plugin;
+};
+
+/**
+ * Create a padlock_plugin instance.
+ */
+plugin_t *plugin_create();
+
+#endif /* PADLOCK_PLUGIN_H_ @}*/
diff --git a/src/libstrongswan/plugins/padlock/padlock_sha1_hasher.c b/src/libstrongswan/plugins/padlock/padlock_sha1_hasher.c
new file mode 100644
index 000000000..4ac5ddf4d
--- /dev/null
+++ b/src/libstrongswan/plugins/padlock/padlock_sha1_hasher.c
@@ -0,0 +1,177 @@
+/*
+ * Copyright (C) 2008 Thomas Kallenberg
+ * Copyright (C) 2008 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.
+ *
+ * $Id$
+ */
+
+#include <string.h>
+#include <arpa/inet.h>
+#include <byteswap.h>
+
+#include "padlock_sha1_hasher.h"
+
+#define PADLOCK_ALIGN __attribute__ ((__aligned__(16)))
+
+typedef struct private_padlock_sha1_hasher_t private_padlock_sha1_hasher_t;
+
+/**
+ * Private data structure with hasing context.
+ */
+struct private_padlock_sha1_hasher_t {
+ /**
+ * Public interface for this hasher.
+ */
+ padlock_sha1_hasher_t public;
+
+ /**
+ * data collected to hash
+ */
+ chunk_t data;
+};
+
+/**
+ * Invoke the actual padlock sha1() operation
+ */
+static void padlock_sha1(int len, u_char *in, u_char *out)
+{
+ /* rep xsha1 */
+ asm volatile (
+ ".byte 0xf3, 0x0f, 0xa6, 0xc8"
+ : "+S"(in), "+D"(out)
+ : "c"(len), "a"(0));
+}
+
+/**
+ * sha1() a buffer of data into digest
+ */
+static void sha1(chunk_t data, u_int32_t *digest)
+{
+ u_int32_t hash[128] PADLOCK_ALIGN;
+
+ hash[0] = 0x67452301;
+ hash[1] = 0xefcdab89;
+ hash[2] = 0x98badcfe;
+ hash[3] = 0x10325476;
+ hash[4] = 0xc3d2e1f0;
+
+ padlock_sha1(data.len, data.ptr, (u_char*)hash);
+
+ digest[0] = bswap_32(hash[0]);
+ digest[1] = bswap_32(hash[1]);
+ digest[2] = bswap_32(hash[2]);
+ digest[3] = bswap_32(hash[3]);
+ digest[4] = bswap_32(hash[4]);
+}
+
+/**
+ * append data to the to-be-hashed buffer
+ */
+static void append_data(private_padlock_sha1_hasher_t *this, chunk_t data)
+{
+ this->data.ptr = realloc(this->data.ptr, this->data.len + data.len);
+ memcpy(this->data.ptr + this->data.len, data.ptr, data.len);
+ this->data.len += data.len;
+}
+
+/**
+ * Implementation of hasher_t.reset.
+ */
+static void reset(private_padlock_sha1_hasher_t *this)
+{
+ chunk_free(&this->data);
+}
+
+/**
+ * Implementation of hasher_t.get_hash.
+ */
+static void get_hash(private_padlock_sha1_hasher_t *this, chunk_t chunk,
+ u_int8_t *hash)
+{
+ if (hash)
+ {
+ if (this->data.len)
+ {
+ append_data(this, chunk);
+ sha1(this->data, (u_int32_t*)hash);
+ }
+ else
+ { /* hash directly if no previous data found */
+ sha1(chunk, (u_int32_t*)hash);
+ }
+ reset(this);
+ }
+ else
+ {
+ append_data(this, chunk);
+ }
+}
+
+/**
+ * Implementation of hasher_t.allocate_hash.
+ */
+static void allocate_hash(private_padlock_sha1_hasher_t *this, chunk_t chunk,
+ chunk_t *hash)
+{
+ if (hash)
+ {
+ *hash = chunk_alloc(HASH_SIZE_SHA1);
+ get_hash(this, chunk, hash->ptr);
+ }
+ else
+ {
+ get_hash(this, chunk, NULL);
+ }
+}
+
+/**
+ * Implementation of hasher_t.get_hash_size.
+ */
+static size_t get_hash_size(private_padlock_sha1_hasher_t *this)
+{
+ return HASH_SIZE_SHA1;
+}
+
+/**
+ * Implementation of hasher_t.destroy.
+ */
+static void destroy(private_padlock_sha1_hasher_t *this)
+{
+ free(this->data.ptr);
+ free(this);
+}
+
+/*
+ * Described in header.
+ */
+padlock_sha1_hasher_t *padlock_sha1_hasher_create(hash_algorithm_t algo)
+{
+ private_padlock_sha1_hasher_t *this;
+
+ if (algo != HASH_SHA1)
+ {
+ return NULL;
+ }
+
+ this = malloc_thing(private_padlock_sha1_hasher_t);
+ this->public.hasher_interface.get_hash = (void (*) (hasher_t*, chunk_t, u_int8_t*))get_hash;
+ this->public.hasher_interface.allocate_hash = (void (*) (hasher_t*, chunk_t, chunk_t*))allocate_hash;
+ this->public.hasher_interface.get_hash_size = (size_t (*) (hasher_t*))get_hash_size;
+ this->public.hasher_interface.reset = (void (*) (hasher_t*))reset;
+ this->public.hasher_interface.destroy = (void (*) (hasher_t*))destroy;
+
+ this->data = chunk_empty;
+
+ return &(this->public);
+}
diff --git a/src/libstrongswan/plugins/padlock/padlock_sha1_hasher.h b/src/libstrongswan/plugins/padlock/padlock_sha1_hasher.h
new file mode 100644
index 000000000..6855b827f
--- /dev/null
+++ b/src/libstrongswan/plugins/padlock/padlock_sha1_hasher.h
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2008 Thomas Kallenberg
+ * Copyright (C) 2008 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.
+ */
+
+/**
+ * @defgroup sha1_hasher sha1_hasher
+ * @{ @ingroup sha1_p
+ */
+
+#ifndef PADLOCK_SHA1_HASHER_H_
+#define PADLOCK_SHA1_HASHER_H_
+
+typedef struct padlock_sha1_hasher_t padlock_sha1_hasher_t;
+
+#include <crypto/hashers/hasher.h>
+
+/**
+ * Implementation of hasher_t interface using the SHA1 algorithm.
+ */
+struct padlock_sha1_hasher_t {
+
+ /**
+ * Implements hasher_t interface.
+ */
+ hasher_t hasher_interface;
+};
+
+/**
+ * Creates a new sha1_hasher_t.
+ *
+ * @param algo algorithm, must be HASH_SHA1
+ * @return sha1_hasher_t object
+ */
+padlock_sha1_hasher_t *padlock_sha1_hasher_create(hash_algorithm_t algo);
+
+#endif /*SHA1_HASHER_H_ @}*/
diff --git a/src/libstrongswan/plugins/plugin.h b/src/libstrongswan/plugins/plugin.h
new file mode 100644
index 000000000..cf0b728a3
--- /dev/null
+++ b/src/libstrongswan/plugins/plugin.h
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2008 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.
+ */
+
+/**
+ * @defgroup plugin plugin
+ * @{ @ingroup plugins
+ */
+
+#ifndef PLUGIN_H_
+#define PLUGIN_H_
+
+typedef struct plugin_t plugin_t;
+
+/**
+ * Interface definition of a plugin.
+ */
+struct plugin_t {
+
+ /**
+ * Destroy a plugin instance.
+ */
+ void (*destroy)(plugin_t *this);
+};
+
+
+/**
+ * Plugin constructor function definiton.
+ *
+ * Each plugin has a constructor functions. This function is called on daemon
+ * startup to initialize each plugin.
+ * The plugin function is named plugin_create().
+ *
+ * @return plugin_t instance
+ */
+typedef plugin_t *(*plugin_constructor_t)(void);
+
+#endif /* PLUGIN_H_ @}*/
diff --git a/src/libstrongswan/plugins/plugin_loader.c b/src/libstrongswan/plugins/plugin_loader.c
new file mode 100644
index 000000000..4c5095e4a
--- /dev/null
+++ b/src/libstrongswan/plugins/plugin_loader.c
@@ -0,0 +1,193 @@
+/*
+ * 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.
+ *
+ * $Id: plugin_loader.c 4108 2008-06-25 14:53:49Z martin $
+ */
+
+#define _GNU_SOURCE
+#include "plugin_loader.h"
+
+#include <string.h>
+#include <dlfcn.h>
+#include <limits.h>
+#include <stdio.h>
+
+#include <debug.h>
+#include <utils/linked_list.h>
+#include <plugins/plugin.h>
+
+typedef struct private_plugin_loader_t private_plugin_loader_t;
+
+/**
+ * private data of plugin_loader
+ */
+struct private_plugin_loader_t {
+
+ /**
+ * public functions
+ */
+ plugin_loader_t public;
+
+ /**
+ * list of loaded plugins
+ */
+ linked_list_t *plugins;
+
+ /**
+ * names of loaded plugins
+ */
+ linked_list_t *names;
+};
+
+/**
+ * load a single plugin
+ */
+static plugin_t* load_plugin(private_plugin_loader_t *this,
+ char *path, char *name)
+{
+ char file[PATH_MAX];
+ void *handle;
+ plugin_t *plugin;
+ plugin_constructor_t constructor;
+
+ snprintf(file, sizeof(file), "%s/libstrongswan-%s.so", path, name);
+
+ handle = dlopen(file, RTLD_LAZY);
+ if (handle == NULL)
+ {
+ DBG1("loading plugin '%s' failed: %s", name, dlerror());
+ return NULL;
+ }
+ constructor = dlsym(handle, "plugin_create");
+ if (constructor == NULL)
+ {
+ DBG1("loading plugin '%s' failed: no plugin_create() function", name);
+ dlclose(handle);
+ return NULL;
+ }
+ plugin = constructor();
+ if (plugin == NULL)
+ {
+ DBG1("loading plugin '%s' failed: plugin_create() returned NULL", name);
+ dlclose(handle);
+ return NULL;
+ }
+ DBG2("plugin '%s' loaded successfully", name);
+
+ /* we do not store or free dlopen() handles, leak_detective requires
+ * the modules to keep loaded until leak report */
+ return plugin;
+}
+
+/**
+ * Implementation of plugin_loader_t.load_plugins.
+ */
+static int load(private_plugin_loader_t *this, char *path, char *list)
+{
+ plugin_t *plugin;
+ char *pos;
+ int count = 0;
+
+ list = strdupa(list);
+ while (TRUE)
+ {
+ /* eat any whitespace in front */
+ while (*list == ' ')
+ {
+ list++;
+ }
+ /* have we reached the end of the list? */
+ if (!*list)
+ {
+ break;
+ }
+ pos = strchr(list, ' ');
+ if (pos)
+ {
+ *pos++ = '\0';
+ }
+ plugin = load_plugin(this, path, list);
+ if (plugin)
+ { /* insert in front to destroy them in reverse order */
+ this->plugins->insert_last(this->plugins, plugin);
+ this->names->insert_last(this->names, strdup(list));
+ count++;
+ }
+ if (pos)
+ {
+ list = pos;
+ }
+ else
+ {
+ break;
+ }
+ }
+ return count;
+}
+
+/**
+ * Implementation of plugin_loader_t.unload
+ */
+static void unload(private_plugin_loader_t *this)
+{
+ plugin_t *plugin;
+ char *name;
+
+ while (this->plugins->remove_first(this->plugins,
+ (void**)&plugin) == SUCCESS)
+ {
+ plugin->destroy(plugin);
+ }
+ while (this->names->remove_first(this->names, (void**)&name) == SUCCESS)
+ {
+ free(name);
+ }
+}
+
+/**
+ * Implementation of plugin_loader_t.create_plugin_enumerator
+ */
+static enumerator_t* create_plugin_enumerator(private_plugin_loader_t *this)
+{
+ return this->names->create_enumerator(this->names);
+}
+
+/**
+ * Implementation of plugin_loader_t.destroy
+ */
+static void destroy(private_plugin_loader_t *this)
+{
+ this->plugins->destroy_offset(this->plugins, offsetof(plugin_t, destroy));
+ this->names->destroy_function(this->names, free);
+ free(this);
+}
+
+/*
+ * see header file
+ */
+plugin_loader_t *plugin_loader_create()
+{
+ private_plugin_loader_t *this = malloc_thing(private_plugin_loader_t);
+
+ this->public.load = (int(*)(plugin_loader_t*, char *path, char *prefix))load;
+ this->public.unload = (void(*)(plugin_loader_t*))unload;
+ this->public.create_plugin_enumerator = (enumerator_t*(*)(plugin_loader_t*))create_plugin_enumerator;
+ this->public.destroy = (void(*)(plugin_loader_t*))destroy;
+
+ this->plugins = linked_list_create();
+ this->names = linked_list_create();
+
+ return &this->public;
+}
+
diff --git a/src/libstrongswan/plugins/plugin_loader.h b/src/libstrongswan/plugins/plugin_loader.h
new file mode 100644
index 000000000..bd24e7558
--- /dev/null
+++ b/src/libstrongswan/plugins/plugin_loader.h
@@ -0,0 +1,67 @@
+/*
+ * 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.
+ */
+
+/**
+ * @defgroup plugin_loader plugin_loader
+ * @{ @ingroup plugin
+ */
+
+#ifndef PLUGIN_LOADER_H_
+#define PLUGIN_LOADER_H_
+
+typedef struct plugin_loader_t plugin_loader_t;
+
+#include <utils/enumerator.h>
+
+/**
+ * The plugin_loader loads plugins from a directory and initializes them
+ */
+struct plugin_loader_t {
+
+ /**
+ * Load a list of plugins from a directory.
+ *
+ * @param path path containing loadable plugins
+ * @param list space separated list of plugins to load
+ * @return number of successfully loaded plugins
+ */
+ int (*load)(plugin_loader_t *this, char *path, char *list);
+
+ /**
+ * Unload all loaded plugins.
+ */
+ void (*unload)(plugin_loader_t *this);
+
+ /**
+ * Create an enumerator over all loaded plugin names.
+ *
+ * @return enumerator over char*
+ */
+ enumerator_t* (*create_plugin_enumerator)(plugin_loader_t *this);
+
+ /**
+ * Unload loaded plugins, destroy plugin_loader instance.
+ */
+ void (*destroy)(plugin_loader_t *this);
+};
+
+/**
+ * Create a plugin_loader instance.
+ *
+ * @return plugin loader instance
+ */
+plugin_loader_t *plugin_loader_create();
+
+#endif /* PLUGIN_LOADER_H_ @}*/
diff --git a/src/libstrongswan/plugins/pubkey/Makefile.am b/src/libstrongswan/plugins/pubkey/Makefile.am
new file mode 100644
index 000000000..3b512614f
--- /dev/null
+++ b/src/libstrongswan/plugins/pubkey/Makefile.am
@@ -0,0 +1,13 @@
+
+INCLUDES = -I$(top_srcdir)/src/libstrongswan
+
+AM_CFLAGS = -rdynamic
+
+plugin_LTLIBRARIES = libstrongswan-pubkey.la
+
+libstrongswan_pubkey_la_SOURCES = pubkey_plugin.h pubkey_plugin.c \
+ pubkey_cert.h pubkey_cert.c\
+ pubkey_public_key.h pubkey_public_key.c
+
+libstrongswan_pubkey_la_LDFLAGS = -module
+
diff --git a/src/libstrongswan/plugins/pubkey/Makefile.in b/src/libstrongswan/plugins/pubkey/Makefile.in
new file mode 100644
index 000000000..ced339d15
--- /dev/null
+++ b/src/libstrongswan/plugins/pubkey/Makefile.in
@@ -0,0 +1,500 @@
+# Makefile.in generated by automake 1.10.1 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+VPATH = @srcdir@
+pkgdatadir = $(datadir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+subdir = src/libstrongswan/plugins/pubkey
+DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/configure.in
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+mkinstalldirs = $(install_sh) -d
+CONFIG_CLEAN_FILES =
+am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
+am__vpath_adj = case $$p in \
+ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
+ *) f=$$p;; \
+ esac;
+am__strip_dir = `echo $$p | sed -e 's|^.*/||'`;
+am__installdirs = "$(DESTDIR)$(plugindir)"
+pluginLTLIBRARIES_INSTALL = $(INSTALL)
+LTLIBRARIES = $(plugin_LTLIBRARIES)
+libstrongswan_pubkey_la_LIBADD =
+am_libstrongswan_pubkey_la_OBJECTS = pubkey_plugin.lo pubkey_cert.lo \
+ pubkey_public_key.lo
+libstrongswan_pubkey_la_OBJECTS = \
+ $(am_libstrongswan_pubkey_la_OBJECTS)
+libstrongswan_pubkey_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(libstrongswan_pubkey_la_LDFLAGS) $(LDFLAGS) -o $@
+DEFAULT_INCLUDES = -I.@am__isrc@
+depcomp = $(SHELL) $(top_srcdir)/depcomp
+am__depfiles_maybe = depfiles
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+ --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
+ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+CCLD = $(CC)
+LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+ --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \
+ $(LDFLAGS) -o $@
+SOURCES = $(libstrongswan_pubkey_la_SOURCES)
+DIST_SOURCES = $(libstrongswan_pubkey_la_SOURCES)
+ETAGS = etags
+CTAGS = ctags
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+AMTAR = @AMTAR@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CXX = @CXX@
+CXXCPP = @CXXCPP@
+CXXDEPMODE = @CXXDEPMODE@
+CXXFLAGS = @CXXFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DSYMUTIL = @DSYMUTIL@
+ECHO = @ECHO@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+F77 = @F77@
+FFLAGS = @FFLAGS@
+GPERF = @GPERF@
+GREP = @GREP@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+IPSEC_ROUTING_TABLE = @IPSEC_ROUTING_TABLE@
+IPSEC_ROUTING_TABLE_PRIO = @IPSEC_ROUTING_TABLE_PRIO@
+LDFLAGS = @LDFLAGS@
+LEX = @LEX@
+LEXLIB = @LEXLIB@
+LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LINUX_HEADERS = @LINUX_HEADERS@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+MAKEINFO = @MAKEINFO@
+MKDIR_P = @MKDIR_P@
+NMEDIT = @NMEDIT@
+OBJEXT = @OBJEXT@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PERL = @PERL@
+PKG_CONFIG = @PKG_CONFIG@
+RANLIB = @RANLIB@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRIP = @STRIP@
+VERSION = @VERSION@
+YACC = @YACC@
+YFLAGS = @YFLAGS@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_CXX = @ac_ct_CXX@
+ac_ct_F77 = @ac_ct_F77@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+confdir = @confdir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+gtk_CFLAGS = @gtk_CFLAGS@
+gtk_LIBS = @gtk_LIBS@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+ipsecdir = @ipsecdir@
+ipsecgroup = @ipsecgroup@
+ipsecuser = @ipsecuser@
+libdir = @libdir@
+libexecdir = @libexecdir@
+libstrongswan_plugins = @libstrongswan_plugins@
+linuxdir = @linuxdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+piddir = @piddir@
+plugindir = @plugindir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+resolv_conf = @resolv_conf@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+simreader = @simreader@
+srcdir = @srcdir@
+strongswan_conf = @strongswan_conf@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+xml_CFLAGS = @xml_CFLAGS@
+xml_LIBS = @xml_LIBS@
+INCLUDES = -I$(top_srcdir)/src/libstrongswan
+AM_CFLAGS = -rdynamic
+plugin_LTLIBRARIES = libstrongswan-pubkey.la
+libstrongswan_pubkey_la_SOURCES = pubkey_plugin.h pubkey_plugin.c \
+ pubkey_cert.h pubkey_cert.c\
+ pubkey_public_key.h pubkey_public_key.c
+
+libstrongswan_pubkey_la_LDFLAGS = -module
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .c .lo .o .obj
+$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \
+ && exit 0; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/libstrongswan/plugins/pubkey/Makefile'; \
+ cd $(top_srcdir) && \
+ $(AUTOMAKE) --gnu src/libstrongswan/plugins/pubkey/Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+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) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(pluginLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) '$$p' '$(DESTDIR)$(plugindir)/$$f'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(pluginLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) "$$p" "$(DESTDIR)$(plugindir)/$$f"; \
+ else :; fi; \
+ done
+
+uninstall-pluginLTLIBRARIES:
+ @$(NORMAL_UNINSTALL)
+ @list='$(plugin_LTLIBRARIES)'; for p in $$list; do \
+ p=$(am__strip_dir) \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(plugindir)/$$p'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(plugindir)/$$p"; \
+ 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
+libstrongswan-pubkey.la: $(libstrongswan_pubkey_la_OBJECTS) $(libstrongswan_pubkey_la_DEPENDENCIES)
+ $(libstrongswan_pubkey_la_LINK) -rpath $(plugindir) $(libstrongswan_pubkey_la_OBJECTS) $(libstrongswan_pubkey_la_LIBADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pubkey_cert.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pubkey_plugin.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pubkey_public_key.Plo@am__quote@
+
+.c.o:
+@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(COMPILE) -c $<
+
+.c.obj:
+@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'`
+
+.c.lo:
+@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $<
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+
+ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonemtpy = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ mkid -fID $$unique
+tags: TAGS
+
+TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ tags=; \
+ here=`pwd`; \
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \
+ test -n "$$unique" || unique=$$empty_fix; \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ $$tags $$unique; \
+ fi
+ctags: CTAGS
+CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ tags=; \
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ test -z "$(CTAGS_ARGS)$$tags$$unique" \
+ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+ $$tags $$unique
+
+GTAGS:
+ here=`$(am__cd) $(top_builddir) && pwd` \
+ && cd $(top_srcdir) \
+ && gtags -i $(GTAGS_ARGS) $$here
+
+distclean-tags:
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+distdir: $(DISTFILES)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ list='$(DISTFILES)'; \
+ dist_files=`for file in $$list; do echo $$file; done | \
+ sed -e "s|^$$srcdirstrip/||;t" \
+ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+ case $$dist_files in \
+ */*) $(MKDIR_P) `echo "$$dist_files" | \
+ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+ sort -u` ;; \
+ esac; \
+ for file in $$dist_files; do \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ if test -d $$d/$$file; then \
+ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
+ fi; \
+ cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
+ else \
+ test -f $(distdir)/$$file \
+ || cp -p $$d/$$file $(distdir)/$$file \
+ || exit 1; \
+ fi; \
+ done
+check-am: all-am
+check: check-am
+all-am: Makefile $(LTLIBRARIES)
+installdirs:
+ for dir in "$(DESTDIR)$(plugindir)"; do \
+ test -z "$$dir" || $(MKDIR_P) "$$dir"; \
+ done
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ `test -z '$(STRIP)' || \
+ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+clean: clean-am
+
+clean-am: clean-generic clean-libtool clean-pluginLTLIBRARIES \
+ mostlyclean-am
+
+distclean: distclean-am
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+ distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+info: info-am
+
+info-am:
+
+install-data-am: install-pluginLTLIBRARIES
+
+install-dvi: install-dvi-am
+
+install-exec-am:
+
+install-html: install-html-am
+
+install-info: install-info-am
+
+install-man:
+
+install-pdf: install-pdf-am
+
+install-ps: install-ps-am
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic \
+ mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am: uninstall-pluginLTLIBRARIES
+
+.MAKE: install-am install-strip
+
+.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \
+ clean-libtool clean-pluginLTLIBRARIES ctags distclean \
+ distclean-compile distclean-generic distclean-libtool \
+ distclean-tags distdir dvi dvi-am html html-am info info-am \
+ install install-am install-data install-data-am install-dvi \
+ install-dvi-am install-exec install-exec-am install-html \
+ install-html-am install-info install-info-am install-man \
+ install-pdf install-pdf-am install-pluginLTLIBRARIES \
+ install-ps install-ps-am install-strip installcheck \
+ installcheck-am installdirs maintainer-clean \
+ maintainer-clean-generic mostlyclean mostlyclean-compile \
+ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
+ tags uninstall uninstall-am uninstall-pluginLTLIBRARIES
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/src/libstrongswan/plugins/pubkey/pubkey_cert.c b/src/libstrongswan/plugins/pubkey/pubkey_cert.c
new file mode 100644
index 000000000..63dffb47b
--- /dev/null
+++ b/src/libstrongswan/plugins/pubkey/pubkey_cert.c
@@ -0,0 +1,284 @@
+/*
+ * Copyright (C) 2008 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.
+ *
+ * $Id$
+ */
+
+#include "pubkey_cert.h"
+
+#include <debug.h>
+
+typedef struct private_pubkey_cert_t private_pubkey_cert_t;
+
+/**
+ * private data of pubkey_cert
+ */
+struct private_pubkey_cert_t {
+
+ /**
+ * public functions
+ */
+ pubkey_cert_t public;
+
+ /**
+ * wrapped public key
+ */
+ public_key_t *key;
+
+ /**
+ * dummy issuer id, ID_ANY
+ */
+ identification_t *issuer;
+
+ /**
+ * reference count
+ */
+ refcount_t ref;
+};
+
+/**
+ * Implementation of certificate_t.get_type
+ */
+static certificate_type_t get_type(private_pubkey_cert_t *this)
+{
+ return CERT_TRUSTED_PUBKEY;
+}
+
+/**
+ * Implementation of certificate_t.get_subject
+ */
+static identification_t* get_subject(private_pubkey_cert_t *this)
+{
+ return this->key->get_id(this->key, ID_PUBKEY_SHA1);
+}
+
+/**
+ * Implementation of certificate_t.get_issuer
+ */
+static identification_t* get_issuer(private_pubkey_cert_t *this)
+{
+ return this->issuer;
+}
+
+/**
+ * Implementation of certificate_t.has_subject.
+ */
+static id_match_t has_subject(private_pubkey_cert_t *this,
+ identification_t *subject)
+{
+ identification_t *id;
+
+ id = this->key->get_id(this->key, subject->get_type(subject));
+ if (id)
+ {
+ return id->matches(id, subject);
+ }
+ return ID_MATCH_NONE;
+}
+
+/**
+ * Implementation of certificate_t.has_subject.
+ */
+static id_match_t has_issuer(private_pubkey_cert_t *this,
+ identification_t *issuer)
+{
+ return ID_MATCH_NONE;
+}
+
+/**
+ * Implementation of certificate_t.equals.
+ */
+static bool equals(private_pubkey_cert_t *this, certificate_t *other)
+{
+ if (this == (private_pubkey_cert_t*)other)
+ {
+ return TRUE;
+ }
+ if (other->get_type(other) != CERT_TRUSTED_PUBKEY)
+ {
+ return FALSE;
+ }
+ return other->has_subject(other, this->key->get_id(this->key, ID_PUBKEY_SHA1));
+}
+
+/**
+ * Implementation of certificate_t.issued_by
+ */
+static bool issued_by(private_pubkey_cert_t *this, certificate_t *issuer)
+{
+ return equals(this, issuer);
+}
+
+/**
+ * Implementation of certificate_t.get_public_key
+ */
+static public_key_t* get_public_key(private_pubkey_cert_t *this)
+{
+ this->key->get_ref(this->key);
+ return this->key;
+}
+/**
+ * Implementation of certificate_t.get_validity.
+ */
+static bool get_validity(private_pubkey_cert_t *this, time_t *when,
+ time_t *not_before, time_t *not_after)
+{
+ if (not_before)
+ {
+ *not_before = 0;
+ }
+ if (not_after)
+ {
+ *not_after = ~0;
+ }
+ return TRUE;
+}
+
+/**
+ * Implementation of certificate_t.is_newer.
+ */
+static bool is_newer(certificate_t *this, certificate_t *that)
+{
+ return FALSE;
+}
+
+/**
+ * Implementation of certificate_t.get_encoding.
+ */
+static chunk_t get_encoding(private_pubkey_cert_t *this)
+{
+ return this->key->get_encoding(this->key);
+}
+
+/**
+ * Implementation of certificate_t.get_ref
+ */
+static private_pubkey_cert_t* get_ref(private_pubkey_cert_t *this)
+{
+ ref_get(&this->ref);
+ return this;
+}
+
+/**
+ * Implementation of pubkey_cert_t.destroy
+ */
+static void destroy(private_pubkey_cert_t *this)
+{
+ if (ref_put(&this->ref))
+ {
+ this->issuer->destroy(this->issuer);
+ this->key->destroy(this->key);
+ free(this);
+ }
+}
+
+/*
+ * see header file
+ */
+static pubkey_cert_t *pubkey_cert_create(public_key_t *key)
+{
+ private_pubkey_cert_t *this = malloc_thing(private_pubkey_cert_t);
+
+ this->public.interface.get_type = (certificate_type_t (*)(certificate_t *this))get_type;
+ this->public.interface.get_subject = (identification_t* (*)(certificate_t *this))get_subject;
+ this->public.interface.get_issuer = (identification_t* (*)(certificate_t *this))get_issuer;
+ this->public.interface.has_subject = (id_match_t (*)(certificate_t*, identification_t *subject))has_subject;
+ this->public.interface.has_issuer = (id_match_t (*)(certificate_t*, identification_t *issuer))has_issuer;
+ this->public.interface.issued_by = (bool (*)(certificate_t *this, certificate_t *issuer))issued_by;
+ this->public.interface.get_public_key = (public_key_t* (*)(certificate_t *this))get_public_key;
+ this->public.interface.get_validity = (bool (*)(certificate_t*, time_t *when, time_t *, time_t*))get_validity;
+ this->public.interface.is_newer = (bool (*)(certificate_t*,certificate_t*))is_newer;
+ this->public.interface.get_encoding = (chunk_t (*)(certificate_t*))get_encoding;
+ this->public.interface.equals = (bool (*)(certificate_t*, certificate_t *other))equals;
+ this->public.interface.get_ref = (certificate_t* (*)(certificate_t *this))get_ref;
+ this->public.interface.destroy = (void (*)(certificate_t *this))destroy;
+
+ this->ref = 1;
+ this->key = key;
+ this->issuer = identification_create_from_encoding(ID_ANY, chunk_empty);
+
+ return &this->public;
+}
+
+typedef struct private_builder_t private_builder_t;
+/**
+ * Builder implementation for key loading
+ */
+struct private_builder_t {
+ /** implements the builder interface */
+ builder_t public;
+ /** loaded public key */
+ pubkey_cert_t *key;
+};
+
+/**
+ * Implementation of builder_t.build
+ */
+static pubkey_cert_t *build(private_builder_t *this)
+{
+ pubkey_cert_t *key = this->key;
+
+ free(this);
+ return key;
+}
+
+/**
+ * Implementation of builder_t.add
+ */
+static void add(private_builder_t *this, builder_part_t part, ...)
+{
+ va_list args;
+
+ if (this->key)
+ {
+ DBG1("ignoring surplus build part %N", builder_part_names, part);
+ return;
+ }
+
+ switch (part)
+ {
+ case BUILD_PUBLIC_KEY:
+ {
+ va_start(args, part);
+ this->key = pubkey_cert_create(va_arg(args, public_key_t*));
+ va_end(args);
+ break;
+ }
+ default:
+ DBG1("ignoring unsupported build part %N", builder_part_names, part);
+ break;
+ }
+}
+
+/**
+ * Builder construction function
+ */
+builder_t *pubkey_cert_builder(certificate_type_t type)
+{
+ private_builder_t *this;
+
+ if (type != CERT_TRUSTED_PUBKEY)
+ {
+ return NULL;
+ }
+
+ this = malloc_thing(private_builder_t);
+
+ this->key = NULL;
+ this->public.add = (void(*)(builder_t *this, builder_part_t part, ...))add;
+ this->public.build = (void*(*)(builder_t *this))build;
+
+ return &this->public;
+}
+
diff --git a/src/libstrongswan/plugins/pubkey/pubkey_cert.h b/src/libstrongswan/plugins/pubkey/pubkey_cert.h
new file mode 100644
index 000000000..71ffe5099
--- /dev/null
+++ b/src/libstrongswan/plugins/pubkey/pubkey_cert.h
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2008 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.
+ *
+ * $Id$
+ */
+
+/**
+ * @defgroup pubkey_cert pubkey_cert
+ * @{ @ingroup certificates
+ */
+
+#ifndef PUBKEY_CERT_H_
+#define PUBKEY_CERT_H_
+
+#include <credentials/certificates/certificate.h>
+
+typedef struct pubkey_cert_t pubkey_cert_t;
+
+/**
+ * A trusted public key wrapped into certificate of type CERT_TRUSTED_PUBKEY.
+ */
+struct pubkey_cert_t {
+
+ /**
+ * Implements certificate_t.
+ */
+ certificate_t interface;
+};
+
+/**
+ * Create the builder for a trusted public key.
+ *
+ * The builders add() function takes BUILD_PUBLIC_KEY to enwrap.
+ *
+ * @param type type of the certificate, must be CERT_pubkey_cert
+ * @return builder instance
+ */
+builder_t *pubkey_cert_builder(certificate_type_t type);
+
+#endif /* PUBKEY_CERT_H_ @}*/
diff --git a/src/libstrongswan/plugins/pubkey/pubkey_plugin.c b/src/libstrongswan/plugins/pubkey/pubkey_plugin.c
new file mode 100644
index 000000000..dd7ac6fd1
--- /dev/null
+++ b/src/libstrongswan/plugins/pubkey/pubkey_plugin.c
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2008 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.
+ *
+ * $Id$
+ */
+
+#include "pubkey_plugin.h"
+
+#include <library.h>
+#include "pubkey_cert.h"
+#include "pubkey_public_key.h"
+
+typedef struct private_pubkey_plugin_t private_pubkey_plugin_t;
+
+/**
+ * private data of pubkey_plugin
+ */
+struct private_pubkey_plugin_t {
+
+ /**
+ * public functions
+ */
+ pubkey_plugin_t public;
+};
+
+/**
+ * Implementation of pubkey_plugin_t.pubkeytroy
+ */
+static void destroy(private_pubkey_plugin_t *this)
+{
+ lib->creds->remove_builder(lib->creds,
+ (builder_constructor_t)pubkey_cert_builder);
+ lib->creds->remove_builder(lib->creds,
+ (builder_constructor_t)pubkey_public_key_builder);
+ free(this);
+}
+
+/*
+ * see header file
+ */
+plugin_t *plugin_create()
+{
+ private_pubkey_plugin_t *this = malloc_thing(private_pubkey_plugin_t);
+
+ this->public.plugin.destroy = (void(*)(plugin_t*))destroy;
+
+ lib->creds->add_builder(lib->creds, CRED_CERTIFICATE, CERT_TRUSTED_PUBKEY,
+ (builder_constructor_t)pubkey_cert_builder);
+ lib->creds->add_builder(lib->creds, CRED_PUBLIC_KEY, KEY_ANY,
+ (builder_constructor_t)pubkey_public_key_builder);
+
+ return &this->public.plugin;
+}
+
diff --git a/src/libstrongswan/plugins/pubkey/pubkey_plugin.h b/src/libstrongswan/plugins/pubkey/pubkey_plugin.h
new file mode 100644
index 000000000..64d0995fc
--- /dev/null
+++ b/src/libstrongswan/plugins/pubkey/pubkey_plugin.h
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2008 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.
+ */
+
+/**
+ * @defgroup pubkey_p pubkey
+ * @ingroup plugins
+ *
+ * @defgroup pubkey_plugin pubkey_plugin
+ * @{ @ingroup pubkey_p
+ */
+
+#ifndef PUBKEY_PLUGIN_H_
+#define PUBKEY_PLUGIN_H_
+
+#include <plugins/plugin.h>
+
+typedef struct pubkey_plugin_t pubkey_plugin_t;
+
+/**
+ * Plugin implementing CERT_TRUSTED_PUBKEY certificate type.
+ */
+struct pubkey_plugin_t {
+
+ /**
+ * implements plugin interface
+ */
+ plugin_t plugin;
+};
+
+/**
+ * Create a pubkey_plugin instance.
+ */
+plugin_t *plugin_create();
+
+#endif /* PUBKEY_PLUGIN_H_ @}*/
diff --git a/src/libstrongswan/plugins/pubkey/pubkey_public_key.c b/src/libstrongswan/plugins/pubkey/pubkey_public_key.c
new file mode 100644
index 000000000..0527ed758
--- /dev/null
+++ b/src/libstrongswan/plugins/pubkey/pubkey_public_key.c
@@ -0,0 +1,185 @@
+/*
+ * Copyright (C) 2008 Tobias Brunner
+ * Copyright (C) 2008 Martin Willi
+ * 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
+ * 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.
+ *
+ * $Id: pubkey_public_key.c 4059 2008-06-11 14:10:02Z martin $
+ */
+
+#include "pubkey_public_key.h"
+
+#include <debug.h>
+#include <asn1/pem.h>
+#include <asn1/oid.h>
+#include <asn1/asn1.h>
+#include <asn1/asn1_parser.h>
+
+/**
+ * ASN.1 definition of a subjectPublicKeyInfo structure
+ */
+static const asn1Object_t pkinfoObjects[] = {
+ { 0, "subjectPublicKeyInfo",ASN1_SEQUENCE, ASN1_NONE }, /* 0 */
+ { 1, "algorithm", ASN1_EOC, ASN1_RAW }, /* 1 */
+ { 1, "subjectPublicKey", ASN1_BIT_STRING, ASN1_BODY }, /* 2 */
+ { 0, "exit", ASN1_EOC, ASN1_EXIT }
+};
+#define PKINFO_SUBJECT_PUBLIC_KEY_ALGORITHM 1
+#define PKINFO_SUBJECT_PUBLIC_KEY 2
+
+
+/**
+ * Load a public key from an ASN1 encoded blob
+ */
+static public_key_t *load(chunk_t blob)
+{
+ asn1_parser_t *parser;
+ chunk_t object;
+ int objectID;
+ public_key_t *key = NULL;
+ key_type_t type = KEY_ANY;
+
+ parser = asn1_parser_create(pkinfoObjects, blob);
+
+ while (parser->iterate(parser, &objectID, &object))
+ {
+ switch (objectID)
+ {
+ case PKINFO_SUBJECT_PUBLIC_KEY_ALGORITHM:
+ {
+ int oid = asn1_parse_algorithmIdentifier(object,
+ parser->get_level(parser)+1, NULL);
+
+ if (oid == OID_RSA_ENCRYPTION)
+ {
+ type = KEY_RSA;
+ }
+ else if (oid == OID_EC_PUBLICKEY)
+ {
+ /* we need the whole subjectPublicKeyInfo for EC public keys */
+ key = lib->creds->create(lib->creds,
+ CRED_PUBLIC_KEY, KEY_ECDSA, BUILD_BLOB_ASN1_DER,
+ chunk_clone(blob), BUILD_END);
+ goto end;
+ }
+ else
+ {
+ /* key type not supported */
+ goto end;
+ }
+ break;
+ }
+ case PKINFO_SUBJECT_PUBLIC_KEY:
+ if (object.len > 0 && *object.ptr == 0x00)
+ {
+ /* skip initial bit string octet defining 0 unused bits */
+ object = chunk_skip(object, 1);
+ }
+ key = lib->creds->create(lib->creds, CRED_PUBLIC_KEY, type,
+ BUILD_BLOB_ASN1_DER, chunk_clone(object),
+ BUILD_END);
+ break;
+ }
+ }
+
+end:
+ parser->destroy(parser);
+ free(blob.ptr);
+ return key;
+}
+
+typedef struct private_builder_t private_builder_t;
+/**
+ * Builder implementation for key loading
+ */
+struct private_builder_t {
+ /** implements the builder interface */
+ builder_t public;
+ /** loaded public key */
+ public_key_t *key;
+};
+
+/**
+ * Implementation of builder_t.build
+ */
+static public_key_t *build(private_builder_t *this)
+{
+ public_key_t *key = this->key;
+
+ free(this);
+ return key;
+}
+
+/**
+ * Implementation of builder_t.add
+ */
+static void add(private_builder_t *this, builder_part_t part, ...)
+{
+ va_list args;
+
+ if (this->key)
+ {
+ DBG1("ignoring surplus build part %N", builder_part_names, part);
+ return;
+ }
+ va_start(args, part);
+ switch (part)
+ {
+ case BUILD_BLOB_ASN1_DER:
+ {
+ this->key = load(va_arg(args, chunk_t));
+ break;
+ }
+ case BUILD_BLOB_ASN1_PEM:
+ {
+ bool pgp;
+ char *pem;
+ chunk_t blob;
+
+ pem = va_arg(args, char *);
+ blob = chunk_clone(chunk_create(pem, strlen(pem)));
+ if (pem_to_bin(&blob, &chunk_empty, &pgp))
+ {
+ this->key = load(chunk_clone(blob));
+ }
+ free(blob.ptr);
+ break;
+ }
+ default:
+ DBG1("ignoring unsupported build part %N", builder_part_names, part);
+ break;
+ }
+ va_end(args);
+}
+
+/**
+ * Builder construction function
+ */
+builder_t *pubkey_public_key_builder(key_type_t type)
+{
+ private_builder_t *this;
+
+ if (type != KEY_ANY)
+ {
+ return NULL;
+ }
+
+ this = malloc_thing(private_builder_t);
+
+ this->key = NULL;
+ this->public.add = (void(*)(builder_t *this, builder_part_t part, ...))add;
+ this->public.build = (void*(*)(builder_t *this))build;
+
+ return &this->public;
+}
+
diff --git a/src/libstrongswan/plugins/pubkey/pubkey_public_key.h b/src/libstrongswan/plugins/pubkey/pubkey_public_key.h
new file mode 100644
index 000000000..914ad74e9
--- /dev/null
+++ b/src/libstrongswan/plugins/pubkey/pubkey_public_key.h
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2008 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.
+ *
+ * $Id: pubkey_public_key.h 3961 2008-05-15 12:33:00Z tobias $
+ */
+
+/**
+ * @defgroup pubkey_public_key pubkey_public_key
+ * @{ @ingroup pubkey_p
+ */
+
+#ifndef PUBKEY_PUBLIC_KEY_H_
+#define PUBKEY_PUBLIC_KEY_H_
+
+#include <credentials/keys/public_key.h>
+
+/**
+ * Create the builder for a generic public key.
+ *
+ * @param type type of the key, must be KEY_ANY
+ * @return builder instance
+ */
+builder_t *pubkey_public_key_builder(key_type_t type);
+
+#endif /*PUBKEY_RSA_PUBLIC_KEY_H_ @}*/
diff --git a/src/libstrongswan/plugins/random/Makefile.am b/src/libstrongswan/plugins/random/Makefile.am
new file mode 100644
index 000000000..8b61d7094
--- /dev/null
+++ b/src/libstrongswan/plugins/random/Makefile.am
@@ -0,0 +1,11 @@
+
+INCLUDES = -I$(top_srcdir)/src/libstrongswan
+
+AM_CFLAGS = -rdynamic
+
+plugin_LTLIBRARIES = libstrongswan-random.la
+
+libstrongswan_random_la_SOURCES = random_plugin.h random_plugin.c \
+ random_rng.c random_rng.h
+libstrongswan_random_la_LDFLAGS = -module
+
diff --git a/src/libstrongswan/plugins/random/Makefile.in b/src/libstrongswan/plugins/random/Makefile.in
new file mode 100644
index 000000000..c4baa04b3
--- /dev/null
+++ b/src/libstrongswan/plugins/random/Makefile.in
@@ -0,0 +1,497 @@
+# Makefile.in generated by automake 1.10.1 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+VPATH = @srcdir@
+pkgdatadir = $(datadir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+subdir = src/libstrongswan/plugins/random
+DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/configure.in
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+mkinstalldirs = $(install_sh) -d
+CONFIG_CLEAN_FILES =
+am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
+am__vpath_adj = case $$p in \
+ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
+ *) f=$$p;; \
+ esac;
+am__strip_dir = `echo $$p | sed -e 's|^.*/||'`;
+am__installdirs = "$(DESTDIR)$(plugindir)"
+pluginLTLIBRARIES_INSTALL = $(INSTALL)
+LTLIBRARIES = $(plugin_LTLIBRARIES)
+libstrongswan_random_la_LIBADD =
+am_libstrongswan_random_la_OBJECTS = random_plugin.lo random_rng.lo
+libstrongswan_random_la_OBJECTS = \
+ $(am_libstrongswan_random_la_OBJECTS)
+libstrongswan_random_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(libstrongswan_random_la_LDFLAGS) $(LDFLAGS) -o $@
+DEFAULT_INCLUDES = -I.@am__isrc@
+depcomp = $(SHELL) $(top_srcdir)/depcomp
+am__depfiles_maybe = depfiles
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+ --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
+ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+CCLD = $(CC)
+LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+ --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \
+ $(LDFLAGS) -o $@
+SOURCES = $(libstrongswan_random_la_SOURCES)
+DIST_SOURCES = $(libstrongswan_random_la_SOURCES)
+ETAGS = etags
+CTAGS = ctags
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+AMTAR = @AMTAR@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CXX = @CXX@
+CXXCPP = @CXXCPP@
+CXXDEPMODE = @CXXDEPMODE@
+CXXFLAGS = @CXXFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DSYMUTIL = @DSYMUTIL@
+ECHO = @ECHO@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+F77 = @F77@
+FFLAGS = @FFLAGS@
+GPERF = @GPERF@
+GREP = @GREP@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+IPSEC_ROUTING_TABLE = @IPSEC_ROUTING_TABLE@
+IPSEC_ROUTING_TABLE_PRIO = @IPSEC_ROUTING_TABLE_PRIO@
+LDFLAGS = @LDFLAGS@
+LEX = @LEX@
+LEXLIB = @LEXLIB@
+LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LINUX_HEADERS = @LINUX_HEADERS@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+MAKEINFO = @MAKEINFO@
+MKDIR_P = @MKDIR_P@
+NMEDIT = @NMEDIT@
+OBJEXT = @OBJEXT@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PERL = @PERL@
+PKG_CONFIG = @PKG_CONFIG@
+RANLIB = @RANLIB@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRIP = @STRIP@
+VERSION = @VERSION@
+YACC = @YACC@
+YFLAGS = @YFLAGS@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_CXX = @ac_ct_CXX@
+ac_ct_F77 = @ac_ct_F77@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+confdir = @confdir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+gtk_CFLAGS = @gtk_CFLAGS@
+gtk_LIBS = @gtk_LIBS@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+ipsecdir = @ipsecdir@
+ipsecgroup = @ipsecgroup@
+ipsecuser = @ipsecuser@
+libdir = @libdir@
+libexecdir = @libexecdir@
+libstrongswan_plugins = @libstrongswan_plugins@
+linuxdir = @linuxdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+piddir = @piddir@
+plugindir = @plugindir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+resolv_conf = @resolv_conf@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+simreader = @simreader@
+srcdir = @srcdir@
+strongswan_conf = @strongswan_conf@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+xml_CFLAGS = @xml_CFLAGS@
+xml_LIBS = @xml_LIBS@
+INCLUDES = -I$(top_srcdir)/src/libstrongswan
+AM_CFLAGS = -rdynamic
+plugin_LTLIBRARIES = libstrongswan-random.la
+libstrongswan_random_la_SOURCES = random_plugin.h random_plugin.c \
+ random_rng.c random_rng.h
+
+libstrongswan_random_la_LDFLAGS = -module
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .c .lo .o .obj
+$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \
+ && exit 0; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/libstrongswan/plugins/random/Makefile'; \
+ cd $(top_srcdir) && \
+ $(AUTOMAKE) --gnu src/libstrongswan/plugins/random/Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+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) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(pluginLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) '$$p' '$(DESTDIR)$(plugindir)/$$f'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(pluginLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) "$$p" "$(DESTDIR)$(plugindir)/$$f"; \
+ else :; fi; \
+ done
+
+uninstall-pluginLTLIBRARIES:
+ @$(NORMAL_UNINSTALL)
+ @list='$(plugin_LTLIBRARIES)'; for p in $$list; do \
+ p=$(am__strip_dir) \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(plugindir)/$$p'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(plugindir)/$$p"; \
+ 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
+libstrongswan-random.la: $(libstrongswan_random_la_OBJECTS) $(libstrongswan_random_la_DEPENDENCIES)
+ $(libstrongswan_random_la_LINK) -rpath $(plugindir) $(libstrongswan_random_la_OBJECTS) $(libstrongswan_random_la_LIBADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/random_plugin.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/random_rng.Plo@am__quote@
+
+.c.o:
+@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(COMPILE) -c $<
+
+.c.obj:
+@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'`
+
+.c.lo:
+@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $<
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+
+ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonemtpy = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ mkid -fID $$unique
+tags: TAGS
+
+TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ tags=; \
+ here=`pwd`; \
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \
+ test -n "$$unique" || unique=$$empty_fix; \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ $$tags $$unique; \
+ fi
+ctags: CTAGS
+CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ tags=; \
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ test -z "$(CTAGS_ARGS)$$tags$$unique" \
+ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+ $$tags $$unique
+
+GTAGS:
+ here=`$(am__cd) $(top_builddir) && pwd` \
+ && cd $(top_srcdir) \
+ && gtags -i $(GTAGS_ARGS) $$here
+
+distclean-tags:
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+distdir: $(DISTFILES)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ list='$(DISTFILES)'; \
+ dist_files=`for file in $$list; do echo $$file; done | \
+ sed -e "s|^$$srcdirstrip/||;t" \
+ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+ case $$dist_files in \
+ */*) $(MKDIR_P) `echo "$$dist_files" | \
+ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+ sort -u` ;; \
+ esac; \
+ for file in $$dist_files; do \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ if test -d $$d/$$file; then \
+ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
+ fi; \
+ cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
+ else \
+ test -f $(distdir)/$$file \
+ || cp -p $$d/$$file $(distdir)/$$file \
+ || exit 1; \
+ fi; \
+ done
+check-am: all-am
+check: check-am
+all-am: Makefile $(LTLIBRARIES)
+installdirs:
+ for dir in "$(DESTDIR)$(plugindir)"; do \
+ test -z "$$dir" || $(MKDIR_P) "$$dir"; \
+ done
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ `test -z '$(STRIP)' || \
+ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+clean: clean-am
+
+clean-am: clean-generic clean-libtool clean-pluginLTLIBRARIES \
+ mostlyclean-am
+
+distclean: distclean-am
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+ distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+info: info-am
+
+info-am:
+
+install-data-am: install-pluginLTLIBRARIES
+
+install-dvi: install-dvi-am
+
+install-exec-am:
+
+install-html: install-html-am
+
+install-info: install-info-am
+
+install-man:
+
+install-pdf: install-pdf-am
+
+install-ps: install-ps-am
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic \
+ mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am: uninstall-pluginLTLIBRARIES
+
+.MAKE: install-am install-strip
+
+.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \
+ clean-libtool clean-pluginLTLIBRARIES ctags distclean \
+ distclean-compile distclean-generic distclean-libtool \
+ distclean-tags distdir dvi dvi-am html html-am info info-am \
+ install install-am install-data install-data-am install-dvi \
+ install-dvi-am install-exec install-exec-am install-html \
+ install-html-am install-info install-info-am install-man \
+ install-pdf install-pdf-am install-pluginLTLIBRARIES \
+ install-ps install-ps-am install-strip installcheck \
+ installcheck-am installdirs maintainer-clean \
+ maintainer-clean-generic mostlyclean mostlyclean-compile \
+ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
+ tags uninstall uninstall-am uninstall-pluginLTLIBRARIES
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/src/libstrongswan/plugins/random/random_plugin.c b/src/libstrongswan/plugins/random/random_plugin.c
new file mode 100644
index 000000000..3eff81ee0
--- /dev/null
+++ b/src/libstrongswan/plugins/random/random_plugin.c
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2008 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.
+ *
+ * $Id$
+ */
+
+#include "random_plugin.h"
+
+#include <library.h>
+#include "random_rng.h"
+
+typedef struct private_random_plugin_t private_random_plugin_t;
+
+/**
+ * private data of random_plugin
+ */
+struct private_random_plugin_t {
+
+ /**
+ * public functions
+ */
+ random_plugin_t public;
+};
+
+/**
+ * Implementation of random_plugin_t.gmptroy
+ */
+static void destroy(private_random_plugin_t *this)
+{
+ lib->crypto->remove_rng(lib->crypto,
+ (rng_constructor_t)random_rng_create);
+ free(this);
+}
+
+/*
+ * see header file
+ */
+plugin_t *plugin_create()
+{
+ private_random_plugin_t *this = malloc_thing(private_random_plugin_t);
+
+ this->public.plugin.destroy = (void(*)(plugin_t*))destroy;
+
+ lib->crypto->add_rng(lib->crypto, RNG_STRONG,
+ (rng_constructor_t)random_rng_create);
+ lib->crypto->add_rng(lib->crypto, RNG_REAL,
+ (rng_constructor_t)random_rng_create);
+
+ return &this->public.plugin;
+}
+
diff --git a/src/libstrongswan/plugins/random/random_plugin.h b/src/libstrongswan/plugins/random/random_plugin.h
new file mode 100644
index 000000000..9e8b99387
--- /dev/null
+++ b/src/libstrongswan/plugins/random/random_plugin.h
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2008 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.
+ */
+
+/**
+ * @defgroup random_p random
+ * @ingroup plugins
+ *
+ * @defgroup random_plugin random_plugin
+ * @{ @ingroup random_p
+ */
+
+#ifndef RANDOM_PLUGIN_H_
+#define RANDOM_PLUGIN_H_
+
+#include <plugins/plugin.h>
+
+typedef struct random_plugin_t random_plugin_t;
+
+/**
+ * Plugin implementing a RNG reading from /dev/[u]random.
+ */
+struct random_plugin_t {
+
+ /**
+ * implements plugin interface
+ */
+ plugin_t plugin;
+};
+
+/**
+ * Create a random_plugin instance.
+ */
+plugin_t *plugin_create();
+
+#endif /* RANDOM_PLUGIN_H_ @}*/
diff --git a/src/libstrongswan/plugins/random/random_rng.c b/src/libstrongswan/plugins/random/random_rng.c
new file mode 100644
index 000000000..1aadc88bd
--- /dev/null
+++ b/src/libstrongswan/plugins/random/random_rng.c
@@ -0,0 +1,134 @@
+/*
+ * Copyright (C) 2005-2008 Martin Willi
+ * Copyright (C) 2005 Jan Hutter
+ * 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.
+ *
+ * $Id$
+ */
+
+#include <string.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <errno.h>
+#include <debug.h>
+
+#include "random_rng.h"
+
+#ifndef DEV_RANDOM
+# define DEV_RANDOM "/dev/random"
+#endif
+
+#ifndef DEV_URANDOM
+# define DEV_URANDOM "/dev/urandom"
+#endif
+
+typedef struct private_random_rng_t private_random_rng_t;
+
+/**
+ * Private data of an random_rng_t object.
+ */
+struct private_random_rng_t {
+
+ /**
+ * Public random_rng_t interface.
+ */
+ random_rng_t public;
+
+ /**
+ * random device, depends on quality
+ */
+ int dev;
+
+ /**
+ * file we read random bytes from
+ */
+ char *file;
+};
+
+/**
+ * Implementation of random_rng_t.get_bytes.
+ */
+static void get_bytes(private_random_rng_t *this, size_t bytes,
+ u_int8_t *buffer)
+{
+ size_t done, got;
+
+ done = 0;
+
+ while (done < bytes)
+ {
+ got = read(this->dev, buffer + done, bytes - done);
+ if (got <= 0)
+ {
+ DBG1("reading from \"%s\" failed: %s, retrying...",
+ this->file, strerror(errno));
+ close(this->dev);
+ sleep(1);
+ this->dev = open(this->file, 0);
+ }
+ done += got;
+ }
+}
+
+/**
+ * Implementation of random_rng_t.allocate_bytes.
+ */
+static void allocate_bytes(private_random_rng_t *this, size_t bytes,
+ chunk_t *chunk)
+{
+ *chunk = chunk_alloc(bytes);
+ get_bytes(this, chunk->len, chunk->ptr);
+}
+
+/**
+ * Implementation of random_rng_t.destroy.
+ */
+static void destroy(private_random_rng_t *this)
+{
+ close(this->dev);
+ free(this);
+}
+
+/*
+ * Described in header.
+ */
+random_rng_t *random_rng_create(rng_quality_t quality)
+{
+ private_random_rng_t *this = malloc_thing(private_random_rng_t);
+
+ /* public functions */
+ this->public.rng.get_bytes = (void (*) (rng_t *, size_t, u_int8_t*)) get_bytes;
+ this->public.rng.allocate_bytes = (void (*) (rng_t *, size_t, chunk_t*)) allocate_bytes;
+ this->public.rng.destroy = (void (*) (rng_t *))destroy;
+
+ if (quality == RNG_REAL)
+ {
+ this->file = DEV_RANDOM;
+ }
+ else
+ {
+ this->file = DEV_URANDOM;
+ }
+
+ this->dev = open(this->file, 0);
+ if (this->dev < 0)
+ {
+ DBG1("opening \"%s\" failed: %s", this->file, strerror(errno));
+ free(this);
+ return NULL;
+ }
+ return &this->public;
+}
+
diff --git a/src/libstrongswan/plugins/random/random_rng.h b/src/libstrongswan/plugins/random/random_rng.h
new file mode 100644
index 000000000..7f82353d8
--- /dev/null
+++ b/src/libstrongswan/plugins/random/random_rng.h
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2008 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.
+ *
+ * $Id$
+ */
+
+/**
+ * @defgroup random_rng random_rng
+ * @{ @ingroup utils
+ */
+
+#ifndef RANDOM_RNG_H_
+#define RANDOM_RNG_H_
+
+typedef struct random_rng_t random_rng_t;
+
+#include <library.h>
+
+/**
+ * rng_t implementation on top of /dev/[u]random
+ */
+struct random_rng_t {
+
+ /**
+ * Implements rng_t.
+ */
+ rng_t rng;
+};
+
+/**
+ * Creates an random_rng_t instance.
+ *
+ * @param quality required quality of randomness
+ * @return created random_rng_t
+ */
+random_rng_t *random_rng_create(rng_quality_t quality);
+
+#endif /*RANDOM_RNG_H_ @} */
diff --git a/src/libstrongswan/plugins/sha1/Makefile.am b/src/libstrongswan/plugins/sha1/Makefile.am
new file mode 100644
index 000000000..299e85083
--- /dev/null
+++ b/src/libstrongswan/plugins/sha1/Makefile.am
@@ -0,0 +1,10 @@
+
+INCLUDES = -I$(top_srcdir)/src/libstrongswan
+
+AM_CFLAGS = -rdynamic
+
+plugin_LTLIBRARIES = libstrongswan-sha1.la
+
+libstrongswan_sha1_la_SOURCES = sha1_plugin.h sha1_plugin.c sha1_hasher.c sha1_hasher.h
+libstrongswan_sha1_la_LDFLAGS = -module
+
diff --git a/src/libstrongswan/plugins/sha1/Makefile.in b/src/libstrongswan/plugins/sha1/Makefile.in
new file mode 100644
index 000000000..b57c46aee
--- /dev/null
+++ b/src/libstrongswan/plugins/sha1/Makefile.in
@@ -0,0 +1,494 @@
+# Makefile.in generated by automake 1.10.1 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+VPATH = @srcdir@
+pkgdatadir = $(datadir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+subdir = src/libstrongswan/plugins/sha1
+DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/configure.in
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+mkinstalldirs = $(install_sh) -d
+CONFIG_CLEAN_FILES =
+am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
+am__vpath_adj = case $$p in \
+ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
+ *) f=$$p;; \
+ esac;
+am__strip_dir = `echo $$p | sed -e 's|^.*/||'`;
+am__installdirs = "$(DESTDIR)$(plugindir)"
+pluginLTLIBRARIES_INSTALL = $(INSTALL)
+LTLIBRARIES = $(plugin_LTLIBRARIES)
+libstrongswan_sha1_la_LIBADD =
+am_libstrongswan_sha1_la_OBJECTS = sha1_plugin.lo sha1_hasher.lo
+libstrongswan_sha1_la_OBJECTS = $(am_libstrongswan_sha1_la_OBJECTS)
+libstrongswan_sha1_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(libstrongswan_sha1_la_LDFLAGS) $(LDFLAGS) -o $@
+DEFAULT_INCLUDES = -I.@am__isrc@
+depcomp = $(SHELL) $(top_srcdir)/depcomp
+am__depfiles_maybe = depfiles
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+ --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
+ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+CCLD = $(CC)
+LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+ --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \
+ $(LDFLAGS) -o $@
+SOURCES = $(libstrongswan_sha1_la_SOURCES)
+DIST_SOURCES = $(libstrongswan_sha1_la_SOURCES)
+ETAGS = etags
+CTAGS = ctags
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+AMTAR = @AMTAR@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CXX = @CXX@
+CXXCPP = @CXXCPP@
+CXXDEPMODE = @CXXDEPMODE@
+CXXFLAGS = @CXXFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DSYMUTIL = @DSYMUTIL@
+ECHO = @ECHO@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+F77 = @F77@
+FFLAGS = @FFLAGS@
+GPERF = @GPERF@
+GREP = @GREP@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+IPSEC_ROUTING_TABLE = @IPSEC_ROUTING_TABLE@
+IPSEC_ROUTING_TABLE_PRIO = @IPSEC_ROUTING_TABLE_PRIO@
+LDFLAGS = @LDFLAGS@
+LEX = @LEX@
+LEXLIB = @LEXLIB@
+LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LINUX_HEADERS = @LINUX_HEADERS@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+MAKEINFO = @MAKEINFO@
+MKDIR_P = @MKDIR_P@
+NMEDIT = @NMEDIT@
+OBJEXT = @OBJEXT@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PERL = @PERL@
+PKG_CONFIG = @PKG_CONFIG@
+RANLIB = @RANLIB@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRIP = @STRIP@
+VERSION = @VERSION@
+YACC = @YACC@
+YFLAGS = @YFLAGS@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_CXX = @ac_ct_CXX@
+ac_ct_F77 = @ac_ct_F77@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+confdir = @confdir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+gtk_CFLAGS = @gtk_CFLAGS@
+gtk_LIBS = @gtk_LIBS@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+ipsecdir = @ipsecdir@
+ipsecgroup = @ipsecgroup@
+ipsecuser = @ipsecuser@
+libdir = @libdir@
+libexecdir = @libexecdir@
+libstrongswan_plugins = @libstrongswan_plugins@
+linuxdir = @linuxdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+piddir = @piddir@
+plugindir = @plugindir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+resolv_conf = @resolv_conf@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+simreader = @simreader@
+srcdir = @srcdir@
+strongswan_conf = @strongswan_conf@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+xml_CFLAGS = @xml_CFLAGS@
+xml_LIBS = @xml_LIBS@
+INCLUDES = -I$(top_srcdir)/src/libstrongswan
+AM_CFLAGS = -rdynamic
+plugin_LTLIBRARIES = libstrongswan-sha1.la
+libstrongswan_sha1_la_SOURCES = sha1_plugin.h sha1_plugin.c sha1_hasher.c sha1_hasher.h
+libstrongswan_sha1_la_LDFLAGS = -module
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .c .lo .o .obj
+$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \
+ && exit 0; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/libstrongswan/plugins/sha1/Makefile'; \
+ cd $(top_srcdir) && \
+ $(AUTOMAKE) --gnu src/libstrongswan/plugins/sha1/Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+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) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(pluginLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) '$$p' '$(DESTDIR)$(plugindir)/$$f'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(pluginLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) "$$p" "$(DESTDIR)$(plugindir)/$$f"; \
+ else :; fi; \
+ done
+
+uninstall-pluginLTLIBRARIES:
+ @$(NORMAL_UNINSTALL)
+ @list='$(plugin_LTLIBRARIES)'; for p in $$list; do \
+ p=$(am__strip_dir) \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(plugindir)/$$p'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(plugindir)/$$p"; \
+ 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
+libstrongswan-sha1.la: $(libstrongswan_sha1_la_OBJECTS) $(libstrongswan_sha1_la_DEPENDENCIES)
+ $(libstrongswan_sha1_la_LINK) -rpath $(plugindir) $(libstrongswan_sha1_la_OBJECTS) $(libstrongswan_sha1_la_LIBADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sha1_hasher.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sha1_plugin.Plo@am__quote@
+
+.c.o:
+@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(COMPILE) -c $<
+
+.c.obj:
+@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'`
+
+.c.lo:
+@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $<
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+
+ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonemtpy = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ mkid -fID $$unique
+tags: TAGS
+
+TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ tags=; \
+ here=`pwd`; \
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \
+ test -n "$$unique" || unique=$$empty_fix; \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ $$tags $$unique; \
+ fi
+ctags: CTAGS
+CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ tags=; \
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ test -z "$(CTAGS_ARGS)$$tags$$unique" \
+ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+ $$tags $$unique
+
+GTAGS:
+ here=`$(am__cd) $(top_builddir) && pwd` \
+ && cd $(top_srcdir) \
+ && gtags -i $(GTAGS_ARGS) $$here
+
+distclean-tags:
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+distdir: $(DISTFILES)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ list='$(DISTFILES)'; \
+ dist_files=`for file in $$list; do echo $$file; done | \
+ sed -e "s|^$$srcdirstrip/||;t" \
+ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+ case $$dist_files in \
+ */*) $(MKDIR_P) `echo "$$dist_files" | \
+ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+ sort -u` ;; \
+ esac; \
+ for file in $$dist_files; do \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ if test -d $$d/$$file; then \
+ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
+ fi; \
+ cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
+ else \
+ test -f $(distdir)/$$file \
+ || cp -p $$d/$$file $(distdir)/$$file \
+ || exit 1; \
+ fi; \
+ done
+check-am: all-am
+check: check-am
+all-am: Makefile $(LTLIBRARIES)
+installdirs:
+ for dir in "$(DESTDIR)$(plugindir)"; do \
+ test -z "$$dir" || $(MKDIR_P) "$$dir"; \
+ done
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ `test -z '$(STRIP)' || \
+ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+clean: clean-am
+
+clean-am: clean-generic clean-libtool clean-pluginLTLIBRARIES \
+ mostlyclean-am
+
+distclean: distclean-am
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+ distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+info: info-am
+
+info-am:
+
+install-data-am: install-pluginLTLIBRARIES
+
+install-dvi: install-dvi-am
+
+install-exec-am:
+
+install-html: install-html-am
+
+install-info: install-info-am
+
+install-man:
+
+install-pdf: install-pdf-am
+
+install-ps: install-ps-am
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic \
+ mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am: uninstall-pluginLTLIBRARIES
+
+.MAKE: install-am install-strip
+
+.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \
+ clean-libtool clean-pluginLTLIBRARIES ctags distclean \
+ distclean-compile distclean-generic distclean-libtool \
+ distclean-tags distdir dvi dvi-am html html-am info info-am \
+ install install-am install-data install-data-am install-dvi \
+ install-dvi-am install-exec install-exec-am install-html \
+ install-html-am install-info install-info-am install-man \
+ install-pdf install-pdf-am install-pluginLTLIBRARIES \
+ install-ps install-ps-am install-strip installcheck \
+ installcheck-am installdirs maintainer-clean \
+ maintainer-clean-generic mostlyclean mostlyclean-compile \
+ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
+ tags uninstall uninstall-am uninstall-pluginLTLIBRARIES
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/src/libstrongswan/plugins/sha1/sha1_hasher.c b/src/libstrongswan/plugins/sha1/sha1_hasher.c
new file mode 100644
index 000000000..c496be8f4
--- /dev/null
+++ b/src/libstrongswan/plugins/sha1/sha1_hasher.c
@@ -0,0 +1,366 @@
+/*
+ * Copyright (C) 2005-2006 Martin Willi
+ * Copyright (C) 2005 Jan Hutter
+ * Hochschule fuer Technik Rapperswil
+ *
+ * Ported from Steve Reid's <steve@edmweb.com> implementation
+ * "SHA1 in C" found in strongSwan.
+ *
+ * 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.
+ *
+ * $Id: sha1_hasher.c 3619 2008-03-19 14:02:52Z martin $
+ */
+
+#include <string.h>
+#include <arpa/inet.h>
+
+#include "sha1_hasher.h"
+
+/*
+ * ugly macro stuff
+ */
+#define rol(value, bits) (((value) << (bits)) | ((value) >> (32 - (bits))))
+
+#if BYTE_ORDER == LITTLE_ENDIAN
+ #define blk0(i) (block->l[i] = (rol(block->l[i],24)&0xFF00FF00) |(rol(block->l[i],8)&0x00FF00FF))
+#elif BYTE_ORDER == BIG_ENDIAN
+ #define blk0(i) block->l[i]
+#else
+ #error "Endianness not defined!"
+#endif
+#define blk(i) (block->l[i&15] = rol(block->l[(i+13)&15]^block->l[(i+8)&15] ^block->l[(i+2)&15]^block->l[i&15],1))
+
+/* (R0+R1), R2, R3, R4 are the different operations used in SHA1 */
+#define R0(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk0(i)+0x5A827999+rol(v,5);w=rol(w,30);
+#define R1(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk(i)+0x5A827999+rol(v,5);w=rol(w,30);
+#define R2(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0x6ED9EBA1+rol(v,5);w=rol(w,30);
+#define R3(v,w,x,y,z,i) z+=(((w|x)&y)|(w&x))+blk(i)+0x8F1BBCDC+rol(v,5);w=rol(w,30);
+#define R4(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0xCA62C1D6+rol(v,5);w=rol(w,30);
+
+
+typedef struct private_sha1_hasher_t private_sha1_hasher_t;
+typedef struct private_sha1_keyed_prf_t private_sha1_keyed_prf_t;
+
+/**
+ * Private data structure with hasing context.
+ */
+struct private_sha1_hasher_t {
+ /**
+ * Public interface for this hasher.
+ */
+ sha1_hasher_t public;
+
+ /*
+ * State of the hasher.
+ */
+ u_int32_t state[5];
+ u_int32_t count[2];
+ u_int8_t buffer[64];
+};
+
+/**
+ * Private data structure with keyed prf context.
+ */
+struct private_sha1_keyed_prf_t {
+ /**
+ * public prf interface
+ */
+ sha1_keyed_prf_t public;
+
+ /**
+ * internal used hasher
+ */
+ private_sha1_hasher_t *hasher;
+};
+
+/*
+ * Hash a single 512-bit block. This is the core of the algorithm. *
+ */
+static void SHA1Transform(u_int32_t state[5], const unsigned char buffer[64])
+{
+ u_int32_t a, b, c, d, e;
+ typedef union {
+ u_int8_t c[64];
+ u_int32_t l[16];
+ } CHAR64LONG16;
+ CHAR64LONG16 block[1]; /* use array to appear as a pointer */
+ memcpy(block, buffer, 64);
+
+ /* Copy context->state[] to working vars */
+ a = state[0];
+ b = state[1];
+ c = state[2];
+ d = state[3];
+ e = state[4];
+ /* 4 rounds of 20 operations each. Loop unrolled. */
+ R0(a,b,c,d,e, 0); R0(e,a,b,c,d, 1); R0(d,e,a,b,c, 2); R0(c,d,e,a,b, 3);
+ R0(b,c,d,e,a, 4); R0(a,b,c,d,e, 5); R0(e,a,b,c,d, 6); R0(d,e,a,b,c, 7);
+ R0(c,d,e,a,b, 8); R0(b,c,d,e,a, 9); R0(a,b,c,d,e,10); R0(e,a,b,c,d,11);
+ R0(d,e,a,b,c,12); R0(c,d,e,a,b,13); R0(b,c,d,e,a,14); R0(a,b,c,d,e,15);
+ R1(e,a,b,c,d,16); R1(d,e,a,b,c,17); R1(c,d,e,a,b,18); R1(b,c,d,e,a,19);
+ R2(a,b,c,d,e,20); R2(e,a,b,c,d,21); R2(d,e,a,b,c,22); R2(c,d,e,a,b,23);
+ R2(b,c,d,e,a,24); R2(a,b,c,d,e,25); R2(e,a,b,c,d,26); R2(d,e,a,b,c,27);
+ R2(c,d,e,a,b,28); R2(b,c,d,e,a,29); R2(a,b,c,d,e,30); R2(e,a,b,c,d,31);
+ R2(d,e,a,b,c,32); R2(c,d,e,a,b,33); R2(b,c,d,e,a,34); R2(a,b,c,d,e,35);
+ R2(e,a,b,c,d,36); R2(d,e,a,b,c,37); R2(c,d,e,a,b,38); R2(b,c,d,e,a,39);
+ R3(a,b,c,d,e,40); R3(e,a,b,c,d,41); R3(d,e,a,b,c,42); R3(c,d,e,a,b,43);
+ R3(b,c,d,e,a,44); R3(a,b,c,d,e,45); R3(e,a,b,c,d,46); R3(d,e,a,b,c,47);
+ R3(c,d,e,a,b,48); R3(b,c,d,e,a,49); R3(a,b,c,d,e,50); R3(e,a,b,c,d,51);
+ R3(d,e,a,b,c,52); R3(c,d,e,a,b,53); R3(b,c,d,e,a,54); R3(a,b,c,d,e,55);
+ R3(e,a,b,c,d,56); R3(d,e,a,b,c,57); R3(c,d,e,a,b,58); R3(b,c,d,e,a,59);
+ R4(a,b,c,d,e,60); R4(e,a,b,c,d,61); R4(d,e,a,b,c,62); R4(c,d,e,a,b,63);
+ R4(b,c,d,e,a,64); R4(a,b,c,d,e,65); R4(e,a,b,c,d,66); R4(d,e,a,b,c,67);
+ R4(c,d,e,a,b,68); R4(b,c,d,e,a,69); R4(a,b,c,d,e,70); R4(e,a,b,c,d,71);
+ R4(d,e,a,b,c,72); R4(c,d,e,a,b,73); R4(b,c,d,e,a,74); R4(a,b,c,d,e,75);
+ R4(e,a,b,c,d,76); R4(d,e,a,b,c,77); R4(c,d,e,a,b,78); R4(b,c,d,e,a,79);
+ /* Add the working vars back into context.state[] */
+ state[0] += a;
+ state[1] += b;
+ state[2] += c;
+ state[3] += d;
+ state[4] += e;
+ /* Wipe variables */
+ a = b = c = d = e = 0;
+ memset(block, '\0', sizeof(block));
+}
+
+/*
+ * Run your data through this.
+ */
+static void SHA1Update(private_sha1_hasher_t* this, u_int8_t *data, u_int32_t len)
+{
+ u_int32_t i;
+ u_int32_t j;
+
+ j = this->count[0];
+ if ((this->count[0] += len << 3) < j)
+ {
+ this->count[1]++;
+ }
+ this->count[1] += (len>>29);
+ j = (j >> 3) & 63;
+ if ((j + len) > 63)
+ {
+ memcpy(&this->buffer[j], data, (i = 64-j));
+ SHA1Transform(this->state, this->buffer);
+ for ( ; i + 63 < len; i += 64)
+ {
+ SHA1Transform(this->state, &data[i]);
+ }
+ j = 0;
+ }
+ else
+ {
+ i = 0;
+ }
+ memcpy(&this->buffer[j], &data[i], len - i);
+}
+
+
+/*
+ * Add padding and return the message digest.
+ */
+static void SHA1Final(private_sha1_hasher_t *this, u_int8_t *digest)
+{
+ u_int32_t i;
+ u_int8_t finalcount[8];
+ u_int8_t c;
+
+ for (i = 0; i < 8; i++)
+ {
+ finalcount[i] = (u_int8_t)((this->count[(i >= 4 ? 0 : 1)]
+ >> ((3-(i & 3)) * 8) ) & 255); /* Endian independent */
+ }
+ c = 0200;
+ SHA1Update(this, &c, 1);
+ while ((this->count[0] & 504) != 448)
+ {
+ c = 0000;
+ SHA1Update(this, &c, 1);
+ }
+ SHA1Update(this, finalcount, 8); /* Should cause a SHA1Transform() */
+ for (i = 0; i < 20; i++)
+ {
+ digest[i] = (u_int8_t)((this->state[i>>2] >> ((3-(i & 3)) * 8) ) & 255);
+ }
+}
+
+/**
+ * Implementation of hasher_t.reset.
+ */
+static void reset(private_sha1_hasher_t *this)
+{
+ this->state[0] = 0x67452301;
+ this->state[1] = 0xEFCDAB89;
+ this->state[2] = 0x98BADCFE;
+ this->state[3] = 0x10325476;
+ this->state[4] = 0xC3D2E1F0;
+ this->count[0] = 0;
+ this->count[1] = 0;
+}
+
+/**
+ * Implementation of hasher_t.get_hash.
+ */
+static void get_hash(private_sha1_hasher_t *this, chunk_t chunk, u_int8_t *buffer)
+{
+ SHA1Update(this, chunk.ptr, chunk.len);
+ if (buffer != NULL)
+ {
+ SHA1Final(this, buffer);
+ reset(this);
+ }
+}
+
+/**
+ * Implementation of hasher_t.allocate_hash.
+ */
+static void allocate_hash(private_sha1_hasher_t *this, chunk_t chunk, chunk_t *hash)
+{
+ SHA1Update(this, chunk.ptr, chunk.len);
+ if (hash != NULL)
+ {
+ hash->ptr = malloc(HASH_SIZE_SHA1);
+ hash->len = HASH_SIZE_SHA1;
+
+ SHA1Final(this, hash->ptr);
+ reset(this);
+ }
+}
+
+/**
+ * Implementation of hasher_t.get_hash_size.
+ */
+static size_t get_hash_size(private_sha1_hasher_t *this)
+{
+ return HASH_SIZE_SHA1;
+}
+
+/**
+ * Implementation of hasher_t.destroy.
+ */
+static void destroy(private_sha1_hasher_t *this)
+{
+ free(this);
+}
+
+/*
+ * Described in header.
+ */
+sha1_hasher_t *sha1_hasher_create(hash_algorithm_t algo)
+{
+ private_sha1_hasher_t *this;
+ if (algo != HASH_SHA1)
+ {
+ return NULL;
+ }
+ this = malloc_thing(private_sha1_hasher_t);
+ this->public.hasher_interface.get_hash = (void (*) (hasher_t*, chunk_t, u_int8_t*))get_hash;
+ this->public.hasher_interface.allocate_hash = (void (*) (hasher_t*, chunk_t, chunk_t*))allocate_hash;
+ this->public.hasher_interface.get_hash_size = (size_t (*) (hasher_t*))get_hash_size;
+ this->public.hasher_interface.reset = (void (*) (hasher_t*))reset;
+ this->public.hasher_interface.destroy = (void (*) (hasher_t*))destroy;
+
+ /* initialize */
+ reset(this);
+
+ return &(this->public);
+}
+
+/**
+ * Implementation of prf_t.get_bytes.
+ */
+static void get_bytes(private_sha1_keyed_prf_t *this, chunk_t seed, u_int8_t *bytes)
+{
+ u_int32_t *hash = (u_int32_t*)bytes;
+
+ SHA1Update(this->hasher, seed.ptr, seed.len);
+
+ hash[0] = htonl(this->hasher->state[0]);
+ hash[1] = htonl(this->hasher->state[1]);
+ hash[2] = htonl(this->hasher->state[2]);
+ hash[3] = htonl(this->hasher->state[3]);
+ hash[4] = htonl(this->hasher->state[4]);
+}
+
+/**
+ * Implementation of prf_t.get_block_size.
+ */
+static size_t get_block_size(private_sha1_keyed_prf_t *this)
+{
+ return HASH_SIZE_SHA1;
+}
+
+/**
+ * Implementation of prf_t.allocate_bytes.
+ */
+static void allocate_bytes(private_sha1_keyed_prf_t *this, chunk_t seed, chunk_t *chunk)
+{
+ *chunk = chunk_alloc(HASH_SIZE_SHA1);
+ get_bytes(this, seed, chunk->ptr);
+}
+
+/**
+ * Implementation of prf_t.get_key_size.
+ */
+static size_t get_key_size(private_sha1_keyed_prf_t *this)
+{
+ return sizeof(this->hasher->state);
+}
+
+/**
+ * Implementation of prf_t.set_key.
+ */
+static void set_key(private_sha1_keyed_prf_t *this, chunk_t key)
+{
+ int i, rounds;
+ u_int32_t *iv = (u_int32_t*)key.ptr;
+
+ reset(this->hasher);
+ rounds = min(key.len/sizeof(u_int32_t), sizeof(this->hasher->state));
+ for (i = 0; i < rounds; i++)
+ {
+ this->hasher->state[i] ^= htonl(iv[i]);
+ }
+}
+
+/**
+ * Implementation of prf_t.destroy.
+ */
+static void destroy_p(private_sha1_keyed_prf_t *this)
+{
+ destroy(this->hasher);
+ free(this);
+}
+
+/**
+ * see header
+ */
+sha1_keyed_prf_t *sha1_keyed_prf_create(pseudo_random_function_t algo)
+{
+ private_sha1_keyed_prf_t *this;
+ if (algo != PRF_KEYED_SHA1)
+ {
+ return NULL;
+ }
+ this = malloc_thing(private_sha1_keyed_prf_t);
+ this->public.prf_interface.get_bytes = (void (*) (prf_t *,chunk_t,u_int8_t*))get_bytes;
+ this->public.prf_interface.allocate_bytes = (void (*) (prf_t*,chunk_t,chunk_t*))allocate_bytes;
+ this->public.prf_interface.get_block_size = (size_t (*) (prf_t*))get_block_size;
+ this->public.prf_interface.get_key_size = (size_t (*) (prf_t*))get_key_size;
+ this->public.prf_interface.set_key = (void (*) (prf_t *,chunk_t))set_key;
+ this->public.prf_interface.destroy = (void (*) (prf_t *))destroy_p;
+
+ this->hasher = (private_sha1_hasher_t*)sha1_hasher_create(HASH_SHA1);
+
+ return &(this->public);
+}
+
diff --git a/src/libstrongswan/plugins/sha1/sha1_hasher.h b/src/libstrongswan/plugins/sha1/sha1_hasher.h
new file mode 100644
index 000000000..2e44797d8
--- /dev/null
+++ b/src/libstrongswan/plugins/sha1/sha1_hasher.h
@@ -0,0 +1,69 @@
+/*
+ * Copyright (C) 2005-2008 Martin Willi
+ * Copyright (C) 2005 Jan Hutter
+ * Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+/**
+ * @defgroup sha1_hasher sha1_hasher
+ * @{ @ingroup sha1_p
+ */
+
+#ifndef SHA1_HASHER_H_
+#define SHA1_HASHER_H_
+
+typedef struct sha1_hasher_t sha1_hasher_t;
+typedef struct sha1_keyed_prf_t sha1_keyed_prf_t;
+
+#include <crypto/hashers/hasher.h>
+#include <crypto/prfs/prf.h>
+
+/**
+ * Implementation of hasher_t interface using the SHA1 algorithm.
+ */
+struct sha1_hasher_t {
+
+ /**
+ * Implements hasher_t interface.
+ */
+ hasher_t hasher_interface;
+};
+
+/**
+ * Implementation of prf_t interface using keyed SHA1 algorithm (used for EAP-AKA).
+ */
+struct sha1_keyed_prf_t {
+
+ /**
+ * Implements prf_t interface.
+ */
+ prf_t prf_interface;
+};
+
+/**
+ * Creates a new sha1_hasher_t.
+ *
+ * @param algo algorithm, must be HASH_SHA1
+ * @return sha1_hasher_t object
+ */
+sha1_hasher_t *sha1_hasher_create(hash_algorithm_t algo);
+
+/**
+ * Creates a new sha1_keyed_prf_t.
+ *
+ * @param algo algorithm, must be PRF_KEYED_SHA1
+ * @return sha1_keyed_prf_tobject
+ */
+sha1_keyed_prf_t *sha1_keyed_prf_create(pseudo_random_function_t algo);
+
+#endif /*SHA1_HASHER_H_ @}*/
diff --git a/src/libstrongswan/plugins/sha1/sha1_plugin.c b/src/libstrongswan/plugins/sha1/sha1_plugin.c
new file mode 100644
index 000000000..e8da99e6c
--- /dev/null
+++ b/src/libstrongswan/plugins/sha1/sha1_plugin.c
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2008 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.
+ *
+ * $Id: sha1_plugin.c 3619 2008-03-19 14:02:52Z martin $
+ */
+
+#include "sha1_plugin.h"
+
+#include <library.h>
+#include "sha1_hasher.h"
+
+typedef struct private_sha1_plugin_t private_sha1_plugin_t;
+
+/**
+ * private data of sha1_plugin
+ */
+struct private_sha1_plugin_t {
+
+ /**
+ * public functions
+ */
+ sha1_plugin_t public;
+};
+
+/**
+ * Implementation of sha1_plugin_t.destroy
+ */
+static void destroy(private_sha1_plugin_t *this)
+{
+ lib->crypto->remove_hasher(lib->crypto,
+ (hasher_constructor_t)sha1_hasher_create);
+ lib->crypto->remove_prf(lib->crypto,
+ (prf_constructor_t)sha1_keyed_prf_create);
+ free(this);
+}
+
+/*
+ * see header file
+ */
+plugin_t *plugin_create()
+{
+ private_sha1_plugin_t *this = malloc_thing(private_sha1_plugin_t);
+
+ this->public.plugin.destroy = (void(*)(plugin_t*))destroy;
+
+ lib->crypto->add_hasher(lib->crypto, HASH_SHA1,
+ (hasher_constructor_t)sha1_hasher_create);
+ lib->crypto->add_prf(lib->crypto, PRF_KEYED_SHA1,
+ (prf_constructor_t)sha1_keyed_prf_create);
+
+ return &this->public.plugin;
+}
+
diff --git a/src/libstrongswan/plugins/sha1/sha1_plugin.h b/src/libstrongswan/plugins/sha1/sha1_plugin.h
new file mode 100644
index 000000000..82ab04c86
--- /dev/null
+++ b/src/libstrongswan/plugins/sha1/sha1_plugin.h
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2008 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.
+ */
+
+/**
+ * @defgroup sha1_p sha1
+ * @ingroup plugins
+ *
+ * @defgroup sha1_plugin sha1_plugin
+ * @{ @ingroup sha1_p
+ */
+
+#ifndef SHA1_PLUGIN_H_
+#define SHA1_PLUGIN_H_
+
+#include <plugins/plugin.h>
+
+typedef struct sha1_plugin_t sha1_plugin_t;
+
+/**
+ * Plugin implementing the SHA1 algorithm in software.
+ */
+struct sha1_plugin_t {
+
+ /**
+ * implements plugin interface
+ */
+ plugin_t plugin;
+};
+
+/**
+ * Create a sha1_plugin instance.
+ */
+plugin_t *plugin_create();
+
+#endif /* SHA1_PLUGIN_H_ @}*/
diff --git a/src/libstrongswan/plugins/sha2/Makefile.am b/src/libstrongswan/plugins/sha2/Makefile.am
new file mode 100644
index 000000000..066e49476
--- /dev/null
+++ b/src/libstrongswan/plugins/sha2/Makefile.am
@@ -0,0 +1,10 @@
+
+INCLUDES = -I$(top_srcdir)/src/libstrongswan
+
+AM_CFLAGS = -rdynamic
+
+plugin_LTLIBRARIES = libstrongswan-sha2.la
+
+libstrongswan_sha2_la_SOURCES = sha2_plugin.h sha2_plugin.c sha2_hasher.c sha2_hasher.h
+libstrongswan_sha2_la_LDFLAGS = -module
+
diff --git a/src/libstrongswan/plugins/sha2/Makefile.in b/src/libstrongswan/plugins/sha2/Makefile.in
new file mode 100644
index 000000000..ec0e45248
--- /dev/null
+++ b/src/libstrongswan/plugins/sha2/Makefile.in
@@ -0,0 +1,494 @@
+# Makefile.in generated by automake 1.10.1 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+VPATH = @srcdir@
+pkgdatadir = $(datadir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+subdir = src/libstrongswan/plugins/sha2
+DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/configure.in
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+mkinstalldirs = $(install_sh) -d
+CONFIG_CLEAN_FILES =
+am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
+am__vpath_adj = case $$p in \
+ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
+ *) f=$$p;; \
+ esac;
+am__strip_dir = `echo $$p | sed -e 's|^.*/||'`;
+am__installdirs = "$(DESTDIR)$(plugindir)"
+pluginLTLIBRARIES_INSTALL = $(INSTALL)
+LTLIBRARIES = $(plugin_LTLIBRARIES)
+libstrongswan_sha2_la_LIBADD =
+am_libstrongswan_sha2_la_OBJECTS = sha2_plugin.lo sha2_hasher.lo
+libstrongswan_sha2_la_OBJECTS = $(am_libstrongswan_sha2_la_OBJECTS)
+libstrongswan_sha2_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(libstrongswan_sha2_la_LDFLAGS) $(LDFLAGS) -o $@
+DEFAULT_INCLUDES = -I.@am__isrc@
+depcomp = $(SHELL) $(top_srcdir)/depcomp
+am__depfiles_maybe = depfiles
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+ --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
+ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+CCLD = $(CC)
+LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+ --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \
+ $(LDFLAGS) -o $@
+SOURCES = $(libstrongswan_sha2_la_SOURCES)
+DIST_SOURCES = $(libstrongswan_sha2_la_SOURCES)
+ETAGS = etags
+CTAGS = ctags
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+AMTAR = @AMTAR@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CXX = @CXX@
+CXXCPP = @CXXCPP@
+CXXDEPMODE = @CXXDEPMODE@
+CXXFLAGS = @CXXFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DSYMUTIL = @DSYMUTIL@
+ECHO = @ECHO@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+F77 = @F77@
+FFLAGS = @FFLAGS@
+GPERF = @GPERF@
+GREP = @GREP@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+IPSEC_ROUTING_TABLE = @IPSEC_ROUTING_TABLE@
+IPSEC_ROUTING_TABLE_PRIO = @IPSEC_ROUTING_TABLE_PRIO@
+LDFLAGS = @LDFLAGS@
+LEX = @LEX@
+LEXLIB = @LEXLIB@
+LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LINUX_HEADERS = @LINUX_HEADERS@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+MAKEINFO = @MAKEINFO@
+MKDIR_P = @MKDIR_P@
+NMEDIT = @NMEDIT@
+OBJEXT = @OBJEXT@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PERL = @PERL@
+PKG_CONFIG = @PKG_CONFIG@
+RANLIB = @RANLIB@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRIP = @STRIP@
+VERSION = @VERSION@
+YACC = @YACC@
+YFLAGS = @YFLAGS@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_CXX = @ac_ct_CXX@
+ac_ct_F77 = @ac_ct_F77@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+confdir = @confdir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+gtk_CFLAGS = @gtk_CFLAGS@
+gtk_LIBS = @gtk_LIBS@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+ipsecdir = @ipsecdir@
+ipsecgroup = @ipsecgroup@
+ipsecuser = @ipsecuser@
+libdir = @libdir@
+libexecdir = @libexecdir@
+libstrongswan_plugins = @libstrongswan_plugins@
+linuxdir = @linuxdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+piddir = @piddir@
+plugindir = @plugindir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+resolv_conf = @resolv_conf@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+simreader = @simreader@
+srcdir = @srcdir@
+strongswan_conf = @strongswan_conf@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+xml_CFLAGS = @xml_CFLAGS@
+xml_LIBS = @xml_LIBS@
+INCLUDES = -I$(top_srcdir)/src/libstrongswan
+AM_CFLAGS = -rdynamic
+plugin_LTLIBRARIES = libstrongswan-sha2.la
+libstrongswan_sha2_la_SOURCES = sha2_plugin.h sha2_plugin.c sha2_hasher.c sha2_hasher.h
+libstrongswan_sha2_la_LDFLAGS = -module
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .c .lo .o .obj
+$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \
+ && exit 0; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/libstrongswan/plugins/sha2/Makefile'; \
+ cd $(top_srcdir) && \
+ $(AUTOMAKE) --gnu src/libstrongswan/plugins/sha2/Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+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) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(pluginLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) '$$p' '$(DESTDIR)$(plugindir)/$$f'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(pluginLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) "$$p" "$(DESTDIR)$(plugindir)/$$f"; \
+ else :; fi; \
+ done
+
+uninstall-pluginLTLIBRARIES:
+ @$(NORMAL_UNINSTALL)
+ @list='$(plugin_LTLIBRARIES)'; for p in $$list; do \
+ p=$(am__strip_dir) \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(plugindir)/$$p'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(plugindir)/$$p"; \
+ 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
+libstrongswan-sha2.la: $(libstrongswan_sha2_la_OBJECTS) $(libstrongswan_sha2_la_DEPENDENCIES)
+ $(libstrongswan_sha2_la_LINK) -rpath $(plugindir) $(libstrongswan_sha2_la_OBJECTS) $(libstrongswan_sha2_la_LIBADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sha2_hasher.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sha2_plugin.Plo@am__quote@
+
+.c.o:
+@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(COMPILE) -c $<
+
+.c.obj:
+@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'`
+
+.c.lo:
+@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $<
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+
+ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonemtpy = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ mkid -fID $$unique
+tags: TAGS
+
+TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ tags=; \
+ here=`pwd`; \
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \
+ test -n "$$unique" || unique=$$empty_fix; \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ $$tags $$unique; \
+ fi
+ctags: CTAGS
+CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ tags=; \
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ test -z "$(CTAGS_ARGS)$$tags$$unique" \
+ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+ $$tags $$unique
+
+GTAGS:
+ here=`$(am__cd) $(top_builddir) && pwd` \
+ && cd $(top_srcdir) \
+ && gtags -i $(GTAGS_ARGS) $$here
+
+distclean-tags:
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+distdir: $(DISTFILES)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ list='$(DISTFILES)'; \
+ dist_files=`for file in $$list; do echo $$file; done | \
+ sed -e "s|^$$srcdirstrip/||;t" \
+ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+ case $$dist_files in \
+ */*) $(MKDIR_P) `echo "$$dist_files" | \
+ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+ sort -u` ;; \
+ esac; \
+ for file in $$dist_files; do \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ if test -d $$d/$$file; then \
+ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
+ fi; \
+ cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
+ else \
+ test -f $(distdir)/$$file \
+ || cp -p $$d/$$file $(distdir)/$$file \
+ || exit 1; \
+ fi; \
+ done
+check-am: all-am
+check: check-am
+all-am: Makefile $(LTLIBRARIES)
+installdirs:
+ for dir in "$(DESTDIR)$(plugindir)"; do \
+ test -z "$$dir" || $(MKDIR_P) "$$dir"; \
+ done
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ `test -z '$(STRIP)' || \
+ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+clean: clean-am
+
+clean-am: clean-generic clean-libtool clean-pluginLTLIBRARIES \
+ mostlyclean-am
+
+distclean: distclean-am
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+ distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+info: info-am
+
+info-am:
+
+install-data-am: install-pluginLTLIBRARIES
+
+install-dvi: install-dvi-am
+
+install-exec-am:
+
+install-html: install-html-am
+
+install-info: install-info-am
+
+install-man:
+
+install-pdf: install-pdf-am
+
+install-ps: install-ps-am
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic \
+ mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am: uninstall-pluginLTLIBRARIES
+
+.MAKE: install-am install-strip
+
+.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \
+ clean-libtool clean-pluginLTLIBRARIES ctags distclean \
+ distclean-compile distclean-generic distclean-libtool \
+ distclean-tags distdir dvi dvi-am html html-am info info-am \
+ install install-am install-data install-data-am install-dvi \
+ install-dvi-am install-exec install-exec-am install-html \
+ install-html-am install-info install-info-am install-man \
+ install-pdf install-pdf-am install-pluginLTLIBRARIES \
+ install-ps install-ps-am install-strip installcheck \
+ installcheck-am installdirs maintainer-clean \
+ maintainer-clean-generic mostlyclean mostlyclean-compile \
+ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
+ tags uninstall uninstall-am uninstall-pluginLTLIBRARIES
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/src/libstrongswan/plugins/sha2/sha2_hasher.c b/src/libstrongswan/plugins/sha2/sha2_hasher.c
new file mode 100644
index 000000000..ca9c2f926
--- /dev/null
+++ b/src/libstrongswan/plugins/sha2/sha2_hasher.c
@@ -0,0 +1,632 @@
+/*
+ * Copyright (C) 2006 Martin Willi
+ * Hochschule fuer Technik Rapperswil
+ * Copyright (C) 2001 Jari Ruusu.
+ *
+ * Ported from strongSwans implementation written by Jari Ruusu.
+ *
+ * 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.
+ *
+ * $Id: sha2_hasher.c 3488 2008-02-21 15:10:02Z martin $
+ */
+
+#include <string.h>
+
+#include "sha2_hasher.h"
+
+
+typedef struct private_sha512_hasher_t private_sha512_hasher_t;
+
+/**
+ * Private data structure with hasing context for SHA384 and SHA512
+ */
+struct private_sha512_hasher_t {
+ /**
+ * Public interface for this hasher.
+ */
+ sha2_hasher_t public;
+
+ unsigned char sha_out[128]; /* results are here, bytes 0..47/0..63 */
+ u_int64_t sha_H[8];
+ u_int64_t sha_blocks;
+ u_int64_t sha_blocksMSB;
+ int sha_bufCnt;
+};
+
+
+typedef struct private_sha256_hasher_t private_sha256_hasher_t;
+
+/**
+ * Private data structure with hasing context for SHA256
+ */
+struct private_sha256_hasher_t {
+ /**
+ * Public interface for this hasher.
+ */
+ sha2_hasher_t public;
+
+ unsigned char sha_out[64]; /* results are here, bytes 0...31 */
+ u_int32_t sha_H[8];
+ u_int64_t sha_blocks;
+ int sha_bufCnt;
+};
+
+
+static const u_int32_t sha256_hashInit[8] = {
+ 0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 0x510e527f, 0x9b05688c,
+ 0x1f83d9ab, 0x5be0cd19
+};
+
+static const u_int32_t sha256_K[64] = {
+ 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1,
+ 0x923f82a4, 0xab1c5ed5, 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3,
+ 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174, 0xe49b69c1, 0xefbe4786,
+ 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
+ 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147,
+ 0x06ca6351, 0x14292967, 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13,
+ 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85, 0xa2bfe8a1, 0xa81a664b,
+ 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
+ 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a,
+ 0x5b9cca4f, 0x682e6ff3, 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208,
+ 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
+};
+
+static const u_int64_t sha512_hashInit[8] = {
+ 0x6a09e667f3bcc908ULL, 0xbb67ae8584caa73bULL, 0x3c6ef372fe94f82bULL,
+ 0xa54ff53a5f1d36f1ULL, 0x510e527fade682d1ULL, 0x9b05688c2b3e6c1fULL,
+ 0x1f83d9abfb41bd6bULL, 0x5be0cd19137e2179ULL
+};
+
+static const u_int64_t sha384_hashInit[8] = {
+ 0xcbbb9d5dc1059ed8ULL, 0x629a292a367cd507ULL, 0x9159015a3070dd17ULL,
+ 0x152fecd8f70e5939ULL, 0x67332667ffc00b31ULL, 0x8eb44a8768581511ULL,
+ 0xdb0c2e0d64f98fa7ULL, 0x47b5481dbefa4fa4ULL
+};
+
+static const u_int64_t sha512_K[80] = {
+ 0x428a2f98d728ae22ULL, 0x7137449123ef65cdULL, 0xb5c0fbcfec4d3b2fULL,
+ 0xe9b5dba58189dbbcULL, 0x3956c25bf348b538ULL, 0x59f111f1b605d019ULL,
+ 0x923f82a4af194f9bULL, 0xab1c5ed5da6d8118ULL, 0xd807aa98a3030242ULL,
+ 0x12835b0145706fbeULL, 0x243185be4ee4b28cULL, 0x550c7dc3d5ffb4e2ULL,
+ 0x72be5d74f27b896fULL, 0x80deb1fe3b1696b1ULL, 0x9bdc06a725c71235ULL,
+ 0xc19bf174cf692694ULL, 0xe49b69c19ef14ad2ULL, 0xefbe4786384f25e3ULL,
+ 0x0fc19dc68b8cd5b5ULL, 0x240ca1cc77ac9c65ULL, 0x2de92c6f592b0275ULL,
+ 0x4a7484aa6ea6e483ULL, 0x5cb0a9dcbd41fbd4ULL, 0x76f988da831153b5ULL,
+ 0x983e5152ee66dfabULL, 0xa831c66d2db43210ULL, 0xb00327c898fb213fULL,
+ 0xbf597fc7beef0ee4ULL, 0xc6e00bf33da88fc2ULL, 0xd5a79147930aa725ULL,
+ 0x06ca6351e003826fULL, 0x142929670a0e6e70ULL, 0x27b70a8546d22ffcULL,
+ 0x2e1b21385c26c926ULL, 0x4d2c6dfc5ac42aedULL, 0x53380d139d95b3dfULL,
+ 0x650a73548baf63deULL, 0x766a0abb3c77b2a8ULL, 0x81c2c92e47edaee6ULL,
+ 0x92722c851482353bULL, 0xa2bfe8a14cf10364ULL, 0xa81a664bbc423001ULL,
+ 0xc24b8b70d0f89791ULL, 0xc76c51a30654be30ULL, 0xd192e819d6ef5218ULL,
+ 0xd69906245565a910ULL, 0xf40e35855771202aULL, 0x106aa07032bbd1b8ULL,
+ 0x19a4c116b8d2d0c8ULL, 0x1e376c085141ab53ULL, 0x2748774cdf8eeb99ULL,
+ 0x34b0bcb5e19b48a8ULL, 0x391c0cb3c5c95a63ULL, 0x4ed8aa4ae3418acbULL,
+ 0x5b9cca4f7763e373ULL, 0x682e6ff3d6b2b8a3ULL, 0x748f82ee5defb2fcULL,
+ 0x78a5636f43172f60ULL, 0x84c87814a1f0ab72ULL, 0x8cc702081a6439ecULL,
+ 0x90befffa23631e28ULL, 0xa4506cebde82bde9ULL, 0xbef9a3f7b2c67915ULL,
+ 0xc67178f2e372532bULL, 0xca273eceea26619cULL, 0xd186b8c721c0c207ULL,
+ 0xeada7dd6cde0eb1eULL, 0xf57d4f7fee6ed178ULL, 0x06f067aa72176fbaULL,
+ 0x0a637dc5a2c898a6ULL, 0x113f9804bef90daeULL, 0x1b710b35131c471bULL,
+ 0x28db77f523047d84ULL, 0x32caab7b40c72493ULL, 0x3c9ebe0a15c9bebcULL,
+ 0x431d67c49c100d4cULL, 0x4cc5d4becb3e42b6ULL, 0x597f299cfc657e2aULL,
+ 0x5fcb6fab3ad6faecULL, 0x6c44198c4a475817ULL
+};
+
+
+/* set macros for SHA256 */
+#define Ch(x,y,z) (((x) & (y)) ^ ((~(x)) & (z)))
+#define Maj(x,y,z) (((x) & (y)) ^ ((x) & (z)) ^ ((y) & (z)))
+#define R(x,y) ((y) >> (x))
+
+#define S(x,y) (((y) >> (x)) | ((y) << (32 - (x))))
+#define uSig0(x) ((S(2,(x))) ^ (S(13,(x))) ^ (S(22,(x))))
+#define uSig1(x) ((S(6,(x))) ^ (S(11,(x))) ^ (S(25,(x))))
+#define lSig0(x) ((S(7,(x))) ^ (S(18,(x))) ^ (R(3,(x))))
+#define lSig1(x) ((S(17,(x))) ^ (S(19,(x))) ^ (R(10,(x))))
+
+/**
+ * Single block SHA256 transformation
+ */
+static void sha256_transform(private_sha256_hasher_t *ctx,
+ const unsigned char *datap)
+{
+ register int j;
+ u_int32_t a, b, c, d, e, f, g, h;
+ u_int32_t T1, T2, W[64], Wm2, Wm15;
+
+ /* read the data, big endian byte order */
+ j = 0;
+ do {
+ W[j] = (((u_int32_t)(datap[0]))<<24) | (((u_int32_t)(datap[1]))<<16) |
+ (((u_int32_t)(datap[2]))<<8 ) | ((u_int32_t)(datap[3]));
+ datap += 4;
+ } while(++j < 16);
+
+ /* initialize variables a...h */
+ a = ctx->sha_H[0];
+ b = ctx->sha_H[1];
+ c = ctx->sha_H[2];
+ d = ctx->sha_H[3];
+ e = ctx->sha_H[4];
+ f = ctx->sha_H[5];
+ g = ctx->sha_H[6];
+ h = ctx->sha_H[7];
+
+ /* apply compression function */
+ j = 0;
+ do
+ {
+ if(j >= 16)
+ {
+ Wm2 = W[j - 2];
+ Wm15 = W[j - 15];
+ W[j] = lSig1(Wm2) + W[j - 7] + lSig0(Wm15) + W[j - 16];
+ }
+ T1 = h + uSig1(e) + Ch(e,f,g) + sha256_K[j] + W[j];
+ T2 = uSig0(a) + Maj(a,b,c);
+ h = g; g = f; f = e;
+ e = d + T1;
+ d = c; c = b; b = a;
+ a = T1 + T2;
+ } while(++j < 64);
+
+ /* compute intermediate hash value */
+ ctx->sha_H[0] += a;
+ ctx->sha_H[1] += b;
+ ctx->sha_H[2] += c;
+ ctx->sha_H[3] += d;
+ ctx->sha_H[4] += e;
+ ctx->sha_H[5] += f;
+ ctx->sha_H[6] += g;
+ ctx->sha_H[7] += h;
+
+ ctx->sha_blocks++;
+}
+
+/**
+ * Update SHA256 hash
+ */
+static void sha256_write(private_sha256_hasher_t *ctx,
+ const unsigned char *datap, int length)
+{
+ while(length > 0)
+ {
+ if(!ctx->sha_bufCnt)
+ {
+ while(length >= sizeof(ctx->sha_out))
+ {
+ sha256_transform(ctx, datap);
+ datap += sizeof(ctx->sha_out);
+ length -= sizeof(ctx->sha_out);
+ }
+ if(!length) return;
+ }
+ ctx->sha_out[ctx->sha_bufCnt] = *datap++;
+ length--;
+ if(++ctx->sha_bufCnt == sizeof(ctx->sha_out))
+ {
+ sha256_transform(ctx, &ctx->sha_out[0]);
+ ctx->sha_bufCnt = 0;
+ }
+ }
+}
+
+/**
+ * finalize SHA256 hash
+ */
+static void sha256_final(private_sha256_hasher_t *ctx)
+{
+ register int j;
+ u_int64_t bitLength;
+ u_int32_t i;
+ unsigned char padByte, *datap;
+
+ bitLength = (ctx->sha_blocks << 9) | (ctx->sha_bufCnt << 3);
+ padByte = 0x80;
+ sha256_write(ctx, &padByte, 1);
+
+ /* pad extra space with zeroes */
+ padByte = 0;
+ while(ctx->sha_bufCnt != 56)
+ {
+ sha256_write(ctx, &padByte, 1);
+ }
+
+ /* write bit length, big endian byte order */
+ ctx->sha_out[56] = bitLength >> 56;
+ ctx->sha_out[57] = bitLength >> 48;
+ ctx->sha_out[58] = bitLength >> 40;
+ ctx->sha_out[59] = bitLength >> 32;
+ ctx->sha_out[60] = bitLength >> 24;
+ ctx->sha_out[61] = bitLength >> 16;
+ ctx->sha_out[62] = bitLength >> 8;
+ ctx->sha_out[63] = bitLength;
+ sha256_transform(ctx, &ctx->sha_out[0]);
+
+ /* return results in ctx->sha_out[0...31] */
+ datap = &ctx->sha_out[0];
+ j = 0;
+ do {
+ i = ctx->sha_H[j];
+ datap[0] = i >> 24;
+ datap[1] = i >> 16;
+ datap[2] = i >> 8;
+ datap[3] = i;
+ datap += 4;
+ } while(++j < 8);
+}
+
+/* update macros for SHA512 */
+#undef S
+#undef uSig0
+#undef uSig1
+#undef lSig0
+#undef lSig1
+#define S(x,y) (((y) >> (x)) | ((y) << (64 - (x))))
+#define uSig0(x) ((S(28,(x))) ^ (S(34,(x))) ^ (S(39,(x))))
+#define uSig1(x) ((S(14,(x))) ^ (S(18,(x))) ^ (S(41,(x))))
+#define lSig0(x) ((S(1,(x))) ^ (S(8,(x))) ^ (R(7,(x))))
+#define lSig1(x) ((S(19,(x))) ^ (S(61,(x))) ^ (R(6,(x))))
+
+/**
+ * Single block SHA384/SHA512 transformation
+ */
+static void sha512_transform(private_sha512_hasher_t *ctx,
+ const unsigned char *datap)
+{
+ register int j;
+ u_int64_t a, b, c, d, e, f, g, h;
+ u_int64_t T1, T2, W[80], Wm2, Wm15;
+
+ /* read the data, big endian byte order */
+ j = 0;
+ do {
+ W[j] = (((u_int64_t)(datap[0]))<<56) | (((u_int64_t)(datap[1]))<<48) |
+ (((u_int64_t)(datap[2]))<<40) | (((u_int64_t)(datap[3]))<<32) |
+ (((u_int64_t)(datap[4]))<<24) | (((u_int64_t)(datap[5]))<<16) |
+ (((u_int64_t)(datap[6]))<<8 ) | ((u_int64_t)(datap[7]));
+ datap += 8;
+ } while(++j < 16);
+
+ /* initialize variables a...h */
+ a = ctx->sha_H[0];
+ b = ctx->sha_H[1];
+ c = ctx->sha_H[2];
+ d = ctx->sha_H[3];
+ e = ctx->sha_H[4];
+ f = ctx->sha_H[5];
+ g = ctx->sha_H[6];
+ h = ctx->sha_H[7];
+
+ /* apply compression function */
+ j = 0;
+ do {
+ if(j >= 16) {
+ Wm2 = W[j - 2];
+ Wm15 = W[j - 15];
+ W[j] = lSig1(Wm2) + W[j - 7] + lSig0(Wm15) + W[j - 16];
+ }
+ T1 = h + uSig1(e) + Ch(e,f,g) + sha512_K[j] + W[j];
+ T2 = uSig0(a) + Maj(a,b,c);
+ h = g; g = f; f = e;
+ e = d + T1;
+ d = c; c = b; b = a;
+ a = T1 + T2;
+ } while(++j < 80);
+
+ /* compute intermediate hash value */
+ ctx->sha_H[0] += a;
+ ctx->sha_H[1] += b;
+ ctx->sha_H[2] += c;
+ ctx->sha_H[3] += d;
+ ctx->sha_H[4] += e;
+ ctx->sha_H[5] += f;
+ ctx->sha_H[6] += g;
+ ctx->sha_H[7] += h;
+
+ ctx->sha_blocks++;
+ if(!ctx->sha_blocks) ctx->sha_blocksMSB++;
+}
+
+/**
+ * Update a SHA384/SHA512 hash
+ */
+static void sha512_write(private_sha512_hasher_t *ctx,
+ const unsigned char *datap, int length)
+{
+ while(length > 0)
+ {
+ if(!ctx->sha_bufCnt)
+ {
+ while(length >= sizeof(ctx->sha_out))
+ {
+ sha512_transform(ctx, datap);
+ datap += sizeof(ctx->sha_out);
+ length -= sizeof(ctx->sha_out);
+ }
+ if(!length) return;
+ }
+ ctx->sha_out[ctx->sha_bufCnt] = *datap++;
+ length--;
+ if(++ctx->sha_bufCnt == sizeof(ctx->sha_out))
+ {
+ sha512_transform(ctx, &ctx->sha_out[0]);
+ ctx->sha_bufCnt = 0;
+ }
+ }
+}
+
+/**
+ * Finalize a SHA384/SHA512 hash
+ */
+static void sha512_final(private_sha512_hasher_t *ctx)
+{
+ register int j;
+ u_int64_t bitLength, bitLengthMSB;
+ u_int64_t i;
+ unsigned char padByte, *datap;
+
+ bitLength = (ctx->sha_blocks << 10) | (ctx->sha_bufCnt << 3);
+ bitLengthMSB = (ctx->sha_blocksMSB << 10) | (ctx->sha_blocks >> 54);
+ padByte = 0x80;
+ sha512_write(ctx, &padByte, 1);
+
+ /* pad extra space with zeroes */
+ padByte = 0;
+ while(ctx->sha_bufCnt != 112)
+ {
+ sha512_write(ctx, &padByte, 1);
+ }
+
+ /* write bit length, big endian byte order */
+ ctx->sha_out[112] = bitLengthMSB >> 56;
+ ctx->sha_out[113] = bitLengthMSB >> 48;
+ ctx->sha_out[114] = bitLengthMSB >> 40;
+ ctx->sha_out[115] = bitLengthMSB >> 32;
+ ctx->sha_out[116] = bitLengthMSB >> 24;
+ ctx->sha_out[117] = bitLengthMSB >> 16;
+ ctx->sha_out[118] = bitLengthMSB >> 8;
+ ctx->sha_out[119] = bitLengthMSB;
+ ctx->sha_out[120] = bitLength >> 56;
+ ctx->sha_out[121] = bitLength >> 48;
+ ctx->sha_out[122] = bitLength >> 40;
+ ctx->sha_out[123] = bitLength >> 32;
+ ctx->sha_out[124] = bitLength >> 24;
+ ctx->sha_out[125] = bitLength >> 16;
+ ctx->sha_out[126] = bitLength >> 8;
+ ctx->sha_out[127] = bitLength;
+ sha512_transform(ctx, &ctx->sha_out[0]);
+
+ /* return results in ctx->sha_out[0...63] */
+ datap = &ctx->sha_out[0];
+ j = 0;
+ do {
+ i = ctx->sha_H[j];
+ datap[0] = i >> 56;
+ datap[1] = i >> 48;
+ datap[2] = i >> 40;
+ datap[3] = i >> 32;
+ datap[4] = i >> 24;
+ datap[5] = i >> 16;
+ datap[6] = i >> 8;
+ datap[7] = i;
+ datap += 8;
+ } while(++j < 8);
+}
+
+/**
+ * Implementation of hasher_t.get_hash for SHA256.
+ */
+static void get_hash256(private_sha256_hasher_t *this,
+ chunk_t chunk, u_int8_t *buffer)
+{
+ sha256_write(this, chunk.ptr, chunk.len);
+ if (buffer != NULL)
+ {
+ sha256_final(this);
+ memcpy(buffer, this->sha_out, HASH_SIZE_SHA256);
+ this->public.hasher_interface.reset(&(this->public.hasher_interface));
+ }
+}
+
+/**
+ * Implementation of hasher_t.get_hash for SHA384.
+ */
+static void get_hash384(private_sha512_hasher_t *this,
+ chunk_t chunk, u_int8_t *buffer)
+{
+ sha512_write(this, chunk.ptr, chunk.len);
+ if (buffer != NULL)
+ {
+ sha512_final(this);
+ memcpy(buffer, this->sha_out, HASH_SIZE_SHA384);
+ this->public.hasher_interface.reset(&(this->public.hasher_interface));
+ }
+}
+
+/**
+ * Implementation of hasher_t.get_hash for SHA512.
+ */
+static void get_hash512(private_sha512_hasher_t *this,
+ chunk_t chunk, u_int8_t *buffer)
+{
+ sha512_write(this, chunk.ptr, chunk.len);
+ if (buffer != NULL)
+ {
+ sha512_final(this);
+ memcpy(buffer, this->sha_out, HASH_SIZE_SHA512);
+ this->public.hasher_interface.reset(&(this->public.hasher_interface));
+ }
+}
+
+/**
+ * Implementation of hasher_t.allocate_hash for SHA256.
+ */
+static void allocate_hash256(private_sha256_hasher_t *this,
+ chunk_t chunk, chunk_t *hash)
+{
+ chunk_t allocated_hash;
+
+ sha256_write(this, chunk.ptr, chunk.len);
+ if (hash != NULL)
+ {
+ sha256_final(this);
+ allocated_hash = chunk_alloc(HASH_SIZE_SHA256);
+ memcpy(allocated_hash.ptr, this->sha_out, HASH_SIZE_SHA256);
+ this->public.hasher_interface.reset(&(this->public.hasher_interface));
+ *hash = allocated_hash;
+ }
+}
+
+/**
+ * Implementation of hasher_t.allocate_hash for SHA384.
+ */
+static void allocate_hash384(private_sha512_hasher_t *this,
+ chunk_t chunk, chunk_t *hash)
+{
+ chunk_t allocated_hash;
+
+ sha512_write(this, chunk.ptr, chunk.len);
+ if (hash != NULL)
+ {
+ sha512_final(this);
+ allocated_hash = chunk_alloc(HASH_SIZE_SHA384);
+ memcpy(allocated_hash.ptr, this->sha_out, HASH_SIZE_SHA384);
+ this->public.hasher_interface.reset(&(this->public.hasher_interface));
+ *hash = allocated_hash;
+ }
+}
+
+/**
+ * Implementation of hasher_t.allocate_hash for SHA512.
+ */
+static void allocate_hash512(private_sha512_hasher_t *this,
+ chunk_t chunk, chunk_t *hash)
+{
+ chunk_t allocated_hash;
+
+ sha512_write(this, chunk.ptr, chunk.len);
+ if (hash != NULL)
+ {
+ sha512_final(this);
+ allocated_hash = chunk_alloc(HASH_SIZE_SHA512);
+ memcpy(allocated_hash.ptr, this->sha_out, HASH_SIZE_SHA512);
+ this->public.hasher_interface.reset(&(this->public.hasher_interface));
+ *hash = allocated_hash;
+ }
+}
+
+/**
+ * Implementation of hasher_t.get_hash_size for SHA256.
+ */
+static size_t get_hash_size256(private_sha256_hasher_t *this)
+{
+ return HASH_SIZE_SHA256;
+}
+
+/**
+ * Implementation of hasher_t.get_hash_size for SHA384.
+ */
+static size_t get_hash_size384(private_sha512_hasher_t *this)
+{
+ return HASH_SIZE_SHA384;
+}
+
+/**
+ * Implementation of hasher_t.get_hash_size for SHA512.
+ */
+static size_t get_hash_size512(private_sha512_hasher_t *this)
+{
+ return HASH_SIZE_SHA512;
+}
+
+/**
+ * Implementation of hasher_t.reset for SHA256
+ */
+static void reset256(private_sha256_hasher_t *ctx)
+{
+ memcpy(&ctx->sha_H[0], &sha256_hashInit[0], sizeof(ctx->sha_H));
+ ctx->sha_blocks = 0;
+ ctx->sha_bufCnt = 0;
+}
+
+/**
+ * Implementation of hasher_t.reset for SHA384
+ */
+static void reset384(private_sha512_hasher_t *ctx)
+{
+ memcpy(&ctx->sha_H[0], &sha384_hashInit[0], sizeof(ctx->sha_H));
+ ctx->sha_blocks = 0;
+ ctx->sha_blocksMSB = 0;
+ ctx->sha_bufCnt = 0;
+}
+
+/**
+ * Implementation of hasher_t.reset for SHA512
+ */
+static void reset512(private_sha512_hasher_t *ctx)
+{
+ memcpy(&ctx->sha_H[0], &sha512_hashInit[0], sizeof(ctx->sha_H));
+ ctx->sha_blocks = 0;
+ ctx->sha_blocksMSB = 0;
+ ctx->sha_bufCnt = 0;
+}
+
+/**
+ * Implementation of hasher_t.destroy.
+ */
+static void destroy(sha2_hasher_t *this)
+{
+ free(this);
+}
+
+/*
+ * Described in header.
+ */
+sha2_hasher_t *sha2_hasher_create(hash_algorithm_t algorithm)
+{
+ sha2_hasher_t *this;
+
+ switch (algorithm)
+ {
+ case HASH_SHA256:
+ this = (sha2_hasher_t*)malloc_thing(private_sha256_hasher_t);
+ this->hasher_interface.reset = (void(*)(hasher_t*))reset256;
+ this->hasher_interface.get_hash_size = (size_t(*)(hasher_t*))get_hash_size256;
+ this->hasher_interface.get_hash = (void(*)(hasher_t*,chunk_t,u_int8_t*))get_hash256;
+ this->hasher_interface.allocate_hash = (void(*)(hasher_t*,chunk_t,chunk_t*))allocate_hash256;
+ break;
+ case HASH_SHA384:
+ /* uses SHA512 data structure */
+ this = (sha2_hasher_t*)malloc_thing(private_sha512_hasher_t);
+ this->hasher_interface.reset = (void(*)(hasher_t*))reset384;
+ this->hasher_interface.get_hash_size = (size_t(*)(hasher_t*))get_hash_size384;
+ this->hasher_interface.get_hash = (void(*)(hasher_t*,chunk_t,u_int8_t*))get_hash384;
+ this->hasher_interface.allocate_hash = (void(*)(hasher_t*,chunk_t,chunk_t*))allocate_hash384;
+ break;
+ case HASH_SHA512:
+ this = (sha2_hasher_t*)malloc_thing(private_sha512_hasher_t);
+ this->hasher_interface.reset = (void(*)(hasher_t*))reset512;
+ this->hasher_interface.get_hash_size = (size_t(*)(hasher_t*))get_hash_size512;
+ this->hasher_interface.get_hash = (void(*)(hasher_t*,chunk_t,u_int8_t*))get_hash512;
+ this->hasher_interface.allocate_hash = (void(*)(hasher_t*,chunk_t,chunk_t*))allocate_hash512;
+ break;
+ default:
+ return NULL;
+ }
+ this->hasher_interface.destroy = (void(*)(hasher_t*))destroy;
+
+ /* initialize */
+ this->hasher_interface.reset(&this->hasher_interface);
+
+ return this;
+}
diff --git a/src/libstrongswan/plugins/sha2/sha2_hasher.h b/src/libstrongswan/plugins/sha2/sha2_hasher.h
new file mode 100644
index 000000000..6d732495a
--- /dev/null
+++ b/src/libstrongswan/plugins/sha2/sha2_hasher.h
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2006-2008 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.
+ */
+
+/**
+ * @defgroup sha2_hasher sha2_hasher
+ * @{ @ingroup sha2_p
+ */
+
+#ifndef SHA2_HASHER_H_
+#define SHA2_HASHER_H_
+
+typedef struct sha2_hasher_t sha2_hasher_t;
+
+#include <crypto/hashers/hasher.h>
+
+/**
+ * Implementation of hasher_t interface using the SHA2 algorithms.
+ *
+ * SHA2 is an other name for the SHA-256, SHA-384 and SHA-512 variants of
+ * the SHA hash algorithm.
+ */
+struct sha2_hasher_t {
+
+ /**
+ * Generic hasher_t interface for this hasher.
+ */
+ hasher_t hasher_interface;
+};
+
+/**
+ * Creates a new sha2_hasher_t.
+ *
+ * @param algorithm HASH_SHA256, HASH_SHA384 or HASH_SHA512
+ * @return sha2_hasher_t object, NULL if not supported
+ */
+sha2_hasher_t *sha2_hasher_create(hash_algorithm_t algorithm);
+
+#endif /* SHA2_HASHER_H_ @}*/
diff --git a/src/libstrongswan/plugins/sha2/sha2_plugin.c b/src/libstrongswan/plugins/sha2/sha2_plugin.c
new file mode 100644
index 000000000..ebb2947ef
--- /dev/null
+++ b/src/libstrongswan/plugins/sha2/sha2_plugin.c
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2008 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.
+ *
+ * $Id: sha2_plugin.c 3488 2008-02-21 15:10:02Z martin $
+ */
+
+#include "sha2_plugin.h"
+
+#include <library.h>
+#include "sha2_hasher.h"
+
+typedef struct private_sha2_plugin_t private_sha2_plugin_t;
+
+/**
+ * private data of sha2_plugin
+ */
+struct private_sha2_plugin_t {
+
+ /**
+ * public functions
+ */
+ sha2_plugin_t public;
+};
+
+/**
+ * Implementation of sha2_plugin_t.destroy
+ */
+static void destroy(private_sha2_plugin_t *this)
+{
+ lib->crypto->remove_hasher(lib->crypto,
+ (hasher_constructor_t)sha2_hasher_create);
+ free(this);
+}
+
+/*
+ * see header file
+ */
+plugin_t *plugin_create()
+{
+ private_sha2_plugin_t *this = malloc_thing(private_sha2_plugin_t);
+
+ this->public.plugin.destroy = (void(*)(plugin_t*))destroy;
+
+ lib->crypto->add_hasher(lib->crypto, HASH_SHA256,
+ (hasher_constructor_t)sha2_hasher_create);
+ lib->crypto->add_hasher(lib->crypto, HASH_SHA384,
+ (hasher_constructor_t)sha2_hasher_create);
+ lib->crypto->add_hasher(lib->crypto, HASH_SHA512,
+ (hasher_constructor_t)sha2_hasher_create);
+
+ return &this->public.plugin;
+}
+
diff --git a/src/libstrongswan/plugins/sha2/sha2_plugin.h b/src/libstrongswan/plugins/sha2/sha2_plugin.h
new file mode 100644
index 000000000..859597758
--- /dev/null
+++ b/src/libstrongswan/plugins/sha2/sha2_plugin.h
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2008 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.
+ */
+
+/**
+ * @defgroup sha2_p sha2
+ * @ingroup plugins
+ *
+ * @defgroup sha2_plugin sha2_plugin
+ * @{ @ingroup sha2_p
+ */
+
+#ifndef SHA2_PLUGIN_H_
+#define SHA2_PLUGIN_H_
+
+#include <plugins/plugin.h>
+
+typedef struct sha2_plugin_t sha2_plugin_t;
+
+/**
+ * Plugin implementing the SHA256, SHA384 and SHA512 algorithms in software.
+ */
+struct sha2_plugin_t {
+
+ /**
+ * implements plugin interface
+ */
+ plugin_t plugin;
+};
+
+/**
+ * Create a sha2_plugin instance.
+ */
+plugin_t *plugin_create();
+
+#endif /* SHA2_PLUGIN_H_ @}*/
diff --git a/src/libstrongswan/plugins/sqlite/Makefile.am b/src/libstrongswan/plugins/sqlite/Makefile.am
new file mode 100644
index 000000000..7c3017abf
--- /dev/null
+++ b/src/libstrongswan/plugins/sqlite/Makefile.am
@@ -0,0 +1,12 @@
+
+INCLUDES = -I$(top_srcdir)/src/libstrongswan
+
+AM_CFLAGS = -rdynamic
+
+plugin_LTLIBRARIES = libstrongswan-sqlite.la
+
+libstrongswan_sqlite_la_SOURCES = sqlite_plugin.h sqlite_plugin.c \
+ sqlite_database.h sqlite_database.c
+libstrongswan_sqlite_la_LDFLAGS = -module
+libstrongswan_sqlite_la_LIBADD = -lsqlite3
+
diff --git a/src/libstrongswan/plugins/sqlite/Makefile.in b/src/libstrongswan/plugins/sqlite/Makefile.in
new file mode 100644
index 000000000..3a73829dc
--- /dev/null
+++ b/src/libstrongswan/plugins/sqlite/Makefile.in
@@ -0,0 +1,499 @@
+# Makefile.in generated by automake 1.10.1 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+VPATH = @srcdir@
+pkgdatadir = $(datadir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+subdir = src/libstrongswan/plugins/sqlite
+DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/configure.in
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+mkinstalldirs = $(install_sh) -d
+CONFIG_CLEAN_FILES =
+am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
+am__vpath_adj = case $$p in \
+ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
+ *) f=$$p;; \
+ esac;
+am__strip_dir = `echo $$p | sed -e 's|^.*/||'`;
+am__installdirs = "$(DESTDIR)$(plugindir)"
+pluginLTLIBRARIES_INSTALL = $(INSTALL)
+LTLIBRARIES = $(plugin_LTLIBRARIES)
+libstrongswan_sqlite_la_DEPENDENCIES =
+am_libstrongswan_sqlite_la_OBJECTS = sqlite_plugin.lo \
+ sqlite_database.lo
+libstrongswan_sqlite_la_OBJECTS = \
+ $(am_libstrongswan_sqlite_la_OBJECTS)
+libstrongswan_sqlite_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(libstrongswan_sqlite_la_LDFLAGS) $(LDFLAGS) -o $@
+DEFAULT_INCLUDES = -I.@am__isrc@
+depcomp = $(SHELL) $(top_srcdir)/depcomp
+am__depfiles_maybe = depfiles
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+ --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
+ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+CCLD = $(CC)
+LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+ --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \
+ $(LDFLAGS) -o $@
+SOURCES = $(libstrongswan_sqlite_la_SOURCES)
+DIST_SOURCES = $(libstrongswan_sqlite_la_SOURCES)
+ETAGS = etags
+CTAGS = ctags
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+AMTAR = @AMTAR@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CXX = @CXX@
+CXXCPP = @CXXCPP@
+CXXDEPMODE = @CXXDEPMODE@
+CXXFLAGS = @CXXFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DSYMUTIL = @DSYMUTIL@
+ECHO = @ECHO@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+F77 = @F77@
+FFLAGS = @FFLAGS@
+GPERF = @GPERF@
+GREP = @GREP@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+IPSEC_ROUTING_TABLE = @IPSEC_ROUTING_TABLE@
+IPSEC_ROUTING_TABLE_PRIO = @IPSEC_ROUTING_TABLE_PRIO@
+LDFLAGS = @LDFLAGS@
+LEX = @LEX@
+LEXLIB = @LEXLIB@
+LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LINUX_HEADERS = @LINUX_HEADERS@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+MAKEINFO = @MAKEINFO@
+MKDIR_P = @MKDIR_P@
+NMEDIT = @NMEDIT@
+OBJEXT = @OBJEXT@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PERL = @PERL@
+PKG_CONFIG = @PKG_CONFIG@
+RANLIB = @RANLIB@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRIP = @STRIP@
+VERSION = @VERSION@
+YACC = @YACC@
+YFLAGS = @YFLAGS@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_CXX = @ac_ct_CXX@
+ac_ct_F77 = @ac_ct_F77@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+confdir = @confdir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+gtk_CFLAGS = @gtk_CFLAGS@
+gtk_LIBS = @gtk_LIBS@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+ipsecdir = @ipsecdir@
+ipsecgroup = @ipsecgroup@
+ipsecuser = @ipsecuser@
+libdir = @libdir@
+libexecdir = @libexecdir@
+libstrongswan_plugins = @libstrongswan_plugins@
+linuxdir = @linuxdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+piddir = @piddir@
+plugindir = @plugindir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+resolv_conf = @resolv_conf@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+simreader = @simreader@
+srcdir = @srcdir@
+strongswan_conf = @strongswan_conf@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+xml_CFLAGS = @xml_CFLAGS@
+xml_LIBS = @xml_LIBS@
+INCLUDES = -I$(top_srcdir)/src/libstrongswan
+AM_CFLAGS = -rdynamic
+plugin_LTLIBRARIES = libstrongswan-sqlite.la
+libstrongswan_sqlite_la_SOURCES = sqlite_plugin.h sqlite_plugin.c \
+ sqlite_database.h sqlite_database.c
+
+libstrongswan_sqlite_la_LDFLAGS = -module
+libstrongswan_sqlite_la_LIBADD = -lsqlite3
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .c .lo .o .obj
+$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \
+ && exit 0; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/libstrongswan/plugins/sqlite/Makefile'; \
+ cd $(top_srcdir) && \
+ $(AUTOMAKE) --gnu src/libstrongswan/plugins/sqlite/Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+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) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(pluginLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) '$$p' '$(DESTDIR)$(plugindir)/$$f'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(pluginLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) "$$p" "$(DESTDIR)$(plugindir)/$$f"; \
+ else :; fi; \
+ done
+
+uninstall-pluginLTLIBRARIES:
+ @$(NORMAL_UNINSTALL)
+ @list='$(plugin_LTLIBRARIES)'; for p in $$list; do \
+ p=$(am__strip_dir) \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(plugindir)/$$p'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(plugindir)/$$p"; \
+ 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
+libstrongswan-sqlite.la: $(libstrongswan_sqlite_la_OBJECTS) $(libstrongswan_sqlite_la_DEPENDENCIES)
+ $(libstrongswan_sqlite_la_LINK) -rpath $(plugindir) $(libstrongswan_sqlite_la_OBJECTS) $(libstrongswan_sqlite_la_LIBADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sqlite_database.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sqlite_plugin.Plo@am__quote@
+
+.c.o:
+@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(COMPILE) -c $<
+
+.c.obj:
+@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'`
+
+.c.lo:
+@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $<
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+
+ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonemtpy = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ mkid -fID $$unique
+tags: TAGS
+
+TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ tags=; \
+ here=`pwd`; \
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \
+ test -n "$$unique" || unique=$$empty_fix; \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ $$tags $$unique; \
+ fi
+ctags: CTAGS
+CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ tags=; \
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ test -z "$(CTAGS_ARGS)$$tags$$unique" \
+ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+ $$tags $$unique
+
+GTAGS:
+ here=`$(am__cd) $(top_builddir) && pwd` \
+ && cd $(top_srcdir) \
+ && gtags -i $(GTAGS_ARGS) $$here
+
+distclean-tags:
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+distdir: $(DISTFILES)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ list='$(DISTFILES)'; \
+ dist_files=`for file in $$list; do echo $$file; done | \
+ sed -e "s|^$$srcdirstrip/||;t" \
+ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+ case $$dist_files in \
+ */*) $(MKDIR_P) `echo "$$dist_files" | \
+ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+ sort -u` ;; \
+ esac; \
+ for file in $$dist_files; do \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ if test -d $$d/$$file; then \
+ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
+ fi; \
+ cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
+ else \
+ test -f $(distdir)/$$file \
+ || cp -p $$d/$$file $(distdir)/$$file \
+ || exit 1; \
+ fi; \
+ done
+check-am: all-am
+check: check-am
+all-am: Makefile $(LTLIBRARIES)
+installdirs:
+ for dir in "$(DESTDIR)$(plugindir)"; do \
+ test -z "$$dir" || $(MKDIR_P) "$$dir"; \
+ done
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ `test -z '$(STRIP)' || \
+ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+clean: clean-am
+
+clean-am: clean-generic clean-libtool clean-pluginLTLIBRARIES \
+ mostlyclean-am
+
+distclean: distclean-am
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+ distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+info: info-am
+
+info-am:
+
+install-data-am: install-pluginLTLIBRARIES
+
+install-dvi: install-dvi-am
+
+install-exec-am:
+
+install-html: install-html-am
+
+install-info: install-info-am
+
+install-man:
+
+install-pdf: install-pdf-am
+
+install-ps: install-ps-am
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic \
+ mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am: uninstall-pluginLTLIBRARIES
+
+.MAKE: install-am install-strip
+
+.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \
+ clean-libtool clean-pluginLTLIBRARIES ctags distclean \
+ distclean-compile distclean-generic distclean-libtool \
+ distclean-tags distdir dvi dvi-am html html-am info info-am \
+ install install-am install-data install-data-am install-dvi \
+ install-dvi-am install-exec install-exec-am install-html \
+ install-html-am install-info install-info-am install-man \
+ install-pdf install-pdf-am install-pluginLTLIBRARIES \
+ install-ps install-ps-am install-strip installcheck \
+ installcheck-am installdirs maintainer-clean \
+ maintainer-clean-generic mostlyclean mostlyclean-compile \
+ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
+ tags uninstall uninstall-am uninstall-pluginLTLIBRARIES
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/src/libstrongswan/plugins/sqlite/sqlite_database.c b/src/libstrongswan/plugins/sqlite/sqlite_database.c
new file mode 100644
index 000000000..d5a03894d
--- /dev/null
+++ b/src/libstrongswan/plugins/sqlite/sqlite_database.c
@@ -0,0 +1,321 @@
+/*
+ * 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.
+ *
+ * $Id: sqlite_database.c 3911 2008-05-07 14:41:13Z martin $
+ */
+
+#include "sqlite_database.h"
+
+#include <sqlite3.h>
+#include <library.h>
+#include <debug.h>
+#include <utils/mutex.h>
+
+typedef struct private_sqlite_database_t private_sqlite_database_t;
+
+/**
+ * private data of sqlite_database
+ */
+struct private_sqlite_database_t {
+
+ /**
+ * public functions
+ */
+ sqlite_database_t public;
+
+ /**
+ * sqlite database connection
+ */
+ sqlite3 *db;
+
+ /**
+ * mutex used to lock execute()
+ */
+ mutex_t *mutex;
+};
+
+/**
+ * Create and run a sqlite stmt using a sql string and args
+ */
+static sqlite3_stmt* run(private_sqlite_database_t *this, char *sql,
+ va_list *args)
+{
+ sqlite3_stmt *stmt = NULL;
+ int params, i, res = SQLITE_OK;
+
+#ifdef HAVE_SQLITE3_PREPARE_V2
+ if (sqlite3_prepare_v2(this->db, sql, -1, &stmt, NULL) == SQLITE_OK)
+#else
+ if (sqlite3_prepare(this->db, sql, -1, &stmt, NULL) == SQLITE_OK)
+#endif
+ {
+ params = sqlite3_bind_parameter_count(stmt);
+ for (i = 1; i <= params; i++)
+ {
+ switch (va_arg(*args, db_type_t))
+ {
+ case DB_INT:
+ {
+ res = sqlite3_bind_int(stmt, i, va_arg(*args, int));
+ break;
+ }
+ case DB_UINT:
+ {
+ res = sqlite3_bind_int64(stmt, i, va_arg(*args, u_int));
+ break;
+ }
+ case DB_TEXT:
+ {
+ const char *text = va_arg(*args, const char*);
+ res = sqlite3_bind_text(stmt, i, text, -1, SQLITE_STATIC);
+ break;
+ }
+ case DB_BLOB:
+ {
+ chunk_t c = va_arg(*args, chunk_t);
+ res = sqlite3_bind_blob(stmt, i, c.ptr, c.len, SQLITE_STATIC);
+ break;
+ }
+ case DB_DOUBLE:
+ {
+ res = sqlite3_bind_double(stmt, i, va_arg(*args, double));
+ break;
+ }
+ case DB_NULL:
+ {
+ res = sqlite3_bind_null(stmt, i);
+ break;
+ }
+ default:
+ {
+ res = SQLITE_MISUSE;
+ break;
+ }
+ }
+ if (res != SQLITE_OK)
+ {
+ break;
+ }
+ }
+ }
+ else
+ {
+ DBG1("preparing sqlite statement failed: %s", sqlite3_errmsg(this->db));
+ }
+ if (res != SQLITE_OK)
+ {
+ DBG1("binding sqlite statement failed: %s", sqlite3_errmsg(this->db));
+ sqlite3_finalize(stmt);
+ return NULL;
+ }
+ return stmt;
+}
+
+typedef struct {
+ /** implements enumerator_t */
+ enumerator_t public;
+ /** associated sqlite statement */
+ sqlite3_stmt *stmt;
+ /** number of result columns */
+ int count;
+ /** column types */
+ db_type_t *columns;
+ /** reference to db connection */
+ sqlite3 *db;
+} sqlite_enumerator_t;
+
+/**
+ * destroy a sqlite enumerator
+ */
+static void sqlite_enumerator_destroy(sqlite_enumerator_t *this)
+{
+ sqlite3_finalize(this->stmt);
+ free(this->columns);
+ free(this);
+}
+
+/**
+ * Implementation of database.query().enumerate
+ */
+static bool sqlite_enumerator_enumerate(sqlite_enumerator_t *this, ...)
+{
+ int i;
+ va_list args;
+
+ switch (sqlite3_step(this->stmt))
+ {
+ case SQLITE_ROW:
+ break;
+ default:
+ DBG1("stepping sqlite statement failed: %s", sqlite3_errmsg(this->db));
+ /* fall */
+ case SQLITE_DONE:
+ return FALSE;
+ }
+ va_start(args, this);
+ for (i = 0; i < this->count; i++)
+ {
+ switch (this->columns[i])
+ {
+ case DB_INT:
+ {
+ int *value = va_arg(args, int*);
+ *value = sqlite3_column_int(this->stmt, i);
+ break;
+ }
+ case DB_UINT:
+ {
+ u_int *value = va_arg(args, u_int*);
+ *value = (u_int)sqlite3_column_int64(this->stmt, i);
+ break;
+ }
+ case DB_TEXT:
+ {
+ const unsigned char **value = va_arg(args, const unsigned char**);
+ *value = sqlite3_column_text(this->stmt, i);
+ break;
+ }
+ case DB_BLOB:
+ {
+ chunk_t *chunk = va_arg(args, chunk_t*);
+ chunk->len = sqlite3_column_bytes(this->stmt, i);
+ chunk->ptr = (u_char*)sqlite3_column_blob(this->stmt, i);
+ break;
+ }
+ case DB_DOUBLE:
+ {
+ double *value = va_arg(args, double*);
+ *value = sqlite3_column_double(this->stmt, i);
+ break;
+ }
+ default:
+ DBG1("invalid result type supplied");
+ return FALSE;
+ }
+ }
+ va_end(args);
+ return TRUE;
+}
+
+/**
+ * Implementation of database_t.query.
+ */
+static enumerator_t* query(private_sqlite_database_t *this, char *sql, ...)
+{
+ sqlite3_stmt *stmt;
+ va_list args;
+ sqlite_enumerator_t *enumerator = NULL;
+ int i;
+
+
+ va_start(args, sql);
+ stmt = run(this, sql, &args);
+ if (stmt)
+ {
+ enumerator = malloc_thing(sqlite_enumerator_t);
+ enumerator->public.enumerate = (void*)sqlite_enumerator_enumerate;
+ enumerator->public.destroy = (void*)sqlite_enumerator_destroy;
+ enumerator->stmt = stmt;
+ enumerator->count = sqlite3_column_count(stmt);
+ enumerator->columns = malloc(sizeof(db_type_t) * enumerator->count);
+ enumerator->db = this->db;
+ for (i = 0; i < enumerator->count; i++)
+ {
+ enumerator->columns[i] = va_arg(args, db_type_t);
+ }
+ }
+ va_end(args);
+ return (enumerator_t*)enumerator;
+}
+
+/**
+ * Implementation of database_t.execute.
+ */
+static int execute(private_sqlite_database_t *this, int *rowid, char *sql, ...)
+{
+ sqlite3_stmt *stmt;
+ int affected = -1;
+ va_list args;
+
+ /* we need a lock to get our rowid/changes correctly */
+ this->mutex->lock(this->mutex);
+ va_start(args, sql);
+ stmt = run(this, sql, &args);
+ va_end(args);
+ if (stmt)
+ {
+ if (sqlite3_step(stmt) == SQLITE_DONE)
+ {
+ if (rowid)
+ {
+ *rowid = sqlite3_last_insert_rowid(this->db);
+ }
+ affected = sqlite3_changes(this->db);
+ }
+ else
+ {
+ DBG1("sqlite execute failed: %s", sqlite3_errmsg(this->db));
+ }
+ sqlite3_finalize(stmt);
+ }
+ this->mutex->unlock(this->mutex);
+ return affected;
+}
+
+/**
+ * Implementation of database_t.destroy
+ */
+static void destroy(private_sqlite_database_t *this)
+{
+ sqlite3_close(this->db);
+ this->mutex->destroy(this->mutex);
+ free(this);
+}
+
+/*
+ * see header file
+ */
+sqlite_database_t *sqlite_database_create(char *uri)
+{
+ char *file;
+ private_sqlite_database_t *this;
+
+ /**
+ * parse sqlite:///path/to/file.db uri
+ */
+ if (!strneq(uri, "sqlite://", 9))
+ {
+ return NULL;
+ }
+ file = uri + 9;
+
+ this = malloc_thing(private_sqlite_database_t);
+
+ this->public.db.query = (enumerator_t* (*)(database_t *this, char *sql, ...))query;
+ this->public.db.execute = (int (*)(database_t *this, int *rowid, char *sql, ...))execute;
+ this->public.db.destroy = (void(*)(database_t*))destroy;
+
+ this->mutex = mutex_create(MUTEX_DEFAULT);
+
+ if (sqlite3_open(file, &this->db) != SQLITE_OK)
+ {
+ DBG1("opening SQLite database '%s' failed: %s",
+ file, sqlite3_errmsg(this->db));
+ destroy(this);
+ return NULL;
+ }
+
+ return &this->public;
+}
+
diff --git a/src/libstrongswan/plugins/sqlite/sqlite_database.h b/src/libstrongswan/plugins/sqlite/sqlite_database.h
new file mode 100644
index 000000000..795785627
--- /dev/null
+++ b/src/libstrongswan/plugins/sqlite/sqlite_database.h
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2007-2008 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.
+ */
+
+/**
+ * @defgroup sqlite_database sqlite_database
+ * @{ @ingroup sqlite_p
+ */
+
+#ifndef SQLITE_DATABASE_H_
+#define SQLITE_DATABASE_H_
+
+#include <database/database.h>
+
+typedef struct sqlite_database_t sqlite_database_t;
+
+/**
+ * sqlite databse_t implementation.
+ */
+struct sqlite_database_t {
+
+ /**
+ * Implements database_t
+ */
+ database_t db;
+};
+
+/**
+ * Create a sqlite_database instance.
+ *
+ * @param uri connection URI, sqlite:///path/to/file.db
+ */
+sqlite_database_t *sqlite_database_create(char *uri);
+
+#endif /* SQLITE_DATABASE_H_ @}*/
diff --git a/src/libstrongswan/plugins/sqlite/sqlite_plugin.c b/src/libstrongswan/plugins/sqlite/sqlite_plugin.c
new file mode 100644
index 000000000..441e59a5e
--- /dev/null
+++ b/src/libstrongswan/plugins/sqlite/sqlite_plugin.c
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2008 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.
+ *
+ * $Id: sqlite_plugin.c 3488 2008-02-21 15:10:02Z martin $
+ */
+
+#include "sqlite_plugin.h"
+
+#include <library.h>
+#include "sqlite_database.h"
+
+typedef struct private_sqlite_plugin_t private_sqlite_plugin_t;
+
+/**
+ * private data of sqlite_plugin
+ */
+struct private_sqlite_plugin_t {
+
+ /**
+ * public functions
+ */
+ sqlite_plugin_t public;
+};
+
+/**
+ * Implementation of plugin_t.destroy
+ */
+static void destroy(private_sqlite_plugin_t *this)
+{
+ lib->db->remove_database(lib->db,
+ (database_constructor_t)sqlite_database_create);
+ free(this);
+}
+
+/*
+ * see header file
+ */
+plugin_t *plugin_create()
+{
+ private_sqlite_plugin_t *this = malloc_thing(private_sqlite_plugin_t);
+
+ this->public.plugin.destroy = (void(*)(plugin_t*))destroy;
+
+ lib->db->add_database(lib->db,
+ (database_constructor_t)sqlite_database_create);
+
+ return &this->public.plugin;
+}
+
diff --git a/src/libstrongswan/plugins/sqlite/sqlite_plugin.h b/src/libstrongswan/plugins/sqlite/sqlite_plugin.h
new file mode 100644
index 000000000..07bf9618f
--- /dev/null
+++ b/src/libstrongswan/plugins/sqlite/sqlite_plugin.h
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2008 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.
+ */
+
+/**
+ * @defgroup sqlite_p sqlite
+ * @ingroup plugins
+ *
+ * @defgroup sqlite_plugin sqlite_plugin
+ * @{ @ingroup sqlite_p
+ */
+
+#ifndef SQLITE_PLUGIN_H_
+#define SQLITE_PLUGIN_H_
+
+#include <plugins/plugin.h>
+
+typedef struct sqlite_plugin_t sqlite_plugin_t;
+
+/**
+ * Plugin implementing sqlite database connectivity
+ */
+struct sqlite_plugin_t {
+
+ /**
+ * implements plugin interface
+ */
+ plugin_t plugin;
+};
+
+/**
+ * Create a sqlite_plugin instance.
+ */
+plugin_t *plugin_create();
+
+#endif /* SQLITE_PLUGIN_H_ @}*/
diff --git a/src/libstrongswan/plugins/x509/Makefile.am b/src/libstrongswan/plugins/x509/Makefile.am
new file mode 100644
index 000000000..3f9f85c36
--- /dev/null
+++ b/src/libstrongswan/plugins/x509/Makefile.am
@@ -0,0 +1,16 @@
+
+INCLUDES = -I$(top_srcdir)/src/libstrongswan
+
+AM_CFLAGS = -rdynamic
+
+plugin_LTLIBRARIES = libstrongswan-x509.la
+
+libstrongswan_x509_la_SOURCES = x509_plugin.h x509_plugin.c \
+ x509_cert.h x509_cert.c \
+ x509_crl.h x509_crl.c \
+ x509_ac.h x509_ac.c \
+ x509_ocsp_request.h x509_ocsp_request.c \
+ x509_ocsp_response.h x509_ocsp_response.c \
+ ietf_attr_list.h ietf_attr_list.c
+libstrongswan_x509_la_LDFLAGS = -module
+
diff --git a/src/libstrongswan/plugins/x509/Makefile.in b/src/libstrongswan/plugins/x509/Makefile.in
new file mode 100644
index 000000000..9178d6c8c
--- /dev/null
+++ b/src/libstrongswan/plugins/x509/Makefile.in
@@ -0,0 +1,508 @@
+# Makefile.in generated by automake 1.10.1 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+VPATH = @srcdir@
+pkgdatadir = $(datadir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+subdir = src/libstrongswan/plugins/x509
+DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/configure.in
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+mkinstalldirs = $(install_sh) -d
+CONFIG_CLEAN_FILES =
+am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
+am__vpath_adj = case $$p in \
+ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
+ *) f=$$p;; \
+ esac;
+am__strip_dir = `echo $$p | sed -e 's|^.*/||'`;
+am__installdirs = "$(DESTDIR)$(plugindir)"
+pluginLTLIBRARIES_INSTALL = $(INSTALL)
+LTLIBRARIES = $(plugin_LTLIBRARIES)
+libstrongswan_x509_la_LIBADD =
+am_libstrongswan_x509_la_OBJECTS = x509_plugin.lo x509_cert.lo \
+ x509_crl.lo x509_ac.lo x509_ocsp_request.lo \
+ x509_ocsp_response.lo ietf_attr_list.lo
+libstrongswan_x509_la_OBJECTS = $(am_libstrongswan_x509_la_OBJECTS)
+libstrongswan_x509_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(libstrongswan_x509_la_LDFLAGS) $(LDFLAGS) -o $@
+DEFAULT_INCLUDES = -I.@am__isrc@
+depcomp = $(SHELL) $(top_srcdir)/depcomp
+am__depfiles_maybe = depfiles
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+ --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
+ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+CCLD = $(CC)
+LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+ --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \
+ $(LDFLAGS) -o $@
+SOURCES = $(libstrongswan_x509_la_SOURCES)
+DIST_SOURCES = $(libstrongswan_x509_la_SOURCES)
+ETAGS = etags
+CTAGS = ctags
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+AMTAR = @AMTAR@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CXX = @CXX@
+CXXCPP = @CXXCPP@
+CXXDEPMODE = @CXXDEPMODE@
+CXXFLAGS = @CXXFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DSYMUTIL = @DSYMUTIL@
+ECHO = @ECHO@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+F77 = @F77@
+FFLAGS = @FFLAGS@
+GPERF = @GPERF@
+GREP = @GREP@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+IPSEC_ROUTING_TABLE = @IPSEC_ROUTING_TABLE@
+IPSEC_ROUTING_TABLE_PRIO = @IPSEC_ROUTING_TABLE_PRIO@
+LDFLAGS = @LDFLAGS@
+LEX = @LEX@
+LEXLIB = @LEXLIB@
+LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LINUX_HEADERS = @LINUX_HEADERS@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+MAKEINFO = @MAKEINFO@
+MKDIR_P = @MKDIR_P@
+NMEDIT = @NMEDIT@
+OBJEXT = @OBJEXT@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PERL = @PERL@
+PKG_CONFIG = @PKG_CONFIG@
+RANLIB = @RANLIB@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRIP = @STRIP@
+VERSION = @VERSION@
+YACC = @YACC@
+YFLAGS = @YFLAGS@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_CXX = @ac_ct_CXX@
+ac_ct_F77 = @ac_ct_F77@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+confdir = @confdir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+gtk_CFLAGS = @gtk_CFLAGS@
+gtk_LIBS = @gtk_LIBS@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+ipsecdir = @ipsecdir@
+ipsecgroup = @ipsecgroup@
+ipsecuser = @ipsecuser@
+libdir = @libdir@
+libexecdir = @libexecdir@
+libstrongswan_plugins = @libstrongswan_plugins@
+linuxdir = @linuxdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+piddir = @piddir@
+plugindir = @plugindir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+resolv_conf = @resolv_conf@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+simreader = @simreader@
+srcdir = @srcdir@
+strongswan_conf = @strongswan_conf@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+xml_CFLAGS = @xml_CFLAGS@
+xml_LIBS = @xml_LIBS@
+INCLUDES = -I$(top_srcdir)/src/libstrongswan
+AM_CFLAGS = -rdynamic
+plugin_LTLIBRARIES = libstrongswan-x509.la
+libstrongswan_x509_la_SOURCES = x509_plugin.h x509_plugin.c \
+ x509_cert.h x509_cert.c \
+ x509_crl.h x509_crl.c \
+ x509_ac.h x509_ac.c \
+ x509_ocsp_request.h x509_ocsp_request.c \
+ x509_ocsp_response.h x509_ocsp_response.c \
+ ietf_attr_list.h ietf_attr_list.c
+
+libstrongswan_x509_la_LDFLAGS = -module
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .c .lo .o .obj
+$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \
+ && exit 0; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/libstrongswan/plugins/x509/Makefile'; \
+ cd $(top_srcdir) && \
+ $(AUTOMAKE) --gnu src/libstrongswan/plugins/x509/Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+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) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(pluginLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) '$$p' '$(DESTDIR)$(plugindir)/$$f'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(pluginLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) "$$p" "$(DESTDIR)$(plugindir)/$$f"; \
+ else :; fi; \
+ done
+
+uninstall-pluginLTLIBRARIES:
+ @$(NORMAL_UNINSTALL)
+ @list='$(plugin_LTLIBRARIES)'; for p in $$list; do \
+ p=$(am__strip_dir) \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(plugindir)/$$p'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(plugindir)/$$p"; \
+ 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
+libstrongswan-x509.la: $(libstrongswan_x509_la_OBJECTS) $(libstrongswan_x509_la_DEPENDENCIES)
+ $(libstrongswan_x509_la_LINK) -rpath $(plugindir) $(libstrongswan_x509_la_OBJECTS) $(libstrongswan_x509_la_LIBADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ietf_attr_list.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/x509_ac.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/x509_cert.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/x509_crl.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/x509_ocsp_request.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/x509_ocsp_response.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/x509_plugin.Plo@am__quote@
+
+.c.o:
+@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(COMPILE) -c $<
+
+.c.obj:
+@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'`
+
+.c.lo:
+@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $<
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+
+ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonemtpy = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ mkid -fID $$unique
+tags: TAGS
+
+TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ tags=; \
+ here=`pwd`; \
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \
+ test -n "$$unique" || unique=$$empty_fix; \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ $$tags $$unique; \
+ fi
+ctags: CTAGS
+CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ tags=; \
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ test -z "$(CTAGS_ARGS)$$tags$$unique" \
+ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+ $$tags $$unique
+
+GTAGS:
+ here=`$(am__cd) $(top_builddir) && pwd` \
+ && cd $(top_srcdir) \
+ && gtags -i $(GTAGS_ARGS) $$here
+
+distclean-tags:
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+distdir: $(DISTFILES)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ list='$(DISTFILES)'; \
+ dist_files=`for file in $$list; do echo $$file; done | \
+ sed -e "s|^$$srcdirstrip/||;t" \
+ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+ case $$dist_files in \
+ */*) $(MKDIR_P) `echo "$$dist_files" | \
+ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+ sort -u` ;; \
+ esac; \
+ for file in $$dist_files; do \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ if test -d $$d/$$file; then \
+ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
+ fi; \
+ cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
+ else \
+ test -f $(distdir)/$$file \
+ || cp -p $$d/$$file $(distdir)/$$file \
+ || exit 1; \
+ fi; \
+ done
+check-am: all-am
+check: check-am
+all-am: Makefile $(LTLIBRARIES)
+installdirs:
+ for dir in "$(DESTDIR)$(plugindir)"; do \
+ test -z "$$dir" || $(MKDIR_P) "$$dir"; \
+ done
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ `test -z '$(STRIP)' || \
+ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+clean: clean-am
+
+clean-am: clean-generic clean-libtool clean-pluginLTLIBRARIES \
+ mostlyclean-am
+
+distclean: distclean-am
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+ distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+info: info-am
+
+info-am:
+
+install-data-am: install-pluginLTLIBRARIES
+
+install-dvi: install-dvi-am
+
+install-exec-am:
+
+install-html: install-html-am
+
+install-info: install-info-am
+
+install-man:
+
+install-pdf: install-pdf-am
+
+install-ps: install-ps-am
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic \
+ mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am: uninstall-pluginLTLIBRARIES
+
+.MAKE: install-am install-strip
+
+.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \
+ clean-libtool clean-pluginLTLIBRARIES ctags distclean \
+ distclean-compile distclean-generic distclean-libtool \
+ distclean-tags distdir dvi dvi-am html html-am info info-am \
+ install install-am install-data install-data-am install-dvi \
+ install-dvi-am install-exec install-exec-am install-html \
+ install-html-am install-info install-info-am install-man \
+ install-pdf install-pdf-am install-pluginLTLIBRARIES \
+ install-ps install-ps-am install-strip installcheck \
+ installcheck-am installdirs maintainer-clean \
+ maintainer-clean-generic mostlyclean mostlyclean-compile \
+ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
+ tags uninstall uninstall-am uninstall-pluginLTLIBRARIES
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/src/libstrongswan/plugins/x509/ietf_attr_list.c b/src/libstrongswan/plugins/x509/ietf_attr_list.c
new file mode 100644
index 000000000..17f6949b2
--- /dev/null
+++ b/src/libstrongswan/plugins/x509/ietf_attr_list.c
@@ -0,0 +1,396 @@
+/*
+ * Copyright (C) 2007 Andreas Steffen, Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+#include <string.h>
+#include <stdio.h>
+
+#include <debug.h>
+#include <library.h>
+
+#include <asn1/oid.h>
+#include <asn1/asn1.h>
+#include <asn1/asn1_parser.h>
+#include <utils/lexparser.h>
+
+#include "ietf_attr_list.h"
+
+/**
+ * Private definition of ietfAttribute kinds
+ */
+typedef enum {
+ IETF_ATTRIBUTE_OCTETS = 0,
+ IETF_ATTRIBUTE_OID = 1,
+ IETF_ATTRIBUTE_STRING = 2
+} ietfAttribute_t;
+
+typedef struct ietfAttr_t ietfAttr_t;
+
+/**
+ * Private definition of an ietfAttribute
+ */
+struct ietfAttr_t {
+ /**
+ * IETF attribute kind
+ */
+ ietfAttribute_t kind;
+
+ /**
+ * IETF attribute valuse
+ */
+ chunk_t value;
+
+ /**
+ * Compares two ietfAttributes
+ *
+ * return -1 if this is earlier in the alphabet than other
+ * return 0 if this equals other
+ * return +1 if this is later in the alphabet than other
+ *
+ * @param this calling object
+ * @param other other object
+ */
+ int (*compare) (const ietfAttr_t *this ,const ietfAttr_t *other);
+
+ /**
+ * Destroys the ietfAttr_t object.
+ *
+ * @param this ietfAttr_t to destroy
+ */
+ void (*destroy) (ietfAttr_t *this);
+};
+
+/**
+ * Implements ietfAttr_t.compare.
+ */
+static int ietfAttr_compare(const ietfAttr_t *this ,const ietfAttr_t *other)
+{
+ int cmp_len, len, cmp_value;
+
+ /* OID attributes are appended after STRING and OCTETS attributes */
+ if (this->kind != IETF_ATTRIBUTE_OID && other->kind == IETF_ATTRIBUTE_OID)
+ {
+ return -1;
+ }
+ if (this->kind == IETF_ATTRIBUTE_OID && other->kind != IETF_ATTRIBUTE_OID)
+ {
+ return 1;
+ }
+
+ cmp_len = this->value.len - other->value.len;
+ len = (cmp_len < 0)? this->value.len : other->value.len;
+ cmp_value = memcmp(this->value.ptr, other->value.ptr, len);
+
+ return (cmp_value == 0)? cmp_len : cmp_value;
+}
+
+/**
+ * Implements ietfAttr_t.destroy.
+ */
+static void ietfAttr_destroy(ietfAttr_t *this)
+{
+ free(this->value.ptr);
+ free(this);
+}
+
+/**
+ * Creates an ietfAttr_t object.
+ */
+static ietfAttr_t *ietfAttr_create(ietfAttribute_t kind, chunk_t value)
+{
+ ietfAttr_t *this = malloc_thing(ietfAttr_t);
+
+ /* initialize */
+ this->kind = kind;
+ this->value = chunk_clone(value);
+
+ /* function */
+ this->compare = ietfAttr_compare;
+ this->destroy = ietfAttr_destroy;
+
+ return this;
+}
+
+/**
+ * Adds an ietfAttr_t object to a sorted linked list
+ */
+static void ietfAttr_add(linked_list_t *list, ietfAttr_t *attr)
+{
+ iterator_t *iterator = list->create_iterator(list, TRUE);
+ ietfAttr_t *current_attr;
+ bool found = FALSE;
+
+ while (iterator->iterate(iterator, (void **)&current_attr))
+ {
+ int cmp = attr->compare(attr, current_attr);
+
+ if (cmp > 0)
+ {
+ continue;
+ }
+ if (cmp == 0)
+ {
+ attr->destroy(attr);
+ }
+ else
+ {
+ iterator->insert_before(iterator, attr);
+ }
+ found = TRUE;
+ break;
+ }
+ iterator->destroy(iterator);
+ if (!found)
+ {
+ list->insert_last(list, attr);
+ }
+}
+
+/*
+ * Described in header.
+ */
+bool ietfAttr_list_equals(linked_list_t *list_a, linked_list_t *list_b)
+{
+ bool result = TRUE;
+
+ /* lists must have the same number of attributes */
+ if (list_a->get_count(list_a) != list_b->get_count(list_b))
+ {
+ return FALSE;
+ }
+ /* empty lists - no attributes */
+ if (list_a->get_count(list_a) == 0)
+ {
+ return TRUE;
+ }
+
+ /* compare two alphabetically-sorted lists */
+ {
+ iterator_t *iterator_a = list_a->create_iterator(list_a, TRUE);
+ iterator_t *iterator_b = list_b->create_iterator(list_b, TRUE);
+ ietfAttr_t *attr_a, *attr_b;
+
+ while (iterator_a->iterate(iterator_a, (void **)&attr_a) &&
+ iterator_b->iterate(iterator_b, (void **)&attr_b))
+ {
+ if (attr_a->compare(attr_a, attr_b) != 0)
+ {
+ /* we have a mismatch */
+ result = FALSE;
+ break;
+ }
+ }
+ iterator_a->destroy(iterator_a);
+ iterator_b->destroy(iterator_b);
+ }
+ return result;
+}
+
+/*
+ * Described in header.
+ */
+void ietfAttr_list_list(linked_list_t *list, FILE *out)
+{
+ iterator_t *iterator = list->create_iterator(list, TRUE);
+ ietfAttr_t *attr;
+ bool first = TRUE;
+
+ while (iterator->iterate(iterator, (void **)&attr))
+ {
+ if (first)
+ {
+ first = FALSE;
+ }
+ else
+ {
+ fprintf(out, ", ");
+ }
+
+ switch (attr->kind)
+ {
+ case IETF_ATTRIBUTE_OCTETS:
+ case IETF_ATTRIBUTE_STRING:
+ fprintf(out, "%.*s", (int)attr->value.len, attr->value.ptr);
+ break;
+ case IETF_ATTRIBUTE_OID:
+ {
+ int oid = asn1_known_oid(attr->value);
+
+ if (oid == OID_UNKNOWN)
+ {
+ fprintf(out, "0x#B", &attr->value);
+ }
+ else
+ {
+ fprintf(out, "%s", oid_names[oid]);
+ }
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ iterator->destroy(iterator);
+}
+
+/*
+ * Described in header.
+ */
+void ietfAttr_list_create_from_string(char *msg, linked_list_t *list)
+{
+ chunk_t line = { msg, strlen(msg) };
+
+ while (eat_whitespace(&line))
+ {
+ chunk_t group;
+
+ /* extract the next comma-separated group attribute */
+ if (!extract_token(&group, ',', &line))
+ {
+ group = line;
+ line.len = 0;
+ }
+
+ /* remove any trailing spaces */
+ while (group.len > 0 && *(group.ptr + group.len - 1) == ' ')
+ {
+ group.len--;
+ }
+
+ /* add the group attribute to the list */
+ if (group.len > 0)
+ {
+ ietfAttr_t *attr = ietfAttr_create(IETF_ATTRIBUTE_STRING, group);
+
+ ietfAttr_add(list, attr);
+ }
+ }
+}
+
+/**
+ * ASN.1 definition of ietfAttrSyntax
+ */
+static const asn1Object_t ietfAttrSyntaxObjects[] =
+{
+ { 0, "ietfAttrSyntax", ASN1_SEQUENCE, ASN1_NONE }, /* 0 */
+ { 1, "policyAuthority", ASN1_CONTEXT_C_0, ASN1_OPT |
+ ASN1_BODY }, /* 1 */
+ { 1, "end opt", ASN1_EOC, ASN1_END }, /* 2 */
+ { 1, "values", ASN1_SEQUENCE, ASN1_LOOP }, /* 3 */
+ { 2, "octets", ASN1_OCTET_STRING, ASN1_OPT |
+ ASN1_BODY }, /* 4 */
+ { 2, "end choice", ASN1_EOC, ASN1_END }, /* 5 */
+ { 2, "oid", ASN1_OID, ASN1_OPT |
+ ASN1_BODY }, /* 6 */
+ { 2, "end choice", ASN1_EOC, ASN1_END }, /* 7 */
+ { 2, "string", ASN1_UTF8STRING, ASN1_OPT |
+ ASN1_BODY }, /* 8 */
+ { 2, "end choice", ASN1_EOC, ASN1_END }, /* 9 */
+ { 1, "end loop", ASN1_EOC, ASN1_END }, /* 10 */
+ { 0, "exit", ASN1_EOC, ASN1_EXIT }
+};
+#define IETF_ATTR_OCTETS 4
+#define IETF_ATTR_OID 6
+#define IETF_ATTR_STRING 8
+
+/*
+ * Described in header.
+ */
+void ietfAttr_list_create_from_chunk(chunk_t chunk, linked_list_t *list, int level0)
+{
+ asn1_parser_t *parser;
+ chunk_t object;
+ int objectID;
+
+ parser = asn1_parser_create(ietfAttrSyntaxObjects, chunk);
+ parser->set_top_level(parser, level0);
+
+ while (parser->iterate(parser, &objectID, &object))
+ {
+ switch (objectID)
+ {
+ case IETF_ATTR_OCTETS:
+ case IETF_ATTR_OID:
+ case IETF_ATTR_STRING:
+ {
+ ietfAttribute_t kind = (objectID - IETF_ATTR_OCTETS) / 2;
+ ietfAttr_t *attr = ietfAttr_create(kind, object);
+ ietfAttr_add(list, attr);
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ parser->destroy(parser);
+}
+
+/*
+ * Described in header.
+ */
+chunk_t ietfAttr_list_encode(linked_list_t *list)
+{
+ chunk_t ietfAttributes;
+ size_t size = 0;
+ u_char *pos;
+ iterator_t *iterator = list->create_iterator(list, TRUE);
+ ietfAttr_t *attr;
+
+ /* precalculate the total size of all values */
+ while (iterator->iterate(iterator, (void **)&attr))
+ {
+ size_t len = attr->value.len;
+
+ size += 1 + (len > 0) + (len >= 128) + (len >= 256) + (len >= 65536) + len;
+ }
+ iterator->destroy(iterator);
+
+ pos = asn1_build_object(&ietfAttributes, ASN1_SEQUENCE, size);
+
+ iterator = list->create_iterator(list, TRUE);
+ while (iterator->iterate(iterator, (void **)&attr))
+ {
+ chunk_t ietfAttribute;
+ asn1_t type = ASN1_NULL;
+
+ switch (attr->kind)
+ {
+ case IETF_ATTRIBUTE_OCTETS:
+ type = ASN1_OCTET_STRING;
+ break;
+ case IETF_ATTRIBUTE_STRING:
+ type = ASN1_UTF8STRING;
+ break;
+ case IETF_ATTRIBUTE_OID:
+ type = ASN1_OID;
+ break;
+ }
+ ietfAttribute = asn1_simple_object(type, attr->value);
+
+ /* copy ietfAttribute into ietfAttributes chunk */
+ memcpy(pos, ietfAttribute.ptr, ietfAttribute.len);
+ pos += ietfAttribute.len;
+ free(ietfAttribute.ptr);
+ }
+ iterator->destroy(iterator);
+
+ return asn1_wrap(ASN1_SEQUENCE, "m", ietfAttributes);
+}
+
+/*
+ * Described in header.
+ */
+void ietfAttr_list_destroy(linked_list_t *list)
+{
+ list->destroy_offset(list, offsetof(ietfAttr_t, destroy));
+}
diff --git a/src/libstrongswan/plugins/x509/ietf_attr_list.h b/src/libstrongswan/plugins/x509/ietf_attr_list.h
new file mode 100644
index 000000000..e3e4add61
--- /dev/null
+++ b/src/libstrongswan/plugins/x509/ietf_attr_list.h
@@ -0,0 +1,81 @@
+/*
+ * Copyright (C) 2007 Andreas Steffen
+ *
+ * Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * $Id$
+ */
+
+/**
+ * @defgroup ietf_attr_list ietf_attr_list
+ * @{ @ingroup x509_p
+ */
+
+#ifndef IETF_ATTR_LIST_H_
+#define IETF_ATTR_LIST_H_
+
+#include <library.h>
+#include <utils/linked_list.h>
+
+
+/**
+ * @brief Compare two linked lists of ietfAttr_t objects for equality
+ *
+ * @param list_a first alphabetically-sorted list
+ * @param list_b second alphabetically-sorted list
+ * @return TRUE if equal
+ */
+bool ietfAttr_list_equals(linked_list_t *list_a, linked_list_t *list_b);
+
+/**
+ * @brief Lists a linked list of ietfAttr_t objects
+ *
+ * @param list alphabetically-sorted linked list of attributes
+ * @param out output file
+ */
+void ietfAttr_list_list(linked_list_t *list, FILE *out);
+
+/**
+ * @brief Create a linked list of ietfAttr_t objects from a string
+ *
+ * @param msg string with comma-separated group names
+ * @param list alphabetically-sorted linked list of attributes
+ */
+void ietfAttr_list_create_from_string(char *msg, linked_list_t *list);
+
+/**
+ * @brief Create a linked list of ietfAttr_t objects from an ASN.1-coded chunk
+ *
+ * @param chunk chunk containing ASN.1-coded attributes
+ * @param list alphabetically-sorted linked list of attributes
+ * @param level0 parsing level
+ */
+void ietfAttr_list_create_from_chunk(chunk_t chunk, linked_list_t *list, int level0);
+
+/**
+ * @brief Encode a linked list of ietfAttr_t objects into an ASN.1-coded chunk
+ *
+ * @param list alphabetically-sorted linked list of attributes
+ * @return chunk containing ASN.1-coded attributes
+ */
+chunk_t ietfAttr_list_encode(linked_list_t *list);
+
+/**
+ * @brief Destroys a linked list of ietfAttr_t objects
+ *
+ * @param list list to be destroyed
+ */
+void ietfAttr_list_destroy(linked_list_t *list);
+
+#endif /* IETF_ATTR_LIST_H_ @}*/
+
diff --git a/src/libstrongswan/plugins/x509/x509_ac.c b/src/libstrongswan/plugins/x509/x509_ac.c
new file mode 100644
index 000000000..cfa38c66b
--- /dev/null
+++ b/src/libstrongswan/plugins/x509/x509_ac.c
@@ -0,0 +1,1140 @@
+/*
+ * Copyright (C) 2002 Ueli Galizzi, Ariane Seiler
+ * Copyright (C) 2003 Martin Berner, Lukas Suter
+ * Copyright (C) 2002-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
+ * 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.
+ *
+ * $Id$
+ */
+
+#include "x509_ac.h"
+#include "ietf_attr_list.h"
+
+#include <library.h>
+#include <debug.h>
+#include <asn1/oid.h>
+#include <asn1/asn1.h>
+#include <asn1/asn1_parser.h>
+#include <asn1/pem.h>
+#include <utils/identification.h>
+#include <utils/linked_list.h>
+#include <credentials/certificates/x509.h>
+
+extern identification_t* x509_parse_authorityKeyIdentifier(chunk_t blob,
+ int level0, chunk_t *authKeySerialNumber);
+
+typedef struct private_x509_ac_t private_x509_ac_t;
+
+/**
+ * private data of x509_ac_t object
+ */
+struct private_x509_ac_t {
+
+ /**
+ * public functions
+ */
+ x509_ac_t public;
+
+ /**
+ * X.509 attribute certificate encoding in ASN.1 DER format
+ */
+ chunk_t encoding;
+
+ /**
+ * X.509 attribute certificate body over which signature is computed
+ */
+ chunk_t certificateInfo;
+
+ /**
+ * Version of the X.509 attribute certificate
+ */
+ u_int version;
+
+ /**
+ * Serial number of the X.509 attribute certificate
+ */
+ chunk_t serialNumber;
+
+ /**
+ * ID representing the issuer of the holder certificate
+ */
+ identification_t *holderIssuer;
+
+ /**
+ * Serial number of the holder certificate
+ */
+ chunk_t holderSerial;
+
+ /**
+ * ID representing the holder
+ */
+ identification_t *entityName;
+
+ /**
+ * ID representing the attribute certificate issuer
+ */
+ identification_t *issuerName;
+
+ /**
+ * Start time of certificate validity
+ */
+ time_t notBefore;
+
+ /**
+ * End time of certificate validity
+ */
+ time_t notAfter;
+
+ /**
+ * List of charging attributes
+ */
+ linked_list_t *charging;
+
+ /**
+ * List of groub attributes
+ */
+ linked_list_t *groups;
+
+ /**
+ * Authority Key Identifier
+ */
+ identification_t *authKeyIdentifier;
+
+ /**
+ * Authority Key Serial Number
+ */
+ chunk_t authKeySerialNumber;
+
+ /**
+ * No revocation information available
+ */
+ bool noRevAvail;
+
+ /**
+ * Signature algorithm
+ */
+ int algorithm;
+
+ /**
+ * Signature
+ */
+ chunk_t signature;
+
+ /**
+ * Holder certificate
+ */
+ certificate_t *holderCert;
+
+ /**
+ * Signer certificate
+ */
+ certificate_t *signerCert;
+
+ /**
+ * Signer private key;
+ */
+ private_key_t *signerKey;
+
+ /**
+ * reference count
+ */
+ refcount_t ref;
+};
+
+static u_char ASN1_group_oid_str[] = {
+ 0x06, 0x08,
+ 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x0a ,0x04
+};
+
+static const chunk_t ASN1_group_oid = chunk_from_buf(ASN1_group_oid_str);
+
+static u_char ASN1_authorityKeyIdentifier_oid_str[] = {
+ 0x06, 0x03,
+ 0x55, 0x1d, 0x23
+};
+
+static const chunk_t ASN1_authorityKeyIdentifier_oid =
+ chunk_from_buf(ASN1_authorityKeyIdentifier_oid_str);
+
+static u_char ASN1_noRevAvail_ext_str[] = {
+ 0x30, 0x09,
+ 0x06, 0x03,
+ 0x55, 0x1d, 0x38,
+ 0x04, 0x02,
+ 0x05, 0x00
+};
+
+static const chunk_t ASN1_noRevAvail_ext = chunk_from_buf(ASN1_noRevAvail_ext_str);
+
+/**
+ * declaration of function implemented in x509_cert.c
+ */
+extern void x509_parse_generalNames(chunk_t blob, int level0, bool implicit,
+ linked_list_t *list);
+/**
+ * parses a directoryName
+ */
+static bool parse_directoryName(chunk_t blob, int level, bool implicit, identification_t **name)
+{
+ bool has_directoryName;
+ linked_list_t *list = linked_list_create();
+
+ x509_parse_generalNames(blob, level, implicit, list);
+ has_directoryName = list->get_count(list) > 0;
+
+ if (has_directoryName)
+ {
+ iterator_t *iterator = list->create_iterator(list, TRUE);
+ identification_t *directoryName;
+ bool first = TRUE;
+
+ while (iterator->iterate(iterator, (void**)&directoryName))
+ {
+ if (first)
+ {
+ *name = directoryName;
+ first = FALSE;
+ }
+ else
+ {
+ DBG1("more than one directory name - first selected");
+ directoryName->destroy(directoryName);
+ }
+ }
+ iterator->destroy(iterator);
+ }
+ else
+ {
+ DBG1("no directoryName found");
+ }
+
+ list->destroy(list);
+ return has_directoryName;
+}
+
+/**
+ * ASN.1 definition of roleSyntax
+ */
+static const asn1Object_t roleSyntaxObjects[] =
+{
+ { 0, "roleSyntax", ASN1_SEQUENCE, ASN1_NONE }, /* 0 */
+ { 1, "roleAuthority", ASN1_CONTEXT_C_0, ASN1_OPT |
+ ASN1_OBJ }, /* 1 */
+ { 1, "end opt", ASN1_EOC, ASN1_END }, /* 2 */
+ { 1, "roleName", ASN1_CONTEXT_C_1, ASN1_OBJ }, /* 3 */
+ { 0, "exit", ASN1_EOC, ASN1_EXIT }
+};
+
+/**
+ * Parses roleSyntax
+ */
+static void parse_roleSyntax(chunk_t blob, int level0)
+{
+ asn1_parser_t *parser;
+ chunk_t object;
+ int objectID;
+
+ parser = asn1_parser_create(roleSyntaxObjects, blob);
+ parser->set_top_level(parser, level0);
+
+ while (parser->iterate(parser, &objectID, &object))
+ {
+ switch (objectID)
+ {
+ default:
+ break;
+ }
+ }
+ parser->destroy(parser);
+}
+
+/**
+ * ASN.1 definition of an X509 attribute certificate
+ */
+static const asn1Object_t acObjects[] =
+{
+ { 0, "AttributeCertificate", ASN1_SEQUENCE, ASN1_OBJ }, /* 0 */
+ { 1, "AttributeCertificateInfo", ASN1_SEQUENCE, ASN1_OBJ }, /* 1 */
+ { 2, "version", ASN1_INTEGER, ASN1_DEF |
+ ASN1_BODY }, /* 2 */
+ { 2, "holder", ASN1_SEQUENCE, ASN1_NONE }, /* 3 */
+ { 3, "baseCertificateID", ASN1_CONTEXT_C_0, ASN1_OPT }, /* 4 */
+ { 4, "issuer", ASN1_SEQUENCE, ASN1_OBJ }, /* 5 */
+ { 4, "serial", ASN1_INTEGER, ASN1_BODY }, /* 6 */
+ { 4, "issuerUID", ASN1_BIT_STRING, ASN1_OPT |
+ ASN1_BODY }, /* 7 */
+ { 4, "end opt", ASN1_EOC, ASN1_END }, /* 8 */
+ { 3, "end opt", ASN1_EOC, ASN1_END }, /* 9 */
+ { 3, "entityName", ASN1_CONTEXT_C_1, ASN1_OPT |
+ ASN1_OBJ }, /* 10 */
+ { 3, "end opt", ASN1_EOC, ASN1_END }, /* 11 */
+ { 3, "objectDigestInfo", ASN1_CONTEXT_C_2, ASN1_OPT }, /* 12 */
+ { 4, "digestedObjectType", ASN1_ENUMERATED, ASN1_BODY }, /* 13 */
+ { 4, "otherObjectTypeID", ASN1_OID, ASN1_OPT |
+ ASN1_BODY }, /* 14 */
+ { 4, "end opt", ASN1_EOC, ASN1_END }, /* 15 */
+ { 4, "digestAlgorithm", ASN1_EOC, ASN1_RAW }, /* 16 */
+ { 3, "end opt", ASN1_EOC, ASN1_END }, /* 17 */
+ { 2, "v2Form", ASN1_CONTEXT_C_0, ASN1_NONE }, /* 18 */
+ { 3, "issuerName", ASN1_SEQUENCE, ASN1_OPT |
+ ASN1_OBJ }, /* 19 */
+ { 3, "end opt", ASN1_EOC, ASN1_END }, /* 20 */
+ { 3, "baseCertificateID", ASN1_CONTEXT_C_0, ASN1_OPT }, /* 21 */
+ { 4, "issuerSerial", ASN1_SEQUENCE, ASN1_NONE }, /* 22 */
+ { 5, "issuer", ASN1_SEQUENCE, ASN1_OBJ }, /* 23 */
+ { 5, "serial", ASN1_INTEGER, ASN1_BODY }, /* 24 */
+ { 5, "issuerUID", ASN1_BIT_STRING, ASN1_OPT |
+ ASN1_BODY }, /* 25 */
+ { 5, "end opt", ASN1_EOC, ASN1_END }, /* 26 */
+ { 3, "end opt", ASN1_EOC, ASN1_END }, /* 27 */
+ { 3, "objectDigestInfo", ASN1_CONTEXT_C_1, ASN1_OPT }, /* 28 */
+ { 4, "digestInfo", ASN1_SEQUENCE, ASN1_OBJ }, /* 29 */
+ { 5, "digestedObjectType", ASN1_ENUMERATED, ASN1_BODY }, /* 30 */
+ { 5, "otherObjectTypeID", ASN1_OID, ASN1_OPT |
+ ASN1_BODY }, /* 31 */
+ { 5, "end opt", ASN1_EOC, ASN1_END }, /* 32 */
+ { 5, "digestAlgorithm", ASN1_EOC, ASN1_RAW }, /* 33 */
+ { 3, "end opt", ASN1_EOC, ASN1_END }, /* 34 */
+ { 2, "signature", ASN1_EOC, ASN1_RAW }, /* 35 */
+ { 2, "serialNumber", ASN1_INTEGER, ASN1_BODY }, /* 36 */
+ { 2, "attrCertValidityPeriod", ASN1_SEQUENCE, ASN1_NONE }, /* 37 */
+ { 3, "notBeforeTime", ASN1_GENERALIZEDTIME, ASN1_BODY }, /* 38 */
+ { 3, "notAfterTime", ASN1_GENERALIZEDTIME, ASN1_BODY }, /* 39 */
+ { 2, "attributes", ASN1_SEQUENCE, ASN1_LOOP }, /* 40 */
+ { 3, "attribute", ASN1_SEQUENCE, ASN1_NONE }, /* 41 */
+ { 4, "type", ASN1_OID, ASN1_BODY }, /* 42 */
+ { 4, "values", ASN1_SET, ASN1_LOOP }, /* 43 */
+ { 5, "value", ASN1_EOC, ASN1_RAW }, /* 44 */
+ { 4, "end loop", ASN1_EOC, ASN1_END }, /* 45 */
+ { 2, "end loop", ASN1_EOC, ASN1_END }, /* 46 */
+ { 2, "extensions", ASN1_SEQUENCE, ASN1_LOOP }, /* 47 */
+ { 3, "extension", ASN1_SEQUENCE, ASN1_NONE }, /* 48 */
+ { 4, "extnID", ASN1_OID, ASN1_BODY }, /* 49 */
+ { 4, "critical", ASN1_BOOLEAN, ASN1_DEF |
+ ASN1_BODY }, /* 50 */
+ { 4, "extnValue", ASN1_OCTET_STRING, ASN1_BODY }, /* 51 */
+ { 2, "end loop", ASN1_EOC, ASN1_END }, /* 52 */
+ { 1, "signatureAlgorithm", ASN1_EOC, ASN1_RAW }, /* 53 */
+ { 1, "signatureValue", ASN1_BIT_STRING, ASN1_BODY }, /* 54 */
+ { 0, "exit", ASN1_EOC, ASN1_EXIT }
+};
+#define AC_OBJ_CERTIFICATE_INFO 1
+#define AC_OBJ_VERSION 2
+#define AC_OBJ_HOLDER_ISSUER 5
+#define AC_OBJ_HOLDER_SERIAL 6
+#define AC_OBJ_ENTITY_NAME 10
+#define AC_OBJ_ISSUER_NAME 19
+#define AC_OBJ_ISSUER 23
+#define AC_OBJ_SIG_ALG 35
+#define AC_OBJ_SERIAL_NUMBER 36
+#define AC_OBJ_NOT_BEFORE 38
+#define AC_OBJ_NOT_AFTER 39
+#define AC_OBJ_ATTRIBUTE_TYPE 42
+#define AC_OBJ_ATTRIBUTE_VALUE 44
+#define AC_OBJ_EXTN_ID 49
+#define AC_OBJ_CRITICAL 50
+#define AC_OBJ_EXTN_VALUE 51
+#define AC_OBJ_ALGORITHM 53
+#define AC_OBJ_SIGNATURE 54
+
+/**
+ * Parses an X.509 attribute certificate
+ */
+static bool parse_certificate(private_x509_ac_t *this)
+{
+ asn1_parser_t *parser;
+ chunk_t object;
+ int objectID;
+ int type = OID_UNKNOWN;
+ int extn_oid = OID_UNKNOWN;
+ int sig_alg = OID_UNKNOWN;
+ bool success = FALSE;
+ bool critical;
+
+ parser = asn1_parser_create(acObjects, this->encoding);
+
+ while (parser->iterate(parser, &objectID, &object))
+ {
+ u_int level = parser->get_level(parser)+1;
+
+ switch (objectID)
+ {
+ case AC_OBJ_CERTIFICATE_INFO:
+ this->certificateInfo = object;
+ break;
+ case AC_OBJ_VERSION:
+ this->version = (object.len) ? (1 + (u_int)*object.ptr) : 1;
+ DBG2(" v%d", this->version);
+ if (this->version != 2)
+ {
+ DBG1("v%d attribute certificates are not supported", this->version);
+ goto end;
+ }
+ break;
+ case AC_OBJ_HOLDER_ISSUER:
+ if (!parse_directoryName(object, level, FALSE, &this->holderIssuer))
+ {
+ goto end;
+ }
+ break;
+ case AC_OBJ_HOLDER_SERIAL:
+ this->holderSerial = object;
+ break;
+ case AC_OBJ_ENTITY_NAME:
+ if (!parse_directoryName(object, level, TRUE, &this->entityName))
+ {
+ goto end;
+ }
+ break;
+ case AC_OBJ_ISSUER_NAME:
+ if (!parse_directoryName(object, level, FALSE, &this->issuerName))
+ {
+ goto end;
+ }
+ break;
+ case AC_OBJ_SIG_ALG:
+ sig_alg = asn1_parse_algorithmIdentifier(object, level, NULL);
+ break;
+ case AC_OBJ_SERIAL_NUMBER:
+ this->serialNumber = object;
+ break;
+ case AC_OBJ_NOT_BEFORE:
+ this->notBefore = asn1_to_time(&object, ASN1_GENERALIZEDTIME);
+ break;
+ case AC_OBJ_NOT_AFTER:
+ this->notAfter = asn1_to_time(&object, ASN1_GENERALIZEDTIME);
+ break;
+ case AC_OBJ_ATTRIBUTE_TYPE:
+ type = asn1_known_oid(object);
+ break;
+ case AC_OBJ_ATTRIBUTE_VALUE:
+ {
+ switch (type)
+ {
+ case OID_AUTHENTICATION_INFO:
+ DBG2(" need to parse authenticationInfo");
+ break;
+ case OID_ACCESS_IDENTITY:
+ DBG2(" need to parse accessIdentity");
+ break;
+ case OID_CHARGING_IDENTITY:
+ ietfAttr_list_create_from_chunk(object, this->charging, level);
+ break;
+ case OID_GROUP:
+ ietfAttr_list_create_from_chunk(object, this->groups, level);
+ break;
+ case OID_ROLE:
+ parse_roleSyntax(object, level);
+ break;
+ default:
+ break;
+ }
+ break;
+ }
+ case AC_OBJ_EXTN_ID:
+ extn_oid = asn1_known_oid(object);
+ break;
+ case AC_OBJ_CRITICAL:
+ critical = object.len && *object.ptr;
+ DBG2(" %s",(critical)?"TRUE":"FALSE");
+ break;
+ case AC_OBJ_EXTN_VALUE:
+ {
+ switch (extn_oid)
+ {
+ case OID_CRL_DISTRIBUTION_POINTS:
+ DBG2(" need to parse crlDistributionPoints");
+ break;
+ case OID_AUTHORITY_KEY_ID:
+ this->authKeyIdentifier = x509_parse_authorityKeyIdentifier(object,
+ level, &this->authKeySerialNumber);
+ break;
+ case OID_TARGET_INFORMATION:
+ DBG2(" need to parse targetInformation");
+ break;
+ case OID_NO_REV_AVAIL:
+ this->noRevAvail = TRUE;
+ break;
+ default:
+ break;
+ }
+ break;
+ }
+ case AC_OBJ_ALGORITHM:
+ this->algorithm = asn1_parse_algorithmIdentifier(object, level,
+ NULL);
+ if (this->algorithm != sig_alg)
+ {
+ DBG1(" signature algorithms do not agree");
+ success = FALSE;
+ goto end;
+ }
+ break;
+ case AC_OBJ_SIGNATURE:
+ this->signature = object;
+ break;
+ default:
+ break;
+ }
+ }
+ success = parser->success(parser);
+
+end:
+ parser->destroy(parser);
+ return success;
+}
+
+/**
+ * build directoryName
+ */
+static chunk_t build_directoryName(asn1_t tag, chunk_t name)
+{
+ return asn1_wrap(tag, "m",
+ asn1_simple_object(ASN1_CONTEXT_C_4, name));
+}
+
+/**
+ * build holder
+ */
+static chunk_t build_holder(private_x509_ac_t *this)
+{
+ x509_t* x509 = (x509_t*)this->holderCert;
+ identification_t *issuer = this->holderCert->get_issuer(this->holderCert);
+ identification_t *subject = this->holderCert->get_subject(this->holderCert);
+
+ return asn1_wrap(ASN1_SEQUENCE, "mm",
+ asn1_wrap(ASN1_CONTEXT_C_0, "mm",
+ build_directoryName(ASN1_SEQUENCE, issuer->get_encoding(issuer)),
+ asn1_simple_object(ASN1_INTEGER, x509->get_serial(x509))
+ ),
+ build_directoryName(ASN1_CONTEXT_C_1, subject->get_encoding(subject)));
+}
+
+/**
+ * build v2Form
+ */
+static chunk_t build_v2_form(private_x509_ac_t *this)
+{
+ identification_t *subject = this->signerCert->get_subject(this->signerCert);
+
+ return asn1_wrap(ASN1_CONTEXT_C_0, "m",
+ build_directoryName(ASN1_SEQUENCE, subject->get_encoding(subject)));
+}
+
+/**
+ * build attrCertValidityPeriod
+ */
+static chunk_t build_attr_cert_validity(private_x509_ac_t *this)
+{
+ return asn1_wrap(ASN1_SEQUENCE, "mm",
+ asn1_from_time(&this->notBefore, ASN1_GENERALIZEDTIME),
+ asn1_from_time(&this->notAfter, ASN1_GENERALIZEDTIME));
+}
+
+
+/**
+ * build attribute type
+ */
+static chunk_t build_attribute_type(const chunk_t type, chunk_t content)
+{
+ return asn1_wrap(ASN1_SEQUENCE, "cm",
+ type,
+ asn1_wrap(ASN1_SET, "m", content));
+}
+
+/**
+ * build attributes
+ */
+static chunk_t build_attributes(private_x509_ac_t *this)
+{
+ return asn1_wrap(ASN1_SEQUENCE, "m",
+ build_attribute_type(ASN1_group_oid, ietfAttr_list_encode(this->groups)));
+}
+
+/**
+ * build authorityKeyIdentifier
+ */
+static chunk_t build_authorityKeyIdentifier(private_x509_ac_t *this)
+{
+ chunk_t keyIdentifier;
+ chunk_t authorityCertIssuer;
+ chunk_t authorityCertSerialNumber;
+ x509_t *x509 = (x509_t*)this->signerCert;
+ identification_t *issuer = this->signerCert->get_issuer(this->signerCert);
+ public_key_t *public = this->signerCert->get_public_key(this->signerCert);
+
+ if (public)
+ {
+ identification_t *keyid = public->get_id(public, ID_PUBKEY_SHA1);
+
+ this->authKeyIdentifier = keyid = keyid->clone(keyid);
+ keyIdentifier = keyid->get_encoding(keyid);
+ public->destroy(public);
+ }
+ else
+ {
+ keyIdentifier = chunk_empty;
+ }
+ authorityCertIssuer = build_directoryName(ASN1_CONTEXT_C_1,
+ issuer->get_encoding(issuer));
+ authorityCertSerialNumber = asn1_simple_object(ASN1_CONTEXT_S_2,
+ x509->get_serial(x509));
+ return asn1_wrap(ASN1_SEQUENCE, "cm",
+ ASN1_authorityKeyIdentifier_oid,
+ asn1_wrap(ASN1_OCTET_STRING, "m",
+ asn1_wrap(ASN1_SEQUENCE, "cmm",
+ keyIdentifier,
+ authorityCertIssuer,
+ authorityCertSerialNumber
+ )
+ )
+ );
+}
+
+/**
+ * build extensions
+ */
+static chunk_t build_extensions(private_x509_ac_t *this)
+{
+ return asn1_wrap(ASN1_SEQUENCE, "mc",
+ build_authorityKeyIdentifier(this),
+ ASN1_noRevAvail_ext);
+}
+
+/**
+ * build attributeCertificateInfo
+ */
+static chunk_t build_attr_cert_info(private_x509_ac_t *this)
+{
+ return asn1_wrap(ASN1_SEQUENCE, "cmmcmmmm",
+ ASN1_INTEGER_1,
+ build_holder(this),
+ build_v2_form(this),
+ asn1_algorithmIdentifier(OID_SHA1_WITH_RSA),
+ asn1_simple_object(ASN1_INTEGER, this->serialNumber),
+ build_attr_cert_validity(this),
+ build_attributes(this),
+ build_extensions(this));
+}
+
+
+/**
+ * build an X.509 attribute certificate
+ */
+static chunk_t build_ac(private_x509_ac_t *this)
+{
+ chunk_t signatureValue;
+ chunk_t attributeCertificateInfo;
+
+ attributeCertificateInfo = build_attr_cert_info(this);
+
+ this->signerKey->sign(this->signerKey, SIGN_RSA_EMSA_PKCS1_SHA1,
+ attributeCertificateInfo, &signatureValue);
+
+ return asn1_wrap(ASN1_SEQUENCE, "mcm",
+ attributeCertificateInfo,
+ asn1_algorithmIdentifier(OID_SHA1_WITH_RSA),
+ asn1_bitstring("m", signatureValue));
+}
+
+/**
+ * Implementation of ac_t.get_serial.
+ */
+static chunk_t get_serial(private_x509_ac_t *this)
+{
+ return this->serialNumber;
+}
+
+/**
+ * Implementation of ac_t.get_holderSerial.
+ */
+static chunk_t get_holderSerial(private_x509_ac_t *this)
+{
+ return this->holderSerial;
+}
+
+/**
+ * Implementation of ac_t.get_holderIssuer.
+ */
+static identification_t* get_holderIssuer(private_x509_ac_t *this)
+{
+ return this->holderIssuer;
+}
+
+/**
+ * Implementation of ac_t.get_authKeyIdentifier.
+ */
+static identification_t* get_authKeyIdentifier(private_x509_ac_t *this)
+{
+ return this->authKeyIdentifier;
+}
+
+/**
+ * Implementation of certificate_t.get_type
+ */
+static certificate_type_t get_type(private_x509_ac_t *this)
+{
+ return CERT_X509_AC;
+}
+
+/**
+ * Implementation of certificate_t.get_subject
+ */
+static identification_t* get_subject(private_x509_ac_t *this)
+{
+ return this->entityName;
+}
+
+/**
+ * Implementation of certificate_t.get_issuer
+ */
+static identification_t* get_issuer(private_x509_ac_t *this)
+{
+ return this->issuerName;
+}
+
+/**
+ * Implementation of certificate_t.has_subject.
+ */
+static id_match_t has_subject(private_x509_ac_t *this, identification_t *subject)
+{
+ return ID_MATCH_NONE;
+}
+
+/**
+ * Implementation of certificate_t.has_issuer.
+ */
+static id_match_t has_issuer(private_x509_ac_t *this, identification_t *issuer)
+{
+ id_match_t match;
+
+ if (issuer->get_type(issuer) == ID_PUBKEY_SHA1)
+ {
+ if (this->authKeyIdentifier)
+ {
+ match = issuer->matches(issuer, this->authKeyIdentifier);
+ }
+ else
+ {
+ match = ID_MATCH_NONE;
+ }
+ }
+ else
+ {
+ match = this->issuerName->matches(this->issuerName, issuer);
+ }
+ return match;
+}
+
+/**
+ * Implementation of certificate_t.issued_by
+ */
+static bool issued_by(private_x509_ac_t *this, certificate_t *issuer)
+{
+ public_key_t *key;
+ signature_scheme_t scheme;
+ bool valid;
+ x509_t *x509 = (x509_t*)issuer;
+
+ /* check if issuer is an X.509 AA certificate */
+ if (issuer->get_type(issuer) != CERT_X509)
+ {
+ return FALSE;
+ }
+ if (!(x509->get_flags(x509) & X509_AA))
+ {
+ return FALSE;
+ }
+
+ /* get the public key of the issuer */
+ key = issuer->get_public_key(issuer);
+
+ /* compare keyIdentifiers if available, otherwise use DNs */
+ if (this->authKeyIdentifier && key)
+ {
+ identification_t *subjectKeyIdentifier = key->get_id(key, ID_PUBKEY_SHA1);
+
+ if (!subjectKeyIdentifier->equals(subjectKeyIdentifier,
+ this->authKeyIdentifier))
+ {
+ return FALSE;
+ }
+ }
+ else
+ {
+ if (!this->issuerName->equals(this->issuerName, issuer->get_subject(issuer)))
+ {
+ return FALSE;
+ }
+ }
+ /* TODO: generic OID to scheme mapper? */
+ switch (this->algorithm)
+ {
+ case OID_MD5_WITH_RSA:
+ scheme = SIGN_RSA_EMSA_PKCS1_MD5;
+ break;
+ case OID_SHA1_WITH_RSA:
+ scheme = SIGN_RSA_EMSA_PKCS1_SHA1;
+ break;
+ case OID_SHA256_WITH_RSA:
+ scheme = SIGN_RSA_EMSA_PKCS1_SHA256;
+ break;
+ case OID_SHA384_WITH_RSA:
+ scheme = SIGN_RSA_EMSA_PKCS1_SHA384;
+ break;
+ case OID_SHA512_WITH_RSA:
+ scheme = SIGN_RSA_EMSA_PKCS1_SHA512;
+ break;
+ case OID_ECDSA_WITH_SHA1:
+ scheme = SIGN_ECDSA_WITH_SHA1;
+ break;
+ default:
+ return FALSE;
+ }
+ if (key == NULL)
+ {
+ return FALSE;
+ }
+ valid = key->verify(key, scheme, this->certificateInfo, this->signature);
+ key->destroy(key);
+ return valid;
+}
+
+/**
+ * Implementation of certificate_t.get_public_key.
+ */
+static public_key_t* get_public_key(private_x509_ac_t *this)
+{
+ return NULL;
+}
+
+/**
+ * Implementation of certificate_t.get_ref.
+ */
+static private_x509_ac_t* get_ref(private_x509_ac_t *this)
+{
+ ref_get(&this->ref);
+ return this;
+}
+
+/**
+ * Implementation of certificate_t.get_validity.
+ */
+static bool get_validity(private_x509_ac_t *this, time_t *when,
+ time_t *not_before, time_t *not_after)
+{
+ time_t t;
+
+ if (when)
+ {
+ t = *when;
+ }
+ else
+ {
+ t = time(NULL);
+ }
+ if (not_before)
+ {
+ *not_before = this->notBefore;
+ }
+ if (not_after)
+ {
+ *not_after = this->notAfter;
+ }
+ return (t >= this->notBefore && t <= this->notAfter);
+}
+
+/**
+ * Implementation of certificate_t.is_newer.
+ */
+static bool is_newer(private_x509_ac_t *this, ac_t *that)
+{
+ certificate_t *this_cert = &this->public.interface.certificate;
+ certificate_t *that_cert = &that->certificate;
+ time_t this_update, that_update, now = time(NULL);
+ bool new;
+
+ this_cert->get_validity(this_cert, &now, &this_update, NULL);
+ that_cert->get_validity(that_cert, &now, &that_update, NULL);
+ new = this_update > that_update;
+ DBG1(" attr cert from %#T is %s - existing attr_cert from %#T %s",
+ &this_update, FALSE, new ? "newer":"not newer",
+ &that_update, FALSE, new ? "replaced":"retained");
+ return new;
+}
+
+/**
+ * Implementation of certificate_t.get_encoding.
+ */
+static chunk_t get_encoding(private_x509_ac_t *this)
+{
+ return chunk_clone(this->encoding);
+}
+
+/**
+ * Implementation of certificate_t.equals.
+ */
+static bool equals(private_x509_ac_t *this, certificate_t *other)
+{
+ chunk_t encoding;
+ bool equal;
+
+ if ((certificate_t*)this == other)
+ {
+ return TRUE;
+ }
+ if (other->equals == (void*)equals)
+ { /* skip allocation if we have the same implementation */
+ return chunk_equals(this->encoding, ((private_x509_ac_t*)other)->encoding);
+ }
+ encoding = other->get_encoding(other);
+ equal = chunk_equals(this->encoding, encoding);
+ free(encoding.ptr);
+ return equal;
+}
+
+/**
+ * Implementation of x509_ac_t.destroy
+ */
+static void destroy(private_x509_ac_t *this)
+{
+ if (ref_put(&this->ref))
+ {
+ DESTROY_IF(this->holderIssuer);
+ DESTROY_IF(this->entityName);
+ DESTROY_IF(this->issuerName);
+ DESTROY_IF(this->authKeyIdentifier);
+ DESTROY_IF(this->holderCert);
+ DESTROY_IF(this->signerCert);
+ DESTROY_IF(this->signerKey);
+
+ ietfAttr_list_destroy(this->charging);
+ ietfAttr_list_destroy(this->groups);
+ free(this->encoding.ptr);
+ free(this);
+ }
+}
+
+/**
+ * create an empty but initialized X.509 attribute certificate
+ */
+static private_x509_ac_t *create_empty(void)
+{
+ private_x509_ac_t *this = malloc_thing(private_x509_ac_t);
+
+ /* public functions */
+ this->public.interface.get_serial = (chunk_t (*)(ac_t*))get_serial;
+ this->public.interface.get_holderSerial = (chunk_t (*)(ac_t*))get_holderSerial;
+ this->public.interface.get_holderIssuer = (identification_t* (*)(ac_t*))get_holderIssuer;
+ this->public.interface.get_authKeyIdentifier = (identification_t* (*)(ac_t*))get_authKeyIdentifier;
+ this->public.interface.certificate.get_type = (certificate_type_t (*)(certificate_t *this))get_type;
+ this->public.interface.certificate.get_subject = (identification_t* (*)(certificate_t *this))get_subject;
+ this->public.interface.certificate.get_issuer = (identification_t* (*)(certificate_t *this))get_issuer;
+ this->public.interface.certificate.has_subject = (id_match_t(*)(certificate_t*, identification_t *subject))has_subject;
+ this->public.interface.certificate.has_issuer = (id_match_t(*)(certificate_t*, identification_t *issuer))has_issuer;
+ this->public.interface.certificate.issued_by = (bool (*)(certificate_t *this, certificate_t *issuer))issued_by;
+ this->public.interface.certificate.get_public_key = (public_key_t* (*)(certificate_t *this))get_public_key;
+ this->public.interface.certificate.get_validity = (bool(*)(certificate_t*, time_t *when, time_t *, time_t*))get_validity;
+ this->public.interface.certificate.is_newer = (bool (*)(certificate_t*,certificate_t*))is_newer;
+ this->public.interface.certificate.get_encoding = (chunk_t(*)(certificate_t*))get_encoding;
+ this->public.interface.certificate.equals = (bool(*)(certificate_t*, certificate_t *other))equals;
+ this->public.interface.certificate.get_ref = (certificate_t* (*)(certificate_t *this))get_ref;
+ this->public.interface.certificate.destroy = (void (*)(certificate_t *this))destroy;
+
+ /* initialize */
+ this->encoding = chunk_empty;
+ this->holderSerial = chunk_empty;
+ this->holderIssuer = NULL;
+ this->entityName = NULL;
+ this->issuerName = NULL;
+ this->authKeyIdentifier = NULL;
+ this->holderCert = NULL;
+ this->signerCert = NULL;
+ this->signerKey = NULL;
+ this->charging = linked_list_create();
+ this->groups = linked_list_create();
+ this->ref = 1;
+
+ return this;
+}
+
+/**
+ * create X.509 attribute certificate from a chunk
+ */
+static private_x509_ac_t* create_from_chunk(chunk_t chunk)
+{
+ private_x509_ac_t *this = create_empty();
+
+ this->encoding = chunk;
+ if (!parse_certificate(this))
+ {
+ destroy(this);
+ return NULL;
+ }
+ return this;
+}
+
+/**
+ * create X.509 crl from a file
+ */
+static private_x509_ac_t* create_from_file(char *path)
+{
+ bool pgp = FALSE;
+ chunk_t chunk;
+ private_x509_ac_t *this;
+
+ if (!pem_asn1_load_file(path, NULL, &chunk, &pgp))
+ {
+ return NULL;
+ }
+
+ this = create_from_chunk(chunk);
+
+ if (this == NULL)
+ {
+ DBG1(" could not parse loaded attribute certificate file '%s'", path);
+ return NULL;
+ }
+ DBG1(" loaded attribute certificate file '%s'", path);
+ return this;
+}
+
+typedef struct private_builder_t private_builder_t;
+/**
+ * Builder implementation for certificate loading
+ */
+struct private_builder_t {
+ /** implements the builder interface */
+ builder_t public;
+ /** X.509 attribute certificate to build */
+ private_x509_ac_t *ac;
+};
+
+/**
+ * Implementation of builder_t.build
+ */
+static private_x509_ac_t* build(private_builder_t *this)
+{
+ private_x509_ac_t *ac = this->ac;
+
+ free(this);
+
+ /* synthesis if encoding does not exist */
+ if (ac && ac->encoding.ptr == NULL)
+ {
+ if (ac->holderCert && ac->signerCert && ac->signerKey)
+ {
+ ac->encoding = build_ac(ac);
+ return ac;
+ }
+ destroy(ac);
+ return NULL;
+ }
+ else
+ {
+ return ac;
+ }
+}
+
+/**
+ * Implementation of builder_t.add
+ */
+static void add(private_builder_t *this, builder_part_t part, ...)
+{
+ va_list args;
+ certificate_t *cert;
+
+ va_start(args, part);
+ switch (part)
+ {
+ case BUILD_FROM_FILE:
+ if (this->ac)
+ {
+ destroy(this->ac);
+ }
+ this->ac = create_from_file(va_arg(args, char*));
+ break;
+ case BUILD_BLOB_ASN1_DER:
+ if (this->ac)
+ {
+ destroy(this->ac);
+ }
+ this->ac = create_from_chunk(va_arg(args, chunk_t));
+ break;
+ case BUILD_NOT_BEFORE_TIME:
+ this->ac->notBefore = va_arg(args, time_t);
+ break;
+ case BUILD_NOT_AFTER_TIME:
+ this->ac->notAfter = va_arg(args, time_t);
+ break;
+ case BUILD_SERIAL:
+ this->ac->serialNumber = va_arg(args, chunk_t);
+ break;
+ case BUILD_IETF_GROUP_ATTR:
+ ietfAttr_list_create_from_string(va_arg(args, char*),
+ this->ac->groups);
+ break;
+ case BUILD_CERT:
+ cert = va_arg(args, certificate_t*);
+ if (cert->get_type(cert) == CERT_X509)
+ {
+ this->ac->holderCert = cert;
+ }
+ else
+ {
+ cert->destroy(cert);
+ }
+ break;
+ case BUILD_SIGNING_CERT:
+ cert = va_arg(args, certificate_t*);
+ if (cert->get_type(cert) == CERT_X509)
+ {
+ this->ac->signerCert = cert;
+ }
+ else
+ {
+ cert->destroy(cert);
+ }
+ break;
+ case BUILD_SIGNING_KEY:
+ this->ac->signerKey = va_arg(args, private_key_t*);
+ break;
+ default:
+ DBG1("ignoring unsupported build part %N", builder_part_names, part);
+ break;
+ }
+ va_end(args);
+}
+
+/**
+ * Builder construction function
+ */
+builder_t *x509_ac_builder(certificate_type_t type)
+{
+ private_builder_t *this;
+
+ if (type != CERT_X509_AC)
+ {
+ return NULL;
+ }
+
+ this = malloc_thing(private_builder_t);
+
+ this->ac = create_empty();
+ this->public.add = (void(*)(builder_t *this, builder_part_t part, ...))add;
+ this->public.build = (void*(*)(builder_t *this))build;
+
+ return &this->public;
+}
+
diff --git a/src/libstrongswan/plugins/x509/x509_ac.h b/src/libstrongswan/plugins/x509/x509_ac.h
new file mode 100644
index 000000000..2fd165e45
--- /dev/null
+++ b/src/libstrongswan/plugins/x509/x509_ac.h
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2002 Ueli Galizzi, Ariane Seiler
+ * Copyright (C) 2003 Martin Berner, Lukas Suter
+ * Copyright (C) 2002-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
+ * 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.
+ *
+ * $Id$
+ */
+
+/**
+ * @defgroup x509_ac x509_ac
+ * @{ @ingroup x509_p
+ */
+
+#ifndef X509_AC_H_
+#define X509_AC_H_
+
+#include <credentials/certificates/ac.h>
+
+typedef struct x509_ac_t x509_ac_t;
+
+/**
+ * Implementation of ac_t using own ASN1 parser.
+ */
+struct x509_ac_t {
+
+ /**
+ * Implements the ac_t interface
+ */
+ ac_t interface;
+};
+
+/**
+ * Create the building facility for X.509 attribute certificates.
+ *
+ * The resulting builder accepts:
+ * BUILD_USER_CERT: user certificate, exactly one
+ * BUILD_SIGNER_CERT: signer certificate, exactly one
+ * BUILD_SIGNER_KEY: signer private key, exactly one
+ * BUILD_SERIAL: serial number, exactly one
+ * BUILD_GROUP_ATTR: group attribute, optional, several possible
+ *
+ * @param type certificate type, CERT_X509_AC only
+ * @return builder instance to build X.509 attribute certificates
+ */
+builder_t *x509_ac_builder(certificate_type_t type);
+
+#endif /* X509_AC_H_ @}*/
diff --git a/src/libstrongswan/plugins/x509/x509_cert.c b/src/libstrongswan/plugins/x509/x509_cert.c
new file mode 100644
index 000000000..714258865
--- /dev/null
+++ b/src/libstrongswan/plugins/x509/x509_cert.c
@@ -0,0 +1,1295 @@
+/*
+ * Copyright (C) 2000 Andreas Hess, Patric Lichtsteiner, Roger Wegmann
+ * Copyright (C) 2001 Marco Bertossa, Andreas Schleiss
+ * Copyright (C) 2002 Mario Strasser
+ * Copyright (C) 2000-2006 Andreas Steffen
+ * Copyright (C) 2006-2008 Martin Willi
+ * Copyright (C) 2008 Tobias Brunner
+ * 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.
+ *
+ * $Id: x509_cert.c 4051 2008-06-10 09:08:27Z tobias $
+ */
+
+#define _GNU_SOURCE
+
+#include "x509_cert.h"
+
+#include <sys/stat.h>
+#include <unistd.h>
+#include <string.h>
+#include <stdio.h>
+
+#include <library.h>
+#include <debug.h>
+#include <asn1/oid.h>
+#include <asn1/asn1.h>
+#include <asn1/asn1_parser.h>
+#include <asn1/pem.h>
+#include <crypto/hashers/hasher.h>
+#include <utils/linked_list.h>
+#include <utils/identification.h>
+
+/**
+ * Different kinds of generalNames
+ */
+typedef enum {
+ GN_OTHER_NAME = 0,
+ GN_RFC822_NAME = 1,
+ GN_DNS_NAME = 2,
+ GN_X400_ADDRESS = 3,
+ GN_DIRECTORY_NAME = 4,
+ GN_EDI_PARTY_NAME = 5,
+ GN_URI = 6,
+ GN_IP_ADDRESS = 7,
+ GN_REGISTERED_ID = 8,
+} generalNames_t;
+
+
+typedef struct private_x509_cert_t private_x509_cert_t;
+
+/**
+ * Private data of a x509_cert_t object.
+ */
+struct private_x509_cert_t {
+ /**
+ * Public interface for this certificate.
+ */
+ x509_cert_t public;
+
+ /**
+ * X.509 certificate encoding in ASN.1 DER format
+ */
+ chunk_t encoding;
+
+ /**
+ * SHA1 hash of the DER encoding of this X.509 certificate
+ */
+ chunk_t encoding_hash;
+
+ /**
+ * X.509 certificate body over which signature is computed
+ */
+ chunk_t tbsCertificate;
+
+ /**
+ * Version of the X.509 certificate
+ */
+ u_int version;
+
+ /**
+ * Serial number of the X.509 certificate
+ */
+ chunk_t serialNumber;
+
+ /**
+ * ID representing the certificate issuer
+ */
+ identification_t *issuer;
+
+ /**
+ * Start time of certificate validity
+ */
+ time_t notBefore;
+
+ /**
+ * End time of certificate validity
+ */
+ time_t notAfter;
+
+ /**
+ * ID representing the certificate subject
+ */
+ identification_t *subject;
+
+ /**
+ * List of subjectAltNames as identification_t
+ */
+ linked_list_t *subjectAltNames;
+
+ /**
+ * List of crlDistributionPoints as allocated char*
+ */
+ linked_list_t *crl_uris;
+
+ /**
+ * List ocspAccessLocations as identification_t
+ */
+ linked_list_t *ocsp_uris;
+
+ /**
+ * certificates embedded public key
+ */
+ public_key_t *public_key;
+
+ /**
+ * Subject Key Identifier
+ */
+ chunk_t subjectKeyID;
+
+ /**
+ * Authority Key Identifier
+ */
+ identification_t *authKeyIdentifier;
+
+ /**
+ * Authority Key Serial Number
+ */
+ chunk_t authKeySerialNumber;
+
+ /**
+ * x509 constraints and other flags
+ */
+ x509_flag_t flags;
+
+ /**
+ * Signature algorithm
+ */
+ int algorithm;
+
+ /**
+ * Signature
+ */
+ chunk_t signature;
+
+ /**
+ * reference count
+ */
+ refcount_t ref;
+};
+
+static u_char ASN1_sAN_oid_buf[] = {
+ 0x06, 0x03, 0x55, 0x1D, 0x11
+};
+static const chunk_t ASN1_subjectAltName_oid = chunk_from_buf(ASN1_sAN_oid_buf);
+
+/**
+ * ASN.1 definition of a basicConstraints extension
+ */
+static const asn1Object_t basicConstraintsObjects[] = {
+ { 0, "basicConstraints", ASN1_SEQUENCE, ASN1_NONE }, /* 0 */
+ { 1, "CA", ASN1_BOOLEAN, ASN1_DEF|ASN1_BODY }, /* 1 */
+ { 1, "pathLenConstraint", ASN1_INTEGER, ASN1_OPT|ASN1_BODY }, /* 2 */
+ { 1, "end opt", ASN1_EOC, ASN1_END }, /* 3 */
+ { 0, "exit", ASN1_EOC, ASN1_EXIT }
+};
+#define BASIC_CONSTRAINTS_CA 1
+
+/**
+ * Extracts the basicConstraints extension
+ */
+static bool parse_basicConstraints(chunk_t blob, int level0)
+{
+ asn1_parser_t *parser;
+ chunk_t object;
+ int objectID;
+ bool isCA = FALSE;
+
+ parser = asn1_parser_create(basicConstraintsObjects, blob);
+ parser->set_top_level(parser, level0);
+
+ while (parser->iterate(parser, &objectID, &object))
+ {
+ if (objectID == BASIC_CONSTRAINTS_CA)
+ {
+ isCA = object.len && *object.ptr;
+ DBG2(" %s", isCA ? "TRUE" : "FALSE");
+ }
+ }
+ parser->destroy(parser);
+
+ return isCA;
+}
+
+/**
+ * ASN.1 definition of otherName
+ */
+static const asn1Object_t otherNameObjects[] = {
+ {0, "type-id", ASN1_OID, ASN1_BODY }, /* 0 */
+ {0, "value", ASN1_CONTEXT_C_0, ASN1_BODY }, /* 1 */
+ {0, "exit", ASN1_EOC, ASN1_EXIT }
+};
+#define ON_OBJ_ID_TYPE 0
+#define ON_OBJ_VALUE 1
+
+/**
+ * Extracts an otherName
+ */
+static bool parse_otherName(chunk_t blob, int level0)
+{
+ asn1_parser_t *parser;
+ chunk_t object;
+ int objectID;
+ int oid = OID_UNKNOWN;
+ bool success = FALSE;
+
+ parser = asn1_parser_create(otherNameObjects, blob);
+ parser->set_top_level(parser, level0);
+
+ while (parser->iterate(parser, &objectID, &object))
+ {
+ switch (objectID)
+ {
+ case ON_OBJ_ID_TYPE:
+ oid = asn1_known_oid(object);
+ break;
+ case ON_OBJ_VALUE:
+ if (oid == OID_XMPP_ADDR)
+ {
+ if (!asn1_parse_simple_object(&object, ASN1_UTF8STRING,
+ parser->get_level(parser)+1, "xmppAddr"))
+ {
+ goto end;
+ }
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ success = parser->success(parser);
+
+end:
+ parser->destroy(parser);
+ return success;
+}
+
+/**
+ * ASN.1 definition of generalName
+ */
+static const asn1Object_t generalNameObjects[] = {
+ { 0, "otherName", ASN1_CONTEXT_C_0, ASN1_OPT|ASN1_BODY }, /* 0 */
+ { 0, "end choice", ASN1_EOC, ASN1_END }, /* 1 */
+ { 0, "rfc822Name", ASN1_CONTEXT_S_1, ASN1_OPT|ASN1_BODY }, /* 2 */
+ { 0, "end choice", ASN1_EOC, ASN1_END }, /* 3 */
+ { 0, "dnsName", ASN1_CONTEXT_S_2, ASN1_OPT|ASN1_BODY }, /* 4 */
+ { 0, "end choice", ASN1_EOC, ASN1_END }, /* 5 */
+ { 0, "x400Address", ASN1_CONTEXT_S_3, ASN1_OPT|ASN1_BODY }, /* 6 */
+ { 0, "end choice", ASN1_EOC, ASN1_END }, /* 7 */
+ { 0, "directoryName", ASN1_CONTEXT_C_4, ASN1_OPT|ASN1_BODY }, /* 8 */
+ { 0, "end choice", ASN1_EOC, ASN1_END }, /* 9 */
+ { 0, "ediPartyName", ASN1_CONTEXT_C_5, ASN1_OPT|ASN1_BODY }, /* 10 */
+ { 0, "end choice", ASN1_EOC, ASN1_END }, /* 11 */
+ { 0, "URI", ASN1_CONTEXT_S_6, ASN1_OPT|ASN1_BODY }, /* 12 */
+ { 0, "end choice", ASN1_EOC, ASN1_END }, /* 13 */
+ { 0, "ipAddress", ASN1_CONTEXT_S_7, ASN1_OPT|ASN1_BODY }, /* 14 */
+ { 0, "end choice", ASN1_EOC, ASN1_END }, /* 15 */
+ { 0, "registeredID", ASN1_CONTEXT_S_8, ASN1_OPT|ASN1_BODY }, /* 16 */
+ { 0, "end choice", ASN1_EOC, ASN1_END }, /* 17 */
+ { 0, "exit", ASN1_EOC, ASN1_EXIT }
+};
+#define GN_OBJ_OTHER_NAME 0
+#define GN_OBJ_RFC822_NAME 2
+#define GN_OBJ_DNS_NAME 4
+#define GN_OBJ_X400_ADDRESS 6
+#define GN_OBJ_DIRECTORY_NAME 8
+#define GN_OBJ_EDI_PARTY_NAME 10
+#define GN_OBJ_URI 12
+#define GN_OBJ_IP_ADDRESS 14
+#define GN_OBJ_REGISTERED_ID 16
+
+/**
+ * Extracts a generalName
+ */
+static identification_t *parse_generalName(chunk_t blob, int level0)
+{
+ asn1_parser_t *parser;
+ chunk_t object;
+ int objectID ;
+
+ identification_t *gn = NULL;
+
+ parser = asn1_parser_create(generalNameObjects, blob);
+ parser->set_top_level(parser, level0);
+
+ while (parser->iterate(parser, &objectID, &object))
+ {
+ id_type_t id_type = ID_ANY;
+
+ switch (objectID)
+ {
+ case GN_OBJ_RFC822_NAME:
+ id_type = ID_RFC822_ADDR;
+ break;
+ case GN_OBJ_DNS_NAME:
+ id_type = ID_FQDN;
+ break;
+ case GN_OBJ_URI:
+ id_type = ID_DER_ASN1_GN_URI;
+ break;
+ case GN_OBJ_DIRECTORY_NAME:
+ id_type = ID_DER_ASN1_DN;
+ break;
+ case GN_OBJ_IP_ADDRESS:
+ id_type = ID_IPV4_ADDR;
+ break;
+ case GN_OBJ_OTHER_NAME:
+ if (!parse_otherName(object, parser->get_level(parser)+1))
+ {
+ goto end;
+ }
+ break;
+ case GN_OBJ_X400_ADDRESS:
+ case GN_OBJ_EDI_PARTY_NAME:
+ case GN_OBJ_REGISTERED_ID:
+ default:
+ break;
+ }
+ if (id_type != ID_ANY)
+ {
+ gn = identification_create_from_encoding(id_type, object);
+ DBG2(" '%D'", gn);
+ goto end;
+ }
+ }
+
+end:
+ parser->destroy(parser);
+ return gn;
+}
+
+/**
+ * ASN.1 definition of generalNames
+ */
+static const asn1Object_t generalNamesObjects[] = {
+ { 0, "generalNames", ASN1_SEQUENCE, ASN1_LOOP }, /* 0 */
+ { 1, "generalName", ASN1_EOC, ASN1_RAW }, /* 1 */
+ { 0, "end loop", ASN1_EOC, ASN1_END }, /* 2 */
+ { 0, "exit", ASN1_EOC, ASN1_EXIT }
+};
+#define GENERAL_NAMES_GN 1
+
+/**
+ * Extracts one or several GNs and puts them into a chained list
+ */
+void x509_parse_generalNames(chunk_t blob, int level0, bool implicit, linked_list_t *list)
+{
+ asn1_parser_t *parser;
+ chunk_t object;
+ int objectID;
+
+ parser = asn1_parser_create(generalNamesObjects, blob);
+ parser->set_top_level(parser, level0);
+ parser->set_flags(parser, implicit, FALSE);
+
+ while (parser->iterate(parser, &objectID, &object))
+ {
+ if (objectID == GENERAL_NAMES_GN)
+ {
+ identification_t *gn = parse_generalName(object,
+ parser->get_level(parser)+1);
+
+ if (gn)
+ {
+ list->insert_last(list, (void *)gn);
+ }
+ }
+ }
+ parser->destroy(parser);
+}
+
+/**
+ * ASN.1 definition of a authorityKeyIdentifier extension
+ */
+static const asn1Object_t authKeyIdentifierObjects[] = {
+ { 0, "authorityKeyIdentifier", ASN1_SEQUENCE, ASN1_NONE }, /* 0 */
+ { 1, "keyIdentifier", ASN1_CONTEXT_S_0, ASN1_OPT|ASN1_BODY }, /* 1 */
+ { 1, "end opt", ASN1_EOC, ASN1_END }, /* 2 */
+ { 1, "authorityCertIssuer", ASN1_CONTEXT_C_1, ASN1_OPT|ASN1_OBJ }, /* 3 */
+ { 1, "end opt", ASN1_EOC, ASN1_END }, /* 4 */
+ { 1, "authorityCertSerialNumber", ASN1_CONTEXT_S_2, ASN1_OPT|ASN1_BODY }, /* 5 */
+ { 1, "end opt", ASN1_EOC, ASN1_END }, /* 6 */
+ { 0, "exit", ASN1_EOC, ASN1_EXIT }
+};
+#define AUTH_KEY_ID_KEY_ID 1
+#define AUTH_KEY_ID_CERT_ISSUER 3
+#define AUTH_KEY_ID_CERT_SERIAL 5
+
+/**
+ * Extracts an authoritykeyIdentifier
+ */
+identification_t* x509_parse_authorityKeyIdentifier(chunk_t blob, int level0,
+ chunk_t *authKeySerialNumber)
+{
+ asn1_parser_t *parser;
+ chunk_t object;
+ int objectID;
+ identification_t *authKeyIdentifier = NULL;
+
+ *authKeySerialNumber = chunk_empty;
+
+ parser = asn1_parser_create(authKeyIdentifierObjects, blob);
+ parser->set_top_level(parser, level0);
+
+ while (parser->iterate(parser, &objectID, &object))
+ {
+ switch (objectID)
+ {
+ case AUTH_KEY_ID_KEY_ID:
+ authKeyIdentifier = identification_create_from_encoding(
+ ID_PUBKEY_SHA1, object);
+ break;
+ case AUTH_KEY_ID_CERT_ISSUER:
+ /* TODO: x509_parse_generalNames(object, level+1, TRUE); */
+ break;
+ case AUTH_KEY_ID_CERT_SERIAL:
+ *authKeySerialNumber = object;
+ break;
+ default:
+ break;
+ }
+ }
+ parser->destroy(parser);
+ return authKeyIdentifier;
+}
+
+/**
+ * ASN.1 definition of a authorityInfoAccess extension
+ */
+static const asn1Object_t authInfoAccessObjects[] = {
+ { 0, "authorityInfoAccess", ASN1_SEQUENCE, ASN1_LOOP }, /* 0 */
+ { 1, "accessDescription", ASN1_SEQUENCE, ASN1_NONE }, /* 1 */
+ { 2, "accessMethod", ASN1_OID, ASN1_BODY }, /* 2 */
+ { 2, "accessLocation", ASN1_EOC, ASN1_RAW }, /* 3 */
+ { 0, "end loop", ASN1_EOC, ASN1_END }, /* 4 */
+ { 0, "exit", ASN1_EOC, ASN1_EXIT }
+};
+#define AUTH_INFO_ACCESS_METHOD 2
+#define AUTH_INFO_ACCESS_LOCATION 3
+
+/**
+ * Extracts an authorityInfoAcess location
+ */
+static void parse_authorityInfoAccess(chunk_t blob, int level0,
+ private_x509_cert_t *this)
+{
+ asn1_parser_t *parser;
+ chunk_t object;
+ int objectID;
+ int accessMethod = OID_UNKNOWN;
+
+ parser = asn1_parser_create(authInfoAccessObjects, blob);
+ parser->set_top_level(parser, level0);
+
+ while (parser->iterate(parser, &objectID, &object))
+ {
+ switch (objectID)
+ {
+ case AUTH_INFO_ACCESS_METHOD:
+ accessMethod = asn1_known_oid(object);
+ break;
+ case AUTH_INFO_ACCESS_LOCATION:
+ {
+ switch (accessMethod)
+ {
+ case OID_OCSP:
+ case OID_CA_ISSUERS:
+ {
+ identification_t *id;
+ char *uri;
+
+ id = parse_generalName(object,
+ parser->get_level(parser)+1);
+ if (id == NULL)
+ {
+ /* parsing went wrong - abort */
+ goto end;
+ }
+ DBG2(" '%D'", id);
+ if (accessMethod == OID_OCSP &&
+ asprintf(&uri, "%D", id) > 0)
+ {
+ this->ocsp_uris->insert_last(this->ocsp_uris, uri);
+ }
+ id->destroy(id);
+ }
+ break;
+ default:
+ /* unkown accessMethod, ignoring */
+ break;
+ }
+ break;
+ }
+ default:
+ break;
+ }
+ }
+
+end:
+ parser->destroy(parser);
+}
+
+/**
+ * ASN.1 definition of a extendedKeyUsage extension
+ */
+static const asn1Object_t extendedKeyUsageObjects[] = {
+ { 0, "extendedKeyUsage", ASN1_SEQUENCE, ASN1_LOOP }, /* 0 */
+ { 1, "keyPurposeID", ASN1_OID, ASN1_BODY }, /* 1 */
+ { 0, "end loop", ASN1_EOC, ASN1_END }, /* 2 */
+ { 0, "exit", ASN1_EOC, ASN1_EXIT }
+};
+#define EXT_KEY_USAGE_PURPOSE_ID 1
+
+/**
+ * Extracts extendedKeyUsage OIDs - currently only OCSP_SIGING is returned
+ */
+static bool parse_extendedKeyUsage(chunk_t blob, int level0)
+{
+ asn1_parser_t *parser;
+ chunk_t object;
+ int objectID;
+ bool ocsp_signing = FALSE;
+
+ parser = asn1_parser_create(extendedKeyUsageObjects, blob);
+ parser->set_top_level(parser, level0);
+
+ while (parser->iterate(parser, &objectID, &object))
+ {
+ if (objectID == EXT_KEY_USAGE_PURPOSE_ID &&
+ asn1_known_oid(object) == OID_OCSP_SIGNING)
+ {
+ ocsp_signing = TRUE;
+ }
+ }
+ parser->destroy(parser);
+ return ocsp_signing;
+}
+
+/**
+ * ASN.1 definition of crlDistributionPoints
+ */
+static const asn1Object_t crlDistributionPointsObjects[] = {
+ { 0, "crlDistributionPoints", ASN1_SEQUENCE, ASN1_LOOP }, /* 0 */
+ { 1, "DistributionPoint", ASN1_SEQUENCE, ASN1_NONE }, /* 1 */
+ { 2, "distributionPoint", ASN1_CONTEXT_C_0, ASN1_OPT|ASN1_LOOP }, /* 2 */
+ { 3, "fullName", ASN1_CONTEXT_C_0, ASN1_OPT|ASN1_OBJ }, /* 3 */
+ { 3, "end choice", ASN1_EOC, ASN1_END }, /* 4 */
+ { 3, "nameRelToCRLIssuer",ASN1_CONTEXT_C_1, ASN1_OPT|ASN1_BODY }, /* 5 */
+ { 3, "end choice", ASN1_EOC, ASN1_END }, /* 6 */
+ { 2, "end opt", ASN1_EOC, ASN1_END }, /* 7 */
+ { 2, "reasons", ASN1_CONTEXT_C_1, ASN1_OPT|ASN1_BODY }, /* 8 */
+ { 2, "end opt", ASN1_EOC, ASN1_END }, /* 9 */
+ { 2, "crlIssuer", ASN1_CONTEXT_C_2, ASN1_OPT|ASN1_BODY }, /* 10 */
+ { 2, "end opt", ASN1_EOC, ASN1_END }, /* 11 */
+ { 0, "end loop", ASN1_EOC, ASN1_END }, /* 12 */
+ { 0, "exit", ASN1_EOC, ASN1_EXIT }
+};
+#define CRL_DIST_POINTS_FULLNAME 3
+
+/**
+ * Extracts one or several crlDistributionPoints into a list
+ */
+static void parse_crlDistributionPoints(chunk_t blob, int level0,
+ private_x509_cert_t *this)
+{
+ asn1_parser_t *parser;
+ chunk_t object;
+ int objectID;
+ linked_list_t *list = linked_list_create();
+
+ parser = asn1_parser_create(crlDistributionPointsObjects, blob);
+ parser->set_top_level(parser, level0);
+
+ while (parser->iterate(parser, &objectID, &object))
+ {
+ if (objectID == CRL_DIST_POINTS_FULLNAME)
+ {
+ identification_t *id;
+
+ /* append extracted generalNames to existing chained list */
+ x509_parse_generalNames(object, parser->get_level(parser)+1,
+ TRUE, list);
+
+ while (list->remove_last(list, (void**)&id) == SUCCESS)
+ {
+ char *uri;
+
+ if (asprintf(&uri, "%D", id) > 0)
+ {
+ this->crl_uris->insert_last(this->crl_uris, uri);
+ }
+ id->destroy(id);
+ }
+ }
+ }
+ parser->destroy(parser);
+ list->destroy(list);
+}
+
+/**
+ * ASN.1 definition of an X.509v3 x509_cert
+ */
+static const asn1Object_t certObjects[] = {
+ { 0, "x509", ASN1_SEQUENCE, ASN1_OBJ }, /* 0 */
+ { 1, "tbsCertificate", ASN1_SEQUENCE, ASN1_OBJ }, /* 1 */
+ { 2, "DEFAULT v1", ASN1_CONTEXT_C_0, ASN1_DEF }, /* 2 */
+ { 3, "version", ASN1_INTEGER, ASN1_BODY }, /* 3 */
+ { 2, "serialNumber", ASN1_INTEGER, ASN1_BODY }, /* 4 */
+ { 2, "signature", ASN1_EOC, ASN1_RAW }, /* 5 */
+ { 2, "issuer", ASN1_SEQUENCE, ASN1_OBJ }, /* 6 */
+ { 2, "validity", ASN1_SEQUENCE, ASN1_NONE }, /* 7 */
+ { 3, "notBefore", ASN1_EOC, ASN1_RAW }, /* 8 */
+ { 3, "notAfter", ASN1_EOC, ASN1_RAW }, /* 9 */
+ { 2, "subject", ASN1_SEQUENCE, ASN1_OBJ }, /* 10 */
+ { 2, "subjectPublicKeyInfo",ASN1_SEQUENCE, ASN1_RAW }, /* 11 */
+ { 2, "issuerUniqueID", ASN1_CONTEXT_C_1, ASN1_OPT }, /* 12 */
+ { 2, "end opt", ASN1_EOC, ASN1_END }, /* 13 */
+ { 2, "subjectUniqueID", ASN1_CONTEXT_C_2, ASN1_OPT }, /* 14 */
+ { 2, "end opt", ASN1_EOC, ASN1_END }, /* 15 */
+ { 2, "optional extensions", ASN1_CONTEXT_C_3, ASN1_OPT }, /* 16 */
+ { 3, "extensions", ASN1_SEQUENCE, ASN1_LOOP }, /* 17 */
+ { 4, "extension", ASN1_SEQUENCE, ASN1_NONE }, /* 18 */
+ { 5, "extnID", ASN1_OID, ASN1_BODY }, /* 19 */
+ { 5, "critical", ASN1_BOOLEAN, ASN1_DEF|ASN1_BODY }, /* 20 */
+ { 5, "extnValue", ASN1_OCTET_STRING, ASN1_BODY }, /* 21 */
+ { 3, "end loop", ASN1_EOC, ASN1_END }, /* 22 */
+ { 2, "end opt", ASN1_EOC, ASN1_END }, /* 23 */
+ { 1, "signatureAlgorithm", ASN1_EOC, ASN1_RAW }, /* 24 */
+ { 1, "signatureValue", ASN1_BIT_STRING, ASN1_BODY }, /* 25 */
+ { 0, "exit", ASN1_EOC, ASN1_EXIT }
+};
+#define X509_OBJ_TBS_CERTIFICATE 1
+#define X509_OBJ_VERSION 3
+#define X509_OBJ_SERIAL_NUMBER 4
+#define X509_OBJ_SIG_ALG 5
+#define X509_OBJ_ISSUER 6
+#define X509_OBJ_NOT_BEFORE 8
+#define X509_OBJ_NOT_AFTER 9
+#define X509_OBJ_SUBJECT 10
+#define X509_OBJ_SUBJECT_PUBLIC_KEY_INFO 11
+#define X509_OBJ_EXTN_ID 19
+#define X509_OBJ_CRITICAL 20
+#define X509_OBJ_EXTN_VALUE 21
+#define X509_OBJ_ALGORITHM 24
+#define X509_OBJ_SIGNATURE 25
+
+/**
+ * Parses an X.509v3 certificate
+ */
+static bool parse_certificate(private_x509_cert_t *this)
+{
+ asn1_parser_t *parser;
+ chunk_t object;
+ int objectID;
+ int extn_oid = OID_UNKNOWN;
+ int sig_alg = OID_UNKNOWN;
+ bool success = FALSE;
+ bool critical;
+
+ parser = asn1_parser_create(certObjects, this->encoding);
+
+ while (parser->iterate(parser, &objectID, &object))
+ {
+ u_int level = parser->get_level(parser)+1;
+
+ switch (objectID)
+ {
+ case X509_OBJ_TBS_CERTIFICATE:
+ this->tbsCertificate = object;
+ break;
+ case X509_OBJ_VERSION:
+ this->version = (object.len) ? (1+(u_int)*object.ptr) : 1;
+ DBG2(" v%d", this->version);
+ break;
+ case X509_OBJ_SERIAL_NUMBER:
+ this->serialNumber = object;
+ break;
+ case X509_OBJ_SIG_ALG:
+ sig_alg = asn1_parse_algorithmIdentifier(object, level, NULL);
+ break;
+ case X509_OBJ_ISSUER:
+ this->issuer = identification_create_from_encoding(ID_DER_ASN1_DN, object);
+ DBG2(" '%D'", this->issuer);
+ break;
+ case X509_OBJ_NOT_BEFORE:
+ this->notBefore = asn1_parse_time(object, level);
+ break;
+ case X509_OBJ_NOT_AFTER:
+ this->notAfter = asn1_parse_time(object, level);
+ break;
+ case X509_OBJ_SUBJECT:
+ this->subject = identification_create_from_encoding(ID_DER_ASN1_DN, object);
+ DBG2(" '%D'", this->subject);
+ break;
+ case X509_OBJ_SUBJECT_PUBLIC_KEY_INFO:
+ this->public_key = lib->creds->create(lib->creds, CRED_PUBLIC_KEY,
+ KEY_ANY, BUILD_BLOB_ASN1_DER, chunk_clone(object), BUILD_END);
+ if (this->public_key == NULL)
+ {
+ DBG1("could not create public key");
+ goto end;
+ }
+ break;
+ case X509_OBJ_EXTN_ID:
+ extn_oid = asn1_known_oid(object);
+ break;
+ case X509_OBJ_CRITICAL:
+ critical = object.len && *object.ptr;
+ DBG2(" %s", critical ? "TRUE" : "FALSE");
+ break;
+ case X509_OBJ_EXTN_VALUE:
+ {
+ switch (extn_oid)
+ {
+ case OID_SUBJECT_KEY_ID:
+ if (!asn1_parse_simple_object(&object, ASN1_OCTET_STRING,
+ level, "keyIdentifier"))
+ {
+ goto end;
+ }
+ this->subjectKeyID = object;
+ break;
+ case OID_SUBJECT_ALT_NAME:
+ x509_parse_generalNames(object, level, FALSE,
+ this->subjectAltNames);
+ break;
+ case OID_BASIC_CONSTRAINTS:
+ if (parse_basicConstraints(object, level))
+ {
+ this->flags |= X509_CA;
+ }
+ break;
+ case OID_CRL_DISTRIBUTION_POINTS:
+ parse_crlDistributionPoints(object, level, this);
+ break;
+ case OID_AUTHORITY_KEY_ID:
+ this->authKeyIdentifier = x509_parse_authorityKeyIdentifier(object,
+ level, &this->authKeySerialNumber);
+ break;
+ case OID_AUTHORITY_INFO_ACCESS:
+ parse_authorityInfoAccess(object, level, this);
+ break;
+ case OID_EXTENDED_KEY_USAGE:
+ if (parse_extendedKeyUsage(object, level))
+ {
+ this->flags |= X509_OCSP_SIGNER;
+ }
+ break;
+ case OID_NS_REVOCATION_URL:
+ case OID_NS_CA_REVOCATION_URL:
+ case OID_NS_CA_POLICY_URL:
+ case OID_NS_COMMENT:
+ if (!asn1_parse_simple_object(&object, ASN1_IA5STRING,
+ level, oid_names[extn_oid].name))
+ {
+ goto end;
+ }
+ break;
+ default:
+ break;
+ }
+ break;
+ }
+ case X509_OBJ_ALGORITHM:
+ this->algorithm = asn1_parse_algorithmIdentifier(object, level, NULL);
+ if (this->algorithm != sig_alg)
+ {
+ DBG1(" signature algorithms do not agree");
+ goto end;
+ }
+ break;
+ case X509_OBJ_SIGNATURE:
+ this->signature = object;
+ break;
+ default:
+ break;
+ }
+ }
+ success = parser->success(parser);
+
+end:
+ parser->destroy(parser);
+ return success;
+}
+
+/**
+ * Implementation of certificate_t.get_type
+ */
+static certificate_type_t get_type(private_x509_cert_t *this)
+{
+ return CERT_X509;
+}
+
+/**
+ * Implementation of certificate_t.get_subject
+ */
+static identification_t* get_subject(private_x509_cert_t *this)
+{
+ return this->subject;
+}
+
+/**
+ * Implementation of certificate_t.get_issuer
+ */
+static identification_t* get_issuer(private_x509_cert_t *this)
+{
+ return this->issuer;
+}
+
+/**
+ * Implementation of certificate_t.has_subject.
+ */
+static id_match_t has_subject(private_x509_cert_t *this, identification_t *subject)
+{
+ identification_t *current;
+ enumerator_t *enumerator;
+ id_match_t match, best;
+
+ if (this->encoding_hash.ptr && subject->get_type(subject) == ID_CERT_DER_SHA1 &&
+ chunk_equals(this->encoding_hash, subject->get_encoding(subject)))
+ {
+ return ID_MATCH_PERFECT;
+ }
+
+ best = this->subject->matches(this->subject, subject);
+ enumerator = this->subjectAltNames->create_enumerator(this->subjectAltNames);
+ while (enumerator->enumerate(enumerator, &current))
+ {
+ match = current->matches(current, subject);
+ if (match > best)
+ {
+ best = match;
+ }
+ }
+ enumerator->destroy(enumerator);
+ return best;
+}
+
+/**
+ * Implementation of certificate_t.has_subject.
+ */
+static id_match_t has_issuer(private_x509_cert_t *this, identification_t *issuer)
+{
+ /* issuerAltNames currently not supported */
+ return this->issuer->matches(this->issuer, issuer);
+}
+
+/**
+ * Implementation of certificate_t.issued_by
+ */
+static bool issued_by(private_x509_cert_t *this, certificate_t *issuer)
+{
+ public_key_t *key;
+ signature_scheme_t scheme;
+ bool valid;
+ x509_t *x509 = (x509_t*)issuer;
+
+ if (&this->public.interface.interface == issuer)
+ {
+ if (this->flags & X509_SELF_SIGNED)
+ {
+ return TRUE;
+ }
+ }
+ else
+ {
+ if (issuer->get_type(issuer) != CERT_X509)
+ {
+ return FALSE;
+ }
+ if (!(x509->get_flags(x509) & X509_CA))
+ {
+ return FALSE;
+ }
+ }
+ if (!this->issuer->equals(this->issuer, issuer->get_subject(issuer)))
+ {
+ return FALSE;
+ }
+ /* TODO: generic OID to scheme mapper? */
+ switch (this->algorithm)
+ {
+ case OID_MD5_WITH_RSA:
+ scheme = SIGN_RSA_EMSA_PKCS1_MD5;
+ break;
+ case OID_SHA1_WITH_RSA:
+ scheme = SIGN_RSA_EMSA_PKCS1_SHA1;
+ break;
+ case OID_SHA256_WITH_RSA:
+ scheme = SIGN_RSA_EMSA_PKCS1_SHA256;
+ break;
+ case OID_SHA384_WITH_RSA:
+ scheme = SIGN_RSA_EMSA_PKCS1_SHA384;
+ break;
+ case OID_SHA512_WITH_RSA:
+ scheme = SIGN_RSA_EMSA_PKCS1_SHA512;
+ break;
+ case OID_ECDSA_WITH_SHA1:
+ scheme = SIGN_ECDSA_WITH_SHA1;
+ break;
+ default:
+ return FALSE;
+ }
+ key = issuer->get_public_key(issuer);
+ if (key == NULL)
+ {
+ return FALSE;
+ }
+ /* TODO: add a lightweight check option (comparing auth/subject keyids only) */
+ valid = key->verify(key, scheme, this->tbsCertificate, this->signature);
+ key->destroy(key);
+ return valid;
+}
+
+/**
+ * Implementation of certificate_t.get_public_key
+ */
+static public_key_t* get_public_key(private_x509_cert_t *this)
+{
+ this->public_key->get_ref(this->public_key);
+ return this->public_key;
+}
+
+/**
+ * Implementation of certificate_t.asdf
+ */
+static private_x509_cert_t* get_ref(private_x509_cert_t *this)
+{
+ ref_get(&this->ref);
+ return this;
+}
+
+/**
+ * Implementation of x509_cert_t.get_flags.
+ */
+static x509_flag_t get_flags(private_x509_cert_t *this)
+{
+ return this->flags;
+}
+
+/**
+ * Implementation of x509_cert_t.get_validity.
+ */
+static bool get_validity(private_x509_cert_t *this, time_t *when,
+ time_t *not_before, time_t *not_after)
+{
+ time_t t;
+
+ if (when)
+ {
+ t = *when;
+ }
+ else
+ {
+ t = time(NULL);
+ }
+ if (not_before)
+ {
+ *not_before = this->notBefore;
+ }
+ if (not_after)
+ {
+ *not_after = this->notAfter;
+ }
+ return (t >= this->notBefore && t <= this->notAfter);
+}
+
+/**
+ * Implementation of certificate_t.is_newer.
+ */
+static bool is_newer(certificate_t *this, certificate_t *that)
+{
+ time_t this_update, that_update, now = time(NULL);
+ bool new;
+
+ this->get_validity(this, &now, &this_update, NULL);
+ that->get_validity(that, &now, &that_update, NULL);
+ new = this_update > that_update;
+ DBG1(" certificate from %#T is %s - existing certificate from %#T %s",
+ &this_update, FALSE, new ? "newer":"not newer",
+ &that_update, FALSE, new ? "replaced":"retained");
+ return new;
+}
+
+/**
+ * Implementation of certificate_t.get_encoding.
+ */
+static chunk_t get_encoding(private_x509_cert_t *this)
+{
+ return chunk_clone(this->encoding);
+}
+
+/**
+ * Implementation of certificate_t.equals.
+ */
+static bool equals(private_x509_cert_t *this, certificate_t *other)
+{
+ chunk_t encoding;
+ bool equal;
+
+ if (this == (private_x509_cert_t*)other)
+ {
+ return TRUE;
+ }
+ if (other->get_type(other) != CERT_X509)
+ {
+ return FALSE;
+ }
+ if (other->equals == (void*)equals)
+ { /* skip allocation if we have the same implementation */
+ return chunk_equals(this->encoding, ((private_x509_cert_t*)other)->encoding);
+ }
+ encoding = other->get_encoding(other);
+ equal = chunk_equals(this->encoding, encoding);
+ free(encoding.ptr);
+ return equal;
+}
+
+/**
+ * Implementation of x509_t.get_serial.
+ */
+static chunk_t get_serial(private_x509_cert_t *this)
+{
+ return this->serialNumber;
+}
+
+/**
+ * Implementation of x509_t.get_authKeyIdentifier.
+ */
+static identification_t *get_authKeyIdentifier(private_x509_cert_t *this)
+{
+ return this->authKeyIdentifier;
+}
+
+/**
+ * Implementation of x509_cert_t.create_subjectAltName_enumerator.
+ */
+static enumerator_t* create_subjectAltName_enumerator(private_x509_cert_t *this)
+{
+ return this->subjectAltNames->create_enumerator(this->subjectAltNames);
+}
+
+/**
+ * Implementation of x509_cert_t.create_ocsp_uri_enumerator.
+ */
+static enumerator_t* create_ocsp_uri_enumerator(private_x509_cert_t *this)
+{
+ return this->ocsp_uris->create_enumerator(this->ocsp_uris);
+}
+
+/**
+ * Implementation of x509_cert_t.create_crl_uri_enumerator.
+ */
+static enumerator_t* create_crl_uri_enumerator(private_x509_cert_t *this)
+{
+ return this->crl_uris->create_enumerator(this->crl_uris);
+}
+
+/**
+ * Implementation of certificate_t.asdf
+ */
+static void destroy(private_x509_cert_t *this)
+{
+ if (ref_put(&this->ref))
+ {
+ this->subjectAltNames->destroy_offset(this->subjectAltNames,
+ offsetof(identification_t, destroy));
+ this->crl_uris->destroy_function(this->crl_uris, free);
+ this->ocsp_uris->destroy_function(this->ocsp_uris, free);
+ DESTROY_IF(this->issuer);
+ DESTROY_IF(this->subject);
+ DESTROY_IF(this->public_key);
+ DESTROY_IF(this->authKeyIdentifier);
+ chunk_free(&this->encoding);
+ chunk_free(&this->encoding_hash);
+ free(this);
+ }
+}
+
+/**
+ * create an empty but initialized X.509 certificate
+ */
+static private_x509_cert_t* create_empty(void)
+{
+ private_x509_cert_t *this = malloc_thing(private_x509_cert_t);
+
+ this->public.interface.interface.get_type = (certificate_type_t (*)(certificate_t *this))get_type;
+ this->public.interface.interface.get_subject = (identification_t* (*)(certificate_t *this))get_subject;
+ this->public.interface.interface.get_issuer = (identification_t* (*)(certificate_t *this))get_issuer;
+ this->public.interface.interface.has_subject = (id_match_t (*)(certificate_t*, identification_t *subject))has_subject;
+ this->public.interface.interface.has_issuer = (id_match_t (*)(certificate_t*, identification_t *issuer))has_issuer;
+ this->public.interface.interface.issued_by = (bool (*)(certificate_t *this, certificate_t *issuer))issued_by;
+ this->public.interface.interface.get_public_key = (public_key_t* (*)(certificate_t *this))get_public_key;
+ this->public.interface.interface.get_validity = (bool (*)(certificate_t*, time_t *when, time_t *, time_t*))get_validity;
+ this->public.interface.interface.is_newer = (bool (*)(certificate_t*,certificate_t*))is_newer;
+ this->public.interface.interface.get_encoding = (chunk_t (*)(certificate_t*))get_encoding;
+ this->public.interface.interface.equals = (bool (*)(certificate_t*, certificate_t *other))equals;
+ this->public.interface.interface.get_ref = (certificate_t* (*)(certificate_t *this))get_ref;
+ this->public.interface.interface.destroy = (void (*)(certificate_t *this))destroy;
+ this->public.interface.get_flags = (x509_flag_t (*)(x509_t*))get_flags;
+ this->public.interface.get_serial = (chunk_t (*)(x509_t*))get_serial;
+ this->public.interface.get_authKeyIdentifier = (identification_t* (*)(x509_t*))get_authKeyIdentifier;
+ this->public.interface.create_subjectAltName_enumerator = (enumerator_t* (*)(x509_t*))create_subjectAltName_enumerator;
+ this->public.interface.create_crl_uri_enumerator = (enumerator_t* (*)(x509_t*))create_crl_uri_enumerator;
+ this->public.interface.create_ocsp_uri_enumerator = (enumerator_t* (*)(x509_t*))create_ocsp_uri_enumerator;
+
+ this->encoding = chunk_empty;
+ this->encoding_hash = chunk_empty;
+ this->public_key = NULL;
+ this->subject = NULL;
+ this->issuer = NULL;
+ this->subjectAltNames = linked_list_create();
+ this->crl_uris = linked_list_create();
+ this->ocsp_uris = linked_list_create();
+ this->subjectKeyID = chunk_empty;
+ this->authKeyIdentifier = NULL;
+ this->authKeySerialNumber = chunk_empty;
+ this->flags = 0;
+ this->ref = 1;
+
+ return this;
+}
+
+/**
+ * create an X.509 certificate from a chunk
+ */
+static private_x509_cert_t *create_from_chunk(chunk_t chunk)
+{
+ private_x509_cert_t *this = create_empty();
+
+ this->encoding = chunk;
+ if (!parse_certificate(this))
+ {
+ destroy(this);
+ return NULL;
+ }
+
+ /* check if the certificate is self-signed */
+ if (issued_by(this, &this->public.interface.interface))
+ {
+ this->flags |= X509_SELF_SIGNED;
+ }
+
+ hasher_t *hasher = lib->crypto->create_hasher(lib->crypto, HASH_SHA1);
+ if (hasher != NULL)
+ {
+ hasher->allocate_hash(hasher, this->encoding, &this->encoding_hash);
+ hasher->destroy(hasher);
+ }
+ else
+ {
+ DBG1(" unable to create hash of certificate, SHA1 not supported");
+ }
+
+ return this;
+}
+
+/**
+ * create an X.509 certificate from a file
+ */
+static private_x509_cert_t *create_from_file(char *path)
+{
+ bool pgp = FALSE;
+ chunk_t chunk;
+ private_x509_cert_t *this;
+
+ if (!pem_asn1_load_file(path, NULL, &chunk, &pgp))
+ {
+ return NULL;
+ }
+
+ this = create_from_chunk(chunk);
+
+ if (this == NULL)
+ {
+ DBG1(" could not parse loaded certificate file '%s'",path);
+ return NULL;
+ }
+ DBG1(" loaded certificate file '%s'", path);
+ return this;
+
+}
+
+typedef struct private_builder_t private_builder_t;
+/**
+ * Builder implementation for certificate loading
+ */
+struct private_builder_t {
+ /** implements the builder interface */
+ builder_t public;
+ /** loaded certificate */
+ private_x509_cert_t *cert;
+ /** additional flags to enforce */
+ x509_flag_t flags;
+};
+
+/**
+ * Implementation of builder_t.build
+ */
+static private_x509_cert_t *build(private_builder_t *this)
+{
+ private_x509_cert_t *cert = this->cert;
+ x509_flag_t flags = this->flags;
+
+ free(this);
+ if (cert == NULL)
+ {
+ return NULL;
+ }
+ if ((flags & X509_CA) && !(cert->flags & X509_CA))
+ {
+ DBG1(" ca certificate must have ca basic constraint set, discarded");
+ destroy(cert);
+ return NULL;
+ }
+ cert->flags |= flags;
+ return cert;
+}
+
+/**
+ * Implementation of builder_t.add
+ */
+static void add(private_builder_t *this, builder_part_t part, ...)
+{
+ va_list args;
+
+ va_start(args, part);
+ switch (part)
+ {
+ case BUILD_FROM_FILE:
+ this->cert = create_from_file(va_arg(args, char*));
+ break;
+ case BUILD_BLOB_ASN1_DER:
+ this->cert = create_from_chunk(va_arg(args, chunk_t));
+ break;
+ case BUILD_X509_FLAG:
+ this->flags = va_arg(args, x509_flag_t);
+ break;
+ default:
+ DBG1("ignoring unsupported build part %N", builder_part_names, part);
+ break;
+ }
+ va_end(args);
+}
+
+/**
+ * Builder construction function
+ */
+builder_t *x509_cert_builder(certificate_type_t type)
+{
+ private_builder_t *this;
+
+ if (type != CERT_X509)
+ {
+ return NULL;
+ }
+
+ this = malloc_thing(private_builder_t);
+
+ this->cert = NULL;
+ this->flags = 0;
+ this->public.add = (void(*)(builder_t *this, builder_part_t part, ...))add;
+ this->public.build = (void*(*)(builder_t *this))build;
+
+ return &this->public;
+}
+
diff --git a/src/libstrongswan/plugins/x509/x509_cert.h b/src/libstrongswan/plugins/x509/x509_cert.h
new file mode 100644
index 000000000..701cc3d63
--- /dev/null
+++ b/src/libstrongswan/plugins/x509/x509_cert.h
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2008 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.
+ *
+ * $Id: x509_cert.h 3650 2008-03-22 08:15:18Z andreas $
+ */
+
+/**
+ * @defgroup x509_cert x509_cert
+ * @{ @ingroup x509_p
+ */
+
+#ifndef X509_CERT_H_
+#define X509_CERT_H_
+
+typedef struct x509_cert_t x509_cert_t;
+
+#include <credentials/certificates/x509.h>
+
+/**
+ * Implementation of x509_t/certificate_t using own ASN1 parser.
+ */
+struct x509_cert_t {
+
+ /**
+ * Implements the x509_t interface
+ */
+ x509_t interface;
+};
+
+/**
+ * Create the building facility for x509 certificates
+ *
+ * @param type certificate type, CERT_X509 only
+ * @return builder instance to build certificate
+ */
+builder_t *x509_cert_builder(certificate_type_t type);
+
+#endif /* X509_CERT_H_ @}*/
diff --git a/src/libstrongswan/plugins/x509/x509_crl.c b/src/libstrongswan/plugins/x509/x509_crl.c
new file mode 100644
index 000000000..3bdda1701
--- /dev/null
+++ b/src/libstrongswan/plugins/x509/x509_crl.c
@@ -0,0 +1,742 @@
+/*
+ * Copyright (C) 2008 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.
+ *
+ * $Id: x509_crl.c 4091 2008-06-22 17:41:07Z andreas $
+ */
+
+#include "x509_crl.h"
+
+typedef struct private_x509_crl_t private_x509_crl_t;
+typedef struct revoked_t revoked_t;
+
+#include <debug.h>
+#include <library.h>
+#include <asn1/oid.h>
+#include <asn1/asn1.h>
+#include <asn1/asn1_parser.h>
+#include <asn1/pem.h>
+#include <credentials/certificates/x509.h>
+#include <utils/linked_list.h>
+
+/**
+ * entry for a revoked certificate
+ */
+struct revoked_t {
+ /**
+ * serial of the revoked certificate
+ */
+ chunk_t serial;
+
+ /**
+ * date of revocation
+ */
+ time_t date;
+
+ /**
+ * reason for revocation
+ */
+ crl_reason_t reason;
+};
+
+/**
+ * private data of x509_crl
+ */
+struct private_x509_crl_t {
+
+ /**
+ * public functions
+ */
+ x509_crl_t public;
+
+ /**
+ * X.509 crl encoding in ASN.1 DER format
+ */
+ chunk_t encoding;
+
+ /**
+ * X.509 crl body over which signature is computed
+ */
+ chunk_t tbsCertList;
+
+ /**
+ * Version of the X.509 crl
+ */
+ u_int version;
+
+ /**
+ * ID representing the crl issuer
+ */
+ identification_t *issuer;
+
+ /**
+ * CRL number
+ */
+ chunk_t crlNumber;
+
+ /**
+ * Time when the crl was generated
+ */
+ time_t thisUpdate;
+
+ /**
+ * Time when an update crl will be available
+ */
+ time_t nextUpdate;
+
+ /**
+ * list of revoked certificates as revoked_t
+ */
+ linked_list_t *revoked;
+
+ /**
+ * Authority Key Identifier
+ */
+ identification_t *authKeyIdentifier;
+
+ /**
+ * Authority Key Serial Number
+ */
+ chunk_t authKeySerialNumber;
+
+ /**
+ * Signature algorithm
+ */
+ int algorithm;
+
+ /**
+ * Signature
+ */
+ chunk_t signature;
+
+ /**
+ * reference counter
+ */
+ refcount_t ref;
+};
+
+/**
+ * from x509_cert
+ */
+extern identification_t* x509_parse_authorityKeyIdentifier(
+ chunk_t blob, int level0,
+ chunk_t *authKeySerialNumber);
+
+/**
+ * ASN.1 definition of an X.509 certificate revocation list
+ */
+static const asn1Object_t crlObjects[] = {
+ { 0, "certificateList", ASN1_SEQUENCE, ASN1_OBJ }, /* 0 */
+ { 1, "tbsCertList", ASN1_SEQUENCE, ASN1_OBJ }, /* 1 */
+ { 2, "version", ASN1_INTEGER, ASN1_OPT |
+ ASN1_BODY }, /* 2 */
+ { 2, "end opt", ASN1_EOC, ASN1_END }, /* 3 */
+ { 2, "signature", ASN1_EOC, ASN1_RAW }, /* 4 */
+ { 2, "issuer", ASN1_SEQUENCE, ASN1_OBJ }, /* 5 */
+ { 2, "thisUpdate", ASN1_EOC, ASN1_RAW }, /* 6 */
+ { 2, "nextUpdate", ASN1_EOC, ASN1_RAW }, /* 7 */
+ { 2, "revokedCertificates", ASN1_SEQUENCE, ASN1_OPT |
+ ASN1_LOOP }, /* 8 */
+ { 3, "certList", ASN1_SEQUENCE, ASN1_NONE }, /* 9 */
+ { 4, "userCertificate", ASN1_INTEGER, ASN1_BODY }, /* 10 */
+ { 4, "revocationDate", ASN1_EOC, ASN1_RAW }, /* 11 */
+ { 4, "crlEntryExtensions", ASN1_SEQUENCE, ASN1_OPT |
+ ASN1_LOOP }, /* 12 */
+ { 5, "extension", ASN1_SEQUENCE, ASN1_NONE }, /* 13 */
+ { 6, "extnID", ASN1_OID, ASN1_BODY }, /* 14 */
+ { 6, "critical", ASN1_BOOLEAN, ASN1_DEF |
+ ASN1_BODY }, /* 15 */
+ { 6, "extnValue", ASN1_OCTET_STRING, ASN1_BODY }, /* 16 */
+ { 4, "end opt or loop", ASN1_EOC, ASN1_END }, /* 17 */
+ { 2, "end opt or loop", ASN1_EOC, ASN1_END }, /* 18 */
+ { 2, "optional extensions", ASN1_CONTEXT_C_0, ASN1_OPT }, /* 19 */
+ { 3, "crlExtensions", ASN1_SEQUENCE, ASN1_LOOP }, /* 20 */
+ { 4, "extension", ASN1_SEQUENCE, ASN1_NONE }, /* 21 */
+ { 5, "extnID", ASN1_OID, ASN1_BODY }, /* 22 */
+ { 5, "critical", ASN1_BOOLEAN, ASN1_DEF |
+ ASN1_BODY }, /* 23 */
+ { 5, "extnValue", ASN1_OCTET_STRING, ASN1_BODY }, /* 24 */
+ { 3, "end loop", ASN1_EOC, ASN1_END }, /* 25 */
+ { 2, "end opt", ASN1_EOC, ASN1_END }, /* 26 */
+ { 1, "signatureAlgorithm", ASN1_EOC, ASN1_RAW }, /* 27 */
+ { 1, "signatureValue", ASN1_BIT_STRING, ASN1_BODY }, /* 28 */
+ { 0, "exit", ASN1_EOC, ASN1_EXIT }
+};
+#define CRL_OBJ_TBS_CERT_LIST 1
+#define CRL_OBJ_VERSION 2
+#define CRL_OBJ_SIG_ALG 4
+#define CRL_OBJ_ISSUER 5
+#define CRL_OBJ_THIS_UPDATE 6
+#define CRL_OBJ_NEXT_UPDATE 7
+#define CRL_OBJ_USER_CERTIFICATE 10
+#define CRL_OBJ_REVOCATION_DATE 11
+#define CRL_OBJ_CRL_ENTRY_EXTN_ID 14
+#define CRL_OBJ_CRL_ENTRY_CRITICAL 15
+#define CRL_OBJ_CRL_ENTRY_EXTN_VALUE 16
+#define CRL_OBJ_EXTN_ID 22
+#define CRL_OBJ_CRITICAL 23
+#define CRL_OBJ_EXTN_VALUE 24
+#define CRL_OBJ_ALGORITHM 27
+#define CRL_OBJ_SIGNATURE 28
+
+/**
+ * Parses an X.509 Certificate Revocation List (CRL)
+ */
+static bool parse(private_x509_crl_t *this)
+{
+ asn1_parser_t *parser;
+ chunk_t object;
+ chunk_t extnID;
+ chunk_t userCertificate = chunk_empty;
+ int objectID;
+ int sig_alg = OID_UNKNOWN;
+ bool success = FALSE;
+ bool critical;
+ revoked_t *revoked = NULL;
+
+ parser = asn1_parser_create(crlObjects, this->encoding);
+
+ while (parser->iterate(parser, &objectID, &object))
+ {
+ u_int level = parser->get_level(parser)+1;
+
+ switch (objectID)
+ {
+ case CRL_OBJ_TBS_CERT_LIST:
+ this->tbsCertList = object;
+ break;
+ case CRL_OBJ_VERSION:
+ this->version = (object.len) ? (1+(u_int)*object.ptr) : 1;
+ DBG2(" v%d", this->version);
+ break;
+ case CRL_OBJ_SIG_ALG:
+ sig_alg = asn1_parse_algorithmIdentifier(object, level, NULL);
+ break;
+ case CRL_OBJ_ISSUER:
+ this->issuer = identification_create_from_encoding(ID_DER_ASN1_DN, object);
+ DBG2(" '%D'", this->issuer);
+ break;
+ case CRL_OBJ_THIS_UPDATE:
+ this->thisUpdate = asn1_parse_time(object, level);
+ break;
+ case CRL_OBJ_NEXT_UPDATE:
+ this->nextUpdate = asn1_parse_time(object, level);
+ break;
+ case CRL_OBJ_USER_CERTIFICATE:
+ userCertificate = object;
+ break;
+ case CRL_OBJ_REVOCATION_DATE:
+ revoked = malloc_thing(revoked_t);
+ revoked->serial = userCertificate;
+ revoked->date = asn1_parse_time(object, level);
+ revoked->reason = CRL_UNSPECIFIED;
+ this->revoked->insert_last(this->revoked, (void *)revoked);
+ break;
+ case CRL_OBJ_CRL_ENTRY_EXTN_ID:
+ case CRL_OBJ_EXTN_ID:
+ extnID = object;
+ break;
+ case CRL_OBJ_CRL_ENTRY_CRITICAL:
+ case CRL_OBJ_CRITICAL:
+ critical = object.len && *object.ptr;
+ DBG2(" %s", critical ? "TRUE" : "FALSE");
+ break;
+ case CRL_OBJ_CRL_ENTRY_EXTN_VALUE:
+ case CRL_OBJ_EXTN_VALUE:
+ {
+ int extn_oid = asn1_known_oid(extnID);
+
+ if (revoked && extn_oid == OID_CRL_REASON_CODE)
+ {
+ if (*object.ptr == ASN1_ENUMERATED &&
+ asn1_length(&object) == 1)
+ {
+ revoked->reason = *object.ptr;
+ }
+ DBG2(" '%N'", crl_reason_names, revoked->reason);
+ }
+ else if (extn_oid == OID_AUTHORITY_KEY_ID)
+ {
+
+ this->authKeyIdentifier = x509_parse_authorityKeyIdentifier(object,
+ level, &this->authKeySerialNumber);
+ }
+ else if (extn_oid == OID_CRL_NUMBER)
+ {
+ if (!asn1_parse_simple_object(&object, ASN1_INTEGER,
+ level, "crlNumber"))
+ {
+ goto end;
+ }
+ this->crlNumber = object;
+ }
+ }
+ break;
+ case CRL_OBJ_ALGORITHM:
+ {
+ this->algorithm = asn1_parse_algorithmIdentifier(object, level, NULL);
+ if (this->algorithm != sig_alg)
+ {
+ DBG1(" signature algorithms do not agree");
+ goto end;
+ }
+ break;
+ }
+ case CRL_OBJ_SIGNATURE:
+ this->signature = object;
+ break;
+ default:
+ break;
+ }
+ }
+ success = parser->success(parser);
+
+end:
+ parser->destroy(parser);
+ return success;
+}
+
+/**
+ * enumerator filter callback for create_enumerator
+ */
+static bool filter(void *data, revoked_t **revoked, chunk_t *serial, void *p2,
+ time_t *date, void *p3, crl_reason_t *reason)
+{
+ if (serial)
+ {
+ *serial = (*revoked)->serial;
+ }
+ if (date)
+ {
+ *date = (*revoked)->date;
+ }
+ if (reason)
+ {
+ *reason = (*revoked)->reason;
+ }
+ return TRUE;
+}
+
+/**
+ * Implementation of crl_t.get_serial.
+ */
+static chunk_t get_serial(private_x509_crl_t *this)
+{
+ return this->crlNumber;
+}
+
+/**
+ * Implementation of crl_t.get_authKeyIdentifier.
+ */
+static identification_t* get_authKeyIdentifier(private_x509_crl_t *this)
+{
+ return this->authKeyIdentifier;
+}
+/**
+ * Implementation of crl_t.create_enumerator.
+ */
+static enumerator_t* create_enumerator(private_x509_crl_t *this)
+{
+ return enumerator_create_filter(
+ this->revoked->create_enumerator(this->revoked),
+ (void*)filter, NULL, NULL);
+}
+
+/**
+ * Implementation of certificate_t.get_type
+ */
+static certificate_type_t get_type(private_x509_crl_t *this)
+{
+ return CERT_X509_CRL;
+}
+
+/**
+ * Implementation of certificate_t.get_issuer and get_subject
+ */
+static identification_t* get_issuer(private_x509_crl_t *this)
+{
+ return this->issuer;
+}
+
+/**
+ * Implementation of certificate_t.has_subject and has_issuer.
+ */
+static id_match_t has_issuer(private_x509_crl_t *this, identification_t *issuer)
+{
+ id_match_t match;
+
+ if (issuer->get_type(issuer) == ID_PUBKEY_SHA1)
+ {
+ if (this->authKeyIdentifier)
+ {
+ match = issuer->matches(issuer, this->authKeyIdentifier);
+ }
+ else
+ {
+ match = ID_MATCH_NONE;
+ }
+ }
+ else
+ {
+ match = this->issuer->matches(this->issuer, issuer);
+ }
+ return match;
+}
+
+/**
+ * Implementation of certificate_t.issued_by
+ */
+static bool issued_by(private_x509_crl_t *this, certificate_t *issuer)
+{
+ public_key_t *key;
+ signature_scheme_t scheme;
+ bool valid;
+ x509_t *x509 = (x509_t*)issuer;
+
+ /* check if issuer is an X.509 CA certificate */
+ if (issuer->get_type(issuer) != CERT_X509)
+ {
+ return FALSE;
+ }
+ if (!(x509->get_flags(x509) & X509_CA))
+ {
+ return FALSE;
+ }
+
+ /* get the public key of the issuer */
+ key = issuer->get_public_key(issuer);
+
+ /* compare keyIdentifiers if available, otherwise use DNs */
+ if (this->authKeyIdentifier && key)
+ {
+ identification_t *subjectKeyIdentifier = key->get_id(key, ID_PUBKEY_SHA1);
+
+ if (!subjectKeyIdentifier->equals(subjectKeyIdentifier,
+ this->authKeyIdentifier))
+ {
+ return FALSE;
+ }
+ }
+ else
+ {
+ if (!this->issuer->equals(this->issuer, issuer->get_subject(issuer)))
+ {
+ return FALSE;
+ }
+ }
+ /* TODO: generic OID to scheme mapper? */
+ switch (this->algorithm)
+ {
+ case OID_MD5_WITH_RSA:
+ scheme = SIGN_RSA_EMSA_PKCS1_MD5;
+ break;
+ case OID_SHA1_WITH_RSA:
+ scheme = SIGN_RSA_EMSA_PKCS1_SHA1;
+ break;
+ case OID_SHA256_WITH_RSA:
+ scheme = SIGN_RSA_EMSA_PKCS1_SHA256;
+ break;
+ case OID_SHA384_WITH_RSA:
+ scheme = SIGN_RSA_EMSA_PKCS1_SHA384;
+ break;
+ case OID_SHA512_WITH_RSA:
+ scheme = SIGN_RSA_EMSA_PKCS1_SHA512;
+ break;
+ case OID_ECDSA_WITH_SHA1:
+ scheme = SIGN_ECDSA_WITH_SHA1;
+ break;
+ default:
+ return FALSE;
+ }
+ if (key == NULL)
+ {
+ return FALSE;
+ }
+ valid = key->verify(key, scheme, this->tbsCertList, this->signature);
+ key->destroy(key);
+ return valid;
+}
+
+/**
+ * Implementation of certificate_t.get_public_key
+ */
+static public_key_t* get_public_key(private_x509_crl_t *this)
+{
+ return NULL;
+}
+
+/**
+ * Implementation of certificate_t.asdf
+ */
+static private_x509_crl_t* get_ref(private_x509_crl_t *this)
+{
+ ref_get(&this->ref);
+ return this;
+}
+
+/**
+ * Implementation of certificate_t.get_validity.
+ */
+static bool get_validity(private_x509_crl_t *this, time_t *when,
+ time_t *not_before, time_t *not_after)
+{
+ time_t t;
+
+ if (when)
+ {
+ t = *when;
+ }
+ else
+ {
+ t = time(NULL);
+ }
+ if (not_before)
+ {
+ *not_before = this->thisUpdate;
+ }
+ if (not_after)
+ {
+ *not_after = this->nextUpdate;
+ }
+ return (t <= this->nextUpdate);
+}
+
+/**
+ * Implementation of certificate_t.is_newer.
+ */
+static bool is_newer(private_x509_crl_t *this, crl_t *that)
+{
+ chunk_t that_crlNumber = that->get_serial(that);
+ bool new;
+
+ /* compare crlNumbers if available - otherwise use thisUpdate */
+ if (this->crlNumber.ptr != NULL && that_crlNumber.ptr != NULL)
+ {
+ new = chunk_compare(this->crlNumber, that_crlNumber) > 0;
+ DBG1(" crl #%#B is %s - existing crl #%#B %s",
+ &this->crlNumber, new ? "newer":"not newer",
+ &that_crlNumber, new ? "replaced":"retained");
+ }
+ else
+ {
+ certificate_t *this_cert = &this->public.crl.certificate;
+ certificate_t *that_cert = &that->certificate;
+
+ time_t this_update, that_update, now = time(NULL);
+
+ this_cert->get_validity(this_cert, &now, &this_update, NULL);
+ that_cert->get_validity(that_cert, &now, &that_update, NULL);
+ new = this_update > that_update;
+ DBG1(" crl from %#T is %s - existing crl from %#T %s",
+ &this_update, FALSE, new ? "newer":"not newer",
+ &that_update, FALSE, new ? "replaced":"retained");
+ }
+ return new;
+}
+
+/**
+ * Implementation of certificate_t.get_encoding.
+ */
+static chunk_t get_encoding(private_x509_crl_t *this)
+{
+ return chunk_clone(this->encoding);
+}
+
+/**
+ * Implementation of certificate_t.equals.
+ */
+static bool equals(private_x509_crl_t *this, certificate_t *other)
+{
+ chunk_t encoding;
+ bool equal;
+
+ if ((certificate_t*)this == other)
+ {
+ return TRUE;
+ }
+ if (other->equals == (void*)equals)
+ { /* skip allocation if we have the same implementation */
+ return chunk_equals(this->encoding, ((private_x509_crl_t*)other)->encoding);
+ }
+ encoding = other->get_encoding(other);
+ equal = chunk_equals(this->encoding, encoding);
+ free(encoding.ptr);
+ return equal;
+}
+
+/**
+ * Implementation of certificate_t.destroy
+ */
+static void destroy(private_x509_crl_t *this)
+{
+ if (ref_put(&this->ref))
+ {
+ this->revoked->destroy_function(this->revoked, free);
+ DESTROY_IF(this->issuer);
+ DESTROY_IF(this->authKeyIdentifier);
+ free(this->encoding.ptr);
+ free(this);
+ }
+}
+
+/**
+ * create an empty but initialized X.509 crl
+ */
+static private_x509_crl_t* create_empty(void)
+{
+ private_x509_crl_t *this = malloc_thing(private_x509_crl_t);
+
+ this->public.crl.get_serial = (chunk_t (*)(crl_t*))get_serial;
+ this->public.crl.get_authKeyIdentifier = (identification_t* (*)(crl_t*))get_authKeyIdentifier;
+ this->public.crl.create_enumerator = (enumerator_t* (*)(crl_t*))create_enumerator;
+ this->public.crl.certificate.get_type = (certificate_type_t (*)(certificate_t *this))get_type;
+ this->public.crl.certificate.get_subject = (identification_t* (*)(certificate_t *this))get_issuer;
+ this->public.crl.certificate.get_issuer = (identification_t* (*)(certificate_t *this))get_issuer;
+ this->public.crl.certificate.has_subject = (id_match_t (*)(certificate_t*, identification_t *subject))has_issuer;
+ this->public.crl.certificate.has_issuer = (id_match_t (*)(certificate_t*, identification_t *issuer))has_issuer;
+ this->public.crl.certificate.issued_by = (bool (*)(certificate_t *this, certificate_t *issuer))issued_by;
+ this->public.crl.certificate.get_public_key = (public_key_t* (*)(certificate_t *this))get_public_key;
+ this->public.crl.certificate.get_validity = (bool (*)(certificate_t*, time_t *when, time_t *, time_t*))get_validity;
+ this->public.crl.certificate.is_newer = (bool (*)(certificate_t*,certificate_t*))is_newer;
+ this->public.crl.certificate.get_encoding = (chunk_t (*)(certificate_t*))get_encoding;
+ this->public.crl.certificate.equals = (bool (*)(certificate_t*, certificate_t *other))equals;
+ this->public.crl.certificate.get_ref = (certificate_t* (*)(certificate_t *this))get_ref;
+ this->public.crl.certificate.destroy = (void (*)(certificate_t *this))destroy;
+
+ this->encoding = chunk_empty;
+ this->tbsCertList = chunk_empty;
+ this->issuer = NULL;
+ this->crlNumber = chunk_empty;
+ this->revoked = linked_list_create();
+ this->authKeyIdentifier = NULL;
+ this->authKeySerialNumber = chunk_empty;
+ this->ref = 1;
+
+ return this;
+}
+
+/**
+ * create an X.509 crl from a chunk
+ */
+static private_x509_crl_t* create_from_chunk(chunk_t chunk)
+{
+ private_x509_crl_t *this = create_empty();
+
+ this->encoding = chunk;
+ if (!parse(this))
+ {
+ destroy(this);
+ return NULL;
+ }
+ return this;
+}
+
+/**
+ * create an X.509 crl from a file
+ */
+static private_x509_crl_t* create_from_file(char *path)
+{
+ bool pgp = FALSE;
+ chunk_t chunk;
+ private_x509_crl_t *this;
+
+ if (!pem_asn1_load_file(path, NULL, &chunk, &pgp))
+ {
+ return NULL;
+ }
+
+ this = create_from_chunk(chunk);
+
+ if (this == NULL)
+ {
+ DBG1(" could not parse loaded crl file '%s'",path);
+ return NULL;
+ }
+ DBG1(" loaded crl file '%s'", path);
+ return this;
+}
+
+typedef struct private_builder_t private_builder_t;
+/**
+ * Builder implementation for certificate loading
+ */
+struct private_builder_t {
+ /** implements the builder interface */
+ builder_t public;
+ /** loaded CRL */
+ private_x509_crl_t *crl;
+};
+
+/**
+ * Implementation of builder_t.build
+ */
+static private_x509_crl_t *build(private_builder_t *this)
+{
+ private_x509_crl_t *crl = this->crl;
+
+ free(this);
+ return crl;
+}
+
+/**
+ * Implementation of builder_t.add
+ */
+static void add(private_builder_t *this, builder_part_t part, ...)
+{
+ va_list args;
+
+ if (this->crl)
+ {
+ DBG1("ignoring surplus build part %N", builder_part_names, part);
+ return;
+ }
+
+ va_start(args, part);
+ switch (part)
+ {
+ case BUILD_FROM_FILE:
+ this->crl = create_from_file(va_arg(args, char*));
+ break;
+ case BUILD_BLOB_ASN1_DER:
+ {
+ this->crl = create_from_chunk(va_arg(args, chunk_t));
+ break;
+ }
+ default:
+ DBG1("ignoring unsupported build part %N", builder_part_names, part);
+ break;
+ }
+ va_end(args);
+}
+
+/**
+ * Builder construction function
+ */
+builder_t *x509_crl_builder(certificate_type_t type)
+{
+ private_builder_t *this;
+
+ if (type != CERT_X509_CRL)
+ {
+ return NULL;
+ }
+
+ this = malloc_thing(private_builder_t);
+
+ this->crl = NULL;
+ this->public.add = (void(*)(builder_t *this, builder_part_t part, ...))add;
+ this->public.build = (void*(*)(builder_t *this))build;
+
+ return &this->public;
+}
+
diff --git a/src/libstrongswan/plugins/x509/x509_crl.h b/src/libstrongswan/plugins/x509/x509_crl.h
new file mode 100644
index 000000000..0d9e5cca4
--- /dev/null
+++ b/src/libstrongswan/plugins/x509/x509_crl.h
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2008 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.
+ */
+
+/**
+ * @defgroup x509_crl x509_crl
+ * @{ @ingroup x509_p
+ */
+
+#ifndef X509_CRL_H_
+#define X509_CRL_H_
+
+typedef struct x509_crl_t x509_crl_t;
+
+#include <credentials/certificates/crl.h>
+
+/**
+ * Implementation of the X509 certification revocation list.
+ */
+struct x509_crl_t {
+
+ /**
+ * Implements the crl_t interface
+ */
+ crl_t crl;
+};
+
+
+/**
+ * Create the building facility for x509 certificate revocation lists.
+ *
+ * @param type certificate type, CERT_X509_CRL only
+ * @return builder instance to build certificate
+ */
+builder_t *x509_crl_builder(certificate_type_t type);
+
+#endif /* X509_CRL_H_ @}*/
diff --git a/src/libstrongswan/plugins/x509/x509_ocsp_request.c b/src/libstrongswan/plugins/x509/x509_ocsp_request.c
new file mode 100644
index 000000000..590a974f7
--- /dev/null
+++ b/src/libstrongswan/plugins/x509/x509_ocsp_request.c
@@ -0,0 +1,612 @@
+/*
+ * Copyright (C) 2008 Martin Willi
+ * Copyright (C) 2007 Andreas Steffen
+ * Hochschule fuer Technik Rapperswil
+ * Copyright (C) 2003 Christoph Gysin, Simon Zwahlen
+ *
+ * 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.
+ *
+ * $Id: x509_ocsp_request.c 4091 2008-06-22 17:41:07Z andreas $
+ */
+
+#include "x509_ocsp_request.h"
+
+#include <library.h>
+#include <asn1/oid.h>
+#include <asn1/asn1.h>
+#include <utils/identification.h>
+#include <utils/linked_list.h>
+#include <debug.h>
+#include <credentials/certificates/x509.h>
+
+#define NONCE_LEN 16
+
+typedef struct private_x509_ocsp_request_t private_x509_ocsp_request_t;
+
+/**
+ * private data of x509_ocsp_request
+ */
+struct private_x509_ocsp_request_t {
+
+ /**
+ * public functions
+ */
+ x509_ocsp_request_t public;
+
+ /**
+ * CA the candidates belong to
+ */
+ x509_t *ca;
+
+ /**
+ * Requestor name, subject of cert used if not set
+ */
+ identification_t *requestor;
+
+ /**
+ * Requestor certificate, included in request
+ */
+ certificate_t *cert;
+
+ /**
+ * Requestor private key to sign request
+ */
+ private_key_t *key;
+
+ /**
+ * list of certificates to check, x509_t
+ */
+ linked_list_t *candidates;
+
+ /**
+ * nonce used in request
+ */
+ chunk_t nonce;
+
+ /**
+ * encoded OCSP request
+ */
+ chunk_t encoding;
+
+ /**
+ * reference count
+ */
+ refcount_t ref;
+};
+
+static u_char ASN1_nonce_oid_str[] = {
+ 0x06, 0x09,
+ 0x2B, 0x06,
+ 0x01, 0x05, 0x05, 0x07, 0x30, 0x01, 0x02
+};
+
+static u_char ASN1_response_oid_str[] = {
+ 0x06, 0x09,
+ 0x2B, 0x06,
+ 0x01, 0x05, 0x05, 0x07, 0x30, 0x01, 0x04
+};
+
+static u_char ASN1_response_content_str[] = {
+ 0x04, 0x0D,
+ 0x30, 0x0B,
+ 0x06, 0x09,
+ 0x2B, 0x06,
+ 0x01, 0x05, 0x05, 0x07, 0x30, 0x01, 0x01
+};
+
+static const chunk_t ASN1_nonce_oid = chunk_from_buf(ASN1_nonce_oid_str);
+static const chunk_t ASN1_response_oid = chunk_from_buf(ASN1_response_oid_str);
+static const chunk_t ASN1_response_content = chunk_from_buf(ASN1_response_content_str);
+
+/**
+ * build requestorName
+ */
+static chunk_t build_requestorName(private_x509_ocsp_request_t *this)
+{
+ if (this->requestor || this->cert)
+ { /* use requestor name, fallback to his cert subject */
+ if (!this->requestor)
+ {
+ this->requestor = this->cert->get_subject(this->cert);
+ this->requestor = this->requestor->clone(this->requestor);
+ }
+ return asn1_wrap(ASN1_CONTEXT_C_1, "m",
+ asn1_simple_object(ASN1_CONTEXT_C_4,
+ this->requestor->get_encoding(this->requestor)));
+
+ }
+ return chunk_empty;
+}
+
+/**
+ * build Request, not using singleRequestExtensions
+ */
+static chunk_t build_Request(private_x509_ocsp_request_t *this,
+ chunk_t issuerNameHash, chunk_t issuerKeyHash,
+ chunk_t serialNumber)
+{
+ return asn1_wrap(ASN1_SEQUENCE, "m",
+ asn1_wrap(ASN1_SEQUENCE, "cmmm",
+ asn1_algorithmIdentifier(OID_SHA1),
+ asn1_simple_object(ASN1_OCTET_STRING, issuerNameHash),
+ asn1_simple_object(ASN1_OCTET_STRING, issuerKeyHash),
+ asn1_simple_object(ASN1_INTEGER, serialNumber)));
+}
+
+/**
+ * build requestList
+ */
+static chunk_t build_requestList(private_x509_ocsp_request_t *this)
+{
+ chunk_t issuerNameHash, issuerKeyHash;
+ identification_t *issuer;
+ x509_t *x509;
+ certificate_t *cert;
+ chunk_t list = chunk_empty;
+ public_key_t *public;
+
+ cert = (certificate_t*)this->ca;
+ public = cert->get_public_key(cert);
+ if (public)
+ {
+ hasher_t *hasher = lib->crypto->create_hasher(lib->crypto, HASH_SHA1);
+ if (hasher)
+ {
+ identification_t *keyid = public->get_id(public, ID_PUBKEY_SHA1);
+ if (keyid)
+ {
+ enumerator_t *enumerator;
+
+ issuerKeyHash = keyid->get_encoding(keyid);
+
+ issuer = cert->get_subject(cert);
+ hasher->allocate_hash(hasher, issuer->get_encoding(issuer),
+ &issuerNameHash);
+ hasher->destroy(hasher);
+
+ enumerator = this->candidates->create_enumerator(this->candidates);
+ while (enumerator->enumerate(enumerator, &x509))
+ {
+ chunk_t request, serialNumber;
+
+ serialNumber = x509->get_serial(x509);
+ request = build_Request(this, issuerNameHash, issuerKeyHash,
+ serialNumber);
+ list = chunk_cat("mm", list, request);
+ }
+ enumerator->destroy(enumerator);
+ chunk_free(&issuerNameHash);
+ }
+ }
+ else
+ {
+ DBG1("creating OCSP request failed, SHA1 not supported");
+ }
+ public->destroy(public);
+ }
+ else
+ {
+ DBG1("creating OCSP request failed, CA certificate has no public key");
+ }
+ return asn1_wrap(ASN1_SEQUENCE, "m", list);
+}
+
+/**
+ * build nonce extension
+ */
+static chunk_t build_nonce(private_x509_ocsp_request_t *this)
+{
+ rng_t *rng;
+
+ rng = lib->crypto->create_rng(lib->crypto, RNG_WEAK);
+ if (rng)
+ {
+ rng->allocate_bytes(rng, NONCE_LEN, &this->nonce);
+ rng->destroy(rng);
+ return asn1_wrap(ASN1_SEQUENCE, "cm", ASN1_nonce_oid,
+ asn1_simple_object(ASN1_OCTET_STRING, this->nonce));
+ }
+ DBG1("creating OCSP request nonce failed, no RNG found");
+ return chunk_empty;
+}
+
+/**
+ * build acceptableResponses extension
+ */
+static chunk_t build_acceptableResponses(private_x509_ocsp_request_t *this)
+{
+ return asn1_wrap(ASN1_SEQUENCE, "cc",
+ ASN1_response_oid,
+ ASN1_response_content);
+}
+
+/**
+ * build requestExtensions
+ */
+static chunk_t build_requestExtensions(private_x509_ocsp_request_t *this)
+{
+ return asn1_wrap(ASN1_CONTEXT_C_2, "m",
+ asn1_wrap(ASN1_SEQUENCE, "mm",
+ build_nonce(this),
+ build_acceptableResponses(this)));
+}
+
+/**
+ * build tbsRequest
+ */
+static chunk_t build_tbsRequest(private_x509_ocsp_request_t *this)
+{
+ return asn1_wrap(ASN1_SEQUENCE, "mmm",
+ build_requestorName(this),
+ build_requestList(this),
+ build_requestExtensions(this));
+}
+
+/**
+ * Build the optionalSignature
+ */
+static chunk_t build_optionalSignature(private_x509_ocsp_request_t *this,
+ chunk_t tbsRequest)
+{
+ int oid;
+ signature_scheme_t scheme;
+ chunk_t certs, signature;
+
+ switch (this->key->get_type(this->key))
+ {
+ /* TODO: use a generic mapping function */
+ case KEY_RSA:
+ oid = OID_SHA1_WITH_RSA;
+ scheme = SIGN_RSA_EMSA_PKCS1_SHA1;
+ break;
+ case KEY_ECDSA:
+ oid = OID_ECDSA_WITH_SHA1;
+ scheme = SIGN_ECDSA_WITH_SHA1;
+ break;
+ default:
+ DBG1("unable to sign OCSP request, %N signature not supported",
+ key_type_names, this->key->get_type(this->key));
+ return chunk_empty;
+ }
+
+ if (!this->key->sign(this->key, scheme, tbsRequest, &signature))
+ {
+ DBG1("creating OCSP signature failed, skipped");
+ return chunk_empty;
+ }
+ if (this->cert)
+ {
+ certs = asn1_wrap(ASN1_CONTEXT_C_0, "m",
+ asn1_wrap(ASN1_SEQUENCE, "m",
+ this->cert->get_encoding(this->cert)));
+ }
+ return asn1_wrap(ASN1_CONTEXT_C_0, "m",
+ asn1_wrap(ASN1_SEQUENCE, "cmm",
+ asn1_algorithmIdentifier(oid),
+ asn1_bitstring("m", signature),
+ certs));
+}
+
+/**
+ * Build the OCSPRequest data
+ *
+ */
+static chunk_t build_OCSPRequest(private_x509_ocsp_request_t *this)
+{
+ chunk_t tbsRequest, optionalSignature = chunk_empty;
+
+ tbsRequest = build_tbsRequest(this);
+ if (this->key)
+ {
+ optionalSignature = build_optionalSignature(this, tbsRequest);
+ }
+ return asn1_wrap(ASN1_SEQUENCE, "mm", tbsRequest, optionalSignature);
+}
+
+
+/**
+ * Implementation of certificate_t.get_type
+ */
+static certificate_type_t get_type(private_x509_ocsp_request_t *this)
+{
+ return CERT_X509_OCSP_REQUEST;
+}
+
+/**
+ * Implementation of certificate_t.get_subject
+ */
+static identification_t* get_subject(private_x509_ocsp_request_t *this)
+{
+ certificate_t *ca = (certificate_t*)this->ca;
+
+ if (this->requestor)
+ {
+ return this->requestor;
+ }
+ if (this->cert)
+ {
+ return this->cert->get_subject(this->cert);
+ }
+ return ca->get_subject(ca);
+}
+
+/**
+ * Implementation of certificate_t.get_issuer
+ */
+static identification_t* get_issuer(private_x509_ocsp_request_t *this)
+{
+ certificate_t *ca = (certificate_t*)this->ca;
+
+ return ca->get_subject(ca);
+}
+
+/**
+ * Implementation of certificate_t.has_subject.
+ */
+static id_match_t has_subject(private_x509_ocsp_request_t *this,
+ identification_t *subject)
+{
+ certificate_t *current;
+ enumerator_t *enumerator;
+ id_match_t match, best = ID_MATCH_NONE;
+
+ enumerator = this->candidates->create_enumerator(this->candidates);
+ while (enumerator->enumerate(enumerator, &current))
+ {
+ match = current->has_subject(current, subject);
+ if (match > best)
+ {
+ best = match;
+ }
+ }
+ enumerator->destroy(enumerator);
+ return best;
+}
+
+/**
+ * Implementation of certificate_t.has_subject.
+ */
+static id_match_t has_issuer(private_x509_ocsp_request_t *this,
+ identification_t *issuer)
+{
+ certificate_t *ca = (certificate_t*)this->ca;
+
+ return ca->has_subject(ca, issuer);
+}
+
+/**
+ * Implementation of certificate_t.issued_by
+ */
+static bool issued_by(private_x509_ocsp_request_t *this, certificate_t *issuer)
+{
+ DBG1("OCSP request validation not implemented!");
+ return FALSE;
+}
+
+/**
+ * Implementation of certificate_t.get_public_key
+ */
+static public_key_t* get_public_key(private_x509_ocsp_request_t *this)
+{
+ return NULL;
+}
+
+/**
+ * Implementation of x509_cert_t.get_validity.
+ */
+static bool get_validity(private_x509_ocsp_request_t *this, time_t *when,
+ time_t *not_before, time_t *not_after)
+{
+ certificate_t *cert;
+
+ if (this->cert)
+ {
+ cert = this->cert;
+ }
+ else
+ {
+ cert = (certificate_t*)this->ca;
+ }
+ return cert->get_validity(cert, when, not_before, not_after);
+}
+
+/**
+ * Implementation of certificate_t.get_encoding.
+ */
+static chunk_t get_encoding(private_x509_ocsp_request_t *this)
+{
+ return chunk_clone(this->encoding);
+}
+
+/**
+ * Implementation of certificate_t.equals.
+ */
+static bool equals(private_x509_ocsp_request_t *this, certificate_t *other)
+{
+ chunk_t encoding;
+ bool equal;
+
+ if (this == (private_x509_ocsp_request_t*)other)
+ {
+ return TRUE;
+ }
+ if (other->get_type(other) != CERT_X509_OCSP_REQUEST)
+ {
+ return FALSE;
+ }
+ if (other->equals == (void*)equals)
+ { /* skip allocation if we have the same implementation */
+ return chunk_equals(this->encoding, ((private_x509_ocsp_request_t*)other)->encoding);
+ }
+ encoding = other->get_encoding(other);
+ equal = chunk_equals(this->encoding, encoding);
+ free(encoding.ptr);
+ return equal;
+}
+
+/**
+ * Implementation of certificate_t.asdf
+ */
+static private_x509_ocsp_request_t* get_ref(private_x509_ocsp_request_t *this)
+{
+ ref_get(&this->ref);
+ return this;
+}
+
+/**
+ * Implementation of x509_ocsp_request_t.destroy
+ */
+static void destroy(private_x509_ocsp_request_t *this)
+{
+ if (ref_put(&this->ref))
+ {
+ DESTROY_IF((certificate_t*)this->ca);
+ DESTROY_IF(this->requestor);
+ DESTROY_IF(this->cert);
+ DESTROY_IF(this->key);
+ this->candidates->destroy_offset(this->candidates, offsetof(certificate_t, destroy));
+ chunk_free(&this->nonce);
+ chunk_free(&this->encoding);
+ free(this);
+ }
+}
+
+/**
+ * create an empty but initialized OCSP request
+ */
+static private_x509_ocsp_request_t *create_empty()
+{
+ private_x509_ocsp_request_t *this = malloc_thing(private_x509_ocsp_request_t);
+
+ this->public.interface.interface.get_type = (certificate_type_t (*)(certificate_t *this))get_type;
+ this->public.interface.interface.get_subject = (identification_t* (*)(certificate_t *this))get_subject;
+ this->public.interface.interface.get_issuer = (identification_t* (*)(certificate_t *this))get_issuer;
+ this->public.interface.interface.has_subject = (id_match_t(*)(certificate_t*, identification_t *subject))has_subject;
+ this->public.interface.interface.has_issuer = (id_match_t(*)(certificate_t*, identification_t *issuer))has_issuer;
+ this->public.interface.interface.issued_by = (bool (*)(certificate_t *this, certificate_t *issuer))issued_by;
+ this->public.interface.interface.get_public_key = (public_key_t* (*)(certificate_t *this))get_public_key;
+ this->public.interface.interface.get_validity = (bool(*)(certificate_t*, time_t *when, time_t *, time_t*))get_validity;
+ this->public.interface.interface.get_encoding = (chunk_t(*)(certificate_t*))get_encoding;
+ this->public.interface.interface.equals = (bool(*)(certificate_t*, certificate_t *other))equals;
+ this->public.interface.interface.get_ref = (certificate_t* (*)(certificate_t *this))get_ref;
+ this->public.interface.interface.destroy = (void (*)(certificate_t *this))destroy;
+
+ this->ca = NULL;
+ this->requestor = NULL;
+ this->cert = NULL;
+ this->key = NULL;
+ this->nonce = chunk_empty;
+ this->encoding = chunk_empty;
+ this->candidates = linked_list_create();
+ this->ref = 1;
+
+ return this;
+}
+
+typedef struct private_builder_t private_builder_t;
+/**
+ * Builder implementation for certificate loading
+ */
+struct private_builder_t {
+ /** implements the builder interface */
+ builder_t public;
+ /** OCSP request to build */
+ private_x509_ocsp_request_t *req;
+};
+
+/**
+ * Implementation of builder_t.build
+ */
+static x509_ocsp_request_t *build(private_builder_t *this)
+{
+ private_x509_ocsp_request_t *req;
+
+ req = this->req;
+ free(this);
+ if (req->ca)
+ {
+ req->encoding = build_OCSPRequest(req);
+ return &req->public;
+ }
+ destroy(req);
+ return NULL;
+}
+
+/**
+ * Implementation of builder_t.add
+ */
+static void add(private_builder_t *this, builder_part_t part, ...)
+{
+ va_list args;
+ certificate_t *cert;
+
+ va_start(args, part);
+ switch (part)
+ {
+ case BUILD_CA_CERT:
+ cert = va_arg(args, certificate_t*);
+ if (cert->get_type(cert) == CERT_X509)
+ {
+ this->req->ca = (x509_t*)cert;
+ }
+ else
+ {
+ cert->destroy(cert);
+ }
+ break;
+ case BUILD_CERT:
+ cert = va_arg(args, certificate_t*);
+ if (cert->get_type(cert) == CERT_X509)
+ {
+ this->req->candidates->insert_last(this->req->candidates, cert);
+ }
+ else
+ {
+ cert->destroy(cert);
+ }
+ break;
+ case BUILD_SIGNING_CERT:
+ this->req->cert = va_arg(args, certificate_t*);
+ break;
+ case BUILD_SIGNING_KEY:
+ this->req->key = va_arg(args, private_key_t*);
+ break;
+ case BUILD_SUBJECT:
+ this->req->requestor = va_arg(args, identification_t*);
+ break;
+ default:
+ DBG1("ignoring unsupported build part %N", builder_part_names, part);
+ break;
+ }
+ va_end(args);
+}
+
+/**
+ * Builder construction function
+ */
+builder_t *x509_ocsp_request_builder(certificate_type_t type)
+{
+ private_builder_t *this;
+
+ if (type != CERT_X509_OCSP_REQUEST)
+ {
+ return NULL;
+ }
+
+ this = malloc_thing(private_builder_t);
+
+ this->req = create_empty();
+ this->public.add = (void(*)(builder_t *this, builder_part_t part, ...))add;
+ this->public.build = (void*(*)(builder_t *this))build;
+
+ return &this->public;
+}
+
diff --git a/src/libstrongswan/plugins/x509/x509_ocsp_request.h b/src/libstrongswan/plugins/x509/x509_ocsp_request.h
new file mode 100644
index 000000000..0a4016f65
--- /dev/null
+++ b/src/libstrongswan/plugins/x509/x509_ocsp_request.h
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2008 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.
+ */
+
+/**
+ * @defgroup x509_ocsp_request x509_ocsp_request
+ * @{ @ingroup x509_p
+ */
+
+#ifndef X509_OCSP_REQUEST_H_
+#define X509_OCSP_REQUEST_H_
+
+#include <credentials/certificates/ocsp_request.h>
+
+typedef struct x509_ocsp_request_t x509_ocsp_request_t;
+
+/**
+ * Implementation of ocsp_request_t using own ASN1 parser.
+ */
+struct x509_ocsp_request_t {
+
+ /**
+ * Implements the ocsp_request_t interface
+ */
+ ocsp_request_t interface;
+};
+
+/**
+ * Create the building facility for OCSP requests.
+ *
+ * The resulting builder accepts:
+ * BUILD_CA_CERT: CA of the checked certificates, exactly one
+ * BUILD_CERT: certificates to check with the request, at least one
+ * BUILD_SUBJECT: subject requesting check, optional
+ * BUILD_SIGNING_CERT: certificate to create requestor signature, optional
+ * BUILD_SIGNING_KEY: private key to create requestor signature, optional
+ *
+ * @param type certificate type, CERT_X509_OCSP_REQUEST only
+ * @return builder instance to build OCSP requests
+ */
+builder_t *x509_ocsp_request_builder(certificate_type_t type);
+
+#endif /* X509_OCSP_REQUEST_H_ @}*/
diff --git a/src/libstrongswan/plugins/x509/x509_ocsp_response.c b/src/libstrongswan/plugins/x509/x509_ocsp_response.c
new file mode 100644
index 000000000..33cf73cd2
--- /dev/null
+++ b/src/libstrongswan/plugins/x509/x509_ocsp_response.c
@@ -0,0 +1,990 @@
+/**
+ * Copyright (C) 2008 Martin Willi
+ * Copyright (C) 2007 Andreas Steffen
+ * Hochschule für Technik Rapperswil
+ * Copyright (C) 2003 Christoph Gysin, Simon Zwahlen
+ *
+ * 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.
+ *
+ * $Id: x509_ocsp_response.c 4091 2008-06-22 17:41:07Z andreas $
+ */
+
+#include "x509_ocsp_response.h"
+
+#include <time.h>
+
+#include <asn1/oid.h>
+#include <asn1/asn1.h>
+#include <asn1/asn1_parser.h>
+#include <utils/identification.h>
+#include <utils/linked_list.h>
+#include <debug.h>
+
+#include <library.h>
+#include <credentials/certificates/x509.h>
+#include <credentials/certificates/crl.h>
+
+/**
+ * how long do we use an OCSP response without a nextUpdate
+ */
+#define OCSP_DEFAULT_LIFETIME 30
+
+typedef struct private_x509_ocsp_response_t private_x509_ocsp_response_t;
+
+/**
+ * Private data of a ocsp_t object.
+ */
+struct private_x509_ocsp_response_t {
+ /**
+ * Public interface for this ocsp object.
+ */
+ x509_ocsp_response_t public;
+
+ /**
+ * complete encoded OCSP response
+ */
+ chunk_t encoding;
+
+ /**
+ * data for signature verficiation
+ */
+ chunk_t tbsResponseData;
+
+ /**
+ * signature algorithm (OID)
+ */
+ int signatureAlgorithm;
+
+ /**
+ * signature
+ */
+ chunk_t signature;
+
+ /**
+ * name or keyid of the responder
+ */
+ identification_t *responderId;
+
+ /**
+ * time of response production
+ */
+ time_t producedAt;
+
+ /**
+ * latest nextUpdate in this OCSP response
+ */
+ time_t usableUntil;
+
+ /**
+ * list of included certificates
+ */
+ linked_list_t *certs;
+
+ /**
+ * Linked list of OCSP responses, single_response_t
+ */
+ linked_list_t *responses;
+
+ /**
+ * Nonce required for ocsp request and response
+ */
+ chunk_t nonce;
+
+ /**
+ * reference counter
+ */
+ refcount_t ref;
+};
+
+/**
+ * single response contained in OCSP response
+ */
+typedef struct {
+ /** hash algorithm OID to for the two hashes */
+ int hashAlgorithm;
+ /** hash of issuer DN */
+ chunk_t issuerNameHash;
+ /** issuerKeyID */
+ chunk_t issuerKeyHash;
+ /** serial number of certificate */
+ chunk_t serialNumber;
+ /** OCSP certificate status */
+ cert_validation_t status;
+ /** time of revocation, if revoked */
+ time_t revocationTime;
+ /** revocation reason, if revoked */
+ crl_reason_t revocationReason;
+ /** creation of associated CRL */
+ time_t thisUpdate;
+ /** creation of next CRL */
+ time_t nextUpdate;
+} single_response_t;
+
+/* our OCSP response version implementation */
+#define OCSP_BASIC_RESPONSE_VERSION 1
+
+/* some OCSP specific prefabricated ASN.1 constants */
+static u_char ASN1_nonce_oid_str[] = {
+ 0x06, 0x09,
+ 0x2B, 0x06,
+ 0x01, 0x05, 0x05, 0x07, 0x30, 0x01, 0x02
+};
+
+static u_char ASN1_response_oid_str[] = {
+ 0x06, 0x09,
+ 0x2B, 0x06,
+ 0x01, 0x05, 0x05, 0x07, 0x30, 0x01, 0x04
+};
+
+static u_char ASN1_response_content_str[] = {
+ 0x04, 0x0D,
+ 0x30, 0x0B,
+ 0x06, 0x09,
+ 0x2B, 0x06,
+ 0x01, 0x05, 0x05, 0x07, 0x30, 0x01, 0x01
+};
+
+static const chunk_t ASN1_nonce_oid = chunk_from_buf(ASN1_nonce_oid_str);
+static const chunk_t ASN1_response_oid = chunk_from_buf(ASN1_response_oid_str);
+static const chunk_t ASN1_response_content = chunk_from_buf(ASN1_response_content_str);
+
+/**
+ * Implementaiton of ocsp_response_t.get_status
+ */
+static cert_validation_t get_status(private_x509_ocsp_response_t *this,
+ x509_t *subject, x509_t *issuer,
+ time_t *revocation_time,
+ crl_reason_t *revocation_reason,
+ time_t *this_update, time_t *next_update)
+{
+ enumerator_t *enumerator;
+ single_response_t *response;
+ cert_validation_t status = VALIDATION_FAILED;
+ certificate_t *issuercert = &issuer->interface;
+
+ enumerator = this->responses->create_enumerator(this->responses);
+ while (enumerator->enumerate(enumerator, &response))
+ {
+ hasher_t *hasher;
+ identification_t *id;
+ chunk_t hash;
+
+ /* check serial first, is cheaper */
+ if (!chunk_equals(subject->get_serial(subject), response->serialNumber))
+ {
+ continue;
+ }
+ /* check issuerKeyHash if available */
+ if (response->issuerKeyHash.ptr)
+ {
+ public_key_t *public;
+
+ public = issuercert->get_public_key(issuercert);
+ if (!public)
+ {
+ continue;
+ }
+ switch (response->hashAlgorithm)
+ { /* TODO: generic mapper function */
+ case OID_SHA1:
+ id = public->get_id(public, ID_PUBKEY_SHA1);
+ break;
+ default:
+ public->destroy(public);
+ continue;
+ }
+ if (!chunk_equals(response->issuerKeyHash, id->get_encoding(id)))
+ {
+ public->destroy(public);
+ continue;
+ }
+ public->destroy(public);
+ }
+ /* check issuerNameHash, if available */
+ else if (response->issuerNameHash.ptr)
+ {
+ hasher = lib->crypto->create_hasher(lib->crypto,
+ hasher_algorithm_from_oid(response->hashAlgorithm));
+ if (!hasher)
+ {
+ continue;
+ }
+ id = issuercert->get_subject(issuercert);
+ hasher->allocate_hash(hasher, id->get_encoding(id), &hash);
+ hasher->destroy(hasher);
+ if (!chunk_equals(hash, response->issuerNameHash))
+ {
+ continue;
+ }
+ }
+ else
+ {
+ continue;
+ }
+ /* got a match */
+ status = response->status;
+ *revocation_time = response->revocationTime;
+ *revocation_reason = response->revocationReason;
+ *this_update = response->thisUpdate;
+ *next_update = response->nextUpdate;
+
+ break;
+ }
+ enumerator->destroy(enumerator);
+ return status;
+}
+
+/**
+ * Implementation of ocsp_response_t.create_cert_enumerator.
+ */
+static enumerator_t* create_cert_enumerator(private_x509_ocsp_response_t *this)
+{
+ return this->certs->create_enumerator(this->certs);
+}
+
+/**
+ * ASN.1 definition of singleResponse
+ */
+static const asn1Object_t singleResponseObjects[] = {
+ { 0, "singleResponse", ASN1_SEQUENCE, ASN1_BODY }, /* 0 */
+ { 1, "certID", ASN1_SEQUENCE, ASN1_NONE }, /* 1 */
+ { 2, "algorithm", ASN1_EOC, ASN1_RAW }, /* 2 */
+ { 2, "issuerNameHash", ASN1_OCTET_STRING, ASN1_BODY }, /* 3 */
+ { 2, "issuerKeyHash", ASN1_OCTET_STRING, ASN1_BODY }, /* 4 */
+ { 2, "serialNumber", ASN1_INTEGER, ASN1_BODY }, /* 5 */
+ { 1, "certStatusGood", ASN1_CONTEXT_S_0, ASN1_OPT }, /* 6 */
+ { 1, "end opt", ASN1_EOC, ASN1_END }, /* 7 */
+ { 1, "certStatusRevoked", ASN1_CONTEXT_C_1, ASN1_OPT }, /* 8 */
+ { 2, "revocationTime", ASN1_GENERALIZEDTIME, ASN1_BODY }, /* 9 */
+ { 2, "revocationReason", ASN1_CONTEXT_C_0, ASN1_OPT }, /* 10 */
+ { 3, "crlReason", ASN1_ENUMERATED, ASN1_BODY }, /* 11 */
+ { 2, "end opt", ASN1_EOC, ASN1_END }, /* 12 */
+ { 1, "end opt", ASN1_EOC, ASN1_END }, /* 13 */
+ { 1, "certStatusUnknown", ASN1_CONTEXT_S_2, ASN1_OPT }, /* 14 */
+ { 1, "end opt", ASN1_EOC, ASN1_END }, /* 15 */
+ { 1, "thisUpdate", ASN1_GENERALIZEDTIME, ASN1_BODY }, /* 16 */
+ { 1, "nextUpdateContext", ASN1_CONTEXT_C_0, ASN1_OPT }, /* 17 */
+ { 2, "nextUpdate", ASN1_GENERALIZEDTIME, ASN1_BODY }, /* 18 */
+ { 1, "end opt", ASN1_EOC, ASN1_END }, /* 19 */
+ { 1, "singleExtensionsContext", ASN1_CONTEXT_C_1, ASN1_OPT }, /* 20 */
+ { 2, "singleExtensions", ASN1_SEQUENCE, ASN1_LOOP }, /* 21 */
+ { 3, "extension", ASN1_SEQUENCE, ASN1_NONE }, /* 22 */
+ { 4, "extnID", ASN1_OID, ASN1_BODY }, /* 23 */
+ { 4, "critical", ASN1_BOOLEAN, ASN1_BODY |
+ ASN1_DEF }, /* 24 */
+ { 4, "extnValue", ASN1_OCTET_STRING, ASN1_BODY }, /* 25 */
+ { 2, "end loop", ASN1_EOC, ASN1_END }, /* 26 */
+ { 1, "end opt", ASN1_EOC, ASN1_END }, /* 27 */
+ { 0, "exit", ASN1_EOC, ASN1_EXIT }
+};
+#define SINGLE_RESPONSE_ALGORITHM 2
+#define SINGLE_RESPONSE_ISSUER_NAME_HASH 3
+#define SINGLE_RESPONSE_ISSUER_KEY_HASH 4
+#define SINGLE_RESPONSE_SERIAL_NUMBER 5
+#define SINGLE_RESPONSE_CERT_STATUS_GOOD 6
+#define SINGLE_RESPONSE_CERT_STATUS_REVOKED 8
+#define SINGLE_RESPONSE_CERT_STATUS_REVOCATION_TIME 9
+#define SINGLE_RESPONSE_CERT_STATUS_CRL_REASON 11
+#define SINGLE_RESPONSE_CERT_STATUS_UNKNOWN 14
+#define SINGLE_RESPONSE_THIS_UPDATE 16
+#define SINGLE_RESPONSE_NEXT_UPDATE 18
+#define SINGLE_RESPONSE_EXT_ID 23
+#define SINGLE_RESPONSE_CRITICAL 24
+#define SINGLE_RESPONSE_EXT_VALUE 25
+
+/**
+ * Parse a single OCSP response
+ */
+static bool parse_singleResponse(private_x509_ocsp_response_t *this,
+ chunk_t blob, int level0)
+{
+ asn1_parser_t *parser;
+ chunk_t object;
+ int objectID;
+ bool success = FALSE;
+
+ single_response_t *response;
+
+ response = malloc_thing(single_response_t);
+ response->hashAlgorithm = OID_UNKNOWN;
+ response->issuerNameHash = chunk_empty;
+ response->issuerKeyHash = chunk_empty;
+ response->serialNumber = chunk_empty;
+ response->status = VALIDATION_FAILED;
+ response->revocationTime = 0;
+ response->revocationReason = CRL_UNSPECIFIED;
+ response->thisUpdate = UNDEFINED_TIME;
+ /* if nextUpdate is missing, we give it a short lifetime */
+ response->nextUpdate = this->producedAt + OCSP_DEFAULT_LIFETIME;
+
+ parser = asn1_parser_create(singleResponseObjects, blob);
+ parser->set_top_level(parser, level0);
+
+ while (parser->iterate(parser, &objectID, &object))
+ {
+ switch (objectID)
+ {
+ case SINGLE_RESPONSE_ALGORITHM:
+ response->hashAlgorithm = asn1_parse_algorithmIdentifier(object,
+ parser->get_level(parser)+1, NULL);
+ break;
+ case SINGLE_RESPONSE_ISSUER_NAME_HASH:
+ response->issuerNameHash = object;
+ break;
+ case SINGLE_RESPONSE_ISSUER_KEY_HASH:
+ response->issuerKeyHash = object;
+ break;
+ case SINGLE_RESPONSE_SERIAL_NUMBER:
+ response->serialNumber = object;
+ break;
+ case SINGLE_RESPONSE_CERT_STATUS_GOOD:
+ response->status = VALIDATION_GOOD;
+ break;
+ case SINGLE_RESPONSE_CERT_STATUS_REVOKED:
+ response->status = VALIDATION_REVOKED;
+ break;
+ case SINGLE_RESPONSE_CERT_STATUS_REVOCATION_TIME:
+ response->revocationTime = asn1_to_time(&object, ASN1_GENERALIZEDTIME);
+ break;
+ case SINGLE_RESPONSE_CERT_STATUS_CRL_REASON:
+ if (object.len == 1)
+ {
+ response->revocationReason = *object.ptr;
+ }
+ break;
+ case SINGLE_RESPONSE_CERT_STATUS_UNKNOWN:
+ response->status = VALIDATION_FAILED;
+ break;
+ case SINGLE_RESPONSE_THIS_UPDATE:
+ response->thisUpdate = asn1_to_time(&object, ASN1_GENERALIZEDTIME);
+ break;
+ case SINGLE_RESPONSE_NEXT_UPDATE:
+ response->nextUpdate = asn1_to_time(&object, ASN1_GENERALIZEDTIME);
+ if (response->nextUpdate > this->usableUntil)
+ {
+ this->usableUntil = response->nextUpdate;
+ }
+ break;
+ }
+ }
+ success = parser->success(parser);
+ parser->destroy(parser);
+ if (success)
+ {
+ if (this->usableUntil == UNDEFINED_TIME)
+ {
+ this->usableUntil = this->producedAt + OCSP_DEFAULT_LIFETIME;
+ }
+ this->responses->insert_last(this->responses, response);
+ }
+ return success;
+}
+
+/**
+ * ASN.1 definition of responses
+ */
+static const asn1Object_t responsesObjects[] = {
+ { 0, "responses", ASN1_SEQUENCE, ASN1_LOOP }, /* 0 */
+ { 1, "singleResponse", ASN1_EOC, ASN1_RAW }, /* 1 */
+ { 0, "end loop", ASN1_EOC, ASN1_END }, /* 2 */
+ { 0, "exit", ASN1_EOC, ASN1_EXIT }
+};
+#define RESPONSES_SINGLE_RESPONSE 1
+
+/**
+ * Parse all responses
+ */
+static bool parse_responses(private_x509_ocsp_response_t *this,
+ chunk_t blob, int level0)
+{
+ asn1_parser_t *parser;
+ chunk_t object;
+ int objectID;
+ bool success = FALSE;
+
+ parser = asn1_parser_create(responsesObjects, blob);
+ parser->set_top_level(parser, level0);
+
+ while (parser->iterate(parser, &objectID, &object))
+ {
+ switch (objectID)
+ {
+ case RESPONSES_SINGLE_RESPONSE:
+ if (!parse_singleResponse(this, object,
+ parser->get_level(parser)+1))
+ {
+ goto end;
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ success = parser->success(parser);
+
+end:
+ parser->destroy(parser);
+ return success;
+}
+
+/**
+ * ASN.1 definition of basicResponse
+ */
+static const asn1Object_t basicResponseObjects[] = {
+ { 0, "BasicOCSPResponse", ASN1_SEQUENCE, ASN1_NONE }, /* 0 */
+ { 1, "tbsResponseData", ASN1_SEQUENCE, ASN1_OBJ }, /* 1 */
+ { 2, "versionContext", ASN1_CONTEXT_C_0, ASN1_NONE |
+ ASN1_DEF }, /* 2 */
+ { 3, "version", ASN1_INTEGER, ASN1_BODY }, /* 3 */
+ { 2, "responderIdContext", ASN1_CONTEXT_C_1, ASN1_OPT }, /* 4 */
+ { 3, "responderIdByName", ASN1_SEQUENCE, ASN1_OBJ }, /* 5 */
+ { 2, "end choice", ASN1_EOC, ASN1_END }, /* 6 */
+ { 2, "responderIdContext", ASN1_CONTEXT_C_2, ASN1_OPT }, /* 7 */
+ { 3, "responderIdByKey", ASN1_OCTET_STRING, ASN1_BODY }, /* 8 */
+ { 2, "end choice", ASN1_EOC, ASN1_END }, /* 9 */
+ { 2, "producedAt", ASN1_GENERALIZEDTIME, ASN1_BODY }, /* 10 */
+ { 2, "responses", ASN1_SEQUENCE, ASN1_OBJ }, /* 11 */
+ { 2, "responseExtensionsContext", ASN1_CONTEXT_C_1, ASN1_OPT }, /* 12 */
+ { 3, "responseExtensions", ASN1_SEQUENCE, ASN1_LOOP }, /* 13 */
+ { 4, "extension", ASN1_SEQUENCE, ASN1_NONE }, /* 14 */
+ { 5, "extnID", ASN1_OID, ASN1_BODY }, /* 15 */
+ { 5, "critical", ASN1_BOOLEAN, ASN1_BODY |
+ ASN1_DEF }, /* 16 */
+ { 5, "extnValue", ASN1_OCTET_STRING, ASN1_BODY }, /* 17 */
+ { 4, "end loop", ASN1_EOC, ASN1_END }, /* 18 */
+ { 2, "end opt", ASN1_EOC, ASN1_END }, /* 19 */
+ { 1, "signatureAlgorithm", ASN1_EOC, ASN1_RAW }, /* 20 */
+ { 1, "signature", ASN1_BIT_STRING, ASN1_BODY }, /* 21 */
+ { 1, "certsContext", ASN1_CONTEXT_C_0, ASN1_OPT }, /* 22 */
+ { 2, "certs", ASN1_SEQUENCE, ASN1_LOOP }, /* 23 */
+ { 3, "certificate", ASN1_SEQUENCE, ASN1_RAW }, /* 24 */
+ { 2, "end loop", ASN1_EOC, ASN1_END }, /* 25 */
+ { 1, "end opt", ASN1_EOC, ASN1_END }, /* 26 */
+ { 0, "exit", ASN1_EOC, ASN1_EXIT }
+};
+#define BASIC_RESPONSE_TBS_DATA 1
+#define BASIC_RESPONSE_VERSION 3
+#define BASIC_RESPONSE_ID_BY_NAME 5
+#define BASIC_RESPONSE_ID_BY_KEY 8
+#define BASIC_RESPONSE_PRODUCED_AT 10
+#define BASIC_RESPONSE_RESPONSES 11
+#define BASIC_RESPONSE_EXT_ID 15
+#define BASIC_RESPONSE_CRITICAL 16
+#define BASIC_RESPONSE_EXT_VALUE 17
+#define BASIC_RESPONSE_ALGORITHM 20
+#define BASIC_RESPONSE_SIGNATURE 21
+#define BASIC_RESPONSE_CERTIFICATE 24
+
+/**
+ * Parse a basicOCSPResponse
+ */
+static bool parse_basicOCSPResponse(private_x509_ocsp_response_t *this,
+ chunk_t blob, int level0)
+{
+ asn1_parser_t *parser;
+ chunk_t object;
+ chunk_t responses = chunk_empty;
+ int objectID;
+ int extn_oid = OID_UNKNOWN;
+ u_int responses_level = level0;
+ certificate_t *cert;
+ bool success = FALSE;
+ bool critical;
+
+ parser = asn1_parser_create(basicResponseObjects, blob);
+ parser->set_top_level(parser, level0);
+
+ while (parser->iterate(parser, &objectID, &object))
+ {
+ switch (objectID)
+ {
+ case BASIC_RESPONSE_TBS_DATA:
+ this->tbsResponseData = object;
+ break;
+ case BASIC_RESPONSE_VERSION:
+ {
+ u_int version = (object.len)? (1 + (u_int)*object.ptr) : 1;
+
+ if (version != OCSP_BASIC_RESPONSE_VERSION)
+ {
+ DBG1(" ocsp ResponseData version %d not supported", version);
+ goto end;
+ }
+ break;
+ }
+ case BASIC_RESPONSE_ID_BY_NAME:
+ this->responderId = identification_create_from_encoding(
+ ID_DER_ASN1_DN, object);
+ DBG2(" '%D'", this->responderId);
+ break;
+ case BASIC_RESPONSE_ID_BY_KEY:
+ this->responderId = identification_create_from_encoding(
+ ID_PUBKEY_INFO_SHA1, object);
+ DBG2(" '%D'", this->responderId);
+ break;
+ case BASIC_RESPONSE_PRODUCED_AT:
+ this->producedAt = asn1_to_time(&object, ASN1_GENERALIZEDTIME);
+ break;
+ case BASIC_RESPONSE_RESPONSES:
+ responses = object;
+ responses_level = parser->get_level(parser)+1;
+ break;
+ case BASIC_RESPONSE_EXT_ID:
+ extn_oid = asn1_known_oid(object);
+ break;
+ case BASIC_RESPONSE_CRITICAL:
+ critical = object.len && *object.ptr;
+ DBG2(" %s", critical ? "TRUE" : "FALSE");
+ break;
+ case BASIC_RESPONSE_EXT_VALUE:
+ if (extn_oid == OID_NONCE)
+ {
+ this->nonce = object;
+ }
+ break;
+ case BASIC_RESPONSE_ALGORITHM:
+ this->signatureAlgorithm = asn1_parse_algorithmIdentifier(object,
+ parser->get_level(parser)+1, NULL);
+ break;
+ case BASIC_RESPONSE_SIGNATURE:
+ this->signature = object;
+ break;
+ case BASIC_RESPONSE_CERTIFICATE:
+ {
+ cert = lib->creds->create(lib->creds, CRED_CERTIFICATE,CERT_X509,
+ BUILD_BLOB_ASN1_DER,
+ chunk_clone(object),
+ BUILD_END);
+ if (cert)
+ {
+ this->certs->insert_last(this->certs, cert);
+ }
+ break;
+ }
+ }
+ }
+ success = parser->success(parser);
+
+end:
+ parser->destroy(parser);
+ if (success)
+ {
+ if (!this->responderId)
+ {
+ this->responderId = identification_create_from_encoding(ID_ANY,
+ chunk_empty);
+ }
+ success = parse_responses(this, responses, responses_level);
+ }
+ return success;
+}
+
+/**
+ * ASN.1 definition of ocspResponse
+ */
+static const asn1Object_t ocspResponseObjects[] = {
+ { 0, "OCSPResponse", ASN1_SEQUENCE, ASN1_NONE }, /* 0 */
+ { 1, "responseStatus", ASN1_ENUMERATED, ASN1_BODY }, /* 1 */
+ { 1, "responseBytesContext", ASN1_CONTEXT_C_0, ASN1_OPT }, /* 2 */
+ { 2, "responseBytes", ASN1_SEQUENCE, ASN1_NONE }, /* 3 */
+ { 3, "responseType", ASN1_OID, ASN1_BODY }, /* 4 */
+ { 3, "response", ASN1_OCTET_STRING, ASN1_BODY }, /* 5 */
+ { 1, "end opt", ASN1_EOC, ASN1_END }, /* 6 */
+ { 0, "exit", ASN1_EOC, ASN1_EXIT }
+};
+#define OCSP_RESPONSE_STATUS 1
+#define OCSP_RESPONSE_TYPE 4
+#define OCSP_RESPONSE 5
+
+/**
+ * Parse OCSPResponse object
+ */
+static bool parse_OCSPResponse(private_x509_ocsp_response_t *this)
+{
+ asn1_parser_t *parser;
+ chunk_t object;
+ int objectID;
+ int responseType = OID_UNKNOWN;
+ bool success = FALSE;
+ ocsp_status_t status;
+
+ parser = asn1_parser_create(ocspResponseObjects, this->encoding);
+
+ while (parser->iterate(parser, &objectID, &object))
+ {
+ switch (objectID)
+ {
+ case OCSP_RESPONSE_STATUS:
+ status = (ocsp_status_t)*object.ptr;
+ switch (status)
+ {
+ case OCSP_SUCCESSFUL:
+ break;
+ default:
+ DBG1(" ocsp response status: %N",
+ ocsp_status_names, status);
+ goto end;
+ }
+ break;
+ case OCSP_RESPONSE_TYPE:
+ responseType = asn1_known_oid(object);
+ break;
+ case OCSP_RESPONSE:
+ switch (responseType)
+ {
+ case OID_BASIC:
+ success = parse_basicOCSPResponse(this, object,
+ parser->get_level(parser)+1);
+ break;
+ default:
+ DBG1(" ocsp response type %#B not supported", &object);
+ goto end;
+ }
+ break;
+ }
+ }
+ success &= parser->success(parser);
+
+end:
+ parser->destroy(parser);
+ return success;
+}
+
+/**
+ * Implementation of certificate_t.get_type
+ */
+static certificate_type_t get_type(private_x509_ocsp_response_t *this)
+{
+ return CERT_X509_OCSP_RESPONSE;
+}
+
+/**
+ * Implementation of certificate_t.get_issuer
+ */
+static identification_t* get_issuer(private_x509_ocsp_response_t *this)
+{
+ return this->responderId;
+}
+
+/**
+ * Implementation of certificate_t.has_subject.
+ */
+static id_match_t has_issuer(private_x509_ocsp_response_t *this,
+ identification_t *issuer)
+{
+ return this->responderId->matches(this->responderId, issuer);
+}
+
+/**
+ * Implementation of certificate_t.issued_by
+ */
+static bool issued_by(private_x509_ocsp_response_t *this, certificate_t *issuer)
+{
+ public_key_t *key;
+ signature_scheme_t scheme;
+ bool valid;
+ x509_t *x509 = (x509_t*)issuer;
+
+ if (issuer->get_type(issuer) != CERT_X509)
+ {
+ return FALSE;
+ }
+ if (this->responderId->get_type(this->responderId) == ID_DER_ASN1_DN)
+ {
+ if (!this->responderId->equals(this->responderId,
+ issuer->get_subject(issuer)))
+ {
+ return FALSE;
+ }
+ }
+ else
+ {
+ bool equal;
+ public_key_t *public = issuer->get_public_key(issuer);
+
+ if (public == NULL)
+ {
+ return FALSE;
+ }
+ equal = this->responderId->equals(this->responderId,
+ public->get_id(public, ID_PUBKEY_SHA1));
+ public->destroy(public);
+ if (!equal)
+ {
+ return FALSE;
+ }
+ }
+ if (!(x509->get_flags(x509) & X509_OCSP_SIGNER) &&
+ !(x509->get_flags(x509) & X509_CA))
+ {
+ return FALSE;
+ }
+ /* TODO: generic OID to scheme mapper? */
+ switch (this->signatureAlgorithm)
+ {
+ case OID_MD5_WITH_RSA:
+ scheme = SIGN_RSA_EMSA_PKCS1_MD5;
+ break;
+ case OID_SHA1_WITH_RSA:
+ scheme = SIGN_RSA_EMSA_PKCS1_SHA1;
+ break;
+ case OID_SHA256_WITH_RSA:
+ scheme = SIGN_RSA_EMSA_PKCS1_SHA256;
+ break;
+ case OID_SHA384_WITH_RSA:
+ scheme = SIGN_RSA_EMSA_PKCS1_SHA384;
+ break;
+ case OID_SHA512_WITH_RSA:
+ scheme = SIGN_RSA_EMSA_PKCS1_SHA512;
+ break;
+ case OID_ECDSA_WITH_SHA1:
+ scheme = SIGN_ECDSA_WITH_SHA1;
+ break;
+ default:
+ return FALSE;
+ }
+ key = issuer->get_public_key(issuer);
+ if (key == NULL)
+ {
+ return FALSE;
+ }
+ valid = key->verify(key, scheme, this->tbsResponseData, this->signature);
+ key->destroy(key);
+ return valid;
+}
+
+/**
+ * Implementation of certificate_t.get_public_key
+ */
+static public_key_t* get_public_key(private_x509_ocsp_response_t *this)
+{
+ return NULL;
+}
+
+/**
+ * Implementation of certificate_t.get_validity.
+ */
+static bool get_validity(private_x509_ocsp_response_t *this, time_t *when,
+ time_t *not_before, time_t *not_after)
+{
+ time_t t;
+
+ if (when == NULL)
+ {
+ t = time(NULL);
+ }
+ else
+ {
+ t = *when;
+ }
+ if (not_before)
+ {
+ *not_before = this->producedAt;
+ }
+ if (not_after)
+ {
+ *not_after = this->usableUntil;
+ }
+ return (t < this->usableUntil);
+}
+
+/**
+ * Implementation of certificate_t.is_newer.
+ */
+static bool is_newer(certificate_t *this, certificate_t *that)
+{
+ time_t this_update, that_update, now = time(NULL);
+ bool new;
+
+ this->get_validity(this, &now, &this_update, NULL);
+ that->get_validity(that, &now, &that_update, NULL);
+ new = this_update > that_update;
+ DBG1(" ocsp response from %#T is %s - existing ocsp response from %#T %s",
+ &this_update, FALSE, new ? "newer":"not newer",
+ &that_update, FALSE, new ? "replaced":"retained");
+ return new;
+}
+
+/**
+ * Implementation of certificate_t.get_encoding.
+ */
+static chunk_t get_encoding(private_x509_ocsp_response_t *this)
+{
+ return chunk_clone(this->encoding);
+}
+
+/**
+ * Implementation of certificate_t.equals.
+ */
+static bool equals(private_x509_ocsp_response_t *this, certificate_t *other)
+{
+ chunk_t encoding;
+ bool equal;
+
+ if (this == (private_x509_ocsp_response_t*)other)
+ {
+ return TRUE;
+ }
+ if (other->get_type(other) != CERT_X509_OCSP_RESPONSE)
+ {
+ return FALSE;
+ }
+ if (other->equals == (void*)equals)
+ { /* skip allocation if we have the same implementation */
+ return chunk_equals(this->encoding, ((private_x509_ocsp_response_t*)other)->encoding);
+ }
+ encoding = other->get_encoding(other);
+ equal = chunk_equals(this->encoding, encoding);
+ free(encoding.ptr);
+ return equal;
+}
+
+/**
+ * Implementation of certificate_t.get_ref
+ */
+static private_x509_ocsp_response_t* get_ref(private_x509_ocsp_response_t *this)
+{
+ ref_get(&this->ref);
+ return this;
+}
+
+/**
+ * Implements ocsp_t.destroy.
+ */
+static void destroy(private_x509_ocsp_response_t *this)
+{
+ if (ref_put(&this->ref))
+ {
+ this->certs->destroy_offset(this->certs, offsetof(certificate_t, destroy));
+ this->responses->destroy_function(this->responses, free);
+ DESTROY_IF(this->responderId);
+ free(this->encoding.ptr);
+ free(this);
+ }
+}
+
+/**
+ * load an OCSP response
+ */
+static x509_ocsp_response_t *load(chunk_t data)
+{
+ private_x509_ocsp_response_t *this;
+
+ this = malloc_thing(private_x509_ocsp_response_t);
+
+ this->public.interface.certificate.get_type = (certificate_type_t (*)(certificate_t *this))get_type;
+ this->public.interface.certificate.get_subject = (identification_t* (*)(certificate_t *this))get_issuer;
+ this->public.interface.certificate.get_issuer = (identification_t* (*)(certificate_t *this))get_issuer;
+ this->public.interface.certificate.has_subject = (id_match_t(*)(certificate_t*, identification_t *subject))has_issuer;
+ this->public.interface.certificate.has_issuer = (id_match_t(*)(certificate_t*, identification_t *issuer))has_issuer;
+ this->public.interface.certificate.issued_by = (bool (*)(certificate_t *this, certificate_t *issuer))issued_by;
+ this->public.interface.certificate.get_public_key = (public_key_t* (*)(certificate_t *this))get_public_key;
+ this->public.interface.certificate.get_validity = (bool(*)(certificate_t*, time_t *when, time_t *, time_t*))get_validity;
+ this->public.interface.certificate.is_newer = (bool (*)(certificate_t*,certificate_t*))is_newer;
+ this->public.interface.certificate.get_encoding = (chunk_t(*)(certificate_t*))get_encoding;
+ this->public.interface.certificate.equals = (bool(*)(certificate_t*, certificate_t *other))equals;
+ this->public.interface.certificate.get_ref = (certificate_t* (*)(certificate_t *this))get_ref;
+ this->public.interface.certificate.destroy = (void (*)(certificate_t *this))destroy;
+ this->public.interface.get_status = (cert_validation_t(*)(ocsp_response_t*, x509_t *subject, x509_t *issuer, time_t *revocation_time,crl_reason_t *revocation_reason,time_t *this_update, time_t *next_update))get_status;
+ this->public.interface.create_cert_enumerator = (enumerator_t*(*)(ocsp_response_t*))create_cert_enumerator;
+
+ this->ref = 1;
+ this->encoding = data;
+ this->tbsResponseData = chunk_empty;
+ this->responderId = NULL;
+ this->producedAt = UNDEFINED_TIME;
+ this->usableUntil = UNDEFINED_TIME;
+ this->responses = linked_list_create();
+ this->nonce = chunk_empty;
+ this->signatureAlgorithm = OID_UNKNOWN;
+ this->signature = chunk_empty;
+ this->certs = linked_list_create();
+
+ if (!parse_OCSPResponse(this))
+ {
+ destroy(this);
+ return NULL;
+ }
+ return &this->public;
+}
+
+
+typedef struct private_builder_t private_builder_t;
+/**
+ * Builder implementation for certificate loading
+ */
+struct private_builder_t {
+ /** implements the builder interface */
+ builder_t public;
+ /** loaded response */
+ x509_ocsp_response_t *res;
+};
+
+/**
+ * Implementation of builder_t.build
+ */
+static x509_ocsp_response_t *build(private_builder_t *this)
+{
+ x509_ocsp_response_t *res = this->res;
+
+ free(this);
+ return res;
+}
+
+/**
+ * Implementation of builder_t.add
+ */
+static void add(private_builder_t *this, builder_part_t part, ...)
+{
+ va_list args;
+
+ if (this->res)
+ {
+ DBG1("ignoring surplus build part %N", builder_part_names, part);
+ return;
+ }
+
+ switch (part)
+ {
+ case BUILD_BLOB_ASN1_DER:
+ {
+ va_start(args, part);
+ this->res = load(va_arg(args, chunk_t));
+ va_end(args);
+ break;
+ }
+ default:
+ DBG1("ignoring unsupported build part %N", builder_part_names, part);
+ break;
+ }
+}
+
+/**
+ * Builder construction function
+ */
+builder_t *x509_ocsp_response_builder(certificate_type_t type)
+{
+ private_builder_t *this;
+
+ if (type != CERT_X509_OCSP_RESPONSE)
+ {
+ return NULL;
+ }
+
+ this = malloc_thing(private_builder_t);
+
+ this->res = NULL;
+ this->public.add = (void(*)(builder_t *this, builder_part_t part, ...))add;
+ this->public.build = (void*(*)(builder_t *this))build;
+
+ return &this->public;
+}
+
diff --git a/src/libstrongswan/plugins/x509/x509_ocsp_response.h b/src/libstrongswan/plugins/x509/x509_ocsp_response.h
new file mode 100644
index 000000000..8b4c8328d
--- /dev/null
+++ b/src/libstrongswan/plugins/x509/x509_ocsp_response.h
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2008 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.
+ */
+
+/**
+ * @defgroup x509_ocsp_response x509_ocsp_response
+ * @{ @ingroup x509_p
+ */
+
+#ifndef X509_OCSP_RESPONSE_H_
+#define X509_OCSP_RESPONSE_H_
+
+#include <credentials/certificates/ocsp_response.h>
+
+typedef struct x509_ocsp_response_t x509_ocsp_response_t;
+
+/**
+ * Implementation of ocsp_response_t using own ASN1 parser.
+ */
+struct x509_ocsp_response_t {
+
+ /**
+ * Implements the ocsp_response_t interface
+ */
+ ocsp_response_t interface;
+};
+
+/**
+ * Create the building facility for OCSP responses.
+ *
+ * @param type certificate type, CERT_X509_OCSP_RESPONSE only
+ * @return builder instance to build OCSP responses
+ */
+builder_t *x509_ocsp_response_builder(certificate_type_t type);
+
+#endif /* X509_OCSP_RESPONSE_H_ @}*/
diff --git a/src/libstrongswan/plugins/x509/x509_plugin.c b/src/libstrongswan/plugins/x509/x509_plugin.c
new file mode 100644
index 000000000..42768487d
--- /dev/null
+++ b/src/libstrongswan/plugins/x509/x509_plugin.c
@@ -0,0 +1,80 @@
+/*
+ * Copyright (C) 2008 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.
+ *
+ * $Id: x509_plugin.c 3640 2008-03-21 10:52:11Z andreas $
+ */
+
+#include "x509_plugin.h"
+
+#include <library.h>
+#include "x509_cert.h"
+#include "x509_ac.h"
+#include "x509_crl.h"
+#include "x509_ocsp_request.h"
+#include "x509_ocsp_response.h"
+
+typedef struct private_x509_plugin_t private_x509_plugin_t;
+
+/**
+ * private data of x509_plugin
+ */
+struct private_x509_plugin_t {
+
+ /**
+ * public functions
+ */
+ x509_plugin_t public;
+};
+
+/**
+ * Implementation of x509_plugin_t.x509troy
+ */
+static void destroy(private_x509_plugin_t *this)
+{
+ lib->creds->remove_builder(lib->creds,
+ (builder_constructor_t)x509_cert_builder);
+ lib->creds->remove_builder(lib->creds,
+ (builder_constructor_t)x509_ac_builder);
+ lib->creds->remove_builder(lib->creds,
+ (builder_constructor_t)x509_crl_builder);
+ lib->creds->remove_builder(lib->creds,
+ (builder_constructor_t)x509_ocsp_request_builder);
+ lib->creds->remove_builder(lib->creds,
+ (builder_constructor_t)x509_ocsp_response_builder);
+ free(this);
+}
+
+/*
+ * see header file
+ */
+plugin_t *plugin_create()
+{
+ private_x509_plugin_t *this = malloc_thing(private_x509_plugin_t);
+
+ this->public.plugin.destroy = (void(*)(plugin_t*))destroy;
+
+ lib->creds->add_builder(lib->creds, CRED_CERTIFICATE, CERT_X509,
+ (builder_constructor_t)x509_cert_builder);
+ lib->creds->add_builder(lib->creds, CRED_CERTIFICATE, CERT_X509_AC,
+ (builder_constructor_t)x509_ac_builder);
+ lib->creds->add_builder(lib->creds, CRED_CERTIFICATE, CERT_X509_CRL,
+ (builder_constructor_t)x509_crl_builder);
+ lib->creds->add_builder(lib->creds, CRED_CERTIFICATE, CERT_X509_OCSP_REQUEST,
+ (builder_constructor_t)x509_ocsp_request_builder);
+ lib->creds->add_builder(lib->creds, CRED_CERTIFICATE, CERT_X509_OCSP_RESPONSE,
+ (builder_constructor_t)x509_ocsp_response_builder);
+
+ return &this->public.plugin;
+}
+
diff --git a/src/libstrongswan/plugins/x509/x509_plugin.h b/src/libstrongswan/plugins/x509/x509_plugin.h
new file mode 100644
index 000000000..9743a2367
--- /dev/null
+++ b/src/libstrongswan/plugins/x509/x509_plugin.h
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2008 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.
+ */
+
+/**
+ * @defgroup x509_p x509
+ * @ingroup plugins
+ *
+ * @defgroup x509_plugin x509_plugin
+ * @{ @ingroup x509_p
+ */
+
+#ifndef X509_PLUGIN_H_
+#define X509_PLUGIN_H_
+
+#include <plugins/plugin.h>
+
+typedef struct x509_plugin_t x509_plugin_t;
+
+/**
+ * Plugin implementing x509, CRL and OCSP certificates.
+ */
+struct x509_plugin_t {
+
+ /**
+ * implements plugin interface
+ */
+ plugin_t plugin;
+};
+
+/**
+ * Create a x509_plugin instance.
+ */
+plugin_t *plugin_create();
+
+#endif /* X509_PLUGIN_H_ @}*/
diff --git a/src/libstrongswan/plugins/xcbc/Makefile.am b/src/libstrongswan/plugins/xcbc/Makefile.am
new file mode 100644
index 000000000..1b10d21f8
--- /dev/null
+++ b/src/libstrongswan/plugins/xcbc/Makefile.am
@@ -0,0 +1,11 @@
+
+INCLUDES = -I$(top_srcdir)/src/libstrongswan
+
+AM_CFLAGS = -rdynamic
+
+plugin_LTLIBRARIES = libstrongswan-xcbc.la
+
+libstrongswan_xcbc_la_SOURCES = xcbc_plugin.h xcbc_plugin.c xcbc.h xcbc.c \
+ xcbc_prf.h xcbc_prf.c xcbc_signer.h xcbc_signer.c
+libstrongswan_xcbc_la_LDFLAGS = -module
+
diff --git a/src/libstrongswan/plugins/xcbc/Makefile.in b/src/libstrongswan/plugins/xcbc/Makefile.in
new file mode 100644
index 000000000..3fdf46955
--- /dev/null
+++ b/src/libstrongswan/plugins/xcbc/Makefile.in
@@ -0,0 +1,499 @@
+# Makefile.in generated by automake 1.10.1 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+VPATH = @srcdir@
+pkgdatadir = $(datadir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+subdir = src/libstrongswan/plugins/xcbc
+DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/configure.in
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+mkinstalldirs = $(install_sh) -d
+CONFIG_CLEAN_FILES =
+am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
+am__vpath_adj = case $$p in \
+ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
+ *) f=$$p;; \
+ esac;
+am__strip_dir = `echo $$p | sed -e 's|^.*/||'`;
+am__installdirs = "$(DESTDIR)$(plugindir)"
+pluginLTLIBRARIES_INSTALL = $(INSTALL)
+LTLIBRARIES = $(plugin_LTLIBRARIES)
+libstrongswan_xcbc_la_LIBADD =
+am_libstrongswan_xcbc_la_OBJECTS = xcbc_plugin.lo xcbc.lo xcbc_prf.lo \
+ xcbc_signer.lo
+libstrongswan_xcbc_la_OBJECTS = $(am_libstrongswan_xcbc_la_OBJECTS)
+libstrongswan_xcbc_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(libstrongswan_xcbc_la_LDFLAGS) $(LDFLAGS) -o $@
+DEFAULT_INCLUDES = -I.@am__isrc@
+depcomp = $(SHELL) $(top_srcdir)/depcomp
+am__depfiles_maybe = depfiles
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+ --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
+ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+CCLD = $(CC)
+LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+ --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \
+ $(LDFLAGS) -o $@
+SOURCES = $(libstrongswan_xcbc_la_SOURCES)
+DIST_SOURCES = $(libstrongswan_xcbc_la_SOURCES)
+ETAGS = etags
+CTAGS = ctags
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+AMTAR = @AMTAR@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CXX = @CXX@
+CXXCPP = @CXXCPP@
+CXXDEPMODE = @CXXDEPMODE@
+CXXFLAGS = @CXXFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DSYMUTIL = @DSYMUTIL@
+ECHO = @ECHO@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+F77 = @F77@
+FFLAGS = @FFLAGS@
+GPERF = @GPERF@
+GREP = @GREP@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+IPSEC_ROUTING_TABLE = @IPSEC_ROUTING_TABLE@
+IPSEC_ROUTING_TABLE_PRIO = @IPSEC_ROUTING_TABLE_PRIO@
+LDFLAGS = @LDFLAGS@
+LEX = @LEX@
+LEXLIB = @LEXLIB@
+LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LINUX_HEADERS = @LINUX_HEADERS@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+MAKEINFO = @MAKEINFO@
+MKDIR_P = @MKDIR_P@
+NMEDIT = @NMEDIT@
+OBJEXT = @OBJEXT@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PERL = @PERL@
+PKG_CONFIG = @PKG_CONFIG@
+RANLIB = @RANLIB@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRIP = @STRIP@
+VERSION = @VERSION@
+YACC = @YACC@
+YFLAGS = @YFLAGS@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_CXX = @ac_ct_CXX@
+ac_ct_F77 = @ac_ct_F77@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+confdir = @confdir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+gtk_CFLAGS = @gtk_CFLAGS@
+gtk_LIBS = @gtk_LIBS@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+ipsecdir = @ipsecdir@
+ipsecgroup = @ipsecgroup@
+ipsecuser = @ipsecuser@
+libdir = @libdir@
+libexecdir = @libexecdir@
+libstrongswan_plugins = @libstrongswan_plugins@
+linuxdir = @linuxdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+piddir = @piddir@
+plugindir = @plugindir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+resolv_conf = @resolv_conf@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+simreader = @simreader@
+srcdir = @srcdir@
+strongswan_conf = @strongswan_conf@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+xml_CFLAGS = @xml_CFLAGS@
+xml_LIBS = @xml_LIBS@
+INCLUDES = -I$(top_srcdir)/src/libstrongswan
+AM_CFLAGS = -rdynamic
+plugin_LTLIBRARIES = libstrongswan-xcbc.la
+libstrongswan_xcbc_la_SOURCES = xcbc_plugin.h xcbc_plugin.c xcbc.h xcbc.c \
+ xcbc_prf.h xcbc_prf.c xcbc_signer.h xcbc_signer.c
+
+libstrongswan_xcbc_la_LDFLAGS = -module
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .c .lo .o .obj
+$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \
+ && exit 0; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/libstrongswan/plugins/xcbc/Makefile'; \
+ cd $(top_srcdir) && \
+ $(AUTOMAKE) --gnu src/libstrongswan/plugins/xcbc/Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+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) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(pluginLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) '$$p' '$(DESTDIR)$(plugindir)/$$f'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(pluginLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) "$$p" "$(DESTDIR)$(plugindir)/$$f"; \
+ else :; fi; \
+ done
+
+uninstall-pluginLTLIBRARIES:
+ @$(NORMAL_UNINSTALL)
+ @list='$(plugin_LTLIBRARIES)'; for p in $$list; do \
+ p=$(am__strip_dir) \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(plugindir)/$$p'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(plugindir)/$$p"; \
+ 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
+libstrongswan-xcbc.la: $(libstrongswan_xcbc_la_OBJECTS) $(libstrongswan_xcbc_la_DEPENDENCIES)
+ $(libstrongswan_xcbc_la_LINK) -rpath $(plugindir) $(libstrongswan_xcbc_la_OBJECTS) $(libstrongswan_xcbc_la_LIBADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xcbc.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xcbc_plugin.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xcbc_prf.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xcbc_signer.Plo@am__quote@
+
+.c.o:
+@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(COMPILE) -c $<
+
+.c.obj:
+@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'`
+
+.c.lo:
+@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $<
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+
+ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonemtpy = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ mkid -fID $$unique
+tags: TAGS
+
+TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ tags=; \
+ here=`pwd`; \
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \
+ test -n "$$unique" || unique=$$empty_fix; \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ $$tags $$unique; \
+ fi
+ctags: CTAGS
+CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ tags=; \
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ test -z "$(CTAGS_ARGS)$$tags$$unique" \
+ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+ $$tags $$unique
+
+GTAGS:
+ here=`$(am__cd) $(top_builddir) && pwd` \
+ && cd $(top_srcdir) \
+ && gtags -i $(GTAGS_ARGS) $$here
+
+distclean-tags:
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+distdir: $(DISTFILES)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ list='$(DISTFILES)'; \
+ dist_files=`for file in $$list; do echo $$file; done | \
+ sed -e "s|^$$srcdirstrip/||;t" \
+ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+ case $$dist_files in \
+ */*) $(MKDIR_P) `echo "$$dist_files" | \
+ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+ sort -u` ;; \
+ esac; \
+ for file in $$dist_files; do \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ if test -d $$d/$$file; then \
+ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
+ fi; \
+ cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
+ else \
+ test -f $(distdir)/$$file \
+ || cp -p $$d/$$file $(distdir)/$$file \
+ || exit 1; \
+ fi; \
+ done
+check-am: all-am
+check: check-am
+all-am: Makefile $(LTLIBRARIES)
+installdirs:
+ for dir in "$(DESTDIR)$(plugindir)"; do \
+ test -z "$$dir" || $(MKDIR_P) "$$dir"; \
+ done
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ `test -z '$(STRIP)' || \
+ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+clean: clean-am
+
+clean-am: clean-generic clean-libtool clean-pluginLTLIBRARIES \
+ mostlyclean-am
+
+distclean: distclean-am
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+ distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+info: info-am
+
+info-am:
+
+install-data-am: install-pluginLTLIBRARIES
+
+install-dvi: install-dvi-am
+
+install-exec-am:
+
+install-html: install-html-am
+
+install-info: install-info-am
+
+install-man:
+
+install-pdf: install-pdf-am
+
+install-ps: install-ps-am
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic \
+ mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am: uninstall-pluginLTLIBRARIES
+
+.MAKE: install-am install-strip
+
+.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \
+ clean-libtool clean-pluginLTLIBRARIES ctags distclean \
+ distclean-compile distclean-generic distclean-libtool \
+ distclean-tags distdir dvi dvi-am html html-am info info-am \
+ install install-am install-data install-data-am install-dvi \
+ install-dvi-am install-exec install-exec-am install-html \
+ install-html-am install-info install-info-am install-man \
+ install-pdf install-pdf-am install-pluginLTLIBRARIES \
+ install-ps install-ps-am install-strip installcheck \
+ installcheck-am installdirs maintainer-clean \
+ maintainer-clean-generic mostlyclean mostlyclean-compile \
+ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
+ tags uninstall uninstall-am uninstall-pluginLTLIBRARIES
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/src/libstrongswan/plugins/xcbc/xcbc.c b/src/libstrongswan/plugins/xcbc/xcbc.c
new file mode 100644
index 000000000..ab37eca40
--- /dev/null
+++ b/src/libstrongswan/plugins/xcbc/xcbc.c
@@ -0,0 +1,299 @@
+/*
+ * Copyright (C) 2008 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 xcbc 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 xcbc License
+ * for more details.
+ *
+ * $Id: xcbc.c 3589 2008-03-13 14:14:44Z martin $
+ */
+
+#include <string.h>
+
+#include "xcbc.h"
+
+#include <debug.h>
+
+typedef struct private_xcbc_t private_xcbc_t;
+
+/**
+ * Private data of a xcbc_t object.
+ *
+ * The variable names are the same as in the RFC.
+ */
+struct private_xcbc_t {
+ /**
+ * Public xcbc_t interface.
+ */
+ xcbc_t xcbc;
+
+ /**
+ * Block size, in bytes
+ */
+ u_int8_t b;
+
+ /**
+ * crypter using k1
+ */
+ crypter_t *k1;
+
+ /**
+ * k2
+ */
+ u_int8_t *k2;
+
+ /**
+ * k3
+ */
+ u_int8_t *k3;
+
+ /**
+ * E
+ */
+ u_int8_t *e;
+
+ /**
+ * remaining, unprocessed bytes in append mode
+ */
+ u_int8_t *remaining;
+
+ /**
+ * number of bytes in remaining
+ */
+ int remaining_bytes;
+
+ /**
+ * TRUE if we have zero bytes to xcbc in final()
+ */
+ bool zero;
+};
+
+/**
+ * xcbc supplied data, but do not run final operation
+ */
+static void update(private_xcbc_t *this, chunk_t data)
+{
+ chunk_t iv;
+
+ if (data.len)
+ {
+ this->zero = FALSE;
+ }
+
+ if (this->remaining_bytes + data.len <= this->b)
+ { /* no complete block, just copy into remaining */
+ memcpy(this->remaining + this->remaining_bytes, data.ptr, data.len);
+ this->remaining_bytes += data.len;
+ return;
+ }
+
+ iv = chunk_alloca(this->b);
+ memset(iv.ptr, 0, iv.len);
+
+ /* (3) For each block M[i], where i = 1 ... n-1:
+ * XOR M[i] with E[i-1], then encrypt the result with Key K1,
+ * yielding E[i].
+ */
+
+ /* append data to remaining bytes, process block M[1] */
+ memcpy(this->remaining + this->remaining_bytes, data.ptr,
+ this->b - this->remaining_bytes);
+ data = chunk_skip(data, this->b - this->remaining_bytes);
+ memxor(this->e, this->remaining, this->b);
+ this->k1->encrypt(this->k1, chunk_create(this->e, this->b), iv, NULL);
+
+ /* process blocks M[2] ... M[n-1] */
+ while (data.len > this->b)
+ {
+ memcpy(this->remaining, data.ptr, this->b);
+ data = chunk_skip(data, this->b);
+ memxor(this->e, this->remaining, this->b);
+ this->k1->encrypt(this->k1, chunk_create(this->e, this->b), iv, NULL);
+ }
+
+ /* store remaining bytes of block M[n] */
+ memcpy(this->remaining, data.ptr, data.len);
+ this->remaining_bytes = data.len;
+}
+
+/**
+ * run last round, data is in this->e
+ */
+static void final(private_xcbc_t *this, u_int8_t *out)
+{
+ chunk_t iv;
+
+ iv = chunk_alloca(this->b);
+ memset(iv.ptr, 0, iv.len);
+
+ /* (4) For block M[n]: */
+ if (this->remaining_bytes == this->b && !this->zero)
+ {
+ /* a) If the blocksize of M[n] is 128 bits:
+ * XOR M[n] with E[n-1] and Key K2, then encrypt the result with
+ * Key K1, yielding E[n].
+ */
+ memxor(this->e, this->remaining, this->b);
+ memxor(this->e, this->k2, this->b);
+ this->k1->encrypt(this->k1, chunk_create(this->e, this->b), iv, NULL);
+ }
+ else
+ {
+ /* b) If the blocksize of M[n] is less than 128 bits:
+ *
+ * i) Pad M[n] with a single "1" bit, followed by the number of
+ * "0" bits (possibly none) required to increase M[n]'s
+ * blocksize to 128 bits.
+ */
+ if (this->remaining_bytes < this->b)
+ {
+ this->remaining[this->remaining_bytes] = 0x80;
+ while (++this->remaining_bytes < this->b)
+ {
+ this->remaining[this->remaining_bytes] = 0x00;
+ }
+ }
+ /* ii) XOR M[n] with E[n-1] and Key K3, then encrypt the result
+ * with Key K1, yielding E[n].
+ */
+ memxor(this->e, this->remaining, this->b);
+ memxor(this->e, this->k3, this->b);
+ this->k1->encrypt(this->k1, chunk_create(this->e, this->b), iv, NULL);
+ }
+
+ memcpy(out, this->e, this->b);
+
+ /* (2) Define E[0] = 0x00000000000000000000000000000000 */
+ memset(this->e, 0, this->b);
+ this->remaining_bytes = 0;
+ this->zero = TRUE;
+}
+
+/**
+ * Implementation of xcbc_t.get_mac.
+ */
+static void get_mac(private_xcbc_t *this, chunk_t data, u_int8_t *out)
+{
+ /* update E, do not process last block */
+ update(this, data);
+
+ if (out)
+ { /* if not in append mode, process last block and output result */
+ final(this, out);
+ }
+}
+
+/**
+ * Implementation of xcbc_t.get_block_size.
+ */
+static size_t get_block_size(private_xcbc_t *this)
+{
+ return this->b;
+}
+
+/**
+ * Implementation of xcbc_t.set_key.
+ */
+static void set_key(private_xcbc_t *this, chunk_t key)
+{
+ chunk_t iv, k1, lengthened;
+
+ /* we support variable keys from RFC4434 */
+ if (key.len == this->b)
+ {
+ lengthened = key;
+ }
+ else if (key.len < this->b)
+ { /* pad short keys */
+ lengthened = chunk_alloca(this->b);
+ memset(lengthened.ptr, 0, lengthened.len);
+ memcpy(lengthened.ptr, key.ptr, key.len);
+ }
+ else
+ { /* shorten key using xcbc */
+ lengthened = chunk_alloca(this->b);
+ memset(lengthened.ptr, 0, lengthened.len);
+ set_key(this, lengthened);
+ get_mac(this, key, lengthened.ptr);
+ }
+
+ k1 = chunk_alloca(this->b);
+ iv = chunk_alloca(this->b);
+ memset(iv.ptr, 0, iv.len);
+
+ /*
+ * (1) Derive 3 128-bit keys (K1, K2 and K3) from the 128-bit secret
+ * key K, as follows:
+ * K1 = 0x01010101010101010101010101010101 encrypted with Key K
+ * K2 = 0x02020202020202020202020202020202 encrypted with Key K
+ * K3 = 0x03030303030303030303030303030303 encrypted with Key K
+ */
+ this->k1->set_key(this->k1, lengthened);
+ memset(this->k2, 0x02, this->b);
+ this->k1->encrypt(this->k1, chunk_create(this->k2, this->b), iv, NULL);
+ memset(this->k3, 0x03, this->b);
+ this->k1->encrypt(this->k1, chunk_create(this->k3, this->b), iv, NULL);
+ memset(k1.ptr, 0x01, this->b);
+ this->k1->encrypt(this->k1, k1, iv, NULL);
+ this->k1->set_key(this->k1, k1);
+}
+
+/**
+ * Implementation of xcbc_t.destroy.
+ */
+static void destroy(private_xcbc_t *this)
+{
+ this->k1->destroy(this->k1);
+ free(this->k2);
+ free(this->k3);
+ free(this->e);
+ free(this->remaining);
+ free(this);
+}
+
+/*
+ * Described in header
+ */
+xcbc_t *xcbc_create(encryption_algorithm_t algo, size_t key_size)
+{
+ private_xcbc_t *this;
+ crypter_t *crypter;
+
+ crypter = lib->crypto->create_crypter(lib->crypto, algo, key_size);
+ if (!crypter)
+ {
+ return NULL;
+ }
+ /* input and output of crypter must be equal for xcbc */
+ if (crypter->get_block_size(crypter) != key_size)
+ {
+ crypter->destroy(crypter);
+ return NULL;
+ }
+
+ this = malloc_thing(private_xcbc_t);
+ this->xcbc.get_mac = (void (*)(xcbc_t *,chunk_t,u_int8_t*))get_mac;
+ this->xcbc.get_block_size = (size_t (*)(xcbc_t *))get_block_size;
+ this->xcbc.set_key = (void (*)(xcbc_t *,chunk_t))set_key;
+ this->xcbc.destroy = (void (*)(xcbc_t *))destroy;
+
+ this->b = crypter->get_block_size(crypter);
+ this->k1 = crypter;
+ this->k2 = malloc(this->b);
+ this->k3 = malloc(this->b);
+ this->e = malloc(this->b);
+ memset(this->e, 0, this->b);
+ this->remaining = malloc(this->b);
+ this->remaining_bytes = 0;
+ this->zero = TRUE;
+
+ return &this->xcbc;
+}
+
diff --git a/src/libstrongswan/plugins/xcbc/xcbc.h b/src/libstrongswan/plugins/xcbc/xcbc.h
new file mode 100644
index 000000000..81812442e
--- /dev/null
+++ b/src/libstrongswan/plugins/xcbc/xcbc.h
@@ -0,0 +1,78 @@
+/*
+ * Copyright (C) 2008 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.
+ */
+
+/**
+ * @defgroup xcbc xcbc
+ * @{ @ingroup xcbc_p
+ */
+
+#ifndef XCBC_H_
+#define XCBC_H_
+
+typedef struct xcbc_t xcbc_t;
+
+#include <crypto/hashers/hasher.h>
+
+/**
+ * Message authentication using CBC crypter.
+ *
+ * This class implements the message authenticaion algorithm
+ * described in RFC3566.
+ */
+struct xcbc_t {
+
+ /**
+ * Generate message authentication code.
+ *
+ * If buffer is NULL, no result is given back. A next call will
+ * append the data to already supplied data. If buffer is not NULL,
+ * the mac of all apended data is calculated, returned and the
+ * state of the xcbc_t is reseted.
+ *
+ * @param data chunk of data to authenticate
+ * @param buffer pointer where the generated bytes will be written
+ */
+ void (*get_mac) (xcbc_t *this, chunk_t data, u_int8_t *buffer);
+
+ /**
+ * Get the block size of this xcbc_t object.
+ *
+ * @return block size in bytes
+ */
+ size_t (*get_block_size) (xcbc_t *this);
+
+ /**
+ * Set the key for this xcbc_t object.
+ *
+ * @param key key to set
+ */
+ void (*set_key) (xcbc_t *this, chunk_t key);
+
+ /**
+ * Destroys a xcbc_t object.
+ */
+ void (*destroy) (xcbc_t *this);
+};
+
+/**
+ * Creates a new xcbc_t object.
+ *
+ * @param algo underlying crypto algorithm
+ * @param key_size key size to use, if required for algorithm
+ * @return xcbc_t object, NULL if not supported
+ */
+xcbc_t *xcbc_create(encryption_algorithm_t algo, size_t key_size);
+
+#endif /*xcbc_H_ @}*/
diff --git a/src/libstrongswan/plugins/xcbc/xcbc_plugin.c b/src/libstrongswan/plugins/xcbc/xcbc_plugin.c
new file mode 100644
index 000000000..f1501476f
--- /dev/null
+++ b/src/libstrongswan/plugins/xcbc/xcbc_plugin.c
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2008 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.
+ *
+ * $Id$
+ */
+
+#include "xcbc_plugin.h"
+
+#include <library.h>
+#include "xcbc_signer.h"
+#include "xcbc_prf.h"
+
+typedef struct private_xcbc_plugin_t private_xcbc_plugin_t;
+
+/**
+ * private data of xcbc_plugin
+ */
+struct private_xcbc_plugin_t {
+
+ /**
+ * public functions
+ */
+ xcbc_plugin_t public;
+};
+
+/**
+ * Implementation of xcbc_plugin_t.xcbctroy
+ */
+static void destroy(private_xcbc_plugin_t *this)
+{
+ lib->crypto->remove_prf(lib->crypto,
+ (prf_constructor_t)xcbc_prf_create);
+ lib->crypto->remove_signer(lib->crypto,
+ (signer_constructor_t)xcbc_signer_create);
+ free(this);
+}
+
+/*
+ * see header file
+ */
+plugin_t *plugin_create()
+{
+ private_xcbc_plugin_t *this = malloc_thing(private_xcbc_plugin_t);
+
+ this->public.plugin.destroy = (void(*)(plugin_t*))destroy;
+
+ lib->crypto->add_prf(lib->crypto, PRF_AES128_XCBC,
+ (prf_constructor_t)xcbc_prf_create);
+ lib->crypto->add_signer(lib->crypto, AUTH_AES_XCBC_96,
+ (signer_constructor_t)xcbc_signer_create);
+
+ return &this->public.plugin;
+}
+
diff --git a/src/libstrongswan/plugins/xcbc/xcbc_plugin.h b/src/libstrongswan/plugins/xcbc/xcbc_plugin.h
new file mode 100644
index 000000000..728d84690
--- /dev/null
+++ b/src/libstrongswan/plugins/xcbc/xcbc_plugin.h
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2008 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.
+ */
+
+/**
+ * @defgroup xcbc_p xcbc
+ * @ingroup plugins
+ *
+ * @defgroup xcbc_plugin xcbc_plugin
+ * @{ @ingroup xcbc_p
+ */
+
+#ifndef XCBC_PLUGIN_H_
+#define XCBC_PLUGIN_H_
+
+#include <plugins/plugin.h>
+
+typedef struct xcbc_plugin_t xcbc_plugin_t;
+
+/**
+ * Plugin implementing xcbc algorithm to provide crypter based PRF and signers.
+ */
+struct xcbc_plugin_t {
+
+ /**
+ * implements plugin interface
+ */
+ plugin_t plugin;
+};
+
+/**
+ * Create a xcbc_plugin instance.
+ */
+plugin_t *plugin_create();
+
+#endif /* XCBC_PLUGIN_H_ @}*/
diff --git a/src/libstrongswan/plugins/xcbc/xcbc_prf.c b/src/libstrongswan/plugins/xcbc/xcbc_prf.c
new file mode 100644
index 000000000..03056594d
--- /dev/null
+++ b/src/libstrongswan/plugins/xcbc/xcbc_prf.c
@@ -0,0 +1,131 @@
+/*
+ * Copyright (C) 2008 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.
+ *
+ * $Id$
+ */
+
+#include "xcbc_prf.h"
+
+#include "xcbc.h"
+
+typedef struct private_xcbc_prf_t private_xcbc_prf_t;
+
+/**
+ * Private data of a xcbc_prf_t object.
+ */
+struct private_xcbc_prf_t {
+
+ /**
+ * Public xcbc_prf_t interface.
+ */
+ xcbc_prf_t public;
+
+ /**
+ * xcbc to use for generation.
+ */
+ xcbc_t *xcbc;
+};
+
+/**
+ * Implementation of prf_t.get_bytes.
+ */
+static void get_bytes(private_xcbc_prf_t *this, chunk_t seed, u_int8_t *buffer)
+{
+ this->xcbc->get_mac(this->xcbc, seed, buffer);
+}
+
+/**
+ * Implementation of prf_t.allocate_bytes.
+ */
+static void allocate_bytes(private_xcbc_prf_t *this, chunk_t seed, chunk_t *chunk)
+{
+ if (chunk)
+ {
+ *chunk = chunk_alloc(this->xcbc->get_block_size(this->xcbc));
+ get_bytes(this, seed, chunk->ptr);
+ }
+ else
+ {
+ get_bytes(this, seed, NULL);
+ }
+}
+
+/**
+ * Implementation of prf_t.get_block_size.
+ */
+static size_t get_block_size(private_xcbc_prf_t *this)
+{
+ return this->xcbc->get_block_size(this->xcbc);
+}
+
+/**
+ * Implementation of prf_t.get_block_size.
+ */
+static size_t get_key_size(private_xcbc_prf_t *this)
+{
+ /* in xcbc, block and key size are always equal */
+ return this->xcbc->get_block_size(this->xcbc);
+}
+
+/**
+ * Implementation of prf_t.set_key.
+ */
+static void set_key(private_xcbc_prf_t *this, chunk_t key)
+{
+ this->xcbc->set_key(this->xcbc, key);
+}
+
+/**
+ * Implementation of prf_t.destroy.
+ */
+static void destroy(private_xcbc_prf_t *this)
+{
+ this->xcbc->destroy(this->xcbc);
+ free(this);
+}
+
+/*
+ * Described in header.
+ */
+xcbc_prf_t *xcbc_prf_create(pseudo_random_function_t algo)
+{
+ private_xcbc_prf_t *this;
+ xcbc_t *xcbc;
+
+ switch (algo)
+ {
+ case PRF_AES128_XCBC:
+ xcbc = xcbc_create(ENCR_AES_CBC, 16);
+ break;
+ default:
+ return NULL;
+ }
+ if (!xcbc)
+ {
+ return NULL;
+ }
+
+ this = malloc_thing(private_xcbc_prf_t);
+ this->xcbc = xcbc;
+
+ this->public.prf_interface.get_bytes = (void (*) (prf_t *,chunk_t,u_int8_t*))get_bytes;
+ this->public.prf_interface.allocate_bytes = (void (*) (prf_t*,chunk_t,chunk_t*))allocate_bytes;
+ this->public.prf_interface.get_block_size = (size_t (*) (prf_t*))get_block_size;
+ this->public.prf_interface.get_key_size = (size_t (*) (prf_t*))get_key_size;
+ this->public.prf_interface.set_key = (void (*) (prf_t *,chunk_t))set_key;
+ this->public.prf_interface.destroy = (void (*) (prf_t *))destroy;
+
+ return &this->public;
+}
+
diff --git a/src/libstrongswan/plugins/xcbc/xcbc_prf.h b/src/libstrongswan/plugins/xcbc/xcbc_prf.h
new file mode 100644
index 000000000..e8692ae23
--- /dev/null
+++ b/src/libstrongswan/plugins/xcbc/xcbc_prf.h
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2008 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.
+ */
+
+/**
+ * @defgroup xcbc_prf xcbc_prf
+ * @{ @ingroup xcbc_p
+ */
+
+#ifndef PRF_XCBC_H_
+#define PRF_XCBC_H_
+
+typedef struct xcbc_prf_t xcbc_prf_t;
+
+#include <crypto/prfs/prf.h>
+
+/**
+ * Implementation of prf_t on CBC block cipher using XCBC, RFC3664/RFC4434.
+ *
+ * This simply wraps a xcbc_t in a prf_t. More a question of
+ * interface matching.
+ */
+struct xcbc_prf_t {
+
+ /**
+ * Generic prf_t interface for this xcbc_prf_t class.
+ */
+ prf_t prf_interface;
+};
+
+/**
+ * Creates a new xcbc_prf_t object.
+ *
+ * @param algo algorithm to implement
+ * @return xcbc_prf_t object, NULL if hash not supported
+ */
+xcbc_prf_t *xcbc_prf_create(pseudo_random_function_t algo);
+
+#endif /*PRF_XCBC_SHA1_H_ @}*/
diff --git a/src/libstrongswan/plugins/xcbc/xcbc_signer.c b/src/libstrongswan/plugins/xcbc/xcbc_signer.c
new file mode 100644
index 000000000..29eb2d25b
--- /dev/null
+++ b/src/libstrongswan/plugins/xcbc/xcbc_signer.c
@@ -0,0 +1,177 @@
+/*
+ * Copyright (C) 2008 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.
+ *
+ * $Id$
+ */
+
+#include <string.h>
+
+#include "xcbc_signer.h"
+#include "xcbc.h"
+
+typedef struct private_xcbc_signer_t private_xcbc_signer_t;
+
+/**
+ * Private data structure with signing context.
+ */
+struct private_xcbc_signer_t {
+
+ /**
+ * Public interface of xcbc_signer_t.
+ */
+ xcbc_signer_t public;
+
+ /**
+ * Assigned xcbc function.
+ */
+ xcbc_t *xcbc;
+
+ /**
+ * Block size (truncation of XCBC MAC)
+ */
+ size_t block_size;
+};
+
+/**
+ * Implementation of signer_t.get_signature.
+ */
+static void get_signature(private_xcbc_signer_t *this,
+ chunk_t data, u_int8_t *buffer)
+{
+ if (buffer == NULL)
+ { /* append mode */
+ this->xcbc->get_mac(this->xcbc, data, NULL);
+ }
+ else
+ {
+ u_int8_t mac[this->xcbc->get_block_size(this->xcbc)];
+
+ this->xcbc->get_mac(this->xcbc, data, mac);
+ memcpy(buffer, mac, this->block_size);
+ }
+}
+
+/**
+ * Implementation of signer_t.allocate_signature.
+ */
+static void allocate_signature (private_xcbc_signer_t *this,
+ chunk_t data, chunk_t *chunk)
+{
+ if (chunk == NULL)
+ { /* append mode */
+ this->xcbc->get_mac(this->xcbc, data, NULL);
+ }
+ else
+ {
+ u_int8_t mac[this->xcbc->get_block_size(this->xcbc)];
+
+ this->xcbc->get_mac(this->xcbc, data, mac);
+
+ chunk->ptr = malloc(this->block_size);
+ chunk->len = this->block_size;
+
+ memcpy(chunk->ptr, mac, this->block_size);
+ }
+}
+
+/**
+ * Implementation of signer_t.verify_signature.
+ */
+static bool verify_signature(private_xcbc_signer_t *this,
+ chunk_t data, chunk_t signature)
+{
+ u_int8_t mac[this->xcbc->get_block_size(this->xcbc)];
+
+ if (signature.len != this->block_size)
+ {
+ return FALSE;
+ }
+
+ this->xcbc->get_mac(this->xcbc, data, mac);
+ return memeq(signature.ptr, mac, this->block_size);
+}
+
+/**
+ * Implementation of signer_t.get_key_size.
+ */
+static size_t get_key_size(private_xcbc_signer_t *this)
+{
+ return this->xcbc->get_block_size(this->xcbc);
+}
+
+/**
+ * Implementation of signer_t.get_block_size.
+ */
+static size_t get_block_size(private_xcbc_signer_t *this)
+{
+ return this->block_size;
+}
+
+/**
+ * Implementation of signer_t.set_key.
+ */
+static void set_key(private_xcbc_signer_t *this, chunk_t key)
+{
+ this->xcbc->set_key(this->xcbc, key);
+}
+
+/**
+ * Implementation of signer_t.destroy.
+ */
+static status_t destroy(private_xcbc_signer_t *this)
+{
+ this->xcbc->destroy(this->xcbc);
+ free(this);
+ return SUCCESS;
+}
+
+/*
+ * Described in header
+ */
+xcbc_signer_t *xcbc_signer_create(integrity_algorithm_t algo)
+{
+ private_xcbc_signer_t *this;
+ size_t trunc;
+ xcbc_t *xcbc;
+
+ switch (algo)
+ {
+ case AUTH_AES_XCBC_96:
+ xcbc = xcbc_create(ENCR_AES_CBC, 16);
+ trunc = 12;
+ break;
+ default:
+ return NULL;
+ }
+ if (xcbc == NULL)
+ {
+ return NULL;
+ }
+
+ this = malloc_thing(private_xcbc_signer_t);
+ this->xcbc = xcbc;
+ this->block_size = min(trunc, xcbc->get_block_size(xcbc));
+
+ /* interface functions */
+ this->public.signer_interface.get_signature = (void (*) (signer_t*, chunk_t, u_int8_t*))get_signature;
+ this->public.signer_interface.allocate_signature = (void (*) (signer_t*, chunk_t, chunk_t*))allocate_signature;
+ this->public.signer_interface.verify_signature = (bool (*) (signer_t*, chunk_t, chunk_t))verify_signature;
+ this->public.signer_interface.get_key_size = (size_t (*) (signer_t*))get_key_size;
+ this->public.signer_interface.get_block_size = (size_t (*) (signer_t*))get_block_size;
+ this->public.signer_interface.set_key = (void (*) (signer_t*,chunk_t))set_key;
+ this->public.signer_interface.destroy = (void (*) (signer_t*))destroy;
+
+ return &this->public;
+}
+
diff --git a/src/libstrongswan/plugins/xcbc/xcbc_signer.h b/src/libstrongswan/plugins/xcbc/xcbc_signer.h
new file mode 100644
index 000000000..c7eff7e17
--- /dev/null
+++ b/src/libstrongswan/plugins/xcbc/xcbc_signer.h
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2008 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.
+ */
+
+/**
+ * @defgroup xcbc_signer xcbc_signer
+ * @{ @ingroup xcbc_p
+ */
+
+#ifndef xcbc_SIGNER_H_
+#define xcbc_SIGNER_H_
+
+typedef struct xcbc_signer_t xcbc_signer_t;
+
+#include <crypto/signers/signer.h>
+
+/**
+ * Implementation of signer_t based on CBC symmetric cypher. XCBC, RFC3566.
+ */
+struct xcbc_signer_t {
+
+ /**
+ * generic signer_t interface for this signer
+ */
+ signer_t signer_interface;
+};
+
+/**
+ * Creates a new xcbc_signer_t.
+ *
+ * @param algo algorithm to implement
+ * @return xcbc_signer_t, NULL if not supported
+ */
+xcbc_signer_t *xcbc_signer_create(integrity_algorithm_t algo);
+
+#endif /*xcbc_SIGNER_H_ @}*/