diff options
author | Rene Mayrhofer <rene@mayrhofer.eu.org> | 2008-07-10 12:47:56 +0000 |
---|---|---|
committer | Rene Mayrhofer <rene@mayrhofer.eu.org> | 2008-07-10 12:47:56 +0000 |
commit | eb841c5ef668a48782ef1154fda65cb6048f5885 (patch) | |
tree | 00dd0cb4313bf2291d94ed511fe51f0b4bc7ea7a /src/libstrongswan | |
parent | 738206039047924ae7e4762a53d121be1ca43000 (diff) | |
download | vyos-strongswan-eb841c5ef668a48782ef1154fda65cb6048f5885.tar.gz vyos-strongswan-eb841c5ef668a48782ef1154fda65cb6048f5885.zip |
- Updated to new upstream.
Diffstat (limited to 'src/libstrongswan')
269 files changed, 35308 insertions, 15017 deletions
diff --git a/src/libstrongswan/Makefile.am b/src/libstrongswan/Makefile.am index fc642c615..869f9677b 100644 --- a/src/libstrongswan/Makefile.am +++ b/src/libstrongswan/Makefile.am @@ -9,73 +9,63 @@ else endif libstrongswan_la_SOURCES += \ -credential_store.h \ library.c library.h \ chunk.c chunk.h \ debug.c debug.h \ enum.c enum.h \ +settings.h settings.c \ printf_hook.c printf_hook.h \ asn1/asn1.c asn1/asn1.h \ +asn1/asn1_parser.c asn1/asn1_parser.h \ asn1/oid.c asn1/oid.h \ asn1/pem.c asn1/pem.h \ -asn1/ttodata.c asn1/ttodata.h \ -crypto/ac.c crypto/ac.h \ -crypto/ca.c crypto/ca.h \ -crypto/certinfo.c crypto/certinfo.h \ -crypto/crl.c crypto/crl.h \ crypto/crypters/crypter.c crypto/crypters/crypter.h \ -crypto/crypters/aes_cbc_crypter.c crypto/crypters/aes_cbc_crypter.h \ -crypto/crypters/des_crypter.c crypto/crypters/des_crypter.h \ -crypto/diffie_hellman.c crypto/diffie_hellman.h \ crypto/hashers/hasher.h crypto/hashers/hasher.c \ -crypto/hashers/sha1_hasher.c crypto/hashers/sha1_hasher.h \ -crypto/hashers/sha2_hasher.c crypto/hashers/sha2_hasher.h \ -crypto/hashers/md5_hasher.c crypto/hashers/md5_hasher.h \ -crypto/hmac.c crypto/hmac.h \ -crypto/ietf_attr_list.c crypto/ietf_attr_list.h \ -crypto/ocsp.c crypto/ocsp.h \ -crypto/pkcs7.c crypto/pkcs7.h \ crypto/pkcs9.c crypto/pkcs9.h \ -crypto/prfs/fips_prf.c crypto/prfs/fips_prf.h \ -crypto/prfs/hmac_prf.c crypto/prfs/hmac_prf.h \ crypto/prfs/prf.c crypto/prfs/prf.h \ +crypto/rngs/rng.c crypto/rngs/rng.h \ crypto/prf_plus.h crypto/prf_plus.c \ -crypto/rsa/rsa_private_key.c crypto/rsa/rsa_private_key.h \ -crypto/rsa/rsa_public_key.h crypto/rsa/rsa_public_key.c \ -crypto/signers/hmac_signer.c crypto/signers/hmac_signer.h \ crypto/signers/signer.c crypto/signers/signer.h \ -crypto/x509.c crypto/x509.h \ -utils/fetcher.c utils/fetcher.h \ +crypto/diffie_hellman.c crypto/diffie_hellman.h \ +crypto/crypto_factory.c crypto/crypto_factory.h \ +credentials/credential_factory.c credentials/credential_factory.h \ +credentials/builder.c credentials/builder.h \ +credentials/keys/private_key.c credentials/keys/private_key.h \ +credentials/keys/public_key.c credentials/keys/public_key.h \ +credentials/keys/shared_key.c credentials/keys/shared_key.h \ +credentials/certificates/certificate.c credentials/certificates/certificate.h \ +credentials/certificates/x509.h credentials/certificates/x509.c \ +credentials/certificates/ac.h \ +credentials/certificates/crl.h credentials/certificates/crl.c \ +credentials/certificates/ocsp_request.h \ +credentials/certificates/ocsp_response.h credentials/certificates/ocsp_response.c \ +fetcher/fetcher.h fetcher/fetcher_manager.h fetcher/fetcher_manager.c \ +database/database.h database/database_factory.h database/database_factory.c \ +utils.h utils.c \ utils/host.c utils/host.h \ utils/identification.c utils/identification.h \ utils/iterator.h \ -utils/leak_detective.c utils/leak_detective.h \ utils/lexparser.c utils/lexparser.h \ utils/linked_list.c utils/linked_list.h \ utils/enumerator.c utils/enumerator.h \ utils/optionsfrom.c utils/optionsfrom.h \ -utils/randomizer.c utils/randomizer.h - -if USE_INTEGRITY_TEST - libstrongswan_la_SOURCES += \ - fips/fips_canister_end.c -endif +utils/mutex.c utils/mutex.h \ +plugins/plugin_loader.c plugins/plugin_loader.h plugins/plugin.h -libstrongswan_la_LIBADD = -lgmp -lpthread +libstrongswan_la_LIBADD = -lpthread -ldl INCLUDES = -I$(top_srcdir)/src/libstrongswan +AM_CFLAGS = -DIPSEC_DIR=\"${ipsecdir}\" \ + -DIPSEC_PLUGINDIR=\"${plugindir}\" if USE_LEAK_DETECTIVE - libstrongswan_la_LIBADD += -ldl - AM_CFLAGS = -DLEAK_DETECTIVE + AM_CFLAGS += -DLEAK_DETECTIVE + libstrongswan_la_SOURCES += utils/leak_detective.c utils/leak_detective.h endif -if USE_LIBCURL - libstrongswan_la_LIBADD += -lcurl -endif - -if USE_LIBLDAP - libstrongswan_la_LIBADD += -lldap -llber +if USE_INTEGRITY_TEST + libstrongswan_la_SOURCES += \ + fips/fips_canister_end.c endif EXTRA_DIST = asn1/oid.txt asn1/oid.pl @@ -88,15 +78,92 @@ asn1/oid.c : asn1/oid.txt asn1/oid.pl asn1/oid.h : asn1/oid.txt asn1/oid.pl cd asn1 && $(PERL) oid.pl + +# build plugins with their own Makefile +####################################### + +SUBDIRS = . + +if USE_AES + SUBDIRS += plugins/aes +endif + +if USE_DES + SUBDIRS += plugins/des +endif + +if USE_MD5 + SUBDIRS += plugins/md5 +endif + +if USE_SHA1 + SUBDIRS += plugins/sha1 +endif + +if USE_SHA2 + SUBDIRS += plugins/sha2 +endif + +if USE_FIPS_PRF + SUBDIRS += plugins/fips_prf +endif + +if USE_GMP + SUBDIRS += plugins/gmp +endif + +if USE_RANDOM + SUBDIRS += plugins/random +endif + +if USE_HMAC + SUBDIRS += plugins/hmac +endif + +if USE_XCBC + SUBDIRS += plugins/xcbc +endif + +if USE_X509 + SUBDIRS += plugins/x509 +endif + +if USE_PUBKEY + SUBDIRS += plugins/pubkey +endif + +if USE_CURL + SUBDIRS += plugins/curl +endif + +if USE_LDAP + SUBDIRS += plugins/ldap +endif + +if USE_MYSQL + SUBDIRS += plugins/mysql +endif + +if USE_SQLITE + SUBDIRS += plugins/sqlite +endif + +if USE_PADLOCK + SUBDIRS += plugins/padlock +endif + +if USE_OPENSSL + SUBDIRS += plugins/openssl +endif + if USE_INTEGRITY_TEST -# build fips_signer which in turn builds fips_signature.h -######################################################### -noinst_PROGRAMS = fips_signer -fips_signer_SOURCES = fips/fips_signer.c -fips_signer_LDADD = libstrongswan.la - -BUILT_SOURCES += fips_signature.h -CLEANFILES = fips_signature.h fips_signer + noinst_PROGRAMS = fips_signer + fips_signer_SOURCES = fips/fips_signer.c + fips_signer_LDADD = libstrongswan.la + + BUILT_SOURCES += fips_signature.h + CLEANFILES = fips_signature.h fips_signer + AM_CFLAGS += -DSTRONGSWAN_CONF=\"${strongswan_conf}\" fips_signature.h : fips_signer ./fips_signer diff --git a/src/libstrongswan/Makefile.in b/src/libstrongswan/Makefile.in index c8a471e00..fc6e40229 100644 --- a/src/libstrongswan/Makefile.in +++ b/src/libstrongswan/Makefile.in @@ -1,8 +1,8 @@ -# Makefile.in generated by automake 1.10 from Makefile.am. +# 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 Free Software Foundation, Inc. +# 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. @@ -33,11 +33,29 @@ PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ -@USE_LEAK_DETECTIVE_TRUE@am__append_1 = -ldl -@USE_LIBCURL_TRUE@am__append_2 = -lcurl -@USE_LIBLDAP_TRUE@am__append_3 = -lldap -llber +@USE_LEAK_DETECTIVE_TRUE@am__append_1 = -DLEAK_DETECTIVE +@USE_LEAK_DETECTIVE_TRUE@am__append_2 = utils/leak_detective.c utils/leak_detective.h +@USE_AES_TRUE@am__append_3 = plugins/aes +@USE_DES_TRUE@am__append_4 = plugins/des +@USE_MD5_TRUE@am__append_5 = plugins/md5 +@USE_SHA1_TRUE@am__append_6 = plugins/sha1 +@USE_SHA2_TRUE@am__append_7 = plugins/sha2 +@USE_FIPS_PRF_TRUE@am__append_8 = plugins/fips_prf +@USE_GMP_TRUE@am__append_9 = plugins/gmp +@USE_RANDOM_TRUE@am__append_10 = plugins/random +@USE_HMAC_TRUE@am__append_11 = plugins/hmac +@USE_XCBC_TRUE@am__append_12 = plugins/xcbc +@USE_X509_TRUE@am__append_13 = plugins/x509 +@USE_PUBKEY_TRUE@am__append_14 = plugins/pubkey +@USE_CURL_TRUE@am__append_15 = plugins/curl +@USE_LDAP_TRUE@am__append_16 = plugins/ldap +@USE_MYSQL_TRUE@am__append_17 = plugins/mysql +@USE_SQLITE_TRUE@am__append_18 = plugins/sqlite +@USE_PADLOCK_TRUE@am__append_19 = plugins/padlock +@USE_OPENSSL_TRUE@am__append_20 = plugins/openssl @USE_INTEGRITY_TEST_TRUE@noinst_PROGRAMS = fips_signer$(EXEEXT) -@USE_INTEGRITY_TEST_TRUE@am__append_4 = fips_signature.h +@USE_INTEGRITY_TEST_TRUE@am__append_21 = fips_signature.h +@USE_INTEGRITY_TEST_TRUE@am__append_22 = -DSTRONGSWAN_CONF=\"${strongswan_conf}\" subdir = src/libstrongswan DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 @@ -55,78 +73,82 @@ am__strip_dir = `echo $$p | sed -e 's|^.*/||'`; am__installdirs = "$(DESTDIR)$(libdir)" libLTLIBRARIES_INSTALL = $(INSTALL) LTLIBRARIES = $(lib_LTLIBRARIES) -am__DEPENDENCIES_1 = -libstrongswan_la_DEPENDENCIES = $(am__DEPENDENCIES_1) \ - $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) -am__libstrongswan_la_SOURCES_DIST = credential_store.h library.c \ - library.h chunk.c chunk.h debug.c debug.h enum.c enum.h \ - printf_hook.c printf_hook.h asn1/asn1.c asn1/asn1.h asn1/oid.c \ - asn1/oid.h asn1/pem.c asn1/pem.h asn1/ttodata.c asn1/ttodata.h \ - crypto/ac.c crypto/ac.h crypto/ca.c crypto/ca.h \ - crypto/certinfo.c crypto/certinfo.h crypto/crl.c crypto/crl.h \ - crypto/crypters/crypter.c crypto/crypters/crypter.h \ - crypto/crypters/aes_cbc_crypter.c \ - crypto/crypters/aes_cbc_crypter.h \ - crypto/crypters/des_crypter.c crypto/crypters/des_crypter.h \ +libstrongswan_la_DEPENDENCIES = +am__libstrongswan_la_SOURCES_DIST = library.c library.h chunk.c \ + chunk.h debug.c debug.h enum.c enum.h settings.h settings.c \ + printf_hook.c printf_hook.h asn1/asn1.c asn1/asn1.h \ + asn1/asn1_parser.c asn1/asn1_parser.h asn1/oid.c asn1/oid.h \ + asn1/pem.c asn1/pem.h crypto/crypters/crypter.c \ + crypto/crypters/crypter.h crypto/hashers/hasher.h \ + crypto/hashers/hasher.c crypto/pkcs9.c crypto/pkcs9.h \ + crypto/prfs/prf.c crypto/prfs/prf.h crypto/rngs/rng.c \ + crypto/rngs/rng.h crypto/prf_plus.h crypto/prf_plus.c \ + crypto/signers/signer.c crypto/signers/signer.h \ crypto/diffie_hellman.c crypto/diffie_hellman.h \ - crypto/hashers/hasher.h crypto/hashers/hasher.c \ - crypto/hashers/sha1_hasher.c crypto/hashers/sha1_hasher.h \ - crypto/hashers/sha2_hasher.c crypto/hashers/sha2_hasher.h \ - crypto/hashers/md5_hasher.c crypto/hashers/md5_hasher.h \ - crypto/hmac.c crypto/hmac.h crypto/ietf_attr_list.c \ - crypto/ietf_attr_list.h crypto/ocsp.c crypto/ocsp.h \ - crypto/pkcs7.c crypto/pkcs7.h crypto/pkcs9.c crypto/pkcs9.h \ - crypto/prfs/fips_prf.c crypto/prfs/fips_prf.h \ - crypto/prfs/hmac_prf.c crypto/prfs/hmac_prf.h \ - crypto/prfs/prf.c crypto/prfs/prf.h crypto/prf_plus.h \ - crypto/prf_plus.c crypto/rsa/rsa_private_key.c \ - crypto/rsa/rsa_private_key.h crypto/rsa/rsa_public_key.h \ - crypto/rsa/rsa_public_key.c crypto/signers/hmac_signer.c \ - crypto/signers/hmac_signer.h crypto/signers/signer.c \ - crypto/signers/signer.h crypto/x509.c crypto/x509.h \ - utils/fetcher.c utils/fetcher.h utils/host.c utils/host.h \ - utils/identification.c utils/identification.h utils/iterator.h \ + crypto/crypto_factory.c crypto/crypto_factory.h \ + credentials/credential_factory.c \ + credentials/credential_factory.h credentials/builder.c \ + credentials/builder.h credentials/keys/private_key.c \ + credentials/keys/private_key.h credentials/keys/public_key.c \ + credentials/keys/public_key.h credentials/keys/shared_key.c \ + credentials/keys/shared_key.h \ + credentials/certificates/certificate.c \ + credentials/certificates/certificate.h \ + credentials/certificates/x509.h \ + credentials/certificates/x509.c credentials/certificates/ac.h \ + credentials/certificates/crl.h credentials/certificates/crl.c \ + credentials/certificates/ocsp_request.h \ + credentials/certificates/ocsp_response.h \ + credentials/certificates/ocsp_response.c fetcher/fetcher.h \ + fetcher/fetcher_manager.h fetcher/fetcher_manager.c \ + database/database.h database/database_factory.h \ + database/database_factory.c utils.h utils.c utils/host.c \ + utils/host.h utils/identification.c utils/identification.h \ + utils/iterator.h utils/lexparser.c utils/lexparser.h \ + utils/linked_list.c utils/linked_list.h utils/enumerator.c \ + utils/enumerator.h utils/optionsfrom.c utils/optionsfrom.h \ + utils/mutex.c utils/mutex.h plugins/plugin_loader.c \ + plugins/plugin_loader.h plugins/plugin.h \ utils/leak_detective.c utils/leak_detective.h \ - utils/lexparser.c utils/lexparser.h utils/linked_list.c \ - utils/linked_list.h utils/enumerator.c utils/enumerator.h \ - utils/optionsfrom.c utils/optionsfrom.h utils/randomizer.c \ - utils/randomizer.h fips/fips_canister_start.c fips/fips.c \ - fips/fips.h fips/fips_canister_end.c + fips/fips_canister_start.c fips/fips.c fips/fips.h \ + fips/fips_canister_end.c +@USE_LEAK_DETECTIVE_TRUE@am__objects_1 = leak_detective.lo @USE_INTEGRITY_TEST_FALSE@am_libstrongswan_la_OBJECTS = library.lo \ @USE_INTEGRITY_TEST_FALSE@ chunk.lo debug.lo enum.lo \ -@USE_INTEGRITY_TEST_FALSE@ printf_hook.lo asn1.lo oid.lo pem.lo \ -@USE_INTEGRITY_TEST_FALSE@ ttodata.lo ac.lo ca.lo certinfo.lo \ -@USE_INTEGRITY_TEST_FALSE@ crl.lo crypter.lo aes_cbc_crypter.lo \ -@USE_INTEGRITY_TEST_FALSE@ des_crypter.lo diffie_hellman.lo \ -@USE_INTEGRITY_TEST_FALSE@ hasher.lo sha1_hasher.lo \ -@USE_INTEGRITY_TEST_FALSE@ sha2_hasher.lo md5_hasher.lo hmac.lo \ -@USE_INTEGRITY_TEST_FALSE@ ietf_attr_list.lo ocsp.lo pkcs7.lo \ -@USE_INTEGRITY_TEST_FALSE@ pkcs9.lo fips_prf.lo hmac_prf.lo \ -@USE_INTEGRITY_TEST_FALSE@ prf.lo prf_plus.lo \ -@USE_INTEGRITY_TEST_FALSE@ rsa_private_key.lo rsa_public_key.lo \ -@USE_INTEGRITY_TEST_FALSE@ hmac_signer.lo signer.lo x509.lo \ -@USE_INTEGRITY_TEST_FALSE@ fetcher.lo host.lo identification.lo \ -@USE_INTEGRITY_TEST_FALSE@ leak_detective.lo lexparser.lo \ +@USE_INTEGRITY_TEST_FALSE@ settings.lo printf_hook.lo asn1.lo \ +@USE_INTEGRITY_TEST_FALSE@ asn1_parser.lo oid.lo pem.lo \ +@USE_INTEGRITY_TEST_FALSE@ crypter.lo hasher.lo pkcs9.lo prf.lo \ +@USE_INTEGRITY_TEST_FALSE@ rng.lo prf_plus.lo signer.lo \ +@USE_INTEGRITY_TEST_FALSE@ diffie_hellman.lo crypto_factory.lo \ +@USE_INTEGRITY_TEST_FALSE@ credential_factory.lo builder.lo \ +@USE_INTEGRITY_TEST_FALSE@ private_key.lo public_key.lo \ +@USE_INTEGRITY_TEST_FALSE@ shared_key.lo certificate.lo x509.lo \ +@USE_INTEGRITY_TEST_FALSE@ crl.lo ocsp_response.lo \ +@USE_INTEGRITY_TEST_FALSE@ fetcher_manager.lo \ +@USE_INTEGRITY_TEST_FALSE@ database_factory.lo utils.lo host.lo \ +@USE_INTEGRITY_TEST_FALSE@ identification.lo lexparser.lo \ @USE_INTEGRITY_TEST_FALSE@ linked_list.lo enumerator.lo \ -@USE_INTEGRITY_TEST_FALSE@ optionsfrom.lo randomizer.lo +@USE_INTEGRITY_TEST_FALSE@ optionsfrom.lo mutex.lo \ +@USE_INTEGRITY_TEST_FALSE@ plugin_loader.lo $(am__objects_1) @USE_INTEGRITY_TEST_TRUE@am_libstrongswan_la_OBJECTS = \ @USE_INTEGRITY_TEST_TRUE@ fips_canister_start.lo fips.lo \ @USE_INTEGRITY_TEST_TRUE@ library.lo chunk.lo debug.lo enum.lo \ -@USE_INTEGRITY_TEST_TRUE@ printf_hook.lo asn1.lo oid.lo pem.lo \ -@USE_INTEGRITY_TEST_TRUE@ ttodata.lo ac.lo ca.lo certinfo.lo \ -@USE_INTEGRITY_TEST_TRUE@ crl.lo crypter.lo aes_cbc_crypter.lo \ -@USE_INTEGRITY_TEST_TRUE@ des_crypter.lo diffie_hellman.lo \ -@USE_INTEGRITY_TEST_TRUE@ hasher.lo sha1_hasher.lo \ -@USE_INTEGRITY_TEST_TRUE@ sha2_hasher.lo md5_hasher.lo hmac.lo \ -@USE_INTEGRITY_TEST_TRUE@ ietf_attr_list.lo ocsp.lo pkcs7.lo \ -@USE_INTEGRITY_TEST_TRUE@ pkcs9.lo fips_prf.lo hmac_prf.lo \ -@USE_INTEGRITY_TEST_TRUE@ prf.lo prf_plus.lo rsa_private_key.lo \ -@USE_INTEGRITY_TEST_TRUE@ rsa_public_key.lo hmac_signer.lo \ -@USE_INTEGRITY_TEST_TRUE@ signer.lo x509.lo fetcher.lo host.lo \ -@USE_INTEGRITY_TEST_TRUE@ identification.lo leak_detective.lo \ -@USE_INTEGRITY_TEST_TRUE@ lexparser.lo linked_list.lo \ -@USE_INTEGRITY_TEST_TRUE@ enumerator.lo optionsfrom.lo \ -@USE_INTEGRITY_TEST_TRUE@ randomizer.lo fips_canister_end.lo +@USE_INTEGRITY_TEST_TRUE@ settings.lo printf_hook.lo asn1.lo \ +@USE_INTEGRITY_TEST_TRUE@ asn1_parser.lo oid.lo pem.lo \ +@USE_INTEGRITY_TEST_TRUE@ crypter.lo hasher.lo pkcs9.lo prf.lo \ +@USE_INTEGRITY_TEST_TRUE@ rng.lo prf_plus.lo signer.lo \ +@USE_INTEGRITY_TEST_TRUE@ diffie_hellman.lo crypto_factory.lo \ +@USE_INTEGRITY_TEST_TRUE@ credential_factory.lo builder.lo \ +@USE_INTEGRITY_TEST_TRUE@ private_key.lo public_key.lo \ +@USE_INTEGRITY_TEST_TRUE@ shared_key.lo certificate.lo x509.lo \ +@USE_INTEGRITY_TEST_TRUE@ crl.lo ocsp_response.lo \ +@USE_INTEGRITY_TEST_TRUE@ fetcher_manager.lo \ +@USE_INTEGRITY_TEST_TRUE@ database_factory.lo utils.lo host.lo \ +@USE_INTEGRITY_TEST_TRUE@ identification.lo lexparser.lo \ +@USE_INTEGRITY_TEST_TRUE@ linked_list.lo enumerator.lo \ +@USE_INTEGRITY_TEST_TRUE@ optionsfrom.lo mutex.lo \ +@USE_INTEGRITY_TEST_TRUE@ plugin_loader.lo $(am__objects_1) \ +@USE_INTEGRITY_TEST_TRUE@ fips_canister_end.lo libstrongswan_la_OBJECTS = $(am_libstrongswan_la_OBJECTS) PROGRAMS = $(noinst_PROGRAMS) am__fips_signer_SOURCES_DIST = fips/fips_signer.c @@ -149,8 +171,22 @@ LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ SOURCES = $(libstrongswan_la_SOURCES) $(fips_signer_SOURCES) DIST_SOURCES = $(am__libstrongswan_la_SOURCES_DIST) \ $(am__fips_signer_SOURCES_DIST) +RECURSIVE_TARGETS = all-recursive check-recursive dvi-recursive \ + html-recursive info-recursive install-data-recursive \ + install-dvi-recursive install-exec-recursive \ + install-html-recursive install-info-recursive \ + install-pdf-recursive install-ps-recursive install-recursive \ + installcheck-recursive installdirs-recursive pdf-recursive \ + ps-recursive uninstall-recursive +RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ + distclean-recursive maintainer-clean-recursive ETAGS = etags CTAGS = ctags +DIST_SUBDIRS = . plugins/aes plugins/des plugins/md5 plugins/sha1 \ + plugins/sha2 plugins/fips_prf plugins/gmp plugins/random \ + plugins/hmac plugins/xcbc plugins/x509 plugins/pubkey \ + plugins/curl plugins/ldap plugins/mysql plugins/sqlite \ + plugins/padlock plugins/openssl DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ @@ -171,6 +207,7 @@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ +DSYMUTIL = @DSYMUTIL@ ECHO = @ECHO@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ @@ -200,6 +237,7 @@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MKDIR_P = @MKDIR_P@ +NMEDIT = @NMEDIT@ OBJEXT = @OBJEXT@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ @@ -230,7 +268,6 @@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ -backenddir = @backenddir@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ @@ -241,12 +278,11 @@ builddir = @builddir@ confdir = @confdir@ datadir = @datadir@ datarootdir = @datarootdir@ -dbus_CFLAGS = @dbus_CFLAGS@ -dbus_LIBS = @dbus_LIBS@ docdir = @docdir@ dvidir = @dvidir@ -eapdir = @eapdir@ exec_prefix = @exec_prefix@ +gtk_CFLAGS = @gtk_CFLAGS@ +gtk_LIBS = @gtk_LIBS@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ @@ -256,12 +292,12 @@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ -interfacedir = @interfacedir@ ipsecdir = @ipsecdir@ -ipsecgid = @ipsecgid@ -ipsecuid = @ipsecuid@ +ipsecgroup = @ipsecgroup@ +ipsecuser = @ipsecuser@ libdir = @libdir@ libexecdir = @libexecdir@ +libstrongswan_plugins = @libstrongswan_plugins@ linuxdir = @linuxdir@ localedir = @localedir@ localstatedir = @localstatedir@ @@ -274,10 +310,12 @@ 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@ @@ -285,145 +323,153 @@ top_srcdir = @top_srcdir@ xml_CFLAGS = @xml_CFLAGS@ xml_LIBS = @xml_LIBS@ lib_LTLIBRARIES = libstrongswan.la -@USE_INTEGRITY_TEST_FALSE@libstrongswan_la_SOURCES = \ -@USE_INTEGRITY_TEST_FALSE@ credential_store.h library.c \ +@USE_INTEGRITY_TEST_FALSE@libstrongswan_la_SOURCES = library.c \ @USE_INTEGRITY_TEST_FALSE@ library.h chunk.c chunk.h debug.c \ -@USE_INTEGRITY_TEST_FALSE@ debug.h enum.c enum.h printf_hook.c \ +@USE_INTEGRITY_TEST_FALSE@ debug.h enum.c enum.h settings.h \ +@USE_INTEGRITY_TEST_FALSE@ settings.c printf_hook.c \ @USE_INTEGRITY_TEST_FALSE@ printf_hook.h asn1/asn1.c \ -@USE_INTEGRITY_TEST_FALSE@ asn1/asn1.h asn1/oid.c asn1/oid.h \ -@USE_INTEGRITY_TEST_FALSE@ asn1/pem.c asn1/pem.h asn1/ttodata.c \ -@USE_INTEGRITY_TEST_FALSE@ asn1/ttodata.h crypto/ac.c \ -@USE_INTEGRITY_TEST_FALSE@ crypto/ac.h crypto/ca.c crypto/ca.h \ -@USE_INTEGRITY_TEST_FALSE@ crypto/certinfo.c crypto/certinfo.h \ -@USE_INTEGRITY_TEST_FALSE@ crypto/crl.c crypto/crl.h \ +@USE_INTEGRITY_TEST_FALSE@ asn1/asn1.h asn1/asn1_parser.c \ +@USE_INTEGRITY_TEST_FALSE@ asn1/asn1_parser.h asn1/oid.c \ +@USE_INTEGRITY_TEST_FALSE@ asn1/oid.h asn1/pem.c asn1/pem.h \ @USE_INTEGRITY_TEST_FALSE@ crypto/crypters/crypter.c \ @USE_INTEGRITY_TEST_FALSE@ crypto/crypters/crypter.h \ -@USE_INTEGRITY_TEST_FALSE@ crypto/crypters/aes_cbc_crypter.c \ -@USE_INTEGRITY_TEST_FALSE@ crypto/crypters/aes_cbc_crypter.h \ -@USE_INTEGRITY_TEST_FALSE@ crypto/crypters/des_crypter.c \ -@USE_INTEGRITY_TEST_FALSE@ crypto/crypters/des_crypter.h \ -@USE_INTEGRITY_TEST_FALSE@ crypto/diffie_hellman.c \ -@USE_INTEGRITY_TEST_FALSE@ crypto/diffie_hellman.h \ @USE_INTEGRITY_TEST_FALSE@ crypto/hashers/hasher.h \ @USE_INTEGRITY_TEST_FALSE@ crypto/hashers/hasher.c \ -@USE_INTEGRITY_TEST_FALSE@ crypto/hashers/sha1_hasher.c \ -@USE_INTEGRITY_TEST_FALSE@ crypto/hashers/sha1_hasher.h \ -@USE_INTEGRITY_TEST_FALSE@ crypto/hashers/sha2_hasher.c \ -@USE_INTEGRITY_TEST_FALSE@ crypto/hashers/sha2_hasher.h \ -@USE_INTEGRITY_TEST_FALSE@ crypto/hashers/md5_hasher.c \ -@USE_INTEGRITY_TEST_FALSE@ crypto/hashers/md5_hasher.h \ -@USE_INTEGRITY_TEST_FALSE@ crypto/hmac.c crypto/hmac.h \ -@USE_INTEGRITY_TEST_FALSE@ crypto/ietf_attr_list.c \ -@USE_INTEGRITY_TEST_FALSE@ crypto/ietf_attr_list.h \ -@USE_INTEGRITY_TEST_FALSE@ crypto/ocsp.c crypto/ocsp.h \ -@USE_INTEGRITY_TEST_FALSE@ crypto/pkcs7.c crypto/pkcs7.h \ @USE_INTEGRITY_TEST_FALSE@ crypto/pkcs9.c crypto/pkcs9.h \ -@USE_INTEGRITY_TEST_FALSE@ crypto/prfs/fips_prf.c \ -@USE_INTEGRITY_TEST_FALSE@ crypto/prfs/fips_prf.h \ -@USE_INTEGRITY_TEST_FALSE@ crypto/prfs/hmac_prf.c \ -@USE_INTEGRITY_TEST_FALSE@ crypto/prfs/hmac_prf.h \ @USE_INTEGRITY_TEST_FALSE@ crypto/prfs/prf.c crypto/prfs/prf.h \ +@USE_INTEGRITY_TEST_FALSE@ crypto/rngs/rng.c crypto/rngs/rng.h \ @USE_INTEGRITY_TEST_FALSE@ crypto/prf_plus.h crypto/prf_plus.c \ -@USE_INTEGRITY_TEST_FALSE@ crypto/rsa/rsa_private_key.c \ -@USE_INTEGRITY_TEST_FALSE@ crypto/rsa/rsa_private_key.h \ -@USE_INTEGRITY_TEST_FALSE@ crypto/rsa/rsa_public_key.h \ -@USE_INTEGRITY_TEST_FALSE@ crypto/rsa/rsa_public_key.c \ -@USE_INTEGRITY_TEST_FALSE@ crypto/signers/hmac_signer.c \ -@USE_INTEGRITY_TEST_FALSE@ crypto/signers/hmac_signer.h \ @USE_INTEGRITY_TEST_FALSE@ crypto/signers/signer.c \ @USE_INTEGRITY_TEST_FALSE@ crypto/signers/signer.h \ -@USE_INTEGRITY_TEST_FALSE@ crypto/x509.c crypto/x509.h \ -@USE_INTEGRITY_TEST_FALSE@ utils/fetcher.c utils/fetcher.h \ -@USE_INTEGRITY_TEST_FALSE@ utils/host.c utils/host.h \ +@USE_INTEGRITY_TEST_FALSE@ crypto/diffie_hellman.c \ +@USE_INTEGRITY_TEST_FALSE@ crypto/diffie_hellman.h \ +@USE_INTEGRITY_TEST_FALSE@ crypto/crypto_factory.c \ +@USE_INTEGRITY_TEST_FALSE@ crypto/crypto_factory.h \ +@USE_INTEGRITY_TEST_FALSE@ credentials/credential_factory.c \ +@USE_INTEGRITY_TEST_FALSE@ credentials/credential_factory.h \ +@USE_INTEGRITY_TEST_FALSE@ credentials/builder.c \ +@USE_INTEGRITY_TEST_FALSE@ credentials/builder.h \ +@USE_INTEGRITY_TEST_FALSE@ credentials/keys/private_key.c \ +@USE_INTEGRITY_TEST_FALSE@ credentials/keys/private_key.h \ +@USE_INTEGRITY_TEST_FALSE@ credentials/keys/public_key.c \ +@USE_INTEGRITY_TEST_FALSE@ credentials/keys/public_key.h \ +@USE_INTEGRITY_TEST_FALSE@ credentials/keys/shared_key.c \ +@USE_INTEGRITY_TEST_FALSE@ credentials/keys/shared_key.h \ +@USE_INTEGRITY_TEST_FALSE@ credentials/certificates/certificate.c \ +@USE_INTEGRITY_TEST_FALSE@ credentials/certificates/certificate.h \ +@USE_INTEGRITY_TEST_FALSE@ credentials/certificates/x509.h \ +@USE_INTEGRITY_TEST_FALSE@ credentials/certificates/x509.c \ +@USE_INTEGRITY_TEST_FALSE@ credentials/certificates/ac.h \ +@USE_INTEGRITY_TEST_FALSE@ credentials/certificates/crl.h \ +@USE_INTEGRITY_TEST_FALSE@ credentials/certificates/crl.c \ +@USE_INTEGRITY_TEST_FALSE@ credentials/certificates/ocsp_request.h \ +@USE_INTEGRITY_TEST_FALSE@ credentials/certificates/ocsp_response.h \ +@USE_INTEGRITY_TEST_FALSE@ credentials/certificates/ocsp_response.c \ +@USE_INTEGRITY_TEST_FALSE@ fetcher/fetcher.h \ +@USE_INTEGRITY_TEST_FALSE@ fetcher/fetcher_manager.h \ +@USE_INTEGRITY_TEST_FALSE@ fetcher/fetcher_manager.c \ +@USE_INTEGRITY_TEST_FALSE@ database/database.h \ +@USE_INTEGRITY_TEST_FALSE@ database/database_factory.h \ +@USE_INTEGRITY_TEST_FALSE@ database/database_factory.c utils.h \ +@USE_INTEGRITY_TEST_FALSE@ utils.c utils/host.c utils/host.h \ @USE_INTEGRITY_TEST_FALSE@ utils/identification.c \ @USE_INTEGRITY_TEST_FALSE@ utils/identification.h \ -@USE_INTEGRITY_TEST_FALSE@ utils/iterator.h \ -@USE_INTEGRITY_TEST_FALSE@ utils/leak_detective.c \ -@USE_INTEGRITY_TEST_FALSE@ utils/leak_detective.h \ -@USE_INTEGRITY_TEST_FALSE@ utils/lexparser.c utils/lexparser.h \ +@USE_INTEGRITY_TEST_FALSE@ utils/iterator.h utils/lexparser.c \ +@USE_INTEGRITY_TEST_FALSE@ utils/lexparser.h \ @USE_INTEGRITY_TEST_FALSE@ utils/linked_list.c \ @USE_INTEGRITY_TEST_FALSE@ utils/linked_list.h \ @USE_INTEGRITY_TEST_FALSE@ utils/enumerator.c \ @USE_INTEGRITY_TEST_FALSE@ utils/enumerator.h \ @USE_INTEGRITY_TEST_FALSE@ utils/optionsfrom.c \ -@USE_INTEGRITY_TEST_FALSE@ utils/optionsfrom.h \ -@USE_INTEGRITY_TEST_FALSE@ utils/randomizer.c \ -@USE_INTEGRITY_TEST_FALSE@ utils/randomizer.h +@USE_INTEGRITY_TEST_FALSE@ utils/optionsfrom.h utils/mutex.c \ +@USE_INTEGRITY_TEST_FALSE@ utils/mutex.h \ +@USE_INTEGRITY_TEST_FALSE@ plugins/plugin_loader.c \ +@USE_INTEGRITY_TEST_FALSE@ plugins/plugin_loader.h \ +@USE_INTEGRITY_TEST_FALSE@ plugins/plugin.h $(am__append_2) @USE_INTEGRITY_TEST_TRUE@libstrongswan_la_SOURCES = \ @USE_INTEGRITY_TEST_TRUE@ fips/fips_canister_start.c \ -@USE_INTEGRITY_TEST_TRUE@ fips/fips.c fips/fips.h \ -@USE_INTEGRITY_TEST_TRUE@ credential_store.h library.c \ +@USE_INTEGRITY_TEST_TRUE@ fips/fips.c fips/fips.h library.c \ @USE_INTEGRITY_TEST_TRUE@ library.h chunk.c chunk.h debug.c \ -@USE_INTEGRITY_TEST_TRUE@ debug.h enum.c enum.h printf_hook.c \ +@USE_INTEGRITY_TEST_TRUE@ debug.h enum.c enum.h settings.h \ +@USE_INTEGRITY_TEST_TRUE@ settings.c printf_hook.c \ @USE_INTEGRITY_TEST_TRUE@ printf_hook.h asn1/asn1.c asn1/asn1.h \ +@USE_INTEGRITY_TEST_TRUE@ asn1/asn1_parser.c asn1/asn1_parser.h \ @USE_INTEGRITY_TEST_TRUE@ asn1/oid.c asn1/oid.h asn1/pem.c \ -@USE_INTEGRITY_TEST_TRUE@ asn1/pem.h asn1/ttodata.c \ -@USE_INTEGRITY_TEST_TRUE@ asn1/ttodata.h crypto/ac.c \ -@USE_INTEGRITY_TEST_TRUE@ crypto/ac.h crypto/ca.c crypto/ca.h \ -@USE_INTEGRITY_TEST_TRUE@ crypto/certinfo.c crypto/certinfo.h \ -@USE_INTEGRITY_TEST_TRUE@ crypto/crl.c crypto/crl.h \ -@USE_INTEGRITY_TEST_TRUE@ crypto/crypters/crypter.c \ +@USE_INTEGRITY_TEST_TRUE@ asn1/pem.h crypto/crypters/crypter.c \ @USE_INTEGRITY_TEST_TRUE@ crypto/crypters/crypter.h \ -@USE_INTEGRITY_TEST_TRUE@ crypto/crypters/aes_cbc_crypter.c \ -@USE_INTEGRITY_TEST_TRUE@ crypto/crypters/aes_cbc_crypter.h \ -@USE_INTEGRITY_TEST_TRUE@ crypto/crypters/des_crypter.c \ -@USE_INTEGRITY_TEST_TRUE@ crypto/crypters/des_crypter.h \ -@USE_INTEGRITY_TEST_TRUE@ crypto/diffie_hellman.c \ -@USE_INTEGRITY_TEST_TRUE@ crypto/diffie_hellman.h \ @USE_INTEGRITY_TEST_TRUE@ crypto/hashers/hasher.h \ @USE_INTEGRITY_TEST_TRUE@ crypto/hashers/hasher.c \ -@USE_INTEGRITY_TEST_TRUE@ crypto/hashers/sha1_hasher.c \ -@USE_INTEGRITY_TEST_TRUE@ crypto/hashers/sha1_hasher.h \ -@USE_INTEGRITY_TEST_TRUE@ crypto/hashers/sha2_hasher.c \ -@USE_INTEGRITY_TEST_TRUE@ crypto/hashers/sha2_hasher.h \ -@USE_INTEGRITY_TEST_TRUE@ crypto/hashers/md5_hasher.c \ -@USE_INTEGRITY_TEST_TRUE@ crypto/hashers/md5_hasher.h \ -@USE_INTEGRITY_TEST_TRUE@ crypto/hmac.c crypto/hmac.h \ -@USE_INTEGRITY_TEST_TRUE@ crypto/ietf_attr_list.c \ -@USE_INTEGRITY_TEST_TRUE@ crypto/ietf_attr_list.h crypto/ocsp.c \ -@USE_INTEGRITY_TEST_TRUE@ crypto/ocsp.h crypto/pkcs7.c \ -@USE_INTEGRITY_TEST_TRUE@ crypto/pkcs7.h crypto/pkcs9.c \ -@USE_INTEGRITY_TEST_TRUE@ crypto/pkcs9.h crypto/prfs/fips_prf.c \ -@USE_INTEGRITY_TEST_TRUE@ crypto/prfs/fips_prf.h \ -@USE_INTEGRITY_TEST_TRUE@ crypto/prfs/hmac_prf.c \ -@USE_INTEGRITY_TEST_TRUE@ crypto/prfs/hmac_prf.h \ +@USE_INTEGRITY_TEST_TRUE@ crypto/pkcs9.c crypto/pkcs9.h \ @USE_INTEGRITY_TEST_TRUE@ crypto/prfs/prf.c crypto/prfs/prf.h \ +@USE_INTEGRITY_TEST_TRUE@ crypto/rngs/rng.c crypto/rngs/rng.h \ @USE_INTEGRITY_TEST_TRUE@ crypto/prf_plus.h crypto/prf_plus.c \ -@USE_INTEGRITY_TEST_TRUE@ crypto/rsa/rsa_private_key.c \ -@USE_INTEGRITY_TEST_TRUE@ crypto/rsa/rsa_private_key.h \ -@USE_INTEGRITY_TEST_TRUE@ crypto/rsa/rsa_public_key.h \ -@USE_INTEGRITY_TEST_TRUE@ crypto/rsa/rsa_public_key.c \ -@USE_INTEGRITY_TEST_TRUE@ crypto/signers/hmac_signer.c \ -@USE_INTEGRITY_TEST_TRUE@ crypto/signers/hmac_signer.h \ @USE_INTEGRITY_TEST_TRUE@ crypto/signers/signer.c \ -@USE_INTEGRITY_TEST_TRUE@ crypto/signers/signer.h crypto/x509.c \ -@USE_INTEGRITY_TEST_TRUE@ crypto/x509.h utils/fetcher.c \ -@USE_INTEGRITY_TEST_TRUE@ utils/fetcher.h utils/host.c \ -@USE_INTEGRITY_TEST_TRUE@ utils/host.h utils/identification.c \ +@USE_INTEGRITY_TEST_TRUE@ crypto/signers/signer.h \ +@USE_INTEGRITY_TEST_TRUE@ crypto/diffie_hellman.c \ +@USE_INTEGRITY_TEST_TRUE@ crypto/diffie_hellman.h \ +@USE_INTEGRITY_TEST_TRUE@ crypto/crypto_factory.c \ +@USE_INTEGRITY_TEST_TRUE@ crypto/crypto_factory.h \ +@USE_INTEGRITY_TEST_TRUE@ credentials/credential_factory.c \ +@USE_INTEGRITY_TEST_TRUE@ credentials/credential_factory.h \ +@USE_INTEGRITY_TEST_TRUE@ credentials/builder.c \ +@USE_INTEGRITY_TEST_TRUE@ credentials/builder.h \ +@USE_INTEGRITY_TEST_TRUE@ credentials/keys/private_key.c \ +@USE_INTEGRITY_TEST_TRUE@ credentials/keys/private_key.h \ +@USE_INTEGRITY_TEST_TRUE@ credentials/keys/public_key.c \ +@USE_INTEGRITY_TEST_TRUE@ credentials/keys/public_key.h \ +@USE_INTEGRITY_TEST_TRUE@ credentials/keys/shared_key.c \ +@USE_INTEGRITY_TEST_TRUE@ credentials/keys/shared_key.h \ +@USE_INTEGRITY_TEST_TRUE@ credentials/certificates/certificate.c \ +@USE_INTEGRITY_TEST_TRUE@ credentials/certificates/certificate.h \ +@USE_INTEGRITY_TEST_TRUE@ credentials/certificates/x509.h \ +@USE_INTEGRITY_TEST_TRUE@ credentials/certificates/x509.c \ +@USE_INTEGRITY_TEST_TRUE@ credentials/certificates/ac.h \ +@USE_INTEGRITY_TEST_TRUE@ credentials/certificates/crl.h \ +@USE_INTEGRITY_TEST_TRUE@ credentials/certificates/crl.c \ +@USE_INTEGRITY_TEST_TRUE@ credentials/certificates/ocsp_request.h \ +@USE_INTEGRITY_TEST_TRUE@ credentials/certificates/ocsp_response.h \ +@USE_INTEGRITY_TEST_TRUE@ credentials/certificates/ocsp_response.c \ +@USE_INTEGRITY_TEST_TRUE@ fetcher/fetcher.h \ +@USE_INTEGRITY_TEST_TRUE@ fetcher/fetcher_manager.h \ +@USE_INTEGRITY_TEST_TRUE@ fetcher/fetcher_manager.c \ +@USE_INTEGRITY_TEST_TRUE@ database/database.h \ +@USE_INTEGRITY_TEST_TRUE@ database/database_factory.h \ +@USE_INTEGRITY_TEST_TRUE@ database/database_factory.c utils.h \ +@USE_INTEGRITY_TEST_TRUE@ utils.c utils/host.c utils/host.h \ +@USE_INTEGRITY_TEST_TRUE@ utils/identification.c \ @USE_INTEGRITY_TEST_TRUE@ utils/identification.h \ -@USE_INTEGRITY_TEST_TRUE@ utils/iterator.h \ -@USE_INTEGRITY_TEST_TRUE@ utils/leak_detective.c \ -@USE_INTEGRITY_TEST_TRUE@ utils/leak_detective.h \ -@USE_INTEGRITY_TEST_TRUE@ utils/lexparser.c utils/lexparser.h \ -@USE_INTEGRITY_TEST_TRUE@ utils/linked_list.c \ +@USE_INTEGRITY_TEST_TRUE@ utils/iterator.h utils/lexparser.c \ +@USE_INTEGRITY_TEST_TRUE@ utils/lexparser.h utils/linked_list.c \ @USE_INTEGRITY_TEST_TRUE@ utils/linked_list.h \ @USE_INTEGRITY_TEST_TRUE@ utils/enumerator.c utils/enumerator.h \ @USE_INTEGRITY_TEST_TRUE@ utils/optionsfrom.c \ -@USE_INTEGRITY_TEST_TRUE@ utils/optionsfrom.h \ -@USE_INTEGRITY_TEST_TRUE@ utils/randomizer.c utils/randomizer.h \ +@USE_INTEGRITY_TEST_TRUE@ utils/optionsfrom.h utils/mutex.c \ +@USE_INTEGRITY_TEST_TRUE@ utils/mutex.h plugins/plugin_loader.c \ +@USE_INTEGRITY_TEST_TRUE@ plugins/plugin_loader.h \ +@USE_INTEGRITY_TEST_TRUE@ plugins/plugin.h $(am__append_2) \ @USE_INTEGRITY_TEST_TRUE@ fips/fips_canister_end.c -libstrongswan_la_LIBADD = -lgmp -lpthread $(am__append_1) \ - $(am__append_2) $(am__append_3) +libstrongswan_la_LIBADD = -lpthread -ldl INCLUDES = -I$(top_srcdir)/src/libstrongswan -@USE_LEAK_DETECTIVE_TRUE@AM_CFLAGS = -DLEAK_DETECTIVE +AM_CFLAGS = -DIPSEC_DIR=\"${ipsecdir}\" \ + -DIPSEC_PLUGINDIR=\"${plugindir}\" $(am__append_1) \ + $(am__append_22) EXTRA_DIST = asn1/oid.txt asn1/oid.pl -BUILT_SOURCES = asn1/oid.c asn1/oid.h $(am__append_4) +BUILT_SOURCES = asn1/oid.c asn1/oid.h $(am__append_21) MAINTAINERCLEANFILES = asn1/oid.c asn1/oid.h + +# build plugins with their own Makefile +####################################### +SUBDIRS = . $(am__append_3) $(am__append_4) $(am__append_5) \ + $(am__append_6) $(am__append_7) $(am__append_8) \ + $(am__append_9) $(am__append_10) $(am__append_11) \ + $(am__append_12) $(am__append_13) $(am__append_14) \ + $(am__append_15) $(am__append_16) $(am__append_17) \ + $(am__append_18) $(am__append_19) $(am__append_20) @USE_INTEGRITY_TEST_TRUE@fips_signer_SOURCES = fips/fips_signer.c @USE_INTEGRITY_TEST_TRUE@fips_signer_LDADD = libstrongswan.la @USE_INTEGRITY_TEST_TRUE@CLEANFILES = fips_signature.h fips_signer all: $(BUILT_SOURCES) - $(MAKE) $(AM_MAKEFLAGS) all-am + $(MAKE) $(AM_MAKEFLAGS) all-recursive .SUFFIXES: .SUFFIXES: .c .lo .o .obj @@ -462,8 +508,8 @@ install-libLTLIBRARIES: $(lib_LTLIBRARIES) @list='$(lib_LTLIBRARIES)'; for p in $$list; do \ if test -f $$p; then \ f=$(am__strip_dir) \ - echo " $(LIBTOOL) --mode=install $(libLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) '$$p' '$(DESTDIR)$(libdir)/$$f'"; \ - $(LIBTOOL) --mode=install $(libLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) "$$p" "$(DESTDIR)$(libdir)/$$f"; \ + echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(libLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) '$$p' '$(DESTDIR)$(libdir)/$$f'"; \ + $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(libLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) "$$p" "$(DESTDIR)$(libdir)/$$f"; \ else :; fi; \ done @@ -471,8 +517,8 @@ uninstall-libLTLIBRARIES: @$(NORMAL_UNINSTALL) @list='$(lib_LTLIBRARIES)'; for p in $$list; do \ p=$(am__strip_dir) \ - echo " $(LIBTOOL) --mode=uninstall rm -f '$(DESTDIR)$(libdir)/$$p'"; \ - $(LIBTOOL) --mode=uninstall rm -f "$(DESTDIR)$(libdir)/$$p"; \ + echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(libdir)/$$p'"; \ + $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(libdir)/$$p"; \ done clean-libLTLIBRARIES: @@ -502,53 +548,49 @@ mostlyclean-compile: distclean-compile: -rm -f *.tab.c -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ac.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/aes_cbc_crypter.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/asn1.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ca.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/certinfo.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/asn1_parser.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/builder.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/certificate.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/chunk.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/credential_factory.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/crl.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/crypter.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/crypto_factory.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/database_factory.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/debug.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/des_crypter.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/diffie_hellman.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/enum.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/enumerator.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fetcher.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fetcher_manager.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fips.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fips_canister_end.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fips_canister_start.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fips_prf.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fips_signer.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hasher.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hmac.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@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/host.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/identification.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ietf_attr_list.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/leak_detective.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lexparser.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/library.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/linked_list.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/md5_hasher.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ocsp.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mutex.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ocsp_response.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/oid.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/optionsfrom.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pem.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pkcs7.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pkcs9.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/plugin_loader.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/prf.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/prf_plus.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/printf_hook.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/randomizer.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rsa_private_key.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rsa_public_key.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sha1_hasher.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sha2_hasher.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/private_key.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/public_key.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rng.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/settings.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/shared_key.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/signer.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ttodata.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/utils.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/x509.Plo@am__quote@ .c.o: @@ -579,6 +621,13 @@ asn1.lo: asn1/asn1.c @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o asn1.lo `test -f 'asn1/asn1.c' || echo '$(srcdir)/'`asn1/asn1.c +asn1_parser.lo: asn1/asn1_parser.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT asn1_parser.lo -MD -MP -MF $(DEPDIR)/asn1_parser.Tpo -c -o asn1_parser.lo `test -f 'asn1/asn1_parser.c' || echo '$(srcdir)/'`asn1/asn1_parser.c +@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/asn1_parser.Tpo $(DEPDIR)/asn1_parser.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='asn1/asn1_parser.c' object='asn1_parser.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o asn1_parser.lo `test -f 'asn1/asn1_parser.c' || echo '$(srcdir)/'`asn1/asn1_parser.c + oid.lo: asn1/oid.c @am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT oid.lo -MD -MP -MF $(DEPDIR)/oid.Tpo -c -o oid.lo `test -f 'asn1/oid.c' || echo '$(srcdir)/'`asn1/oid.c @am__fastdepCC_TRUE@ mv -f $(DEPDIR)/oid.Tpo $(DEPDIR)/oid.Plo @@ -593,41 +642,6 @@ pem.lo: asn1/pem.c @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o pem.lo `test -f 'asn1/pem.c' || echo '$(srcdir)/'`asn1/pem.c -ttodata.lo: asn1/ttodata.c -@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT ttodata.lo -MD -MP -MF $(DEPDIR)/ttodata.Tpo -c -o ttodata.lo `test -f 'asn1/ttodata.c' || echo '$(srcdir)/'`asn1/ttodata.c -@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/ttodata.Tpo $(DEPDIR)/ttodata.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='asn1/ttodata.c' object='ttodata.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o ttodata.lo `test -f 'asn1/ttodata.c' || echo '$(srcdir)/'`asn1/ttodata.c - -ac.lo: crypto/ac.c -@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT ac.lo -MD -MP -MF $(DEPDIR)/ac.Tpo -c -o ac.lo `test -f 'crypto/ac.c' || echo '$(srcdir)/'`crypto/ac.c -@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/ac.Tpo $(DEPDIR)/ac.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='crypto/ac.c' object='ac.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o ac.lo `test -f 'crypto/ac.c' || echo '$(srcdir)/'`crypto/ac.c - -ca.lo: crypto/ca.c -@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT ca.lo -MD -MP -MF $(DEPDIR)/ca.Tpo -c -o ca.lo `test -f 'crypto/ca.c' || echo '$(srcdir)/'`crypto/ca.c -@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/ca.Tpo $(DEPDIR)/ca.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='crypto/ca.c' object='ca.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o ca.lo `test -f 'crypto/ca.c' || echo '$(srcdir)/'`crypto/ca.c - -certinfo.lo: crypto/certinfo.c -@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT certinfo.lo -MD -MP -MF $(DEPDIR)/certinfo.Tpo -c -o certinfo.lo `test -f 'crypto/certinfo.c' || echo '$(srcdir)/'`crypto/certinfo.c -@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/certinfo.Tpo $(DEPDIR)/certinfo.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='crypto/certinfo.c' object='certinfo.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o certinfo.lo `test -f 'crypto/certinfo.c' || echo '$(srcdir)/'`crypto/certinfo.c - -crl.lo: crypto/crl.c -@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT crl.lo -MD -MP -MF $(DEPDIR)/crl.Tpo -c -o crl.lo `test -f 'crypto/crl.c' || echo '$(srcdir)/'`crypto/crl.c -@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/crl.Tpo $(DEPDIR)/crl.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='crypto/crl.c' object='crl.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o crl.lo `test -f 'crypto/crl.c' || echo '$(srcdir)/'`crypto/crl.c - crypter.lo: crypto/crypters/crypter.c @am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT crypter.lo -MD -MP -MF $(DEPDIR)/crypter.Tpo -c -o crypter.lo `test -f 'crypto/crypters/crypter.c' || echo '$(srcdir)/'`crypto/crypters/crypter.c @am__fastdepCC_TRUE@ mv -f $(DEPDIR)/crypter.Tpo $(DEPDIR)/crypter.Plo @@ -635,27 +649,6 @@ crypter.lo: crypto/crypters/crypter.c @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o crypter.lo `test -f 'crypto/crypters/crypter.c' || echo '$(srcdir)/'`crypto/crypters/crypter.c -aes_cbc_crypter.lo: crypto/crypters/aes_cbc_crypter.c -@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT aes_cbc_crypter.lo -MD -MP -MF $(DEPDIR)/aes_cbc_crypter.Tpo -c -o aes_cbc_crypter.lo `test -f 'crypto/crypters/aes_cbc_crypter.c' || echo '$(srcdir)/'`crypto/crypters/aes_cbc_crypter.c -@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/aes_cbc_crypter.Tpo $(DEPDIR)/aes_cbc_crypter.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='crypto/crypters/aes_cbc_crypter.c' object='aes_cbc_crypter.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o aes_cbc_crypter.lo `test -f 'crypto/crypters/aes_cbc_crypter.c' || echo '$(srcdir)/'`crypto/crypters/aes_cbc_crypter.c - -des_crypter.lo: crypto/crypters/des_crypter.c -@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT des_crypter.lo -MD -MP -MF $(DEPDIR)/des_crypter.Tpo -c -o des_crypter.lo `test -f 'crypto/crypters/des_crypter.c' || echo '$(srcdir)/'`crypto/crypters/des_crypter.c -@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/des_crypter.Tpo $(DEPDIR)/des_crypter.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='crypto/crypters/des_crypter.c' object='des_crypter.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o des_crypter.lo `test -f 'crypto/crypters/des_crypter.c' || echo '$(srcdir)/'`crypto/crypters/des_crypter.c - -diffie_hellman.lo: crypto/diffie_hellman.c -@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT diffie_hellman.lo -MD -MP -MF $(DEPDIR)/diffie_hellman.Tpo -c -o diffie_hellman.lo `test -f 'crypto/diffie_hellman.c' || echo '$(srcdir)/'`crypto/diffie_hellman.c -@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/diffie_hellman.Tpo $(DEPDIR)/diffie_hellman.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='crypto/diffie_hellman.c' object='diffie_hellman.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o diffie_hellman.lo `test -f 'crypto/diffie_hellman.c' || echo '$(srcdir)/'`crypto/diffie_hellman.c - hasher.lo: crypto/hashers/hasher.c @am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT hasher.lo -MD -MP -MF $(DEPDIR)/hasher.Tpo -c -o hasher.lo `test -f 'crypto/hashers/hasher.c' || echo '$(srcdir)/'`crypto/hashers/hasher.c @am__fastdepCC_TRUE@ mv -f $(DEPDIR)/hasher.Tpo $(DEPDIR)/hasher.Plo @@ -663,131 +656,131 @@ hasher.lo: crypto/hashers/hasher.c @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o hasher.lo `test -f 'crypto/hashers/hasher.c' || echo '$(srcdir)/'`crypto/hashers/hasher.c -sha1_hasher.lo: crypto/hashers/sha1_hasher.c -@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT sha1_hasher.lo -MD -MP -MF $(DEPDIR)/sha1_hasher.Tpo -c -o sha1_hasher.lo `test -f 'crypto/hashers/sha1_hasher.c' || echo '$(srcdir)/'`crypto/hashers/sha1_hasher.c -@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/sha1_hasher.Tpo $(DEPDIR)/sha1_hasher.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='crypto/hashers/sha1_hasher.c' object='sha1_hasher.lo' libtool=yes @AMDEPBACKSLASH@ +pkcs9.lo: crypto/pkcs9.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT pkcs9.lo -MD -MP -MF $(DEPDIR)/pkcs9.Tpo -c -o pkcs9.lo `test -f 'crypto/pkcs9.c' || echo '$(srcdir)/'`crypto/pkcs9.c +@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/pkcs9.Tpo $(DEPDIR)/pkcs9.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='crypto/pkcs9.c' object='pkcs9.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o sha1_hasher.lo `test -f 'crypto/hashers/sha1_hasher.c' || echo '$(srcdir)/'`crypto/hashers/sha1_hasher.c +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o pkcs9.lo `test -f 'crypto/pkcs9.c' || echo '$(srcdir)/'`crypto/pkcs9.c -sha2_hasher.lo: crypto/hashers/sha2_hasher.c -@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT sha2_hasher.lo -MD -MP -MF $(DEPDIR)/sha2_hasher.Tpo -c -o sha2_hasher.lo `test -f 'crypto/hashers/sha2_hasher.c' || echo '$(srcdir)/'`crypto/hashers/sha2_hasher.c -@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/sha2_hasher.Tpo $(DEPDIR)/sha2_hasher.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='crypto/hashers/sha2_hasher.c' object='sha2_hasher.lo' libtool=yes @AMDEPBACKSLASH@ +prf.lo: crypto/prfs/prf.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT prf.lo -MD -MP -MF $(DEPDIR)/prf.Tpo -c -o prf.lo `test -f 'crypto/prfs/prf.c' || echo '$(srcdir)/'`crypto/prfs/prf.c +@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/prf.Tpo $(DEPDIR)/prf.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='crypto/prfs/prf.c' object='prf.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o sha2_hasher.lo `test -f 'crypto/hashers/sha2_hasher.c' || echo '$(srcdir)/'`crypto/hashers/sha2_hasher.c +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o prf.lo `test -f 'crypto/prfs/prf.c' || echo '$(srcdir)/'`crypto/prfs/prf.c -md5_hasher.lo: crypto/hashers/md5_hasher.c -@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT md5_hasher.lo -MD -MP -MF $(DEPDIR)/md5_hasher.Tpo -c -o md5_hasher.lo `test -f 'crypto/hashers/md5_hasher.c' || echo '$(srcdir)/'`crypto/hashers/md5_hasher.c -@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/md5_hasher.Tpo $(DEPDIR)/md5_hasher.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='crypto/hashers/md5_hasher.c' object='md5_hasher.lo' libtool=yes @AMDEPBACKSLASH@ +rng.lo: crypto/rngs/rng.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT rng.lo -MD -MP -MF $(DEPDIR)/rng.Tpo -c -o rng.lo `test -f 'crypto/rngs/rng.c' || echo '$(srcdir)/'`crypto/rngs/rng.c +@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/rng.Tpo $(DEPDIR)/rng.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='crypto/rngs/rng.c' object='rng.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o md5_hasher.lo `test -f 'crypto/hashers/md5_hasher.c' || echo '$(srcdir)/'`crypto/hashers/md5_hasher.c +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o rng.lo `test -f 'crypto/rngs/rng.c' || echo '$(srcdir)/'`crypto/rngs/rng.c -hmac.lo: crypto/hmac.c -@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT hmac.lo -MD -MP -MF $(DEPDIR)/hmac.Tpo -c -o hmac.lo `test -f 'crypto/hmac.c' || echo '$(srcdir)/'`crypto/hmac.c -@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/hmac.Tpo $(DEPDIR)/hmac.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='crypto/hmac.c' object='hmac.lo' libtool=yes @AMDEPBACKSLASH@ +prf_plus.lo: crypto/prf_plus.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT prf_plus.lo -MD -MP -MF $(DEPDIR)/prf_plus.Tpo -c -o prf_plus.lo `test -f 'crypto/prf_plus.c' || echo '$(srcdir)/'`crypto/prf_plus.c +@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/prf_plus.Tpo $(DEPDIR)/prf_plus.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='crypto/prf_plus.c' object='prf_plus.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o hmac.lo `test -f 'crypto/hmac.c' || echo '$(srcdir)/'`crypto/hmac.c +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o prf_plus.lo `test -f 'crypto/prf_plus.c' || echo '$(srcdir)/'`crypto/prf_plus.c -ietf_attr_list.lo: crypto/ietf_attr_list.c -@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT ietf_attr_list.lo -MD -MP -MF $(DEPDIR)/ietf_attr_list.Tpo -c -o ietf_attr_list.lo `test -f 'crypto/ietf_attr_list.c' || echo '$(srcdir)/'`crypto/ietf_attr_list.c -@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/ietf_attr_list.Tpo $(DEPDIR)/ietf_attr_list.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='crypto/ietf_attr_list.c' object='ietf_attr_list.lo' libtool=yes @AMDEPBACKSLASH@ +signer.lo: crypto/signers/signer.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT signer.lo -MD -MP -MF $(DEPDIR)/signer.Tpo -c -o signer.lo `test -f 'crypto/signers/signer.c' || echo '$(srcdir)/'`crypto/signers/signer.c +@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/signer.Tpo $(DEPDIR)/signer.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='crypto/signers/signer.c' object='signer.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o ietf_attr_list.lo `test -f 'crypto/ietf_attr_list.c' || echo '$(srcdir)/'`crypto/ietf_attr_list.c +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o signer.lo `test -f 'crypto/signers/signer.c' || echo '$(srcdir)/'`crypto/signers/signer.c -ocsp.lo: crypto/ocsp.c -@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT ocsp.lo -MD -MP -MF $(DEPDIR)/ocsp.Tpo -c -o ocsp.lo `test -f 'crypto/ocsp.c' || echo '$(srcdir)/'`crypto/ocsp.c -@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/ocsp.Tpo $(DEPDIR)/ocsp.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='crypto/ocsp.c' object='ocsp.lo' libtool=yes @AMDEPBACKSLASH@ +diffie_hellman.lo: crypto/diffie_hellman.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT diffie_hellman.lo -MD -MP -MF $(DEPDIR)/diffie_hellman.Tpo -c -o diffie_hellman.lo `test -f 'crypto/diffie_hellman.c' || echo '$(srcdir)/'`crypto/diffie_hellman.c +@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/diffie_hellman.Tpo $(DEPDIR)/diffie_hellman.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='crypto/diffie_hellman.c' object='diffie_hellman.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o ocsp.lo `test -f 'crypto/ocsp.c' || echo '$(srcdir)/'`crypto/ocsp.c +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o diffie_hellman.lo `test -f 'crypto/diffie_hellman.c' || echo '$(srcdir)/'`crypto/diffie_hellman.c -pkcs7.lo: crypto/pkcs7.c -@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT pkcs7.lo -MD -MP -MF $(DEPDIR)/pkcs7.Tpo -c -o pkcs7.lo `test -f 'crypto/pkcs7.c' || echo '$(srcdir)/'`crypto/pkcs7.c -@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/pkcs7.Tpo $(DEPDIR)/pkcs7.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='crypto/pkcs7.c' object='pkcs7.lo' libtool=yes @AMDEPBACKSLASH@ +crypto_factory.lo: crypto/crypto_factory.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT crypto_factory.lo -MD -MP -MF $(DEPDIR)/crypto_factory.Tpo -c -o crypto_factory.lo `test -f 'crypto/crypto_factory.c' || echo '$(srcdir)/'`crypto/crypto_factory.c +@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/crypto_factory.Tpo $(DEPDIR)/crypto_factory.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='crypto/crypto_factory.c' object='crypto_factory.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o pkcs7.lo `test -f 'crypto/pkcs7.c' || echo '$(srcdir)/'`crypto/pkcs7.c +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o crypto_factory.lo `test -f 'crypto/crypto_factory.c' || echo '$(srcdir)/'`crypto/crypto_factory.c -pkcs9.lo: crypto/pkcs9.c -@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT pkcs9.lo -MD -MP -MF $(DEPDIR)/pkcs9.Tpo -c -o pkcs9.lo `test -f 'crypto/pkcs9.c' || echo '$(srcdir)/'`crypto/pkcs9.c -@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/pkcs9.Tpo $(DEPDIR)/pkcs9.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='crypto/pkcs9.c' object='pkcs9.lo' libtool=yes @AMDEPBACKSLASH@ +credential_factory.lo: credentials/credential_factory.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT credential_factory.lo -MD -MP -MF $(DEPDIR)/credential_factory.Tpo -c -o credential_factory.lo `test -f 'credentials/credential_factory.c' || echo '$(srcdir)/'`credentials/credential_factory.c +@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/credential_factory.Tpo $(DEPDIR)/credential_factory.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='credentials/credential_factory.c' object='credential_factory.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o pkcs9.lo `test -f 'crypto/pkcs9.c' || echo '$(srcdir)/'`crypto/pkcs9.c +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o credential_factory.lo `test -f 'credentials/credential_factory.c' || echo '$(srcdir)/'`credentials/credential_factory.c -fips_prf.lo: crypto/prfs/fips_prf.c -@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT fips_prf.lo -MD -MP -MF $(DEPDIR)/fips_prf.Tpo -c -o fips_prf.lo `test -f 'crypto/prfs/fips_prf.c' || echo '$(srcdir)/'`crypto/prfs/fips_prf.c -@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/fips_prf.Tpo $(DEPDIR)/fips_prf.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='crypto/prfs/fips_prf.c' object='fips_prf.lo' libtool=yes @AMDEPBACKSLASH@ +builder.lo: credentials/builder.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT builder.lo -MD -MP -MF $(DEPDIR)/builder.Tpo -c -o builder.lo `test -f 'credentials/builder.c' || echo '$(srcdir)/'`credentials/builder.c +@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/builder.Tpo $(DEPDIR)/builder.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='credentials/builder.c' object='builder.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o fips_prf.lo `test -f 'crypto/prfs/fips_prf.c' || echo '$(srcdir)/'`crypto/prfs/fips_prf.c +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o builder.lo `test -f 'credentials/builder.c' || echo '$(srcdir)/'`credentials/builder.c -hmac_prf.lo: crypto/prfs/hmac_prf.c -@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT hmac_prf.lo -MD -MP -MF $(DEPDIR)/hmac_prf.Tpo -c -o hmac_prf.lo `test -f 'crypto/prfs/hmac_prf.c' || echo '$(srcdir)/'`crypto/prfs/hmac_prf.c -@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/hmac_prf.Tpo $(DEPDIR)/hmac_prf.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='crypto/prfs/hmac_prf.c' object='hmac_prf.lo' libtool=yes @AMDEPBACKSLASH@ +private_key.lo: credentials/keys/private_key.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT private_key.lo -MD -MP -MF $(DEPDIR)/private_key.Tpo -c -o private_key.lo `test -f 'credentials/keys/private_key.c' || echo '$(srcdir)/'`credentials/keys/private_key.c +@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/private_key.Tpo $(DEPDIR)/private_key.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='credentials/keys/private_key.c' object='private_key.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o hmac_prf.lo `test -f 'crypto/prfs/hmac_prf.c' || echo '$(srcdir)/'`crypto/prfs/hmac_prf.c +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o private_key.lo `test -f 'credentials/keys/private_key.c' || echo '$(srcdir)/'`credentials/keys/private_key.c -prf.lo: crypto/prfs/prf.c -@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT prf.lo -MD -MP -MF $(DEPDIR)/prf.Tpo -c -o prf.lo `test -f 'crypto/prfs/prf.c' || echo '$(srcdir)/'`crypto/prfs/prf.c -@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/prf.Tpo $(DEPDIR)/prf.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='crypto/prfs/prf.c' object='prf.lo' libtool=yes @AMDEPBACKSLASH@ +public_key.lo: credentials/keys/public_key.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT public_key.lo -MD -MP -MF $(DEPDIR)/public_key.Tpo -c -o public_key.lo `test -f 'credentials/keys/public_key.c' || echo '$(srcdir)/'`credentials/keys/public_key.c +@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/public_key.Tpo $(DEPDIR)/public_key.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='credentials/keys/public_key.c' object='public_key.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o prf.lo `test -f 'crypto/prfs/prf.c' || echo '$(srcdir)/'`crypto/prfs/prf.c +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o public_key.lo `test -f 'credentials/keys/public_key.c' || echo '$(srcdir)/'`credentials/keys/public_key.c -prf_plus.lo: crypto/prf_plus.c -@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT prf_plus.lo -MD -MP -MF $(DEPDIR)/prf_plus.Tpo -c -o prf_plus.lo `test -f 'crypto/prf_plus.c' || echo '$(srcdir)/'`crypto/prf_plus.c -@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/prf_plus.Tpo $(DEPDIR)/prf_plus.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='crypto/prf_plus.c' object='prf_plus.lo' libtool=yes @AMDEPBACKSLASH@ +shared_key.lo: credentials/keys/shared_key.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT shared_key.lo -MD -MP -MF $(DEPDIR)/shared_key.Tpo -c -o shared_key.lo `test -f 'credentials/keys/shared_key.c' || echo '$(srcdir)/'`credentials/keys/shared_key.c +@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/shared_key.Tpo $(DEPDIR)/shared_key.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='credentials/keys/shared_key.c' object='shared_key.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o prf_plus.lo `test -f 'crypto/prf_plus.c' || echo '$(srcdir)/'`crypto/prf_plus.c +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o shared_key.lo `test -f 'credentials/keys/shared_key.c' || echo '$(srcdir)/'`credentials/keys/shared_key.c -rsa_private_key.lo: crypto/rsa/rsa_private_key.c -@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT rsa_private_key.lo -MD -MP -MF $(DEPDIR)/rsa_private_key.Tpo -c -o rsa_private_key.lo `test -f 'crypto/rsa/rsa_private_key.c' || echo '$(srcdir)/'`crypto/rsa/rsa_private_key.c -@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/rsa_private_key.Tpo $(DEPDIR)/rsa_private_key.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='crypto/rsa/rsa_private_key.c' object='rsa_private_key.lo' libtool=yes @AMDEPBACKSLASH@ +certificate.lo: credentials/certificates/certificate.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT certificate.lo -MD -MP -MF $(DEPDIR)/certificate.Tpo -c -o certificate.lo `test -f 'credentials/certificates/certificate.c' || echo '$(srcdir)/'`credentials/certificates/certificate.c +@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/certificate.Tpo $(DEPDIR)/certificate.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='credentials/certificates/certificate.c' object='certificate.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o rsa_private_key.lo `test -f 'crypto/rsa/rsa_private_key.c' || echo '$(srcdir)/'`crypto/rsa/rsa_private_key.c +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o certificate.lo `test -f 'credentials/certificates/certificate.c' || echo '$(srcdir)/'`credentials/certificates/certificate.c -rsa_public_key.lo: crypto/rsa/rsa_public_key.c -@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT rsa_public_key.lo -MD -MP -MF $(DEPDIR)/rsa_public_key.Tpo -c -o rsa_public_key.lo `test -f 'crypto/rsa/rsa_public_key.c' || echo '$(srcdir)/'`crypto/rsa/rsa_public_key.c -@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/rsa_public_key.Tpo $(DEPDIR)/rsa_public_key.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='crypto/rsa/rsa_public_key.c' object='rsa_public_key.lo' libtool=yes @AMDEPBACKSLASH@ +x509.lo: credentials/certificates/x509.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT x509.lo -MD -MP -MF $(DEPDIR)/x509.Tpo -c -o x509.lo `test -f 'credentials/certificates/x509.c' || echo '$(srcdir)/'`credentials/certificates/x509.c +@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/x509.Tpo $(DEPDIR)/x509.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='credentials/certificates/x509.c' object='x509.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o rsa_public_key.lo `test -f 'crypto/rsa/rsa_public_key.c' || echo '$(srcdir)/'`crypto/rsa/rsa_public_key.c +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o x509.lo `test -f 'credentials/certificates/x509.c' || echo '$(srcdir)/'`credentials/certificates/x509.c -hmac_signer.lo: crypto/signers/hmac_signer.c -@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT hmac_signer.lo -MD -MP -MF $(DEPDIR)/hmac_signer.Tpo -c -o hmac_signer.lo `test -f 'crypto/signers/hmac_signer.c' || echo '$(srcdir)/'`crypto/signers/hmac_signer.c -@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/hmac_signer.Tpo $(DEPDIR)/hmac_signer.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='crypto/signers/hmac_signer.c' object='hmac_signer.lo' libtool=yes @AMDEPBACKSLASH@ +crl.lo: credentials/certificates/crl.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT crl.lo -MD -MP -MF $(DEPDIR)/crl.Tpo -c -o crl.lo `test -f 'credentials/certificates/crl.c' || echo '$(srcdir)/'`credentials/certificates/crl.c +@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/crl.Tpo $(DEPDIR)/crl.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='credentials/certificates/crl.c' object='crl.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o hmac_signer.lo `test -f 'crypto/signers/hmac_signer.c' || echo '$(srcdir)/'`crypto/signers/hmac_signer.c +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o crl.lo `test -f 'credentials/certificates/crl.c' || echo '$(srcdir)/'`credentials/certificates/crl.c -signer.lo: crypto/signers/signer.c -@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT signer.lo -MD -MP -MF $(DEPDIR)/signer.Tpo -c -o signer.lo `test -f 'crypto/signers/signer.c' || echo '$(srcdir)/'`crypto/signers/signer.c -@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/signer.Tpo $(DEPDIR)/signer.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='crypto/signers/signer.c' object='signer.lo' libtool=yes @AMDEPBACKSLASH@ +ocsp_response.lo: credentials/certificates/ocsp_response.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT ocsp_response.lo -MD -MP -MF $(DEPDIR)/ocsp_response.Tpo -c -o ocsp_response.lo `test -f 'credentials/certificates/ocsp_response.c' || echo '$(srcdir)/'`credentials/certificates/ocsp_response.c +@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/ocsp_response.Tpo $(DEPDIR)/ocsp_response.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='credentials/certificates/ocsp_response.c' object='ocsp_response.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o signer.lo `test -f 'crypto/signers/signer.c' || echo '$(srcdir)/'`crypto/signers/signer.c +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o ocsp_response.lo `test -f 'credentials/certificates/ocsp_response.c' || echo '$(srcdir)/'`credentials/certificates/ocsp_response.c -x509.lo: crypto/x509.c -@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT x509.lo -MD -MP -MF $(DEPDIR)/x509.Tpo -c -o x509.lo `test -f 'crypto/x509.c' || echo '$(srcdir)/'`crypto/x509.c -@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/x509.Tpo $(DEPDIR)/x509.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='crypto/x509.c' object='x509.lo' libtool=yes @AMDEPBACKSLASH@ +fetcher_manager.lo: fetcher/fetcher_manager.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT fetcher_manager.lo -MD -MP -MF $(DEPDIR)/fetcher_manager.Tpo -c -o fetcher_manager.lo `test -f 'fetcher/fetcher_manager.c' || echo '$(srcdir)/'`fetcher/fetcher_manager.c +@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/fetcher_manager.Tpo $(DEPDIR)/fetcher_manager.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='fetcher/fetcher_manager.c' object='fetcher_manager.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o x509.lo `test -f 'crypto/x509.c' || echo '$(srcdir)/'`crypto/x509.c +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o fetcher_manager.lo `test -f 'fetcher/fetcher_manager.c' || echo '$(srcdir)/'`fetcher/fetcher_manager.c -fetcher.lo: utils/fetcher.c -@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT fetcher.lo -MD -MP -MF $(DEPDIR)/fetcher.Tpo -c -o fetcher.lo `test -f 'utils/fetcher.c' || echo '$(srcdir)/'`utils/fetcher.c -@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/fetcher.Tpo $(DEPDIR)/fetcher.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='utils/fetcher.c' object='fetcher.lo' libtool=yes @AMDEPBACKSLASH@ +database_factory.lo: database/database_factory.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT database_factory.lo -MD -MP -MF $(DEPDIR)/database_factory.Tpo -c -o database_factory.lo `test -f 'database/database_factory.c' || echo '$(srcdir)/'`database/database_factory.c +@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/database_factory.Tpo $(DEPDIR)/database_factory.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='database/database_factory.c' object='database_factory.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o fetcher.lo `test -f 'utils/fetcher.c' || echo '$(srcdir)/'`utils/fetcher.c +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o database_factory.lo `test -f 'database/database_factory.c' || echo '$(srcdir)/'`database/database_factory.c host.lo: utils/host.c @am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT host.lo -MD -MP -MF $(DEPDIR)/host.Tpo -c -o host.lo `test -f 'utils/host.c' || echo '$(srcdir)/'`utils/host.c @@ -803,13 +796,6 @@ identification.lo: utils/identification.c @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o identification.lo `test -f 'utils/identification.c' || echo '$(srcdir)/'`utils/identification.c -leak_detective.lo: utils/leak_detective.c -@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT leak_detective.lo -MD -MP -MF $(DEPDIR)/leak_detective.Tpo -c -o leak_detective.lo `test -f 'utils/leak_detective.c' || echo '$(srcdir)/'`utils/leak_detective.c -@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/leak_detective.Tpo $(DEPDIR)/leak_detective.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='utils/leak_detective.c' object='leak_detective.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o leak_detective.lo `test -f 'utils/leak_detective.c' || echo '$(srcdir)/'`utils/leak_detective.c - lexparser.lo: utils/lexparser.c @am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT lexparser.lo -MD -MP -MF $(DEPDIR)/lexparser.Tpo -c -o lexparser.lo `test -f 'utils/lexparser.c' || echo '$(srcdir)/'`utils/lexparser.c @am__fastdepCC_TRUE@ mv -f $(DEPDIR)/lexparser.Tpo $(DEPDIR)/lexparser.Plo @@ -838,12 +824,26 @@ optionsfrom.lo: utils/optionsfrom.c @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o optionsfrom.lo `test -f 'utils/optionsfrom.c' || echo '$(srcdir)/'`utils/optionsfrom.c -randomizer.lo: utils/randomizer.c -@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT randomizer.lo -MD -MP -MF $(DEPDIR)/randomizer.Tpo -c -o randomizer.lo `test -f 'utils/randomizer.c' || echo '$(srcdir)/'`utils/randomizer.c -@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/randomizer.Tpo $(DEPDIR)/randomizer.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='utils/randomizer.c' object='randomizer.lo' libtool=yes @AMDEPBACKSLASH@ +mutex.lo: utils/mutex.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT mutex.lo -MD -MP -MF $(DEPDIR)/mutex.Tpo -c -o mutex.lo `test -f 'utils/mutex.c' || echo '$(srcdir)/'`utils/mutex.c +@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/mutex.Tpo $(DEPDIR)/mutex.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='utils/mutex.c' object='mutex.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o randomizer.lo `test -f 'utils/randomizer.c' || echo '$(srcdir)/'`utils/randomizer.c +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o mutex.lo `test -f 'utils/mutex.c' || echo '$(srcdir)/'`utils/mutex.c + +plugin_loader.lo: plugins/plugin_loader.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT plugin_loader.lo -MD -MP -MF $(DEPDIR)/plugin_loader.Tpo -c -o plugin_loader.lo `test -f 'plugins/plugin_loader.c' || echo '$(srcdir)/'`plugins/plugin_loader.c +@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/plugin_loader.Tpo $(DEPDIR)/plugin_loader.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='plugins/plugin_loader.c' object='plugin_loader.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o plugin_loader.lo `test -f 'plugins/plugin_loader.c' || echo '$(srcdir)/'`plugins/plugin_loader.c + +leak_detective.lo: utils/leak_detective.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT leak_detective.lo -MD -MP -MF $(DEPDIR)/leak_detective.Tpo -c -o leak_detective.lo `test -f 'utils/leak_detective.c' || echo '$(srcdir)/'`utils/leak_detective.c +@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/leak_detective.Tpo $(DEPDIR)/leak_detective.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='utils/leak_detective.c' object='leak_detective.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o leak_detective.lo `test -f 'utils/leak_detective.c' || echo '$(srcdir)/'`utils/leak_detective.c fips_canister_start.lo: fips/fips_canister_start.c @am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT fips_canister_start.lo -MD -MP -MF $(DEPDIR)/fips_canister_start.Tpo -c -o fips_canister_start.lo `test -f 'fips/fips_canister_start.c' || echo '$(srcdir)/'`fips/fips_canister_start.c @@ -886,42 +886,124 @@ mostlyclean-libtool: clean-libtool: -rm -rf .libs _libs +# This directory's subdirectories are mostly independent; you can cd +# into them and run `make' without going through this Makefile. +# To change the values of `make' variables: instead of editing Makefiles, +# (1) if the variable is set in `config.status', edit `config.status' +# (which will cause the Makefiles to be regenerated when you run `make'); +# (2) otherwise, pass the desired values on the `make' command line. +$(RECURSIVE_TARGETS): + @failcom='exit 1'; \ + for f in x $$MAKEFLAGS; do \ + case $$f in \ + *=* | --[!k]*);; \ + *k*) failcom='fail=yes';; \ + esac; \ + done; \ + dot_seen=no; \ + target=`echo $@ | sed s/-recursive//`; \ + list='$(SUBDIRS)'; for subdir in $$list; do \ + echo "Making $$target in $$subdir"; \ + if test "$$subdir" = "."; then \ + dot_seen=yes; \ + local_target="$$target-am"; \ + else \ + local_target="$$target"; \ + fi; \ + (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ + || eval $$failcom; \ + done; \ + if test "$$dot_seen" = "no"; then \ + $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ + fi; test -z "$$fail" + +$(RECURSIVE_CLEAN_TARGETS): + @failcom='exit 1'; \ + for f in x $$MAKEFLAGS; do \ + case $$f in \ + *=* | --[!k]*);; \ + *k*) failcom='fail=yes';; \ + esac; \ + done; \ + dot_seen=no; \ + case "$@" in \ + distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ + *) list='$(SUBDIRS)' ;; \ + esac; \ + rev=''; for subdir in $$list; do \ + if test "$$subdir" = "."; then :; else \ + rev="$$subdir $$rev"; \ + fi; \ + done; \ + rev="$$rev ."; \ + target=`echo $@ | sed s/-recursive//`; \ + for subdir in $$rev; do \ + echo "Making $$target in $$subdir"; \ + if test "$$subdir" = "."; then \ + local_target="$$target-am"; \ + else \ + local_target="$$target"; \ + fi; \ + (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ + || eval $$failcom; \ + done && test -z "$$fail" +tags-recursive: + list='$(SUBDIRS)'; for subdir in $$list; do \ + test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \ + done +ctags-recursive: + list='$(SUBDIRS)'; for subdir in $$list; do \ + test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) ctags); \ + done + 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; } \ - END { for (i in files) print i; }'`; \ + $(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: tags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) tags=; \ here=`pwd`; \ + if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ + include_option=--etags-include; \ + empty_fix=.; \ + else \ + include_option=--include; \ + empty_fix=; \ + fi; \ + list='$(SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + test ! -f $$subdir/TAGS || \ + tags="$$tags $$include_option=$$here/$$subdir/TAGS"; \ + fi; \ + done; \ 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; } \ - END { for (i in files) print i; }'`; \ + $(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) \ +CTAGS: ctags-recursive $(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; } \ - END { for (i in files) print i; }'`; \ + $(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 @@ -960,24 +1042,42 @@ distdir: $(DISTFILES) || exit 1; \ fi; \ done + list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + test -d "$(distdir)/$$subdir" \ + || $(MKDIR_P) "$(distdir)/$$subdir" \ + || exit 1; \ + distdir=`$(am__cd) $(distdir) && pwd`; \ + top_distdir=`$(am__cd) $(top_distdir) && pwd`; \ + (cd $$subdir && \ + $(MAKE) $(AM_MAKEFLAGS) \ + top_distdir="$$top_distdir" \ + distdir="$$distdir/$$subdir" \ + am__remove_distdir=: \ + am__skip_length_check=: \ + distdir) \ + || exit 1; \ + fi; \ + done check-am: all-am check: $(BUILT_SOURCES) - $(MAKE) $(AM_MAKEFLAGS) check-am + $(MAKE) $(AM_MAKEFLAGS) check-recursive all-am: Makefile $(LTLIBRARIES) $(PROGRAMS) -installdirs: +installdirs: installdirs-recursive +installdirs-am: for dir in "$(DESTDIR)$(libdir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: $(BUILT_SOURCES) - $(MAKE) $(AM_MAKEFLAGS) install-am -install-exec: install-exec-am -install-data: install-data-am -uninstall: uninstall-am + $(MAKE) $(AM_MAKEFLAGS) install-recursive +install-exec: install-exec-recursive +install-data: install-data-recursive +uninstall: uninstall-recursive install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am -installcheck: installcheck-am +installcheck: installcheck-recursive install-strip: $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ @@ -996,80 +1096,83 @@ maintainer-clean-generic: @echo "it deletes files that may require special tools to rebuild." -test -z "$(BUILT_SOURCES)" || rm -f $(BUILT_SOURCES) -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES) -clean: clean-am +clean: clean-recursive clean-am: clean-generic clean-libLTLIBRARIES clean-libtool \ clean-noinstPROGRAMS mostlyclean-am -distclean: distclean-am +distclean: distclean-recursive -rm -rf ./$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags -dvi: dvi-am +dvi: dvi-recursive dvi-am: -html: html-am +html: html-recursive -info: info-am +info: info-recursive info-am: install-data-am: -install-dvi: install-dvi-am +install-dvi: install-dvi-recursive install-exec-am: install-libLTLIBRARIES -install-html: install-html-am +install-html: install-html-recursive -install-info: install-info-am +install-info: install-info-recursive install-man: -install-pdf: install-pdf-am +install-pdf: install-pdf-recursive -install-ps: install-ps-am +install-ps: install-ps-recursive installcheck-am: -maintainer-clean: maintainer-clean-am +maintainer-clean: maintainer-clean-recursive -rm -rf ./$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic -mostlyclean: mostlyclean-am +mostlyclean: mostlyclean-recursive mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool -pdf: pdf-am +pdf: pdf-recursive pdf-am: -ps: ps-am +ps: ps-recursive ps-am: uninstall-am: uninstall-libLTLIBRARIES -.MAKE: install-am install-strip +.MAKE: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) install-am \ + install-strip -.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ +.PHONY: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) CTAGS GTAGS \ + all all-am check check-am clean clean-generic \ clean-libLTLIBRARIES clean-libtool clean-noinstPROGRAMS ctags \ - distclean distclean-compile distclean-generic \ + ctags-recursive 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-libLTLIBRARIES install-man install-pdf \ install-pdf-am install-ps install-ps-am install-strip \ - installcheck installcheck-am installdirs maintainer-clean \ - maintainer-clean-generic mostlyclean mostlyclean-compile \ - mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ - tags uninstall uninstall-am uninstall-libLTLIBRARIES + installcheck installcheck-am installdirs installdirs-am \ + maintainer-clean maintainer-clean-generic mostlyclean \ + mostlyclean-compile mostlyclean-generic mostlyclean-libtool \ + pdf pdf-am ps ps-am tags tags-recursive uninstall uninstall-am \ + uninstall-libLTLIBRARIES asn1/oid.c : asn1/oid.txt asn1/oid.pl diff --git a/src/libstrongswan/asn1/asn1.c b/src/libstrongswan/asn1/asn1.c index 3f0b829a9..524abfe5e 100644 --- a/src/libstrongswan/asn1/asn1.c +++ b/src/libstrongswan/asn1/asn1.c @@ -1,10 +1,3 @@ -/** - * @file asn1.c - * - * @brief Simple ASN.1 parser - * - */ - /* * Copyright (C) 2006 Martin Will * Copyright (C) 2000-2008 Andreas Steffen @@ -21,19 +14,23 @@ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * - * RCSID $Id: asn1.c 3451 2008-02-05 19:27:05Z andreas $ + * $Id: asn1.c 4047 2008-06-10 07:36:44Z tobias $ */ #include <stdio.h> #include <string.h> #include <time.h> -#include "asn1.h" - #include <library.h> #include <debug.h> -/* some common prefabricated ASN.1 constants */ +#include "oid.h" +#include "asn1.h" +#include "asn1_parser.h" + +/** + * some common prefabricated ASN.1 constants + */ static u_char ASN1_INTEGER_0_str[] = { 0x02, 0x00 }; static u_char ASN1_INTEGER_1_str[] = { 0x02, 0x01, 0x01 }; static u_char ASN1_INTEGER_2_str[] = { 0x02, 0x01, 0x02 }; @@ -42,7 +39,9 @@ const chunk_t ASN1_INTEGER_0 = chunk_from_buf(ASN1_INTEGER_0_str); const chunk_t ASN1_INTEGER_1 = chunk_from_buf(ASN1_INTEGER_1_str); const chunk_t ASN1_INTEGER_2 = chunk_from_buf(ASN1_INTEGER_2_str); -/* some popular algorithmIdentifiers */ +/** + * some popular algorithmIdentifiers + */ static u_char ASN1_md2_id_str[] = { 0x30, 0x0c, @@ -149,19 +148,8 @@ static const chunk_t ASN1_sha256WithRSA_id = chunk_from_buf(ASN1_sha256WithRSA_i static const chunk_t ASN1_sha384WithRSA_id = chunk_from_buf(ASN1_sha384WithRSA_id_str); static const chunk_t ASN1_sha512WithRSA_id = chunk_from_buf(ASN1_sha512WithRSA_id_str); -/* ASN.1 definiton of an algorithmIdentifier */ -static const asn1Object_t algorithmIdentifierObjects[] = { - { 0, "algorithmIdentifier", ASN1_SEQUENCE, ASN1_NONE }, /* 0 */ - { 1, "algorithm", ASN1_OID, ASN1_BODY }, /* 1 */ - { 1, "parameters", ASN1_EOC, ASN1_RAW } /* 2 */ -}; - -#define ALGORITHM_ID_ALG 1 -#define ALGORITHM_ID_PARAMETERS 2 -#define ALGORITHM_ID_ROOF 3 - -/** - * return the ASN.1 encoded algorithm identifier +/* + * Defined in header. */ chunk_t asn1_algorithmIdentifier(int oid) { @@ -198,11 +186,10 @@ chunk_t asn1_algorithmIdentifier(int oid) } } -/** - * If the oid is listed in the oid_names table then the corresponding - * position in the oid_names table is returned otherwise -1 is returned +/* + * Defined in header. */ -int known_oid(chunk_t object) +int asn1_known_oid(chunk_t object) { int oid = 0; @@ -230,8 +217,8 @@ int known_oid(chunk_t object) return -1; } -/** - * Decodes the length in bytes of an ASN.1 object +/* + * Defined in header. */ u_int asn1_length(chunk_t *blob) { @@ -278,26 +265,9 @@ u_int asn1_length(chunk_t *blob) } /** - * determines if a character string is of type ASN.1 printableString - */ -bool is_printablestring(chunk_t str) -{ - const char printablestring_charset[] = - "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789 '()+,-./:=?"; - u_int i; - - for (i = 0; i < str.len; i++) - { - if (strchr(printablestring_charset, str.ptr[i]) == NULL) - return FALSE; - } - return TRUE; -} - -/** * Converts ASN.1 UTCTIME or GENERALIZEDTIME into calender time */ -time_t asn1totime(const chunk_t *utctime, asn1_t type) +time_t asn1_to_time(const chunk_t *utctime, asn1_t type) { struct tm t; time_t tz_offset; @@ -372,7 +342,7 @@ time_t asn1totime(const chunk_t *utctime, asn1_t type) /** * Convert a date into ASN.1 UTCTIME or GENERALIZEDTIME format */ -chunk_t timetoasn1(const time_t *time, asn1_t type) +chunk_t asn1_from_time(const time_t *time, asn1_t type) { int offset; const char *format; @@ -397,31 +367,17 @@ chunk_t timetoasn1(const time_t *time, asn1_t type) return asn1_simple_object(type, formatted_time); } - -/** - * Initializes the internal context of the ASN.1 parser - */ -void asn1_init(asn1_ctx_t *ctx, chunk_t blob, u_int level0, - bool implicit, bool private) -{ - ctx->blobs[0] = blob; - ctx->level0 = level0; - ctx->implicit = implicit; - ctx->private = private; - memset(ctx->loopAddr, '\0', sizeof(ctx->loopAddr)); -} - -/** - * print the value of an ASN.1 simple object +/* + * Defined in header. */ -static void debug_asn1_simple_object(chunk_t object, asn1_t type, bool private) +void asn1_debug_simple_object(chunk_t object, asn1_t type, bool private) { int oid; switch (type) { case ASN1_OID: - oid = known_oid(object); + oid = asn1_known_oid(object); if (oid != OID_UNKNOWN) { DBG2(" '%s'", oid_names[oid].name); @@ -438,7 +394,7 @@ static void debug_asn1_simple_object(chunk_t object, asn1_t type, bool private) case ASN1_UTCTIME: case ASN1_GENERALIZEDTIME: { - time_t time = asn1totime(&object, type); + time_t time = asn1_to_time(&object, type); DBG2(" '%T'", &time); } @@ -457,147 +413,9 @@ static void debug_asn1_simple_object(chunk_t object, asn1_t type, bool private) } /** - * Parses and extracts the next ASN.1 object - */ -bool extract_object(asn1Object_t const *objects, u_int *objectID, chunk_t *object, u_int *level, asn1_ctx_t *ctx) -{ - asn1Object_t obj = objects[*objectID]; - chunk_t *blob; - chunk_t *blob1; - u_char *start_ptr; - - *object = chunk_empty; - - if (obj.flags & ASN1_END) /* end of loop or option found */ - { - if (ctx->loopAddr[obj.level] && ctx->blobs[obj.level+1].len > 0) - { - *objectID = ctx->loopAddr[obj.level]; /* another iteration */ - obj = objects[*objectID]; - } - else - { - ctx->loopAddr[obj.level] = 0; /* exit loop or option*/ - return TRUE; - } - } - - *level = ctx->level0 + obj.level; - blob = ctx->blobs + obj.level; - blob1 = blob + 1; - start_ptr = blob->ptr; - - /* handle ASN.1 defaults values */ - if ((obj.flags & ASN1_DEF) && (blob->len == 0 || *start_ptr != obj.type) ) - { - /* field is missing */ - DBG2("L%d - %s:", *level, obj.name); - if (obj.type & ASN1_CONSTRUCTED) - { - (*objectID)++ ; /* skip context-specific tag */ - } - return TRUE; - } - - /* handle ASN.1 options */ - - if ((obj.flags & ASN1_OPT) - && (blob->len == 0 || *start_ptr != obj.type)) - { - /* advance to end of missing option field */ - do - (*objectID)++; - while (!((objects[*objectID].flags & ASN1_END) - && (objects[*objectID].level == obj.level))); - return TRUE; - } - - /* an ASN.1 object must possess at least a tag and length field */ - - if (blob->len < 2) - { - DBG1("L%d - %s: ASN.1 object smaller than 2 octets", - *level, obj.name); - return FALSE; - } - - blob1->len = asn1_length(blob); - - if (blob1->len == ASN1_INVALID_LENGTH || blob->len < blob1->len) - { - DBG1("L%d - %s: length of ASN.1 object invalid or too large", - *level, obj.name); - return FALSE; - } - - blob1->ptr = blob->ptr; - blob->ptr += blob1->len; - blob->len -= blob1->len; - - /* return raw ASN.1 object without prior type checking */ - - if (obj.flags & ASN1_RAW) - { - DBG2("L%d - %s:", *level, obj.name); - object->ptr = start_ptr; - object->len = (size_t)(blob->ptr - start_ptr); - return TRUE; - } - - if (*start_ptr != obj.type && !(ctx->implicit && *objectID == 0)) - { - DBG1("L%d - %s: ASN1 tag 0x%02x expected, but is 0x%02x", - *level, obj.name, obj.type, *start_ptr); - DBG3("%b", start_ptr, (u_int)(blob->ptr - start_ptr)); - return FALSE; - } - - DBG2("L%d - %s:", ctx->level0+obj.level, obj.name); - - /* In case of "SEQUENCE OF" or "SET OF" start a loop */ - if (obj.flags & ASN1_LOOP) - { - if (blob1->len > 0) - { - /* at least one item, start the loop */ - ctx->loopAddr[obj.level] = *objectID + 1; - } - else - { - /* no items, advance directly to end of loop */ - do - (*objectID)++; - while (!((objects[*objectID].flags & ASN1_END) - && (objects[*objectID].level == obj.level))); - return TRUE; - } - } - - if (obj.flags & ASN1_OBJ) - { - object->ptr = start_ptr; - object->len = (size_t)(blob->ptr - start_ptr); - if (ctx->private) - { - DBG4("%B", object); - } - else - { - DBG3("%B", object); - } - } - else if (obj.flags & ASN1_BODY) - { - *object = *blob1; - debug_asn1_simple_object(*object, obj.type, ctx->private); - } - return TRUE; -} - -/** * parse an ASN.1 simple type */ -bool parse_asn1_simple_object(chunk_t *object, asn1_t type, u_int level, const char* name) +bool asn1_parse_simple_object(chunk_t *object, asn1_t type, u_int level, const char* name) { size_t len; @@ -625,44 +443,69 @@ bool parse_asn1_simple_object(chunk_t *object, asn1_t type, u_int level, const c } DBG2("L%d - %s:", level, name); - debug_asn1_simple_object(*object, type, FALSE); + asn1_debug_simple_object(*object, type, FALSE); return TRUE; } /** - * extracts an algorithmIdentifier + * ASN.1 definition of an algorithmIdentifier + */ +static const asn1Object_t algorithmIdentifierObjects[] = { + { 0, "algorithmIdentifier", ASN1_SEQUENCE, ASN1_NONE }, /* 0 */ + { 1, "algorithm", ASN1_OID, ASN1_BODY }, /* 1 */ + { 1, "parameters", ASN1_EOC, ASN1_RAW }, /* 2 */ + { 0, "exit", ASN1_EOC, ASN1_EXIT } +}; +/* parameters are optional in case of ecdsa-with-SHA1 as algorithm (RFC 3279) */ +static const asn1Object_t algorithmIdentifierObjectsOptional[] = { + { 0, "algorithmIdentifier", ASN1_SEQUENCE, ASN1_NONE }, /* 0 */ + { 1, "algorithm", ASN1_OID, ASN1_BODY }, /* 1 */ + { 1, "parameters", ASN1_EOC, ASN1_RAW|ASN1_OPT }, /* 2 */ + { 1, "end opt", ASN1_EOC, ASN1_END }, /* 3 */ + { 0, "exit", ASN1_EOC, ASN1_EXIT } +}; +#define ALGORITHM_ID_ALG 1 +#define ALGORITHM_ID_PARAMETERS 2 + +/* + * Defined in header */ -int parse_algorithmIdentifier(chunk_t blob, int level0, chunk_t *parameters) +int asn1_parse_algorithmIdentifier(chunk_t blob, int level0, chunk_t *parameters) { - asn1_ctx_t ctx; + asn1_parser_t *parser; chunk_t object; - u_int level; + int objectID; int alg = OID_UNKNOWN; - int objectID = 0; + const asn1Object_t *objects = algorithmIdentifierObjectsOptional; - asn1_init(&ctx, blob, level0, FALSE, FALSE); + if (parameters != NULL) + { + objects = algorithmIdentifierObjects; + } + + parser = asn1_parser_create(objects, blob); + parser->set_top_level(parser, level0); - while (objectID < ALGORITHM_ID_ROOF) + while (parser->iterate(parser, &objectID, &object)) { - if (!extract_object(algorithmIdentifierObjects, &objectID, &object, &level, &ctx)) - return OID_UNKNOWN; - switch (objectID) { case ALGORITHM_ID_ALG: - alg = known_oid(object); + alg = asn1_known_oid(object); break; case ALGORITHM_ID_PARAMETERS: if (parameters != NULL) + { *parameters = object; + } break; default: break; } - objectID++; } + parser->destroy(parser); return alg; - } +} /* * tests if a blob contains a valid ASN.1 set or sequence @@ -696,10 +539,27 @@ bool is_asn1(chunk_t blob) return FALSE; } +/* + * Defined in header. + */ +bool asn1_is_printablestring(chunk_t str) +{ + const char printablestring_charset[] = + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789 '()+,-./:=?"; + u_int i; + + for (i = 0; i < str.len; i++) + { + if (strchr(printablestring_charset, str.ptr[i]) == NULL) + return FALSE; + } + return TRUE; +} + /** * codes ASN.1 lengths up to a size of 16'777'215 bytes */ -void code_asn1_length(size_t length, chunk_t *code) +static void asn1_code_length(size_t length, chunk_t *code) { if (length < 128) { @@ -732,14 +592,14 @@ void code_asn1_length(size_t length, chunk_t *code) /** * build an empty asn.1 object with tag and length fields already filled in */ -u_char* build_asn1_object(chunk_t *object, asn1_t type, size_t datalen) +u_char* asn1_build_object(chunk_t *object, asn1_t type, size_t datalen) { u_char length_buf[4]; chunk_t length = { length_buf, 0 }; u_char *pos; /* code the asn.1 length field */ - code_asn1_length(datalen, &length); + asn1_code_length(datalen, &length); /* allocate memory for the asn.1 TLV object */ object->len = 1 + length.len + datalen; @@ -759,13 +619,13 @@ u_char* build_asn1_object(chunk_t *object, asn1_t type, size_t datalen) } /** - * build a simple ASN.1 object + * Build a simple ASN.1 object */ chunk_t asn1_simple_object(asn1_t tag, chunk_t content) { chunk_t object; - u_char *pos = build_asn1_object(&object, tag, content.len); + u_char *pos = asn1_build_object(&object, tag, content.len); memcpy(pos, content.ptr, content.len); pos += content.len; @@ -778,7 +638,7 @@ chunk_t asn1_simple_object(asn1_t tag, chunk_t content) chunk_t asn1_bitstring(const char *mode, chunk_t content) { chunk_t object; - u_char *pos = build_asn1_object(&object, ASN1_BIT_STRING, 1 + content.len); + u_char *pos = asn1_build_object(&object, ASN1_BIT_STRING, 1 + content.len); *pos++ = 0x00; memcpy(pos, content.ptr, content.len); @@ -812,7 +672,7 @@ chunk_t asn1_wrap(asn1_t type, const char *mode, ...) va_end(chunks); /* allocate needed memory for construct */ - pos = build_asn1_object(&construct, type, construct.len); + pos = asn1_build_object(&construct, type, construct.len); /* copy or move the chunks */ va_start(chunks, mode); @@ -834,55 +694,39 @@ chunk_t asn1_wrap(asn1_t type, const char *mode, ...) } /** - * convert a MP integer into a DER coded ASN.1 object - */ -chunk_t asn1_integer_from_mpz(const mpz_t value) -{ - size_t bits = mpz_sizeinbase(value, 2); /* size in bits */ - chunk_t n; - - n.len = 1 + bits / 8; /* size in bytes */ - n.ptr = mpz_export(NULL, NULL, 1, n.len, 1, 0, value); - - return asn1_wrap(ASN1_INTEGER, "m", n); -} - -/** * ASN.1 definition of time */ static const asn1Object_t timeObjects[] = { - { 0, "utcTime", ASN1_UTCTIME, ASN1_OPT|ASN1_BODY }, /* 0 */ - { 0, "end opt", ASN1_EOC, ASN1_END }, /* 1 */ - { 0, "generalizeTime",ASN1_GENERALIZEDTIME, ASN1_OPT|ASN1_BODY }, /* 2 */ - { 0, "end opt", ASN1_EOC, ASN1_END } /* 3 */ + { 0, "utcTime", ASN1_UTCTIME, ASN1_OPT|ASN1_BODY }, /* 0 */ + { 0, "end opt", ASN1_EOC, ASN1_END }, /* 1 */ + { 0, "generalizeTime", ASN1_GENERALIZEDTIME, ASN1_OPT|ASN1_BODY }, /* 2 */ + { 0, "end opt", ASN1_EOC, ASN1_END }, /* 3 */ + { 0, "exit", ASN1_EOC, ASN1_EXIT } }; #define TIME_UTC 0 #define TIME_GENERALIZED 2 -#define TIME_ROOF 4 /** * extracts and converts a UTCTIME or GENERALIZEDTIME object */ -time_t parse_time(chunk_t blob, int level0) +time_t asn1_parse_time(chunk_t blob, int level0) { - asn1_ctx_t ctx; + asn1_parser_t *parser; chunk_t object; - u_int level; - int objectID = 0; + int objectID; + time_t utc_time = 0; - asn1_init(&ctx, blob, level0, FALSE, FALSE); + parser= asn1_parser_create(timeObjects, blob); + parser->set_top_level(parser, level0); - while (objectID < TIME_ROOF) + while (parser->iterate(parser, &objectID, &object)) { - if (!extract_object(timeObjects, &objectID, &object, &level, &ctx)) - return 0; - if (objectID == TIME_UTC || objectID == TIME_GENERALIZED) { - return asn1totime(&object, (objectID == TIME_UTC) - ? ASN1_UTCTIME : ASN1_GENERALIZEDTIME); + utc_time = asn1_to_time(&object, (objectID == TIME_UTC) + ? ASN1_UTCTIME : ASN1_GENERALIZEDTIME); } - objectID++; } - return 0; + parser->destroy(parser); + return utc_time; } diff --git a/src/libstrongswan/asn1/asn1.h b/src/libstrongswan/asn1/asn1.h index d9d85ba44..0f2e6e5c0 100644 --- a/src/libstrongswan/asn1/asn1.h +++ b/src/libstrongswan/asn1/asn1.h @@ -1,10 +1,3 @@ -/** - * @file asn1.h - * - * @brief Simple ASN.1 parser - * - */ - /* * Copyright (C) 2006 Martin Will * Copyright (C) 2000-2008 Andreas Steffen @@ -21,23 +14,23 @@ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * - * RCSID $Id: asn1.h 3423 2008-01-22 10:32:37Z andreas $ + * $Id: asn1.h 3876 2008-04-26 09:24:14Z andreas $ + */ + +/** + * @defgroup asn1i asn1 + * @{ @ingroup asn1 */ -#ifndef _ASN1_H -#define _ASN1_H +#ifndef ASN1_H_ +#define ASN1_H_ #include <stdarg.h> -#include <gmp.h> #include <library.h> -#include <asn1/oid.h> - /** - * @brief Definition of some primitive ASN1 types - * - * @ingroup asn1 + * Definition of some primitive ASN1 types */ typedef enum { ASN1_EOC = 0x00, @@ -65,7 +58,6 @@ typedef enum { ASN1_CONSTRUCTED = 0x20, ASN1_SEQUENCE = 0x30, - ASN1_SET = 0x31, ASN1_CONTEXT_S_0 = 0x80, @@ -86,64 +78,155 @@ typedef enum { ASN1_CONTEXT_C_5 = 0xA5 } asn1_t; -/* Definition of ASN1 flags */ +#define ASN1_INVALID_LENGTH 0xffffffff -#define ASN1_NONE 0x00 -#define ASN1_DEF 0x01 -#define ASN1_OPT 0x02 -#define ASN1_LOOP 0x04 -#define ASN1_END 0x08 -#define ASN1_OBJ 0x10 -#define ASN1_BODY 0x20 -#define ASN1_RAW 0x40 +/** + * Some common prefabricated ASN.1 constants + */ +extern const chunk_t ASN1_INTEGER_0; +extern const chunk_t ASN1_INTEGER_1; +extern const chunk_t ASN1_INTEGER_2; -#define ASN1_INVALID_LENGTH 0xffffffff -/* definition of an ASN.1 object */ +/** Some ASN.1 analysis functions */ -typedef struct { - u_int level; - const u_char *name; - asn1_t type; - u_char flags; -} asn1Object_t; +/** + * Returns some popular algorithmIdentifiers + * + * @param oid known OID index + * @return body of the corresponding OID + */ +chunk_t asn1_algorithmIdentifier(int oid); -#define ASN1_MAX_LEVEL 10 +/** + * Converts an ASN.1 OID into a known OID index + * + * @param object body of an OID + * @return index into the oid_names[] table or OID_UNKNOWN + */ +int asn1_known_oid(chunk_t object); -typedef struct { - bool implicit; - bool private; - u_int level0; - u_int loopAddr[ASN1_MAX_LEVEL+1]; - chunk_t blobs[ASN1_MAX_LEVEL+2]; -} asn1_ctx_t; +/** + * Returns the length of an ASN.1 object + * The blob pointer is advanced past the tag length fields + * + * @param pointer to an ASN.1 coded blob + * @return length of ASN.1 object + */ +u_int asn1_length(chunk_t *blob); -/* some common prefabricated ASN.1 constants */ -extern const chunk_t ASN1_INTEGER_0; -extern const chunk_t ASN1_INTEGER_1; -extern const chunk_t ASN1_INTEGER_2; +/** + * Parses an ASN.1 algorithmIdentifier object + * + * @param blob ASN.1 coded blob + * @param level0 top-most level offset + * @param params returns optional [ASN.1 coded] parameters + * @return known OID index or OID_UNKNOWN + */ +int asn1_parse_algorithmIdentifier(chunk_t blob, int level0, chunk_t *params); + +/** + * Parse the top-most level of an ASN.1 object + * + * @param object ASN.1 coded object + * @param type Expected ASN.1 type + * @param level0 top-most level offset + * @param name descriptive name of object + * @return TRUE if parsing successful + */ +bool asn1_parse_simple_object(chunk_t *object, asn1_t type, u_int level0, + const char* name); + +/** + * Print the value of an ASN.1 simple object + * + * @param object ASN.1 object to be printed + * @param type asn1_t type + * @param private ASN.1 data is confidential (use debug level 4) + */ +void asn1_debug_simple_object(chunk_t object, asn1_t type, bool private); + +/** + * Converts an ASN.1 UTCTIME or GENERALIZEDTIME string to time_t + * + * @param utctime body of an ASN.1 coded time object + * @param type ASN1_UTCTIME or ASN1_GENERALIZEDTIME + * @return time_t in UTC + */ +time_t asn1_to_time(const chunk_t *utctime, asn1_t type); + +/** + * Converts time_t to an ASN.1 UTCTIME or GENERALIZEDTIME string + * + * @param time time_t in UTC + * @param type ASN1_UTCTIME or ASN1_GENERALIZEDTIME + * @return body of an ASN.1 code time object + */ +chunk_t asn1_from_time(const time_t *time, asn1_t type); + +/** + * Parse an ASN.1 UTCTIME or GENERALIZEDTIME object + * + * @param blob ASN.1 coded time object + * @param level top-most level offset + * @return time_t in UTC + */ +time_t asn1_parse_time(chunk_t blob, int level0); + +/** + * Determines if a binary blob is ASN.1 coded + * + * @param blob blob to be tested + * @return TRUE if blob is ASN.1 coded (SEQUENCE or SET) + */ +bool is_asn1(chunk_t blob); + +/** + * Determines if a character string can be coded as PRINTABLESTRING + * + * @param str character string to be tested + * @return TRUE if no special characters are contained + */ +bool asn1_is_printablestring(chunk_t str); + + +/** some ASN.1 synthesis functions */ + +/** + * Build an empty ASN.1 object with tag and length fields already filled in + * + * @param object returned object - memory is allocated by function + * @param type ASN.1 type to be created + * @param datalen size of the body to be created + * @return points to the first position in the body + */ +u_char* asn1_build_object(chunk_t *object, asn1_t type, size_t datalen); + +/** + * Build a simple ASN.1 object + * + * @param tag ASN.1 type to be created + * @param content content of the ASN.1 object + * @return chunk containing the ASN.1 coded object + */ +chunk_t asn1_simple_object(asn1_t tag, chunk_t content); + +/** + * Build an ASN.1 BITSTRING object + * + * @param mode 'c' for copy or 'm' for move + * @param content content of the BITSTRING + * @return chunk containing the ASN.1 coded BITSTRING + */ +chunk_t asn1_bitstring(const char *mode, chunk_t content); + +/** + * Build an ASN.1 object from a variable number of individual chunks + * + * @param typ ASN.1 type to be created + * @param mode for each list member: 'c' for copy or 'm' for move + * @return chunk containing the ASN.1 coded object + */ +chunk_t asn1_wrap(asn1_t type, const char *mode, ...); -/* returns some popular algorithmIdentifiers */ -extern chunk_t asn1_algorithmIdentifier(int oid); - -extern int known_oid(chunk_t object); -extern u_int asn1_length(chunk_t *blob); -extern bool is_printablestring(chunk_t str); -extern time_t asn1totime(const chunk_t *utctime, asn1_t type); -extern chunk_t timetoasn1(const time_t *time, asn1_t type); -extern void asn1_init(asn1_ctx_t *ctx, chunk_t blob, u_int level0, bool implicit, bool private); -extern bool extract_object(asn1Object_t const *objects, u_int *objectID, chunk_t *object, u_int *level, asn1_ctx_t *ctx); -extern bool parse_asn1_simple_object(chunk_t *object, asn1_t type, u_int level, const char* name); -extern int parse_algorithmIdentifier(chunk_t blob, int level0, chunk_t *parameters); -extern time_t parse_time(chunk_t blob, int level0); - -extern bool is_asn1(chunk_t blob); - -extern void code_asn1_length(size_t length, chunk_t *code); -extern u_char* build_asn1_object(chunk_t *object, asn1_t type, size_t datalen); -extern chunk_t asn1_integer_from_mpz(const mpz_t value); -extern chunk_t asn1_simple_object(asn1_t tag, chunk_t content); -extern chunk_t asn1_bitstring(const char *mode, chunk_t content); -extern chunk_t asn1_wrap(asn1_t type, const char *mode, ...); - -#endif /* _ASN1_H */ +#endif /* ASN1_H_ @}*/ diff --git a/src/libstrongswan/asn1/asn1_parser.c b/src/libstrongswan/asn1/asn1_parser.c new file mode 100644 index 000000000..7a2028fc3 --- /dev/null +++ b/src/libstrongswan/asn1/asn1_parser.c @@ -0,0 +1,302 @@ +/* + * Copyright (C) 2006 Martin Will + * Copyright (C) 2000-2008 Andreas Steffen + * + * Hochschule fuer Technik Rapperswil + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * 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: asn1_parser.c 3894 2008-04-28 18:44:21Z andreas $ + */ + +#include <stdio.h> +#include <string.h> +#include <time.h> + +#include <library.h> +#include <debug.h> + +#include "asn1.h" +#include "asn1_parser.h" + +#define ASN1_MAX_LEVEL 10 + +typedef struct private_asn1_parser_t private_asn1_parser_t; + +/** + * Private data of an asn1_cxt_t object. + */ +struct private_asn1_parser_t { + /** + * Public interface. + */ + asn1_parser_t public; + + /** + * Syntax definition of ASN.1 object + */ + asn1Object_t const *objects; + + /** + * Current syntax definition line + */ + int line; + + /** + * Current stat of the parsing operation + */ + bool success; + + /** + * Declare object data as private - use debug level 4 to log it + */ + bool private; + + /** + * Top-most type is implicit - ignore it + */ + bool implicit; + + /** + * Top-most parsing level - defaults to 0 + */ + u_int level0; + + /** + * Jump back address for loops for each level + */ + int loopAddr[ASN1_MAX_LEVEL + 1]; + + /** + * Current parsing pointer for each level + */ + chunk_t blobs[ASN1_MAX_LEVEL + 2]; +}; + +/** + * Implementation of asn1_parser_t.iterate + */ +static bool iterate(private_asn1_parser_t *this, int *objectID, chunk_t *object) +{ + chunk_t *blob, *blob1; + u_char *start_ptr; + u_int level; + asn1Object_t obj; + + *object = chunk_empty; + + /* Advance to the next object syntax definition line */ + obj = this->objects[++(this->line)]; + + /* Terminate if the end of the object syntax definition has been reached */ + if (obj.flags & ASN1_EXIT) + { + return FALSE; + } + + if (obj.flags & ASN1_END) /* end of loop or option found */ + { + if (this->loopAddr[obj.level] && this->blobs[obj.level+1].len > 0) + { + this->line = this->loopAddr[obj.level]; /* another iteration */ + obj = this->objects[this->line]; + } + else + { + this->loopAddr[obj.level] = 0; /* exit loop or option*/ + goto end; + } + } + + level = this->level0 + obj.level; + blob = this->blobs + obj.level; + blob1 = blob + 1; + start_ptr = blob->ptr; + + /* handle ASN.1 defaults values */ + if ((obj.flags & ASN1_DEF) && (blob->len == 0 || *start_ptr != obj.type) ) + { + /* field is missing */ + DBG2("L%d - %s:", level, obj.name); + if (obj.type & ASN1_CONSTRUCTED) + { + this->line++ ; /* skip context-specific tag */ + } + goto end; + } + + /* handle ASN.1 options */ + + if ((obj.flags & ASN1_OPT) + && (blob->len == 0 || *start_ptr != obj.type)) + { + /* advance to end of missing option field */ + do + { + this->line++; + } + while (!((this->objects[this->line].flags & ASN1_END) && + (this->objects[this->line].level == obj.level))); + goto end; + } + + /* an ASN.1 object must possess at least a tag and length field */ + + if (blob->len < 2) + { + DBG1("L%d - %s: ASN.1 object smaller than 2 octets", + level, obj.name); + this->success = FALSE; + goto end; + } + + blob1->len = asn1_length(blob); + + if (blob1->len == ASN1_INVALID_LENGTH || blob->len < blob1->len) + { + DBG1("L%d - %s: length of ASN.1 object invalid or too large", + level, obj.name); + this->success = FALSE; + } + + blob1->ptr = blob->ptr; + blob->ptr += blob1->len; + blob->len -= blob1->len; + + /* return raw ASN.1 object without prior type checking */ + + if (obj.flags & ASN1_RAW) + { + DBG2("L%d - %s:", level, obj.name); + object->ptr = start_ptr; + object->len = (size_t)(blob->ptr - start_ptr); + goto end; + } + + if (*start_ptr != obj.type && !(this->implicit && this->line == 0)) + { + DBG1("L%d - %s: ASN1 tag 0x%02x expected, but is 0x%02x", + level, obj.name, obj.type, *start_ptr); + DBG3("%b", start_ptr, (u_int)(blob->ptr - start_ptr)); + this->success = FALSE; + goto end; + } + + DBG2("L%d - %s:", level, obj.name); + + /* In case of "SEQUENCE OF" or "SET OF" start a loop */ + if (obj.flags & ASN1_LOOP) + { + if (blob1->len > 0) + { + /* at least one item, start the loop */ + this->loopAddr[obj.level] = this->line + 1; + } + else + { + /* no items, advance directly to end of loop */ + do + { + this->line++; + } + while (!((this->objects[this->line].flags & ASN1_END) && + (this->objects[this->line].level == obj.level))); + goto end; + } + } + + if (obj.flags & ASN1_OBJ) + { + object->ptr = start_ptr; + object->len = (size_t)(blob->ptr - start_ptr); + if (this->private) + { + DBG4("%B", object); + } + else + { + DBG3("%B", object); + } + } + else if (obj.flags & ASN1_BODY) + { + *object = *blob1; + asn1_debug_simple_object(*object, obj.type, this->private); + } + +end: + *objectID = this->line; + return this->success; +} + +/** + * Implementation of asn1_parser_t.get_level + */ +static u_int get_level(private_asn1_parser_t *this) +{ + return this->level0 + this->objects[this->line].level; +} + +/** + * Implementation of asn1_parser_t.set_top_level + */ +static void set_top_level(private_asn1_parser_t *this, u_int level0) +{ + this->level0 = level0; +} + +/** + * Implementation of asn1_parser_t.set_flags + */ +static void set_flags(private_asn1_parser_t *this, bool implicit, bool private) +{ + this->implicit = implicit; + this->private = private; +} + +/** + * Implementation of asn1_parser_t.success + */ +static bool success(private_asn1_parser_t *this) +{ + return this->success; +} + +/** + * Implementation of asn1_parser_t.destroy + */ +static void destroy(private_asn1_parser_t *this) +{ + free(this); +} + +/** + * Defined in header. + */ +asn1_parser_t* asn1_parser_create(asn1Object_t const *objects, chunk_t blob) +{ + private_asn1_parser_t *this = malloc_thing(private_asn1_parser_t); + + memset(this, '\0', sizeof(private_asn1_parser_t)); + this->objects = objects; + this->blobs[0] = blob; + this->line = -1; + this->success = TRUE; + + this->public.iterate = (bool (*)(asn1_parser_t*, int*, chunk_t*))iterate; + this->public.get_level = (u_int (*)(asn1_parser_t*))get_level; + this->public.set_top_level = (void (*)(asn1_parser_t*, u_int))set_top_level; + this->public.set_flags = (void (*)(asn1_parser_t*, bool, bool))set_flags; + this->public.success = (bool (*)(asn1_parser_t*))success; + this->public.destroy = (void (*)(asn1_parser_t*))destroy; + + return &this->public; +} diff --git a/src/libstrongswan/asn1/asn1_parser.h b/src/libstrongswan/asn1/asn1_parser.h new file mode 100644 index 000000000..d84a5336f --- /dev/null +++ b/src/libstrongswan/asn1/asn1_parser.h @@ -0,0 +1,119 @@ +/* + * Copyright (C) 2006 Martin Will + * Copyright (C) 2000-2008 Andreas Steffen + * + * Hochschule fuer Technik Rapperswil + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * 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: asn1_parser.h 3894 2008-04-28 18:44:21Z andreas $ + */ + +/** + * @defgroup asn1_parser asn1_parser + * @{ @ingroup asn1 + */ + +#ifndef ASN1_PARSER_H_ +#define ASN1_PARSER_H_ + +#include <stdarg.h> + +#include <library.h> + +/** + * Definition of ASN.1 flags + */ +#define ASN1_NONE 0x00 +#define ASN1_DEF 0x01 +#define ASN1_OPT 0x02 +#define ASN1_LOOP 0x04 +#define ASN1_END 0x08 +#define ASN1_OBJ 0x10 +#define ASN1_BODY 0x20 +#define ASN1_RAW 0x40 +#define ASN1_EXIT 0x80 + +typedef struct asn1Object_t asn1Object_t; + +/** + * Syntax definition of an ASN.1 object + */ +struct asn1Object_t{ + u_int level; + const u_char *name; + asn1_t type; + u_char flags; +}; + +typedef struct asn1_parser_t asn1_parser_t; + +/** + * Public interface of an ASN.1 parser + */ +struct asn1_parser_t { + + /** + * Parse the next ASN.1 object in the hierarchy and return it + * + * @param objectID current line in the object syntax definition + * @param object current object + * @return - FALSE if end of object syntax definition was reached + * or a parsing error occurred + * - TRUE otherwise + */ + bool (*iterate)(asn1_parser_t *this, int *objectID, chunk_t *object); + + /** + * Get the current parsing level + * + * @return current level + */ + u_int (*get_level)(asn1_parser_t *this); + + /** + * Set the top-most level + * + * @param level top-most level + */ + void (*set_top_level)(asn1_parser_t *this, u_int level0); + + /** + * Set implicit and private flags + * + * @param implicit top-most type of object is implicit + * @param private object data is private (use debug level 4) + */ + void (*set_flags)(asn1_parser_t *this, bool implicit, bool private); + + /** + * Show final parsing status + * + * @return TRUE if parsing was successful, FALSE otherwise + */ + bool (*success)(asn1_parser_t *this); + + /** + * Destroy the ASN.1 parser + */ + void (*destroy)(asn1_parser_t *this); +}; + +/** + * Create an ASN.1 parser + * + * @param objects syntax definition of the ASN.1 object to be parsed + * @param blob ASN.1 coded binary blob + * @return ASN.1 context + */ +asn1_parser_t* asn1_parser_create(asn1Object_t const *objects, chunk_t blob); + +#endif /* ASN1_PARSER_H_ @}*/ diff --git a/src/libstrongswan/asn1/oid.c b/src/libstrongswan/asn1/oid.c index 63896be6b..f9eb26d1d 100644 --- a/src/libstrongswan/asn1/oid.c +++ b/src/libstrongswan/asn1/oid.c @@ -62,10 +62,10 @@ const oid_t oid_names[] = { { 0x25, 50, 0, "extendedKeyUsage" }, /* 49 */ { 0x37, 51, 0, "targetInformation" }, /* 50 */ { 0x38, 0, 0, "noRevAvail" }, /* 51 */ - {0x2A, 95, 1, "" }, /* 52 */ + {0x2A, 131, 1, "" }, /* 52 */ { 0x86, 0, 1, "" }, /* 53 */ { 0x48, 0, 1, "" }, /* 54 */ - { 0x86, 0, 1, "" }, /* 55 */ + { 0x86, 95, 1, "" }, /* 55 */ { 0xF6, 61, 1, "" }, /* 56 */ { 0x7D, 0, 1, "NortelNetworks" }, /* 57 */ { 0x07, 0, 1, "Entrust" }, /* 58 */ @@ -105,105 +105,175 @@ const oid_t oid_names[] = { { 0x05, 0, 0, "md5" }, /* 92 */ { 0x03, 0, 1, "encryptionAlgorithm" }, /* 93 */ { 0x07, 0, 0, "3des-ede-cbc" }, /* 94 */ - {0x2B, 161, 1, "" }, /* 95 */ - { 0x06, 148, 1, "dod" }, /* 96 */ - { 0x01, 0, 1, "internet" }, /* 97 */ - { 0x04, 116, 1, "private" }, /* 98 */ - { 0x01, 0, 1, "enterprise" }, /* 99 */ - { 0x82, 109, 1, "" }, /* 100 */ - { 0x37, 0, 1, "Microsoft" }, /* 101 */ - { 0x0A, 106, 1, "" }, /* 102 */ - { 0x03, 0, 1, "" }, /* 103 */ - { 0x03, 105, 0, "msSGC" }, /* 104 */ - { 0x04, 0, 0, "msEncryptingFileSystem" }, /* 105 */ - { 0x14, 0, 1, "msEnrollmentInfrastructure"}, /* 106 */ - { 0x02, 0, 1, "msCertificateTypeExtension"}, /* 107 */ - { 0x02, 0, 0, "msSmartcardLogon" }, /* 108 */ - { 0x89, 0, 1, "" }, /* 109 */ - { 0x31, 0, 1, "" }, /* 110 */ - { 0x01, 0, 1, "" }, /* 111 */ - { 0x01, 0, 1, "" }, /* 112 */ - { 0x02, 0, 1, "" }, /* 113 */ - { 0x02, 115, 0, "" }, /* 114 */ - { 0x4B, 0, 0, "TCGID" }, /* 115 */ - { 0x05, 0, 1, "security" }, /* 116 */ - { 0x05, 0, 1, "mechanisms" }, /* 117 */ - { 0x07, 0, 1, "id-pkix" }, /* 118 */ - { 0x01, 121, 1, "id-pe" }, /* 119 */ - { 0x01, 0, 0, "authorityInfoAccess" }, /* 120 */ - { 0x03, 131, 1, "id-kp" }, /* 121 */ - { 0x01, 123, 0, "serverAuth" }, /* 122 */ - { 0x02, 124, 0, "clientAuth" }, /* 123 */ - { 0x03, 125, 0, "codeSigning" }, /* 124 */ - { 0x04, 126, 0, "emailProtection" }, /* 125 */ - { 0x05, 127, 0, "ipsecEndSystem" }, /* 126 */ - { 0x06, 128, 0, "ipsecTunnel" }, /* 127 */ - { 0x07, 129, 0, "ipsecUser" }, /* 128 */ - { 0x08, 130, 0, "timeStamping" }, /* 129 */ - { 0x09, 0, 0, "ocspSigning" }, /* 130 */ - { 0x08, 133, 1, "id-otherNames" }, /* 131 */ - { 0x05, 0, 0, "xmppAddr" }, /* 132 */ - { 0x0A, 138, 1, "id-aca" }, /* 133 */ - { 0x01, 135, 0, "authenticationInfo" }, /* 134 */ - { 0x02, 136, 0, "accessIdentity" }, /* 135 */ - { 0x03, 137, 0, "chargingIdentity" }, /* 136 */ - { 0x04, 0, 0, "group" }, /* 137 */ - { 0x30, 0, 1, "id-ad" }, /* 138 */ - { 0x01, 147, 1, "ocsp" }, /* 139 */ - { 0x01, 141, 0, "basic" }, /* 140 */ - { 0x02, 142, 0, "nonce" }, /* 141 */ - { 0x03, 143, 0, "crl" }, /* 142 */ - { 0x04, 144, 0, "response" }, /* 143 */ - { 0x05, 145, 0, "noCheck" }, /* 144 */ - { 0x06, 146, 0, "archiveCutoff" }, /* 145 */ - { 0x07, 0, 0, "serviceLocator" }, /* 146 */ - { 0x02, 0, 0, "caIssuers" }, /* 147 */ - { 0x0E, 154, 1, "oiw" }, /* 148 */ - { 0x03, 0, 1, "secsig" }, /* 149 */ - { 0x02, 0, 1, "algorithms" }, /* 150 */ - { 0x07, 152, 0, "des-cbc" }, /* 151 */ - { 0x1A, 153, 0, "sha-1" }, /* 152 */ - { 0x1D, 0, 0, "sha-1WithRSASignature" }, /* 153 */ - { 0x24, 0, 1, "TeleTrusT" }, /* 154 */ - { 0x03, 0, 1, "algorithm" }, /* 155 */ - { 0x03, 0, 1, "signatureAlgorithm" }, /* 156 */ - { 0x01, 0, 1, "rsaSignature" }, /* 157 */ - { 0x02, 159, 0, "rsaSigWithripemd160" }, /* 158 */ - { 0x03, 160, 0, "rsaSigWithripemd128" }, /* 159 */ - { 0x04, 0, 0, "rsaSigWithripemd256" }, /* 160 */ - {0x60, 0, 1, "" }, /* 161 */ - { 0x86, 0, 1, "" }, /* 162 */ - { 0x48, 0, 1, "" }, /* 163 */ - { 0x01, 0, 1, "organization" }, /* 164 */ - { 0x65, 172, 1, "gov" }, /* 165 */ - { 0x03, 0, 1, "csor" }, /* 166 */ - { 0x04, 0, 1, "nistalgorithm" }, /* 167 */ - { 0x02, 0, 1, "hashalgs" }, /* 168 */ - { 0x01, 170, 0, "id-SHA-256" }, /* 169 */ - { 0x02, 171, 0, "id-SHA-384" }, /* 170 */ - { 0x03, 0, 0, "id-SHA-512" }, /* 171 */ - { 0x86, 0, 1, "" }, /* 172 */ - { 0xf8, 0, 1, "" }, /* 173 */ - { 0x42, 186, 1, "netscape" }, /* 174 */ - { 0x01, 181, 1, "" }, /* 175 */ - { 0x01, 177, 0, "nsCertType" }, /* 176 */ - { 0x03, 178, 0, "nsRevocationUrl" }, /* 177 */ - { 0x04, 179, 0, "nsCaRevocationUrl" }, /* 178 */ - { 0x08, 180, 0, "nsCaPolicyUrl" }, /* 179 */ - { 0x0d, 0, 0, "nsComment" }, /* 180 */ - { 0x03, 184, 1, "directory" }, /* 181 */ - { 0x01, 0, 1, "" }, /* 182 */ - { 0x03, 0, 0, "employeeNumber" }, /* 183 */ - { 0x04, 0, 1, "policy" }, /* 184 */ - { 0x01, 0, 0, "nsSGC" }, /* 185 */ - { 0x45, 0, 1, "verisign" }, /* 186 */ - { 0x01, 0, 1, "pki" }, /* 187 */ - { 0x09, 0, 1, "attributes" }, /* 188 */ - { 0x02, 190, 0, "messageType" }, /* 189 */ - { 0x03, 191, 0, "pkiStatus" }, /* 190 */ - { 0x04, 192, 0, "failInfo" }, /* 191 */ - { 0x05, 193, 0, "senderNonce" }, /* 192 */ - { 0x06, 194, 0, "recipientNonce" }, /* 193 */ - { 0x07, 195, 0, "transID" }, /* 194 */ - { 0x08, 0, 0, "extensionReq" } /* 195 */ + { 0xCE, 0, 1, "" }, /* 95 */ + { 0x3D, 0, 1, "ansi-X9-62" }, /* 96 */ + { 0x02, 99, 1, "id-publicKeyType" }, /* 97 */ + { 0x01, 0, 0, "id-ecPublicKey" }, /* 98 */ + { 0x03, 129, 1, "ellipticCurve" }, /* 99 */ + { 0x00, 121, 1, "c-TwoCurve" }, /* 100 */ + { 0x01, 102, 0, "c2pnb163v1" }, /* 101 */ + { 0x02, 103, 0, "c2pnb163v2" }, /* 102 */ + { 0x03, 104, 0, "c2pnb163v3" }, /* 103 */ + { 0x04, 105, 0, "c2pnb176w1" }, /* 104 */ + { 0x05, 106, 0, "c2tnb191v1" }, /* 105 */ + { 0x06, 107, 0, "c2tnb191v2" }, /* 106 */ + { 0x07, 108, 0, "c2tnb191v3" }, /* 107 */ + { 0x08, 109, 0, "c2onb191v4" }, /* 108 */ + { 0x09, 110, 0, "c2onb191v5" }, /* 109 */ + { 0x0A, 111, 0, "c2pnb208w1" }, /* 110 */ + { 0x0B, 112, 0, "c2tnb239v1" }, /* 111 */ + { 0x0C, 113, 0, "c2tnb239v2" }, /* 112 */ + { 0x0D, 114, 0, "c2tnb239v3" }, /* 113 */ + { 0x0E, 115, 0, "c2onb239v4" }, /* 114 */ + { 0x0F, 116, 0, "c2onb239v5" }, /* 115 */ + { 0x10, 117, 0, "c2pnb272w1" }, /* 116 */ + { 0x11, 118, 0, "c2pnb304w1" }, /* 117 */ + { 0x12, 119, 0, "c2tnb359v1" }, /* 118 */ + { 0x13, 120, 0, "c2pnb368w1" }, /* 119 */ + { 0x14, 0, 0, "c2tnb431r1" }, /* 120 */ + { 0x01, 0, 1, "primeCurve" }, /* 121 */ + { 0x01, 123, 0, "prime192v1" }, /* 122 */ + { 0x02, 124, 0, "prime192v2" }, /* 123 */ + { 0x03, 125, 0, "prime192v3" }, /* 124 */ + { 0x04, 126, 0, "prime239v1" }, /* 125 */ + { 0x05, 127, 0, "prime239v2" }, /* 126 */ + { 0x06, 128, 0, "prime239v3" }, /* 127 */ + { 0x07, 0, 0, "prime256v1" }, /* 128 */ + { 0x04, 0, 1, "id-ecSigType" }, /* 129 */ + { 0x01, 0, 0, "ecdsa-with-SHA1" }, /* 130 */ + {0x2B, 231, 1, "" }, /* 131 */ + { 0x06, 184, 1, "dod" }, /* 132 */ + { 0x01, 0, 1, "internet" }, /* 133 */ + { 0x04, 152, 1, "private" }, /* 134 */ + { 0x01, 0, 1, "enterprise" }, /* 135 */ + { 0x82, 145, 1, "" }, /* 136 */ + { 0x37, 0, 1, "Microsoft" }, /* 137 */ + { 0x0A, 142, 1, "" }, /* 138 */ + { 0x03, 0, 1, "" }, /* 139 */ + { 0x03, 141, 0, "msSGC" }, /* 140 */ + { 0x04, 0, 0, "msEncryptingFileSystem" }, /* 141 */ + { 0x14, 0, 1, "msEnrollmentInfrastructure"}, /* 142 */ + { 0x02, 0, 1, "msCertificateTypeExtension"}, /* 143 */ + { 0x02, 0, 0, "msSmartcardLogon" }, /* 144 */ + { 0x89, 0, 1, "" }, /* 145 */ + { 0x31, 0, 1, "" }, /* 146 */ + { 0x01, 0, 1, "" }, /* 147 */ + { 0x01, 0, 1, "" }, /* 148 */ + { 0x02, 0, 1, "" }, /* 149 */ + { 0x02, 151, 0, "" }, /* 150 */ + { 0x4B, 0, 0, "TCGID" }, /* 151 */ + { 0x05, 0, 1, "security" }, /* 152 */ + { 0x05, 0, 1, "mechanisms" }, /* 153 */ + { 0x07, 0, 1, "id-pkix" }, /* 154 */ + { 0x01, 157, 1, "id-pe" }, /* 155 */ + { 0x01, 0, 0, "authorityInfoAccess" }, /* 156 */ + { 0x03, 167, 1, "id-kp" }, /* 157 */ + { 0x01, 159, 0, "serverAuth" }, /* 158 */ + { 0x02, 160, 0, "clientAuth" }, /* 159 */ + { 0x03, 161, 0, "codeSigning" }, /* 160 */ + { 0x04, 162, 0, "emailProtection" }, /* 161 */ + { 0x05, 163, 0, "ipsecEndSystem" }, /* 162 */ + { 0x06, 164, 0, "ipsecTunnel" }, /* 163 */ + { 0x07, 165, 0, "ipsecUser" }, /* 164 */ + { 0x08, 166, 0, "timeStamping" }, /* 165 */ + { 0x09, 0, 0, "ocspSigning" }, /* 166 */ + { 0x08, 169, 1, "id-otherNames" }, /* 167 */ + { 0x05, 0, 0, "xmppAddr" }, /* 168 */ + { 0x0A, 174, 1, "id-aca" }, /* 169 */ + { 0x01, 171, 0, "authenticationInfo" }, /* 170 */ + { 0x02, 172, 0, "accessIdentity" }, /* 171 */ + { 0x03, 173, 0, "chargingIdentity" }, /* 172 */ + { 0x04, 0, 0, "group" }, /* 173 */ + { 0x30, 0, 1, "id-ad" }, /* 174 */ + { 0x01, 183, 1, "ocsp" }, /* 175 */ + { 0x01, 177, 0, "basic" }, /* 176 */ + { 0x02, 178, 0, "nonce" }, /* 177 */ + { 0x03, 179, 0, "crl" }, /* 178 */ + { 0x04, 180, 0, "response" }, /* 179 */ + { 0x05, 181, 0, "noCheck" }, /* 180 */ + { 0x06, 182, 0, "archiveCutoff" }, /* 181 */ + { 0x07, 0, 0, "serviceLocator" }, /* 182 */ + { 0x02, 0, 0, "caIssuers" }, /* 183 */ + { 0x0E, 190, 1, "oiw" }, /* 184 */ + { 0x03, 0, 1, "secsig" }, /* 185 */ + { 0x02, 0, 1, "algorithms" }, /* 186 */ + { 0x07, 188, 0, "des-cbc" }, /* 187 */ + { 0x1A, 189, 0, "sha-1" }, /* 188 */ + { 0x1D, 0, 0, "sha-1WithRSASignature" }, /* 189 */ + { 0x24, 197, 1, "TeleTrusT" }, /* 190 */ + { 0x03, 0, 1, "algorithm" }, /* 191 */ + { 0x03, 0, 1, "signatureAlgorithm" }, /* 192 */ + { 0x01, 0, 1, "rsaSignature" }, /* 193 */ + { 0x02, 195, 0, "rsaSigWithripemd160" }, /* 194 */ + { 0x03, 196, 0, "rsaSigWithripemd128" }, /* 195 */ + { 0x04, 0, 0, "rsaSigWithripemd256" }, /* 196 */ + { 0x81, 0, 1, "" }, /* 197 */ + { 0x04, 0, 1, "Certicom" }, /* 198 */ + { 0x00, 0, 1, "curve" }, /* 199 */ + { 0x01, 201, 0, "sect163k1" }, /* 200 */ + { 0x02, 202, 0, "sect163r1" }, /* 201 */ + { 0x03, 203, 0, "sect239k1" }, /* 202 */ + { 0x04, 204, 0, "sect113r1" }, /* 203 */ + { 0x05, 205, 0, "sect113r2" }, /* 204 */ + { 0x06, 206, 0, "secp112r1" }, /* 205 */ + { 0x07, 207, 0, "secp112r2" }, /* 206 */ + { 0x08, 208, 0, "secp160r1" }, /* 207 */ + { 0x09, 209, 0, "secp160k1" }, /* 208 */ + { 0x0A, 210, 0, "secp256k1" }, /* 209 */ + { 0x0F, 211, 0, "sect163r2" }, /* 210 */ + { 0x10, 212, 0, "sect283k1" }, /* 211 */ + { 0x11, 213, 0, "sect283r1" }, /* 212 */ + { 0x16, 214, 0, "sect131r1" }, /* 213 */ + { 0x17, 215, 0, "sect131r2" }, /* 214 */ + { 0x18, 216, 0, "sect193r1" }, /* 215 */ + { 0x19, 217, 0, "sect193r2" }, /* 216 */ + { 0x1A, 218, 0, "sect233k1" }, /* 217 */ + { 0x1B, 219, 0, "sect233r1" }, /* 218 */ + { 0x1C, 220, 0, "secp128r1" }, /* 219 */ + { 0x1D, 221, 0, "secp128r2" }, /* 220 */ + { 0x1E, 222, 0, "secp160r2" }, /* 221 */ + { 0x1F, 223, 0, "secp192k1" }, /* 222 */ + { 0x20, 224, 0, "secp224k1" }, /* 223 */ + { 0x21, 225, 0, "secp224r1" }, /* 224 */ + { 0x22, 226, 0, "secp384r1" }, /* 225 */ + { 0x23, 227, 0, "secp521r1" }, /* 226 */ + { 0x24, 228, 0, "sect409k1" }, /* 227 */ + { 0x25, 229, 0, "sect409r1" }, /* 228 */ + { 0x26, 230, 0, "sect571k1" }, /* 229 */ + { 0x27, 0, 0, "sect571r1" }, /* 230 */ + {0x60, 0, 1, "" }, /* 231 */ + { 0x86, 0, 1, "" }, /* 232 */ + { 0x48, 0, 1, "" }, /* 233 */ + { 0x01, 0, 1, "organization" }, /* 234 */ + { 0x65, 242, 1, "gov" }, /* 235 */ + { 0x03, 0, 1, "csor" }, /* 236 */ + { 0x04, 0, 1, "nistalgorithm" }, /* 237 */ + { 0x02, 0, 1, "hashalgs" }, /* 238 */ + { 0x01, 240, 0, "id-SHA-256" }, /* 239 */ + { 0x02, 241, 0, "id-SHA-384" }, /* 240 */ + { 0x03, 0, 0, "id-SHA-512" }, /* 241 */ + { 0x86, 0, 1, "" }, /* 242 */ + { 0xf8, 0, 1, "" }, /* 243 */ + { 0x42, 256, 1, "netscape" }, /* 244 */ + { 0x01, 251, 1, "" }, /* 245 */ + { 0x01, 247, 0, "nsCertType" }, /* 246 */ + { 0x03, 248, 0, "nsRevocationUrl" }, /* 247 */ + { 0x04, 249, 0, "nsCaRevocationUrl" }, /* 248 */ + { 0x08, 250, 0, "nsCaPolicyUrl" }, /* 249 */ + { 0x0d, 0, 0, "nsComment" }, /* 250 */ + { 0x03, 254, 1, "directory" }, /* 251 */ + { 0x01, 0, 1, "" }, /* 252 */ + { 0x03, 0, 0, "employeeNumber" }, /* 253 */ + { 0x04, 0, 1, "policy" }, /* 254 */ + { 0x01, 0, 0, "nsSGC" }, /* 255 */ + { 0x45, 0, 1, "verisign" }, /* 256 */ + { 0x01, 0, 1, "pki" }, /* 257 */ + { 0x09, 0, 1, "attributes" }, /* 258 */ + { 0x02, 260, 0, "messageType" }, /* 259 */ + { 0x03, 261, 0, "pkiStatus" }, /* 260 */ + { 0x04, 262, 0, "failInfo" }, /* 261 */ + { 0x05, 263, 0, "senderNonce" }, /* 262 */ + { 0x06, 264, 0, "recipientNonce" }, /* 263 */ + { 0x07, 265, 0, "transID" }, /* 264 */ + { 0x08, 0, 0, "extensionReq" } /* 265 */ }; diff --git a/src/libstrongswan/asn1/oid.h b/src/libstrongswan/asn1/oid.h index 9980221ab..a0fb95f18 100644 --- a/src/libstrongswan/asn1/oid.h +++ b/src/libstrongswan/asn1/oid.h @@ -49,37 +49,97 @@ extern const oid_t oid_names[]; #define OID_MD2 91 #define OID_MD5 92 #define OID_3DES_EDE_CBC 94 -#define OID_AUTHORITY_INFO_ACCESS 120 -#define OID_OCSP_SIGNING 130 -#define OID_XMPP_ADDR 132 -#define OID_AUTHENTICATION_INFO 134 -#define OID_ACCESS_IDENTITY 135 -#define OID_CHARGING_IDENTITY 136 -#define OID_GROUP 137 -#define OID_OCSP 139 -#define OID_BASIC 140 -#define OID_NONCE 141 -#define OID_CRL 142 -#define OID_RESPONSE 143 -#define OID_NO_CHECK 144 -#define OID_ARCHIVE_CUTOFF 145 -#define OID_SERVICE_LOCATOR 146 -#define OID_CA_ISSUERS 147 -#define OID_DES_CBC 151 -#define OID_SHA1 152 -#define OID_SHA1_WITH_RSA_OIW 153 -#define OID_SHA256 169 -#define OID_SHA384 170 -#define OID_SHA512 171 -#define OID_NS_REVOCATION_URL 177 -#define OID_NS_CA_REVOCATION_URL 178 -#define OID_NS_CA_POLICY_URL 179 -#define OID_NS_COMMENT 180 -#define OID_PKI_MESSAGE_TYPE 189 -#define OID_PKI_STATUS 190 -#define OID_PKI_FAIL_INFO 191 -#define OID_PKI_SENDER_NONCE 192 -#define OID_PKI_RECIPIENT_NONCE 193 -#define OID_PKI_TRANS_ID 194 +#define OID_EC_PUBLICKEY 98 +#define OID_C2PNB163V1 101 +#define OID_C2PNB163V2 102 +#define OID_C2PNB163V3 103 +#define OID_C2PNB176W1 104 +#define OID_C2PNB191V1 105 +#define OID_C2PNB191V2 106 +#define OID_C2PNB191V3 107 +#define OID_C2PNB191V4 108 +#define OID_C2PNB191V5 109 +#define OID_C2PNB208W1 110 +#define OID_C2PNB239V1 111 +#define OID_C2PNB239V2 112 +#define OID_C2PNB239V3 113 +#define OID_C2PNB239V4 114 +#define OID_C2PNB239V5 115 +#define OID_C2PNB272W1 116 +#define OID_C2PNB304W1 117 +#define OID_C2PNB359V1 118 +#define OID_C2PNB368W1 119 +#define OID_C2PNB431R1 120 +#define OID_PRIME192V1 122 +#define OID_PRIME192V2 123 +#define OID_PRIME192V3 124 +#define OID_PRIME239V1 125 +#define OID_PRIME239V2 126 +#define OID_PRIME239V3 127 +#define OID_PRIME256V1 128 +#define OID_ECDSA_WITH_SHA1 130 +#define OID_AUTHORITY_INFO_ACCESS 156 +#define OID_OCSP_SIGNING 166 +#define OID_XMPP_ADDR 168 +#define OID_AUTHENTICATION_INFO 170 +#define OID_ACCESS_IDENTITY 171 +#define OID_CHARGING_IDENTITY 172 +#define OID_GROUP 173 +#define OID_OCSP 175 +#define OID_BASIC 176 +#define OID_NONCE 177 +#define OID_CRL 178 +#define OID_RESPONSE 179 +#define OID_NO_CHECK 180 +#define OID_ARCHIVE_CUTOFF 181 +#define OID_SERVICE_LOCATOR 182 +#define OID_CA_ISSUERS 183 +#define OID_DES_CBC 187 +#define OID_SHA1 188 +#define OID_SHA1_WITH_RSA_OIW 189 +#define OID_SECT163K1 200 +#define OID_SECT163R1 201 +#define OID_SECT239K1 202 +#define OID_SECT113R1 203 +#define OID_SECT113R2 204 +#define OID_SECT112R1 205 +#define OID_SECT112R2 206 +#define OID_SECT160R1 207 +#define OID_SECT160K1 208 +#define OID_SECT256K1 209 +#define OID_SECT163R2 210 +#define OID_SECT283K1 211 +#define OID_SECT283R1 212 +#define OID_SECT131R1 213 +#define OID_SECT131R2 214 +#define OID_SECT193R1 215 +#define OID_SECT193R2 216 +#define OID_SECT233K1 217 +#define OID_SECT233R1 218 +#define OID_SECT128R1 219 +#define OID_SECT128R2 220 +#define OID_SECT160R2 221 +#define OID_SECT192K1 222 +#define OID_SECT224K1 223 +#define OID_SECT224R1 224 +#define OID_SECT384R1 225 +#define OID_SECT521R1 226 +#define OID_SECT409K1 227 +#define OID_SECT409R1 228 +#define OID_SECT571K1 229 +#define OID_SECT571R1 230 +#define OID_SHA256 239 +#define OID_SHA384 240 +#define OID_SHA512 241 +#define OID_NS_REVOCATION_URL 247 +#define OID_NS_CA_REVOCATION_URL 248 +#define OID_NS_CA_POLICY_URL 249 +#define OID_NS_COMMENT 250 +#define OID_PKI_MESSAGE_TYPE 259 +#define OID_PKI_STATUS 260 +#define OID_PKI_FAIL_INFO 261 +#define OID_PKI_SENDER_NONCE 262 +#define OID_PKI_RECIPIENT_NONCE 263 +#define OID_PKI_TRANS_ID 264 #endif /* OID_H_ */ diff --git a/src/libstrongswan/asn1/oid.txt b/src/libstrongswan/asn1/oid.txt index e6dede287..6bb765787 100644 --- a/src/libstrongswan/asn1/oid.txt +++ b/src/libstrongswan/asn1/oid.txt @@ -93,6 +93,42 @@ 0x05 "md5" OID_MD5 0x03 "encryptionAlgorithm" 0x07 "3des-ede-cbc" OID_3DES_EDE_CBC + 0xCE "" + 0x3D "ansi-X9-62" + 0x02 "id-publicKeyType" + 0x01 "id-ecPublicKey" OID_EC_PUBLICKEY + 0x03 "ellipticCurve" + 0x00 "c-TwoCurve" + 0x01 "c2pnb163v1" OID_C2PNB163V1 + 0x02 "c2pnb163v2" OID_C2PNB163V2 + 0x03 "c2pnb163v3" OID_C2PNB163V3 + 0x04 "c2pnb176w1" OID_C2PNB176W1 + 0x05 "c2tnb191v1" OID_C2PNB191V1 + 0x06 "c2tnb191v2" OID_C2PNB191V2 + 0x07 "c2tnb191v3" OID_C2PNB191V3 + 0x08 "c2onb191v4" OID_C2PNB191V4 + 0x09 "c2onb191v5" OID_C2PNB191V5 + 0x0A "c2pnb208w1" OID_C2PNB208W1 + 0x0B "c2tnb239v1" OID_C2PNB239V1 + 0x0C "c2tnb239v2" OID_C2PNB239V2 + 0x0D "c2tnb239v3" OID_C2PNB239V3 + 0x0E "c2onb239v4" OID_C2PNB239V4 + 0x0F "c2onb239v5" OID_C2PNB239V5 + 0x10 "c2pnb272w1" OID_C2PNB272W1 + 0x11 "c2pnb304w1" OID_C2PNB304W1 + 0x12 "c2tnb359v1" OID_C2PNB359V1 + 0x13 "c2pnb368w1" OID_C2PNB368W1 + 0x14 "c2tnb431r1" OID_C2PNB431R1 + 0x01 "primeCurve" + 0x01 "prime192v1" OID_PRIME192V1 + 0x02 "prime192v2" OID_PRIME192V2 + 0x03 "prime192v3" OID_PRIME192V3 + 0x04 "prime239v1" OID_PRIME239V1 + 0x05 "prime239v2" OID_PRIME239V2 + 0x06 "prime239v3" OID_PRIME239V3 + 0x07 "prime256v1" OID_PRIME256V1 + 0x04 "id-ecSigType" + 0x01 "ecdsa-with-SHA1" OID_ECDSA_WITH_SHA1 0x2B "" 0x06 "dod" 0x01 "internet" @@ -159,6 +195,40 @@ 0x02 "rsaSigWithripemd160" 0x03 "rsaSigWithripemd128" 0x04 "rsaSigWithripemd256" + 0x81 "" + 0x04 "Certicom" + 0x00 "curve" + 0x01 "sect163k1" OID_SECT163K1 + 0x02 "sect163r1" OID_SECT163R1 + 0x03 "sect239k1" OID_SECT239K1 + 0x04 "sect113r1" OID_SECT113R1 + 0x05 "sect113r2" OID_SECT113R2 + 0x06 "secp112r1" OID_SECT112R1 + 0x07 "secp112r2" OID_SECT112R2 + 0x08 "secp160r1" OID_SECT160R1 + 0x09 "secp160k1" OID_SECT160K1 + 0x0A "secp256k1" OID_SECT256K1 + 0x0F "sect163r2" OID_SECT163R2 + 0x10 "sect283k1" OID_SECT283K1 + 0x11 "sect283r1" OID_SECT283R1 + 0x16 "sect131r1" OID_SECT131R1 + 0x17 "sect131r2" OID_SECT131R2 + 0x18 "sect193r1" OID_SECT193R1 + 0x19 "sect193r2" OID_SECT193R2 + 0x1A "sect233k1" OID_SECT233K1 + 0x1B "sect233r1" OID_SECT233R1 + 0x1C "secp128r1" OID_SECT128R1 + 0x1D "secp128r2" OID_SECT128R2 + 0x1E "secp160r2" OID_SECT160R2 + 0x1F "secp192k1" OID_SECT192K1 + 0x20 "secp224k1" OID_SECT224K1 + 0x21 "secp224r1" OID_SECT224R1 + 0x22 "secp384r1" OID_SECT384R1 + 0x23 "secp521r1" OID_SECT521R1 + 0x24 "sect409k1" OID_SECT409K1 + 0x25 "sect409r1" OID_SECT409R1 + 0x26 "sect571k1" OID_SECT571K1 + 0x27 "sect571r1" OID_SECT571R1 0x60 "" 0x86 "" 0x48 "" diff --git a/src/libstrongswan/asn1/pem.c b/src/libstrongswan/asn1/pem.c index b752a97ab..d3176b6bc 100755 --- a/src/libstrongswan/asn1/pem.c +++ b/src/libstrongswan/asn1/pem.c @@ -1,5 +1,7 @@ /* - * Copyright (C) 2001-2004 Andreas Steffen, Zuercher Hochschule Winterthur + * Copyright (C) 2001-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 @@ -11,7 +13,7 @@ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * - * RCSID $Id: pem.c 3256 2007-10-07 13:42:43Z andreas $ + * $Id: pem.c 4029 2008-06-03 12:14:02Z martin $ */ #include <stdio.h> @@ -27,7 +29,6 @@ #include <library.h> #include <debug.h> #include <asn1/asn1.h> -#include <asn1/ttodata.h> #include <utils/lexparser.h> #include <crypto/hashers/hasher.h> @@ -83,7 +84,7 @@ static bool find_boundary(const char* tag, chunk_t *line) /* * decrypts a passphrase protected encrypted data block */ -static err_t pem_decrypt(chunk_t *blob, encryption_algorithm_t alg, size_t key_size, +static bool pem_decrypt(chunk_t *blob, encryption_algorithm_t alg, size_t key_size, chunk_t *iv, chunk_t *passphrase) { hasher_t *hasher; @@ -95,10 +96,18 @@ static err_t pem_decrypt(chunk_t *blob, encryption_algorithm_t alg, size_t key_s u_int8_t padding, *last_padding_pos, *first_padding_pos; if (passphrase == NULL || passphrase->len == 0) - return "missing passphrase"; + { + DBG1(" missing passphrase"); + return FALSE; + } /* build key from passphrase and IV */ - hasher = hasher_create(HASH_MD5); + hasher = lib->crypto->create_hasher(lib->crypto, HASH_MD5); + if (hasher == NULL) + { + DBG1(" MD5 hash algorithm not available"); + return FALSE; + } hash.len = hasher->get_hash_size(hasher); hash.ptr = alloca(hash.len); hasher->get_hash(hasher, *passphrase, NULL); @@ -115,13 +124,23 @@ static err_t pem_decrypt(chunk_t *blob, encryption_algorithm_t alg, size_t key_s hasher->destroy(hasher); /* decrypt blob */ - crypter = crypter_create(alg, key_size); + crypter = lib->crypto->create_crypter(lib->crypto, alg, key_size); + if (crypter == NULL) + { + DBG1(" %N encryption algorithm not available", + encryption_algorithm_names, alg); + return FALSE; + } crypter->set_key(crypter, key); - if (crypter->decrypt(crypter, *blob, *iv, &decrypted) != SUCCESS) + + if (iv->len != crypter->get_block_size(crypter) || + blob->len % iv->len) { crypter->destroy(crypter); - return "data size is not multiple of block size"; + DBG1(" data size is not multiple of block size"); + return FALSE; } + crypter->decrypt(crypter, *blob, *iv, &decrypted); crypter->destroy(crypter); memcpy(blob->ptr, decrypted.ptr, blob->len); chunk_free(&decrypted); @@ -135,11 +154,14 @@ static err_t pem_decrypt(chunk_t *blob, encryption_algorithm_t alg, size_t key_s while (--last_padding_pos > first_padding_pos) { if (*last_padding_pos != padding) - return "invalid passphrase"; + { + DBG1(" invalid passphrase"); + return FALSE; + } } /* remove padding */ blob->len -= padding; - return NULL; + return TRUE; } /* Converts a PEM encoded file into its binary form @@ -147,7 +169,7 @@ static err_t pem_decrypt(chunk_t *blob, encryption_algorithm_t alg, size_t key_s * RFC 1421 Privacy Enhancement for Electronic Mail, February 1993 * RFC 934 Message Encapsulation, January 1985 */ -err_t pem_to_bin(chunk_t *blob, chunk_t *passphrase, bool *pgp) +bool pem_to_bin(chunk_t *blob, chunk_t *passphrase, bool *pgp) { typedef enum { PEM_PRE = 0, @@ -223,7 +245,6 @@ err_t pem_to_bin(chunk_t *blob, chunk_t *passphrase, bool *pgp) encrypted = TRUE; else if (match("DEK-Info", &name)) { - size_t len = 0; chunk_t dek; if (!extract_token(&dek, ',', &value)) @@ -251,21 +272,16 @@ err_t pem_to_bin(chunk_t *blob, chunk_t *passphrase, bool *pgp) } else { - return "encryption algorithm not supported"; + DBG1(" encryption algorithm '%.s' not supported", + dek.len, dek.ptr); + return FALSE; } - eat_whitespace(&value); - ugh = ttodata(value.ptr, value.len, 16, iv.ptr, 16, &len); - if (ugh) - return "error in IV"; - - iv.len = len; + iv = chunk_from_hex(value, iv.ptr); } } else /* state is PEM_BODY */ { - const char *ugh = NULL; - size_t len = 0; chunk_t data; /* remove any trailing whitespace */ @@ -280,21 +296,18 @@ err_t pem_to_bin(chunk_t *blob, chunk_t *passphrase, bool *pgp) *pgp = TRUE; data.ptr++; data.len--; - DBG2(" Armor checksum: %.*s", (int)data.len, data.ptr); + DBG2(" armor checksum: %.*s", (int)data.len, data.ptr); continue; } - - ugh = ttodata(data.ptr, data.len, 64, dst.ptr, blob->len - dst.len, &len); - if (ugh) + + if (blob->len - dst.len < data.len / 4 * 3) { state = PEM_ABORT; - break; - } - else - { - dst.ptr += len; - dst.len += len; } + data = chunk_from_base64(data, dst.ptr); + + dst.ptr += data.len; + dst.len += data.len; } } } @@ -302,19 +315,24 @@ err_t pem_to_bin(chunk_t *blob, chunk_t *passphrase, bool *pgp) blob->len = dst.len; if (state != PEM_POST) - return "file coded in unknown format, discarded"; - - return (encrypted)? pem_decrypt(blob, alg, key_size, &iv, passphrase) : NULL; + { + DBG1(" file coded in unknown format, discarded"); + return FALSE; + } + if (!encrypted) + { + return TRUE; + } + return pem_decrypt(blob, alg, key_size, &iv, passphrase); + } /* load a coded key or certificate file with autodetection * of binary DER or base64 PEM ASN.1 formats and armored PGP format */ -bool pem_asn1_load_file(const char *filename, chunk_t *passphrase, - const char *type, chunk_t *blob, bool *pgp) +bool pem_asn1_load_file(char *filename, chunk_t *passphrase, + chunk_t *blob, bool *pgp) { - err_t ugh = NULL; - FILE *fd = fopen(filename, "r"); if (fd) @@ -326,7 +344,7 @@ bool pem_asn1_load_file(const char *filename, chunk_t *passphrase, blob->ptr = malloc(blob->len); bytes = fread(blob->ptr, 1, blob->len, fd); fclose(fd); - DBG1(" loading %s file '%s' (%d bytes)", type, filename, bytes); + DBG2(" loading '%s' (%d bytes)", filename, bytes); *pgp = FALSE; @@ -341,9 +359,7 @@ bool pem_asn1_load_file(const char *filename, chunk_t *passphrase, DBG4(" passphrase:", passphrase->ptr, passphrase->len); /* try PEM format */ - ugh = pem_to_bin(blob, passphrase, pgp); - - if (ugh == NULL) + if (pem_to_bin(blob, passphrase, pgp)) { if (*pgp) { @@ -355,16 +371,16 @@ bool pem_asn1_load_file(const char *filename, chunk_t *passphrase, DBG2(" file coded in PEM format"); return TRUE; } - ugh = "file coded in unknown format, discarded"; + DBG1(" file coded in unknown format, discarded"); } /* a conversion error has occured */ - DBG1(" %s", ugh); chunk_free(blob); } else { - DBG1(" could not open %s file '%s'", type, filename); + DBG1(" reading file '%s' failed", filename); } return FALSE; } + diff --git a/src/libstrongswan/asn1/pem.h b/src/libstrongswan/asn1/pem.h index 0f4b7202c..4b76fbe80 100755 --- a/src/libstrongswan/asn1/pem.h +++ b/src/libstrongswan/asn1/pem.h @@ -1,5 +1,7 @@ /* - * Copyright (C) 2001-2004 Andreas Steffen, Zuercher Hochschule Winterthur + * Copyright (C) 2001-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 @@ -10,6 +12,8 @@ * 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: pem.h 4011 2008-05-23 19:18:08Z andreas $ */ #ifndef PEM_H_ @@ -19,9 +23,9 @@ #include <library.h> -err_t pem_to_bin(chunk_t *blob, chunk_t *passphrase, bool *pgp); +bool pem_to_bin(chunk_t *blob, chunk_t *passphrase, bool *pgp); -bool pem_asn1_load_file(const char *filename, chunk_t *passphrase, - const char *type, chunk_t *blob, bool *pgp); +bool pem_asn1_load_file(char *filename, chunk_t *passphrase, + chunk_t *blob, bool *pgp); -#endif /*PEM_H_*/ +#endif /*PEM_H_ @} */ diff --git a/src/libstrongswan/asn1/ttodata.c b/src/libstrongswan/asn1/ttodata.c deleted file mode 100644 index 125313c2a..000000000 --- a/src/libstrongswan/asn1/ttodata.c +++ /dev/null @@ -1,433 +0,0 @@ -/* - * convert from text form of arbitrary data (e.g., keys) to binary - * Copyright (C) 2000 Henry Spencer. - * - * This library is free software; you can redistribute it and/or modify it - * under the terms of the GNU Library General Public License as published by - * the Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. See <http://www.fsf.org/copyleft/lgpl.txt>. - * - * This library 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 Library General Public - * License for more details. - */ - -#include "ttodata.h" - -#include <string.h> -#include <ctype.h> - -/* converters and misc */ -static int unhex(const char *, char *, size_t); -static int unb64(const char *, char *, size_t); -static int untext(const char *, char *, size_t); -static const char *badch(const char *, int, char *, size_t); - -/* internal error codes for converters */ -#define SHORT (-2) /* internal buffer too short */ -#define BADPAD (-3) /* bad base64 padding */ -#define BADCH0 (-4) /* invalid character 0 */ -#define BADCH1 (-5) /* invalid character 1 */ -#define BADCH2 (-6) /* invalid character 2 */ -#define BADCH3 (-7) /* invalid character 3 */ -#define BADOFF(code) (BADCH0-(code)) - -/** - * @brief convert text to data, with verbose error reports - * - * If some of this looks slightly odd, it's because it has changed - * repeatedly (from the original atodata()) without a major rewrite. - * - * @param src - * @param srclen 0 means apply strlen() - * @param base 0 means figure it out - * @param dst need not be valid if dstlen is 0 - * @param dstlen - * @param lenp where to record length (NULL is nowhere) - * @param errp error buffer - * @param flags - * @return NULL on success, else literal or errp - */ -const char *ttodatav(const char *src, size_t srclen, int base, char *dst, size_t dstlen, size_t *lenp, char *errp, size_t errlen, unsigned int flags) -{ - size_t ingroup; /* number of input bytes converted at once */ - char buf[4]; /* output from conversion */ - int nbytes; /* size of output */ - int (*decode)(const char *, char *, size_t); - char *stop; - int ndone; - int i; - int underscoreok; - int skipSpace = 0; - - if (srclen == 0) - { - srclen = strlen(src); - } - if (dstlen == 0) - { - dst = buf; /* point it somewhere valid */ - } - stop = dst + dstlen; - - if (base == 0) - { - if (srclen < 2) - { - return "input too short to be valid"; - } - if (*src++ != '0') - { - return "input does not begin with format prefix"; - } - switch (*src++) - { - case 'x': - case 'X': - base = 16; - break; - case 's': - case 'S': - base = 64; - break; - case 't': - case 'T': - base = 256; - break; - default: - return "unknown format prefix"; - } - srclen -= 2; - } - switch (base) - { - case 16: - decode = unhex; - underscoreok = 1; - ingroup = 2; - break; - case 64: - decode = unb64; - underscoreok = 0; - ingroup = 4; - if(flags & TTODATAV_IGNORESPACE) - { - skipSpace = 1; - } - break; - case 256: - decode = untext; - ingroup = 1; - underscoreok = 0; - break; - default: - return "unknown base"; - } - - /* proceed */ - ndone = 0; - while (srclen > 0) - { - char stage[4]; /* staging area for group */ - size_t sl = 0; - - /* Grab ingroup characters into stage, - * squeezing out blanks if we are supposed to ignore them. - */ - for (sl = 0; sl < ingroup; src++, srclen--) - { - if (srclen == 0) - { - return "input ends in mid-byte, perhaps truncated"; - } - else if (!(skipSpace && (*src == ' ' || *src == '\t'))) - { - stage[sl++] = *src; - } - } - - nbytes = (*decode)(stage, buf, sizeof(buf)); - switch (nbytes) - { - case BADCH0: - case BADCH1: - case BADCH2: - case BADCH3: - return badch(stage, nbytes, errp, errlen); - case SHORT: - return "internal buffer too short (\"can't happen\")"; - case BADPAD: - return "bad (non-zero) padding at end of base64 input"; - } - if (nbytes <= 0) - { - return "unknown internal error"; - } - for (i = 0; i < nbytes; i++) - { - if (dst < stop) - { - *dst++ = buf[i]; - } - ndone++; - } - while (srclen >= 1 && skipSpace && (*src == ' ' || *src == '\t')) - { - src++; - srclen--; - } - if (underscoreok && srclen > 1 && (*src == '_' || *src == ':')) - { - /* srclen > 1 means not last character */ - src++; - srclen--; - } - } - - if (ndone == 0) - { - return "no data bytes specified by input"; - } - if (lenp != NULL) - { - *lenp = ndone; - } - return NULL; -} - -/** - * @brief ttodata - convert text to data - * - * @param src - * @param srclen 0 means apply strlen() - * @param base 0 means figure it out - * @param dst need not be valid if dstlen is 0 - * @param dstlen - * @param lenp where to record length (NULL is nowhere) - * @return NULL on success, else literal - */ -const char *ttodata(const char *src, size_t srclen, int base, char *dst, size_t dstlen, size_t *lenp) -{ - return ttodatav(src, srclen, base, dst, dstlen, lenp, (char *)NULL, - (size_t)0, TTODATAV_SPACECOUNTS); -} - -/** - * @brief atodata - convert ASCII to data - * - * backward-compatibility interface - * - * @param src - * @param srclen - * @param dst - * @param dstlen - * @return 0 for failure, true length for success - */ -size_t atodata(const char *src, size_t srclen, char *dst, size_t dstlen) -{ - size_t len; - const char *err; - - err = ttodata(src, srclen, 0, dst, dstlen, &len); - return (err)? 0:len; -} - -/** - * @brief atobytes - convert ASCII to data bytes - * - * another backward-compatibility interface - */ -const char *atobytes(const char *src, size_t srclen, char *dst, size_t dstlen, size_t *lenp) -{ - return ttodata(src, srclen, 0, dst, dstlen, lenp); -} - -/** - * @brief unhex - convert two ASCII hex digits to byte - * - * @param src known to be full length - * @param dstnumber of result bytes, or error code - * @param dstlen not large enough is a failure - * @return - */ -static int unhex(const char *src, char *dst, size_t dstlen) -{ - char *p; - unsigned byte; - static char hex[] = "0123456789abcdef"; - - if (dstlen < 1) - { - return SHORT; - } - - p = strchr(hex, *src); - if (p == NULL) - { - p = strchr(hex, tolower(*src)); - } - if (p == NULL) - { - return BADCH0; - } - byte = (p - hex) << 4; - src++; - - p = strchr(hex, *src); - if (p == NULL) - { - p = strchr(hex, tolower(*src)); - } - if (p == NULL) - { - return BADCH1; - } - byte |= (p - hex); - - *dst = byte; - return 1; -} - -/** - * @brief unb64 - convert four ASCII base64 digits to three bytes - * - * Note that a base64 digit group is padded out with '=' if it represents - * less than three bytes: one byte is dd==, two is ddd=, three is dddd. - * - * @param src known to be full length - * @param dst - * @param dstlen - * @return number of result bytes, or error code - */ -static int unb64(const char *src, char *dst, size_t dstlen) -{ - char *p; - unsigned byte1; - unsigned byte2; - static char base64[] = - "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; - - if (dstlen < 3) - { - return SHORT; - } - p = strchr(base64, *src++); - - if (p == NULL) - { - return BADCH0; - } - byte1 = (p - base64) << 2; /* first six bits */ - - p = strchr(base64, *src++); - if (p == NULL) - { - return BADCH1; - } - - byte2 = p - base64; /* next six: two plus four */ - *dst++ = byte1 | (byte2 >> 4); - byte1 = (byte2 & 0xf) << 4; - - p = strchr(base64, *src++); - if (p == NULL) - { - if (*(src-1) == '=' && *src == '=') - { - if (byte1 != 0) /* bad padding */ - { - return BADPAD; - } - return 1; - } - return BADCH2; - } - - byte2 = p - base64; /* next six: four plus two */ - *dst++ = byte1 | (byte2 >> 2); - byte1 = (byte2 & 0x3) << 6; - - p = strchr(base64, *src++); - if (p == NULL) - { - if (*(src-1) == '=') - { - if (byte1 != 0) /* bad padding */ - { - return BADPAD; - } - return 2; - } - return BADCH3; - } - byte2 = p - base64; /* last six */ - *dst++ = byte1 | byte2; - - return 3; -} - -/** - * @brief untext - convert one ASCII character to byte - * - * @param src known to be full length - * @param dst - * @param dstlen not large enough is a failure - * @return number of result bytes, or error code - */ -static int untext(const char *src, char *dst, size_t dstlen) -{ - if (dstlen < 1) - { - return SHORT; - } - *dst = *src; - return 1; -} - -/** - * @brief badch - produce a nice complaint about an unknown character - * - * If the compiler complains that the array bigenough[] has a negative - * size, that means the TTODATAV_BUF constant has been set too small. - * - * @param src - * @param errcode - * @param errp might be NULL - * @param errlen - * @return literal or errp - */ -static const char *badch(const char *src, int errcode, char *errp, size_t errlen) -{ - static const char pre[] = "unknown character (`"; - static const char suf[] = "') in input"; - char buf[5]; -# define REQD (sizeof(pre) - 1 + sizeof(buf) - 1 + sizeof(suf)) - struct sizecheck { - char bigenough[TTODATAV_BUF - REQD]; /* see above */ - }; - char ch; - - if (errp == NULL || errlen < REQD) - { - return "unknown character in input"; - } - strcpy(errp, pre); - ch = *(src + BADOFF(errcode)); - if (isprint(ch)) - { - buf[0] = ch; - buf[1] = '\0'; - } - else - { - buf[0] = '\\'; - buf[1] = ((ch & 0700) >> 6) + '0'; - buf[2] = ((ch & 0070) >> 3) + '0'; - buf[3] = ((ch & 0007) >> 0) + '0'; - buf[4] = '\0'; - } - strcat(errp, buf); - strcat(errp, suf); - return (const char *)errp; -} diff --git a/src/libstrongswan/asn1/ttodata.h b/src/libstrongswan/asn1/ttodata.h deleted file mode 100644 index 6125c6b82..000000000 --- a/src/libstrongswan/asn1/ttodata.h +++ /dev/null @@ -1,28 +0,0 @@ -/* - * convert from text form of arbitrary data (e.g., keys) to binary - * Copyright (C) 2000 Henry Spencer. - * - * This library is free software; you can redistribute it and/or modify it - * under the terms of the GNU Library General Public License as published by - * the Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. See <http://www.fsf.org/copyleft/lgpl.txt>. - * - * This library 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 Library General Public - * License for more details. - */ - -#ifndef TTODATA_H_ -#define TTODATA_H_ - -#include <library.h> - -#define TTODATAV_BUF 40 /* ttodatav's largest non-literal message */ -#define TTODATAV_IGNORESPACE (1<<1) /* ignore spaces in base64 encodings*/ -#define TTODATAV_SPACECOUNTS 0 /* do not ignore spaces in base64 */ - -err_t ttodata(const char *src, size_t srclen, int base, char *buf, size_t buflen, size_t *needed); - - -#endif /* TTODATA_H_ */ diff --git a/src/libstrongswan/chunk.c b/src/libstrongswan/chunk.c index 0d7841641..7e7a7c69d 100644 --- a/src/libstrongswan/chunk.c +++ b/src/libstrongswan/chunk.c @@ -1,10 +1,3 @@ -/** - * @file chunk.c - * - * @brief Pointer/lenght abstraction and its functions. - * - */ - /* * Copyright (C) 2005-2006 Martin Willi * Copyright (C) 2005 Jan Hutter @@ -19,16 +12,19 @@ * 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: chunk.c 3868 2008-04-24 13:26:22Z martin $ */ #include <stdio.h> #include <sys/stat.h> +#include <unistd.h> +#include <errno.h> #include "chunk.h" #include <debug.h> #include <printf_hook.h> -#include <utils/randomizer.h> /** * Empty chunk. @@ -211,43 +207,41 @@ void chunk_split(chunk_t chunk, const char *mode, ...) /** * Described in header. */ -bool chunk_write(chunk_t chunk, const char *path, const char *label, mode_t mask, bool force) +bool chunk_write(chunk_t chunk, char *path, mode_t mask, bool force) { mode_t oldmask; FILE *fd; + bool good = FALSE; - if (!force) + if (!force && access(path, F_OK) == 0) { - fd = fopen(path, "r"); - if (fd) - { - fclose(fd); - DBG1(" %s file '%s' already exists", label, path); - return FALSE; - } + DBG1(" file '%s' already exists", path); + return FALSE; } - - /* set umask */ oldmask = umask(mask); - fd = fopen(path, "w"); - if (fd) { - fwrite(chunk.ptr, sizeof(u_char), chunk.len, fd); + if (fwrite(chunk.ptr, sizeof(u_char), chunk.len, fd) == chunk.len) + { + good = TRUE; + } + else + { + DBG1(" writing to file '%s' failed: %s", path, strerror(errno)); + } fclose(fd); - DBG1(" written %s file '%s' (%u bytes)", label, path, chunk.len); - umask(oldmask); return TRUE; } else { - DBG1(" could not open %s file '%s' for writing", label, path); - umask(oldmask); - return FALSE; + DBG1(" could not open file '%s': %s", path, strerror(errno)); } + umask(oldmask); + return good; } + /** hex conversion digits */ static char hexdig_upper[] = "0123456789ABCDEF"; static char hexdig_lower[] = "0123456789abcdef"; @@ -255,10 +249,9 @@ static char hexdig_lower[] = "0123456789abcdef"; /** * Described in header. */ -char *chunk_to_hex(chunk_t chunk, bool uppercase) +chunk_t chunk_to_hex(chunk_t chunk, char *buf, bool uppercase) { - int i; - char *str; + int i, len;; char *hexdig = hexdig_lower; if (uppercase) @@ -266,51 +259,182 @@ char *chunk_to_hex(chunk_t chunk, bool uppercase) hexdig = hexdig_upper; } - str = malloc(chunk.len * 2 + 1); - str[chunk.len * 2] = '\0'; + len = chunk.len * 2; + if (!buf) + { + buf = malloc(len + 1); + } + buf[len] = '\0'; - for (i = 0; i < chunk.len; i ++) + for (i = 0; i < chunk.len; i++) { - str[i*2] = hexdig[(chunk.ptr[i] >> 4) & 0xF]; - str[i*2+1] = hexdig[(chunk.ptr[i] ) & 0xF]; + buf[i*2] = hexdig[(chunk.ptr[i] >> 4) & 0xF]; + buf[i*2+1] = hexdig[(chunk.ptr[i] ) & 0xF]; + } + return chunk_create(buf, len); +} + +/** + * convert a signle hex character to its binary value + */ +static char hex2bin(char hex) +{ + switch (hex) + { + case '0' ... '9': + return hex - '0'; + case 'A' ... 'F': + return hex - 'A' + 10; + case 'a' ... 'f': + return hex - 'a' + 10; + default: + return 0; } - return str; } /** * Described in header. */ -void chunk_free(chunk_t *chunk) +chunk_t chunk_from_hex(chunk_t hex, char *buf) { - free(chunk->ptr); - chunk->ptr = NULL; - chunk->len = 0; + int i, len; + + len = hex.len / 2; + if (!buf) + { + buf = malloc(len); + } + for (i = 0; i < len; i++) + { + buf[i] = hex2bin(*hex.ptr++) << 4; + buf[i] |= hex2bin(*hex.ptr++); + } + return chunk_create(buf, len); } +/** base 64 conversion digits */ +static char b64digits[] = + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; + /** * Described in header. */ -void chunk_free_randomized(chunk_t *chunk) +chunk_t chunk_to_base64(chunk_t chunk, char *buf) { - if (chunk->ptr) + int i, len; + char *pos; + + len = chunk.len + ((3 - chunk.len % 3) % 3); + if (!buf) { - if (chunk->len > 0) + buf = malloc(len * 4 / 3 + 1); + } + pos = buf; + for (i = 0; i < len; i+=3) + { + *pos++ = b64digits[chunk.ptr[i] >> 2]; + if (i+1 >= chunk.len) + { + *pos++ = b64digits[(chunk.ptr[i] & 0x03) << 4]; + *pos++ = '='; + *pos++ = '='; + break; + } + *pos++ = b64digits[((chunk.ptr[i] & 0x03) << 4) | (chunk.ptr[i+1] >> 4)]; + if (i+2 >= chunk.len) { - randomizer_t *randomizer = randomizer_create(); + *pos++ = b64digits[(chunk.ptr[i+1] & 0x0F) << 2]; + *pos++ = '='; + break; + } + *pos++ = b64digits[((chunk.ptr[i+1] & 0x0F) << 2) | (chunk.ptr[i+2] >> 6)]; + *pos++ = b64digits[chunk.ptr[i+2] & 0x3F]; + } + *pos = '\0'; + return chunk_create(buf, len * 4 / 3); +} + +/** + * convert a base 64 digit to its binary form (inversion of b64digits array) + */ +static int b642bin(char b64) +{ + switch (b64) + { + case 'A' ... 'Z': + return b64 - 'A'; + case 'a' ... 'z': + return ('Z' - 'A' + 1) + b64 - 'a'; + case '0' ... '9': + return ('Z' - 'A' + 1) + ('z' - 'a' + 1) + b64 - '0'; + case '+': + case '-': + return 62; + case '/': + case '_': + return 63; + case '=': + return 0; + default: + return -1; + } +} - randomizer->get_pseudo_random_bytes(randomizer, - chunk->len, chunk->ptr); - randomizer->destroy(randomizer); - }; - free(chunk->ptr); - chunk->ptr = NULL; +/** + * Described in header. + */ +chunk_t chunk_from_base64(chunk_t base64, char *buf) +{ + u_char *pos, byte[4]; + int i, j, len, outlen; + + len = base64.len / 4 * 3; + if (!buf) + { + buf = malloc(len); + } + pos = base64.ptr; + outlen = 0; + for (i = 0; i < len; i+=3) + { + outlen += 3; + for (j = 0; j < 4; j++) + { + if (*pos == '=') + { + outlen--; + } + byte[j] = b642bin(*pos++); + } + buf[i] = (byte[0] << 2) | (byte[1] >> 4); + buf[i+1] = (byte[1] << 4) | (byte[2] >> 2); + buf[i+2] = (byte[2] << 6) | (byte[3]); } + return chunk_create(buf, outlen); +} + +/** + * Described in header. + */ +void chunk_free(chunk_t *chunk) +{ + free(chunk->ptr); + chunk->ptr = NULL; chunk->len = 0; } /** * Described in header. */ +void chunk_clear(chunk_t *chunk) +{ + memset(chunk->ptr, 0, chunk->len); + chunk_free(chunk); +} + +/** + * Described in header. + */ chunk_t chunk_skip(chunk_t chunk, size_t bytes) { if (chunk.len > bytes) @@ -347,91 +471,21 @@ bool chunk_equals(chunk_t a, chunk_t b) } /** - * Described in header. - */ -bool chunk_equals_or_null(chunk_t a, chunk_t b) -{ - if (a.ptr == NULL || b.ptr == NULL) - return TRUE; - return a.len == b.len && memeq(a.ptr, b.ptr, a.len); -} - -/** - * Number of bytes per line to dump raw data - */ -#define BYTES_PER_LINE 16 - -/** - * output handler in printf() for byte ranges - */ -static int print_bytes(FILE *stream, const struct printf_info *info, - const void *const *args) -{ - char *bytes = *((void**)(args[0])); - int len = *((size_t*)(args[1])); - - char buffer[BYTES_PER_LINE * 3]; - char ascii_buffer[BYTES_PER_LINE + 1]; - char *buffer_pos = buffer; - char *bytes_pos = bytes; - char *bytes_roof = bytes + len; - int line_start = 0; - int i = 0; - int written = 0; - - written += fprintf(stream, "=> %d bytes @ %p", len, bytes); - - while (bytes_pos < bytes_roof) - { - *buffer_pos++ = hexdig_upper[(*bytes_pos >> 4) & 0xF]; - *buffer_pos++ = hexdig_upper[ *bytes_pos & 0xF]; - - ascii_buffer[i++] = - (*bytes_pos > 31 && *bytes_pos < 127) ? *bytes_pos : '.'; - - if (++bytes_pos == bytes_roof || i == BYTES_PER_LINE) - { - int padding = 3 * (BYTES_PER_LINE - i); - int written; - - while (padding--) - { - *buffer_pos++ = ' '; - } - *buffer_pos++ = '\0'; - ascii_buffer[i] = '\0'; - - written += fprintf(stream, "\n%4d: %s %s", - line_start, buffer, ascii_buffer); - - - buffer_pos = buffer; - line_start += BYTES_PER_LINE; - i = 0; - } - else - { - *buffer_pos++ = ' '; - } - } - return written; -} - -/** * output handler in printf() for chunks */ -static int print_chunk(FILE *stream, const struct printf_info *info, +static int chunk_print(FILE *stream, const struct printf_info *info, const void *const *args) { chunk_t *chunk = *((chunk_t**)(args[0])); bool first = TRUE; chunk_t copy = *chunk; int written = 0; + printf_hook_functions_t mem = mem_get_printf_hooks(); if (!info->alt) { const void *new_args[] = {&chunk->ptr, &chunk->len}; - return print_bytes(stream, info, new_args); + return mem.print(stream, info, new_args); } while (copy.len > 0) @@ -451,10 +505,24 @@ static int print_chunk(FILE *stream, const struct printf_info *info, } /** - * register printf() handlers + * arginfo handler for printf() mem ranges */ -static void __attribute__ ((constructor))print_register() +static int chunk_arginfo(const struct printf_info *info, size_t n, int *argtypes) { - register_printf_function(PRINTF_CHUNK, print_chunk, arginfo_ptr); - register_printf_function(PRINTF_BYTES, print_bytes, arginfo_ptr_int); + if (n > 0) + { + argtypes[0] = PA_POINTER; + } + return 1; } + +/** + * return printf hook functions for a chunk + */ +printf_hook_functions_t chunk_get_printf_hooks() +{ + printf_hook_functions_t hooks = {chunk_print, chunk_arginfo}; + + return hooks; +} + diff --git a/src/libstrongswan/chunk.h b/src/libstrongswan/chunk.h index 9c0aabba1..146b175d6 100644 --- a/src/libstrongswan/chunk.h +++ b/src/libstrongswan/chunk.h @@ -1,12 +1,5 @@ -/** - * @file chunk.h - * - * @brief Pointer/length abstraction and its functions. - * - */ - /* - * Copyright (C) 2005-2006 Martin Willi + * Copyright (C) 2005-2008 Martin Willi * Copyright (C) 2005 Jan Hutter * Hochschule fuer Technik Rapperswil * @@ -19,6 +12,13 @@ * 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: chunk.h 3868 2008-04-24 13:26:22Z martin $ + */ + +/** + * @defgroup chunk chunk + * @{ @ingroup libstrongswan */ #ifndef CHUNK_H_ @@ -26,8 +26,7 @@ #include <string.h> #include <stdarg.h> - -#include <library.h> +#include <sys/types.h> typedef struct chunk_t chunk_t; @@ -41,6 +40,8 @@ struct chunk_t { size_t len; }; +#include <library.h> + /** * A { NULL, 0 }-chunk handy for initialization. */ @@ -64,7 +65,7 @@ size_t chunk_length(const char *mode, ...); /** * Concatenate chunks into a chunk pointing to "ptr", * "mode" is a string of "c" (copy) and "m" (move), which says - * how to handle to chunks in "..." + * how to handle the chunks in "..." */ chunk_t chunk_create_cat(u_char *ptr, const char* mode, ...); @@ -81,12 +82,54 @@ void chunk_split(chunk_t chunk, const char *mode, ...); /** * Write the binary contents of a chunk_t to a file */ -bool chunk_write(chunk_t chunk, const char *path, const char *label, mode_t mask, bool force); +bool chunk_write(chunk_t chunk, char *path, mode_t mask, bool force); + +/** + * Convert a chunk of data to hex encoding. + * + * The resulting string is '\0' terminated, but the chunk does not include + * the '\0'. If buf is supplied, it must hold at least (chunk.len * 2 + 1). + * + * @param chunk data to convert + * @param buff buffer to write to, NULL to malloc + * @param uppercase TRUE to use uppercase letters + * @return chunk of encoded data + */ +chunk_t chunk_to_hex(chunk_t chunk, char *buf, bool uppercase); + +/** + * Convert a hex encoded in a binary chunk. + * + * If buf is supplied, it must hold at least (hex.len / 2). + * + * @param hex hex encoded input data + * @param buf buffer to write decoded data, NULL to malloc + * @return converted data + */ +chunk_t chunk_from_hex(chunk_t hex, char *buf); + +/** + * Convert a chunk of data to its base64 encoding. + * + * The resulting string is '\0' terminated, but the chunk does not include + * the '\0'. If buf is supplied, it must hold at least (chunk.len * 4 / 3 + 1). + * + * @param chunk data to convert + * @param buff buffer to write to, NULL to malloc + * @return chunk of encoded data + */ +chunk_t chunk_to_base64(chunk_t chunk, char *buf); /** - * convert a chunk to an allocated hex string + * Convert a base64 in a binary chunk. + * + * If buf is supplied, it must hold at least (base64.len / 4 * 3). + * + * @param base64 base64 encoded input data + * @param buf buffer to write decoded data, NULL to malloc + * @return converted data */ -char *chunk_to_hex(chunk_t chunk, bool uppercase); +chunk_t chunk_from_base64(chunk_t base64, char *buf); /** * Free contents of a chunk @@ -94,9 +137,9 @@ char *chunk_to_hex(chunk_t chunk, bool uppercase); void chunk_free(chunk_t *chunk); /** - * Overwrite the contents of a chunk with pseudo-random bytes and free them + * Overwrite the contents of a chunk and free it */ -void chunk_free_randomized(chunk_t *chunk); +void chunk_clear(chunk_t *chunk); /** * Initialize a chunk to point to buffer inspectable by sizeof() @@ -156,9 +199,11 @@ int chunk_compare(chunk_t a, chunk_t b); bool chunk_equals(chunk_t a, chunk_t b); /** - * Compare two chunks for equality, - * NULL chunks are always equal. + * Get printf hooks for a chunk. + * + * Arguments are: + * chunk_t *chunk */ -bool chunk_equals_or_null(chunk_t a, chunk_t b); +printf_hook_functions_t chunk_get_printf_hooks(); -#endif /* CHUNK_H_ */ +#endif /* CHUNK_H_ @}*/ diff --git a/src/libstrongswan/credential_store.h b/src/libstrongswan/credential_store.h deleted file mode 100755 index 62b6ad2d5..000000000 --- a/src/libstrongswan/credential_store.h +++ /dev/null @@ -1,330 +0,0 @@ -/** - * @file credential_store.h - * - * @brief Interface credential_store_t. - * - */ - -/* - * 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. - */ - -#ifndef CREDENTIAL_STORE_H_ -#define CREDENTIAL_STORE_H_ - -typedef struct credential_store_t credential_store_t; - -#include <library.h> -#include <crypto/x509.h> -#include <crypto/ca.h> -#include <crypto/rsa/rsa_private_key.h> -#include <crypto/rsa/rsa_public_key.h> -#include <utils/identification.h> - - -/** - * @brief The interface for a credential_store backend. - * - * @b Constructors: - * - stroke_create() - * - * @ingroup config - */ -struct credential_store_t { - - /** - * @brief Returns the secret shared by two specific IDs. - * - * The returned chunk must be destroyed by the caller after usage. - * - * @param this calling object - * @param my_id my ID identifiying the secret. - * @param other_id peer ID identifying the secret. - * @param[out] secret the pre-shared secret will be written there. - * @return - * - NOT_FOUND if no preshared secrets for specific ID could be found - * - SUCCESS - * - */ - status_t (*get_shared_key) (credential_store_t *this, identification_t *my_id, - identification_t *other_id, chunk_t *shared_key); - - /** - * @brief Returns the EAP secret for two specified IDs. - * - * The returned chunk must be destroyed by the caller after usage. - * - * @param this calling object - * @param my_id my ID identifiying the secret. - * @param other_id peer ID identifying the secret. - * @param[out] eap_key the EAP secret will be written here - * @return - * - NOT_FOUND if no preshared secrets for specific ID could be found - * - SUCCESS - * - */ - status_t (*get_eap_key) (credential_store_t *this, identification_t *my_id, - identification_t *other_id, chunk_t *eap_key); - - /** - * @brief Returns the RSA public key of a specific ID. - * - * @param this calling object - * @param id identification_t object identifiying the key. - * @return public key, or NULL if not found - */ - rsa_public_key_t* (*get_rsa_public_key) (credential_store_t *this, identification_t *id); - - /** - * @brief Is there a matching RSA private key belonging to an RSA public key? - * - * @param this calling object - * @param pubkey public key - * @return TRUE if matching private key was found - */ - bool (*has_rsa_private_key) (credential_store_t *this, rsa_public_key_t *pubkey); - - /** - * @brief Returns the certificate of a specific ID. - * - * @param this calling object - * @param id identification_t object identifiying the cert. - * @return certificate, or NULL if not found - */ - x509_t* (*get_certificate) (credential_store_t *this, identification_t *id); - - /** - * @brief Returns the auth certificate of a specific subject distinguished name. - * - * @param this calling object - * @param auth_flags set of allowed authority types - * @param id identification_t object identifiying the cacert. - * @return certificate, or NULL if not found - */ - x509_t* (*get_auth_certificate) (credential_store_t *this, u_int auth_flags, identification_t *id); - - /** - * @brief Returns the ca certificate of a specific keyID. - * - * @param this calling object - * @param keyid identification_t object identifiying the cacert. - * @return certificate, or NULL if not found - */ - x509_t* (*get_ca_certificate_by_keyid) (credential_store_t *this, chunk_t keyid); - - /** - * @brief Returns the issuing ca of a given certificate. - * - * @param this calling object - * @param cert certificate for which issuer ca info is required - * @return ca info, or NULL if not found - */ - ca_info_t* (*get_issuer) (credential_store_t *this, x509_t* cert); - - /** - * @brief RSA private key belonging to an RSA public key - * - * - * @param this calling object - * @param pubkey public key used to find the matching private key - * @param hash_algorithm hash algorithm to be used for signature - * @param data data block to be signed - * @param signature signature to be returned - * @return status of the signature process - SUCCESS if successful - */ - status_t (*rsa_signature) (credential_store_t *this, rsa_public_key_t *pubkey, hash_algorithm_t hash_algorithm, - chunk_t data, chunk_t *signature); - - /** - * @brief Verify an RSA signature given the ID of the signer - * - * @param this calling object - * @param hash hash value to be verified. - * @param sig signature to be verified. - * @param id identification_t object identifiying the signer. - * @param issuer_p issuer of the signer's certificate (if not self-signed). - * @return status of the verification - SUCCESS if successful - */ - status_t (*verify_signature) (credential_store_t *this, chunk_t hash, chunk_t sig, identification_t *id, - ca_info_t **issuer_p); - - /** - * @brief Verify an X.509 certificate up to trust anchor without any status checks - * - * @param this calling object - * @param label label characterizing the certificate to be verified - * @param cert certificate to be verified - * @return TRUE if trusted - */ - bool (*is_trusted) (credential_store_t *this, const char *label, x509_t *cert); - - /** - * @brief Verify an X.509 certificate up to trust anchor including status checks - * - * @param this calling object - * @param cert certificate to be verified - * @param found found a certificate copy in the credential store - * @return TRUE if valid, trusted, and current status is good - */ - bool (*verify) (credential_store_t *this, x509_t *cert, bool *found); - - /** - * @brief If an end certificate does not already exists in the credential store then add it. - * - * @param this calling object - * @param cert certificate to be added - * @return pointer to the added or already existing certificate - */ - x509_t* (*add_end_certificate) (credential_store_t *this, x509_t *cert); - - /** - * @brief If an authority certificate does not already exists in the credential store then add it. - * - * @param this calling object - * @param cert authority certificate to be added - * @param auth_flag authority flags to add to the certificate - * @return pointer to the added or already existing certificate - */ - x509_t* (*add_auth_certificate) (credential_store_t *this, x509_t *cert, u_int auth_flag); - - /** - * @brief If a ca info record does not already exists in the credential store then add it. - * - * @param this calling object - * @param ca_info ca info record to be added - * @return pointer to the added or already existing ca_info_t record - */ - ca_info_t* (*add_ca_info) (credential_store_t *this, ca_info_t *ca_info); - - /** - * @brief Release a ca info record with a given name. - * - * @param this calling object - * @param name name of the ca info record to be released - * @return - * - SUCCESS, or - * - NOT_FOUND - */ - status_t (*release_ca_info) (credential_store_t *this, const char *name); - - /** - * @brief Create an iterator over all end certificates. - * - * @param this calling object - * @return iterator - */ - iterator_t* (*create_cert_iterator) (credential_store_t *this); - - /** - * @brief Create an iterator over all authority certificates. - * - * @param this calling object - * @return iterator - */ - iterator_t* (*create_auth_cert_iterator) (credential_store_t *this); - - /** - * @brief Create an iterator over all CA info records - * - * @param this calling object - * @return iterator - */ - iterator_t* (*create_cainfo_iterator) (credential_store_t *this); - - /** - * @brief Create an iterator over all attribute certificates. - * - * @param this calling object - * @return iterator - */ - iterator_t* (*create_acert_iterator) (credential_store_t *this); - - /** - * @brief Loads ca certificates from a default directory. - * - * Certificates in both DER and PEM format are accepted - * - * @param this calling object - */ - void (*load_ca_certificates) (credential_store_t *this); - - /** - * @brief Loads authorization authority certificates from a default directory. - * - * Certificates in both DER and PEM format are accepted - * - * @param this calling object - */ - void (*load_aa_certificates) (credential_store_t *this); - - /** - * @brief Loads attribute certificates from a default directory. - * - * Certificates in both DER and PEM format are accepted - * - * @param this calling object - */ - void (*load_attr_certificates) (credential_store_t *this); - - /** - * @brief Loads ocsp certificates from a default directory. - * - * Certificates in both DER and PEM format are accepted - * - * @param this calling object - */ - void (*load_ocsp_certificates) (credential_store_t *this); - - /** - * @brief Loads CRLs from a default directory. - * - * Certificates in both DER and PEM format are accepted - * - * @param this calling object - * @param path directory to load crls from - */ - void (*load_crls) (credential_store_t *this); - - /** - * @brief Loads secrets in ipsec.secrets - * - * RSA private key files can be either in DER or PEM format - * Optional encryption with a passphrase supported - * - * @param this calling object - * @param reload are the secrets to be reloaded - */ - void (*load_secrets) (credential_store_t *this, bool reload); - - /** - * @brief Destroys a credential_store_t object. - * - * @param this calling object - */ - void (*destroy) (credential_store_t *this); -}; - -/** - * @brief Creates a credential_store_t instance. - * - * @param strict enforce a strict crl policy - * @return credential store instance. - * - * @ingroup config - */ -credential_store_t *credential_store_create(bool strict); - - -#endif /*CREDENTIAL_STORE_H_*/ diff --git a/src/libstrongswan/credentials/builder.c b/src/libstrongswan/credentials/builder.c new file mode 100644 index 000000000..c13a8a860 --- /dev/null +++ b/src/libstrongswan/credentials/builder.c @@ -0,0 +1,38 @@ +/* + * 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. + */ + +#include "builder.h" + +ENUM(builder_part_names, BUILD_BLOB_ASN1_DER, BUILD_END, + "BUILD_FROM_FILE", + "BUILD_BLOB_ASN1_DER", + "BUILD_BLOB_ASN1_PEM", + "BUILD_KEY_SIZE", + "BUILD_SIGNING_KEY", + "BUILD_SIGNING_CERT", + "BUILD_PUBLIC_KEY", + "BUILD_SUBJECT", + "BUILD_SUBJECT_ALTNAME", + "BUILD_ISSUER", + "BUILD_ISSUER_ALTNAME", + "BUILD_NOT_BEFORE_TIME", + "BUILD_NOT_AFTER_TIME", + "BUILD_SERIAL", + "BUILD_IETF_GROUP_ATTR", + "BUILD_CA_CERT", + "BUILD_CERT", + "BUILD_X509_FLAG", + "BUILD_END", +); diff --git a/src/libstrongswan/credentials/builder.h b/src/libstrongswan/credentials/builder.h new file mode 100644 index 000000000..22c106b7a --- /dev/null +++ b/src/libstrongswan/credentials/builder.h @@ -0,0 +1,115 @@ +/* + * 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 builder builder + * @{ @ingroup credentials + */ + +#ifndef BUILDER_H_ +#define BUILDER_H_ + +typedef struct builder_t builder_t; +typedef enum builder_part_t builder_part_t; + +/** + * Constructor function which creates a new builder instance. + * + * @param subtype constructor specific subtype, e.g. certificate_type_t + * @return builder to construct a instance of type + */ +typedef builder_t* (*builder_constructor_t)(int subtype); + +#include <library.h> + +/** + * Parts to build credentials from. + */ +enum builder_part_t { + /** path to a file containing an ASN1 blob, char* */ + BUILD_FROM_FILE, + /** DER encoded ASN1 blob, chunk_t */ + BUILD_BLOB_ASN1_DER, + /** PEM encoded ASN1 blob, null terminated char* */ + BUILD_BLOB_ASN1_PEM, + /** key size in bits, as used for key generation, u_int */ + BUILD_KEY_SIZE, + /** private key to use for signing, private_key_t* */ + BUILD_SIGNING_KEY, + /** certificate used for signing, certificate_t* */ + BUILD_SIGNING_CERT, + /** public key to include, public_key_t* */ + BUILD_PUBLIC_KEY, + /** subject for e.g. certificates, identification_t* */ + BUILD_SUBJECT, + /** additional subject name, identification_t* */ + BUILD_SUBJECT_ALTNAME, + /** issuer for e.g. certificates, identification_t* */ + BUILD_ISSUER, + /** additional issuer name, identification_t* */ + BUILD_ISSUER_ALTNAME, + /** notBefore, time_t* */ + BUILD_NOT_BEFORE_TIME, + /** notAfter, time_t* */ + BUILD_NOT_AFTER_TIME, + /** a serial number in binary form, chunk_t */ + BUILD_SERIAL, + /** a comma-separated list of ietf group attributes, char* */ + BUILD_IETF_GROUP_ATTR, + /** a ca certificate, certificate_t* */ + BUILD_CA_CERT, + /** a certificate, certificate_t* */ + BUILD_CERT, + /** enforce an additional X509 flag, x509_flag_t */ + BUILD_X509_FLAG, + /** end of variable argument builder list */ + BUILD_END, +}; + +/** + * enum names for build_part_t + */ +extern enum_name_t *builder_part_names; + +/** + * Credential construction API. + * + * The builder allows the construction of credentials in a generic and + * flexible way. + */ +struct builder_t { + + /** + * Add a part to the construct. + * + * Any added parts get owned by the builder/construct, so clone/refcount + * them if needed. + * + * @param part kind of part + * @param ... part specific variable argument + */ + void (*add)(builder_t *this, builder_part_t part, ...); + + /** + * Build the construct with all supplied parts. + * + * Once build() is called, the builder gets destroyed. + * + * @return specific interface, as requested with constructor. + */ + void* (*build)(builder_t *this); +}; + +#endif /* BUILDER_H_ @}*/ diff --git a/src/libstrongswan/credentials/certificates/ac.h b/src/libstrongswan/credentials/certificates/ac.h new file mode 100644 index 000000000..4e33390bb --- /dev/null +++ b/src/libstrongswan/credentials/certificates/ac.h @@ -0,0 +1,86 @@ +/* + * 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: ac.h 3300 2007-10-12 21:53:18Z andreas $ + */ + +/** + * @defgroup ac ac + * @{ @ingroup certificates + */ + +#ifndef AC_H_ +#define AC_H_ + +#include <library.h> +#include <credentials/certificates/certificate.h> + +typedef struct ac_t ac_t; + +/** + * X.509 attribute certificate interface. + * + * This interface adds additional methods to the certificate_t type to + * allow further operations on these certificates. + */ +struct ac_t { + + /** + * Implements the certificate_t interface + */ + certificate_t certificate; + + /** + * Get the attribute certificate's serial number. + * + * @return chunk pointing to serialNumber + */ + chunk_t (*get_serial)(ac_t *this); + + /** + * Get the serial number of the holder certificate. + * + * @return chunk pointing to serialNumber + */ + chunk_t (*get_holderSerial)(ac_t *this); + + /** + * Get the issuer of the holder certificate. + * + * @return holderIssuer as identification_t* + */ + identification_t* (*get_holderIssuer)(ac_t *this); + + /** + * Get the thauthorityKeyIdentifier. + * + * @return authKeyIdentifier as identification_t* + */ + identification_t* (*get_authKeyIdentifier)(ac_t *this); + + /** + * @brief Checks if two attribute certificates belong to the same holder + * + * @param this calling attribute certificate + * @param that other attribute certificate + * @return TRUE if same holder + */ + bool (*equals_holder) (ac_t *this, ac_t *other); +}; + +#endif /* AC_H_ @}*/ + diff --git a/src/libstrongswan/credentials/certificates/certificate.c b/src/libstrongswan/credentials/certificates/certificate.c new file mode 100644 index 000000000..c5bc9a68d --- /dev/null +++ b/src/libstrongswan/credentials/certificates/certificate.c @@ -0,0 +1,41 @@ +/* + * 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: certificate.c 3664 2008-03-26 15:21:50Z martin $ + */ + +#include "certificate.h" + +#include <credentials/certificates/x509.h> + +ENUM(certificate_type_names, CERT_ANY, CERT_PGP, + "ANY", + "X509", + "X509_CRL", + "X509_OCSP_REQUEST", + "X509_OCSP_RESPONSE", + "X509_AC", + "X509_CHAIN", + "TRUSTED_PUBKEY", + "PGP", +); + +ENUM(cert_validation_names, VALIDATION_GOOD, VALIDATION_SKIPPED, + "VALIDATION_GOOD", + "VALIDATION_STALE", + "VALIDATION_REVOKED", + "VALIDATION_FAILED", + "VALIDATION_SKIPPED", +); + diff --git a/src/libstrongswan/credentials/certificates/certificate.h b/src/libstrongswan/credentials/certificates/certificate.h new file mode 100644 index 000000000..14f4de389 --- /dev/null +++ b/src/libstrongswan/credentials/certificates/certificate.h @@ -0,0 +1,192 @@ +/* + * 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 certificate certificate + * @{ @ingroup certificates + */ + +#ifndef CERTIFICATE_H_ +#define CERTIFICATE_H_ + +typedef struct certificate_t certificate_t; +typedef enum certificate_type_t certificate_type_t; +typedef enum cert_validation_t cert_validation_t; + +#include <library.h> +#include <utils/identification.h> +#include <credentials/keys/public_key.h> + +/** + * Kind of a certificate_t + */ +enum certificate_type_t { + /** just any certificate */ + CERT_ANY, + /** X.509 certificate */ + CERT_X509, + /** X.509 certificate revocation list */ + CERT_X509_CRL, + /** X.509 online certificate status protocol request */ + CERT_X509_OCSP_REQUEST, + /** X.509 online certificate status protocol response */ + CERT_X509_OCSP_RESPONSE, + /** X.509 attribute certificate */ + CERT_X509_AC, + /** trusted, preinstalled public key */ + CERT_TRUSTED_PUBKEY, + /** PGP certificate */ + CERT_PGP, +}; + +/** + * Enum names for certificate_type_t + */ +extern enum_name_t *certificate_type_names; + +/** + * Result of a certificate validation. + */ +enum cert_validation_t { + /** certificate has been validated successfully */ + VALIDATION_GOOD, + /** certificate has been validated, but check based on stale information */ + VALIDATION_STALE, + /** certificate has been revoked */ + VALIDATION_REVOKED, + /** validation failed due to a processing error */ + VALIDATION_FAILED, + /** validation has been skipped due to missing validation information */ + VALIDATION_SKIPPED, +}; + +/** + * Enum names for cert_validation_t + */ +extern enum_name_t *cert_validation_names; + +/** + * An abstract certificate. + * + * A certificate designs a subject-issuer relationship. It may have an + * associated public key. + */ +struct certificate_t { + + /** + * Get the type of the certificate. + * + * @return certifcate type + */ + certificate_type_t (*get_type)(certificate_t *this); + + /** + * Get the primary subject to which this certificate belongs. + * + * @return subject identity + */ + identification_t* (*get_subject)(certificate_t *this); + + /** + * Check if certificate contains a subject ID. + * + * A certificate may contain additional subject identifiers, which are + * not returned by get_subject (e.g. subjectAltNames) + * + * @param subject subject identity + * @return matching value of best match + */ + id_match_t (*has_subject)(certificate_t *this, identification_t *subject); + + /** + * Get the issuer which signed this certificate. + * + * @return issuer identity + */ + identification_t* (*get_issuer)(certificate_t *this); + + /** + * Check if certificate contains an issuer ID. + * + * A certificate may contain additional issuer identifiers, which are + * not returned by get_issuer (e.g. issuerAltNames) + * + * @param subject isser identity + * @return matching value of best match + */ + id_match_t (*has_issuer)(certificate_t *this, identification_t *issuer); + + /** + * Check if this certificate is issued and signed by a specific issuer. + * + * @param issuer issuer's certificate + * @return TRUE if certificate issued by issuer and trusted + */ + bool (*issued_by)(certificate_t *this, certificate_t *issuer); + + /** + * Get the public key associated to this certificate. + * + * @return newly referenced public_key, NULL if none available + */ + public_key_t* (*get_public_key)(certificate_t *this); + + /** + * Check the lifetime of the certificate. + * + * @param when check validity at a certain time (NULL for now) + * @param not_before receives certificates start of lifetime + * @param not_after receives certificates end of lifetime + * @return TRUE if when between not_after and not_before + */ + bool (*get_validity)(certificate_t *this, time_t *when, + time_t *not_before, time_t *not_after); + + /** + * Is this newer than that? + * + * @return TRUE if newer, FALSE otherwise + */ + bool (*is_newer)(certificate_t *this, certificate_t *that); + + /** + * Get the certificate in an encoded form. + * + * @return allocated chunk of encoded cert + */ + chunk_t (*get_encoding)(certificate_t *this); + + /** + * Check if two certificates are equal. + * + * @param other certificate to compair against this + * @return TRUE if certificates are equal + */ + bool (*equals)(certificate_t *this, certificate_t *other); + + /** + * Get a new reference to the certificate. + * + * @return this, with an increased refcount + */ + certificate_t* (*get_ref)(certificate_t *this); + + /** + * Destroy a certificate. + */ + void (*destroy)(certificate_t *this); +}; + +#endif /* CERTIFICATE_H_ @}*/ diff --git a/src/libstrongswan/credentials/certificates/crl.c b/src/libstrongswan/credentials/certificates/crl.c new file mode 100644 index 000000000..1fdc095c1 --- /dev/null +++ b/src/libstrongswan/credentials/certificates/crl.c @@ -0,0 +1,31 @@ +/* + * Copyright (C) 2008 Martin Willi + * Copyright (C) 2006 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: crl.c 3656 2008-03-25 22:28:27Z andreas $ + */ + +#include "crl.h" + +ENUM(crl_reason_names, CRL_UNSPECIFIED, CRL_REMOVE_FROM_CRL, + "unspecified", + "key compromise", + "ca compromise", + "affiliation changed", + "superseded", + "cessation of operation", + "certificate hold", + "reason #7", + "remove from crl", +); diff --git a/src/libstrongswan/credentials/certificates/crl.h b/src/libstrongswan/credentials/certificates/crl.h new file mode 100644 index 000000000..f1fb70efd --- /dev/null +++ b/src/libstrongswan/credentials/certificates/crl.h @@ -0,0 +1,88 @@ +/* + * Copyright (C) 2008 Martin Willi + * Copyright (C) 2006 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: crl.h 3656 2008-03-25 22:28:27Z andreas $ + */ + +/** + * @defgroup crl crl + * @{ @ingroup certificates + */ + +#ifndef CRL_H_ +#define CRL_H_ + +typedef struct crl_t crl_t; +typedef enum crl_reason_t crl_reason_t; + +#include <library.h> +#include <credentials/certificates/certificate.h> + +/** + * RFC 2459 CRL reason codes + */ +enum crl_reason_t { + CRL_UNSPECIFIED = 0, + CRL_KEY_COMPROMISE = 1, + CRL_CA_COMPROMISE = 2, + CRL_AFFILIATION_CHANGED = 3, + CRL_SUPERSEDED = 4, + CRL_CESSATION_OF_OPERATON = 5, + CRL_CERTIFICATE_HOLD = 6, + CRL_REMOVE_FROM_CRL = 8, +}; + +/** + * enum names for crl_reason_t + */ +extern enum_name_t *crl_reason_names; + +/** + * X509 certificate revocation list (CRL) interface definition. + */ +struct crl_t { + + /** + * Implements (parts of) the certificate_t interface + */ + certificate_t certificate; + + /** + * Get the CRL serial number. + * + * @return chunk pointing to internal crlNumber + */ + chunk_t (*get_serial)(crl_t *this); + + /** + * Get the the authorityKeyIdentifier. + * + * @return authKeyIdentifier as identification_t* + */ + identification_t* (*get_authKeyIdentifier)(crl_t *this); + + /** + * Create an enumerator over all revoked certificates. + * + * The enumerator takes 3 pointer arguments: + * chunk_t serial, time_t revocation_date, crl_reason_t reason + * + * @return enumerator over revoked certificates. + */ + enumerator_t* (*create_enumerator)(crl_t *this); + +}; + +#endif /* CRL_H_ @}*/ diff --git a/src/libstrongswan/credentials/certificates/ocsp_request.h b/src/libstrongswan/credentials/certificates/ocsp_request.h new file mode 100644 index 000000000..377eabd23 --- /dev/null +++ b/src/libstrongswan/credentials/certificates/ocsp_request.h @@ -0,0 +1,41 @@ +/* + * 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 ocsp_request ocsp_request + * @{ @ingroup certificates + */ + +#ifndef OCSP_REQUEST_H_ +#define OCSP_REQUEST_H_ + +#include <credentials/certificates/certificate.h> + +typedef struct ocsp_request_t ocsp_request_t; + +/** + * OCSP request message. + */ +struct ocsp_request_t { + + /** + * Implements certificiate_t interface + */ + certificate_t interface; +}; + +#endif /* OCSP_REQUEST_H_ @}*/ diff --git a/src/libstrongswan/credentials/certificates/ocsp_response.c b/src/libstrongswan/credentials/certificates/ocsp_response.c new file mode 100644 index 000000000..02e12f761 --- /dev/null +++ b/src/libstrongswan/credentials/certificates/ocsp_response.c @@ -0,0 +1,29 @@ +/* + * 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 "ocsp_response.h" + +ENUM(ocsp_status_names, OCSP_SUCCESSFUL, OCSP_UNAUTHORIZED, + "successful", + "malformed request", + "internal error", + "try later", + "status #4", + "signature required", + "unauthorized" +); + diff --git a/src/libstrongswan/credentials/certificates/ocsp_response.h b/src/libstrongswan/credentials/certificates/ocsp_response.h new file mode 100644 index 000000000..416f712f3 --- /dev/null +++ b/src/libstrongswan/credentials/certificates/ocsp_response.h @@ -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$ + */ + +/** + * @defgroup ocsp_response ocsp_response + * @{ @ingroup certificates + */ + +#ifndef OCSP_RESPONSE_H_ +#define OCSP_RESPONSE_H_ + +#include <credentials/certificates/x509.h> +#include <credentials/certificates/crl.h> + +typedef struct ocsp_response_t ocsp_response_t; +typedef enum ocsp_status_t ocsp_status_t; + +/** + * OCSP response status + */ +enum ocsp_status_t { + OCSP_SUCCESSFUL = 0, + OCSP_MALFORMEDREQUEST = 1, + OCSP_INTERNALERROR = 2, + OCSP_TRYLATER = 3, + OCSP_SIGREQUIRED = 5, + OCSP_UNAUTHORIZED = 6, +}; + +/** + * enum names for ocsp_status_t + */ +extern enum_name_t *ocsp_status_names; + +/** + * OCSP response message. + */ +struct ocsp_response_t { + + /** + * Implements certificiate_t interface + */ + certificate_t certificate; + + /** + * Check the status of a certificate by this OCSP response. + * + * @param subject certificate to check status + * @param issuer issuer certificate of subject + * @param revocation_time receives time of revocation, if revoked + * @param revocation_reason receives reason of revocation, if revoked + * @param this_update creation time of revocation list + * @param next_update exptected time of next revocation list + * @return certificate revocation status + */ + cert_validation_t (*get_status)(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); + + /** + * Create an enumerator over the contained certificates. + * + * @return enumerator over certificate_t* + */ + enumerator_t* (*create_cert_enumerator)(ocsp_response_t *this); +}; + +#endif /* OCSP_RESPONSE_H_ @}*/ diff --git a/src/libstrongswan/credentials/certificates/x509.c b/src/libstrongswan/credentials/certificates/x509.c new file mode 100644 index 000000000..15d223e3e --- /dev/null +++ b/src/libstrongswan/credentials/certificates/x509.c @@ -0,0 +1,26 @@ +/* + * 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.c 3656 2008-03-25 22:28:27Z andreas $ + */ + +#include "x509.h" + +ENUM(x509_flag_names, X509_CA, X509_SELF_SIGNED, + "X509_CA", + "X509_AA", + "X509_OCSP_SIGNER", + "X509_SELF_SIGNED", +); + diff --git a/src/libstrongswan/credentials/certificates/x509.h b/src/libstrongswan/credentials/certificates/x509.h new file mode 100644 index 000000000..737dcdc67 --- /dev/null +++ b/src/libstrongswan/credentials/certificates/x509.h @@ -0,0 +1,107 @@ +/* + * 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. + * + * $Id: x509.h 3656 2008-03-25 22:28:27Z andreas $ + */ + +/** + * @defgroup x509 x509 + * @{ @ingroup certificates + */ + +#ifndef X509_H_ +#define X509_H_ + +#include <utils/enumerator.h> +#include <credentials/certificates/certificate.h> + +typedef struct x509_t x509_t; +typedef enum x509_flag_t x509_flag_t; + +/** + * X.509 certificate flags. + */ +enum x509_flag_t { + /** cert has CA constraint */ + X509_CA = (1<<0), + /** cert has AA constraint */ + X509_AA = (1<<1), + /** cert has OCSP signer constraint */ + X509_OCSP_SIGNER = (1<<2), + /** cert is self-signed */ + X509_SELF_SIGNED = (1<<3), +}; + +/** + * enum names for x509 flags + */ +extern enum_name_t *x509_flag_names; + +/** + * X.509 certificate interface. + * + * This interface adds additional methods to the certificate_t type to + * allow further operations on these certificates. + */ +struct x509_t { + + /** + * Implements certificate_t. + */ + certificate_t interface; + + /** + * Get the flags set for this certificate. + * + * @return set of flags + */ + x509_flag_t (*get_flags)(x509_t *this); + + /** + * Get the certificate serial number. + * + * @return chunk pointing to internal serial number + */ + chunk_t (*get_serial)(x509_t *this); + + /** + * Get the the authorityKeyIdentifier. + * + * @return authKeyIdentifier as identification_t* + */ + identification_t* (*get_authKeyIdentifier)(x509_t *this); + + /** + * Create an enumerator over all subjectAltNames. + * + * @return enumerator over subjectAltNames as identification_t* + */ + enumerator_t* (*create_subjectAltName_enumerator)(x509_t *this); + + /** + * Create an enumerator over all CRL URIs. + * + * @return enumerator over URIs as char* + */ + enumerator_t* (*create_crl_uri_enumerator)(x509_t *this); + + /** + * Create an enumerator over all OCSP URIs. + * + * @return enumerator over URIs as char* + */ + enumerator_t* (*create_ocsp_uri_enumerator)(x509_t *this); +}; + +#endif /* X509_H_ @}*/ diff --git a/src/libstrongswan/credentials/credential_factory.c b/src/libstrongswan/credentials/credential_factory.c new file mode 100644 index 000000000..52ee2060d --- /dev/null +++ b/src/libstrongswan/credentials/credential_factory.c @@ -0,0 +1,312 @@ +/* + * 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: credential_factory.c 4059 2008-06-11 14:10:02Z martin $ + */ + +#include "credential_factory.h" + +#include <debug.h> +#include <utils/linked_list.h> +#include <utils/mutex.h> +#include <credentials/certificates/x509.h> + +ENUM(credential_type_names, CRED_PRIVATE_KEY, CRED_CERTIFICATE, + "CRED_PRIVATE_KEY", + "CRED_PUBLIC_KEY", + "CRED_CERTIFICATE", +); + +typedef struct private_credential_factory_t private_credential_factory_t; + +/** + * private data of credential_factory + */ +struct private_credential_factory_t { + + /** + * public functions + */ + credential_factory_t public; + + /** + * list with entry_t + */ + linked_list_t *constructors; + + /** + * mutex to lock access to modules + */ + mutex_t *mutex; +}; + +typedef struct entry_t entry_t; +struct entry_t { + /** kind of credential builder */ + credential_type_t type; + /** subtype of credential, e.g. certificate_type_t */ + int subtype; + /** builder construction function */ + builder_constructor_t constructor; +}; + +/** + * Implementation of credential_factory_t.create_builder. + */ +static builder_t* create_builder(private_credential_factory_t *this, + credential_type_t type, int subtype) +{ + enumerator_t *enumerator; + entry_t *entry; + builder_t *builder = NULL; + + this->mutex->lock(this->mutex); + enumerator = this->constructors->create_enumerator(this->constructors); + while (enumerator->enumerate(enumerator, &entry)) + { + if (entry->type == type && entry->subtype == subtype) + { + builder = entry->constructor(subtype); + if (builder) + { + break; + } + } + } + enumerator->destroy(enumerator); + this->mutex->unlock(this->mutex); + return builder; +} + +/** + * Implementation of credential_factory_t.add_builder_constructor. + */ +static void add_builder(private_credential_factory_t *this, + credential_type_t type, int subtype, + builder_constructor_t constructor) +{ + entry_t *entry = malloc_thing(entry_t); + + entry->type = type; + entry->subtype = subtype; + entry->constructor = constructor; + this->mutex->lock(this->mutex); + this->constructors->insert_last(this->constructors, entry); + this->mutex->unlock(this->mutex); +} + +/** + * Implementation of credential_factory_t.remove_builder. + */ +static void remove_builder(private_credential_factory_t *this, + builder_constructor_t constructor) +{ + enumerator_t *enumerator; + entry_t *entry; + + this->mutex->lock(this->mutex); + enumerator = this->constructors->create_enumerator(this->constructors); + while (enumerator->enumerate(enumerator, &entry)) + { + if (entry->constructor == constructor) + { + this->constructors->remove_at(this->constructors, enumerator); + free(entry); + } + } + enumerator->destroy(enumerator); + this->mutex->unlock(this->mutex); +} + +/** + * Implementation of credential_factory_t.create. + */ +static void* create(private_credential_factory_t *this, credential_type_t type, + int subtype, ...) +{ + builder_t *builder; + builder_part_t part; + va_list args; + + builder = create_builder(this, type, subtype); + if (builder) + { + va_start(args, subtype); + while (TRUE) + { + part = va_arg(args, builder_part_t); + + switch (part) + { + case BUILD_END: + break; + case BUILD_BLOB_ASN1_DER: + case BUILD_SERIAL: + builder->add(builder, part, va_arg(args, chunk_t)); + continue; + case BUILD_X509_FLAG: + builder->add(builder, part, va_arg(args, x509_flag_t)); + continue; + case BUILD_KEY_SIZE: + builder->add(builder, part, va_arg(args, u_int)); + continue; + case BUILD_NOT_BEFORE_TIME: + case BUILD_NOT_AFTER_TIME: + builder->add(builder, part, va_arg(args, time_t)); + continue; + case BUILD_BLOB_ASN1_PEM: + case BUILD_FROM_FILE: + case BUILD_SIGNING_KEY: + case BUILD_PUBLIC_KEY: + case BUILD_SUBJECT: + case BUILD_SUBJECT_ALTNAME: + case BUILD_ISSUER: + case BUILD_ISSUER_ALTNAME: + case BUILD_SIGNING_CERT: + case BUILD_CA_CERT: + case BUILD_CERT: + case BUILD_IETF_GROUP_ATTR: + builder->add(builder, part, va_arg(args, void*)); + continue; + default: + DBG1("builder part %N not supported by factory", + builder_part_names, part); + break; + } + break; + } + va_end(args); + + return builder->build(builder); + } + else + { + DBG1("failed to create a builder for credential type %N," + " subtype (%d)", credential_type_names, type, subtype); + } + + /** shredder all data on failure */ + va_start(args, subtype); + while (TRUE) + { + part = va_arg(args, builder_part_t); + + switch (part) + { + case BUILD_END: + break; + case BUILD_BLOB_ASN1_DER: + { + chunk_t chunk = va_arg(args, chunk_t); + free(chunk.ptr); + continue; + } + case BUILD_SERIAL: + { + va_arg(args, chunk_t); + continue; + } + case BUILD_X509_FLAG: + { + va_arg(args, x509_flag_t); + continue; + } + case BUILD_KEY_SIZE: + { + va_arg(args, u_int); + continue; + } + case BUILD_NOT_BEFORE_TIME: + case BUILD_NOT_AFTER_TIME: + { + va_arg(args, time_t); + continue; + } + case BUILD_SIGNING_KEY: + { + private_key_t *private = va_arg(args, private_key_t*); + private->destroy(private); + continue; + } + case BUILD_PUBLIC_KEY: + { + public_key_t *public = va_arg(args, public_key_t*); + public->destroy(public); + continue; + } + case BUILD_SUBJECT: + case BUILD_SUBJECT_ALTNAME: + case BUILD_ISSUER: + case BUILD_ISSUER_ALTNAME: + { + identification_t *id = va_arg(args, identification_t*); + id->destroy(id); + continue; + } + case BUILD_SIGNING_CERT: + case BUILD_CA_CERT: + case BUILD_CERT: + { + certificate_t *cert = va_arg(args, certificate_t*); + cert->destroy(cert); + continue; + } + case BUILD_BLOB_ASN1_PEM: + case BUILD_FROM_FILE: + case BUILD_IETF_GROUP_ATTR: + { + va_arg(args, void*); + continue; + } + default: + DBG1("builder part %N not supported by factory", + builder_part_names, part); + continue; + } + break; + } + va_end(args); + return NULL; +} + +/** + * Implementation of credential_factory_t.destroy + */ +static void destroy(private_credential_factory_t *this) +{ + this->constructors->destroy_function(this->constructors, free); + this->mutex->destroy(this->mutex); + free(this); +} + +/* + * see header file + */ +credential_factory_t *credential_factory_create() +{ + private_credential_factory_t *this = malloc_thing(private_credential_factory_t); + + this->public.create = (void*(*)(credential_factory_t*, credential_type_t type, int subtype, ...))create; + this->public.create_builder = (builder_t*(*)(credential_factory_t*, credential_type_t type, int subtype))create_builder; + this->public.add_builder = (void(*)(credential_factory_t*,credential_type_t type, int subtype, builder_constructor_t constructor))add_builder; + this->public.remove_builder = (void(*)(credential_factory_t*,builder_constructor_t constructor))remove_builder; + this->public.destroy = (void(*)(credential_factory_t*))destroy; + + this->constructors = linked_list_create(); + + this->mutex = mutex_create(MUTEX_RECURSIVE); + + return &this->public; +} + diff --git a/src/libstrongswan/credentials/credential_factory.h b/src/libstrongswan/credentials/credential_factory.h new file mode 100644 index 000000000..873cf8ab2 --- /dev/null +++ b/src/libstrongswan/credentials/credential_factory.h @@ -0,0 +1,105 @@ +/* + * 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 credential_factory credential_factory + * @{ @ingroup credentials + */ + +#ifndef CREDENTIAL_FACTORY_H_ +#define CREDENTIAL_FACTORY_H_ + +typedef struct credential_factory_t credential_factory_t; +typedef enum credential_type_t credential_type_t; + +#include <credentials/keys/private_key.h> +#include <credentials/keys/public_key.h> +#include <credentials/certificates/certificate.h> +#include <credentials/builder.h> + +/** + * Kind of credential. + */ +enum credential_type_t { + /** private key, implemented in private_key_t */ + CRED_PRIVATE_KEY, + /** public key, implemented in public_key_t */ + CRED_PUBLIC_KEY, + /** certificates, implemented in certificate_t */ + CRED_CERTIFICATE, +}; + +/** + * enum names for credential_type_t + */ +extern enum_name_t *credential_type_names; + +/** + * Manages credential construction functions and creates instances. + */ +struct credential_factory_t { + + /** + * Create a credential using a list of builder_part_t's. + * + * The variable argument list takes builder_part_t types followed + * by the type specific value. The list must be terminated using BUILD_END. + * + * @param type credential type to build + * @param subtype subtype specific for type of the credential + * @param ... build_part_t arguments, BUILD_END terminated. + * @return type specific credential, NULL if failed + */ + void* (*create)(credential_factory_t *this, credential_type_t type, + int subtype, ...); + + /** + * Create a builder instance to build credentials. + * + * @param type type of credentials the builder creates + * @param subtype type specific subtype, such as certificate_type_t + * @return builder instance + */ + builder_t* (*create_builder)(credential_factory_t *this, + credential_type_t type, int subtype); + /** + * Register a builder_t constructor function. + * + * @param type type of credential the builder creates + * @param constructor builder constructor function to register + */ + void (*add_builder)(credential_factory_t *this, + credential_type_t type, int subtype, + builder_constructor_t constructor); + /** + * Unregister a builder_t constructor function. + * + * @param constructor constructor function to unregister. + */ + void (*remove_builder)(credential_factory_t *this, + builder_constructor_t constructor); + + /** + * Destroy a credential_factory instance. + */ + void (*destroy)(credential_factory_t *this); +}; + +/** + * Create a credential_factory instance. + */ +credential_factory_t *credential_factory_create(); + +#endif /* CREDENTIAL_FACTORY_H_ @}*/ diff --git a/src/libstrongswan/credentials/keys/private_key.c b/src/libstrongswan/credentials/keys/private_key.c new file mode 100644 index 000000000..018cab1c0 --- /dev/null +++ b/src/libstrongswan/credentials/keys/private_key.c @@ -0,0 +1,19 @@ +/* + * 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: private_key.c 3488 2008-02-21 15:10:02Z martin $ + */ + +#include "private_key.h" + diff --git a/src/libstrongswan/credentials/keys/private_key.h b/src/libstrongswan/credentials/keys/private_key.h new file mode 100644 index 000000000..c28988309 --- /dev/null +++ b/src/libstrongswan/credentials/keys/private_key.h @@ -0,0 +1,114 @@ +/* + * 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: private_key.h 3620 2008-03-19 14:21:56Z martin $ + */ + +/** + * @defgroup private_key private_key + * @{ @ingroup keys + */ + +#ifndef PRIVATE_KEY_H_ +#define PRIVATE_KEY_H_ + +typedef struct private_key_t private_key_t; + +#include <utils/identification.h> +#include <credentials/keys/public_key.h> + +/** + * Abstract private key interface. + */ +struct private_key_t { + + /** + * Get the key type. + * + * @return type of the key + */ + key_type_t (*get_type)(private_key_t *this); + + /** + * Create a signature over a chunk of data. + * + * @param scheme signature scheme to use + * @param data chunk of data to sign + * @param signature where to allocate created signature + * @return TRUE if signature created + */ + bool (*sign)(private_key_t *this, signature_scheme_t scheme, + chunk_t data, chunk_t *signature); + /** + * Decrypt a chunk of data. + * + * @param crypto chunk containing encrypted data + * @param plain where to allocate decrypted data + * @return TRUE if data decrypted and plaintext allocated + */ + bool (*decrypt)(private_key_t *this, chunk_t crypto, chunk_t *plain); + + /** + * Get the strength of the key in bytes. + * + * @return strength of the key in bytes + */ + size_t (*get_keysize) (private_key_t *this); + + /** + * Get a unique key identifier, such as a hash over the public key. + * + * @param type type of the key ID to get + * @return unique ID of the key as identification_t, or NULL + */ + identification_t* (*get_id) (private_key_t *this, id_type_t type); + + /** + * Get the public part from the private key. + * + * @return public key + */ + public_key_t* (*get_public_key)(private_key_t *this); + + /** + * Check if a private key belongs to a public key. + * + * @param public public key + * @return TRUE, if keys belong together + */ + bool (*belongs_to) (private_key_t *this, public_key_t *public); + + /** + * Get an encoded form of the private key. + * + * @todo Do we need a encoding type specification? + * + * @return allocated chunk containing encoded private key + */ + chunk_t (*get_encoding)(private_key_t *this); + + /** + * Increase the refcount to this private key. + * + * @return this, with an increased refcount + */ + private_key_t* (*get_ref)(private_key_t *this); + + /** + * Decrease refcount, destroy private_key if no more references. + */ + void (*destroy)(private_key_t *this); +}; + +#endif /* PRIVATE_KEY_H_ @} */ diff --git a/src/libstrongswan/credentials/keys/public_key.c b/src/libstrongswan/credentials/keys/public_key.c new file mode 100644 index 000000000..80b9f03c3 --- /dev/null +++ b/src/libstrongswan/credentials/keys/public_key.c @@ -0,0 +1,37 @@ +/* + * 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: public_key.c 4051 2008-06-10 09:08:27Z tobias $ + */ + +#include "public_key.h" + +ENUM(key_type_names, KEY_RSA, KEY_ECDSA, + "RSA", + "ECDSA" +); + +ENUM(signature_scheme_names, SIGN_DEFAULT, SIGN_ECDSA_521, + "DEFAULT", + "RSA_EMSA_PKCS1_MD5", + "RSA_EMSA_PKCS1_SHA1", + "RSA_EMSA_PKCS1_SHA256", + "RSA_EMSA_PKCS1_SHA384", + "RSA_EMSA_PKCS1_SHA512", + "ECDSA_WITH_SHA1", + "ECDSA-256", + "ECDSA-384", + "ECDSA-521", +); + diff --git a/src/libstrongswan/credentials/keys/public_key.h b/src/libstrongswan/credentials/keys/public_key.h new file mode 100644 index 000000000..62dbe4303 --- /dev/null +++ b/src/libstrongswan/credentials/keys/public_key.h @@ -0,0 +1,155 @@ +/* + * 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: public_key.h 4051 2008-06-10 09:08:27Z tobias $ + */ + +/** + * @defgroup public_key public_key + * @{ @ingroup keys + */ + +#ifndef PUBLIC_KEY_H_ +#define PUBLIC_KEY_H_ + +typedef struct public_key_t public_key_t; +typedef enum key_type_t key_type_t; +typedef enum key_id_type_t key_id_type_t; +typedef enum signature_scheme_t signature_scheme_t; + +#include <library.h> +#include <utils/identification.h> + +/** + * Type of a key pair, the used crypto system + */ +enum key_type_t { + /** key type wildcard */ + KEY_ANY, + /** RSA crypto system as in PKCS#1 */ + KEY_RSA, + /** ECDSA as in ANSI X9.62 */ + KEY_ECDSA, + /** DSS, ElGamal, ... */ +}; + +/** + * Enum names for key_type_t + */ +extern enum_name_t *key_type_names; + +/** + * Signature scheme for signature creation + * + * EMSA-PKCS1 signatures are from the PKCS#1 standard. They include + * the ASN1-OID of the used hash algorithm. + */ +enum signature_scheme_t { + /** default scheme of that underlying crypto system */ + SIGN_DEFAULT, + /** EMSA-PKCS1 with MD5 */ + SIGN_RSA_EMSA_PKCS1_MD5, + /** EMSA-PKCS1 signature as in PKCS#1 standard using SHA1 as hash. */ + SIGN_RSA_EMSA_PKCS1_SHA1, + /** EMSA-PKCS1 signature as in PKCS#1 standard using SHA256 as hash. */ + SIGN_RSA_EMSA_PKCS1_SHA256, + /** EMSA-PKCS1 signature as in PKCS#1 standard using SHA384 as hash. */ + SIGN_RSA_EMSA_PKCS1_SHA384, + /** EMSA-PKCS1 signature as in PKCS#1 standard using SHA512 as hash. */ + SIGN_RSA_EMSA_PKCS1_SHA512, + /** ECDSA using SHA-1 as hash. */ + SIGN_ECDSA_WITH_SHA1, + /** ECDSA with SHA-256 on the P-256 curve as in RFC 4754 */ + SIGN_ECDSA_256, + /** ECDSA with SHA-384 on the P-384 curve as in RFC 4754 */ + SIGN_ECDSA_384, + /** ECDSA with SHA-512 on the P-521 curve as in RFC 4754 */ + SIGN_ECDSA_521, +}; + +/** + * Enum names for signature_scheme_t + */ +extern enum_name_t *signature_scheme_names; + +/** + * Abstract interface of a public key. + */ +struct public_key_t { + + /** + * Get the key type. + * + * @return type of the key + */ + key_type_t (*get_type)(public_key_t *this); + + /** + * Verifies a signature against a chunk of data. + * + * @param scheme signature scheme to use for verification, may be default + * @param data data to check signature against + * @param signature signature to check + * @return TRUE if signature matches + */ + bool (*verify)(public_key_t *this, signature_scheme_t scheme, + chunk_t data, chunk_t signature); + + /** + * Encrypt a chunk of data. + * + * @param crypto chunk containing plaintext data + * @param plain where to allocate encrypted data + * @return TRUE if data successfully encrypted + */ + bool (*encrypt)(public_key_t *this, chunk_t crypto, chunk_t *plain); + + /** + * Get the strength of the key in bytes. + * + * @return strength of the key in bytes + */ + size_t (*get_keysize) (public_key_t *this); + + /** + * Get a unique key identifier, such as a hash over the key. + * + * @param type type of the key ID to get + * @return unique ID of the key as identification_t, or NULL + */ + identification_t* (*get_id) (public_key_t *this, id_type_t type); + + /** + * Get an encoded form of the key. + * + * @todo Do we need a encoding type specification? + * + * @return allocated chunk containing encoded key + */ + chunk_t (*get_encoding)(public_key_t *this); + + /** + * Increase the refcount of the key. + * + * @return this with an increased refcount + */ + public_key_t* (*get_ref)(public_key_t *this); + + /** + * Destroy a public_key instance. + */ + void (*destroy)(public_key_t *this); +}; + +#endif /* PUBLIC_KEY_H_ @} */ diff --git a/src/libstrongswan/credentials/keys/shared_key.c b/src/libstrongswan/credentials/keys/shared_key.c new file mode 100644 index 000000000..f55b52c3a --- /dev/null +++ b/src/libstrongswan/credentials/keys/shared_key.c @@ -0,0 +1,111 @@ +/* + * 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: shared_key.c 3600 2008-03-14 15:11:29Z martin $ + */ + +#include "shared_key.h" + +ENUM(shared_key_type_names, SHARED_ANY, SHARED_PIN, + "ANY", + "IKE", + "EAP", + "PRIVATE_KEY_PASS", + "PIN", +); + +typedef struct private_shared_key_t private_shared_key_t; + +/** + * private data of shared_key + */ +struct private_shared_key_t { + + /** + * public functions + */ + shared_key_t public; + + /** + * type of this shared key + */ + shared_key_type_t type; + + /** + * associated shared key data + */ + chunk_t key; + + /** + * reference counter + */ + refcount_t ref; +}; + +/** + * Implements shared_key_t.get_type + */ +static shared_key_type_t get_type(private_shared_key_t *this) +{ + return this->type; +} + +/** + * Implements shared_key_t.get_key + */ +static chunk_t get_key(private_shared_key_t *this) +{ + return this->key; +} + +/** + * Implements shared_key_t.get_ref + */ +static shared_key_t* get_ref(private_shared_key_t *this) +{ + ref_get(&this->ref); + return &this->public; +} + +/** + * Implementation of shared_key_t.destroy + */ +static void destroy(private_shared_key_t *this) +{ + if (ref_put(&this->ref)) + { + free(this->key.ptr); + free(this); + } +} + +/* + * see header file + */ +shared_key_t *shared_key_create(shared_key_type_t type, chunk_t key) +{ + private_shared_key_t *this = malloc_thing(private_shared_key_t); + + this->public.get_type = (shared_key_type_t (*)(shared_key_t *this))get_type; + this->public.get_key = (chunk_t (*)(shared_key_t *this))get_key; + this->public.get_ref = (shared_key_t* (*)(shared_key_t *this))get_ref; + this->public.destroy = (void(*)(shared_key_t*))destroy; + + this->type = type; + this->key = key; + this->ref = 1; + + return &this->public; +} + diff --git a/src/libstrongswan/credentials/keys/shared_key.h b/src/libstrongswan/credentials/keys/shared_key.h new file mode 100644 index 000000000..ceb1309b7 --- /dev/null +++ b/src/libstrongswan/credentials/keys/shared_key.h @@ -0,0 +1,95 @@ +/* + * 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 shared_key shared_key + * @{ @ingroup keys + */ + +#ifndef SHARED_KEY_H_ +#define SHARED_KEY_H_ + +#include <utils/enumerator.h> +#include <utils/identification.h> + +typedef struct shared_key_t shared_key_t; +typedef enum shared_key_type_t shared_key_type_t; + +/** + * Type of a shared key. + */ +enum shared_key_type_t { + /** wildcard for all keys */ + SHARED_ANY, + /** PSK for IKE authentication */ + SHARED_IKE, + /** key for a EAP authentication method */ + SHARED_EAP, + /** key to decrypt encrypted private keys */ + SHARED_PRIVATE_KEY_PASS, + /** PIN to unlock a smartcard */ + SHARED_PIN, +}; + +/** + * enum names for shared_key_type_t + */ +extern enum_name_t *shared_key_type_names; + +/** + * A symmetric key shared between multiple owners. + * + * This class is not thread save, do not add owners while others might be + * reading. + */ +struct shared_key_t { + + /** + * Get the kind of this key. + * + * @return type of the key + */ + shared_key_type_t (*get_type)(shared_key_t *this); + + /** + * Get the shared key data. + * + * @return chunk pointing to the internal key + */ + chunk_t (*get_key)(shared_key_t *this); + + /** + * Increase refcount of the key. + * + * @return this with an increased refcount + */ + shared_key_t* (*get_ref)(shared_key_t *this); + + /** + * Destroy a shared_key instance if all references are gone. + */ + void (*destroy)(shared_key_t *this); +}; + +/** + * A simple private key implementation + * + * @param type type of the shared key + * @param key key data, gets owned by instance + * @return simple shared key instance + */ +shared_key_t *shared_key_create(shared_key_type_t type, chunk_t key); + +#endif /** SHARED_KEY_H_ @} */ diff --git a/src/libstrongswan/crypto/ac.c b/src/libstrongswan/crypto/ac.c deleted file mode 100644 index 641ce5d64..000000000 --- a/src/libstrongswan/crypto/ac.c +++ /dev/null @@ -1,636 +0,0 @@ -/** - * @file ac.c - * - * @brief Implementation of x509ac_t. - * - */ - -/* - * Copyright (C) 2002 Ueli Galizzi, Ariane Seiler - * Copyright (C) 2003 Martin Berner, Lukas Suter - * 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. - * - * RCSID $Id: ac.c 3355 2007-11-20 12:06:40Z martin $ - */ - -#include <string.h> -#include <stdio.h> - -#include <library.h> -#include <debug.h> - -#include <asn1/asn1.h> -#include <asn1/pem.h> -#include <crypto/x509.h> -#include <crypto/ietf_attr_list.h> -#include <utils/identification.h> -#include <utils/linked_list.h> -#include <utils/lexparser.h> - -#include "ac.h" - -#define ACERT_WARNING_INTERVAL 1 /* day */ - -typedef struct private_x509ac_t private_x509ac_t; - -/** - * Private data of a x509ac_t object. - */ -struct private_x509ac_t { - /** - * Public interface for this attribute certificate. - */ - x509ac_t public; - - /** - * Time when attribute certificate was installed - */ - time_t installed; - - /** - * X.509 attribute certificate in DER format - */ - chunk_t certificate; - - /** - * 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; - - /** - * Signature algorithm - */ - int sigAlg; - - /** - * 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 - */ - chunk_t authKeyID; - - /** - * Authority Key Serial Number - */ - chunk_t authKeySerialNumber; - - /** - * No revocation information available - */ - bool noRevAvail; - - /** - * Signature algorithm (must be identical to sigAlg) - */ - int algorithm; - - /** - * Signature - */ - chunk_t signature; -}; - -/** - * 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 */ -}; - -#define ROLE_ROOF 4 - -/** - * 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 */ -}; - -#define AC_OBJ_CERTIFICATE 0 -#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 -#define AC_OBJ_ROOF 55 - -/** - * Implements x509ac_t.is_valid - */ -static err_t is_valid(const private_x509ac_t *this, time_t *until) -{ - time_t current_time = time(NULL); - - DBG2(" not before : %T", &this->notBefore); - DBG2(" current time: %T", ¤t_time); - DBG2(" not after : %T", &this->notAfter); - - if (until != NULL && - (*until == UNDEFINED_TIME || this->notAfter < *until)) - { - *until = this->notAfter; - } - if (current_time < this->notBefore) - { - return "is not valid yet"; - } - if (current_time > this->notAfter) - { - return "has expired"; - } - DBG2(" attribute certificate is valid"); - return NULL; -} - -/** - * Implements x509ac_t.is_newer - */ -static bool is_newer(const private_x509ac_t *this, const private_x509ac_t *other) -{ - return this->notBefore > other->notBefore; -} - -/** - * Implements x509ac_t.equals_holder. - */ -static bool equals_holder(const private_x509ac_t *this, const private_x509ac_t *other) -{ - return this->holderIssuer->equals(this->holderIssuer, other->holderIssuer) - && chunk_equals(this->holderSerial, other->holderSerial); -} - -/** - * 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; -} - -/** - * parses roleSyntax - */ -static void parse_roleSyntax(chunk_t blob, int level0) -{ - asn1_ctx_t ctx; - chunk_t object; - u_int level; - int objectID = 0; - - asn1_init(&ctx, blob, level0, FALSE, FALSE); - while (objectID < ROLE_ROOF) - { - if (!extract_object(roleSyntaxObjects, &objectID, &object, &level, &ctx)) - { - return; - } - - switch (objectID) - { - default: - break; - } - objectID++; - } -} - -/** - * Parses an X.509 attribute certificate - */ -static bool parse_certificate(chunk_t blob, private_x509ac_t *this) -{ - asn1_ctx_t ctx; - bool critical; - chunk_t object; - u_int level; - int objectID = 0; - int type = OID_UNKNOWN; - int extn_oid = OID_UNKNOWN; - - asn1_init(&ctx, blob, 0, FALSE, FALSE); - while (objectID < AC_OBJ_ROOF) - { - if (!extract_object(acObjects, &objectID, &object, &level, &ctx)) - { - return FALSE; - } - - /* those objects which will parsed further need the next higher level */ - level++; - - switch (objectID) - { - case AC_OBJ_CERTIFICATE: - this->certificate = object; - break; - 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); - return FALSE; - } - break; - case AC_OBJ_HOLDER_ISSUER: - if (!parse_directoryName(object, level, FALSE, &this->holderIssuer)) - { - return FALSE; - } - break; - case AC_OBJ_HOLDER_SERIAL: - this->holderSerial = object; - break; - case AC_OBJ_ENTITY_NAME: - if (!parse_directoryName(object, level, TRUE, &this->entityName)) - { - return FALSE; - } - break; - case AC_OBJ_ISSUER_NAME: - if (!parse_directoryName(object, level, FALSE, &this->issuerName)) - { - return FALSE; - } - break; - case AC_OBJ_SIG_ALG: - this->sigAlg = parse_algorithmIdentifier(object, level, NULL); - break; - case AC_OBJ_SERIAL_NUMBER: - this->serialNumber = object; - break; - case AC_OBJ_NOT_BEFORE: - this->notBefore = asn1totime(&object, ASN1_GENERALIZEDTIME); - break; - case AC_OBJ_NOT_AFTER: - this->notAfter = asn1totime(&object, ASN1_GENERALIZEDTIME); - break; - case AC_OBJ_ATTRIBUTE_TYPE: - type = 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 = 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: - x509_parse_authorityKeyIdentifier(object, level, - &this->authKeyID, &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 = parse_algorithmIdentifier(object, level, NULL); - break; - case AC_OBJ_SIGNATURE: - this->signature = object; - break; - default: - break; - } - objectID++; - } - this->installed = time(NULL); - return TRUE; -} - -/** - * Implementation of x509ac_t.list. - */ -static void list(const private_x509ac_t *this, FILE *out, bool utc) -{ - time_t now = time(NULL); - - fprintf(out, "%#T\n", &this->installed, utc); - - if (this->entityName) - { - fprintf(out, " holder: '%D'\n", this->entityName); - } - if (this->holderIssuer) - { - fprintf(out, " hissuer: '%D'\n", this->holderIssuer); - } - if (this->holderSerial.ptr) - { - fprintf(out, " hserial: %#B\n", &this->holderSerial); - } - - /* list all group attributes on a single line */ - fprintf(out, " groups: "); - ietfAttr_list_list(this->groups, out); - fprintf(out, "\n"); - - fprintf(out, " issuer: '%D'\n", this->issuerName); - fprintf(out, " serial: %#B\n", &this->serialNumber); - - fprintf(out, " validity: not before %#T, ", &this->notBefore, utc); - if (now < this->notBefore) - { - fprintf(out, "not valid yet (valid in %#V)\n", &now, &this->notBefore); - } - else - { - fprintf(out, "ok\n"); - } - - fprintf(out, " not after %#T, ", &this->notAfter, utc); - if (now > this->notAfter) - { - fprintf(out, "expired (%#V ago)\n", &now, &this->notAfter); - } - else - { - fprintf(out, "ok"); - if (now > this->notAfter - ACERT_WARNING_INTERVAL * 60 * 60 * 24) - { - fprintf(out, " (expires in %#V)", &now, &this->notAfter); - } - fprintf(out, " \n"); - } - - if (this->authKeyID.ptr) - { - fprintf(out, " authkey: %#B\n", &this->authKeyID); - } - if (this->authKeySerialNumber.ptr) - { - fprintf(out, " aserial: %#B\n", &this->authKeySerialNumber); - } -} - -/** - * Implements x509ac_t.destroy - */ -static void destroy(private_x509ac_t *this) -{ - DESTROY_IF(this->holderIssuer); - DESTROY_IF(this->entityName); - DESTROY_IF(this->issuerName); - ietfAttr_list_destroy(this->charging); - ietfAttr_list_destroy(this->groups); - free(this->certificate.ptr); - free(this); -} - -/** - * Described in header. - */ -x509ac_t *x509ac_create_from_chunk(chunk_t chunk) -{ - private_x509ac_t *this = malloc_thing(private_x509ac_t); - - /* initialize */ - this->holderIssuer = NULL; - this->entityName = NULL; - this->issuerName = NULL; - this->charging = linked_list_create(); - this->groups = linked_list_create(); - - /* public functions */ - this->public.is_valid = (err_t (*) (const x509ac_t*,time_t*))is_valid; - this->public.is_newer = (bool (*) (const x509ac_t*,const x509ac_t*))is_newer; - this->public.equals_holder = (bool (*) (const x509ac_t*,const x509ac_t*))equals_holder; - this->public.list = (void (*) (const x509ac_t*,FILE*,bool))list; - this->public.destroy = (void (*) (x509ac_t*))destroy; - - if (!parse_certificate(chunk, this)) - { - destroy(this); - return NULL; - } - return &this->public; -} - -/** - * Described in header. - */ -x509ac_t *x509ac_create_from_file(const char *filename) -{ - bool pgp = FALSE; - chunk_t chunk = chunk_empty; - - if (!pem_asn1_load_file(filename, NULL, "attribute certificate", &chunk, &pgp)) - { - return NULL; - } - return x509ac_create_from_chunk(chunk); -} - diff --git a/src/libstrongswan/crypto/ac.h b/src/libstrongswan/crypto/ac.h deleted file mode 100644 index 8a4ccbd4c..000000000 --- a/src/libstrongswan/crypto/ac.h +++ /dev/null @@ -1,110 +0,0 @@ -/** - * @file ac.h - * - * @brief Interface of x509ac_t. - * - */ - -/* - * Copyright (C) 2002 Ueli Galizzi, Ariane Seiler - * Copyright (C) 2003 Martin Berner, Lukas Suter - * 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. - * - * RCSID $Id: ac.h 3300 2007-10-12 21:53:18Z andreas $ - */ - -#ifndef AC_H_ -#define AC_H_ - -#include <library.h> - -typedef struct x509ac_t x509ac_t; - -/** - * @brief X.509 attribute certificate. - * - * @b Constructors: - * - x509ac_create_from_chunk() - * - x509ac_create_from_file() - * - * @ingroup crypto - */ -struct x509ac_t { - - /** - * @brief Checks the validity interval of the attribute certificate - * - * @param this certificate being examined - * @param until until = min(until, notAfter) - * @return NULL if the certificate is valid - */ - err_t (*is_valid) (const x509ac_t *this, time_t *until); - - /** @brief Checks if this attr cert is newer than the other attr cert - * - * @param this calling object - * @param other other attr cert object - * @return TRUE if this was issued more recently than other - */ - bool (*is_newer) (const x509ac_t *this, const x509ac_t *other); - - /** - * @brief Checks if two attribute certificates belong to the same holder - * - * @param this calling attribute certificate - * @param that other attribute certificate - * @return TRUE if same holder - */ - bool (*equals_holder) (const x509ac_t *this, const x509ac_t *other); - - /** - * @brief Log the attribute certificate info to out. - * - * @param this calling object - * @param out stream to write to - * @param utc TRUE for UTC times, FALSE for local time - */ - void (*list)(const x509ac_t *this, FILE *out, bool utc); - - /** - * @brief Destroys the attribute certificate. - * - * @param this certificate to destroy - */ - void (*destroy) (x509ac_t *this); -}; - -/** - * @brief Read a x509 attribute certificate from a DER encoded blob. - * - * @param chunk chunk containing DER encoded data - * @return created x509ac_t certificate, or NULL if invalid. - * - * @ingroup crypto - */ -x509ac_t *x509ac_create_from_chunk(chunk_t chunk); - -/** - * @brief Read a x509 attribute certificate from a DER encoded file. - * - * @param filename file containing DER encoded data - * @return created x509ac_t certificate, or NULL if invalid. - * - * @ingroup crypto - */ -x509ac_t *x509ac_create_from_file(const char *filename); - -#endif /* AC_H_ */ - diff --git a/src/libstrongswan/crypto/ca.c b/src/libstrongswan/crypto/ca.c deleted file mode 100644 index 510e3528e..000000000 --- a/src/libstrongswan/crypto/ca.c +++ /dev/null @@ -1,813 +0,0 @@ -/** - * @file ca.c - * - * @brief Implementation of ca_info_t. - * - */ - -/* - * 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 <sys/stat.h> -#include <unistd.h> -#include <string.h> -#include <stdio.h> -#include <pthread.h> - -#include "x509.h" -#include "crl.h" -#include "ca.h" -#include "ac.h" -#include "certinfo.h" -#include "ocsp.h" - -#include <library.h> -#include <debug.h> -#include <utils/linked_list.h> -#include <utils/identification.h> -#include <utils/fetcher.h> - -typedef struct private_ca_info_t private_ca_info_t; - -/** - * Private data of a ca_info_t object. - */ -struct private_ca_info_t { - /** - * Public interface for this ca info record - */ - ca_info_t public; - - /** - * Name of the ca info record - */ - char *name; - - /** - * Time when ca info record was installed - */ - time_t installed; - - /** - * Distinguished Name of the CA - */ - x509_t *cacert; - - /** - * List of attribute certificates - */ - linked_list_t *attrcerts; - - /** - * List of crl URIs - */ - linked_list_t *crluris; - - /** - * List of ocsp URIs - */ - linked_list_t *ocspuris; - - /** - * CRL issued by this ca - */ - crl_t *crl; - - /** - * List of certificate info records - */ - linked_list_t *certinfos; - - /** - * mutex controls access to the elements: - * name, crluris, ocspuris, crl, and certinfos - */ - pthread_mutex_t mutex; -}; - -/** - * static options set by ca_info_set_options() - */ -static strict_t strict_crl_policy = STRICT_NO; -static bool cache_crls = FALSE; -static u_int crl_check_interval = 0; - -/** - * Implements ca_info_t.equals - */ -static bool equals(const private_ca_info_t *this, const private_ca_info_t *that) -{ - return chunk_equals(this->cacert->get_keyid(this->cacert), - that->cacert->get_keyid(that->cacert)); -} - -/** - * Implements ca_info_t.equals_name_release_info - */ -static bool equals_name_release_info(private_ca_info_t *this, const char *name) -{ - bool found; - - pthread_mutex_lock(&(this->mutex)); - found = this->name != NULL && streq(this->name, name); - - if (found) - { - this->crluris->destroy_offset(this->crluris, - offsetof(identification_t, destroy)); - this->crluris = linked_list_create(); - - this->ocspuris->destroy_offset(this->ocspuris, - offsetof(identification_t, destroy)); - this->ocspuris = linked_list_create(); - - free(this->name); - this->name = NULL; - } - - pthread_mutex_unlock(&(this->mutex)); - return found; -} - -/** - * Implements ca_info_t.is_crl_issuer - */ -static bool is_cert_issuer(private_ca_info_t *this, const x509_t *cert) -{ - return cert->is_issuer(cert, this->cacert); -} - -/** - * Implements ca_info_t.is_crl_issuer - */ -static bool is_crl_issuer(private_ca_info_t *this, const crl_t *crl) -{ - return crl->is_issuer(crl, this->cacert); -} - -/** - * Implements ca_info_t.is_ca - */ -static bool is_ca(private_ca_info_t *this) -{ - return this->cacert->is_ca(this->cacert); -} - -/** - * Implements ca_info_t.is_strict - */ -static bool is_strict(private_ca_info_t *this) -{ - bool strict = strict_crl_policy != STRICT_NO; - - if (strict_crl_policy == STRICT_IFURI) - { - pthread_mutex_lock(&(this->mutex)); - strict = this->crluris->get_count(this->crluris) > 0 || - this->ocspuris->get_count(this->ocspuris) > 0; - pthread_mutex_unlock(&(this->mutex)); - } - return strict; -} - -/** - * Implements ca_info_t.has_crl - */ -static bool has_crl(private_ca_info_t *this) -{ - bool found; - - pthread_mutex_lock(&(this->mutex)); - found = this->crl != NULL; - pthread_mutex_unlock(&(this->mutex)); - - return found; -} - -/** - * Implements ca_info_t.has_certinfos - */ -static bool has_certinfos(private_ca_info_t *this) -{ - bool found; - - pthread_mutex_lock(&(this->mutex)); - found = this->certinfos->get_count(this->certinfos) > 0; - pthread_mutex_unlock(&(this->mutex)); - - return found; -} - -/** - * Implements ca_info_t.add_crl - */ -static void add_crl(private_ca_info_t *this, crl_t *crl) -{ - pthread_mutex_lock(&(this->mutex)); - - if (this->crl) - { - if (crl->is_newer(crl, this->crl)) - { - this->crl->destroy(this->crl); - this->crl = crl; - DBG1(" this crl is newer - existing crl replaced"); - } - else - { - crl->destroy(crl); - DBG1(" this crl is not newer - existing crl retained"); - } - } - else - { - this->crl = crl; - DBG2(" crl added"); - } - - pthread_mutex_unlock(&(this->mutex)); -} - -/** - * Implements ca_info_t.list_crl - */ -static void list_crl(private_ca_info_t *this, FILE *out, bool utc) -{ - pthread_mutex_lock(&this->mutex); - this->crl->list(this->crl, out, utc); - pthread_mutex_unlock(&this->mutex); -} - -/** - * Implements ca_info_t.list_certinfos - */ -static void list_certinfos(private_ca_info_t *this, FILE *out, bool utc) -{ - iterator_t *iterator; - certinfo_t *certinfo; - chunk_t authkey; - - pthread_mutex_lock(&this->mutex); - - authkey = this->cacert->get_subjectKeyID(this->cacert); - fprintf(out," authname: '%D'\n", this->cacert->get_subject(this->cacert)); - fprintf(out," authkey: %#B\n", &authkey); - - iterator = this->certinfos->create_iterator(this->certinfos, TRUE); - while (iterator->iterate(iterator, (void**)&certinfo)) - { - time_t nextUpdate, thisUpdate, now; - chunk_t serial; - - now = time(NULL); - nextUpdate = certinfo->get_nextUpdate(certinfo); - thisUpdate = certinfo->get_thisUpdate(certinfo); - serial = certinfo->get_serialNumber(certinfo); - - fprintf(out, "%#T, until %#T, ", &thisUpdate, utc, &nextUpdate, utc); - if (now > nextUpdate) - { - fprintf(out, "expired (%#V ago)\n", &now, &nextUpdate); - } - else - { - fprintf(out, "ok (expires in %#V)\n", &now, &nextUpdate); - } - fprintf(out, " serial: %#B, %N\n", &serial, - cert_status_names, certinfo->get_status(certinfo)); - } - iterator->destroy(iterator); - - pthread_mutex_unlock(&this->mutex); -} - -/** - * Find an exact copy of an identification in a linked list - */ -static identification_t* find_identification(linked_list_t *list, identification_t *id) -{ - identification_t *found_id = NULL, *current_id; - - iterator_t *iterator = list->create_iterator(list, TRUE); - - while (iterator->iterate(iterator, (void**)¤t_id)) - { - if (id->equals(id, current_id)) - { - found_id = current_id; - break; - } - } - iterator->destroy(iterator); - - return found_id; -} - -/** - * Add a unique identification to a linked list - */ -static identification_t *add_identification(linked_list_t *list, identification_t *id) -{ - identification_t *found_id = find_identification(list, id); - - if (found_id) - { - id->destroy(id); - return found_id; - } - else - { - list->insert_last(list, (void*)id); - return id; - } -} - -/** - * Implements ca_info_t.add_crluri - */ -static void add_crluri(private_ca_info_t *this, chunk_t uri) -{ - if (uri.len < 6 || - (strncasecmp(uri.ptr, "http", 4) != 0 && - strncasecmp(uri.ptr, "ldap", 4) != 0 && - strncasecmp(uri.ptr, "file", 4) != 0 && - strncasecmp(uri.ptr, "ftp", 3) != 0)) - { - DBG1(" invalid crl uri '%.*s'", uri.len, uri.ptr); - return; - } - else - { - identification_t *crluri = identification_create_from_encoding(ID_DER_ASN1_GN_URI, uri); - - pthread_mutex_lock(&(this->mutex)); - add_identification(this->crluris, crluri); - pthread_mutex_unlock(&(this->mutex)); - } -} - -/** - * Implements ca_info_t.add_ocspuri - */ -static void add_ocspuri(private_ca_info_t *this, chunk_t uri) -{ - if (uri.len < 7 || strncasecmp(uri.ptr, "http", 4) != 0) - { - DBG1(" invalid ocsp uri '%.*s'", uri.len, uri.ptr); - return; - } - else - { - identification_t *ocspuri = identification_create_from_encoding(ID_DER_ASN1_GN_URI, uri); - - pthread_mutex_lock(&(this->mutex)); - add_identification(this->ocspuris, ocspuri); - pthread_mutex_unlock(&(this->mutex)); - } -} - -/** - * Implements ca_info_t.add_info. - */ -void add_info (private_ca_info_t *this, const private_ca_info_t *that) -{ - pthread_mutex_lock(&(this->mutex)); - - if (this->name == NULL && that->name != NULL) - { - this->name = strdup(that->name); - } - - pthread_mutex_unlock(&(this->mutex)); - - { - identification_t *uri; - - iterator_t *iterator = that->crluris->create_iterator(that->crluris, TRUE); - - while (iterator->iterate(iterator, (void**)&uri)) - { - if (uri->get_type(uri) == ID_DER_ASN1_GN_URI) - { - add_crluri(this, uri->get_encoding(uri)); - } - } - iterator->destroy(iterator); - } - - { - identification_t *uri; - - iterator_t *iterator = that->ocspuris->create_iterator(that->ocspuris, TRUE); - - while (iterator->iterate(iterator, (void**)&uri)) - { - if (uri->get_type(uri) == ID_DER_ASN1_GN_URI) - { - add_ocspuri(this, uri->get_encoding(uri)); - } - } - iterator->destroy(iterator); - } -} - -/** - * Implements ca_info_t.get_certificate. - */ -static x509_t* get_certificate(private_ca_info_t* this) -{ - return this->cacert; -} - -/** - * caches a crl by saving it to a given crl directory - */ -void cache_crl(private_ca_info_t* this, const char *crl_dir, crl_t *crl) -{ - char buffer[BUF_LEN]; - char *path; - char *pos = buffer; - int len = BUF_LEN; - int n; - - chunk_t authKeyID = this->cacert->get_subjectKeyID(this->cacert); - chunk_t uri; - - uri.ptr = buffer; - uri.len = 7 + strlen(crl_dir) + 1 + 2*authKeyID.len + 4; - - if (uri.len >= BUF_LEN) - { - DBG1("file uri exceeds buffer length of %d bytes - crl not saved", BUF_LEN); - return; - } - - /* print the file uri prefix */ - n = snprintf(pos, len, "file://"); - pos += n; len -= n; - - /* remember the start of the path string */ - path = pos; - - /* print the default crl directory path */ - n = snprintf(pos, len, "%s/", crl_dir); - pos += n; len -= n; - - /* create and print a unique crl filename derived from the authKeyID */ - while (authKeyID.len-- > 0) - { - n = snprintf(pos, len, "%02x", *authKeyID.ptr++); - pos += n; len -= n; - } - - /* add the file suffix */ - n = snprintf(pos, len, ".crl"); - - if (crl->write_to_file(crl, path, 0022, TRUE)) - { - identification_t *crluri = identification_create_from_encoding(ID_DER_ASN1_GN_URI, uri); - - add_identification(this->crluris, crluri); - } -} - -/** - * Implements ca_info_t.verify_by_crl. - */ -static cert_status_t verify_by_crl(private_ca_info_t* this, certinfo_t *certinfo, - const char *crl_dir) -{ - rsa_public_key_t *issuer_public_key = this->cacert->get_public_key(this->cacert); - bool stale; - - pthread_mutex_lock(&(this->mutex)); - if (this->crl == NULL) - { - stale = TRUE; - DBG1("no crl is locally available"); - } - else - { - stale = !this->crl->is_valid(this->crl); - DBG1("crl is %s", stale? "stale":"valid"); - } - - if (stale && crl_check_interval > 0) - { - iterator_t *iterator = this->crluris->create_iterator(this->crluris, TRUE); - identification_t *uri; - - while (iterator->iterate(iterator, (void**)&uri)) - { - fetcher_t *fetcher; - char uri_string[BUF_LEN]; - chunk_t uri_chunk = uri->get_encoding(uri); - chunk_t response_chunk; - - snprintf(uri_string, BUF_LEN, "%.*s", uri_chunk.len, uri_chunk.ptr); - fetcher = fetcher_create(uri_string); - - response_chunk = fetcher->get(fetcher); - fetcher->destroy(fetcher); - if (response_chunk.ptr != NULL) - { - crl_t *crl = crl_create_from_chunk(response_chunk); - - if (crl == NULL) - { - free(response_chunk.ptr); - continue; - } - if (!is_crl_issuer(this, crl)) - { - DBG1(" fetched crl has wrong issuer"); - crl->destroy(crl); - continue; - } - if (!crl->verify(crl, issuer_public_key)) - { - DBG1("fetched crl signature is invalid"); - crl->destroy(crl); - continue; - } - DBG2("fetched crl signature is valid"); - - if (this->crl == NULL) - { - this->crl = crl; - } - else if (crl->is_newer(crl, this->crl)) - { - this->crl->destroy(this->crl); - this->crl = crl; - DBG1("this crl is newer - existing crl replaced"); - } - else - { - crl->destroy(crl); - DBG1("this crl is not newer - existing crl retained"); - continue; - } - if (crl->is_valid(crl)) - { - if (cache_crls && strncasecmp(uri_string, "file", 4) != 0) - { - cache_crl(this, crl_dir, crl); - } - /* we found a valid crl and therefore exit the fetch loop */ - break; - } - else - { - DBG1("fetched crl is stale"); - } - } - } - iterator->destroy(iterator); - } - - if (this->crl) - { - if (!this->crl->verify(this->crl, issuer_public_key)) - { - DBG1("crl signature is invalid"); - goto ret; - } - DBG2("crl signature is valid"); - - this->crl->get_status(this->crl, certinfo); - } - -ret: - pthread_mutex_unlock(&(this->mutex)); - return certinfo->get_status(certinfo); -} - -/** - * Implements ca_info_t.verify_by_ocsp. - */ -static cert_status_t verify_by_ocsp(private_ca_info_t* this, - certinfo_t *certinfo, - credential_store_t *credentials) -{ - bool stale; - iterator_t *iterator; - certinfo_t *cached_certinfo = NULL; - int comparison = 1; - - pthread_mutex_lock(&(this->mutex)); - - /* do we support OCSP at all? */ - if (this->ocspuris->get_count(this->ocspuris) == 0) - { - goto ret; - } - - iterator = this->certinfos->create_iterator(this->certinfos, TRUE); - - /* find the list insertion point in alphabetical order */ - while(iterator->iterate(iterator, (void**)&cached_certinfo)) - { - comparison = certinfo->compare_serialNumber(certinfo, cached_certinfo); - - if (comparison <= 0) - { - break; - } - } - - /* do we have a valid certinfo_t for this serial number in our cache? */ - if (comparison == 0) - { - stale = cached_certinfo->get_nextUpdate(cached_certinfo) < time(NULL); - DBG1("ocsp status in cache is %s", stale ? "stale":"fresh"); - } - else - { - stale = TRUE; - DBG1("ocsp status is not in cache"); - } - - if (stale) - { - ocsp_t *ocsp; - - ocsp = ocsp_create(this->cacert, this->ocspuris); - ocsp->fetch(ocsp, certinfo, credentials); - if (certinfo->get_status(certinfo) != CERT_UNDEFINED) - { - if (comparison != 0) - { - cached_certinfo = certinfo_create(certinfo->get_serialNumber(certinfo)); - - if (comparison > 0) - { - this->certinfos->insert_last(this->certinfos, (void *)cached_certinfo); - } - else - { - iterator->insert_before(iterator, (void *)cached_certinfo); - } - } - cached_certinfo->update(cached_certinfo, certinfo); - } - ocsp->destroy(ocsp); - } - else - { - certinfo->update(certinfo, cached_certinfo); - } - - iterator->destroy(iterator); - -ret: - pthread_mutex_unlock(&(this->mutex)); - return certinfo->get_status(certinfo); -} - -/** - * Implements ca_info_t.purge_ocsp - */ -static void purge_ocsp(private_ca_info_t *this) -{ - pthread_mutex_lock(&(this->mutex)); - - this->certinfos->destroy_offset(this->certinfos, - offsetof(certinfo_t, destroy)); - this->certinfos = linked_list_create(); - - pthread_mutex_unlock(&(this->mutex)); -} - -/** - * Implements ca_info_t.destroy - */ -static void destroy(private_ca_info_t *this) -{ - this->attrcerts->destroy_offset(this->attrcerts, - offsetof(x509ac_t, destroy)); - this->crluris->destroy_offset(this->crluris, - offsetof(identification_t, destroy)); - this->ocspuris->destroy_offset(this->ocspuris, - offsetof(identification_t, destroy)); - this->certinfos->destroy_offset(this->certinfos, - offsetof(certinfo_t, destroy)); - DESTROY_IF(this->crl); - free(this->name); - free(this); -} - -/** - * list the info of this CA - */ -static void list(private_ca_info_t* this, FILE* out, bool utc) -{ - chunk_t chunk; - identification_t *uri; - iterator_t *iterator; - bool first; - - pthread_mutex_lock(&(this->mutex)); - fprintf(out, "%#T", &this->installed, utc); - - if (this->name) - { - fprintf(out, ", \"%s\"\n", this->name); - } - else - { - fprintf(out, "\n"); - } - - fprintf(out, " authname: '%D'\n", this->cacert->get_subject(this->cacert)); - chunk = this->cacert->get_subjectKeyID(this->cacert); - fprintf(out, " authkey: %#B\n", &chunk); - chunk = this->cacert->get_keyid(this->cacert); - fprintf(out, " keyid: %#B\n", &chunk); - - first = TRUE; - iterator = this->crluris->create_iterator(this->crluris, TRUE); - while (iterator->iterate(iterator, (void**)&uri)) - { - fprintf(out, " %s '%D'\n", first ? "crluris:":" ", uri); - first = FALSE; - } - iterator->destroy(iterator); - - first = TRUE; - iterator = this->ocspuris->create_iterator(this->ocspuris, TRUE); - while (iterator->iterate(iterator, (void**)&uri)) - { - fprintf(out, " %s '%D'\n", first ? "ocspuris:":" ", uri); - first = FALSE; - } - iterator->destroy(iterator); - pthread_mutex_unlock(&(this->mutex)); -} - -/* - * Described in header. - */ -void ca_info_set_options(strict_t strict, bool cache, u_int interval) -{ - strict_crl_policy = strict; - cache_crls = cache; - crl_check_interval = interval; -} - -/* - * Described in header. - */ -ca_info_t *ca_info_create(const char *name, x509_t *cacert) -{ - private_ca_info_t *this = malloc_thing(private_ca_info_t); - - /* initialize */ - this->installed = time(NULL); - this->name = (name == NULL)? NULL:strdup(name); - this->cacert = cacert; - this->attrcerts = linked_list_create(); - this->crluris = linked_list_create(); - this->ocspuris = linked_list_create(); - this->certinfos = linked_list_create(); - this->crl = NULL; - - /* initialize the mutex */ - pthread_mutex_init(&(this->mutex), NULL); - - /* public functions */ - this->public.equals = (bool (*) (const ca_info_t*,const ca_info_t*))equals; - this->public.equals_name_release_info = (bool (*) (ca_info_t*,const char*))equals_name_release_info; - this->public.is_cert_issuer = (bool (*) (ca_info_t*,const x509_t*))is_cert_issuer; - this->public.is_crl_issuer = (bool (*) (ca_info_t*,const crl_t*))is_crl_issuer; - this->public.is_ca = (bool (*) (ca_info_t*))is_ca; - this->public.is_strict = (bool (*) (ca_info_t*))is_strict; - this->public.add_info = (void (*) (ca_info_t*,const ca_info_t*))add_info; - this->public.add_crl = (void (*) (ca_info_t*,crl_t*))add_crl; - this->public.has_crl = (bool (*) (ca_info_t*))has_crl; - this->public.has_certinfos = (bool (*) (ca_info_t*))has_certinfos; - this->public.list = (void (*) (ca_info_t*,FILE*,bool))list; - this->public.list_crl = (void (*) (ca_info_t*,FILE*,bool))list_crl; - this->public.list_certinfos = (void (*) (ca_info_t*,FILE*,bool))list_certinfos; - this->public.add_crluri = (void (*) (ca_info_t*,chunk_t))add_crluri; - this->public.add_ocspuri = (void (*) (ca_info_t*,chunk_t))add_ocspuri; - this->public.get_certificate = (x509_t* (*) (ca_info_t*))get_certificate; - this->public.verify_by_crl = (cert_status_t (*) (ca_info_t*,certinfo_t*, const char*))verify_by_crl; - this->public.verify_by_ocsp = (cert_status_t (*) (ca_info_t*,certinfo_t*,credential_store_t*))verify_by_ocsp; - this->public.purge_ocsp = (void (*) (ca_info_t*))purge_ocsp; - this->public.destroy = (void (*) (ca_info_t*))destroy; - - return &this->public; -} diff --git a/src/libstrongswan/crypto/ca.h b/src/libstrongswan/crypto/ca.h deleted file mode 100644 index ff6271b15..000000000 --- a/src/libstrongswan/crypto/ca.h +++ /dev/null @@ -1,243 +0,0 @@ -/** - * @file ca.h - * - * @brief Interface of ca_info_t. - * - */ - -/* - * 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. - */ - -#ifndef CA_H_ -#define CA_H_ - -typedef struct ca_info_t ca_info_t; - -#include <library.h> - -#include "x509.h" -#include "crl.h" - -#define MAX_CA_PATH_LEN 7 - -/*forward declaration */ -struct credential_store_t; - -/** - * @brief X.509 certification authority information record - * - * @b Constructors: - * - ca_info_create() - * - * @ingroup transforms - */ -struct ca_info_t { - - /** - * @brief Compare two ca info records - * - * Comparison is done via the keyid of the ca certificate - * - * @param this first ca info object - * @param that second ca info objct - * @return TRUE if a match is found - */ - bool (*equals) (const ca_info_t *this, const ca_info_t* that); - - /** - * @brief If the ca info record has the same name then release the name and URIs - * - * @param this ca info object - * @return TRUE if a match is found - */ - bool (*equals_name_release_info) (ca_info_t *this, const char *name); - - /** - * @brief Checks if a certificate was issued by this ca - * - * @param this ca info object - * @param cert certificate to be checked - * @return TRUE if the issuing ca has been found - */ - bool (*is_cert_issuer) (ca_info_t *this, const x509_t *cert); - - /** - * @brief Checks if a crl was issued by this ca - * - * @param this ca info object - * @param crl crl to be checked - * @return TRUE if the issuing ca has been found - */ - bool (*is_crl_issuer) (ca_info_t *this, const crl_t *crl); - - /** - * @brief Checks if the ca certificate has the isCA flag set - * - * @param this ca info object - * @return TRUE if the isCA flag is set - */ - bool (*is_ca) (ca_info_t *this); - - /** - * @brief Checks if the ca enforces a strict crl policy - * - * @param this ca info object - * @return TRUE if the crl policy is strict - */ - bool (*is_strict) (ca_info_t *this); - - /** - * @brief Merges info from a secondary ca info object - * - * @param this primary ca info object - * @param that secondary ca info object - */ - void (*add_info) (ca_info_t *this, const ca_info_t *that); - - /** - * @brief Adds a new or replaces an obsoleted CRL - * - * @param this ca info object - * @param crl crl to be added - */ - void (*add_crl) (ca_info_t *this, crl_t *crl); - - /** - * @brief Does the CA have a CRL? - * - * @param this ca info object - * @return TRUE if crl is available - */ - bool (*has_crl) (ca_info_t *this); - - /** - * @brief Does the CA have OCSP certinfos? - * - * @param this ca info object - * @return TRUE if there are any certinfos - */ - bool (*has_certinfos) (ca_info_t *this); - - /** - * @brief Print the CA info onto the console - * - * @param this ca info object - * @param out output stream - * @param utc TRUE - utc - FALSE - local time - */ - void (*list) (ca_info_t *this, FILE *out, bool utc); - - /** - * @brief List the CRL onto the console - * - * @param this ca info object - * @param out output stream - * @param utc TRUE - utc - FALSE - local time - */ - void (*list_crl) (ca_info_t *this, FILE *out, bool utc); - - /** - * @brief List the OCSP certinfos onto the console - * - * @param this ca info object - * @param out output stream - * @param utc TRUE - utc - FALSE - local time - */ - void (*list_certinfos) (ca_info_t *this, FILE *out, bool utc); - - /** - * @brief Adds a CRL URI to a list - * - * @param this ca info object - * @param uri crl uri to be added - */ - void (*add_crluri) (ca_info_t *this, chunk_t uri); - - /** - * @brief Adds a OCSP URI to a list - * - * @param this ca info object - * @param uri ocsp uri to be added - */ - void (*add_ocspuri) (ca_info_t *this, chunk_t uri); - - /** - * @brief Get the ca certificate - * - * @param this ca info object - * @return ca certificate - */ - x509_t* (*get_certificate) (ca_info_t *this); - - /** - * @brief Verify the status of a certificate by CRL - * - * @param this ca info object - * @param certinfo detailed certificate status information - * @param crl_dir directory where fetched crls should be stored - * @return certificate status - */ - cert_status_t (*verify_by_crl) (ca_info_t *this, certinfo_t *certinfo, const char *crl_dir); - - /** - * @brief Verify the status of a certificate by OCSP - * - * @param this ca info object - * @param certinfo detailed certificate status information - * @param credentials credential store needed for trust path verification - * @return certificate status - */ - cert_status_t (*verify_by_ocsp) (ca_info_t* this, certinfo_t* certinfo, struct credential_store_t* credentials); - - /** - * @brief Purge the OCSP certinfos of a ca info record - * - * @param this ca info object - */ - void (*purge_ocsp) (ca_info_t *this); - - /** - * @brief Destroys a ca info record - * - * @param this ca info to destroy - */ - void (*destroy) (ca_info_t *this); -}; - -/** - * @brief Set ca info options - * - * @param cache TRUE if crls shall be cached by storing them - * @param interval crl_check_interval to be set in seconds - * - * @ingroup crypto - */ -void ca_info_set_options(strict_t strict, bool cache, u_int interval); - -/** - * @brief Create a ca info record - * - * @param name name of the ca info record - * @param cacert path to the ca certificate - * @return created ca_info_t, or NULL if invalid. - * - * @ingroup crypto - */ -ca_info_t *ca_info_create(const char *name, x509_t *cacert); - -#endif /* CA_H_ */ diff --git a/src/libstrongswan/crypto/certinfo.c b/src/libstrongswan/crypto/certinfo.c deleted file mode 100644 index 8a125e247..000000000 --- a/src/libstrongswan/crypto/certinfo.c +++ /dev/null @@ -1,257 +0,0 @@ -/** - * @file certinfo.c - * - * @brief Implementation of certinfo_t. - * - */ - -/* - * Copyright (C) 2006 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 <time.h> -#include <stdio.h> - -#include <library.h> - -#include "certinfo.h" - -typedef struct private_certinfo_t private_certinfo_t; - -/** - * Private data of a certinfo_t object. - */ -struct private_certinfo_t { - /** - * Public interface for this certificate status information object. - */ - certinfo_t public; - - /** - * Serial number of the certificate - */ - chunk_t serialNumber; - - /** - * Certificate status - */ - cert_status_t status; - - /** - * Certificate status is for one-time use only - */ - bool once; - - /** - * Time when the certificate status info was generated - */ - time_t thisUpdate; - - /** - * Time when an updated certifcate status info will be available - */ - time_t nextUpdate; - - /** - * Time of certificate revocation - */ - time_t revocationTime; - - /** - * Reason of certificate revocation - */ - crl_reason_t revocationReason; -}; - -ENUM(cert_status_names, CERT_GOOD, CERT_UNTRUSTED, - "good", - "revoked", - "unknown", - "unknown", - "untrusted", -); - -ENUM(crl_reason_names, REASON_UNSPECIFIED, REASON_REMOVE_FROM_CRL, - "unspecified", - "key compromise", - "ca compromise", - "affiliation changed", - "superseded", - "cessation of operation", - "certificate hold", - "reason #7", - "remove from crl", -); - -/** - * Implements certinfo_t.compare_serialNumber - */ -static int compare_serialNumber(const private_certinfo_t *this, const private_certinfo_t *that) -{ - return chunk_compare(this->serialNumber, that->serialNumber); -} - -/** - * Implements certinfo_t.equals_serialNumber - */ -static bool equals_serialNumber(const private_certinfo_t *this, const private_certinfo_t *that) -{ - return chunk_equals(this->serialNumber, that->serialNumber); -} - -/** - * Implements certinfo_t.get_serialNumber - */ -static chunk_t get_serialNumber(const private_certinfo_t *this) -{ - return this->serialNumber; -} - -/** - * Implements certinfo_t.set_status - */ -static void set_status(private_certinfo_t *this, cert_status_t status) -{ - this->status = status; -} - -/** - * Implements certinfo_t.get_status - */ -static cert_status_t get_status(const private_certinfo_t *this) -{ - return this->status; -} - -/** - * Implements certinfo_t.set_thisUpdate - */ -static void set_thisUpdate(private_certinfo_t *this, time_t thisUpdate) -{ - this->thisUpdate = thisUpdate; -} - -/** - * Implements certinfo_t.get_thisUpdate - */ -static time_t get_thisUpdate(const private_certinfo_t *this) -{ - return this->thisUpdate; -} - -/** - * Implements certinfo_t.set_nextUpdate - */ -static void set_nextUpdate(private_certinfo_t *this, time_t nextUpdate) -{ - this->nextUpdate = nextUpdate; -} - -/** - * Implements certinfo_t.get_nextUpdate - */ -static time_t get_nextUpdate(const private_certinfo_t *this) -{ - return this->nextUpdate; -} - -/** - * Implements certinfo_t.set_revocationTime - */ -static void set_revocationTime(private_certinfo_t *this, time_t revocationTime) -{ - this->revocationTime = revocationTime; -} - -/** - * Implements certinfo_t.get_revocationTime - */ -static time_t get_revocationTime(const private_certinfo_t *this) -{ - return this->revocationTime; -} - -/** - * Implements certinfo_t.set_revocationReason - */ -static void set_revocationReason(private_certinfo_t *this, crl_reason_t reason) -{ - this->revocationReason = reason; -} - -/** - * Implements certinfo_t.get_revocationReason - */ -static crl_reason_t get_revocationReason(const private_certinfo_t *this) -{ - return this->revocationReason; -} - -/** - * Implements certinfo_t.update - */ -static void update(private_certinfo_t *this, const private_certinfo_t *that) -{ - if (equals_serialNumber(this, that)) - { - chunk_t this_serialNumber = this->serialNumber; - - *this = *that; - this->serialNumber = this_serialNumber; - } -} - -/** - * Implements certinfo_t.destroy - */ -static void destroy(private_certinfo_t *this) -{ - free(this->serialNumber.ptr); - free(this); -} - -/* - * Described in header. - */ -certinfo_t *certinfo_create(chunk_t serial) -{ - private_certinfo_t *this = malloc_thing(private_certinfo_t); - - /* initialize */ - this->serialNumber = chunk_clone(serial); - this->status = CERT_UNDEFINED; - this->thisUpdate = UNDEFINED_TIME; - this->nextUpdate = UNDEFINED_TIME; - this->revocationTime = UNDEFINED_TIME; - this->revocationReason = REASON_UNSPECIFIED; - - /* public functions */ - this->public.compare_serialNumber = (int (*) (const certinfo_t*,const certinfo_t*))compare_serialNumber; - this->public.equals_serialNumber = (bool (*) (const certinfo_t*,const certinfo_t*))equals_serialNumber; - this->public.get_serialNumber = (chunk_t (*) (const certinfo_t*))get_serialNumber; - this->public.set_status = (void (*) (certinfo_t*,cert_status_t))set_status; - this->public.get_status = (cert_status_t (*) (const certinfo_t*))get_status; - this->public.set_thisUpdate = (void (*) (certinfo_t*,time_t))set_thisUpdate; - this->public.get_thisUpdate = (time_t (*) (const certinfo_t*))get_thisUpdate; - this->public.set_nextUpdate = (void (*) (certinfo_t*,time_t))set_nextUpdate; - this->public.get_nextUpdate = (time_t (*) (const certinfo_t*))get_nextUpdate; - this->public.set_revocationTime = (void (*) (certinfo_t*,time_t))set_revocationTime; - this->public.get_revocationTime = (time_t (*) (const certinfo_t*))get_revocationTime; - this->public.set_revocationReason = (void (*) (certinfo_t*, crl_reason_t))set_revocationReason; - this->public.get_revocationReason = (crl_reason_t(*) (const certinfo_t*))get_revocationReason; - this->public.update = (void (*) (certinfo_t*, const certinfo_t*))update; - this->public.destroy = (void (*) (certinfo_t*))destroy; - - return &this->public; -} diff --git a/src/libstrongswan/crypto/certinfo.h b/src/libstrongswan/crypto/certinfo.h deleted file mode 100644 index 476befda8..000000000 --- a/src/libstrongswan/crypto/certinfo.h +++ /dev/null @@ -1,203 +0,0 @@ -/** - * @file certinfo.h - * - * @brief Interface of certinfo_t. - * - */ - -/* - * Copyright (C) 2006 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. - */ - -#ifndef CERTINFO_H_ -#define CERTINFO_H_ - -typedef enum cert_status_t cert_status_t; -typedef enum crl_reason_t crl_reason_t; -typedef struct certinfo_t certinfo_t; - -#include <library.h> - -/** - * RFC 2560 OCSP - certificate status - */ -enum cert_status_t { - CERT_GOOD = 0, - CERT_REVOKED = 1, - CERT_UNKNOWN = 2, - CERT_UNDEFINED = 3, - CERT_UNTRUSTED = 4 /* private use */ -}; - -extern enum_name_t *cert_status_names; - -/** - * RFC 2459 CRL reason codes - */ -enum crl_reason_t { - REASON_UNSPECIFIED = 0, - REASON_KEY_COMPROMISE = 1, - REASON_CA_COMPROMISE = 2, - REASON_AFFILIATION_CHANGED = 3, - REASON_SUPERSEDED = 4, - REASON_CESSATION_OF_OPERATON = 5, - REASON_CERTIFICATE_HOLD = 6, - REASON_REMOVE_FROM_CRL = 8 -}; - -extern enum_name_t *crl_reason_names; - -/** - * @brief X.509 certificate status information - * - * @ingroup transforms - */ -struct certinfo_t { - - /** - * @brief Check if both certinfo objects have the same serialNumber. - * - * @param this calling object - * @param that second certinfo_t object - * @return TRUE if the same serialNumber - */ - bool (*equals_serialNumber) (const certinfo_t *this, const certinfo_t *that); - - /** - * @brief Compares two serial numbers. - * - * @param this calling object - * @param that second certinfo_t object - * @return negative if this is smaller than that - * zero if this equals that - * positive if this is greater than that - */ - int (*compare_serialNumber) (const certinfo_t *this, const certinfo_t *that); - - /** - * @brief Get serial number. - * - * @param this calling object - * @return serialNumber - */ - chunk_t (*get_serialNumber) (const certinfo_t *this); - - /** - * @brief Set certificate status. - * - * @param this calling object - * @param status status - */ - void (*set_status) (certinfo_t *this, cert_status_t status); - - /** - * @brief Get certificate status. - * - * @param this calling object - * @return status - */ - cert_status_t (*get_status) (const certinfo_t *this); - - /** - * @brief Set thisUpdate. - * - * @param this calling object - * @param thisUpdate thisUpdate - */ - void (*set_thisUpdate) (certinfo_t *this, time_t thisUpdate); - - /** - * @brief Get thisUpdate. - * - * @param this calling object - * @return thisUpdate - */ - time_t (*get_thisUpdate) (const certinfo_t *this); - - /** - * @brief Set nextUpdate. - * - * @param this calling object - * @param nextUpdate - */ - void (*set_nextUpdate) (certinfo_t *this, time_t nextUpdate); - - /** - * @brief Get nextUpdate. - * - * @param this calling object - * @return nextUpdate - */ - time_t (*get_nextUpdate) (const certinfo_t *this); - - /** - * @brief Set revocationTime. - * - * @param this calling object - * @param revocationTime revocationTime - */ - void (*set_revocationTime) (certinfo_t *this, time_t revocationTime); - - /** - * @brief Get revocationTime. - * - * @param this calling object - * @return revocationTime - */ - time_t (*get_revocationTime) (const certinfo_t *this); - - /** - * @brief Set revocationReason. - * - * @param this calling object - * @param reason revocationReason - */ - void (*set_revocationReason) (certinfo_t *this, crl_reason_t reason); - - /** - * @brief Get revocationReason. - * - * @param this calling object - * @return revocationReason - */ - crl_reason_t (*get_revocationReason) (const certinfo_t *this); - - /** - * @brief Set revocationReason. - * - * @param this calling object to be updated - * @param that object containing updated information - */ - void (*update) (certinfo_t *this, const certinfo_t *that); - - /** - * @brief Destroys the certinfo_t object. - * - * @param this certinfo_t to destroy - */ - void (*destroy) (certinfo_t *this); - -}; - -/** - * @brief Create a certinfo_t object. - * - * @param serial chunk serial number of the certificate - * @return created certinfo_t object - * - * @ingroup transforms - */ -certinfo_t *certinfo_create(chunk_t serial); - -#endif /* CERTINFO_H_ */ diff --git a/src/libstrongswan/crypto/crl.c b/src/libstrongswan/crypto/crl.c deleted file mode 100755 index ab23bb9ec..000000000 --- a/src/libstrongswan/crypto/crl.c +++ /dev/null @@ -1,536 +0,0 @@ -/** - * @file crl.c - * - * @brief Implementation of crl_t. - * - */ - -/* - * Copyright (C) 2006 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. - * - * RCSID $Id: crl.c 3355 2007-11-20 12:06:40Z martin $ - */ - -#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/pem.h> -#include <utils/linked_list.h> -#include <utils/identification.h> - -#include "certinfo.h" -#include "x509.h" -#include "crl.h" - -#define CRL_WARNING_INTERVAL 7 /* days */ - -/* access structure for a revoked certificate */ - -typedef struct revokedCert_t revokedCert_t; - -struct revokedCert_t { - chunk_t userCertificate; - time_t revocationDate; - crl_reason_t revocationReason; -}; - -typedef struct private_crl_t private_crl_t; - -/** - * Private data of a crl_t object. - */ -struct private_crl_t { - /** - * Public interface for this crl. - */ - crl_t public; - - /** - * Time when crl was installed - */ - time_t installed; - - /** - * List of crlDistributionPoints - */ - linked_list_t *crlDistributionPoints; - - /** - * X.509 crl in DER format - */ - chunk_t certificateList; - - /** - * X.509 crl body over which signature is computed - */ - chunk_t tbsCertList; - - /** - * Version of the X.509 crl - */ - u_int version; - - /** - * Signature algorithm - */ - int sigAlg; - - /** - * 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 identification_t's representing subjectAltNames - */ - linked_list_t *revokedCertificates; - - /** - * Authority Key Identifier - */ - chunk_t authKeyID; - - /** - * Authority Key Serial Number - */ - chunk_t authKeySerialNumber; - - /** - * Signature algorithm (must be identical to sigAlg) - */ - int algorithm; - - /** - * Signature - */ - chunk_t signature; -}; - -/** - * 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 */ - }; - -#define CRL_OBJ_CERTIFICATE_LIST 0 -#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 -#define CRL_OBJ_ROOF 29 - -/** - * Parses a CRL revocation reason code - */ -static crl_reason_t parse_crl_reasonCode(chunk_t object) -{ - crl_reason_t reason = REASON_UNSPECIFIED; - - if (*object.ptr == ASN1_ENUMERATED && asn1_length(&object) == 1) - { - reason = *object.ptr; - } - DBG2(" '%N'", crl_reason_names, reason); - - return reason; -} - -/** - * Parses an X.509 Certificate Revocation List (CRL) - */ -bool parse_x509crl(chunk_t blob, u_int level0, private_crl_t *crl) -{ - asn1_ctx_t ctx; - bool critical; - chunk_t extnID; - chunk_t userCertificate = chunk_empty; - revokedCert_t *revokedCert = NULL; - chunk_t object; - u_int level; - int objectID = 0; - - asn1_init(&ctx, blob, level0, FALSE, FALSE); - - while (objectID < CRL_OBJ_ROOF) - { - if (!extract_object(crlObjects, &objectID, &object, &level, &ctx)) - return FALSE; - - /* those objects which will parsed further need the next higher level */ - level++; - - switch (objectID) - { - case CRL_OBJ_CERTIFICATE_LIST: - crl->certificateList = object; - break; - case CRL_OBJ_TBS_CERT_LIST: - crl->tbsCertList = object; - break; - case CRL_OBJ_VERSION: - crl->version = (object.len) ? (1+(u_int)*object.ptr) : 1; - DBG2(" v%d", crl->version); - break; - case CRL_OBJ_SIG_ALG: - crl->sigAlg = parse_algorithmIdentifier(object, level, NULL); - break; - case CRL_OBJ_ISSUER: - crl->issuer = identification_create_from_encoding(ID_DER_ASN1_DN, object); - DBG2(" '%D'", crl->issuer); - break; - case CRL_OBJ_THIS_UPDATE: - crl->thisUpdate = parse_time(object, level); - break; - case CRL_OBJ_NEXT_UPDATE: - crl->nextUpdate = parse_time(object, level); - break; - case CRL_OBJ_USER_CERTIFICATE: - userCertificate = object; - break; - case CRL_OBJ_REVOCATION_DATE: - revokedCert = malloc_thing(revokedCert_t); - revokedCert->userCertificate = userCertificate; - revokedCert->revocationDate = parse_time(object, level); - revokedCert->revocationReason = REASON_UNSPECIFIED; - crl->revokedCertificates->insert_last(crl->revokedCertificates, (void *)revokedCert); - 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 = known_oid(extnID); - - if (revokedCert && extn_oid == OID_CRL_REASON_CODE) - { - revokedCert->revocationReason = parse_crl_reasonCode(object); - } - else if (extn_oid == OID_AUTHORITY_KEY_ID) - { - x509_parse_authorityKeyIdentifier(object, level, - &crl->authKeyID, &crl->authKeySerialNumber); - } - else if (extn_oid == OID_CRL_NUMBER) - { - if (!parse_asn1_simple_object(&object, ASN1_INTEGER, level, "crlNumber")) - { - return FALSE; - } - crl->crlNumber = object; - } - } - break; - case CRL_OBJ_ALGORITHM: - crl->algorithm = parse_algorithmIdentifier(object, level, NULL); - if (crl->algorithm != crl->sigAlg) - { - DBG1(" signature algorithms do not agree"); - return FALSE; - } - break; - case CRL_OBJ_SIGNATURE: - crl->signature = object; - break; - default: - break; - } - objectID++; - } - time(&crl->installed); - return TRUE; -} - -/** - * Implements crl_t.is_valid - */ -static bool is_valid(const private_crl_t *this) -{ - time_t current_time = time(NULL); - - DBG2(" this update : %T", &this->thisUpdate); - DBG2(" current time: %T", ¤t_time); - DBG2(" next update: %T", &this->nextUpdate); - - return current_time < this->nextUpdate; -} - -/** - * Implements crl_t.get_issuer - */ -static identification_t *get_issuer(const private_crl_t *this) -{ - return this->issuer; -} - -/** - * Implements crl_t.equals_issuer - */ -static bool equals_issuer(const private_crl_t *this, const private_crl_t *other) -{ - return (this->authKeyID.ptr) - ? chunk_equals(this->authKeyID, other->authKeyID) - : (this->issuer->equals(this->issuer, other->issuer) - && chunk_equals_or_null(this->authKeySerialNumber, other->authKeySerialNumber)); -} - -/** - * Implements crl_t.is_issuer - */ -static bool is_issuer(const private_crl_t *this, const x509_t *issuer) -{ - return (this->authKeyID.ptr) - ? chunk_equals(this->authKeyID, issuer->get_subjectKeyID(issuer)) - : (this->issuer->equals(this->issuer, issuer->get_subject(issuer)) - && chunk_equals_or_null(this->authKeySerialNumber, issuer->get_serialNumber(issuer))); -} - -/** - * Implements crl_t.is_newer - */ -static bool is_newer(const private_crl_t *this, const private_crl_t *other) -{ - return (this->nextUpdate > other->nextUpdate); -} - -/** - * Implements crl_t.verify - */ -static bool verify(const private_crl_t *this, const rsa_public_key_t *signer) -{ - hash_algorithm_t algorithm = hasher_algorithm_from_oid(this->algorithm); - - if (algorithm == HASH_UNKNOWN) - { - DBG1(" unknown signature algorithm"); - return FALSE; - } - return signer->verify_emsa_pkcs1_signature(signer, algorithm, this->tbsCertList, this->signature) == SUCCESS; -} - -/** - * Implements crl_t.get_status - */ -static void get_status(const private_crl_t *this, certinfo_t *certinfo) -{ - chunk_t serialNumber = certinfo->get_serialNumber(certinfo); - iterator_t *iterator; - revokedCert_t *revokedCert; - - certinfo->set_nextUpdate(certinfo, this->nextUpdate); - certinfo->set_status(certinfo, CERT_GOOD); - - iterator = this->revokedCertificates->create_iterator(this->revokedCertificates, TRUE); - while (iterator->iterate(iterator, (void**)&revokedCert)) - { - if (chunk_equals(serialNumber, revokedCert->userCertificate)) - { - certinfo->set_status(certinfo, CERT_REVOKED); - certinfo->set_revocationTime(certinfo, revokedCert->revocationDate); - certinfo->set_revocationReason(certinfo, revokedCert->revocationReason); - break; - } - } - iterator->destroy(iterator); -} - -/** - * Implements crl_t.write_to_file. - */ -static bool write_to_file(private_crl_t *this, const char *path, mode_t mask, bool force) -{ - return chunk_write(this->certificateList, path, "crl", mask, force); -} - -/** - * Implements crl_t.destroy - */ -static void destroy(private_crl_t *this) -{ - this->revokedCertificates->destroy_function(this->revokedCertificates, free); - this->crlDistributionPoints->destroy_offset(this->crlDistributionPoints, - offsetof(identification_t, destroy)); - DESTROY_IF(this->issuer); - free(this->certificateList.ptr); - free(this); -} - -/** - * Implementation of crl_t.list. - */ -static void list(private_crl_t *this, FILE* out, bool utc) -{ - time_t now; - - now = time(NULL); - - fprintf(out, "%#T, revoked certs: %d\n", &this->installed, utc, - this->revokedCertificates->get_count(this->revokedCertificates)); - fprintf(out, " issuer: '%D'\n", this->issuer); - if (this->crlNumber.ptr) - { - fprintf(out, " crlnumber: %#B\n", &this->crlNumber); - } - fprintf(out, " updates: this %#T\n", &this->thisUpdate, utc); - fprintf(out, " next %#T ", &this->nextUpdate, utc); - if (this->nextUpdate == UNDEFINED_TIME) - { - fprintf(out, "ok (expires never)\n"); - } - else if (now > this->nextUpdate) - { - fprintf(out, "expired (%#V ago)\n", &now, &this->nextUpdate); - } - else if (now > this->nextUpdate - CRL_WARNING_INTERVAL * 60 * 60 * 24) - { - fprintf(out, "ok (expires in %#V)\n", &now, &this->nextUpdate); - } - else - { - fprintf(out, "ok\n"); - } - if (this->authKeyID.ptr) - { - fprintf(out, " authkey: %#B\n", &this->authKeyID); - } - if (this->authKeySerialNumber.ptr) - { - fprintf(out, " aserial: %#B\n", &this->authKeySerialNumber); - } -} - -/* - * Described in header. - */ -crl_t *crl_create_from_chunk(chunk_t chunk) -{ - private_crl_t *this = malloc_thing(private_crl_t); - - /* initialize */ - this->crlDistributionPoints = linked_list_create(); - this->tbsCertList = chunk_empty; - this->issuer = NULL; - this->crlNumber = chunk_empty; - this->revokedCertificates = linked_list_create(); - this->authKeyID = chunk_empty; - this->authKeySerialNumber = chunk_empty; - - /* public functions */ - this->public.get_issuer = (identification_t* (*) (const crl_t*))get_issuer; - this->public.equals_issuer = (bool (*) (const crl_t*,const crl_t*))equals_issuer; - this->public.is_issuer = (bool (*) (const crl_t*,const x509_t*))is_issuer; - this->public.is_valid = (bool (*) (const crl_t*))is_valid; - this->public.is_newer = (bool (*) (const crl_t*,const crl_t*))is_newer; - this->public.verify = (bool (*) (const crl_t*,const rsa_public_key_t*))verify; - this->public.get_status = (void (*) (const crl_t*,certinfo_t*))get_status; - this->public.write_to_file = (bool (*) (const crl_t*,const char*,mode_t,bool))write_to_file; - this->public.list = (void(*)(crl_t*, FILE* out, bool utc))list; - this->public.destroy = (void (*) (crl_t*))destroy; - - if (!parse_x509crl(chunk, 0, this)) - { - destroy(this); - return NULL; - } - - return &this->public; -} - -/* - * Described in header. - */ -crl_t *crl_create_from_file(const char *filename) -{ - bool pgp = FALSE; - chunk_t chunk = chunk_empty; - - if (!pem_asn1_load_file(filename, NULL, "crl", &chunk, &pgp)) - { - return NULL; - } - return crl_create_from_chunk(chunk); -} diff --git a/src/libstrongswan/crypto/crl.h b/src/libstrongswan/crypto/crl.h deleted file mode 100755 index bcf031dd4..000000000 --- a/src/libstrongswan/crypto/crl.h +++ /dev/null @@ -1,158 +0,0 @@ -/** - * @file crl.h - * - * @brief Interface of crl_t. - * - */ - -/* - * Copyright (C) 2006 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. - * - * RCSID $Id: crl.h 3300 2007-10-12 21:53:18Z andreas $ - */ - -#ifndef CRL_H_ -#define CRL_H_ - -typedef struct crl_t crl_t; - -#include <library.h> -#include <crypto/rsa/rsa_public_key.h> -#include <crypto/certinfo.h> -#include <utils/identification.h> -#include <utils/iterator.h> - -/** - * @brief X.509 certificate revocation list - * - * @b Constructors: - * - crl_create_from_chunk() - * - crl_create_from_file() - * - * @ingroup transforms - */ -struct crl_t { - - /** - * @brief Get the crl's issuer ID. - * - * The resulting ID is always a identification_t - * of type ID_DER_ASN1_DN. - * - * @param this calling object - * @return issuers ID - */ - identification_t *(*get_issuer) (const crl_t *this); - - /** - * @brief Check if both crls have the same issuer. - * - * @param this calling object - * @param other other crl - * @return TRUE if the same issuer - */ - bool (*equals_issuer) (const crl_t *this, const crl_t *other); - - /** - * @brief Check if ia candidate cert is the issuer of the crl - * - * @param this calling object - * @param issuer candidate issuer of the crl - * @return TRUE if issuer - */ - bool (*is_issuer) (const crl_t *this, const x509_t *issuer); - - /** - * @brief Checks the validity interval of the crl - * - * @param this calling object - * @return TRUE if the crl is valid - */ - bool (*is_valid) (const crl_t *this); - - /** - * @brief Checks if this crl is newer (thisUpdate) than the other crl - * - * @param this calling object - * @param other other crl object - * @return TRUE if this was issued more recently than other - */ - bool (*is_newer) (const crl_t *this, const crl_t *other); - - /** - * @brief Check if a crl is trustworthy. - * - * @param this calling object - * @param signer signer's RSA public key - * @return TRUE if crl is trustworthy - */ - bool (*verify) (const crl_t *this, const rsa_public_key_t *signer); - - /** - * @brief Get the certificate status - * - * @param this calling object - * @param certinfo certinfo is updated - */ - void (*get_status) (const crl_t *this, certinfo_t *certinfo); - - /** - * @brief Log the info of this CRL to out. - * - * @param this calling object - * @param out stream to write to - * @param utc TRUE for UTC, FALSE for local time - */ - void (*list)(crl_t *this, FILE* out, bool utc); - - /** - * @brief Write a der-encoded crl to a file - * - * @param this calling object - * @param path path where the file is to be stored - * @param mask file access control rights - * @param force overwrite the file if it already exists - * @return TRUE if successfully written - */ - bool (*write_to_file) (const crl_t *this, const char *path, mode_t mask, bool force); - - /** - * @brief Destroys the crl. - * - * @param this crl to destroy - */ - void (*destroy) (crl_t *this); -}; - -/** - * @brief Read a x509 crl from a DER encoded blob. - * - * @param chunk chunk containing DER encoded data - * @return created crl_t, or NULL if invalid. - * - * @ingroup transforms - */ -crl_t *crl_create_from_chunk(chunk_t chunk); - -/** - * @brief Read a x509 crl from a DER encoded file. - * - * @param filename file containing DER encoded data - * @return created crl_t, or NULL if invalid. - * - * @ingroup transforms - */ -crl_t *crl_create_from_file(const char *filename); - -#endif /* CRL_H_ */ diff --git a/src/libstrongswan/crypto/crypters/crypter.c b/src/libstrongswan/crypto/crypters/crypter.c index 7f62741a7..2c291a9f5 100644 --- a/src/libstrongswan/crypto/crypters/crypter.c +++ b/src/libstrongswan/crypto/crypters/crypter.c @@ -1,10 +1,3 @@ -/** - * @file crypter.c - * - * @brief Generic constructor for crypter_t. - * - */ - /* * Copyright (C) 2005-2006 Martin Willi * Copyright (C) 2005 Jan Hutter @@ -19,15 +12,12 @@ * 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: crypter.c 3971 2008-05-16 13:27:21Z tobias $ */ - #include "crypter.h" -#include <crypto/crypters/aes_cbc_crypter.h> -#include <crypto/crypters/des_crypter.h> - - ENUM_BEGIN(encryption_algorithm_names, ENCR_UNDEFINED, ENCR_UNDEFINED, "UNDEFINED"); ENUM_NEXT(encryption_algorithm_names, ENCR_DES_IV64, ENCR_DES_IV32, ENCR_UNDEFINED, @@ -40,29 +30,16 @@ ENUM_NEXT(encryption_algorithm_names, ENCR_DES_IV64, ENCR_DES_IV32, ENCR_UNDEFIN "BLOWFISH", "3IDEA", "DES_IV32"); -ENUM_NEXT(encryption_algorithm_names, ENCR_NULL, ENCR_AES_CTR, ENCR_DES_IV32, +ENUM_NEXT(encryption_algorithm_names, ENCR_NULL, ENCR_AES_CCM_ICV16, ENCR_DES_IV32, "NULL", "AES_CBC", - "AES_CTR"); -ENUM_END(encryption_algorithm_names, ENCR_AES_CTR); + "AES_CTR", + "AES_CCM_8", + "AES_CCM_12", + "AES_CCM_16"); +ENUM_NEXT(encryption_algorithm_names, ENCR_AES_GCM_ICV8, ENCR_AES_GCM_ICV16, ENCR_AES_CCM_ICV16, + "AES_GCM_8", + "AES_GCM_12", + "AES_GCM_16"); +ENUM_END(encryption_algorithm_names, ENCR_AES_GCM_ICV16); -/* - * Described in header. - */ -crypter_t *crypter_create(encryption_algorithm_t encryption_algorithm, size_t key_size) -{ - switch (encryption_algorithm) - { - case ENCR_AES_CBC: - { - return (crypter_t*)aes_cbc_crypter_create(key_size); - } - case ENCR_DES: - case ENCR_3DES: - { - return (crypter_t*)des_crypter_create(encryption_algorithm); - } - default: - return NULL; - } -} diff --git a/src/libstrongswan/crypto/crypters/crypter.h b/src/libstrongswan/crypto/crypters/crypter.h index 46d94ce93..aade888fa 100644 --- a/src/libstrongswan/crypto/crypters/crypter.h +++ b/src/libstrongswan/crypto/crypters/crypter.h @@ -1,10 +1,3 @@ -/** - * @file crypter.h - * - * @brief Interface crypter_t - * - */ - /* * Copyright (C) 2005-2006 Martin Willi * Copyright (C) 2005 Jan Hutter @@ -19,6 +12,13 @@ * 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: crypter.h 3971 2008-05-16 13:27:21Z tobias $ + */ + +/** + * @defgroup crypter crypter + * @{ @ingroup crypto */ #ifndef CRYPTER_H_ @@ -30,21 +30,12 @@ typedef struct crypter_t crypter_t; #include <library.h> /** - * @brief Encryption algorithm, as in IKEv2 RFC 3.3.2. - * - * Currently only the following algorithms are implemented: - * - ENCR_AES_CBC - * - ENCR_DES - * - ENCR_3DES - * - * @ingroup crypters + * Encryption algorithm, as in IKEv2 RFC 3.3.2. */ enum encryption_algorithm_t { ENCR_UNDEFINED = 1024, ENCR_DES_IV64 = 1, - /** Implemented in class des_crypter_t */ ENCR_DES = 2, - /** Implemented in class des_crypter_t */ ENCR_3DES = 3, ENCR_RC5 = 4, ENCR_IDEA = 5, @@ -53,9 +44,14 @@ enum encryption_algorithm_t { ENCR_3IDEA = 8, ENCR_DES_IV32 = 9, ENCR_NULL = 11, - /** Implemented in class aes_cbc_crypter_t */ ENCR_AES_CBC = 12, - ENCR_AES_CTR = 13 + ENCR_AES_CTR = 13, + ENCR_AES_CCM_ICV8 = 14, + ENCR_AES_CCM_ICV12 = 15, + ENCR_AES_CCM_ICV16 = 16, + ENCR_AES_GCM_ICV8 = 18, + ENCR_AES_GCM_ICV12 = 19, + ENCR_AES_GCM_ICV16 = 20 }; /** @@ -64,92 +60,65 @@ enum encryption_algorithm_t { extern enum_name_t *encryption_algorithm_names; /** - * @brief Generic interface for symmetric encryption algorithms. - * - * @b Constructors: - * - crypter_create() - * - * @ingroup crypters + * Generic interface for symmetric encryption algorithms. */ struct crypter_t { /** - * @brief Encrypt a chunk of data and allocate space for the encrypted value. + * Encrypt a chunk of data and allocate space for the encrypted value. * - * @param this calling object - * @param data data to encrypt - * @param iv initializing vector - * @param[out] encrypted pointer where the encrypted bytes will be written - * @return - * - SUCCESS - * - INVALID_ARG if data size not a multiple of block size + * The length of the iv must equal to get_block_size(), while the length + * of data must be a multiple it. + * If encrypted is NULL, the encryption is done in-place (overwriting data). + * + * @param data data to encrypt + * @param iv initializing vector + * @param encrypted chunk to allocate encrypted data, or NULL */ - status_t (*encrypt) (crypter_t *this, chunk_t data, chunk_t iv, chunk_t *encrypted); + void (*encrypt) (crypter_t *this, chunk_t data, chunk_t iv, + chunk_t *encrypted); /** - * @brief Decrypt a chunk of data and allocate space for the decrypted value. + * Decrypt a chunk of data and allocate space for the decrypted value. + * + * The length of the iv must equal to get_block_size(), while the length + * of data must be a multiple it. + * If decrpyted is NULL, the encryption is done in-place (overwriting data). * - * @param this calling object - * @param data data to decrypt - * @param iv initializing vector - * @param[out] encrypted pointer where the decrypted bytes will be written - * @return - * - SUCCESS - * - INVALID_ARG if data size not a multiple of block size + * @param data data to decrypt + * @param iv initializing vector + * @param encrypted chunk to allocate decrypted data, or NULL */ - status_t (*decrypt) (crypter_t *this, chunk_t data, chunk_t iv, chunk_t *decrypted); + void (*decrypt) (crypter_t *this, chunk_t data, chunk_t iv, + chunk_t *decrypted); /** - * @brief Get the block size of this crypter_t object. + * Get the block size of the crypto algorithm. * - * @param this calling object * @return block size in bytes */ size_t (*get_block_size) (crypter_t *this); /** - * @brief Get the key size of this crypter_t object. + * Get the key size of the crypto algorithm. * - * @param this calling object * @return key size in bytes */ size_t (*get_key_size) (crypter_t *this); /** - * @brief Set the key for this crypter_t object. - * - * @param this calling object + * Set the key. + * + * The length of the key must match get_key_size(). + * * @param key key to set - * @return - * - SUCCESS - * - INVALID_ARG if key length invalid */ - status_t (*set_key) (crypter_t *this, chunk_t key); + void (*set_key) (crypter_t *this, chunk_t key); /** - * @brief Destroys a crypter_t object. - * - * @param this calling object + * Destroys a crypter_t object. */ void (*destroy) (crypter_t *this); }; -/** - * @brief Generic constructor for crypter_t objects. - * - * Currently only the following algorithms are implemented: - * - ENCR_AES_CBC - * - ENCR_DES - * - ENCR_3DES - * - * The key_size is ignored for algorithms with fixed key size. - * - * @param encryption_algorithm Algorithm to use for crypter - * @param key_size size of the key in bytes - * @return - * - crypter_t object - * - NULL if encryption algorithm/key_size is not supported - */ -crypter_t *crypter_create(encryption_algorithm_t encryption_algorithm, size_t key_size); - -#endif /*CRYPTER_H_*/ +#endif /*CRYPTER_H_ @} */ diff --git a/src/libstrongswan/crypto/crypto_factory.c b/src/libstrongswan/crypto/crypto_factory.c new file mode 100644 index 000000000..46fa983b2 --- /dev/null +++ b/src/libstrongswan/crypto/crypto_factory.c @@ -0,0 +1,571 @@ +/* + * 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: crypto_factory.c 3806 2008-04-15 05:56:35Z martin $ + */ + +#include "crypto_factory.h" + +#include <utils/linked_list.h> +#include <utils/mutex.h> + +typedef struct crypter_entry_t crypter_entry_t; +struct crypter_entry_t { + /** encryption algorithm */ + encryption_algorithm_t algo; + /** associated constructor */ + crypter_constructor_t create; +}; + +typedef struct signer_entry_t signer_entry_t; +struct signer_entry_t { + /** integrity algorithm */ + integrity_algorithm_t algo; + /** associated constructor */ + signer_constructor_t create; +}; + +typedef struct hasher_entry_t hasher_entry_t; +struct hasher_entry_t { + /** hash algorithm */ + hash_algorithm_t algo; + /** associated constructor */ + hasher_constructor_t create; +}; + +typedef struct prf_entry_t prf_entry_t; +struct prf_entry_t { + /** hash algorithm */ + pseudo_random_function_t algo; + /** associated constructor */ + prf_constructor_t create; +}; + +typedef struct rng_entry_t rng_entry_t; +struct rng_entry_t { + /** quality of randomness */ + rng_quality_t quality; + /** associated constructor */ + rng_constructor_t create; +}; + +typedef struct dh_entry_t dh_entry_t; +struct dh_entry_t { + /** hash algorithm */ + diffie_hellman_group_t group; + /** associated constructor */ + dh_constructor_t create; +}; + +typedef struct private_crypto_factory_t private_crypto_factory_t; + +/** + * private data of crypto_factory + */ +struct private_crypto_factory_t { + + /** + * public functions + */ + crypto_factory_t public; + + /** + * registered crypters, as crypter_entry_t + */ + linked_list_t *crypters; + + /** + * registered signers, as signer_entry_t + */ + linked_list_t *signers; + + /** + * registered hashers, as hasher_entry_t + */ + linked_list_t *hashers; + + /** + * registered prfs, as prf_entry_t + */ + linked_list_t *prfs; + + /** + * registered rngs, as rng_entry_t + */ + linked_list_t *rngs; + + /** + * registered diffie hellman, as dh_entry_t + */ + linked_list_t *dhs; + + /** + * mutex to lock access to modules + */ + mutex_t *mutex; +}; + +/** + * Implementation of crypto_factory_t.create_crypter. + */ +static crypter_t* create_crypter(private_crypto_factory_t *this, + encryption_algorithm_t algo, size_t key_size) +{ + enumerator_t *enumerator; + crypter_entry_t *entry; + crypter_t *crypter = NULL; + + this->mutex->lock(this->mutex); + enumerator = this->crypters->create_enumerator(this->crypters); + while (enumerator->enumerate(enumerator, &entry)) + { + if (entry->algo == algo) + { + crypter = entry->create(algo, key_size); + if (crypter) + { + break; + } + } + } + enumerator->destroy(enumerator); + this->mutex->unlock(this->mutex); + return crypter; +} + +/** + * Implementation of crypto_factory_t.create_signer. + */ +static signer_t* create_signer(private_crypto_factory_t *this, + integrity_algorithm_t algo) +{ + enumerator_t *enumerator; + signer_entry_t *entry; + signer_t *signer = NULL; + + this->mutex->lock(this->mutex); + enumerator = this->signers->create_enumerator(this->signers); + while (enumerator->enumerate(enumerator, &entry)) + { + if (entry->algo == algo) + { + signer = entry->create(algo); + if (signer) + { + break; + } + } + } + enumerator->destroy(enumerator); + this->mutex->unlock(this->mutex); + + return signer; +} + +/** + * Implementation of crypto_factory_t.create_hasher. + */ +static hasher_t* create_hasher(private_crypto_factory_t *this, + hash_algorithm_t algo) +{ + enumerator_t *enumerator; + hasher_entry_t *entry; + hasher_t *hasher = NULL; + + this->mutex->lock(this->mutex); + enumerator = this->hashers->create_enumerator(this->hashers); + while (enumerator->enumerate(enumerator, &entry)) + { + if (algo == HASH_PREFERRED || entry->algo == algo) + { + hasher = entry->create(entry->algo); + if (hasher) + { + break; + } + } + } + enumerator->destroy(enumerator); + this->mutex->unlock(this->mutex); + return hasher; +} + +/** + * Implementation of crypto_factory_t.create_prf. + */ +static prf_t* create_prf(private_crypto_factory_t *this, + pseudo_random_function_t algo) +{ + enumerator_t *enumerator; + prf_entry_t *entry; + prf_t *prf = NULL; + + this->mutex->lock(this->mutex); + enumerator = this->prfs->create_enumerator(this->prfs); + while (enumerator->enumerate(enumerator, &entry)) + { + if (entry->algo == algo) + { + prf = entry->create(algo); + if (prf) + { + break; + } + } + } + enumerator->destroy(enumerator); + this->mutex->unlock(this->mutex); + return prf; +} + +/** + * Implementation of crypto_factory_t.create_rng. + */ +static rng_t* create_rng(private_crypto_factory_t *this, rng_quality_t quality) +{ + enumerator_t *enumerator; + rng_entry_t *entry; + u_int diff = ~0; + rng_constructor_t constr = NULL; + + this->mutex->lock(this->mutex); + enumerator = this->rngs->create_enumerator(this->rngs); + while (enumerator->enumerate(enumerator, &entry)) + { /* find the best matching quality, but at least as good as requested */ + if (entry->quality >= quality && diff > entry->quality - quality) + { + diff = entry->quality - quality; + constr = entry->create; + if (diff == 0) + { /* perfect match, won't get better */ + break; + } + } + } + enumerator->destroy(enumerator); + this->mutex->unlock(this->mutex); + if (constr) + { + return constr(quality); + } + return NULL; +} + +/** + * Implementation of crypto_factory_t.create_dh. + */ +static diffie_hellman_t* create_dh(private_crypto_factory_t *this, + diffie_hellman_group_t group) +{ + enumerator_t *enumerator; + dh_entry_t *entry; + diffie_hellman_t *diffie_hellman = NULL; + + this->mutex->lock(this->mutex); + enumerator = this->dhs->create_enumerator(this->dhs); + while (enumerator->enumerate(enumerator, &entry)) + { + if (entry->group == group) + { + diffie_hellman = entry->create(group); + if (diffie_hellman) + { + break; + } + } + } + enumerator->destroy(enumerator); + this->mutex->unlock(this->mutex); + return diffie_hellman; +} + +/** + * Implementation of crypto_factory_t.add_crypter. + */ +static void add_crypter(private_crypto_factory_t *this, + encryption_algorithm_t algo, + crypter_constructor_t create) +{ + crypter_entry_t *entry = malloc_thing(crypter_entry_t); + + entry->algo = algo; + entry->create = create; + this->mutex->lock(this->mutex); + this->crypters->insert_last(this->crypters, entry); + this->mutex->unlock(this->mutex); +} + +/** + * Implementation of crypto_factory_t.remove_crypter. + */ +static void remove_crypter(private_crypto_factory_t *this, + crypter_constructor_t create) +{ + crypter_entry_t *entry; + enumerator_t *enumerator; + + this->mutex->lock(this->mutex); + enumerator = this->crypters->create_enumerator(this->crypters); + while (enumerator->enumerate(enumerator, &entry)) + { + if (entry->create == create) + { + this->crypters->remove_at(this->crypters, enumerator); + free(entry); + } + } + enumerator->destroy(enumerator); + this->mutex->unlock(this->mutex); +} + +/** + * Implementation of crypto_factory_t.add_signer. + */ +static void add_signer(private_crypto_factory_t *this, + integrity_algorithm_t algo, signer_constructor_t create) +{ + signer_entry_t *entry = malloc_thing(signer_entry_t); + + entry->algo = algo; + entry->create = create; + this->mutex->lock(this->mutex); + this->signers->insert_last(this->signers, entry); + this->mutex->unlock(this->mutex); +} + +/** + * Implementation of crypto_factory_t.remove_signer. + */ +static void remove_signer(private_crypto_factory_t *this, + signer_constructor_t create) +{ + signer_entry_t *entry; + enumerator_t *enumerator; + + this->mutex->lock(this->mutex); + enumerator = this->signers->create_enumerator(this->signers); + while (enumerator->enumerate(enumerator, &entry)) + { + if (entry->create == create) + { + this->signers->remove_at(this->signers, enumerator); + free(entry); + } + } + enumerator->destroy(enumerator); + this->mutex->unlock(this->mutex); +} + +/** + * Implementation of crypto_factory_t.add_hasher. + */ +static void add_hasher(private_crypto_factory_t *this, hash_algorithm_t algo, + hasher_constructor_t create) +{ + hasher_entry_t *entry = malloc_thing(hasher_entry_t); + + entry->algo = algo; + entry->create = create; + this->mutex->lock(this->mutex); + this->hashers->insert_last(this->hashers, entry); + this->mutex->unlock(this->mutex); +} + +/** + * Implementation of crypto_factory_t.remove_hasher. + */ +static void remove_hasher(private_crypto_factory_t *this, + hasher_constructor_t create) +{ + hasher_entry_t *entry; + enumerator_t *enumerator; + + this->mutex->lock(this->mutex); + enumerator = this->hashers->create_enumerator(this->hashers); + while (enumerator->enumerate(enumerator, &entry)) + { + if (entry->create == create) + { + this->hashers->remove_at(this->hashers, enumerator); + free(entry); + } + } + enumerator->destroy(enumerator); + this->mutex->unlock(this->mutex); +} + +/** + * Implementation of crypto_factory_t.add_prf. + */ +static void add_prf(private_crypto_factory_t *this, + pseudo_random_function_t algo, prf_constructor_t create) +{ + prf_entry_t *entry = malloc_thing(prf_entry_t); + + entry->algo = algo; + entry->create = create; + this->mutex->lock(this->mutex); + this->prfs->insert_last(this->prfs, entry); + this->mutex->unlock(this->mutex); +} + +/** + * Implementation of crypto_factory_t.remove_prf. + */ +static void remove_prf(private_crypto_factory_t *this, prf_constructor_t create) +{ + prf_entry_t *entry; + enumerator_t *enumerator; + + this->mutex->lock(this->mutex); + enumerator = this->prfs->create_enumerator(this->prfs); + while (enumerator->enumerate(enumerator, &entry)) + { + if (entry->create == create) + { + this->prfs->remove_at(this->prfs, enumerator); + free(entry); + } + } + enumerator->destroy(enumerator); + this->mutex->unlock(this->mutex); +} + +/** + * Implementation of crypto_factory_t.add_rng. + */ +static void add_rng(private_crypto_factory_t *this, rng_quality_t quality, + rng_constructor_t create) +{ + rng_entry_t *entry = malloc_thing(rng_entry_t); + + entry->quality = quality; + entry->create = create; + this->mutex->lock(this->mutex); + this->rngs->insert_last(this->rngs, entry); + this->mutex->unlock(this->mutex); +} + +/** + * Implementation of crypto_factory_t.remove_rng. + */ +static void remove_rng(private_crypto_factory_t *this, rng_constructor_t create) +{ + rng_entry_t *entry; + enumerator_t *enumerator; + + this->mutex->lock(this->mutex); + enumerator = this->rngs->create_enumerator(this->rngs); + while (enumerator->enumerate(enumerator, &entry)) + { + if (entry->create == create) + { + this->rngs->remove_at(this->rngs, enumerator); + free(entry); + } + } + enumerator->destroy(enumerator); + this->mutex->unlock(this->mutex); +} + +/** + * Implementation of crypto_factory_t.add_dh. + */ +static void add_dh(private_crypto_factory_t *this, diffie_hellman_group_t group, + dh_constructor_t create) +{ + dh_entry_t *entry = malloc_thing(dh_entry_t); + + entry->group = group; + entry->create = create; + this->mutex->lock(this->mutex); + this->dhs->insert_last(this->dhs, entry); + this->mutex->unlock(this->mutex); +} + +/** + * Implementation of crypto_factory_t.remove_dh. + */ +static void remove_dh(private_crypto_factory_t *this, dh_constructor_t create) +{ + dh_entry_t *entry; + enumerator_t *enumerator; + + this->mutex->lock(this->mutex); + enumerator = this->dhs->create_enumerator(this->dhs); + while (enumerator->enumerate(enumerator, &entry)) + { + if (entry->create == create) + { + this->dhs->remove_at(this->dhs, enumerator); + free(entry); + } + } + enumerator->destroy(enumerator); + this->mutex->unlock(this->mutex); +} + +/** + * Implementation of crypto_factory_t.destroy + */ +static void destroy(private_crypto_factory_t *this) +{ + this->crypters->destroy_function(this->crypters, free); + this->signers->destroy_function(this->signers, free); + this->hashers->destroy_function(this->hashers, free); + this->prfs->destroy_function(this->prfs, free); + this->rngs->destroy_function(this->rngs, free); + this->dhs->destroy_function(this->dhs, free); + this->mutex->destroy(this->mutex); + free(this); +} + +/* + * see header file + */ +crypto_factory_t *crypto_factory_create() +{ + private_crypto_factory_t *this = malloc_thing(private_crypto_factory_t); + + this->public.create_crypter = (crypter_t*(*)(crypto_factory_t*, encryption_algorithm_t, size_t))create_crypter; + this->public.create_signer = (signer_t*(*)(crypto_factory_t*, integrity_algorithm_t))create_signer; + this->public.create_hasher = (hasher_t*(*)(crypto_factory_t*, hash_algorithm_t))create_hasher; + this->public.create_prf = (prf_t*(*)(crypto_factory_t*, pseudo_random_function_t))create_prf; + this->public.create_rng = (rng_t*(*)(crypto_factory_t*, rng_quality_t quality))create_rng; + this->public.create_dh = (diffie_hellman_t*(*)(crypto_factory_t*, diffie_hellman_group_t group))create_dh; + this->public.add_crypter = (void(*)(crypto_factory_t*, encryption_algorithm_t algo, crypter_constructor_t create))add_crypter; + this->public.remove_crypter = (void(*)(crypto_factory_t*, crypter_constructor_t create))remove_crypter; + this->public.add_signer = (void(*)(crypto_factory_t*, integrity_algorithm_t algo, signer_constructor_t create))add_signer; + this->public.remove_signer = (void(*)(crypto_factory_t*, signer_constructor_t create))remove_signer; + this->public.add_hasher = (void(*)(crypto_factory_t*, hash_algorithm_t algo, hasher_constructor_t create))add_hasher; + this->public.remove_hasher = (void(*)(crypto_factory_t*, hasher_constructor_t create))remove_hasher; + this->public.add_prf = (void(*)(crypto_factory_t*, pseudo_random_function_t algo, prf_constructor_t create))add_prf; + this->public.remove_prf = (void(*)(crypto_factory_t*, prf_constructor_t create))remove_prf; + this->public.add_rng = (void(*)(crypto_factory_t*, rng_quality_t quality, rng_constructor_t create))add_rng; + this->public.remove_rng = (void(*)(crypto_factory_t*, rng_constructor_t create))remove_rng; + this->public.add_dh = (void(*)(crypto_factory_t*, diffie_hellman_group_t algo, dh_constructor_t create))add_dh; + this->public.remove_dh = (void(*)(crypto_factory_t*, dh_constructor_t create))remove_dh; + this->public.destroy = (void(*)(crypto_factory_t*))destroy; + + this->crypters = linked_list_create(); + this->signers = linked_list_create(); + this->hashers = linked_list_create(); + this->prfs = linked_list_create(); + this->rngs = linked_list_create(); + this->dhs = linked_list_create(); + this->mutex = mutex_create(MUTEX_RECURSIVE); + + return &this->public; +} + diff --git a/src/libstrongswan/crypto/crypto_factory.h b/src/libstrongswan/crypto/crypto_factory.h new file mode 100644 index 000000000..6bf070c31 --- /dev/null +++ b/src/libstrongswan/crypto/crypto_factory.h @@ -0,0 +1,235 @@ +/* + * 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 crypto_factory crypto_factory + * @{ @ingroup crypto + */ + +#ifndef CRYPTO_FACTORY_H_ +#define CRYPTO_FACTORY_H_ + +typedef struct crypto_factory_t crypto_factory_t; + +#include <library.h> +#include <crypto/crypters/crypter.h> +#include <crypto/signers/signer.h> +#include <crypto/hashers/hasher.h> +#include <crypto/prfs/prf.h> +#include <crypto/rngs/rng.h> +#include <crypto/diffie_hellman.h> + +/** + * Constructor function for crypters + */ +typedef crypter_t* (*crypter_constructor_t)(encryption_algorithm_t algo, + size_t key_size); +/** + * Constructor function for signers + */ +typedef signer_t* (*signer_constructor_t)(integrity_algorithm_t algo); + +/** + * Constructor function for hashers + */ +typedef hasher_t* (*hasher_constructor_t)(hash_algorithm_t algo); + +/** + * Constructor function for pseudo random functions + */ +typedef prf_t* (*prf_constructor_t)(pseudo_random_function_t algo); + +/** + * Constructor function for source of randomness + */ +typedef rng_t* (*rng_constructor_t)(rng_quality_t quality); + +/** + * Constructor function for diffie hellman + */ +typedef diffie_hellman_t* (*dh_constructor_t)(diffie_hellman_group_t group); + +/** + * Handles crypto modules and creates instances. + */ +struct crypto_factory_t { + + /** + * Create a crypter instance. + * + * @param algo encryption algorithm + * @param key_size length of the key in bytes + * @return crypter_t instance, NULL if not supported + */ + crypter_t* (*create_crypter)(crypto_factory_t *this, + encryption_algorithm_t algo, size_t key_size); + + /** + * Create a symmetric signer instance. + * + * @param algo MAC algorithm to use + * @return signer_t instance, NULL if not supported + */ + signer_t* (*create_signer)(crypto_factory_t *this, + integrity_algorithm_t algo); + + /** + * Create a hasher instance. + * + * @param algo hash algorithm + * @return hasher_t instance, NULL if not supported + */ + hasher_t* (*create_hasher)(crypto_factory_t *this, hash_algorithm_t algo); + + /** + * Create a pseudo random function instance. + * + * @param algo PRF algorithm to use + * @return prf_t instance, NULL if not supported + */ + prf_t* (*create_prf)(crypto_factory_t *this, pseudo_random_function_t algo); + + /** + * Create a source of randomness. + * + * @param quality required randomness quality + * @return rng_t instance, NULL if no RNG with such a quality + */ + rng_t* (*create_rng)(crypto_factory_t *this, rng_quality_t quality); + + /** + * Create a diffie hellman instance. + * + * @param group diffie hellman group + * @return diffie_hellman_t instance, NULL if not supported + */ + diffie_hellman_t* (*create_dh)(crypto_factory_t *this, + diffie_hellman_group_t group); + + /** + * Register a crypter constructor. + * + * @param algo algorithm to constructor + * @param create constructor function for that algorithm + * @return + */ + void (*add_crypter)(crypto_factory_t *this, encryption_algorithm_t algo, + crypter_constructor_t create); + + /** + * Unregister a crypter constructor. + * + * @param create constructor function to unregister + */ + void (*remove_crypter)(crypto_factory_t *this, crypter_constructor_t create); + + /** + * Register a signer constructor. + * + * @param algo algorithm to constructor + * @param create constructor function for that algorithm + * @return + */ + void (*add_signer)(crypto_factory_t *this, integrity_algorithm_t algo, + signer_constructor_t create); + + /** + * Unregister a signer constructor. + * + * @param create constructor function to unregister + */ + void (*remove_signer)(crypto_factory_t *this, signer_constructor_t create); + + /** + * Register a hasher constructor. + * + * The first added hasher is the preferred hasher returned on + * create_hasher(HASH_PREFERRED). + * + * @param algo algorithm to constructor + * @param create constructor function for that algorithm + * @return + */ + void (*add_hasher)(crypto_factory_t *this, hash_algorithm_t algo, + hasher_constructor_t create); + + /** + * Unregister a hasher constructor. + * + * @param create constructor function to unregister + */ + void (*remove_hasher)(crypto_factory_t *this, hasher_constructor_t create); + + /** + * Register a prf constructor. + * + * @param algo algorithm to constructor + * @param create constructor function for that algorithm + * @return + */ + void (*add_prf)(crypto_factory_t *this, pseudo_random_function_t algo, + prf_constructor_t create); + + /** + * Unregister a prf constructor. + * + * @param create constructor function to unregister + */ + void (*remove_prf)(crypto_factory_t *this, prf_constructor_t create); + + /** + * Register a source of randomness. + * + * @param quality quality of randomness this RNG serves + * @param create constructor function for such a quality + */ + void (*add_rng)(crypto_factory_t *this, rng_quality_t quality, rng_constructor_t create); + + /** + * Unregister a source of randomness. + * + * @param create constructor function to unregister + */ + void (*remove_rng)(crypto_factory_t *this, rng_constructor_t create); + + /** + * Register a diffie hellman constructor. + * + * @param group dh group to constructor + * @param create constructor function for that algorithm + * @return + */ + void (*add_dh)(crypto_factory_t *this, diffie_hellman_group_t group, + dh_constructor_t create); + + /** + * Unregister a diffie hellman constructor. + * + * @param create constructor function to unregister + */ + void (*remove_dh)(crypto_factory_t *this, dh_constructor_t create); + + /** + * Destroy a crypto_factory instance. + */ + void (*destroy)(crypto_factory_t *this); +}; + +/** + * Create a crypto_factory instance. + */ +crypto_factory_t *crypto_factory_create(); + +#endif /* CRYPTO_FACTORY_H_ @}*/ diff --git a/src/libstrongswan/crypto/diffie_hellman.c b/src/libstrongswan/crypto/diffie_hellman.c index 605892e87..02d2cb52a 100644 --- a/src/libstrongswan/crypto/diffie_hellman.c +++ b/src/libstrongswan/crypto/diffie_hellman.c @@ -1,14 +1,5 @@ -/** - * @file diffie_hellman.c - * - * @brief Implementation of diffie_hellman_t. - * - */ - /* - * Copyright (C) 1998-2002 D. Hugh Redelmeier. - * Copyright (C) 1999, 2000, 2001 Henry Spencer. - * Copyright (C) 2005-2007 Martin Willi + * Copyright (C) 2005-2008 Martin Willi * Copyright (C) 2005 Jan Hutter * Hochschule fuer Technik Rapperswil * @@ -21,569 +12,29 @@ * 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: diffie_hellman.c 4023 2008-05-29 06:55:03Z andreas $ */ -#include <gmp.h> - #include "diffie_hellman.h" -#include <utils/randomizer.h> -#include <debug.h> - ENUM_BEGIN(diffie_hellman_group_names, MODP_NONE, MODP_1024_BIT, "MODP_NONE", "MODP_768_BIT", "MODP_1024_BIT"); ENUM_NEXT(diffie_hellman_group_names, MODP_1536_BIT, MODP_1536_BIT, MODP_1024_BIT, "MODP_1536_BIT"); -ENUM_NEXT(diffie_hellman_group_names, MODP_2048_BIT, MODP_8192_BIT, MODP_1536_BIT, +ENUM_NEXT(diffie_hellman_group_names, MODP_2048_BIT, ECP_521_BIT, MODP_1536_BIT, "MODP_2048_BIT", "MODP_3072_BIT", "MODP_4096_BIT", "MODP_6144_BIT", - "MODP_8192_BIT"); -ENUM_END(diffie_hellman_group_names, MODP_8192_BIT); - - -/** - * 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_diffie_hellman_t private_diffie_hellman_t; - -/** - * Private data of an diffie_hellman_t object. - * - */ -struct private_diffie_hellman_t { - /** - * Public diffie_hellman_t interface. - */ - 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 diffie_hellman_t.set_other_public_value. - */ -static void set_other_public_value(private_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 diffie_hellman_t.get_other_public_value. - */ -static status_t get_other_public_value(private_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 diffie_hellman_t.get_my_public_value. - */ -static void get_my_public_value(private_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 diffie_hellman_t.get_shared_secret. - */ -static status_t get_shared_secret(private_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 diffie_hellman_t.get_dh_group. - */ -static diffie_hellman_group_t get_dh_group(private_diffie_hellman_t *this) -{ - return this->group; -} - -/** - * Lookup the modulus in modulo table - */ -static status_t set_modulus(private_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 diffie_hellman_t.destroy. - */ -static void destroy(private_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. - */ -diffie_hellman_t *diffie_hellman_create(diffie_hellman_group_t group) -{ - private_diffie_hellman_t *this = malloc_thing(private_diffie_hellman_t); - randomizer_t *randomizer; - chunk_t random; - status_t status; - - /* public functions */ - this->public.get_shared_secret = (status_t (*)(diffie_hellman_t *, chunk_t *)) get_shared_secret; - this->public.set_other_public_value = (void (*)(diffie_hellman_t *, chunk_t )) set_other_public_value; - this->public.get_other_public_value = (status_t (*)(diffie_hellman_t *, chunk_t *)) get_other_public_value; - this->public.get_my_public_value = (void (*)(diffie_hellman_t *, chunk_t *)) get_my_public_value; - this->public.get_dh_group = (diffie_hellman_group_t (*)(diffie_hellman_t *)) get_dh_group; - this->public.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; - } - randomizer = randomizer_create(); - status = randomizer->allocate_pseudo_random_bytes( - randomizer, this->p_len, &random); - randomizer->destroy(randomizer); - if (status != SUCCESS) - { - destroy(this); - return NULL; - } - 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; -} + "MODP_8192_BIT", + "ECP_256_BIT", + "ECP_384_BIT", + "ECP_521_BIT"); +ENUM_NEXT(diffie_hellman_group_names, ECP_192_BIT, ECP_224_BIT, ECP_521_BIT, + "ECP_192_BIT", + "ECP_224_BIT"); +ENUM_END(diffie_hellman_group_names, ECP_224_BIT); diff --git a/src/libstrongswan/crypto/diffie_hellman.h b/src/libstrongswan/crypto/diffie_hellman.h index 8cd06d60e..c66ae56c3 100644 --- a/src/libstrongswan/crypto/diffie_hellman.h +++ b/src/libstrongswan/crypto/diffie_hellman.h @@ -1,10 +1,3 @@ -/** - * @file diffie_hellman.h - * - * @brief Interface of diffie_hellman_t. - * - */ - /* * Copyright (C) 2005-2007 Martin Willi * Copyright (C) 2005 Jan Hutter @@ -19,6 +12,13 @@ * 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: diffie_hellman.h 4023 2008-05-29 06:55:03Z andreas $ + */ + +/** + * @defgroup diffie_hellman diffie_hellman + * @{ @ingroup crypto */ #ifndef DIFFIE_HELLMAN_H_ @@ -30,24 +30,28 @@ typedef struct diffie_hellman_t diffie_hellman_t; #include <library.h> /** - * @brief Diffie-Hellman group. + * Diffie-Hellman group. * * The modulus (or group) to use for a Diffie-Hellman calculation. - * * See IKEv2 RFC 3.3.2 and RFC 3526. - * - * @ingroup crypto + * + * ECP groups are defined in RFC 4753 and RFC 5114. */ enum diffie_hellman_group_t { - MODP_NONE = 0, - MODP_768_BIT = 1, - MODP_1024_BIT = 2, - MODP_1536_BIT = 5, + MODP_NONE = 0, + MODP_768_BIT = 1, + MODP_1024_BIT = 2, + MODP_1536_BIT = 5, MODP_2048_BIT = 14, MODP_3072_BIT = 15, MODP_4096_BIT = 16, MODP_6144_BIT = 17, - MODP_8192_BIT = 18 + MODP_8192_BIT = 18, + ECP_256_BIT = 19, + ECP_384_BIT = 20, + ECP_521_BIT = 21, + ECP_192_BIT = 25, + ECP_224_BIT = 26, }; /** @@ -56,89 +60,60 @@ enum diffie_hellman_group_t { extern enum_name_t *diffie_hellman_group_names; /** - * @brief Implementation of the Diffie-Hellman algorithm, as in RFC2631. - * - * @b Constructors: - * - diffie_hellman_create() - * - * @ingroup crypto + * Implementation of the Diffie-Hellman algorithm, as in RFC2631. */ struct diffie_hellman_t { /** - * @brief Returns the shared secret of this diffie hellman exchange. + * Returns the shared secret of this diffie hellman exchange. * * Space for returned secret is allocated and must be * freed by the caller. * - * @param this calling object * @param secret shared secret will be written into this chunk - * @return - * - SUCCESS - * - FAILED if not both DH values are set + * @return SUCCESS, FAILED if not both DH values are set */ status_t (*get_shared_secret) (diffie_hellman_t *this, chunk_t *secret); /** - * @brief Sets the public value of partner. + * Sets the public value of partner. * * Chunk gets cloned and can be destroyed afterwards. * - * @param this calling object * @param value public value of partner */ void (*set_other_public_value) (diffie_hellman_t *this, chunk_t value); /** - * @brief Gets the public value of partner. + * Gets the public value of partner. * * Space for returned chunk is allocated and must be freed by the caller. * - * @param this calling object * @param value public value of partner is stored at this location - * @return - * - SUCCESS - * - FAILED if other public value not set + * @return SUCCESS, FAILED if other public value not set */ status_t (*get_other_public_value) (diffie_hellman_t *this, chunk_t *value); /** - * @brief Gets the own public value to transmit. + * Gets the own public value to transmit. * * Space for returned chunk is allocated and must be freed by the caller. * - * @param this calling object * @param value public value of caller is stored at this location */ void (*get_my_public_value) (diffie_hellman_t *this, chunk_t *value); /** - * @brief Get the DH group used. + * Get the DH group used. * - * @param this calling object * @return DH group set in construction */ diffie_hellman_group_t (*get_dh_group) (diffie_hellman_t *this); /** - * @brief Destroys an diffie_hellman_t object. - * - * @param this diffie_hellman_t object to destroy + * Destroys an diffie_hellman_t object. */ void (*destroy) (diffie_hellman_t *this); }; -/** - * @brief Creates a new diffie_hellman_t object. - * - * @param group Diffie Hellman group number to use - * @return - * - diffie_hellman_t object - * - NULL if dh group not supported - * - * @ingroup crypto - */ -diffie_hellman_t *diffie_hellman_create(diffie_hellman_group_t group); - -#endif /*DIFFIE_HELLMAN_H_*/ - +#endif /*DIFFIE_HELLMAN_H_ @} */ diff --git a/src/libstrongswan/crypto/hashers/hasher.c b/src/libstrongswan/crypto/hashers/hasher.c index 9fa778aa6..6c29d1d5d 100644 --- a/src/libstrongswan/crypto/hashers/hasher.c +++ b/src/libstrongswan/crypto/hashers/hasher.c @@ -1,10 +1,3 @@ -/** - * @file hasher.c - * - * @brief Generic constructor for hasher_t. - * - */ - /* * Copyright (C) 2005 Jan Hutter * Copyright (C) 2005-2006 Martin Willi @@ -21,20 +14,16 @@ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * - * RCSID $Id: hasher.c 3423 2008-01-22 10:32:37Z andreas $ + * $Id: hasher.c 3619 2008-03-19 14:02:52Z martin $ */ - #include "hasher.h" #include <asn1/oid.h> -#include <crypto/hashers/sha1_hasher.h> -#include <crypto/hashers/sha2_hasher.h> -#include <crypto/hashers/md5_hasher.h> - ENUM(hash_algorithm_names, HASH_UNKNOWN, HASH_SHA512, "HASH_UNKNOWN", + "HASH_PREFERRED", "HASH_MD2", "HASH_MD5", "HASH_SHA1", @@ -46,66 +35,31 @@ ENUM(hash_algorithm_names, HASH_UNKNOWN, HASH_SHA512, /* * Described in header. */ -hasher_t *hasher_create(hash_algorithm_t hash_algorithm) -{ - switch (hash_algorithm) - { - case HASH_SHA1: - { - return (hasher_t*)sha1_hasher_create(); - } - case HASH_SHA256: - case HASH_SHA384: - case HASH_SHA512: - { - return (hasher_t*)sha2_hasher_create(hash_algorithm); - } - case HASH_MD5: - { - return (hasher_t*)md5_hasher_create(); - } - default: - return NULL; - } -} - -/* - * Described in header. - */ hash_algorithm_t hasher_algorithm_from_oid(int oid) { - hash_algorithm_t algorithm; - switch (oid) { case OID_MD2: case OID_MD2_WITH_RSA: - algorithm = HASH_MD2; - break; + return HASH_MD2; case OID_MD5: case OID_MD5_WITH_RSA: - algorithm = HASH_MD5; - break; + return HASH_MD5; case OID_SHA1: case OID_SHA1_WITH_RSA: - algorithm = HASH_SHA1; - break; + return HASH_SHA1; case OID_SHA256: case OID_SHA256_WITH_RSA: - algorithm = HASH_SHA256; - break; + return HASH_SHA256; case OID_SHA384: case OID_SHA384_WITH_RSA: - algorithm = HASH_SHA384; - break; + return HASH_SHA384; case OID_SHA512: case OID_SHA512_WITH_RSA: - algorithm = HASH_SHA512; - break; + return HASH_SHA512; default: - algorithm = HASH_UNKNOWN; + return HASH_UNKNOWN; } - return algorithm; } /* diff --git a/src/libstrongswan/crypto/hashers/hasher.h b/src/libstrongswan/crypto/hashers/hasher.h index e73de7f01..e19b0318b 100644 --- a/src/libstrongswan/crypto/hashers/hasher.h +++ b/src/libstrongswan/crypto/hashers/hasher.h @@ -1,10 +1,3 @@ -/** - * @file hasher.h - * - * @brief Interface hasher_t. - * - */ - /* * Copyright (C) 2005 Jan Hutter * Copyright (C) 2005-2006 Martin Willi @@ -21,7 +14,12 @@ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * - * RCSID $Id: hasher.h 3423 2008-01-22 10:32:37Z andreas $ + * $Id: hasher.h 3619 2008-03-19 14:02:52Z martin $ + */ + +/** + * @defgroup traffic_selector traffic_selector + * @{ @ingroup config */ #ifndef HASHER_H_ @@ -33,30 +31,19 @@ typedef struct hasher_t hasher_t; #include <library.h> /** - * @brief Algorithms to use for hashing. - * - * Currently only the following algorithms are implemented: - * - HASH_MD5 - * - HASH_SHA1 - * - HASH_SHA256 - * - HASH_SHA384 - * - HASH_SHA512 - * - * @ingroup hashers + * Algorithms to use for hashing. */ enum hash_algorithm_t { - HASH_UNKNOWN = 0, - HASH_MD2 = 1, - /** Implemented in class md5_hasher_t */ - HASH_MD5 = 2, - /** Implemented in class sha1_hasher_t */ - HASH_SHA1 = 3, - /** Implemented in class sha2_hasher_t */ - HASH_SHA256 = 4, - /** Implemented in class sha2_hasher_t */ - HASH_SHA384 = 5, - /** Implemented in class sha2_hasher_t */ - HASH_SHA512 = 6, + /** not specified hash function */ + HASH_UNKNOWN = 0, + /** preferred hash function, general purpose */ + HASH_PREFERRED = 1, + HASH_MD2 = 2, + HASH_MD5 = 3, + HASH_SHA1 = 4, + HASH_SHA256 = 5, + HASH_SHA384 = 6, + HASH_SHA512 = 7, }; #define HASH_SIZE_MD2 16 @@ -65,7 +52,6 @@ enum hash_algorithm_t { #define HASH_SIZE_SHA256 32 #define HASH_SIZE_SHA384 48 #define HASH_SIZE_SHA512 64 -#define HASH_SIZE_MAX 64 /** * enum names for hash_algorithm_t. @@ -73,16 +59,11 @@ enum hash_algorithm_t { extern enum_name_t *hash_algorithm_names; /** - * @brief Generic interface for all hash functions. - * - * @b Constructors: - * - hasher_create() - * - * @ingroup hashers + * Generic interface for all hash functions. */ struct hasher_t { /** - * @brief Hash data and write it in the buffer. + * Hash data and write it in the buffer. * * If the parameter hash is NULL, no result is written back * and more data can be appended to already hashed data. @@ -91,108 +72,63 @@ struct hasher_t { * The hash output parameter must hold at least * hash_t.get_block_size() bytes. * - * @param this calling object - * @param data data to hash - * @param[out] hash pointer where the hash will be written + * @param data data to hash + * @param hash pointer where the hash will be written */ void (*get_hash) (hasher_t *this, chunk_t data, u_int8_t *hash); /** - * @brief Hash data and allocate space for the hash. + * Hash data and allocate space for the hash. * * If the parameter hash is NULL, no result is written back * and more data can be appended to already hashed data. * If not, the result is written back and the hasher is reset. * - * @param this calling object - * @param data chunk with data to hash - * @param[out] hash chunk which will hold allocated hash + * @param data chunk with data to hash + * @param hash chunk which will hold allocated hash */ void (*allocate_hash) (hasher_t *this, chunk_t data, chunk_t *hash); /** - * @brief Get the size of the resulting hash. + * Get the size of the resulting hash. * - * @param this calling object - * @return hash size in bytes + * @return hash size in bytes */ size_t (*get_hash_size) (hasher_t *this); /** - * @brief Resets the hashers state. - * - * @param this calling object + * Resets the hashers state. */ void (*reset) (hasher_t *this); /** - * @brief Get the state of the hasher. - * - * A hasher stores internal state information. This state may be - * manipulated to include a "seed" into the hashing operation. It used by - * some exotic protocols (such as AKA). - * The data pointed by chunk may be manipulated, but not replaced nor freed. - * This is more a hack than a feature. The hasher's state may be byte - * order dependant; use with care. - * - * @param this calling object - */ - chunk_t (*get_state) (hasher_t *this); - - /** - * @brief Destroys a hasher object. - * - * @param this calling object + * Destroys a hasher object. */ void (*destroy) (hasher_t *this); }; /** - * @brief Generic interface to create a hasher_t. + * Conversion of ASN.1 OID to hash algorithm. * - * @param hash_algorithm Algorithm to use for hashing - * @return - * - hasher_t object - * - NULL if algorithm not supported - * - * @ingroup hashers - */ -hasher_t *hasher_create(hash_algorithm_t hash_algorithm); - -/** - * @brief Conversion of ASN.1 OID to hash algorithm. - * - * @param oid ASN.1 OID - * @return - * - hash algorithm - * - HASH_UNKNOWN if OID unsuported - * - * @ingroup hashers + * @param oid ASN.1 OID + * @return hash algorithm, HASH_UNKNOWN if OID unsuported */ hash_algorithm_t hasher_algorithm_from_oid(int oid); /** - * @brief Conversion of hash algorithm into ASN.1 OID. + * Conversion of hash algorithm into ASN.1 OID. * - * @param alg hash algorithm - * @return - * - ASN.1 hash OID if known hash algorithm - * - OID_UNKNOW - * - * @ingroup hashers + * @param alg hash algorithm + * @return ASN.1 OID, or OID_UNKNOW */ int hasher_algorithm_to_oid(hash_algorithm_t alg); /** - * @brief Conversion of hash signature algorithm into ASN.1 OID. - * - * @param alg hash algorithm - * @return - * - ASN.1 signature OID if known hash algorithm - * - OID_UNKNOW + * Conversion of hash signature algorithm into ASN.1 OID. * - * @ingroup hashers + * @param alg hash algorithm + * @return ASN.1 OID if, or OID_UNKNOW */ int hasher_signature_algorithm_to_oid(hash_algorithm_t alg); -#endif /* HASHER_H_ */ +#endif /* HASHER_H_ @} */ diff --git a/src/libstrongswan/crypto/ocsp.c b/src/libstrongswan/crypto/ocsp.c deleted file mode 100644 index 4bbec31de..000000000 --- a/src/libstrongswan/crypto/ocsp.c +++ /dev/null @@ -1,934 +0,0 @@ -/** - * @file ocsp.c - * - * @brief Implementation of ocsp_t. - * - */ - -/* Support of the Online Certificate Status Protocol (OCSP) - * - * Copyright (C) 2003 Christoph Gysin, Simon Zwahlen - * Copyright (C) 2007 Andreas Steffen - * - * Hochschule für Technik Rapperswil - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * for more details. - * - * RCSID $Id$ - */ - -#include <unistd.h> -#include <stdlib.h> -#include <stdio.h> -#include <string.h> -#include <time.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <fcntl.h> - -#include <asn1/oid.h> -#include <asn1/asn1.h> -#include <utils/identification.h> -#include <utils/randomizer.h> -#include <utils/fetcher.h> -#include <debug.h> - -#include "hashers/hasher.h" -#include "rsa/rsa_public_key.h" -#include "certinfo.h" -#include "x509.h" -#include "ocsp.h" - -#define NONCE_LENGTH 16 - -typedef struct private_ocsp_t private_ocsp_t; - -/** - * Private data of a ocsp_t object. - */ -struct private_ocsp_t { - /** - * Public interface for this ocsp object. - */ - ocsp_t public; - - /** - * CA certificate. - */ - x509_t *cacert; - - /** - * Requestor certificate - */ - x509_t *requestor_cert; - - /** - * Linked list of ocsp uris - */ - linked_list_t *uris; - - /** - * Linked list of certinfos to be requested - */ - linked_list_t *certinfos; - - /** - * Nonce required for ocsp request and response - */ - chunk_t nonce; - - /** - * SHA-1 hash over issuer distinguished name - */ - chunk_t authNameID; - - /** - * SHA-1 hash over issuer public key - */ - chunk_t authKeyID; -}; - -ENUM(response_status_names, STATUS_SUCCESSFUL, STATUS_UNAUTHORIZED, - "successful", - "malformed request", - "internal error", - "try later", - "signature required", - "unauthorized" -); - -/* response container */ -typedef struct response_t response_t; - -struct response_t { - chunk_t chunk; - chunk_t tbs; - identification_t *responder_id_name; - chunk_t responder_id_key; - time_t produced_at; - chunk_t responses; - chunk_t nonce; - int algorithm; - chunk_t signature; - x509_t *responder_cert; - - /** - * @brief Destroys the response_t object - * - * @param this response_t to destroy - */ - void (*destroy) (response_t *this); -}; - -/** - * Implements response_t.destroy. - */ -static void response_destroy(response_t *this) -{ - DESTROY_IF(this->responder_id_name); - DESTROY_IF(this->responder_cert); - free(this->chunk.ptr); - free(this); -} - -/** - * Creates a response_t object - */ -static response_t* response_create_from_chunk(chunk_t chunk) -{ - response_t *this = malloc_thing(response_t); - - this->chunk = chunk; - this->tbs = chunk_empty; - this->responder_id_name = NULL; - this->responder_id_key = chunk_empty; - this->produced_at = UNDEFINED_TIME; - this->responses = chunk_empty; - this->nonce = chunk_empty; - this->algorithm = OID_UNKNOWN; - this->signature = chunk_empty; - this->responder_cert = NULL; - - this->destroy = (void (*) (response_t*))response_destroy; - - return this; -} - -/* 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); - -/* asn.1 definitions for parsing */ - -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 */ -}; - -#define OCSP_RESPONSE_STATUS 1 -#define OCSP_RESPONSE_TYPE 4 -#define OCSP_RESPONSE 5 -#define OCSP_RESPONSE_ROOF 7 - -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 */ -}; - -#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 -#define BASIC_RESPONSE_ROOF 27 - -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 */ -}; - -#define RESPONSES_SINGLE_RESPONSE 1 -#define RESPONSES_ROOF 3 - -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 */ -}; - -#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 -#define SINGLE_RESPONSE_ROOF 28 - -/** - * build requestorName (into TBSRequest) - */ -static chunk_t build_requestor_name(private_ocsp_t *this) -{ - identification_t *requestor_name = this->requestor_cert->get_subject(this->requestor_cert); - - return asn1_wrap(ASN1_CONTEXT_C_1, "m", - asn1_simple_object(ASN1_CONTEXT_C_4, - requestor_name->get_encoding(requestor_name))); -} - -/** - * build request (into requestList) - * no singleRequestExtensions used - */ -static chunk_t build_request(private_ocsp_t *this, certinfo_t *certinfo) -{ - chunk_t serialNumber = certinfo->get_serialNumber(certinfo); - - chunk_t reqCert = asn1_wrap(ASN1_SEQUENCE, "cmmm", - asn1_algorithmIdentifier(OID_SHA1), - asn1_simple_object(ASN1_OCTET_STRING, this->authNameID), - asn1_simple_object(ASN1_OCTET_STRING, this->authKeyID), - asn1_simple_object(ASN1_INTEGER, serialNumber)); - - return asn1_wrap(ASN1_SEQUENCE, "m", reqCert); -} - -/** - * build requestList (into TBSRequest) - */ -static chunk_t build_request_list(private_ocsp_t *this) -{ - chunk_t requestList; - size_t datalen = 0; - linked_list_t *request_list = linked_list_create(); - - { - iterator_t *iterator = this->certinfos->create_iterator(this->certinfos, TRUE); - certinfo_t *certinfo; - - while (iterator->iterate(iterator, (void**)&certinfo)) - { - chunk_t *request = malloc_thing(chunk_t); - - *request = build_request(this, certinfo); - request_list->insert_last(request_list, (void*)request); - datalen += request->len; - } - iterator->destroy(iterator); - } - { - iterator_t *iterator = request_list->create_iterator(request_list, TRUE); - chunk_t *request; - - u_char *pos = build_asn1_object(&requestList, ASN1_SEQUENCE, datalen); - - while (iterator->iterate(iterator, (void**)&request)) - { - memcpy(pos, request->ptr, request->len); - pos += request->len; - free(request->ptr); - free(request); - } - iterator->destroy(iterator); - request_list->destroy(request_list); - } - return requestList; -} - -/** - * build nonce extension (into requestExtensions) - */ -static chunk_t build_nonce_extension(private_ocsp_t *this) -{ - randomizer_t *randomizer = randomizer_create(); - - /* generate a random nonce */ - randomizer->allocate_pseudo_random_bytes(randomizer, NONCE_LENGTH, &this->nonce); - randomizer->destroy(randomizer); - - return asn1_wrap(ASN1_SEQUENCE, "cm", - ASN1_nonce_oid, - asn1_simple_object(ASN1_OCTET_STRING, this->nonce)); -} - -/** - * build requestExtensions (into TBSRequest) - */ -static chunk_t build_request_ext(private_ocsp_t *this) -{ - return asn1_wrap(ASN1_CONTEXT_C_2, "m", - asn1_wrap(ASN1_SEQUENCE, "mm", - build_nonce_extension(this), - asn1_wrap(ASN1_SEQUENCE, "cc", - ASN1_response_oid, - ASN1_response_content - ) - ) - ); -} - -/** - * build TBSRequest (into OCSPRequest) - */ -static chunk_t build_tbs_request(private_ocsp_t *this, bool has_requestor_cert) -{ - /* version is skipped since the default is ok */ - return asn1_wrap(ASN1_SEQUENCE, "mmm", - (has_requestor_cert)? build_requestor_name(this): chunk_empty, - build_request_list(this), - build_request_ext(this)); -} - -/** - * build signature into ocsp request - * gets built only if a request cert with a corresponding private key is found - */ -static chunk_t build_signature(private_ocsp_t *this, chunk_t tbsRequest) -{ - /* TODO */ - return chunk_empty; -} - -/** - * assembles an ocsp request and sets the nonce field in private_ocsp_t to the sent nonce - */ -static chunk_t ocsp_build_request(private_ocsp_t *this) -{ - bool has_requestor_cert; - chunk_t keyid = this->cacert->get_keyid(this->cacert); - chunk_t tbsRequest, signature; - - DBG2("assembling ocsp request"); - DBG2("issuer: '%D'", this->cacert->get_subject(this->cacert)); - DBG2("keyid: %#B", &keyid); - - /* looks for requestor cert and matching private key */ - has_requestor_cert = FALSE; - - /* TODO has_requestor_cert = get_ocsp_requestor_cert(location); */ - - /* build content */ - tbsRequest = build_tbs_request(this, has_requestor_cert); - - /* sign tbsReuqest */ - signature = (has_requestor_cert)? build_signature(this, tbsRequest): chunk_empty; - - return asn1_wrap(ASN1_SEQUENCE, "mm", - tbsRequest, - signature); - - return signature; -} - -/** - * parse a basic OCSP response - */ -static bool ocsp_parse_basic_response(chunk_t blob, int level0, response_t *res) -{ - u_int level, version; - asn1_ctx_t ctx; - bool critical; - chunk_t object; - int objectID = 0; - int extn_oid = OID_UNKNOWN; - - asn1_init(&ctx, blob, level0, FALSE, FALSE); - - while (objectID < BASIC_RESPONSE_ROOF) - { - if (!extract_object(basicResponseObjects, &objectID, &object, &level, &ctx)) - { - return FALSE; - } - - switch (objectID) - { - case BASIC_RESPONSE_TBS_DATA: - res->tbs = object; - break; - case BASIC_RESPONSE_VERSION: - version = (object.len)? (1 + (u_int)*object.ptr) : 1; - if (version != OCSP_BASIC_RESPONSE_VERSION) - { - DBG1("wrong ocsp basic response version (version= %i)", version); - return FALSE; - } - break; - case BASIC_RESPONSE_ID_BY_NAME: - res->responder_id_name = identification_create_from_encoding(ID_DER_ASN1_DN, object); - DBG2(" '%D'", res->responder_id_name); - break; - case BASIC_RESPONSE_ID_BY_KEY: - res->responder_id_key = object; - break; - case BASIC_RESPONSE_PRODUCED_AT: - res->produced_at = asn1totime(&object, ASN1_GENERALIZEDTIME); - break; - case BASIC_RESPONSE_RESPONSES: - res->responses = object; - break; - case BASIC_RESPONSE_EXT_ID: - extn_oid = 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) - res->nonce = object; - break; - case BASIC_RESPONSE_ALGORITHM: - res->algorithm = parse_algorithmIdentifier(object, level+1, NULL); - break; - case BASIC_RESPONSE_SIGNATURE: - res->signature = object; - break; - case BASIC_RESPONSE_CERTIFICATE: - { - chunk_t blob = chunk_clone(object); - - res->responder_cert = x509_create_from_chunk(blob, level+1); - } - break; - } - objectID++; - } - return TRUE; -} - -/** - * parse an ocsp response and return the result as a response_t struct - */ -static response_status ocsp_parse_response(response_t *res) -{ - asn1_ctx_t ctx; - chunk_t object; - u_int level; - int objectID = 0; - int ocspResponseType = OID_UNKNOWN; - response_status rStatus = STATUS_INTERNALERROR; - - asn1_init(&ctx, res->chunk, 0, FALSE, FALSE); - - while (objectID < OCSP_RESPONSE_ROOF) - { - if (!extract_object(ocspResponseObjects, &objectID, &object, &level, &ctx)) - { - return STATUS_INTERNALERROR; - } - - switch (objectID) - { - case OCSP_RESPONSE_STATUS: - rStatus = (response_status) *object.ptr; - DBG2(" '%N'", response_status_names, rStatus); - - switch (rStatus) - { - case STATUS_SUCCESSFUL: - break; - case STATUS_MALFORMEDREQUEST: - case STATUS_INTERNALERROR: - case STATUS_TRYLATER: - case STATUS_SIGREQUIRED: - case STATUS_UNAUTHORIZED: - DBG1("unsuccessful ocsp response: server said '%N'", - response_status_names, rStatus); - return rStatus; - default: - return STATUS_INTERNALERROR; - } - break; - case OCSP_RESPONSE_TYPE: - ocspResponseType = known_oid(object); - break; - case OCSP_RESPONSE: - { - switch (ocspResponseType) - { - case OID_BASIC: - if (!ocsp_parse_basic_response(object, level+1, res)) - { - return STATUS_INTERNALERROR; - } - break; - default: - DBG1("ocsp response is not of type BASIC"); - DBG1("ocsp response OID: %#B", &object); - return STATUS_INTERNALERROR; - } - } - break; - } - objectID++; - } - return rStatus; -} - -/** - * Check if the OCSP response has a valid signature - */ -static bool ocsp_valid_response(response_t *res, x509_t *ocsp_cert) -{ - rsa_public_key_t *public_key; - time_t until = UNDEFINED_TIME; - err_t ugh; - hash_algorithm_t algorithm = hasher_algorithm_from_oid(res->algorithm); - - if (algorithm == HASH_UNKNOWN) - { - DBG1("unknown signature algorithm"); - return FALSE; - } - - DBG2("verifying ocsp response signature:"); - DBG2("signer: '%D'", ocsp_cert->get_subject(ocsp_cert)); - DBG2("issuer: '%D'", ocsp_cert->get_issuer(ocsp_cert)); - - ugh = ocsp_cert->is_valid(ocsp_cert, &until); - if (ugh != NULL) - { - DBG1("ocsp signer certificate %s", ugh); - return FALSE; - } - public_key = ocsp_cert->get_public_key(ocsp_cert); - - return public_key->verify_emsa_pkcs1_signature(public_key, algorithm, res->tbs, res->signature) == SUCCESS; -} - -/** - * parse a single OCSP response - */ -static bool ocsp_parse_single_response(private_ocsp_t *this, chunk_t blob, int level0) -{ - u_int level, extn_oid; - asn1_ctx_t ctx; - bool critical; - chunk_t object; - int objectID = 0; - - certinfo_t *certinfo = NULL; - - asn1_init(&ctx, blob, level0, FALSE, FALSE); - - while (objectID < SINGLE_RESPONSE_ROOF) - { - if (!extract_object(singleResponseObjects, &objectID, &object, &level, &ctx)) - { - return FALSE; - } - - switch (objectID) - { - case SINGLE_RESPONSE_ALGORITHM: - if (parse_algorithmIdentifier(object, level+1, NULL) != OID_SHA1) - { - DBG1("only sha-1 hash supported in ocsp single response"); - return FALSE; - } - break; - case SINGLE_RESPONSE_ISSUER_NAME_HASH: - if (!chunk_equals(object, this->authNameID)) - { - DBG1("ocsp single response has wrong issuer name hash"); - return FALSE; - } - break; - case SINGLE_RESPONSE_ISSUER_KEY_HASH: - if (!chunk_equals(object, this->authKeyID)) - { - DBG1("ocsp single response has wrong issuer key hash"); - return FALSE; - } - break; - case SINGLE_RESPONSE_SERIAL_NUMBER: - { - iterator_t *iterator = this->certinfos->create_iterator(this->certinfos, TRUE); - certinfo_t *current_certinfo; - - while (iterator->iterate(iterator, (void**)¤t_certinfo)) - { - if (chunk_equals(object, current_certinfo->get_serialNumber(current_certinfo))) - { - certinfo = current_certinfo; - } - } - iterator->destroy(iterator); - if (certinfo == NULL) - { - DBG1("unrequested serial number in ocsp single response"); - return FALSE; - } - } - break; - case SINGLE_RESPONSE_CERT_STATUS_GOOD: - certinfo->set_status(certinfo, CERT_GOOD); - break; - case SINGLE_RESPONSE_CERT_STATUS_REVOKED: - certinfo->set_status(certinfo, CERT_REVOKED); - break; - case SINGLE_RESPONSE_CERT_STATUS_REVOCATION_TIME: - certinfo->set_revocationTime(certinfo, - asn1totime(&object, ASN1_GENERALIZEDTIME)); - break; - case SINGLE_RESPONSE_CERT_STATUS_CRL_REASON: - certinfo->set_revocationReason(certinfo, - (object.len == 1) ? *object.ptr : REASON_UNSPECIFIED); - break; - case SINGLE_RESPONSE_CERT_STATUS_UNKNOWN: - certinfo->set_status(certinfo, CERT_UNKNOWN); - break; - case SINGLE_RESPONSE_THIS_UPDATE: - certinfo->set_thisUpdate(certinfo, - asn1totime(&object, ASN1_GENERALIZEDTIME)); - break; - case SINGLE_RESPONSE_NEXT_UPDATE: - certinfo->set_nextUpdate(certinfo, - asn1totime(&object, ASN1_GENERALIZEDTIME)); - break; - case SINGLE_RESPONSE_EXT_ID: - extn_oid = known_oid(object); - break; - case SINGLE_RESPONSE_CRITICAL: - critical = object.len && *object.ptr; - DBG2(" %s", critical ? "TRUE" : "FALSE"); - case SINGLE_RESPONSE_EXT_VALUE: - break; - } - objectID++; - } - return TRUE; -} - -/** - * verify and process ocsp response and update the ocsp cache - */ -static void ocsp_process_response(private_ocsp_t *this, response_t *res, credential_store_t *credentials) -{ - x509_t *ocsp_cert = NULL; - - /* parse the ocsp response without looking at the single responses yet */ - response_status status = ocsp_parse_response(res); - - if (status != STATUS_SUCCESSFUL) - { - DBG1("error in ocsp response"); - return; - } - - /* check if there was a nonce in the request */ - if (this->nonce.ptr != NULL && res->nonce.ptr == NULL) - { - DBG1("ocsp response contains no nonce, replay attack possible"); - } - - /* check if the nonces are identical */ - if (res->nonce.ptr != NULL && !chunk_equals(res->nonce, this->nonce)) - { - DBG1("invalid nonce in ocsp response"); - return; - } - - /* check if we received a trusted responder certificate */ - if (res->responder_cert) - { - if (res->responder_cert->is_ocsp_signer(res->responder_cert)) - { - DBG2("received certificate is ocsp signer"); - if (credentials->is_trusted(credentials, "OCSP signing", res->responder_cert)) - { - DBG1("received ocsp signer certificate is trusted"); - ocsp_cert = credentials->add_auth_certificate(credentials, - res->responder_cert, AUTH_OCSP); - res->responder_cert = NULL; - } - else - { - DBG1("received ocsp signer certificate is not trusted - rejected"); - } - } - else - { - DBG1("received certificate is no ocsp signer - rejected"); - } - } - - /* if we didn't receive a trusted responder cert, search the credential store */ - if (ocsp_cert == NULL) - { - ocsp_cert = credentials->get_auth_certificate(credentials, - AUTH_OCSP|AUTH_CA, res->responder_id_name); - if (ocsp_cert == NULL) - { - DBG1("no ocsp signer certificate found"); - return; - } - } - - /* check the response signature */ - if (!ocsp_valid_response(res, ocsp_cert)) - { - DBG1("ocsp response signature is invalid"); - return; - } - DBG2("ocsp response signature is valid"); - - /* now parse the single responses one at a time */ - { - u_int level; - asn1_ctx_t ctx; - chunk_t object; - int objectID = 0; - - asn1_init(&ctx, res->responses, 0, FALSE, FALSE); - - while (objectID < RESPONSES_ROOF) - { - if (!extract_object(responsesObjects, &objectID, &object, &level, &ctx)) - { - return; - } - if (objectID == RESPONSES_SINGLE_RESPONSE) - { - ocsp_parse_single_response(this, object, level+1); - } - objectID++; - } - } -} - -/** - * Implements ocsp_t.fetch. - */ -static void fetch(private_ocsp_t *this, certinfo_t *certinfo, credential_store_t *credentials) -{ - chunk_t request; - response_t *response = NULL; - - if (this->uris->get_count(this->uris) == 0) - { - return; - } - this->certinfos->insert_last(this->certinfos, (void*)certinfo); - - request = ocsp_build_request(this); - DBG3("ocsp request: %B", &request); - { - iterator_t *iterator = this->uris->create_iterator(this->uris, TRUE); - identification_t *uri; - - while (iterator->iterate(iterator, (void**)&uri)) - { - fetcher_t *fetcher; - char uri_string[BUF_LEN]; - chunk_t uri_chunk = uri->get_encoding(uri); - chunk_t response_chunk; - - snprintf(uri_string, BUF_LEN, "%.*s", uri_chunk.len, uri_chunk.ptr); - fetcher = fetcher_create(uri_string); - - response_chunk = fetcher->post(fetcher, "application/ocsp-request", request); - fetcher->destroy(fetcher); - if (response_chunk.ptr != NULL) - { - response = response_create_from_chunk(response_chunk); - break; - } - } - iterator->destroy(iterator); - } - free(request.ptr); - - if (response == NULL) - { - return; - } - DBG3("ocsp response: %B", &response->chunk); - ocsp_process_response(this, response, credentials); - response->destroy(response); -} - -/** - * Implements ocsp_t.destroy. - */ -static void destroy(private_ocsp_t *this) -{ - this->certinfos->destroy(this->certinfos); - free(this->authNameID.ptr); - free(this->nonce.ptr); - free(this); -} - -/* - * Described in header. - */ -ocsp_t *ocsp_create(x509_t *cacert, linked_list_t *uris) -{ - private_ocsp_t *this = malloc_thing(private_ocsp_t); - - /* initialize */ - this->cacert = cacert; - this->uris = uris; - this->certinfos = linked_list_create(); - this->nonce = chunk_empty; - this->authKeyID = cacert->get_subjectKeyID(cacert); - { - hasher_t *hasher = hasher_create(HASH_SHA1); - identification_t *issuer = cacert->get_subject(cacert); - - hasher->allocate_hash(hasher, issuer->get_encoding(issuer), - &this->authNameID); - hasher->destroy(hasher); - } - - /* public functions */ - this->public.fetch = (void (*) (ocsp_t*,certinfo_t*,credential_store_t*))fetch; - this->public.destroy = (void (*) (ocsp_t*))destroy; - - return &this->public; -} diff --git a/src/libstrongswan/crypto/ocsp.h b/src/libstrongswan/crypto/ocsp.h deleted file mode 100644 index e468bb8be..000000000 --- a/src/libstrongswan/crypto/ocsp.h +++ /dev/null @@ -1,89 +0,0 @@ -/** - * @file ocsp.h - * - * @brief Interface of ocsp_t - * - */ - -/* Support of the Online Certificate Status Protocol (OCSP) Support - * - * Copyright (C) 2003 Christoph Gysin, Simon Zwahlen - * Copyright (C) 2007 Andreas Steffen - * - * Hochschule fuer Technik Rapperswil, Switzerland - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * for more details. - * - * RCSID $Id$ - */ - -#ifndef OCSP_H_ -#define OCSP_H_ - -typedef struct ocsp_t ocsp_t; - -#include <credential_store.h> -#include <utils/linked_list.h> - -#include "certinfo.h" - -/* constants */ -#define OCSP_BASIC_RESPONSE_VERSION 1 -#define OCSP_DEFAULT_VALID_TIME 120 /* validity of one-time response in seconds */ -#define OCSP_WARNING_INTERVAL 2 /* days */ - -/* OCSP response status */ -typedef enum { - STATUS_SUCCESSFUL = 0, - STATUS_MALFORMEDREQUEST = 1, - STATUS_INTERNALERROR = 2, - STATUS_TRYLATER = 3, - STATUS_SIGREQUIRED = 5, - STATUS_UNAUTHORIZED= 6 -} response_status; - -/** - * @brief Online Certficate Status Protocol (OCSP) - * - * @ingroup transforms - */ -struct ocsp_t { - - /** - * @brief Fetches the actual certificate status via OCSP - * - * @param uris linked list of ocsp uris - * @param certinfo certificate status info to be updated - * @param credentials credential store needed for trust path verification - */ - void (*fetch) (ocsp_t *this, certinfo_t *certinfo, credential_store_t *credentials); - - /** - * @brief Destroys the ocsp_t object. - * - * @param this ocsp object to destroy - */ - void (*destroy) (ocsp_t *this); - -}; - -/** - * @brief Create an ocsp_t object. - * - * @param cacert ca certificate - * @param uris linked list of ocsp uris - * @return created ocsp_t object - * - * @ingroup transforms - */ -ocsp_t *ocsp_create(x509_t *cacert, linked_list_t *uris); - -#endif /* OCSP_H_ */ diff --git a/src/libstrongswan/crypto/pkcs7.c b/src/libstrongswan/crypto/pkcs7.c deleted file mode 100644 index 48d3e2d78..000000000 --- a/src/libstrongswan/crypto/pkcs7.c +++ /dev/null @@ -1,1077 +0,0 @@ -/** - * @file pkcs7.c - * - * @brief Implementation of pkcs7_t. - * - */ - -/* - * Copyright (C) 2005 Jan Hutter, Martin Willi - * Copyright (C) 2002-2008 Andreas Steffen - * - * Hochschule fuer Technik Rapperswil, Switzerland - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * for more details. - * - * RCSID $Id: pkcs7.c 3438 2008-02-02 00:29:03Z andreas $ - */ - -#include <stdlib.h> -#include <string.h> - -#include <library.h> -#include "debug.h" - -#include <asn1/asn1.h> -#include <asn1/oid.h> -#include <crypto/x509.h> -#include <crypto/pkcs9.h> -#include <crypto/hashers/hasher.h> -#include <crypto/crypters/crypter.h> -#include <crypto/rsa/rsa_public_key.h> -#include <utils/randomizer.h> -#include <utils/linked_list.h> - -#include "pkcs7.h" - -typedef struct private_pkcs7_t private_pkcs7_t; - -/** - * Private data of a pkcs7_t object. - */ -struct private_pkcs7_t { - /** - * Public interface for this certificate. - */ - pkcs7_t public; - - /** - * contentInfo type - */ - int type; - - /** - * ASN.1 encoded content - */ - chunk_t content; - - /** - * Has the content already been parsed? - */ - bool parsed; - - /** - * ASN.1 parsing start level - */ - u_int level; - - /** - * retrieved data - */ - chunk_t data; - - /** - * ASN.1 encoded attributes - */ - pkcs9_t *attributes; - - /** - * Linked list of X.509 certificates - */ - linked_list_t *certs; -}; - -/** - * ASN.1 definition of the PKCS#7 ContentInfo type - */ -static const asn1Object_t contentInfoObjects[] = { - { 0, "contentInfo", ASN1_SEQUENCE, ASN1_NONE }, /* 0 */ - { 1, "contentType", ASN1_OID, ASN1_BODY }, /* 1 */ - { 1, "content", ASN1_CONTEXT_C_0, ASN1_OPT | - ASN1_BODY }, /* 2 */ - { 1, "end opt", ASN1_EOC, ASN1_END } /* 3 */ -}; - -#define PKCS7_INFO_TYPE 1 -#define PKCS7_INFO_CONTENT 2 -#define PKCS7_INFO_ROOF 4 - -/** - * ASN.1 definition of the PKCS#7 signedData type - */ -static const asn1Object_t signedDataObjects[] = { - { 0, "signedData", ASN1_SEQUENCE, ASN1_NONE }, /* 0 */ - { 1, "version", ASN1_INTEGER, ASN1_BODY }, /* 1 */ - { 1, "digestAlgorithms", ASN1_SET, ASN1_LOOP }, /* 2 */ - { 2, "algorithm", ASN1_EOC, ASN1_RAW }, /* 3 */ - { 1, "end loop", ASN1_EOC, ASN1_END }, /* 4 */ - { 1, "contentInfo", ASN1_EOC, ASN1_RAW }, /* 5 */ - { 1, "certificates", ASN1_CONTEXT_C_0, ASN1_OPT | - ASN1_LOOP }, /* 6 */ - { 2, "certificate", ASN1_SEQUENCE, ASN1_OBJ }, /* 7 */ - { 1, "end opt or loop", ASN1_EOC, ASN1_END }, /* 8 */ - { 1, "crls", ASN1_CONTEXT_C_1, ASN1_OPT | - ASN1_LOOP }, /* 9 */ - { 2, "crl", ASN1_SEQUENCE, ASN1_OBJ }, /* 10 */ - { 1, "end opt or loop", ASN1_EOC, ASN1_END }, /* 11 */ - { 1, "signerInfos", ASN1_SET, ASN1_LOOP }, /* 12 */ - { 2, "signerInfo", ASN1_SEQUENCE, ASN1_NONE }, /* 13 */ - { 3, "version", ASN1_INTEGER, ASN1_BODY }, /* 14 */ - { 3, "issuerAndSerialNumber", ASN1_SEQUENCE, ASN1_BODY }, /* 15 */ - { 4, "issuer", ASN1_SEQUENCE, ASN1_OBJ }, /* 16 */ - { 4, "serial", ASN1_INTEGER, ASN1_BODY }, /* 17 */ - { 3, "digestAlgorithm", ASN1_EOC, ASN1_RAW }, /* 18 */ - { 3, "authenticatedAttributes", ASN1_CONTEXT_C_0, ASN1_OPT | - ASN1_OBJ }, /* 19 */ - { 3, "end opt", ASN1_EOC, ASN1_END }, /* 20 */ - { 3, "digestEncryptionAlgorithm", ASN1_EOC, ASN1_RAW }, /* 21 */ - { 3, "encryptedDigest", ASN1_OCTET_STRING, ASN1_BODY }, /* 22 */ - { 3, "unauthenticatedAttributes", ASN1_CONTEXT_C_1, ASN1_OPT }, /* 23 */ - { 3, "end opt", ASN1_EOC, ASN1_END }, /* 24 */ - { 1, "end loop", ASN1_EOC, ASN1_END } /* 25 */ -}; - -#define PKCS7_DIGEST_ALG 3 -#define PKCS7_SIGNED_CONTENT_INFO 5 -#define PKCS7_SIGNED_CERT 7 -#define PKCS7_SIGNER_INFO 13 -#define PKCS7_SIGNED_ISSUER 16 -#define PKCS7_SIGNED_SERIAL_NUMBER 17 -#define PKCS7_DIGEST_ALGORITHM 18 -#define PKCS7_AUTH_ATTRIBUTES 19 -#define PKCS7_DIGEST_ENC_ALGORITHM 21 -#define PKCS7_ENCRYPTED_DIGEST 22 -#define PKCS7_SIGNED_ROOF 26 - -/** - * ASN.1 definition of the PKCS#7 envelopedData type - */ -static const asn1Object_t envelopedDataObjects[] = { - { 0, "envelopedData", ASN1_SEQUENCE, ASN1_NONE }, /* 0 */ - { 1, "version", ASN1_INTEGER, ASN1_BODY }, /* 1 */ - { 1, "recipientInfos", ASN1_SET, ASN1_LOOP }, /* 2 */ - { 2, "recipientInfo", ASN1_SEQUENCE, ASN1_BODY }, /* 3 */ - { 3, "version", ASN1_INTEGER, ASN1_BODY }, /* 4 */ - { 3, "issuerAndSerialNumber", ASN1_SEQUENCE, ASN1_BODY }, /* 5 */ - { 4, "issuer", ASN1_SEQUENCE, ASN1_OBJ }, /* 6 */ - { 4, "serial", ASN1_INTEGER, ASN1_BODY }, /* 7 */ - { 3, "encryptionAlgorithm", ASN1_EOC, ASN1_RAW }, /* 8 */ - { 3, "encryptedKey", ASN1_OCTET_STRING, ASN1_BODY }, /* 9 */ - { 1, "end loop", ASN1_EOC, ASN1_END }, /* 10 */ - { 1, "encryptedContentInfo", ASN1_SEQUENCE, ASN1_OBJ }, /* 11 */ - { 2, "contentType", ASN1_OID, ASN1_BODY }, /* 12 */ - { 2, "contentEncryptionAlgorithm", ASN1_EOC, ASN1_RAW }, /* 13 */ - { 2, "encryptedContent", ASN1_CONTEXT_S_0, ASN1_BODY } /* 14 */ -}; - -#define PKCS7_ENVELOPED_VERSION 1 -#define PKCS7_RECIPIENT_INFO_VERSION 4 -#define PKCS7_ISSUER 6 -#define PKCS7_SERIAL_NUMBER 7 -#define PKCS7_ENCRYPTION_ALG 8 -#define PKCS7_ENCRYPTED_KEY 9 -#define PKCS7_CONTENT_TYPE 12 -#define PKCS7_CONTENT_ENC_ALGORITHM 13 -#define PKCS7_ENCRYPTED_CONTENT 14 -#define PKCS7_ENVELOPED_ROOF 15 - -/** - * PKCS7 contentInfo OIDs - */ -static u_char ASN1_pkcs7_data_oid_str[] = { - 0x06, 0x09, - 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x07, 0x01 -}; - -static u_char ASN1_pkcs7_signed_data_oid_str[] = { - 0x06, 0x09, - 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x07, 0x02 -}; - -static u_char ASN1_pkcs7_enveloped_data_oid_str[] = { - 0x06, 0x09, - 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x07, 0x03 -}; - -static u_char ASN1_pkcs7_signed_enveloped_data_oid_str[] = { - 0x06, 0x09, - 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x07, 0x04 -}; - -static u_char ASN1_pkcs7_digested_data_oid_str[] = { - 0x06, 0x09, - 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x07, 0x05 -}; - -static char ASN1_pkcs7_encrypted_data_oid_str[] = { - 0x06, 0x09, - 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x07, 0x06 -}; - -static const chunk_t ASN1_pkcs7_data_oid = - chunk_from_buf(ASN1_pkcs7_data_oid_str); -static const chunk_t ASN1_pkcs7_signed_data_oid = - chunk_from_buf(ASN1_pkcs7_signed_data_oid_str); -static const chunk_t ASN1_pkcs7_enveloped_data_oid = - chunk_from_buf(ASN1_pkcs7_enveloped_data_oid_str); -static const chunk_t ASN1_pkcs7_signed_enveloped_data_oid = - chunk_from_buf(ASN1_pkcs7_signed_enveloped_data_oid_str); -static const chunk_t ASN1_pkcs7_digested_data_oid = - chunk_from_buf(ASN1_pkcs7_digested_data_oid_str); -static const chunk_t ASN1_pkcs7_encrypted_data_oid = - chunk_from_buf(ASN1_pkcs7_encrypted_data_oid_str); - -/** - * 3DES and DES encryption OIDs - */ -static u_char ASN1_3des_ede_cbc_oid_str[] = { - 0x06, 0x08, - 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x03, 0x07 -}; - -static u_char ASN1_des_cbc_oid_str[] = { - 0x06, 0x05, - 0x2B, 0x0E, 0x03, 0x02, 0x07 -}; - -static const chunk_t ASN1_3des_ede_cbc_oid = - chunk_from_buf(ASN1_3des_ede_cbc_oid_str); -static const chunk_t ASN1_des_cbc_oid = - chunk_from_buf(ASN1_des_cbc_oid_str); - -/** - * Implements pkcs7_t.is_data. - */ -static bool is_data(private_pkcs7_t *this) -{ - return this->type == OID_PKCS7_DATA; -} - -/** - * Implements pkcs7_t.is_signedData. - */ -static bool is_signedData(private_pkcs7_t *this) -{ - return this->type == OID_PKCS7_SIGNED_DATA; -} - -/** - * Implements pkcs7_t.is_envelopedData. - */ -static bool is_envelopedData(private_pkcs7_t *this) -{ - return this->type == OID_PKCS7_ENVELOPED_DATA; -} - -/** - * Check whether to abort the requested parsing - */ -static bool abort_parsing(private_pkcs7_t *this, int type) -{ - if (this->type != type) - { - DBG1("pkcs7 content to be parsed is not of type '%s'", - oid_names[type]); - return TRUE; - } - if (this->parsed) - { - DBG1("pkcs7 content has already been parsed"); - return TRUE; - } - this->parsed = TRUE; - return FALSE; -} - -/** - * Implements pkcs7_t.parse_data. - */ -static bool parse_data(private_pkcs7_t *this) -{ - chunk_t data = this->content; - - if (abort_parsing(this, OID_PKCS7_DATA)) - { - return FALSE; - } - if (data.len == 0) - { - this->data = chunk_empty; - return TRUE; - } - if (parse_asn1_simple_object(&data, ASN1_OCTET_STRING, this->level, "data")) - { - this->data = chunk_clone(data); - return TRUE; - } - else - { - return FALSE; - } -} - -/** - * Implements pkcs7_t.parse_signedData. - */ -static bool parse_signedData(private_pkcs7_t *this, x509_t *cacert) -{ - asn1_ctx_t ctx; - chunk_t object; - u_int level; - int objectID = 0; - - int digest_alg = OID_UNKNOWN; - int enc_alg = OID_UNKNOWN; - int signerInfos = 0; - - chunk_t encrypted_digest = chunk_empty; - - if (abort_parsing(this, OID_PKCS7_SIGNED_DATA)) - { - return FALSE; - } - - asn1_init(&ctx, this->content, this->level, FALSE, FALSE); - - while (objectID < PKCS7_SIGNED_ROOF) - { - if (!extract_object(signedDataObjects, &objectID, &object, &level, &ctx)) - { - return FALSE; - } - - switch (objectID) - { - case PKCS7_DIGEST_ALG: - digest_alg = parse_algorithmIdentifier(object, level, NULL); - break; - case PKCS7_SIGNED_CONTENT_INFO: - { - chunk_t pureData; - pkcs7_t *data = pkcs7_create_from_chunk(object, level+1); - - if (data == NULL) - { - return FALSE; - } - if (!data->parse_data(data)) - { - data->destroy(data); - return FALSE; - } - pureData = data->get_data(data); - this->data = (pureData.len)? chunk_clone(pureData) : chunk_empty; - data->destroy(data); - } - break; - case PKCS7_SIGNED_CERT: - { - x509_t *cert = x509_create_from_chunk(chunk_clone(object), level+1); - - if (cert) - { - this->certs->insert_last(this->certs, (void*)cert); - } - } - break; - case PKCS7_SIGNER_INFO: - signerInfos++; - DBG2(" signer #%d", signerInfos); - break; - case PKCS7_SIGNED_ISSUER: - { - identification_t *issuer; - - issuer = identification_create_from_encoding(ID_DER_ASN1_DN, object); - DBG2(" '%D'", issuer); - issuer->destroy(issuer); - } - break; - case PKCS7_AUTH_ATTRIBUTES: - *object.ptr = ASN1_SET; - this->attributes = pkcs9_create_from_chunk(object, level+1); - *object.ptr = ASN1_CONTEXT_C_0; - break; - case PKCS7_DIGEST_ALGORITHM: - digest_alg = parse_algorithmIdentifier(object, level, NULL); - break; - case PKCS7_DIGEST_ENC_ALGORITHM: - enc_alg = parse_algorithmIdentifier(object, level, NULL); - break; - case PKCS7_ENCRYPTED_DIGEST: - encrypted_digest = object; - } - objectID++; - } - - /* check the signature only if a cacert is available */ - if (cacert != NULL) - { - hash_algorithm_t algorithm = hasher_algorithm_from_oid(digest_alg); - rsa_public_key_t *signer = cacert->get_public_key(cacert); - - if (signerInfos == 0) - { - DBG1("no signerInfo object found"); - return FALSE; - } - else if (signerInfos > 1) - { - DBG1("more than one signerInfo object found"); - return FALSE; - } - if (this->attributes == NULL) - { - DBG1("no authenticatedAttributes object found"); - return FALSE; - } - if (enc_alg != OID_RSA_ENCRYPTION) - { - DBG1("only RSA digest encryption supported"); - return FALSE; - } - if (signer->verify_emsa_pkcs1_signature(signer, algorithm, - this->attributes->get_encoding(this->attributes), encrypted_digest) != SUCCESS) - { - DBG1("invalid digest signature"); - return FALSE; - } - else - { - DBG2("digest signature is valid"); - } - if (this->data.ptr != NULL) - { - chunk_t messageDigest = this->attributes->get_messageDigest(this->attributes); - - if (messageDigest.ptr == NULL) - { - DBG1("messageDigest attribute not found"); - return FALSE; - } - else - { - hasher_t *hasher = hasher_create(algorithm); - chunk_t hash; - bool valid; - - hasher->allocate_hash(hasher, this->data, &hash); - hasher->destroy(hasher); - DBG3("hash: %B", &hash); - - valid = chunk_equals(messageDigest, hash); - free(messageDigest.ptr); - free(hash.ptr); - if (valid) - { - DBG2("messageDigest is valid"); - } - else - { - DBG1("invalid messageDigest"); - return FALSE; - } - } - } - } - return TRUE; -} - -/** - * Parse PKCS#7 envelopedData content - */ -static bool parse_envelopedData(private_pkcs7_t *this, chunk_t serialNumber, - rsa_private_key_t *key) -{ - asn1_ctx_t ctx; - chunk_t object; - u_int level; - int objectID = 0; - - chunk_t iv = chunk_empty; - chunk_t symmetric_key = chunk_empty; - chunk_t encrypted_content = chunk_empty; - - crypter_t *crypter = NULL; - - if (abort_parsing(this, OID_PKCS7_ENVELOPED_DATA)) - { - return FALSE; - } - - asn1_init(&ctx, this->content, this->level, FALSE, FALSE); - - while (objectID < PKCS7_ENVELOPED_ROOF) - { - if (!extract_object(envelopedDataObjects, &objectID, &object, &level, &ctx)) - { - goto failed; - } - - switch (objectID) - { - case PKCS7_ENVELOPED_VERSION: - if (*object.ptr != 0) - { - DBG1("envelopedData version is not 0"); - goto failed; - } - break; - case PKCS7_RECIPIENT_INFO_VERSION: - if (*object.ptr != 0) - { - DBG1("recipient info version is not 0"); - goto failed; - } - break; - case PKCS7_ISSUER: - { - identification_t *issuer; - - issuer = identification_create_from_encoding(ID_DER_ASN1_DN, object); - DBG2(" '%D'", issuer); - issuer->destroy(issuer); - } - break; - case PKCS7_SERIAL_NUMBER: - if (!chunk_equals(serialNumber, object)) - { - DBG1("serial numbers do not match"); - goto failed; - } - break; - case PKCS7_ENCRYPTION_ALG: - { - int alg = parse_algorithmIdentifier(object, level, NULL); - - if (alg != OID_RSA_ENCRYPTION) - { - DBG1("only rsa encryption supported"); - goto failed; - } - } - break; - case PKCS7_ENCRYPTED_KEY: - if (key->pkcs1_decrypt(key, object, &symmetric_key) != SUCCESS) - { - DBG1("symmetric key could not be decrypted with rsa"); - goto failed; - } - DBG4("symmetric key : %B", &symmetric_key); - break; - case PKCS7_CONTENT_TYPE: - if (known_oid(object) != OID_PKCS7_DATA) - { - DBG1("encrypted content not of type pkcs7 data"); - goto failed; - } - break; - case PKCS7_CONTENT_ENC_ALGORITHM: - { - int alg = parse_algorithmIdentifier(object, level, &iv); - - switch (alg) - { - case OID_DES_CBC: - crypter = crypter_create(ENCR_DES, 0); - break; - case OID_3DES_EDE_CBC: - crypter = crypter_create(ENCR_3DES, 0); - break; - default: - DBG1("Only DES and 3DES supported for symmetric encryption"); - goto failed; - } - if (symmetric_key.len != crypter->get_key_size(crypter)) - { - DBG1("symmetric key has wrong length"); - goto failed; - } - if (!parse_asn1_simple_object(&iv, ASN1_OCTET_STRING, level+1, "IV")) - { - DBG1("IV could not be parsed"); - goto failed; - } - if (iv.len != crypter->get_block_size(crypter)) - { - DBG1("IV has wrong length"); - goto failed; - } - } - break; - case PKCS7_ENCRYPTED_CONTENT: - encrypted_content = object; - break; - } - objectID++; - } - - /* decrypt the content */ - crypter->set_key(crypter, symmetric_key); - crypter->decrypt(crypter, encrypted_content, iv, &this->data); - DBG3("decrypted content with padding: %B", &this->data); - - /* remove the padding */ - { - u_char *pos = this->data.ptr + this->data.len - 1; - u_char pattern = *pos; - size_t padding = pattern; - - if (padding > this->data.len) - { - DBG1("padding greater than data length"); - goto failed; - } - this->data.len -= padding; - - while (padding-- > 0) - { - if (*pos-- != pattern) - { - DBG1("wrong padding pattern"); - goto failed; - } - } - } - crypter->destroy(crypter); - free(symmetric_key.ptr); - return TRUE; - -failed: - DESTROY_IF(crypter); - free(symmetric_key.ptr); - chunk_free(&this->data); - return FALSE; -} - -/** - * Implements pkcs7_t.get_data. - */ -static chunk_t get_data(private_pkcs7_t *this) -{ - return this->data; -} - -/** - * Implements pkcs7_t.get_contentInfo. - */ -static chunk_t get_contentInfo(private_pkcs7_t *this) -{ - chunk_t content_type; - - /* select DER-encoded OID for pkcs7_contentInfo type */ - switch(this->type) - { - case OID_PKCS7_DATA: - content_type = ASN1_pkcs7_data_oid; - break; - case OID_PKCS7_SIGNED_DATA: - content_type = ASN1_pkcs7_signed_data_oid; - break; - case OID_PKCS7_ENVELOPED_DATA: - content_type = ASN1_pkcs7_enveloped_data_oid; - break; - case OID_PKCS7_SIGNED_ENVELOPED_DATA: - content_type = ASN1_pkcs7_signed_enveloped_data_oid; - break; - case OID_PKCS7_DIGESTED_DATA: - content_type = ASN1_pkcs7_digested_data_oid; - break; - case OID_PKCS7_ENCRYPTED_DATA: - content_type = ASN1_pkcs7_encrypted_data_oid; - break; - case OID_UNKNOWN: - default: - DBG1("invalid pkcs7 contentInfo type"); - return chunk_empty; - } - - return (this->content.ptr == NULL) - ? asn1_simple_object(ASN1_SEQUENCE, content_type) - : asn1_wrap(ASN1_SEQUENCE, "cm", - content_type, - asn1_simple_object(ASN1_CONTEXT_C_0, this->content) - ); -} - -/** - * Implements pkcs7_t.create_certificate_iterator - */ -static iterator_t *create_certificate_iterator(const private_pkcs7_t *this) -{ - return this->certs->create_iterator(this->certs, TRUE); -} - -/** - * Implements pkcs7_t.set_certificate - */ -static void set_certificate(private_pkcs7_t *this, x509_t *cert) -{ - if (cert) - { - /* TODO the certificate is currently not cloned */ - this->certs->insert_last(this->certs, cert); - } -} - -/** - * Implements pkcs7_t.set_attributes - */ -static void set_attributes(private_pkcs7_t *this, pkcs9_t *attributes) -{ - this->attributes = attributes; -} - -/** - * build a DER-encoded issuerAndSerialNumber object - */ -chunk_t pkcs7_build_issuerAndSerialNumber(x509_t *cert) -{ - identification_t *issuer = cert->get_issuer(cert); - - return asn1_wrap(ASN1_SEQUENCE, "cm", - issuer->get_encoding(issuer), - asn1_simple_object(ASN1_INTEGER, cert->get_serialNumber(cert))); -} - -/** - * Implements pkcs7_t.build_envelopedData. - */ -bool build_envelopedData(private_pkcs7_t *this, x509_t *cert, - encryption_algorithm_t alg) -{ - chunk_t iv, symmetricKey, in, out, alg_oid; - crypter_t *crypter; - - /* select OID of symmetric encryption algorithm */ - switch (alg) - { - case ENCR_DES: - alg_oid = ASN1_des_cbc_oid; - break; - case ENCR_3DES: - alg_oid = ASN1_3des_ede_cbc_oid; - break; - default: - DBG1(" encryption algorithm %N not supported", - encryption_algorithm_names, alg); - return FALSE; - } - - crypter = crypter_create(alg, 0); - if (crypter == NULL) - { - DBG1(" could not create crypter for algorithm %N", - encryption_algorithm_names, alg); - return FALSE; - } - - /* generate a true random symmetric encryption key - * and a pseudo-random iv - */ - { - randomizer_t *randomizer = randomizer_create(); - - randomizer->allocate_random_bytes(randomizer, - crypter->get_key_size(crypter), &symmetricKey); - DBG4(" symmetric encryption key: %B", &symmetricKey); - - randomizer->allocate_pseudo_random_bytes(randomizer, - crypter->get_block_size(crypter), &iv); - DBG4(" initialization vector: %B", &iv); - - randomizer->destroy(randomizer); - } - - /* pad the data so that the total length becomes - * a multiple of the block size - */ - { - size_t block_size = crypter->get_block_size(crypter); - size_t padding = block_size - this->data.len % block_size; - - in.len = this->data.len + padding; - in.ptr = malloc(in.len); - - DBG2(" padding %d bytes of data to multiple block size of %d bytes", - (int)this->data.len, (int)in.len); - - /* copy data */ - memcpy(in.ptr, this->data.ptr, this->data.len); - /* append padding */ - memset(in.ptr + this->data.len, padding, padding); - } - DBG3(" padded unencrypted data: %B", &in); - - /* symmetric encryption of data object */ - crypter->set_key(crypter, symmetricKey); - crypter->encrypt(crypter, in, iv, &out); - crypter->destroy(crypter); - chunk_free_randomized(&in); - DBG3(" encrypted data: %B", &out); - - /* build pkcs7 enveloped data object */ - { - chunk_t contentEncryptionAlgorithm = asn1_wrap(ASN1_SEQUENCE, "cm", - alg_oid, - asn1_wrap(ASN1_OCTET_STRING, "m", iv)); - - chunk_t encryptedContentInfo = asn1_wrap(ASN1_SEQUENCE, "cmm", - ASN1_pkcs7_data_oid, - contentEncryptionAlgorithm, - asn1_wrap(ASN1_CONTEXT_S_0, "m", out)); - - chunk_t wrappedKey, encryptedKey, recipientInfo; - - rsa_public_key_t *public_key = cert->get_public_key(cert); - - public_key->pkcs1_encrypt(public_key, symmetricKey, &wrappedKey); - chunk_free_randomized(&symmetricKey); - - encryptedKey = asn1_wrap(ASN1_OCTET_STRING, "m", wrappedKey); - - recipientInfo = asn1_wrap(ASN1_SEQUENCE, "cmcm", - ASN1_INTEGER_0, - pkcs7_build_issuerAndSerialNumber(cert), - asn1_algorithmIdentifier(OID_RSA_ENCRYPTION), - encryptedKey); - - this->content = asn1_wrap(ASN1_SEQUENCE, "cmm", - ASN1_INTEGER_0, - asn1_wrap(ASN1_SET, "m", recipientInfo), - encryptedContentInfo); - this->type = OID_PKCS7_ENVELOPED_DATA; - } - return TRUE; -} - -/** - * Implements pkcs7_t.build_signedData. - */ -bool build_signedData(private_pkcs7_t *this, rsa_private_key_t *private_key, - hash_algorithm_t alg) -{ - int signature_oid = hasher_signature_algorithm_to_oid(alg); - chunk_t authenticatedAttributes = chunk_empty; - chunk_t encryptedDigest = chunk_empty; - chunk_t signerInfo; - x509_t *cert; - - if (this->certs->get_first(this->certs, (void**)&cert) != SUCCESS) - { - DBG1(" no pkcs7 signer certificate found"); - return FALSE; - } - - if (this->attributes != NULL) - { - if (this->data.ptr != NULL) - { - /* take the current time as signingTime */ - time_t now = time(NULL); - chunk_t signingTime = timetoasn1(&now, ASN1_UTCTIME); - - chunk_t messageDigest, attributes; - hasher_t *hasher = hasher_create(alg); - - hasher->allocate_hash(hasher, this->data, &messageDigest); - hasher->destroy(hasher); - this->attributes->set_attribute(this->attributes, - OID_PKCS9_CONTENT_TYPE, ASN1_pkcs7_data_oid); - this->attributes->set_messageDigest(this->attributes, - messageDigest); - this->attributes->set_attribute(this->attributes, - OID_PKCS9_SIGNING_TIME, signingTime); - attributes = this->attributes->get_encoding(this->attributes); - - free(messageDigest.ptr); - free(signingTime.ptr); - - private_key->build_emsa_pkcs1_signature(private_key, alg, - attributes, &encryptedDigest); - authenticatedAttributes = chunk_clone(attributes); - *authenticatedAttributes.ptr = ASN1_CONTEXT_C_0; - } - } - else if (this->data.ptr != NULL) - { - private_key->build_emsa_pkcs1_signature(private_key, alg, - this->data, &encryptedDigest); - } - if (encryptedDigest.ptr) - { - encryptedDigest = asn1_wrap(ASN1_OCTET_STRING, "m", encryptedDigest); - } - - signerInfo = asn1_wrap(ASN1_SEQUENCE, "cmcmcm", - ASN1_INTEGER_1, - pkcs7_build_issuerAndSerialNumber(cert), - asn1_algorithmIdentifier(signature_oid), - authenticatedAttributes, - asn1_algorithmIdentifier(OID_RSA_ENCRYPTION), - encryptedDigest); - - if (this->data.ptr != NULL) - { - this->content = asn1_simple_object(ASN1_OCTET_STRING, this->data); - chunk_free(&this->data); - } - this->type = OID_PKCS7_DATA; - this->data = get_contentInfo(this); - chunk_free(&this->content); - - this->type = OID_PKCS7_SIGNED_DATA; - - this->content = asn1_wrap(ASN1_SEQUENCE, "cmcmm", - ASN1_INTEGER_1, - asn1_simple_object(ASN1_SET, asn1_algorithmIdentifier(signature_oid)), - this->data, - asn1_simple_object(ASN1_CONTEXT_C_0, cert->get_certificate(cert)), - asn1_wrap(ASN1_SET, "m", signerInfo)); - - return TRUE; -} - -/** - * Implements pkcs7_t.destroy - */ -static void destroy(private_pkcs7_t *this) -{ - DESTROY_IF(this->attributes); - this->certs->destroy_offset(this->certs, offsetof(x509_t, destroy)); - free(this->content.ptr); - free(this->data.ptr); - free(this); -} - -/** - * Parse PKCS#7 contentInfo object - */ -static bool parse_contentInfo(chunk_t blob, u_int level0, private_pkcs7_t *cInfo) -{ - asn1_ctx_t ctx; - chunk_t object; - u_int level; - int objectID = 0; - - asn1_init(&ctx, blob, level0, FALSE, FALSE); - - while (objectID < PKCS7_INFO_ROOF) - { - if (!extract_object(contentInfoObjects, &objectID, &object, &level, &ctx)) - { - return FALSE; - } - - if (objectID == PKCS7_INFO_TYPE) - { - cInfo->type = known_oid(object); - if (cInfo->type < OID_PKCS7_DATA - || cInfo->type > OID_PKCS7_ENCRYPTED_DATA) - { - DBG1("unknown pkcs7 content type"); - return FALSE; - } - } - else if (objectID == PKCS7_INFO_CONTENT && object.len > 0) - { - cInfo->content = chunk_clone(object); - } - objectID++; - } - return TRUE; -} - -/** - * Generic private constructor - */ -static private_pkcs7_t *pkcs7_create_empty(void) -{ - private_pkcs7_t *this = malloc_thing(private_pkcs7_t); - - /* initialize */ - this->type = OID_UNKNOWN; - this->content = chunk_empty; - this->parsed = FALSE; - this->level = 0; - this->data = chunk_empty; - this->attributes = NULL; - this->certs = linked_list_create(); - - /*public functions */ - this->public.is_data = (bool (*) (pkcs7_t*))is_data; - this->public.is_signedData = (bool (*) (pkcs7_t*))is_signedData; - this->public.is_envelopedData = (bool (*) (pkcs7_t*))is_envelopedData; - this->public.parse_data = (bool (*) (pkcs7_t*))parse_data; - this->public.parse_signedData = (bool (*) (pkcs7_t*,x509_t*))parse_signedData; - this->public.parse_envelopedData = (bool (*) (pkcs7_t*,chunk_t,rsa_private_key_t*))parse_envelopedData; - this->public.get_data = (chunk_t (*) (pkcs7_t*))get_data; - this->public.get_contentInfo = (chunk_t (*) (pkcs7_t*))get_contentInfo; - this->public.create_certificate_iterator = (iterator_t* (*) (pkcs7_t*))create_certificate_iterator; - this->public.set_certificate = (void (*) (pkcs7_t*,x509_t*))set_certificate; - this->public.set_attributes = (void (*) (pkcs7_t*,pkcs9_t*))set_attributes; - this->public.build_envelopedData = (bool (*) (pkcs7_t*,x509_t*,encryption_algorithm_t))build_envelopedData; - this->public.build_signedData = (bool (*) (pkcs7_t*,rsa_private_key_t*,hash_algorithm_t))build_signedData; - this->public.destroy = (void (*) (pkcs7_t*))destroy; - - return this; -} - -/* - * Described in header. - */ -pkcs7_t *pkcs7_create_from_chunk(chunk_t chunk, u_int level) -{ - private_pkcs7_t *this = pkcs7_create_empty(); - - this->level = level + 2; - if (!parse_contentInfo(chunk, level, this)) - { - destroy(this); - return NULL; - } - return &this->public; -} - -/* - * Described in header. - */ -pkcs7_t *pkcs7_create_from_data(chunk_t data) -{ - private_pkcs7_t *this = pkcs7_create_empty(); - - this->data = chunk_clone(data); - this->parsed = TRUE; - - return &this->public; -} - -/* - * Described in header. - */ -pkcs7_t *pkcs7_create_from_file(const char *filename, const char *label) -{ - bool pgp = FALSE; - chunk_t chunk = chunk_empty; - char cert_label[BUF_LEN]; - pkcs7_t *pkcs7; - - snprintf(cert_label, BUF_LEN, "%s pkcs7", label); - - if (!pem_asn1_load_file(filename, NULL, cert_label, &chunk, &pgp)) - { - return NULL; - } - - pkcs7 = pkcs7_create_from_chunk(chunk, 0); - free(chunk.ptr); - return pkcs7; -} diff --git a/src/libstrongswan/crypto/pkcs7.h b/src/libstrongswan/crypto/pkcs7.h deleted file mode 100644 index 74bd25361..000000000 --- a/src/libstrongswan/crypto/pkcs7.h +++ /dev/null @@ -1,209 +0,0 @@ -/** - * @file pkcs7.h - * - * @brief Interface of pkcs7_t. - * - */ - -/* - * Copyright (C) 2005 Jan Hutter, Martin Willi - * Copyright (C) 2002-2008 Andreas Steffen - * - * Hochschule fuer Technik Rapperswil, Switzerland - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * for more details. - * - * RCSID $Id: pkcs7.h 3437 2008-02-01 22:26:01Z andreas $ - */ - -#ifndef _PKCS7_H -#define _PKCS7_H - -typedef struct pkcs7_t pkcs7_t; - -#include <library.h> -#include <crypto/x509.h> -#include <crypto/pkcs9.h> -#include <crypto/rsa/rsa_private_key.h> -#include <crypto/crypters/crypter.h> -#include <utils/iterator.h> - -/** - * @brief PKCS#7 contentInfo object. - * - * @b Constructors: - * -pkcs7_create_from_chunk() - * -pkcs7_create_from_data() - * - * @ingroup crypto - */ -struct pkcs7_t { - /** - * @brief Check if the PKCS#7 contentType is data - * - * @param this calling object - * @return TRUE if the contentType is data - */ - bool (*is_data) (pkcs7_t *this); - - /** - * @brief Check if the PKCS#7 contentType is signedData - * - * @param this calling object - * @return TRUE if the contentType is signedData - */ - bool (*is_signedData) (pkcs7_t *this); - - /** - * @brief Check if the PKCS#7 contentType is envelopedData - * - * @param this calling object - * @return TRUE if the contentType is envelopedData - */ - bool (*is_envelopedData) (pkcs7_t *this); - - /** - * @brief Parse a PKCS#7 data content. - * - * @param this calling object - * @return TRUE if parsing was successful - */ - bool (*parse_data) (pkcs7_t *this); - - /** - * @brief Parse a PKCS#7 signedData content. - * - * @param this calling object - * @param cacert cacert used to verify the signature - * @return TRUE if parsing was successful - */ - bool (*parse_signedData) (pkcs7_t *this, x509_t *cacert); - - /** - * @brief Parse a PKCS#7 envelopedData content. - * - * @param this calling object - * @param serialNumber serialNumber of the request - * @param key RSA private key used to decrypt the symmetric key - * @return TRUE if parsing was successful - */ - bool (*parse_envelopedData) (pkcs7_t *this, chunk_t serialNumber, rsa_private_key_t *key); - - /** - * @brief Returns the parsed data object - * - * @param this calling object - * @return chunk containing the data object - */ - chunk_t (*get_data) (pkcs7_t *this); - - /** - * @brief Returns the a DER-encoded contentInfo object - * - * @param this calling object - * @return chunk containing the contentInfo object - */ - chunk_t (*get_contentInfo) (pkcs7_t *this); - - /** - * @brief Create an iterator for the certificates. - * - * @param this calling object - * @return iterator for the certificates - */ - iterator_t *(*create_certificate_iterator) (pkcs7_t *this); - - /** - * @brief Add a certificate. - * - * @param this calling object - * @param cert certificate to be included - */ - void (*set_certificate) (pkcs7_t *this, x509_t *cert); - - /** - * @brief Add authenticated attributes. - * - * @param this calling object - * @param attributes attributes to be included - */ - void (*set_attributes) (pkcs7_t *this, pkcs9_t *attributes); - - /** - * @brief Build a data object - * - * @param this PKCS#7 data to be built - * @return TRUE if build was successful - */ - bool (*build_data) (pkcs7_t *this); - - /** - * @brief Build an envelopedData object - * - * @param this PKCS#7 data object to envelop - * @param cert receivers's certificate - * @param alg encryption algorithm - * @return TRUE if build was successful - */ - bool (*build_envelopedData) (pkcs7_t *this, x509_t *cert, encryption_algorithm_t alg); - - /** - * @brief Build an signedData object - * - * @param this PKCS#7 data object to sign - * @param key signer's RSA private key - * @param alg digest algorithm used for signature - * @return TRUE if build was successful - */ - bool (*build_signedData) (pkcs7_t *this, rsa_private_key_t *key, hash_algorithm_t alg); - - /** - * @brief Destroys the contentInfo object. - * - * @param this PKCS#7 contentInfo object to destroy - */ - void (*destroy) (pkcs7_t *this); -}; - -/** - * @brief Read a PKCS#7 contentInfo object from a DER encoded chunk. - * - * @param chunk chunk containing DER encoded data - * @param level ASN.1 parsing start level - * @return created pkcs7_contentInfo object, or NULL if invalid. - * - * @ingroup crypto - */ -pkcs7_t *pkcs7_create_from_chunk(chunk_t chunk, u_int level); - -/** - * @brief Create a PKCS#7 contentInfo object - * - * @param chunk chunk containing data - * @return created pkcs7_contentInfo object. - * - * @ingroup crypto - */ -pkcs7_t *pkcs7_create_from_data(chunk_t data); - -/** - * @brief Read a X.509 certificate from a DER encoded file. - * - * @param filename file containing DER encoded data - * @param label label describing kind of PKCS#7 file - * @return created pkcs7_t object, or NULL if invalid. - * - * @ingroup crypto - */ -pkcs7_t *pkcs7_create_from_file(const char *filename, const char *label); - - -#endif /* _PKCS7_H */ diff --git a/src/libstrongswan/crypto/pkcs9.c b/src/libstrongswan/crypto/pkcs9.c index 1003c9011..1c1b5a586 100644 --- a/src/libstrongswan/crypto/pkcs9.c +++ b/src/libstrongswan/crypto/pkcs9.c @@ -1,13 +1,5 @@ -/** - * @file pkcs9.c - * - * @brief Implementation of pkcs9_t. - * - */ - /* * Copyright (C)2008 Andreas Steffen - * * Hochschule fuer Technik Rapperswil, Switzerland * * This program is free software; you can redistribute it and/or modify it @@ -20,7 +12,7 @@ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * - * RCSID $Id: pkcs7.c 3423 2008-01-22 10:32:37Z andreas $ + * $Id: pkcs9.c 3891 2008-04-28 16:00:52Z andreas $ */ #include <library.h> @@ -28,6 +20,7 @@ #include <asn1/oid.h> #include <asn1/asn1.h> +#include <asn1/asn1_parser.h> #include <utils/linked_list.h> #include "pkcs9.h" @@ -84,22 +77,6 @@ struct attribute_t { }; -/* ASN.1 definition of the X.501 atttribute type */ - -static const asn1Object_t attributesObjects[] = { - { 0, "attributes", ASN1_SET, ASN1_LOOP }, /* 0 */ - { 1, "attribute", ASN1_SEQUENCE, ASN1_NONE }, /* 1 */ - { 2, "type", ASN1_OID, ASN1_BODY }, /* 2 */ - { 2, "values", ASN1_SET, ASN1_LOOP }, /* 3 */ - { 3, "value", ASN1_EOC, ASN1_RAW }, /* 4 */ - { 2, "end loop", ASN1_EOC, ASN1_END }, /* 5 */ - { 0, "end loop", ASN1_EOC, ASN1_END }, /* 6 */ -}; - -#define ATTRIBUTE_OBJ_TYPE 2 -#define ATTRIBUTE_OBJ_VALUE 4 -#define ATTRIBUTE_OBJ_ROOF 7 - /** * PKCS#9 attribute type OIDs */ @@ -267,7 +244,7 @@ static void build_encoding(private_pkcs9_t *this) /* allocate memory for the attributes and build the encoding */ { - u_char *pos = build_asn1_object(&this->encoding, ASN1_SET, attributes_len); + u_char *pos = asn1_build_object(&this->encoding, ASN1_SET, attributes_len); iterator = this->attributes->create_iterator(this->attributes, TRUE); @@ -335,7 +312,8 @@ static chunk_t get_messageDigest(private_pkcs9_t *this) { return chunk_empty; } - if (!parse_asn1_simple_object(&value, asn1_attributeType(oid), 0, oid_names[oid].name)) + if (!asn1_parse_simple_object(&value, asn1_attributeType(oid), 0, + oid_names[oid].name)) { return chunk_empty; } @@ -398,29 +376,41 @@ pkcs9_t *pkcs9_create(void) } /** + * ASN.1 definition of the X.501 atttribute type + */ +static const asn1Object_t attributesObjects[] = { + { 0, "attributes", ASN1_SET, ASN1_LOOP }, /* 0 */ + { 1, "attribute", ASN1_SEQUENCE, ASN1_NONE }, /* 1 */ + { 2, "type", ASN1_OID, ASN1_BODY }, /* 2 */ + { 2, "values", ASN1_SET, ASN1_LOOP }, /* 3 */ + { 3, "value", ASN1_EOC, ASN1_RAW }, /* 4 */ + { 2, "end loop", ASN1_EOC, ASN1_END }, /* 5 */ + { 0, "end loop", ASN1_EOC, ASN1_END }, /* 6 */ + { 0, "exit", ASN1_EOC, ASN1_EXIT } +}; +#define ATTRIBUTE_OBJ_TYPE 2 +#define ATTRIBUTE_OBJ_VALUE 4 + +/** * Parse a PKCS#9 attribute list */ static bool parse_attributes(chunk_t chunk, int level0, private_pkcs9_t* this) { - asn1_ctx_t ctx; + asn1_parser_t *parser; chunk_t object; - u_int level; + int objectID; int oid = OID_UNKNOWN; - int objectID = 0; + bool success = FALSE; - asn1_init(&ctx, chunk, level0, FALSE, FALSE); + parser = asn1_parser_create(attributesObjects, chunk); + parser->set_top_level(parser, level0); - while (objectID < ATTRIBUTE_OBJ_ROOF) + while (parser->iterate(parser, &objectID, &object)) { - if (!extract_object(attributesObjects, &objectID, &object, &level, &ctx)) - { - return FALSE; - } - switch (objectID) { case ATTRIBUTE_OBJ_TYPE: - oid = known_oid(object); + oid = asn1_known_oid(object); break; case ATTRIBUTE_OBJ_VALUE: if (oid == OID_UNKNOWN) @@ -431,7 +421,8 @@ static bool parse_attributes(chunk_t chunk, int level0, private_pkcs9_t* this) { attribute_t *attribute = attribute_create(oid, object); - this->attributes->insert_last(this->attributes, (void*)attribute); + this->attributes->insert_last(this->attributes, + (void*)attribute); } /* parse known attributes */ { @@ -439,16 +430,21 @@ static bool parse_attributes(chunk_t chunk, int level0, private_pkcs9_t* this) if (type != ASN1_EOC) { - if (!parse_asn1_simple_object(&object, type, level+1, oid_names[oid].name)) + if (!asn1_parse_simple_object(&object, type, + parser->get_level(parser)+1, + oid_names[oid].name)) { - return FALSE; + goto end; } } } } - objectID++; } - return TRUE; + success = parser->success(parser); + +end: + parser->destroy(parser); + return success; } diff --git a/src/libstrongswan/crypto/pkcs9.h b/src/libstrongswan/crypto/pkcs9.h index 44915720c..89cdec83d 100644 --- a/src/libstrongswan/crypto/pkcs9.h +++ b/src/libstrongswan/crypto/pkcs9.h @@ -1,13 +1,5 @@ -/** - * @file pkcs7.h - * - * @brief Interface of pkcs9_t. - * - */ - /* - * Copyright (C) 2008 Andreas Steffen - * + * Copyright (C) 2008 Andreas Steffen * Hochschule fuer Technik Rapperswil, Switzerland * * This program is free software; you can redistribute it and/or modify it @@ -20,102 +12,89 @@ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * - * RCSID $Id: pkcs7.h 3423 2008-01-22 10:32:37Z andreas $ + * $Id: pkcs9.h 3589 2008-03-13 14:14:44Z martin $ + */ + +/** + * @defgroup pkcs9 pkcs9 + * @{ @ingroup crypto */ -#ifndef _PKCS9_H -#define _PKCS9_H +#ifndef PKCS9_H_ +#define PKCS9_H_ typedef struct pkcs9_t pkcs9_t; #include <library.h> /** - * @brief PKCS#9 . - * - * @b Constructors: - * -pkcs9_create_from_chunk() - * -pkcs9_create() - * - * @ingroup crypto + * PKCS#9 attributes. */ struct pkcs9_t { + /** - * @brief generate ASN.1 encoding of attribute list - * - * @param this PKCS#9 attribute list to be encoded + * Generate ASN.1 encoding of attribute list */ void (*build_encoding) (pkcs9_t *this); /** - * @brief gets ASN.1 encoding of PKCS#9 attribute list + * Gets ASN.1 encoding of PKCS#9 attribute list * - * @param this calling object * @return ASN.1 encoded PKCSI#9 list */ chunk_t (*get_encoding) (pkcs9_t *this); /** - * @brief gets a PKCS#9 attribute + * Gets a PKCS#9 attribute * - * @param this calling object * @param oid OID of the attribute * @return ASN.1 encoded value of the attribute */ chunk_t (*get_attribute) (pkcs9_t *this, int oid); /** - * @brief adds a PKCS#9 attribute + * Adds a PKCS#9 attribute * - * @param this calling object * @param oid OID of the attribute * @param value ASN.1 encoded value of the attribute */ void (*set_attribute) (pkcs9_t *this, int oid, chunk_t value); /** - * @brief gets a PKCS#9 messageDigest attribute + * Gets a PKCS#9 messageDigest attribute * - * @param this calling object * @return messageDigest */ chunk_t (*get_messageDigest) (pkcs9_t *this); /** - * @brief add a PKCS#9 messageDigest attribute + * Add a PKCS#9 messageDigest attribute * - * @param this calling object * @param value messageDigest */ void (*set_messageDigest) (pkcs9_t *this, chunk_t value); /** - * @brief Destroys the PKCS#9 attribute list. - * - * @param this PKCS#9 attribute list to destroy + * Destroys the PKCS#9 attribute list. */ void (*destroy) (pkcs9_t *this); }; /** - * @brief Read a PKCS#9 attribute list from a DER encoded chunk. + * Read a PKCS#9 attribute list from a DER encoded chunk. * * @param chunk chunk containing DER encoded data * @param level ASN.1 parsing start level * @return created pkcs9 attribute list, or NULL if invalid. - * - * @ingroup crypto */ pkcs9_t *pkcs9_create_from_chunk(chunk_t chunk, u_int level); /** - * @brief Create an empty PKCS#9 attribute list + * Create an empty PKCS#9 attribute list * * @param chunk chunk containing data * @return created pkcs9 attribute list. - * - * @ingroup crypto */ pkcs9_t *pkcs9_create(void); -#endif /* _PKCS9_H */ +#endif /* PKCS9_H_ @} */ diff --git a/src/libstrongswan/crypto/prf_plus.c b/src/libstrongswan/crypto/prf_plus.c index 6bd444b1f..de7dbff84 100644 --- a/src/libstrongswan/crypto/prf_plus.c +++ b/src/libstrongswan/crypto/prf_plus.c @@ -1,10 +1,3 @@ -/** - * @file prf_plus.c - * - * @brief Implementation of prf_plus_t. - * - */ - /* * Copyright (C) 2005-2006 Martin Willi * Copyright (C) 2005 Jan Hutter @@ -19,6 +12,8 @@ * 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: prf_plus.c 3589 2008-03-13 14:14:44Z martin $ */ #include <string.h> diff --git a/src/libstrongswan/crypto/prf_plus.h b/src/libstrongswan/crypto/prf_plus.h index 90f9ce2eb..e63827858 100644 --- a/src/libstrongswan/crypto/prf_plus.h +++ b/src/libstrongswan/crypto/prf_plus.h @@ -1,10 +1,3 @@ -/** - * @file prf_plus.h - * - * @brief Interface for prf_plus.h. - * - */ - /* * Copyright (C) 2005-2006 Martin Willi * Copyright (C) 2005 Jan Hutter @@ -19,6 +12,13 @@ * 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: prf_plus.h 3589 2008-03-13 14:14:44Z martin $ + */ + +/** + * @defgroup prf_plus prf_plus + * @{ @ingroup crypto */ #ifndef PRF_PLUS_H_ @@ -29,53 +29,43 @@ typedef struct prf_plus_t prf_plus_t; #include <crypto/prfs/prf.h> /** - * @brief Implementation of the prf+ function described in IKEv2 RFC. + * Implementation of the prf+ function described in IKEv2 RFC. * * This class implements the prf+ algorithm. Internally it uses a pseudo random * function, which implements the prf_t interface. - * * See IKEv2 RFC 2.13. - * - * @b Constructors: - * - prf_plus_create() - * - * @ingroup transforms */ struct prf_plus_t { /** - * @brief Get pseudo random bytes. + * Get pseudo random bytes. * * Get the next few bytes of the prf+ output. Space * must be allocated by the caller. * - * @param this calling object - * @param length number of bytes to get - * @param[out] buffer pointer where the generated bytes will be written + * @param length number of bytes to get + * @param buffer pointer where the generated bytes will be written */ void (*get_bytes) (prf_plus_t *this, size_t length, u_int8_t *buffer); /** - * @brief Allocate pseudo random bytes. + * Allocate pseudo random bytes. * * Get the next few bytes of the prf+ output. This function * will allocate the required space. * - * @param this calling object - * @param length number of bytes to get - * @param[out] chunk chunk which will hold generated bytes + * @param length number of bytes to get + * @param chunk chunk which will hold generated bytes */ void (*allocate_bytes) (prf_plus_t *this, size_t length, chunk_t *chunk); /** - * @brief Destroys a prf_plus_t object. - * - * @param this calling object + * Destroys a prf_plus_t object. */ void (*destroy) (prf_plus_t *this); }; /** - * @brief Creates a new prf_plus_t object. + * Creates a new prf_plus_t object. * * Seed will be cloned. prf will * not be cloned, must be destroyed outside after @@ -84,9 +74,7 @@ struct prf_plus_t { * @param prf prf object to use * @param seed input seed for prf * @return prf_plus_t object - * - * @ingroup transforms */ prf_plus_t *prf_plus_create(prf_t *prf, chunk_t seed); -#endif /*PRF_PLUS_H_*/ +#endif /*PRF_PLUS_H_ @} */ diff --git a/src/libstrongswan/crypto/prfs/prf.c b/src/libstrongswan/crypto/prfs/prf.c index f803829af..812f6278d 100644 --- a/src/libstrongswan/crypto/prfs/prf.c +++ b/src/libstrongswan/crypto/prfs/prf.c @@ -1,10 +1,3 @@ -/** - * @file prf.c - * - * @brief Generic constructor for all prf_t - * - */ - /* * Copyright (C) 2005-2006 Martin Willi * Copyright (C) 2005 Jan Hutter @@ -19,20 +12,18 @@ * 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: prf.c 3619 2008-03-19 14:02:52Z martin $ */ - #include "prf.h" -#include <crypto/hashers/hasher.h> -#include <crypto/prfs/hmac_prf.h> -#include <crypto/prfs/fips_prf.h> - -ENUM_BEGIN(pseudo_random_function_names, PRF_UNDEFINED, PRF_FIPS_DES, +ENUM_BEGIN(pseudo_random_function_names, PRF_UNDEFINED, PRF_KEYED_SHA1, "PRF_UNDEFINED", "PRF_FIPS_SHA1_160", - "PRF_FIPS_DES"); -ENUM_NEXT(pseudo_random_function_names, PRF_HMAC_MD5, PRF_HMAC_SHA2_512, PRF_FIPS_DES, + "PRF_FIPS_DES", + "PRF_KEYED_SHA1"); +ENUM_NEXT(pseudo_random_function_names, PRF_HMAC_MD5, PRF_HMAC_SHA2_512, PRF_KEYED_SHA1, "PRF_HMAC_MD5", "PRF_HMAC_SHA1", "PRF_HMAC_TIGER", @@ -42,29 +33,3 @@ ENUM_NEXT(pseudo_random_function_names, PRF_HMAC_MD5, PRF_HMAC_SHA2_512, PRF_FIP "PRF_HMAC_SHA2_512"); ENUM_END(pseudo_random_function_names, PRF_HMAC_SHA2_512); -/* - * Described in header. - */ -prf_t *prf_create(pseudo_random_function_t pseudo_random_function) -{ - switch (pseudo_random_function) - { - case PRF_HMAC_SHA1: - return (prf_t*)hmac_prf_create(HASH_SHA1); - case PRF_HMAC_MD5: - return (prf_t*)hmac_prf_create(HASH_MD5); - case PRF_HMAC_SHA2_256: - return (prf_t*)hmac_prf_create(HASH_SHA256); - case PRF_HMAC_SHA2_384: - return (prf_t*)hmac_prf_create(HASH_SHA384); - case PRF_HMAC_SHA2_512: - return (prf_t*)hmac_prf_create(HASH_SHA512); - case PRF_FIPS_SHA1_160: - return (prf_t*)fips_prf_create(20, g_sha1); - case PRF_FIPS_DES: - case PRF_HMAC_TIGER: - case PRF_AES128_CBC: - default: - return NULL; - } -} diff --git a/src/libstrongswan/crypto/prfs/prf.h b/src/libstrongswan/crypto/prfs/prf.h index 8560a4a9c..324eb89b4 100644 --- a/src/libstrongswan/crypto/prfs/prf.h +++ b/src/libstrongswan/crypto/prfs/prf.h @@ -1,10 +1,3 @@ -/** - * @file prf.h - * - * @brief Interface prf_t. - * - */ - /* * Copyright (C) 2005-2006 Martin Willi * Copyright (C) 2005 Jan Hutter @@ -19,6 +12,13 @@ * 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: prf.h 3916 2008-05-08 12:43:27Z martin $ + */ + +/** + * @defgroup prf prf + * @{ @ingroup crypto */ #ifndef PRF_H_ @@ -30,12 +30,10 @@ typedef struct prf_t prf_t; #include <library.h> /** - * @brief Pseudo random function, as in IKEv2 RFC 3.3.2. + * Pseudo random function, as in IKEv2 RFC 3.3.2. * * PRF algorithms not defined in IKEv2 are allocated in "private use" * space. - * - * @ingroup prfs */ enum pseudo_random_function_t { PRF_UNDEFINED = 1024, @@ -44,7 +42,7 @@ enum pseudo_random_function_t { /** Implemented via hmac_prf_t. */ PRF_HMAC_SHA1 = 2, PRF_HMAC_TIGER = 3, - PRF_AES128_CBC = 4, + PRF_AES128_XCBC = 4, /** Implemented via hmac_prf_t. */ PRF_HMAC_SHA2_256 = 5, /** Implemented via hmac_prf_t. */ @@ -55,6 +53,11 @@ enum pseudo_random_function_t { PRF_FIPS_SHA1_160 = 1025, /** Could be implemented via fips_prf_t, uses fixed output size of 160bit */ PRF_FIPS_DES = 1026, + /** + * Keyed hash algorithm using SHA1, used in EAP-AKA: + * This PRF uses SHA1, but XORs the key into the IV. No "Final()" operation + * is applied to the SHA1 state. */ + PRF_KEYED_SHA1 = 1027, }; /** @@ -63,80 +66,53 @@ enum pseudo_random_function_t { extern enum_name_t *pseudo_random_function_names; /** - * @brief Generic interface for pseudo-random-functions. - * - * @b Constructors: - * - prf_create() - * - hmac_prf_create() - * - * @todo Implement more prf algorithms - * - * @ingroup prfs + * Generic interface for pseudo-random-functions. */ struct prf_t { /** - * @brief Generates pseudo random bytes and writes them in the buffer. + * Generates pseudo random bytes and writes them in the buffer. * - * @param this calling object - * @param seed a chunk containing the seed for the next bytes - * @param[out] buffer pointer where the generated bytes will be written + * @param seed a chunk containing the seed for the next bytes + * @param buffer pointer where the generated bytes will be written */ void (*get_bytes) (prf_t *this, chunk_t seed, u_int8_t *buffer); /** - * @brief Generates pseudo random bytes and allocate space for them. + * Generates pseudo random bytes and allocate space for them. * - * @param this calling object - * @param seed a chunk containing the seed for the next bytes - * @param[out] chunk chunk which will hold generated bytes + * @param seed a chunk containing the seed for the next bytes + * @param chunk chunk which will hold generated bytes */ void (*allocate_bytes) (prf_t *this, chunk_t seed, chunk_t *chunk); /** - * @brief Get the block size of this prf_t object. + * Get the block size of this prf_t object. * - * @param this calling object - * @return block size in bytes + * @return block size in bytes */ size_t (*get_block_size) (prf_t *this); /** - * @brief Get the key size of this prf_t object. + * Get the key size of this prf_t object. * * This is a suggestion only, all implemented PRFs accept variable key * length. * - * @param this calling object - * @return key size in bytes + * @return key size in bytes */ size_t (*get_key_size) (prf_t *this); /** - * @brief Set the key for this prf_t object. + * Set the key for this prf_t object. * - * @param this calling object - * @param key key to set + * @param key key to set */ void (*set_key) (prf_t *this, chunk_t key); /** - * @brief Destroys a prf object. - * - * @param this calling object + * Destroys a prf object. */ void (*destroy) (prf_t *this); }; -/** - * @brief Generic constructor for a prf_t oject. - * - * @param pseudo_random_function Algorithm to use - * @return - * - prf_t object - * - NULL if prf algorithm not supported - * - * @ingroup prfs - */ -prf_t *prf_create(pseudo_random_function_t pseudo_random_function); - -#endif /*PRF_H_*/ +#endif /*PRF_H_ @} */ diff --git a/src/libstrongswan/crypto/rngs/rng.c b/src/libstrongswan/crypto/rngs/rng.c new file mode 100644 index 000000000..435e043e8 --- /dev/null +++ b/src/libstrongswan/crypto/rngs/rng.c @@ -0,0 +1,24 @@ +/* + * 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 "rng.h" + +ENUM(rng_quality_names, RNG_WEAK, RNG_REAL, + "RNG_WEAK", + "RNG_STRONG", + "RNG_REAL", +); diff --git a/src/libstrongswan/crypto/rngs/rng.h b/src/libstrongswan/crypto/rngs/rng.h new file mode 100644 index 000000000..08f7af209 --- /dev/null +++ b/src/libstrongswan/crypto/rngs/rng.h @@ -0,0 +1,75 @@ +/* + * 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: rng.h 3619 2008-03-19 14:02:52Z martin $ + */ + +/** + * @defgroup rng rng + * @{ @ingroup crypto + */ + +#ifndef RNG_H_ +#define RNG_H_ + +typedef enum rng_quality_t rng_quality_t; +typedef struct rng_t rng_t; + +#include <library.h> + +/** + * Quality of generated random bytes. + */ +enum rng_quality_t { + /** weak randomness, usable for nonces, IVs */ + RNG_WEAK, + /** stronger randomness, usable for session keys */ + RNG_STRONG, + /** real random, key material */ + RNG_REAL, +}; + +/** + * enum name for rng_quality_t. + */ +extern enum_name_t *rng_quality_names; + +/** + * Generic interface for random number generators. + */ +struct rng_t { + + /** + * Generates random bytes and writes them in the buffer. + * + * @param len number of bytes to get + * @param buffer pointer where the generated bytes will be written + */ + void (*get_bytes) (rng_t *this, u_int len, u_int8_t *buffer); + + /** + * Generates random bytes and allocate space for them. + * + * @param len number of bytes to get + * @param chunk chunk which will hold generated bytes + */ + void (*allocate_bytes) (rng_t *this, u_int len, chunk_t *chunk); + + /** + * Destroys a rng object. + */ + void (*destroy) (rng_t *this); +}; + +#endif /*RNG_H_ @} */ diff --git a/src/libstrongswan/crypto/rsa/rsa_private_key.c b/src/libstrongswan/crypto/rsa/rsa_private_key.c deleted file mode 100644 index 1b1499887..000000000 --- a/src/libstrongswan/crypto/rsa/rsa_private_key.c +++ /dev/null @@ -1,722 +0,0 @@ -/** - * @file rsa_private_key.c - * - * @brief Implementation of rsa_private_key_t. - * - */ - -/* - * Copyright (C) 2005 Jan Hutter - * Copyright (C) 2005-2006 Martin Willi - * Copyright (C) 2007-2008 Andreas Steffen - * - * Hochschule fuer Technik Rapperswil - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * for more details. - * - * RCSID $Id: rsa_private_key.c 3429 2008-01-27 20:59:22Z andreas $ - */ - -#include <gmp.h> -#include <sys/stat.h> -#include <unistd.h> -#include <string.h> - -#include "rsa_public_key.h" -#include "rsa_private_key.h" - -#include <debug.h> -#include <asn1/asn1.h> -#include <asn1/pem.h> -#include <utils/randomizer.h> - -/** - * defined in rsa_public_key.c - */ -extern chunk_t rsa_public_key_info_to_asn1(const mpz_t n, const mpz_t e); -extern chunk_t rsa_public_key_id_create(const mpz_t n, const mpz_t e); - -/** - * Public exponent to use for key generation. - */ -#define PUBLIC_EXPONENT 0x10001 - -typedef struct private_rsa_private_key_t private_rsa_private_key_t; - -/** - * Private data of a rsa_private_key_t object. - */ -struct private_rsa_private_key_t { - /** - * Public interface for this signer. - */ - 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 publicKeyInfo object - */ - chunk_t keyid; - - /** - * @brief Implements the RSADP algorithm specified in PKCS#1. - * - * @param this calling object - * @param data data to process - * @return processed data - */ - chunk_t (*rsadp) (private_rsa_private_key_t *this, chunk_t data); - - /** - * @brief Implements the RSASP1 algorithm specified in PKCS#1. - * @param this calling object - * @param data data to process - * @return processed data - */ - chunk_t (*rsasp1) (private_rsa_private_key_t *this, chunk_t data); -}; - -/* ASN.1 definition of a PKCS#1 RSA private key */ -static const asn1Object_t privkey_objects[] = { - { 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 */ -}; - -#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 -#define PRIV_KEY_ROOF 16 - -/** - * Auxiliary function overwriting private key material with - * pseudo-random bytes before releasing it - */ -static void mpz_clear_randomized(mpz_t z) -{ - size_t len = mpz_size(z) * GMP_LIMB_BITS / BITS_PER_BYTE; - u_int8_t *random_bytes = alloca(len); - - randomizer_t *randomizer = randomizer_create(); - - randomizer->get_pseudo_random_bytes(randomizer, len, random_bytes); - - /* overwrite mpz_t with pseudo-random bytes before clearing it */ - mpz_import(z, len, 1, 1, 1, 0, random_bytes); - mpz_clear(z); - - randomizer->destroy(randomizer); -} - -/** - * Generate a random prime number with prime_len bytes - */ -static status_t compute_prime(private_rsa_private_key_t *this, size_t prime_len, mpz_t *prime) -{ - randomizer_t *randomizer; - chunk_t random_bytes; - status_t status; - - randomizer = randomizer_create(); - mpz_init(*prime); - - do - { - DBG1(" generating %d bit prime from %s ...", BITS_PER_BYTE * prime_len, DEV_RANDOM); - status = randomizer->allocate_random_bytes(randomizer, prime_len, &random_bytes); - if (status != SUCCESS) - { - randomizer->destroy(randomizer); - mpz_clear(*prime); - return FAILED; - } - - /* make sure most significant bit is set */ - random_bytes.ptr[0] = random_bytes.ptr[0] | 0x80; - - /* convert chunk to mpz value */ - mpz_import(*prime, random_bytes.len, 1, 1, 1, 0, random_bytes.ptr); - - /* get next prime */ - mpz_nextprime (*prime, *prime); - - /* free the random_bytes after overwriting them with a pseudo-random sequence */ - chunk_free_randomized(&random_bytes); - } - /* check if it isnt too large */ - while (((mpz_sizeinbase(*prime, 2) + 7) / BITS_PER_BYTE) > prime_len); - - randomizer->destroy(randomizer); - return SUCCESS; -} - -/** - * Implementation of private_rsa_private_key_t.rsadp and private_rsa_private_key_t.rsasp1. - */ -static chunk_t rsadp(private_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; -} - -/** - * Implementation of rsa_private_key_t.pkcs1_decrypt. - */ -static status_t pkcs1_decrypt(private_rsa_private_key_t *this, - chunk_t in, chunk_t *out) -{ - status_t status = FAILED; - chunk_t em, em_ori; - - /* decrypt the input data */ - em = em_ori = this->rsadp(this, in); - - /* PKCS#1 v1.5 EME encryption formatting - * EM = 00 || 02 || PS || 00 || M - * PS = pseudo-random nonzero octets - */ - - /* check for magic bytes */ - if (*(em.ptr) != 0x00 || *(em.ptr+1) != 0x02) - { - DBG1("incorrect padding - probably wrong RSA key"); - goto end; - } - em.ptr += 2; - em.len -= 2; - - /* the plaintext data starts after first 0x00 byte */ - while (em.len-- > 0 && *em.ptr++ != 0x00); - - if (em.len == 0) - { - DBG1("no plaintext data found"); - goto end; - } - - *out = chunk_clone(em); - status = SUCCESS; - -end: - free(em_ori.ptr); - return status; -} - -/** - * Implementation of rsa_private_key_t.build_emsa_pkcs1_signature. - */ -static status_t build_emsa_pkcs1_signature(private_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 NOT_SUPPORTED; - } - - /* get hasher */ - hasher = hasher_create(hash_algorithm); - if (hasher == NULL) - { - return NOT_SUPPORTED; - } - - /* 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 = this->rsasp1(this, em); - - free(digestInfo.ptr); - free(em.ptr); - - return SUCCESS; -} - -/** - * Implementation of rsa_private_key_t.pkcs1_write. - */ -static bool pkcs1_write(private_rsa_private_key_t *this, const char *filename, bool force) -{ - bool status; - - chunk_t pkcs1 = asn1_wrap(ASN1_SEQUENCE, "cmmmmmmmm", - ASN1_INTEGER_0, - asn1_integer_from_mpz(this->n), - asn1_integer_from_mpz(this->e), - asn1_integer_from_mpz(this->d), - asn1_integer_from_mpz(this->p), - asn1_integer_from_mpz(this->q), - asn1_integer_from_mpz(this->exp1), - asn1_integer_from_mpz(this->exp2), - asn1_integer_from_mpz(this->coeff)); - - status = chunk_write(pkcs1, filename, "pkcs1", 0066, force); - chunk_free_randomized(&pkcs1); - return status; -} - -/** - * Implementation of rsa_private_key_t.get_public_key. - */ -rsa_public_key_t *get_public_key(private_rsa_private_key_t *this) -{ - return rsa_public_key_create(this->n, this->e); -} - -/** - * Implementation of rsa_private_key.belongs_to. - */ -static bool belongs_to(private_rsa_private_key_t *this, rsa_public_key_t *public) -{ - return chunk_equals(this->keyid, public->get_keyid(public)); -} - -/** - * Check the loaded key if it is valid and usable - * TODO: Log errors - */ -static status_t check(private_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 / BITS_PER_BYTE) - { - return FAILED; - } - - /* we picked a max modulus size to simplify buffer allocation */ - if (this->k > 8192 / BITS_PER_BYTE) - { - 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); - return status; -} - -/** - * Implementation of rsa_private_key.destroy. - */ -static void destroy(private_rsa_private_key_t *this) -{ - 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); - chunk_free_randomized(&this->keyid); - free(this); -} - -/** - * Internal generic constructor - */ -static private_rsa_private_key_t *rsa_private_key_create_empty(void) -{ - private_rsa_private_key_t *this = malloc_thing(private_rsa_private_key_t); - - /* public functions */ - this->public.pkcs1_decrypt = (status_t (*) (rsa_private_key_t*,chunk_t,chunk_t*))pkcs1_decrypt; - this->public.build_emsa_pkcs1_signature = (status_t (*) (rsa_private_key_t*,hash_algorithm_t,chunk_t,chunk_t*))build_emsa_pkcs1_signature; - this->public.pkcs1_write = (bool (*) (rsa_private_key_t*,const char*,bool))pkcs1_write; - this->public.get_public_key = (rsa_public_key_t* (*) (rsa_private_key_t*))get_public_key; - this->public.belongs_to = (bool (*) (rsa_private_key_t*,rsa_public_key_t*))belongs_to; - this->public.destroy = (void (*) (rsa_private_key_t*))destroy; - - /* private functions */ - this->rsadp = rsadp; - this->rsasp1 = rsadp; /* same algorithm */ - - this->keyid = chunk_empty; - - return this; -} - -/* - * See header - */ -rsa_private_key_t *rsa_private_key_create(size_t key_size) -{ - mpz_t p, q, n, e, d, exp1, exp2, coeff; - mpz_t m, q1, t; - private_rsa_private_key_t *this; - size_t key_len = key_size / BITS_PER_BYTE; - size_t prime_len = key_len / 2; - - /* Get values of primes p and q */ - if (compute_prime(this, prime_len, &p) != SUCCESS) - { - return NULL; - } - if (compute_prime(this, prime_len, &q) != SUCCESS) - { - mpz_clear(p); - 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) (greatest common divisor) */ - - 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); - - /* determine exact the modulus size in bits */ - key_size = mpz_sizeinbase(n, 2); - - /* create and fill in rsa_private_key_t object */ - this = rsa_private_key_create_empty(); - this->k = (key_size + 7) / BITS_PER_BYTE; - this->keyid = rsa_public_key_id_create(n, e); - *(this->p) = *p; - *(this->q) = *q; - *(this->n) = *n; - *(this->e) = *e; - *(this->d) = *d; - *(this->exp1) = *exp1; - *(this->exp2) = *exp2; - *(this->coeff) = *coeff; - DBG1("generated %d bit RSA key with keyid: %#B", key_size, &this->keyid); - - return &this->public; -} - -/* - * see header - */ -rsa_private_key_t *rsa_private_key_create_from_chunk(chunk_t blob) -{ - asn1_ctx_t ctx; - chunk_t object; - u_int level; - int objectID = 0; - private_rsa_private_key_t *this; - - this = 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); - - asn1_init(&ctx, blob, 0, FALSE, TRUE); - - while (objectID < PRIV_KEY_ROOF) - { - if (!extract_object(privkey_objects, &objectID, &object, &level, &ctx)) - { - destroy(this); - return FALSE; - } - switch (objectID) - { - case PRIV_KEY_VERSION: - if (object.len > 0 && *object.ptr != 0) - { - destroy(this); - return NULL; - } - 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; - } - objectID++; - } - - this->k = (mpz_sizeinbase(this->n, 2) + 7) / BITS_PER_BYTE; - this->keyid = rsa_public_key_id_create(this->n, this->e); - - if (check(this) != SUCCESS) - { - destroy(this); - return NULL; - } - else - { - return &this->public; - } -} - -/* - * see header - */ -rsa_private_key_t *rsa_private_key_create_from_file(char *filename, chunk_t *passphrase) -{ - bool pgp = FALSE; - chunk_t chunk = chunk_empty; - rsa_private_key_t *key = NULL; - - if (!pem_asn1_load_file(filename, passphrase, "private key", &chunk, &pgp)) - return NULL; - - key = rsa_private_key_create_from_chunk(chunk); - chunk_free_randomized(&chunk); - return key; -} diff --git a/src/libstrongswan/crypto/rsa/rsa_private_key.h b/src/libstrongswan/crypto/rsa/rsa_private_key.h deleted file mode 100644 index 8013f03c2..000000000 --- a/src/libstrongswan/crypto/rsa/rsa_private_key.h +++ /dev/null @@ -1,163 +0,0 @@ -/** - * @file rsa_private_key.h - * - * @brief Interface of rsa_private_key_t. - * - */ - -/* - * Copyright (C) 2005 Jan Hutter - * Copyright (C) 2005-2006 Martin Willi - * Copyright (C) 2007-2008 Andreas Steffen - * - * Hochschule fuer Technik Rapperswil - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * for more details. - * - * RCSID $Id: rsa_private_key.h 3423 2008-01-22 10:32:37Z andreas $ - */ - -#ifndef RSA_PRIVATE_KEY_H_ -#define RSA_PRIVATE_KEY_H_ - -typedef struct rsa_private_key_t rsa_private_key_t; - -#include <library.h> -#include <crypto/rsa/rsa_public_key.h> -#include <crypto/hashers/hasher.h> - -/** - * @brief RSA private key with associated functions. - * - * Currently only supports signing using EMSA encoding. - * - * @b Constructors: - * - rsa_private_key_create() - * - rsa_private_key_create_from_chunk() - * - rsa_private_key_create_from_file() - * - * @see rsa_public_key_t - * - * @ingroup rsa - */ -struct rsa_private_key_t { - - /** - * @brief Decrypt a data block based on EME-PKCS1 encoding. - * - * - * @param this calling object - * @param data encrypted input data - * @param out decrypted output data - * @return - * - SUCCESS - * - FAILED if padding is not correct - */ - status_t (*pkcs1_decrypt) (rsa_private_key_t *this, chunk_t in, chunk_t *out); - - /** - * @brief Build a signature over a chunk using EMSA-PKCS1 encoding. - * - * This signature creates a hash using the specified hash algorithm, concatenates - * it with an ASN1-OID of the hash algorithm and runs the RSASP1 function - * on it. - * - * @param this calling object - * @param hash_algorithm hash algorithm to use for hashing - * @param data data to sign - * @param[out] signature allocated signature - * @return - * - SUCCESS - * - INVALID_STATE, if key not set - * - NOT_SUPPORTED, if hash algorithm not supported - */ - status_t (*build_emsa_pkcs1_signature) (rsa_private_key_t *this, hash_algorithm_t hash_algorithm, chunk_t data, chunk_t *signature); - - /** - * @brief Writes an RSA private key to a file in PKCS#1 format. - * - * @param this calling object - * @param filename file to which the key should be written. - * @param force if TRUE overwrite existing file - * @return TRUE if successful - FALSE otherwise - */ - bool (*pkcs1_write) (rsa_private_key_t *this, const char *filename, bool force); - - /** - * @brief Create a rsa_public_key_t with the public part of the key. - * - * @param this calling object - * @return public_key - */ - rsa_public_key_t *(*get_public_key) (rsa_private_key_t *this); - - /** - * @brief Check if a private key belongs to a public key. - * - * Compares the public part of the private key with the - * public key, return TRUE if it equals. - * - * @param this private key - * @param public public key - * @return TRUE, if keys belong together - */ - bool (*belongs_to) (rsa_private_key_t *this, rsa_public_key_t *public); - - /** - * @brief Destroys the private key. - * - * @param this private key to destroy - */ - void (*destroy) (rsa_private_key_t *this); -}; - -/** - * @brief Generate a new RSA key with specified key length. - * - * @param key_size size of the key in bits - * @return generated rsa_private_key_t. - * - * @ingroup rsa - */ -rsa_private_key_t *rsa_private_key_create(size_t key_size); - -/** - * @brief Load an RSA private key from a chunk. - * - * Load a key from a chunk, encoded as described in PKCS#1 - * (ASN1 DER encoded). - * - * @param chunk chunk containing the DER encoded key - * @return loaded rsa_private_key_t, or NULL - * - * @ingroup rsa - */ -rsa_private_key_t *rsa_private_key_create_from_chunk(chunk_t chunk); - -/** - * @brief Load an RSA private key from a file. - * - * Load a key from a file, which is either in a unencrypted binary - * format (DER), or in a (encrypted) PEM format. The supplied - * passphrase is used to decrypt an ecrypted key. - * - * @param filename filename which holds the key - * @param passphrase optional passphase for decryption, can be NULL - * @return loaded rsa_private_key_t, or NULL - * - * @todo Implement PEM file loading - * @todo Implement key decryption - * - * @ingroup rsa - */ -rsa_private_key_t *rsa_private_key_create_from_file(char *filename, chunk_t *passphrase); - -#endif /*RSA_PRIVATE_KEY_H_*/ diff --git a/src/libstrongswan/crypto/rsa/rsa_public_key.c b/src/libstrongswan/crypto/rsa/rsa_public_key.c deleted file mode 100644 index 10af0527e..000000000 --- a/src/libstrongswan/crypto/rsa/rsa_public_key.c +++ /dev/null @@ -1,516 +0,0 @@ -/** - * @file rsa_public_key.c - * - * @brief Implementation of rsa_public_key_t. - * - */ - -/* - * Copyright (C) 2005 Jan Hutter - * Copyright (C) 2005-2006 Martin Willi - * Copyright (C) 2007-2008 Andreas Steffen - * - * Hochschule fuer Technik Rapperswil - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * for more details. - * - * RCSID $Id: rsa_public_key.c 3428 2008-01-27 20:58:52Z andreas $ - */ - -#include <gmp.h> -#include <sys/stat.h> -#include <unistd.h> -#include <stdio.h> -#include <string.h> - -#include "rsa_public_key.h" - -#include <debug.h> -#include <utils/randomizer.h> -#include <crypto/hashers/hasher.h> -#include <asn1/asn1.h> -#include <asn1/pem.h> - -/* 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 */ -}; - -#define PUB_KEY_RSA_PUBLIC_KEY 0 -#define PUB_KEY_MODULUS 1 -#define PUB_KEY_EXPONENT 2 -#define PUB_KEY_ROOF 3 - -/* 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 */ -}; - -#define DIGEST_INFO 0 -#define DIGEST_INFO_ALGORITHM 1 -#define DIGEST_INFO_DIGEST 2 -#define DIGEST_INFO_ROOF 3 - -typedef struct private_rsa_public_key_t private_rsa_public_key_t; - -/** - * Private data structure with signing context. - */ -struct private_rsa_public_key_t { - /** - * Public interface for this signer. - */ - 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 - */ - chunk_t keyid; - - /** - * @brief Implements the RSAEP algorithm specified in PKCS#1. - * - * @param this calling object - * @param data data to process - * @return processed data - */ - chunk_t (*rsaep) (const private_rsa_public_key_t *this, chunk_t data); - - /** - * @brief Implements the RSASVP1 algorithm specified in PKCS#1. - * - * @param this calling object - * @param data data to process - * @return processed data - */ - chunk_t (*rsavp1) (const private_rsa_public_key_t *this, chunk_t data); -}; - -/** - * Implementation of private_rsa_public_key_t.rsaep and private_rsa_public_key_t.rsavp1 - */ -static chunk_t rsaep(const private_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; -} - -/** - * Implementation of rsa_public_key_t.eme_pkcs1_encrypt. - */ -static status_t pkcs1_encrypt(private_rsa_public_key_t *this, - chunk_t in, chunk_t *out) -{ - chunk_t em; - u_char *pos; - int padding = this->k - in.len - 3; - - if (padding < 8) - { - DBG1("rsa padding of %d bytes is too small", padding); - return FAILED; - } - em.len = this->k; - em.ptr = pos = malloc(em.len); - - /* add padding according to PKCS#1 7.2.1 1.+2. */ - *pos++ = 0x00; - *pos++ = 0x02; - - /* pad with pseudo random bytes unequal to zero */ - { - randomizer_t *randomizer = randomizer_create(); - - /* pad with pseudo random bytes unequal to zero */ - while (padding--) - { - randomizer->get_pseudo_random_bytes(randomizer, 1, pos); - while (!*pos) - { - randomizer->get_pseudo_random_bytes(randomizer, 1, pos); - } - pos++; - } - randomizer->destroy(randomizer); - } - - /* append the padding terminator */ - *pos++ = 0x00; - - /* now add the data */ - memcpy(pos, in.ptr, in.len); - *out = this->rsaep(this, em); - free(em.ptr); - return SUCCESS; -} - -/** - * Implementation of rsa_public_key.verify_emsa_pkcs1_signature. - */ -static status_t verify_emsa_pkcs1_signature(const private_rsa_public_key_t *this, - hash_algorithm_t algorithm, - chunk_t data, chunk_t signature) -{ - chunk_t em_ori, em; - status_t res = FAILED; - - /* 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 = this->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) - { - DBG2("incorrect padding - probably wrong RSA key"); - 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_ctx_t ctx; - chunk_t object; - u_int level; - int objectID = 0; - hash_algorithm_t hash_algorithm = HASH_UNKNOWN; - - asn1_init(&ctx, em, 0, FALSE, FALSE); - - while (objectID < DIGEST_INFO_ROOF) - { - if (!extract_object(digestInfoObjects, &objectID, &object, &level, &ctx)) - { - goto end; - } - 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; - } - break; - case DIGEST_INFO_ALGORITHM: - { - int hash_oid = parse_algorithmIdentifier(object, level+1, NULL); - - hash_algorithm = hasher_algorithm_from_oid(hash_oid); - if (hash_algorithm == HASH_UNKNOWN - || (algorithm != HASH_UNKNOWN && hash_algorithm != algorithm)) - { - DBG1("wrong hash algorithm used in signature"); - goto end; - } - } - break; - case DIGEST_INFO_DIGEST: - { - chunk_t hash; - hasher_t *hasher = hasher_create(hash_algorithm); - - 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; - } - - /* build our own hash */ - hasher->allocate_hash(hasher, data, &hash); - hasher->destroy(hasher); - - /* compare the hashes */ - res = memeq(object.ptr, hash.ptr, hash.len) ? SUCCESS : FAILED; - free(hash.ptr); - } - break; - default: - break; - } - objectID++; - } - } - -end: - free(em_ori.ptr); - return res; -} - - -/** - * Implementation of rsa_public_key_t.get_modulus. - */ -static mpz_t *get_modulus(const private_rsa_public_key_t *this) -{ - return (mpz_t*)&this->n; -} - -/** - * Implementation of rsa_public_key_t.get_keysize. - */ -static size_t get_keysize(const private_rsa_public_key_t *this) -{ - return this->k; -} - -/** - * Build a DER-encoded publicKeyInfo object from an RSA public key. - * Also used in rsa_private_key.c. - */ -chunk_t rsa_public_key_info_to_asn1(const mpz_t n, const mpz_t e) -{ - chunk_t publicKey = asn1_wrap(ASN1_SEQUENCE, "mm", - asn1_integer_from_mpz(n), - asn1_integer_from_mpz(e)); - - return asn1_wrap(ASN1_SEQUENCE, "cm", - asn1_algorithmIdentifier(OID_RSA_ENCRYPTION), - asn1_bitstring("m", publicKey)); -} - -/** - * Form the RSA keyid as a SHA-1 hash of a publicKeyInfo object - * Also used in rsa_private_key.c. - */ -chunk_t rsa_public_key_id_create(mpz_t n, mpz_t e) -{ - chunk_t keyid; - chunk_t publicKeyInfo = rsa_public_key_info_to_asn1(n, e); - hasher_t *hasher = hasher_create(HASH_SHA1); - - hasher->allocate_hash(hasher, publicKeyInfo, &keyid); - hasher->destroy(hasher); - free(publicKeyInfo.ptr); - - return keyid; -} - -/** - * Implementation of rsa_public_key_t.get_publicKeyInfo. - */ -static chunk_t get_publicKeyInfo(const private_rsa_public_key_t *this) -{ - return rsa_public_key_info_to_asn1(this->n, this->e); -} - -/** - * Implementation of rsa_public_key_t.get_keyid. - */ -static chunk_t get_keyid(const private_rsa_public_key_t *this) -{ - return this->keyid; -} - -/* forward declaration used by rsa_public_key_t.clone */ -private_rsa_public_key_t *rsa_public_key_create_empty(void); - -/** - * Implementation of rsa_public_key_t.clone. - */ -static rsa_public_key_t* _clone(const private_rsa_public_key_t *this) -{ - private_rsa_public_key_t *clone = rsa_public_key_create_empty(); - - mpz_init_set(clone->n, this->n); - mpz_init_set(clone->e, this->e); - clone->keyid = chunk_clone(this->keyid); - clone->k = this->k; - - return &clone->public; -} - -/** - * Implementation of rsa_public_key_t.destroy. - */ -static void destroy(private_rsa_public_key_t *this) -{ - mpz_clear(this->n); - mpz_clear(this->e); - free(this->keyid.ptr); - free(this); -} - -/** - * Generic private constructor - */ -private_rsa_public_key_t *rsa_public_key_create_empty(void) -{ - private_rsa_public_key_t *this = malloc_thing(private_rsa_public_key_t); - - /* public functions */ - this->public.pkcs1_encrypt = (status_t (*) (rsa_public_key_t*,chunk_t,chunk_t*))pkcs1_encrypt; - this->public.verify_emsa_pkcs1_signature = (status_t (*) (const rsa_public_key_t*,hash_algorithm_t,chunk_t,chunk_t))verify_emsa_pkcs1_signature; - this->public.get_modulus = (mpz_t *(*) (const rsa_public_key_t*))get_modulus; - this->public.get_keysize = (size_t (*) (const rsa_public_key_t*))get_keysize; - this->public.get_publicKeyInfo = (chunk_t (*) (const rsa_public_key_t*))get_publicKeyInfo; - this->public.get_keyid = (chunk_t (*) (const rsa_public_key_t*))get_keyid; - this->public.clone = (rsa_public_key_t* (*) (const rsa_public_key_t*))_clone; - this->public.destroy = (void (*) (rsa_public_key_t*))destroy; - - /* private functions */ - this->rsaep = rsaep; - this->rsavp1 = rsaep; /* same algorithm */ - - return this; -} - -/* - * See header - */ -rsa_public_key_t *rsa_public_key_create(mpz_t n, mpz_t e) -{ - private_rsa_public_key_t *this = rsa_public_key_create_empty(); - - mpz_init_set(this->n, n); - mpz_init_set(this->e, e); - - this->k = (mpz_sizeinbase(n, 2) + 7) / BITS_PER_BYTE; - this->keyid = rsa_public_key_id_create(n, e); - return &this->public; -} -/* - * See header - */ -rsa_public_key_t *rsa_public_key_create_from_chunk(chunk_t blob) -{ - asn1_ctx_t ctx; - chunk_t object; - u_int level; - int objectID = 0; - - private_rsa_public_key_t *this = rsa_public_key_create_empty(); - - mpz_init(this->n); - mpz_init(this->e); - - asn1_init(&ctx, blob, 0, FALSE, FALSE); - - while (objectID < PUB_KEY_ROOF) - { - if (!extract_object(pubkeyObjects, &objectID, &object, &level, &ctx)) - { - destroy(this); - return FALSE; - } - 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; - } - objectID++; - } - - this->k = (mpz_sizeinbase(this->n, 2) + 7) / BITS_PER_BYTE; - this->keyid = rsa_public_key_id_create(this->n, this->e); - return &this->public; -} - -/* - * See header - */ -rsa_public_key_t *rsa_public_key_create_from_file(char *filename) -{ - bool pgp = FALSE; - chunk_t chunk = chunk_empty; - rsa_public_key_t *pubkey = NULL; - - if (!pem_asn1_load_file(filename, NULL, "public key", &chunk, &pgp)) - { - return NULL; - } - pubkey = rsa_public_key_create_from_chunk(chunk); - free(chunk.ptr); - return pubkey; -} diff --git a/src/libstrongswan/crypto/rsa/rsa_public_key.h b/src/libstrongswan/crypto/rsa/rsa_public_key.h deleted file mode 100644 index c0bd3e351..000000000 --- a/src/libstrongswan/crypto/rsa/rsa_public_key.h +++ /dev/null @@ -1,173 +0,0 @@ -/** - * @file rsa_public_key.h - * - * @brief Interface of rsa_public_key_t. - * - */ - -/* - * Copyright (C) 2005 Jan Hutter - * Copyright (C) 2005-2006 Martin Willi - * Copyright (C) 2007-2008 Andreas Steffen - * - * Hochschule fuer Technik Rapperswil - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * for more details. - * - * RCSID $Id: rsa_public_key.h 3423 2008-01-22 10:32:37Z andreas $ - */ - -#ifndef RSA_PUBLIC_KEY_H_ -#define RSA_PUBLIC_KEY_H_ - -typedef struct rsa_public_key_t rsa_public_key_t; - -#include <gmp.h> - -#include <library.h> -#include <crypto/hashers/hasher.h> - -/** - * @brief RSA public key with associated functions. - * - * Currently only supports signature verification using - * the EMSA encoding (see PKCS1) - * - * @b Constructors: - * - rsa_public_key_create() - * - rsa_public_key_create_from_chunk() - * - rsa_public_key_create_from_file() - * - * @ingroup rsa - */ -struct rsa_public_key_t { - - /** - * @brief Encrypt a data block using EME-PKCS1 encoding. - * - * - * @param this calling object - * @param data plaintext input data - * @param out encrypted output data - * @return - * - SUCCESS - * - FAILED if data block is too large - */ - status_t (*pkcs1_encrypt) (rsa_public_key_t *this, chunk_t in, chunk_t *out); - - /** - * @brief Verify an EMSA-PKCS1 encoded signature. - * - * Processes the supplied signature with the RSAVP1 function, - * selects the hash algorithm form the resultign ASN1-OID and - * verifies the hash against the supplied data. - * - * @param this rsa_public_key to use - * @param data data to sign - # @param algorithm hash algorithm the signature is based on - * @param signature signature to verify - * @return - * - SUCCESS, if signature ok - * - INVALID_STATE, if key not set - * - NOT_SUPPORTED, if hash algorithm not supported - * - INVALID_ARG, if signature is not a signature - * - FAILED if signature invalid or unable to verify - */ - status_t (*verify_emsa_pkcs1_signature) (const rsa_public_key_t *this, - hash_algorithm_t algorithm, - chunk_t data, chunk_t signature); - - /** - * @brief Get the modulus of the key. - * - * @param this calling object - * @return modulus (n) of the key - */ - mpz_t *(*get_modulus) (const rsa_public_key_t *this); - - /** - * @brief Get the size of the modulus in bytes. - * - * @param this calling object - * @return size of the modulus (n) in bytes - */ - size_t (*get_keysize) (const rsa_public_key_t *this); - - /** - * @brief Get the DER encoded publicKeyInfo object. - * - * @param this calling object - * @return DER encoded publicKeyInfo object - */ - chunk_t (*get_publicKeyInfo) (const rsa_public_key_t *this); - - /** - * @brief Get the keyid formed as the SHA-1 hash of a publicKeyInfo object. - * - * @param this calling object - * @return keyid in the form of a SHA-1 hash - */ - chunk_t (*get_keyid) (const rsa_public_key_t *this); - - /** - * @brief Clone the public key. - * - * @param this public key to clone - * @return clone of this - */ - rsa_public_key_t *(*clone) (const rsa_public_key_t *this); - - /** - * @brief Destroys the public key. - * - * @param this public key to destroy - */ - void (*destroy) (rsa_public_key_t *this); -}; - -/** - * @brief Create a RSA public key from modulus and public exponent. - * - * @param n modulus - * @param e public exponent - * @return created rsa_public_key_t - * - * @ingroup rsa - */ -rsa_public_key_t *rsa_public_key_create(mpz_t n, mpz_t e); - -/** - * @brief Load an RSA public key from a chunk. - * - * Load a key from a chunk, encoded in the more frequently - * used publicKeyInfo object (ASN1 DER encoded). - * - * @param chunk chunk containing the DER encoded key - * @return loaded rsa_public_key_t, or NULL - * - * @ingroup rsa - */ -rsa_public_key_t *rsa_public_key_create_from_chunk(chunk_t chunk); - -/** - * @brief Load an RSA public key from a file. - * - * Load a key from a file, which is either in binary - * format (DER), or in PEM format. - * - * @param filename filename which holds the key - * @return loaded rsa_public_key_t, or NULL - * - * @ingroup rsa - */ -rsa_public_key_t *rsa_public_key_create_from_file(char *filename); - -#endif /*RSA_PUBLIC_KEY_H_*/ diff --git a/src/libstrongswan/crypto/signers/signer.c b/src/libstrongswan/crypto/signers/signer.c index 747bc5efa..8412ff62e 100644 --- a/src/libstrongswan/crypto/signers/signer.c +++ b/src/libstrongswan/crypto/signers/signer.c @@ -1,10 +1,3 @@ -/** - * @file signer.c - * - * @brief Implementation of generic signer_t constructor. - * - */ - /* * Copyright (C) 2005-2006 Martin Willi * Copyright (C) 2005 Jan Hutter @@ -19,12 +12,12 @@ * 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: signer.c 3589 2008-03-13 14:14:44Z martin $ */ #include "signer.h" -#include <crypto/signers/hmac_signer.h> - ENUM_BEGIN(integrity_algorithm_names, AUTH_UNDEFINED, AUTH_HMAC_SHA1_128, "UNDEFINED", "AUTH_HMAC_SHA1_128"); @@ -40,26 +33,3 @@ ENUM_NEXT(integrity_algorithm_names, AUTH_HMAC_SHA2_256_128, AUTH_HMAC_SHA2_512_ "AUTH_HMAC_SHA2_512_256"); ENUM_END(integrity_algorithm_names, AUTH_HMAC_SHA2_512_256); -/* - * Described in header. - */ -signer_t *signer_create(integrity_algorithm_t integrity_algorithm) -{ - switch(integrity_algorithm) - { - case AUTH_HMAC_SHA1_96: - return (signer_t *)hmac_signer_create(HASH_SHA1, 12); - case AUTH_HMAC_SHA1_128: - return (signer_t *)hmac_signer_create(HASH_SHA1, 16); - case AUTH_HMAC_MD5_96: - return (signer_t *)hmac_signer_create(HASH_MD5, 12); - case AUTH_HMAC_SHA2_256_128: - return (signer_t *)hmac_signer_create(HASH_SHA256, 16); - case AUTH_HMAC_SHA2_384_192: - return (signer_t *)hmac_signer_create(HASH_SHA384, 24); - case AUTH_HMAC_SHA2_512_256: - return (signer_t *)hmac_signer_create(HASH_SHA512, 32); - default: - return NULL; - } -} diff --git a/src/libstrongswan/crypto/signers/signer.h b/src/libstrongswan/crypto/signers/signer.h index 4218e4146..f67c38f07 100644 --- a/src/libstrongswan/crypto/signers/signer.h +++ b/src/libstrongswan/crypto/signers/signer.h @@ -1,10 +1,3 @@ -/** - * @file signer.h - * - * @brief Interface for signer_t. - * - */ - /* * Copyright (C) 2005-2006 Martin Willi * Copyright (C) 2005 Jan Hutter @@ -19,6 +12,13 @@ * 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: signer.h 3589 2008-03-13 14:14:44Z martin $ + */ + +/** + * @defgroup signer signer + * @{ @ingroup crypto */ #ifndef SIGNER_H_ @@ -30,11 +30,9 @@ typedef struct signer_t signer_t; #include <library.h> /** - * @brief Integrity algorithm, as in IKEv2 RFC 3.3.2. + * Integrity algorithm, as in IKEv2 RFC 3.3.2. * * Algorithms not specified in IKEv2 are allocated in private use space. - * - * @ingroup signers */ enum integrity_algorithm_t { AUTH_UNDEFINED = 1024, @@ -61,93 +59,65 @@ enum integrity_algorithm_t { extern enum_name_t *integrity_algorithm_names; /** - * @brief Generig interface for a symmetric signature algorithm. - * - * @b Constructors: - * - signer_create() - * - hmac_signer_create() - * - * @todo Implement more integrity algorithms - * - * @ingroup signers + * Generig interface for a symmetric signature algorithm. */ struct signer_t { /** - * @brief Generate a signature. + * Generate a signature. * * If buffer is NULL, data is processed and prepended to a next call until * buffer is a valid pointer. * - * @param this calling object - * @param data a chunk containing the data to sign - * @param[out] buffer pointer where the signature will be written + * @param data a chunk containing the data to sign + * @param buffer pointer where the signature will be written */ void (*get_signature) (signer_t *this, chunk_t data, u_int8_t *buffer); /** - * @brief Generate a signature and allocate space for it. + * Generate a signature and allocate space for it. * * If chunk is NULL, data is processed and prepended to a next call until * chunk is a valid chunk pointer. * - * @param this calling object - * @param data a chunk containing the data to sign - * @param[out] chunk chunk which will hold the allocated signature + * @param data a chunk containing the data to sign + * @param chunk chunk which will hold the allocated signature */ void (*allocate_signature) (signer_t *this, chunk_t data, chunk_t *chunk); /** - * @brief Verify a signature. + * Verify a signature. * - * @param this calling object - * @param data a chunk containing the data to verify - * @param signature a chunk containing the signature - * @return TRUE, if signature is valid, FALSE otherwise + * @param data a chunk containing the data to verify + * @param signature a chunk containing the signature + * @return TRUE, if signature is valid, FALSE otherwise */ bool (*verify_signature) (signer_t *this, chunk_t data, chunk_t signature); /** - * @brief Get the block size of this signature algorithm. + * Get the block size of this signature algorithm. * - * @param this calling object - * @return block size in bytes + * @return block size in bytes */ size_t (*get_block_size) (signer_t *this); /** - * @brief Get the key size of the signature algorithm. + * Get the key size of the signature algorithm. * - * @param this calling object - * @return key size in bytes + * @return key size in bytes */ size_t (*get_key_size) (signer_t *this); /** - * @brief Set the key for this object. + * Set the key for this object. * - * @param this calling object - * @param key key to set + * @param key key to set */ void (*set_key) (signer_t *this, chunk_t key); /** - * @brief Destroys a signer_t object. - * - * @param this calling object + * Destroys a signer_t object. */ void (*destroy) (signer_t *this); }; -/** - * @brief Creates a new signer_t object. - * - * @param integrity_algorithm Algorithm to use for signing and verifying. - * @return - * - signer_t object - * - NULL if signer not supported - * - * @ingroup signers - */ -signer_t *signer_create(integrity_algorithm_t integrity_algorithm); - -#endif /*SIGNER_H_*/ +#endif /*SIGNER_H_ @} */ diff --git a/src/libstrongswan/crypto/x509.c b/src/libstrongswan/crypto/x509.c deleted file mode 100755 index eadf11327..000000000 --- a/src/libstrongswan/crypto/x509.c +++ /dev/null @@ -1,1562 +0,0 @@ -/** - * @file x509.c - * - * @brief Implementation of x509_t. - * - */ - -/* - * Copyright (C) 2000 Andreas Hess, Patric Lichtsteiner, Roger Wegmann - * Copyright (C) 2001 Marco Bertossa, Andreas Schleiss - * Copyright (C) 2002 Mario Strasser - * Copyright (C) 2006 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. - * - * RCSID $Id: x509.c 3423 2008-01-22 10:32:37Z andreas $ - */ - -#include <gmp.h> -#include <sys/stat.h> -#include <unistd.h> -#include <string.h> -#include <stdio.h> - -#include "x509.h" -#include "hashers/hasher.h" -#include <library.h> -#include <debug.h> -#include <asn1/oid.h> -#include <asn1/asn1.h> -#include <asn1/pem.h> -#include <utils/linked_list.h> -#include <utils/identification.h> - -#define CERT_WARNING_INTERVAL 30 /* days */ - -/** - * Different kinds of generalNames - */ -typedef enum generalNames_t generalNames_t; - -enum generalNames_t { - 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, -}; - -typedef struct private_x509_t private_x509_t; - -/** - * Private data of a x509_t object. - */ -struct private_x509_t { - /** - * Public interface for this certificate. - */ - x509_t public; - - /** - * Time when certificate was installed - */ - time_t installed; - - /** - * Time until certificate can be trusted - */ - time_t until; - - /** - * Certificate status - */ - cert_status_t status; - - /** - * Authority flags - */ - u_int authority_flags; - - /** - * X.509 Certificate in DER format - */ - chunk_t certificate; - - /** - * 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; - - /** - * Signature algorithm - */ - int signatureAlgorithm; - - /** - * ID representing the certificate issuer - */ - identification_t *issuer; - - /** - * link to the info recored of the certificate issuer - */ - ca_info_t *ca_info; - - /** - * 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 identification_t's representing subjectAltNames - */ - linked_list_t *subjectAltNames; - - /** - * List of identification_t's representing crlDistributionPoints - */ - linked_list_t *crlDistributionPoints; - - /** - * List of identification_t's representing ocspAccessLocations - */ - linked_list_t *ocspAccessLocations; - - /** - * Subject public key - */ - chunk_t subjectPublicKey; - - /** - * Subject RSA public key, if subjectPublicKeyAlgorithm == RSA - */ - rsa_public_key_t *public_key; - - /** - * Subject Key Identifier - */ - chunk_t subjectKeyID; - - /** - * Authority Key Identifier - */ - chunk_t authKeyID; - - /** - * Authority Key Serial Number - */ - chunk_t authKeySerialNumber; - - /** - * Indicates if the certificate is self-signed - */ - bool isSelfSigned; - - /** - * CA basic constraints flag - */ - bool isCA; - - /** - * OCSPSigner extended key usage flag - */ - bool isOcspSigner; - - /** - * Signature - */ - chunk_t signature; - -}; - -/** - * 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 */ -}; -#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 -#define GN_OBJ_ROOF 18 - -/** - * 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 */ -}; -#define ON_OBJ_ID_TYPE 0 -#define ON_OBJ_VALUE 1 -#define ON_OBJ_ROOF 2 -/** - * 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 */ -}; -#define BASIC_CONSTRAINTS_CA 1 -#define BASIC_CONSTRAINTS_ROOF 4 - -/** - * ASN.1 definition of a keyIdentifier - */ -static const asn1Object_t keyIdentifierObjects[] = { - { 0, "keyIdentifier", ASN1_OCTET_STRING, ASN1_BODY } /* 0 */ -}; - -/** - * ASN.1 definition of a authorityKeyIdentifier extension - */ -static const asn1Object_t authorityKeyIdentifierObjects[] = { - { 0, "authorityKeyIdentifier", ASN1_SEQUENCE, ASN1_NONE }, /* 0 */ - { 1, "keyIdentifier", ASN1_CONTEXT_S_0, ASN1_OPT|ASN1_OBJ }, /* 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 */ -}; -#define AUTH_KEY_ID_KEY_ID 1 -#define AUTH_KEY_ID_CERT_ISSUER 3 -#define AUTH_KEY_ID_CERT_SERIAL 5 -#define AUTH_KEY_ID_ROOF 7 - -/** - * ASN.1 definition of a authorityInfoAccess extension - */ -static const asn1Object_t authorityInfoAccessObjects[] = { - { 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 */ -}; -#define AUTH_INFO_ACCESS_METHOD 2 -#define AUTH_INFO_ACCESS_LOCATION 3 -#define AUTH_INFO_ACCESS_ROOF 5 - -/** - * 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 */ -}; - -#define EXT_KEY_USAGE_PURPOSE_ID 1 -#define EXT_KEY_USAGE_ROOF 3 - -/** - * 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 */ -}; -#define GENERAL_NAMES_GN 1 -#define GENERAL_NAMES_ROOF 3 - - -/** - * 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 */ -}; -#define CRL_DIST_POINTS_FULLNAME 3 -#define CRL_DIST_POINTS_ROOF 13 - -/** - * ASN.1 definition of an X.509v3 x509 - */ -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_NONE }, /* 11 */ - { 3, "algorithm", ASN1_EOC, ASN1_RAW }, /* 12 */ - { 3, "subjectPublicKey", ASN1_BIT_STRING, ASN1_NONE }, /* 13 */ - { 4, "RSAPublicKey", ASN1_SEQUENCE, ASN1_RAW }, /* 14 */ - { 2, "issuerUniqueID", ASN1_CONTEXT_C_1, ASN1_OPT }, /* 15 */ - { 2, "end opt", ASN1_EOC, ASN1_END }, /* 16 */ - { 2, "subjectUniqueID", ASN1_CONTEXT_C_2, ASN1_OPT }, /* 17 */ - { 2, "end opt", ASN1_EOC, ASN1_END }, /* 18 */ - { 2, "optional extensions", ASN1_CONTEXT_C_3, ASN1_OPT }, /* 19 */ - { 3, "extensions", 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 */ -}; -#define X509_OBJ_CERTIFICATE 0 -#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_ALGORITHM 12 -#define X509_OBJ_SUBJECT_PUBLIC_KEY 13 -#define X509_OBJ_RSA_PUBLIC_KEY 14 -#define X509_OBJ_EXTN_ID 22 -#define X509_OBJ_CRITICAL 23 -#define X509_OBJ_EXTN_VALUE 24 -#define X509_OBJ_ALGORITHM 27 -#define X509_OBJ_SIGNATURE 28 -#define X509_OBJ_ROOF 29 - - -static u_char ASN1_subjectAltName_oid_str[] = { - 0x06, 0x03, 0x55, 0x1D, 0x11 -}; - -static const chunk_t ASN1_subjectAltName_oid = chunk_from_buf(ASN1_subjectAltName_oid_str); - - -/** - * compare two X.509 x509s by comparing their signatures - */ -static bool equals(const private_x509_t *this, const private_x509_t *other) -{ - return chunk_equals(this->signature, other->signature); -} - -/** - * extracts the basicConstraints extension - */ -static bool parse_basicConstraints(chunk_t blob, int level0) -{ - asn1_ctx_t ctx; - chunk_t object; - u_int level; - int objectID = 0; - bool isCA = FALSE; - - asn1_init(&ctx, blob, level0, FALSE, FALSE); - - while (objectID < BASIC_CONSTRAINTS_ROOF) { - - if (!extract_object(basicConstraintsObjects, &objectID, &object,&level, &ctx)) - { - break; - } - if (objectID == BASIC_CONSTRAINTS_CA) - { - isCA = object.len && *object.ptr; - DBG2(" %s", isCA ? "TRUE" : "FALSE"); - } - objectID++; - } - return isCA; -} - -/** - * extracts an otherName - */ -static bool parse_otherName(chunk_t blob, int level0) -{ - asn1_ctx_t ctx; - chunk_t object; - u_int level; - int objectID = 0; - int oid = OID_UNKNOWN; - - asn1_init(&ctx, blob, level0, FALSE, FALSE); - - while (objectID < ON_OBJ_ROOF) - { - if (!extract_object(otherNameObjects, &objectID, &object, &level, &ctx)) - return FALSE; - - switch (objectID) - { - case ON_OBJ_ID_TYPE: - oid = known_oid(object); - break; - case ON_OBJ_VALUE: - if (oid == OID_XMPP_ADDR) - { - if (!parse_asn1_simple_object(&object, ASN1_UTF8STRING, level + 1, "xmppAddr")) - return FALSE; - } - break; - default: - break; - } - objectID++; - } - return TRUE; -} - -/** - * extracts a generalName - */ -static identification_t *parse_generalName(chunk_t blob, int level0) -{ - asn1_ctx_t ctx; - chunk_t object; - int objectID = 0; - u_int level; - - asn1_init(&ctx, blob, level0, FALSE, FALSE); - - while (objectID < GN_OBJ_ROOF) - { - id_type_t id_type = ID_ANY; - - if (!extract_object(generalNameObjects, &objectID, &object, &level, &ctx)) - return NULL; - - 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 = (object.len == 4)? ID_IPV4_ADDR : ID_IPV6_ADDR; - break; - case GN_OBJ_OTHER_NAME: - if (!parse_otherName(object, level + 1)) - return NULL; - break; - case GN_OBJ_X400_ADDRESS: - case GN_OBJ_EDI_PARTY_NAME: - case GN_OBJ_REGISTERED_ID: - break; - default: - break; - } - - if (id_type != ID_ANY) - { - identification_t *gn = identification_create_from_encoding(id_type, object); - DBG2(" '%D'", gn); - return gn; - } - objectID++; - } - return NULL; -} - - -/* - * Defined in header. - */ -void x509_parse_generalNames(chunk_t blob, int level0, bool implicit, linked_list_t *list) -{ - asn1_ctx_t ctx; - chunk_t object; - u_int level; - int objectID = 0; - - asn1_init(&ctx, blob, level0, implicit, FALSE); - - while (objectID < GENERAL_NAMES_ROOF) - { - if (!extract_object(generalNamesObjects, &objectID, &object, &level, &ctx)) - return; - - if (objectID == GENERAL_NAMES_GN) - { - identification_t *gn = parse_generalName(object, level+1); - - if (gn != NULL) - list->insert_last(list, (void *)gn); - } - objectID++; - } - return; -} - -/** - * extracts a keyIdentifier - */ -static chunk_t parse_keyIdentifier(chunk_t blob, int level0, bool implicit) -{ - asn1_ctx_t ctx; - chunk_t object; - u_int level; - int objectID = 0; - - asn1_init(&ctx, blob, level0, implicit, FALSE); - - extract_object(keyIdentifierObjects, &objectID, &object, &level, &ctx); - return object; -} - -/* - * Defined in header. - */ -void x509_parse_authorityKeyIdentifier(chunk_t blob, int level0 , chunk_t *authKeyID, chunk_t *authKeySerialNumber) -{ - asn1_ctx_t ctx; - chunk_t object; - u_int level; - int objectID = 0; - - *authKeyID = chunk_empty; - *authKeySerialNumber = chunk_empty; - - asn1_init(&ctx, blob, level0, FALSE, FALSE); - - while (objectID < AUTH_KEY_ID_ROOF) - { - if (!extract_object(authorityKeyIdentifierObjects, &objectID, &object, &level, &ctx)) - { - return; - } - switch (objectID) - { - case AUTH_KEY_ID_KEY_ID: - *authKeyID = parse_keyIdentifier(object, level+1, TRUE); - break; - case AUTH_KEY_ID_CERT_ISSUER: - { - /* TODO: parse_generalNames(object, level+1, TRUE); */ - break; - } - case AUTH_KEY_ID_CERT_SERIAL: - *authKeySerialNumber = object; - break; - default: - break; - } - objectID++; - } -} - -/** - * extracts an authorityInfoAcess location - */ -static void parse_authorityInfoAccess(chunk_t blob, int level0, linked_list_t *list) -{ - asn1_ctx_t ctx; - chunk_t object; - u_int level; - int objectID = 0; - int accessMethod = OID_UNKNOWN; - - asn1_init(&ctx, blob, level0, FALSE, FALSE); - while (objectID < AUTH_INFO_ACCESS_ROOF) - { - if (!extract_object(authorityInfoAccessObjects, &objectID, &object, &level, &ctx)) - { - return; - } - switch (objectID) - { - case AUTH_INFO_ACCESS_METHOD: - accessMethod = known_oid(object); - break; - case AUTH_INFO_ACCESS_LOCATION: - { - switch (accessMethod) - { - case OID_OCSP: - case OID_CA_ISSUERS: - { - identification_t *accessLocation; - - accessLocation = parse_generalName(object, level+1); - if (accessLocation == NULL) - { - /* parsing went wrong - abort */ - return; - } - DBG2(" '%D'", accessLocation); - if (accessMethod == OID_OCSP) - { - list->insert_last(list, (void *)accessLocation); - } - else - { - /* caIsssuer accessLocation is not used yet */ - accessLocation->destroy(accessLocation); - } - } - break; - default: - /* unkown accessMethod, ignoring */ - break; - } - break; - } - default: - break; - } - objectID++; - } -} - -/** - * extracts extendedKeyUsage OIDs - */ -static bool parse_extendedKeyUsage(chunk_t blob, int level0) -{ - asn1_ctx_t ctx; - chunk_t object; - u_int level; - int objectID = 0; - - asn1_init(&ctx, blob, level0, FALSE, FALSE); - while (objectID < EXT_KEY_USAGE_ROOF) - { - if (!extract_object(extendedKeyUsageObjects, &objectID, &object, &level, &ctx)) - { - return FALSE; - } - if (objectID == EXT_KEY_USAGE_PURPOSE_ID && - known_oid(object) == OID_OCSP_SIGNING) - { - return TRUE; - } - objectID++; - } - return FALSE; -} - -/** - * extracts one or several crlDistributionPoints and puts them into - * a chained list - */ -static void parse_crlDistributionPoints(chunk_t blob, int level0, linked_list_t *list) -{ - asn1_ctx_t ctx; - chunk_t object; - u_int level; - int objectID = 0; - - asn1_init(&ctx, blob, level0, FALSE, FALSE); - while (objectID < CRL_DIST_POINTS_ROOF) - { - if (!extract_object(crlDistributionPointsObjects, &objectID, &object, &level, &ctx)) - { - return; - } - if (objectID == CRL_DIST_POINTS_FULLNAME) - { - /* append extracted generalNames to existing chained list */ - x509_parse_generalNames(object, level+1, TRUE, list); - - } - objectID++; - } -} - - -/** - * Parses an X.509v3 certificate - */ -static bool parse_certificate(chunk_t blob, u_int level0, private_x509_t *this) -{ - asn1_ctx_t ctx; - bool critical; - chunk_t object; - u_int level; - int objectID = 0; - int extn_oid = OID_UNKNOWN; - - asn1_init(&ctx, blob, level0, FALSE, FALSE); - while (objectID < X509_OBJ_ROOF) - { - if (!extract_object(certObjects, &objectID, &object, &level, &ctx)) - { - return FALSE; - } - - /* those objects which will parsed further need the next higher level */ - level++; - - switch (objectID) - { - case X509_OBJ_CERTIFICATE: - this->certificate = object; - break; - 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: - this->signatureAlgorithm = 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 = parse_time(object, level); - break; - case X509_OBJ_NOT_AFTER: - this->notAfter = 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_ALGORITHM: - if (parse_algorithmIdentifier(object, level, NULL) != OID_RSA_ENCRYPTION) - { - DBG1(" unsupported public key algorithm"); - return FALSE; - } - break; - case X509_OBJ_SUBJECT_PUBLIC_KEY: - if (ctx.blobs[4].len > 0 && *ctx.blobs[4].ptr == 0x00) - { - /* skip initial bit string octet defining 0 unused bits */ - ctx.blobs[4].ptr++; ctx.blobs[4].len--; - } - else - { - DBG1(" invalid RSA public key format"); - return FALSE; - } - break; - case X509_OBJ_RSA_PUBLIC_KEY: - this->subjectPublicKey = object; - break; - case X509_OBJ_EXTN_ID: - extn_oid = 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: - this->subjectKeyID = chunk_clone(parse_keyIdentifier(object, level, FALSE)); - break; - case OID_SUBJECT_ALT_NAME: - x509_parse_generalNames(object, level, FALSE, this->subjectAltNames); - break; - case OID_BASIC_CONSTRAINTS: - this->isCA = parse_basicConstraints(object, level); - break; - case OID_CRL_DISTRIBUTION_POINTS: - parse_crlDistributionPoints(object, level, this->crlDistributionPoints); - break; - case OID_AUTHORITY_KEY_ID: - x509_parse_authorityKeyIdentifier(object, level, - &this->authKeyID, &this->authKeySerialNumber); - break; - case OID_AUTHORITY_INFO_ACCESS: - parse_authorityInfoAccess(object, level, this->ocspAccessLocations); - break; - case OID_EXTENDED_KEY_USAGE: - this->isOcspSigner = parse_extendedKeyUsage(object, level); - break; - case OID_NS_REVOCATION_URL: - case OID_NS_CA_REVOCATION_URL: - case OID_NS_CA_POLICY_URL: - case OID_NS_COMMENT: - if (!parse_asn1_simple_object(&object, ASN1_IA5STRING , level, oid_names[extn_oid].name)) - return FALSE; - break; - default: - break; - } - break; - } - case X509_OBJ_ALGORITHM: - { - int alg = parse_algorithmIdentifier(object, level, NULL); - - if (alg != this->signatureAlgorithm) - { - DBG1(" signature algorithms do not agree"); - return FALSE; - } - } - break; - case X509_OBJ_SIGNATURE: - this->signature = object; - break; - default: - break; - } - objectID++; - } - - /* generate the subjectKeyID if it is missing in the certificate */ - if (this->subjectKeyID.ptr == NULL) - { - hasher_t *hasher = hasher_create(HASH_SHA1); - - hasher->allocate_hash(hasher, this->subjectPublicKey, &this->subjectKeyID); - hasher->destroy(hasher); - } - - this->installed = time(NULL); - return TRUE; -} - -/** - * Implements x509_t.is_valid - */ -static err_t is_valid(const private_x509_t *this, time_t *until) -{ - time_t current_time = time(NULL); - - DBG2(" not before : %T", &this->notBefore); - DBG2(" current time: %T", ¤t_time); - DBG2(" not after : %T", &this->notAfter); - - if (until != NULL && - (*until == UNDEFINED_TIME || this->notAfter < *until)) - { - *until = this->notAfter; - } - if (current_time < this->notBefore) - { - return "is not valid yet"; - } - if (current_time > this->notAfter) - { - return "has expired"; - } - DBG2(" certificate is valid"); - return NULL; -} - -/** - * Implements x509_t.is_ca - */ -static bool is_ca(const private_x509_t *this) -{ - return this->isCA; -} - -/** - * Implements x509_t.is_ocsp_signer - */ -static bool is_ocsp_signer(const private_x509_t *this) -{ - return this->isOcspSigner; -} - -/** - * Implements x509_t.is_self_signed - */ -static bool is_self_signed(const private_x509_t *this) -{ - return this->isSelfSigned; -} - -/** - * Implements x509_t.equals_subjectAltName - */ -static bool equals_subjectAltName(const private_x509_t *this, identification_t *id) -{ - bool found = FALSE; - identification_t *subjectAltName; - iterator_t *iterator; - - iterator = this->subjectAltNames->create_iterator(this->subjectAltNames, TRUE); - while (iterator->iterate(iterator, (void**)&subjectAltName)) - { - if (id->equals(id, subjectAltName)) - { - found = TRUE; - break; - } - } - iterator->destroy(iterator); - return found; -} - -/** - * Implements x509_t.is_issuer - */ -static bool is_issuer(const private_x509_t *this, const private_x509_t *issuer) -{ - return (this->authKeyID.ptr) - ? chunk_equals(this->authKeyID, issuer->subjectKeyID) - : (this->issuer->equals(this->issuer, issuer->subject) - && chunk_equals_or_null(this->authKeySerialNumber, issuer->serialNumber)); -} - -/** - * Implements x509_t.get_certificate - */ -static chunk_t get_certificate(const private_x509_t *this) -{ - return this->certificate; -} - -/** - * Implements x509_t.get_public_key - */ -static rsa_public_key_t *get_public_key(const private_x509_t *this) -{ - return this->public_key; -} - -/** - * Implements x509_t.get_serialNumber - */ -static chunk_t get_serialNumber(const private_x509_t *this) -{ - return this->serialNumber; -} - -/** - * Implements x509_t.get_subjectKeyID - */ -static chunk_t get_subjectKeyID(const private_x509_t *this) -{ - return this->subjectKeyID; -} - -/** - * Implements x509_t.get_keyid - */ -static chunk_t get_keyid(const private_x509_t *this) -{ - return this->public_key->get_keyid(this->public_key); -} - -/** - * Implements x509_t.get_issuer - */ -static identification_t *get_issuer(const private_x509_t *this) -{ - return this->issuer; -} - -/** - * Implements x509_t.get_subject - */ -static identification_t *get_subject(const private_x509_t *this) -{ - return this->subject; -} - -/** - * Implements x509_t.set_ca_info - */ -static void set_ca_info(private_x509_t *this, ca_info_t *ca_info) -{ - this->ca_info = ca_info; -} - -/** - * Implements x509_t.get_ca_info - */ -static ca_info_t *get_ca_info(const private_x509_t *this) -{ - return this->ca_info; -} - -/** - * Implements x509_t.set_until - */ -static void set_until(private_x509_t *this, time_t until) -{ - this->until = until; -} - -/** - * Implements x509_t.get_until - */ -static time_t get_until(const private_x509_t *this) -{ - return this->until; -} - -/** - * Implements x509_t.set_status - */ -static void set_status(private_x509_t *this, cert_status_t status) -{ - this->status = status; -} - -/** - * Implements x509_t.get_status - */ -static cert_status_t get_status(const private_x509_t *this) -{ - return this->status; -} - -/** - * Implements x509_t.add_authority_flags - */ -static void add_authority_flags(private_x509_t *this, u_int flags) -{ - this->authority_flags |= flags; -} - -/** - * Implements x509_t.add_authority_flags - */ -static u_int get_authority_flags(private_x509_t *this) -{ - return this->authority_flags; -} - -/** - * Implements x509_t.has_authority_flag - */ -static bool has_authority_flag(private_x509_t *this, u_int flags) -{ - return (this->authority_flags & flags) != AUTH_NONE; -} - -/** - * Implements x509_t.create_crluri_iterator - */ -static iterator_t *create_crluri_iterator(const private_x509_t *this) -{ - return this->crlDistributionPoints->create_iterator(this->crlDistributionPoints, TRUE); -} - -/** - * Implements x509_t.create_crluri_iterator - */ -static iterator_t *create_ocspuri_iterator(const private_x509_t *this) -{ - return this->ocspAccessLocations->create_iterator(this->ocspAccessLocations, TRUE); -} - -/** - * Implements x509_t.verify - */ -static bool verify(const private_x509_t *this, const rsa_public_key_t *signer) -{ - hash_algorithm_t algorithm = hasher_algorithm_from_oid(this->signatureAlgorithm); - - if (algorithm == HASH_UNKNOWN) - { - DBG1(" unknown signature algorithm"); - return FALSE; - } - return signer->verify_emsa_pkcs1_signature(signer, algorithm, this->tbsCertificate, this->signature) == SUCCESS; -} - -/** - * Implementation of x509_t.list. - */ -static void list(private_x509_t *this, FILE *out, bool utc) -{ - iterator_t *iterator; - time_t now = time(NULL); - - fprintf(out, "%#T\n", &this->installed, utc); - - if (this->subjectAltNames->get_count(this->subjectAltNames)) - { - identification_t *subjectAltName; - bool first = TRUE; - - fprintf(out, " altNames: "); - iterator = this->subjectAltNames->create_iterator(this->subjectAltNames, TRUE); - while (iterator->iterate(iterator, (void**)&subjectAltName)) - { - if (first) - { - first = FALSE; - } - else - { - fprintf(out, ", "); - } - fprintf(out, "'%D'", subjectAltName); - } - iterator->destroy(iterator); - fprintf(out, "\n"); - } - fprintf(out, " subject: '%D'\n", this->subject); - fprintf(out, " issuer: '%D'\n", this->issuer); - fprintf(out, " serial: %#B\n", &this->serialNumber); - fprintf(out, " validity: not before %#T, ", &this->notBefore, utc); - if (now < this->notBefore) - { - fprintf(out, "not valid yet (valid in %#V)\n", &now, &this->notBefore); - } - else - { - fprintf(out, "ok\n"); - } - - fprintf(out, " not after %#T, ", &this->notAfter, utc); - if (now > this->notAfter) - { - fprintf(out, "expired (%#V ago)\n", &now, &this->notAfter); - } - else - { - fprintf(out, "ok"); - if (now > this->notAfter - CERT_WARNING_INTERVAL * 60 * 60 * 24) - { - fprintf(out, " (expires in %#V)", &now, &this->notAfter); - } - fprintf(out, " \n"); - } - - { - chunk_t keyid = this->public_key->get_keyid(this->public_key); - fprintf(out, " keyid: %#B\n", &keyid); - } - - if (this->subjectKeyID.ptr) - { - fprintf(out, " subjkey: %#B\n", &this->subjectKeyID); - } - if (this->authKeyID.ptr) - { - fprintf(out, " authkey: %#B\n", &this->authKeyID); - } - if (this->authKeySerialNumber.ptr) - { - fprintf(out, " aserial: %#B\n", &this->authKeySerialNumber); - } - - fprintf(out, " pubkey: RSA %d bits", BITS_PER_BYTE * - this->public_key->get_keysize(this->public_key)); - fprintf(out, ", status %N", - cert_status_names, this->status); - - switch (this->status) - { - case CERT_GOOD: - fprintf(out, " until %#T", &this->until, utc); - break; - case CERT_REVOKED: - fprintf(out, " on %#T", &this->until, utc); - break; - case CERT_UNKNOWN: - case CERT_UNDEFINED: - case CERT_UNTRUSTED: - default: - break; - } -} - -/** - * Implements x509_t.add_subjectAltNames. - */ -static void add_subjectAltNames(private_x509_t *this, linked_list_t *subjectAltNames) -{ - iterator_t *iterator = subjectAltNames->create_iterator(subjectAltNames, TRUE); - identification_t *name = NULL; - - while (iterator->iterate(iterator, (void**)&name)) - { - name = name->clone(name); - this->subjectAltNames->insert_last(this->subjectAltNames, (void*)name); - } - iterator->destroy(iterator); -} - -/* - * Defined in header. - */ -chunk_t x509_build_generalNames(linked_list_t *list) -{ - linked_list_t *generalNames = linked_list_create(); - iterator_t *iterator = list->create_iterator(list, TRUE); - identification_t *name; - chunk_t names = chunk_empty; - size_t len = 0; - - while (iterator->iterate(iterator, (void**)&name)) - { - asn1_t asn1_type = ASN1_EOC; - chunk_t *generalName; - - switch (name->get_type(name)) - { - case ID_RFC822_ADDR: - asn1_type = ASN1_CONTEXT_S_1; - break; - case ID_FQDN: - asn1_type = ASN1_CONTEXT_S_2; - break; - case ID_DER_ASN1_DN: - asn1_type = ASN1_CONTEXT_C_4; - break; - case ID_DER_ASN1_GN_URI: - asn1_type = ASN1_CONTEXT_S_6; - break; - case ID_IPV4_ADDR: - case ID_IPV6_ADDR: - asn1_type = ASN1_CONTEXT_S_7; - break; - default: - continue; - } - - generalName = malloc_thing(chunk_t); - *generalName = asn1_simple_object(asn1_type, name->get_encoding(name)); - len += generalName->len; - generalNames->insert_last(generalNames, (void*)generalName); - } - iterator->destroy(iterator); - - if (len > 0) - { - iterator_t *iterator = generalNames->create_iterator(generalNames, TRUE); - chunk_t *generalName; - u_char *pos = build_asn1_object(&names, ASN1_SEQUENCE, len); - - while (iterator->iterate(iterator, (void**)&generalName)) - { - memcpy(pos, generalName->ptr, generalName->len); - pos += generalName->len; - free(generalName->ptr); - free(generalName); - } - iterator->destroy(iterator); - } - generalNames->destroy(generalNames); - return names; -} - -/* - * Defined in header. - */ -chunk_t x509_build_subjectAltNames(linked_list_t *list) -{ - chunk_t generalNames = x509_build_generalNames(list); - - if (generalNames.len) - { - return asn1_wrap(ASN1_SEQUENCE, "cm", - ASN1_subjectAltName_oid, - asn1_wrap(ASN1_OCTET_STRING, "m", generalNames) - ); - } - else - { - return chunk_empty; - } -} - -/** - * Build a to-be-signed X.509 certificate body - */ -static chunk_t x509_build_tbs(private_x509_t *this) -{ - /* version is always X.509v3 */ - chunk_t version = asn1_simple_object(ASN1_CONTEXT_C_0, ASN1_INTEGER_2); - - chunk_t extensions = chunk_empty; - - if (this->subjectAltNames->get_count(this->subjectAltNames)) - { - extensions = asn1_wrap(ASN1_CONTEXT_C_3, "m", - asn1_wrap(ASN1_SEQUENCE, "m", - x509_build_subjectAltNames(this->subjectAltNames))); - } - - return asn1_wrap(ASN1_SEQUENCE, "mmccmcmm", - version, - asn1_simple_object(ASN1_INTEGER, this->serialNumber), - asn1_algorithmIdentifier(this->signatureAlgorithm), - this->issuer->get_encoding(this->issuer), - asn1_wrap(ASN1_SEQUENCE, "mm", - timetoasn1(&this->notBefore, ASN1_UTCTIME), - timetoasn1(&this->notAfter, ASN1_UTCTIME) - ), - this->subject->get_encoding(this->subject), - this->public_key->get_publicKeyInfo(this->public_key), - extensions - ); -} - -/** - * Implementation of x509_t.build_encoding. - */ -static void build_encoding(private_x509_t *this, hash_algorithm_t alg, - rsa_private_key_t *private_key) -{ - chunk_t signature; - - this->signatureAlgorithm = hasher_signature_algorithm_to_oid(alg); - this->tbsCertificate = x509_build_tbs(this); - private_key->build_emsa_pkcs1_signature(private_key, alg, - this->tbsCertificate, &signature); - this->signature = asn1_bitstring("m", signature); - this->certificate = asn1_wrap(ASN1_SEQUENCE, "mcm", - this->tbsCertificate, - asn1_algorithmIdentifier(this->signatureAlgorithm), - this->signature); - -} - -/** - * Implements x509_t.destroy - */ -static void destroy(private_x509_t *this) -{ - this->subjectAltNames->destroy_offset(this->subjectAltNames, - offsetof(identification_t, destroy)); - this->crlDistributionPoints->destroy_offset(this->crlDistributionPoints, - offsetof(identification_t, destroy)); - this->ocspAccessLocations->destroy_offset(this->ocspAccessLocations, - offsetof(identification_t, destroy)); - DESTROY_IF(this->issuer); - DESTROY_IF(this->subject); - DESTROY_IF(this->public_key); - free(this->subjectKeyID.ptr); - free(this->certificate.ptr); - free(this); -} - -/** - * Internal generic constructor - */ -static private_x509_t *x509_create_empty(void) -{ - private_x509_t *this = malloc_thing(private_x509_t); - - /* initialize */ - this->subjectPublicKey = chunk_empty; - this->public_key = NULL; - this->subject = NULL; - this->issuer = NULL; - this->ca_info = NULL; - this->subjectAltNames = linked_list_create(); - this->crlDistributionPoints = linked_list_create(); - this->ocspAccessLocations = linked_list_create(); - this->subjectKeyID = chunk_empty; - this->authKeyID = chunk_empty; - this->authKeySerialNumber = chunk_empty; - this->authority_flags = AUTH_NONE; - this->isCA = FALSE; - this->isOcspSigner = FALSE; - - /* public functions */ - this->public.equals = (bool (*) (const x509_t*,const x509_t*))equals; - this->public.equals_subjectAltName = (bool (*) (const x509_t*,identification_t*))equals_subjectAltName; - this->public.is_issuer = (bool (*) (const x509_t*,const x509_t*))is_issuer; - this->public.is_valid = (err_t (*) (const x509_t*,time_t*))is_valid; - this->public.is_ca = (bool (*) (const x509_t*))is_ca; - this->public.is_self_signed = (bool (*) (const x509_t*))is_self_signed; - this->public.is_ocsp_signer = (bool (*) (const x509_t*))is_ocsp_signer; - this->public.get_certificate = (chunk_t (*) (const x509_t*))get_certificate; - this->public.get_public_key = (rsa_public_key_t* (*) (const x509_t*))get_public_key; - this->public.get_serialNumber = (chunk_t (*) (const x509_t*))get_serialNumber; - this->public.get_subjectKeyID = (chunk_t (*) (const x509_t*))get_subjectKeyID; - this->public.get_keyid = (chunk_t (*) (const x509_t*))get_keyid; - this->public.get_issuer = (identification_t* (*) (const x509_t*))get_issuer; - this->public.get_subject = (identification_t* (*) (const x509_t*))get_subject; - this->public.set_ca_info = (void (*) (x509_t*,ca_info_t*))set_ca_info; - this->public.get_ca_info = (ca_info_t* (*) (const x509_t*))get_ca_info; - this->public.set_until = (void (*) (x509_t*,time_t))set_until; - this->public.get_until = (time_t (*) (const x509_t*))get_until; - this->public.set_status = (void (*) (x509_t*,cert_status_t))set_status; - this->public.get_status = (cert_status_t (*) (const x509_t*))get_status; - this->public.add_authority_flags = (void (*) (x509_t*,u_int))add_authority_flags; - this->public.get_authority_flags = (u_int (*) (x509_t*))get_authority_flags; - this->public.has_authority_flag = (bool (*) (x509_t*,u_int))has_authority_flag; - this->public.create_crluri_iterator = (iterator_t* (*) (const x509_t*))create_crluri_iterator; - this->public.create_ocspuri_iterator = (iterator_t* (*) (const x509_t*))create_ocspuri_iterator; - this->public.verify = (bool (*) (const x509_t*,const rsa_public_key_t*))verify; - this->public.list = (void (*) (x509_t*, FILE *out, bool utc))list; - this->public.add_subjectAltNames = (void (*) (x509_t*,linked_list_t*))add_subjectAltNames; - this->public.build_encoding = (void (*) (x509_t*,hash_algorithm_t,rsa_private_key_t*))build_encoding; - this->public.destroy = (void (*) (x509_t*))destroy; - - return this; -} - -/* - * Described in header. - */ -x509_t *x509_create(chunk_t serialNumber, identification_t *issuer, - time_t notBefore, time_t notAfter, - identification_t *subject, - rsa_public_key_t *public_key) -{ - private_x509_t *this = x509_create_empty(); - - this->serialNumber = serialNumber; - this->issuer = issuer->clone(issuer); - this->notBefore = notBefore; - this->notAfter = notAfter; - this->subject = subject->clone(subject); - this->public_key = public_key->clone(public_key); - - return &this->public; -} - -/* - * Described in header. - */ -x509_t *x509_create_from_chunk(chunk_t chunk, u_int level) -{ - private_x509_t *this = x509_create_empty(); - - if (!parse_certificate(chunk, level, this)) - { - destroy(this); - return NULL; - } - - /* extract public key from certificate */ - this->public_key = rsa_public_key_create_from_chunk(this->subjectPublicKey); - if (this->public_key == NULL) - { - destroy(this); - return NULL; - } - - /* set trusted lifetime of public key to notAfter */ - this->until = this->notAfter; - - /* check if the certificate is self-signed */ - this->isSelfSigned = FALSE; - if (this->subject->equals(this->subject, this->issuer)) - { - hash_algorithm_t algorithm = hasher_algorithm_from_oid(this->signatureAlgorithm); - - if (algorithm == HASH_UNKNOWN) - { - destroy(this); - return NULL; - } - this->isSelfSigned = this->public_key->verify_emsa_pkcs1_signature(this->public_key, - algorithm, this->tbsCertificate, this->signature) == SUCCESS; - } - if (this->isSelfSigned) - { - DBG2(" certificate is self-signed"); - this->status = CERT_GOOD; - } - else - { - this->status = CERT_UNDEFINED; - } - - return &this->public; -} - -/* - * Described in header. - */ -x509_t *x509_create_from_file(const char *filename, const char *label) -{ - bool pgp = FALSE; - chunk_t chunk = chunk_empty; - char cert_label[BUF_LEN]; - - snprintf(cert_label, BUF_LEN, "%s certificate", label); - - if (!pem_asn1_load_file(filename, NULL, cert_label, &chunk, &pgp)) - { - return NULL; - } - return x509_create_from_chunk(chunk, 0); -} diff --git a/src/libstrongswan/crypto/x509.h b/src/libstrongswan/crypto/x509.h deleted file mode 100755 index def45be6b..000000000 --- a/src/libstrongswan/crypto/x509.h +++ /dev/null @@ -1,406 +0,0 @@ -/** - * @file x509.h - * - * @brief Interface of x509_t. - * - */ - -/* - * Copyright (C) 2000 Andreas Hess, Patric Lichtsteiner, Roger Wegmann - * Copyright (C) 2001 Marco Bertossa, Andreas Schleiss - * Copyright (C) 2002 Mario Strasser - * Copyright (C) 2006 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. - * - * RCSID $Id: x509.h 3421 2008-01-22 01:09:19Z andreas $ - */ - -#ifndef X509_H_ -#define X509_H_ - -typedef struct x509_t x509_t; - -#include <library.h> -#include <crypto/rsa/rsa_private_key.h> -#include <crypto/hashers/hasher.h> -#include <crypto/certinfo.h> -#include <crypto/ca.h> -#include <utils/identification.h> -#include <utils/iterator.h> -#include <utils/linked_list.h> - -/* authority flags */ - -#define AUTH_NONE 0x00 /* no authorities */ -#define AUTH_CA 0x01 /* certification authority */ -#define AUTH_AA 0x02 /* authorization authority */ -#define AUTH_OCSP 0x04 /* ocsp signing authority */ - -/** - * @brief X.509 certificate. - * - * @b Constructors: - * - x509_create() - * - x509_create_from_chunk() - * - x509_create_from_file() - * - * @ingroup crypto - */ -struct x509_t { - - /** - * @brief Set trusted public key life. - * - * @param this calling object - * @param until time until public key is trusted - */ - void (*set_until) (x509_t *this, time_t until); - - /** - * @brief Get trusted public key life. - * - * @param this calling object - * @return time until public key is trusted - */ - time_t (*get_until) (const x509_t *this); - - /** - * @brief Set the certificate status - * - * @param this calling object - * @param status certificate status - */ - void (*set_status) (x509_t *this, cert_status_t status); - - /** - * @brief Get the certificate status - * - * @param this calling object - * @return certificate status - */ - cert_status_t (*get_status) (const x509_t *this); - - /** - * @brief Add authority flags - * - * @param this calling object - * @param flag flags to be added - */ - void (*add_authority_flags) (x509_t *this, u_int flags); - - /** - * @brief Get authority flags - * - * @param this calling object - * @return authority flags - */ - u_int (*get_authority_flags) (x509_t *this); - - /** - * @brief Check a specific authority flag - * - * @param this calling object - * @param flag flag to be checked - * @return TRUE if flag is present - */ - bool (*has_authority_flag) (x509_t *this, u_int flag); - - /** - * @brief Get the DER-encoded X.509 certificate body - * - * @param this calling object - * @return DER-encoded X.509 certificate - */ - chunk_t (*get_certificate) (const x509_t *this); - - /** - * @brief Get the RSA public key from the certificate. - * - * @param this calling object - * @return public_key - */ - rsa_public_key_t *(*get_public_key) (const x509_t *this); - - /** - * @brief Get serial number from the certificate. - * - * @param this calling object - * @return serialNumber - */ - chunk_t (*get_serialNumber) (const x509_t *this); - - /** - * @brief Get subjectKeyID from the certificate. - * - * @param this calling object - * @return subjectKeyID - */ - chunk_t (*get_subjectKeyID) (const x509_t *this); - - /** - * @brief Get keyid from the certificate's public key. - * - * @param this calling object - * @return keyid - */ - chunk_t (*get_keyid) (const x509_t *this); - - /** - * @brief Get the issuerDistinguishedName - * - * The resulting ID is always a identification_t - * of type ID_DER_ASN1_DN. - * - * @param this calling object - * @return issuers ID - */ - identification_t *(*get_issuer) (const x509_t *this); - - /** - * @brief Get the subjectDistinguishedName. - * - * The resulting ID is always a identification_t - * of type ID_DER_ASN1_DN. - * - * @param this calling object - * @return subjects ID - */ - identification_t *(*get_subject) (const x509_t *this); - - /** - * @brief Set a link ca info - * - * @param this calling object - * @param ca_info link to the info record of the issuing ca - */ - void (*set_ca_info) (x509_t *this, ca_info_t *ca_info); - - /** - * @brief Get the . - * - * The resulting ID is always a identification_t - * of type ID_DER_ASN1_DN. - * - * @param this calling object - * @return link to the info record of the issuing ca - * or NULL if it does not [yet] exist - */ - ca_info_t *(*get_ca_info) (const x509_t *this); - - /** - * @brief Create an iterator for the crlDistributionPoints. - * - * @param this calling object - * @return iterator for crlDistributionPoints - */ - iterator_t *(*create_crluri_iterator) (const x509_t *this); - - /** - * @brief Create an iterator for the ocspAccessLocations. - * - * @param this calling object - * @return iterator for ocspAccessLocations - */ - iterator_t *(*create_ocspuri_iterator) (const x509_t *this); - - /** - * @brief Check if a certificate is trustworthy - * - * @param this calling object - * @param signer signer's RSA public key - */ - bool (*verify) (const x509_t *this, const rsa_public_key_t *signer); - - /** - * @brief Compare two certificates. - * - * Comparison is done via the certificates signature. - * - * @param this first cert for compare - * @param other second cert for compare - * @return TRUE if signature is equal - */ - bool (*equals) (const x509_t *this, const x509_t *that); - - /** - * @brief Checks if the certificate contains a subjectAltName equal to id. - * - * @param this certificate being examined - * @param id id which is being compared to the subjectAltNames - * @return TRUE if a match is found - */ - bool (*equals_subjectAltName) (const x509_t *this, identification_t *id); - - /** - * @brief Checks if the subject of the other cert is the issuer of this cert. - * - * @param this certificate - * @param issuer potential issuer certificate - * @return TRUE if issuer is found - */ - bool (*is_issuer) (const x509_t *this, const x509_t *issuer); - - /** - * @brief Checks the validity interval of the certificate - * - * @param this certificate being examined - * @param until until = min(until, notAfter) - * @return NULL if the certificate is valid - */ - err_t (*is_valid) (const x509_t *this, time_t *until); - - /** - * @brief Returns the CA basic constraints flag - * - * @param this certificate being examined - * @return TRUE if the CA flag is set - */ - bool (*is_ca) (const x509_t *this); - - /** - * @brief Returns the OCSPSigner extended key usage flag - * - * @param this certificate being examined - * @return TRUE if the OCSPSigner flag is set - */ - bool (*is_ocsp_signer) (const x509_t *this); - - /** - * @brief Checks if the certificate is self-signed (subject equals issuer) - * - * @param this certificate being examined - * @return TRUE if self-signed - */ - bool (*is_self_signed) (const x509_t *this); - - /** - * @brief Log the certificate info to out. - * - * @param this calling object - * @param out stream to write to - * @param utc TRUE for UTC times, FALSE for local time - */ - void (*list) (x509_t *this, FILE *out, bool utc); - - /** - * @brief Adds a list of subjectAltNames - * - * @param this calling object - * @param subjectAltNames list of subjectAltNames to be added - */ - void (*add_subjectAltNames) (x509_t *this, linked_list_t *subjectAltNames); - - /** - * @brief Builds a DER-encoded signed X.509 certificate - * - * @param this calling object - * @param alg hash algorithm used to compute the certificate digest - * @param private_key RSA private key used to sign the certificate digest - */ - void (*build_encoding) (x509_t *this, hash_algorithm_t alg, rsa_private_key_t *private_key); - - /** - * @brief Destroys the certificate. - * - * @param this certificate to destroy - */ - void (*destroy) (x509_t *this); -}; - -/** - * @brief Create a X.509 certificate from its components - * - * @param serialNumber chunk containing the serialNumber - * @param issuer issuer distinguished name - * @param notBefore start date of validity - * @param notAfter end date of validity - * @param subject subject distinguished name - * @param public_key public key - * - * @return created x509_t certificate, or NULL if invalid. - * - * @ingroup crypto - */ -x509_t *x509_create(chunk_t serialNumber, identification_t *issuer, - time_t notBefore, time_t notAfter, - identification_t *subject, - rsa_public_key_t *public_key); - -/** - * @brief Read a X.509 certificate from a DER encoded blob. - * - * @param chunk chunk containing DER encoded data - * @return created x509_t certificate, or NULL if invalid. - * - * @ingroup crypto - */ -x509_t *x509_create_from_chunk(chunk_t chunk, u_int level); - -/** - * @brief Read a X.509 certificate from a DER encoded file. - * - * @param filename file containing DER encoded data - * @param label label describing kind of certificate - * @return created x509_t certificate, or NULL if invalid. - * - * @ingroup crypto - */ -x509_t *x509_create_from_file(const char *filename, const char *label); - -/** - * @brief Parses a DER encoded authorityKeyIdentifier - * - * @param blob blob containing DER encoded data - * @param level0 indicates the current parsing level - * @param authKeyID assigns the authorityKeyIdentifier - * @param authKeySerialNumber assigns the authKeySerialNumber - * - * @ingroup crypto - */ -void x509_parse_authorityKeyIdentifier(chunk_t blob, int level0, chunk_t *authKeyID, chunk_t *authKeySerialNumber); - -/** - * @brief Parses DER encoded generalNames - * - * @param blob blob containing DER encoded data - * @param level0 indicates the current parsing level - * @param implicit implicit coding is used - * @param list list of decoded generalNames - * - * @ingroup crypto - */ -void x509_parse_generalNames(chunk_t blob, int level0, bool implicit, linked_list_t *list); - -/** - * @brief Builds a DER encoded list of generalNames - * - * @param list list of generalNames to be encoded - * @return DER encoded list of generalNames - * - * @ingroup crypto - */ -chunk_t x509_build_generalNames(linked_list_t *list); - -/** - * @brief Builds a DER encoded list of subjectAltNames - * - * @param list list of subjectAltNames to be encoded - * @return DER encoded list of subjectAltNames - * - * @ingroup crypto - */ -chunk_t x509_build_subjectAltNames(linked_list_t *list); - -#endif /* X509_H_ */ diff --git a/src/libstrongswan/database/database.h b/src/libstrongswan/database/database.h new file mode 100644 index 000000000..1cf5c2542 --- /dev/null +++ b/src/libstrongswan/database/database.h @@ -0,0 +1,103 @@ +/* + * 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 databasei database + * @{ @ingroup database + */ + +#ifndef DATABASE_H_ +#define DATABASE_H_ + +typedef enum db_type_t db_type_t; +typedef struct database_t database_t; + +#include <utils/enumerator.h> + +/** + * Database column types + */ +enum db_type_t { + /** integer type, argument is an "int" */ + DB_INT, + /** unsigned integer, argument is an "u_int" */ + DB_UINT, + /** string type, argument is a "char*" */ + DB_TEXT, + /** binary large object type, argument is a "chunk_t" */ + DB_BLOB, + /** floating point, argument is a "double" */ + DB_DOUBLE, + /** NULL, takes no argument */ + DB_NULL, +}; + + +/** + * Interface for a database implementation. + * + * @code + int affected, rowid, aint; + char *atext; + database_t *db; + enumerator_t *enumerator; + + db = lib->database->create("mysql://user:pass@host/database"); + affected = db->execute(db, &rowid, "INSERT INTO table VALUES (?, ?)", + DB_INT, 77, DB_TEXT, "a text"); + printf("inserted %d row, new row ID: %d\n", affected, rowid); + + enumerator = db->query(db, "SELECT aint, atext FROM table WHERE aint > ?", + DB_INT, 10, // 1 argument to SQL string + DB_INT, DB_TEXT); // 2 enumerated types in query + if (enumerator) + { + while (enumerator->enumerate(enumerator, &aint, &atext)) + { + printf("%d: %s\n", aint, atext); + } + enumerator->destroy(enumerator); + } + @endcode + */ +struct database_t { + + /** + * Run a query which returns rows, such as a SELECT. + * + * @param sql sql query string, containing '?' placeholders + * @param ... list of sql placeholder db_type_t followed by its value, + * followed by enumerators arguments as db_type_t's + * @return enumerator as defined with arguments, NULL on failure + */ + enumerator_t* (*query)(database_t *this, char *sql, ...); + + /** + * Execute a query which dows not return rows, such as INSERT. + * + * @param rowid pointer to write inserted AUTO_INCREMENT row ID, or NULL + * @param sql sql string, containing '?' placeholders + * @param ... list of sql placeholder db_type_t followed by its value + * @return number of affected rows, < 0 on failure + */ + int (*execute)(database_t *this, int *rowid, char *sql, ...); + + /** + * Destroy a database connection. + */ + void (*destroy)(database_t *this); +}; + +#endif /* DATABASE_H_ @}*/ diff --git a/src/libstrongswan/database/database_factory.c b/src/libstrongswan/database/database_factory.c new file mode 100644 index 000000000..9ceb829c6 --- /dev/null +++ b/src/libstrongswan/database/database_factory.c @@ -0,0 +1,119 @@ +/* + * 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: database_factory.c 3488 2008-02-21 15:10:02Z martin $ + */ + +#include "database_factory.h" + +#include <utils/linked_list.h> +#include <utils/mutex.h> + +typedef struct private_database_factory_t private_database_factory_t; + +/** + * private data of database_factory + */ +struct private_database_factory_t { + + /** + * public functions + */ + database_factory_t public; + + /** + * list of registered database_t implementations + */ + linked_list_t *databases; + + /** + * mutex to lock access to databases + */ + mutex_t *mutex; +}; + +/** + * Implementation of database_factory_t.create. + */ +static database_t* create(private_database_factory_t *this, char *uri) +{ + enumerator_t *enumerator; + database_t *database = NULL; + database_constructor_t create; + + this->mutex->lock(this->mutex); + enumerator = this->databases->create_enumerator(this->databases); + while (enumerator->enumerate(enumerator, &create)) + { + database = create(uri); + if (database) + { + break; + } + } + enumerator->destroy(enumerator); + this->mutex->unlock(this->mutex); + return database; +} + +/** + * Implementation of database_factory_t.add_database. + */ +static void add_database(private_database_factory_t *this, + database_constructor_t create) +{ + this->mutex->lock(this->mutex); + this->databases->insert_last(this->databases, create); + this->mutex->unlock(this->mutex); +} + +/** + * Implementation of database_factory_t.remove_database. + */ +static void remove_database(private_database_factory_t *this, + database_constructor_t create) +{ + this->mutex->lock(this->mutex); + this->databases->remove(this->databases, create, NULL); + this->mutex->unlock(this->mutex); +} + +/** + * Implementation of database_factory_t.destroy + */ +static void destroy(private_database_factory_t *this) +{ + this->databases->destroy(this->databases); + this->mutex->destroy(this->mutex); + free(this); +} + +/* + * see header file + */ +database_factory_t *database_factory_create() +{ + private_database_factory_t *this = malloc_thing(private_database_factory_t); + + this->public.create = (database_t*(*)(database_factory_t*, char *url))create; + this->public.add_database = (void(*)(database_factory_t*, database_constructor_t))add_database; + this->public.remove_database = (void(*)(database_factory_t*, database_constructor_t))remove_database; + this->public.destroy = (void(*)(database_factory_t*))destroy; + + this->databases = linked_list_create(); + this->mutex = mutex_create(MUTEX_DEFAULT); + + return &this->public; +} + diff --git a/src/libstrongswan/database/database_factory.h b/src/libstrongswan/database/database_factory.h new file mode 100644 index 000000000..358f49054 --- /dev/null +++ b/src/libstrongswan/database/database_factory.h @@ -0,0 +1,73 @@ +/* + * 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 database_factory database_factory + * @{ @ingroup database + */ + +#ifndef DATABASE_FACTORY_H_ +#define DATABASE_FACTORY_H_ + +typedef struct database_factory_t database_factory_t; + +#include <database/database.h> + +/** + * Generic database construction function. + * + * @param uri implementation specific connection URI + */ +typedef database_t*(*database_constructor_t)(char *uri); + +/** + * Create instances of database connections using registered constructors. + */ +struct database_factory_t { + + /** + * Create a database connection instance. + * + * @param uri implementation specific connection URI + * @return database_t instance, NULL if not supported/failed + */ + database_t* (*create)(database_factory_t *this, char *uri); + + /** + * Register a database constructor. + * + * @param create database constructor to register + */ + void (*add_database)(database_factory_t *this, database_constructor_t create); + + /** + * Unregister a previously registered database constructor. + * + * @param create database constructor to unregister + */ + void (*remove_database)(database_factory_t *this, database_constructor_t create); + + /** + * Destroy a database_factory instance. + */ + void (*destroy)(database_factory_t *this); +}; + +/** + * Create a database_factory instance. + */ +database_factory_t *database_factory_create(); + +#endif /* DATABASE_FACTORY_H_ @}*/ diff --git a/src/libstrongswan/debug.c b/src/libstrongswan/debug.c index a71e978b8..e20bef2da 100644 --- a/src/libstrongswan/debug.c +++ b/src/libstrongswan/debug.c @@ -1,10 +1,3 @@ -/** - * @file library.c - * - * @brief Logging functions for the library. - * - */ - /* * Copyright (C) 2006 Martin Willi * Hochschule fuer Technik Rapperswil @@ -18,6 +11,8 @@ * 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: debug.c 4058 2008-06-11 14:09:46Z martin $ */ #include <stdarg.h> @@ -30,12 +25,15 @@ */ void dbg_default(int level, char *fmt, ...) { - va_list args; + if (level <= 1) + { + va_list args; - va_start(args, fmt); - vfprintf(stderr, fmt, args); - fprintf(stderr, "\n"); - va_end(args); + va_start(args, fmt); + vfprintf(stderr, fmt, args); + fprintf(stderr, "\n"); + va_end(args); + } } void (*dbg) (int level, char *fmt, ...) = dbg_default; diff --git a/src/libstrongswan/debug.h b/src/libstrongswan/debug.h index 71f2c7dfd..b120cc601 100644 --- a/src/libstrongswan/debug.h +++ b/src/libstrongswan/debug.h @@ -1,10 +1,3 @@ -/** - * @file log.h - * - * @brief Logging functions for the library. - * - */ - /* * Copyright (C) 2006 Martin Willi * Hochschule fuer Technik Rapperswil @@ -18,6 +11,13 @@ * 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: debug.h 3589 2008-03-13 14:14:44Z martin $ + */ + +/** + * @defgroup debug debug + * @{ @ingroup libstrongswan */ #ifndef DEBUG_H_ @@ -60,4 +60,4 @@ extern void (*dbg) (int level, char *fmt, ...); /** default logging function, prints to stderr */ void dbg_default(int level, char *fmt, ...); -#endif /* DEBUG_H_ */ +#endif /* DEBUG_H_ @} */ diff --git a/src/libstrongswan/enum.c b/src/libstrongswan/enum.c index ade7c16a1..5eb283807 100644 --- a/src/libstrongswan/enum.c +++ b/src/libstrongswan/enum.c @@ -1,10 +1,3 @@ -/** - * @file library.c - * - * @brief enum value to string conversion functions. - * - */ - /* * Copyright (C) 2006 Martin Willi * Hochschule fuer Technik Rapperswil @@ -18,6 +11,8 @@ * 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: enum.c 3589 2008-03-13 14:14:44Z martin $ */ #include <stddef.h> @@ -46,7 +41,7 @@ static char *enum_name(enum_name_t *e, int val) /** * output handler in printf() for enum names */ -static int print_enum(FILE *stream, const struct printf_info *info, +static int print(FILE *stream, const struct printf_info *info, const void *const *args) { enum_name_t *ed = *((enum_name_t**)(args[0])); @@ -65,9 +60,25 @@ static int print_enum(FILE *stream, const struct printf_info *info, } /** - * register printf() handlers + * arginfo handler for printf() hook + */ +static int arginfo(const struct printf_info *info, size_t n, int *argtypes) +{ + if (n > 1) + { + argtypes[0] = PA_POINTER; + argtypes[1] = PA_INT; + } + return 2; +} + +/** + * return printf hook functions */ -static void __attribute__ ((constructor))print_register() +printf_hook_functions_t enum_get_printf_hooks() { - register_printf_function(PRINTF_ENUM, print_enum, arginfo_ptr_int); + printf_hook_functions_t hooks = {print, arginfo}; + + return hooks; } + diff --git a/src/libstrongswan/enum.h b/src/libstrongswan/enum.h index cd06e424b..5e44293c0 100644 --- a/src/libstrongswan/enum.h +++ b/src/libstrongswan/enum.h @@ -1,12 +1,5 @@ -/** - * @file enum.h - * - * @brief enum value to string conversion functions. - * - */ - /* - * Copyright (C) 2006 Martin Willi + * Copyright (C) 2006-2008 Martin Willi * Hochschule fuer Technik Rapperswil * * This program is free software; you can redistribute it and/or modify it @@ -18,15 +11,24 @@ * 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: enum.h 3589 2008-03-13 14:14:44Z martin $ + */ + +/** + * @defgroup enum enum + * @{ @ingroup libstrongswan */ #ifndef ENUM_H_ #define ENUM_H_ +#include <printf_hook.h> + typedef struct enum_name_t enum_name_t; /** - * @brief Struct to store names for enums. + * Struct to store names for enums. * * To print the string representation of enumeration values, the strings * are stored in these structures. Every enum_name contains a range @@ -34,14 +36,16 @@ typedef struct enum_name_t enum_name_t; * Use the convenience macros to define these linked ranges. * * For a single range, use: - * ENUM(name, first, last, string1, string2, ...) - * + * @code + ENUM(name, first, last, string1, string2, ...) + @endcode * For multiple linked ranges, use: - * ENUM_BEGIN(name, first, last, string1, string2, ...) - * ENUM_NEXT(name, first, last, last_from_previous, string3, ...) - * ENUM_NEXT(name, first, last, last_from_previous, string4, ...) - * ENUM_END(name, last_from_previous) - * + * @code + ENUM_BEGIN(name, first, last, string1, string2, ...) + ENUM_NEXT(name, first, last, last_from_previous, string3, ...) + ENUM_NEXT(name, first, last, last_from_previous, string4, ...) + ENUM_END(name, last_from_previous) + @endcode * The ENUM and the ENUM_END define a enum_name_t pointer with the name supplied * in "name". * @@ -62,7 +66,7 @@ struct enum_name_t { }; /** - * @brief Begin a new enum_name list. + * Begin a new enum_name list. * * @param name name of the enum_name list * @param first enum value of the first enum string @@ -72,7 +76,7 @@ struct enum_name_t { #define ENUM_BEGIN(name, first, last, ...) static enum_name_t name##last = {first, last, NULL, { __VA_ARGS__ }} /** - * @brief Continue a enum name list startetd with ENUM_BEGIN. + * Continue a enum name list startetd with ENUM_BEGIN. * * @param name name of the enum_name list * @param first enum value of the first enum string @@ -83,7 +87,7 @@ struct enum_name_t { #define ENUM_NEXT(name, first, last, prev, ...) static enum_name_t name##last = {first, last, &name##prev, { __VA_ARGS__ }} /** - * @brief Complete enum name list started with ENUM_BEGIN. + * Complete enum name list started with ENUM_BEGIN. * * @param name name of the enum_name list * @param prev enum value of the "last" defined in ENUM_BEGIN/previous ENUM_NEXT @@ -91,7 +95,7 @@ struct enum_name_t { #define ENUM_END(name, prev) enum_name_t *name = &name##prev; /** - * @brief Define a enum name with only one range. + * Define a enum name with only one range. * * This is a convenience macro to use when a enum_name list contains only * one range, and is equal as defining ENUM_BEGIN followed by ENUM_END. @@ -103,4 +107,13 @@ struct enum_name_t { */ #define ENUM(name, first, last, ...) ENUM_BEGIN(name, first, last, __VA_ARGS__); ENUM_END(name, last) -#endif /* ENUM_H_ */ +/** + * Get printf hook functions for enum_names_t. + * + * The handler takes the arguments: enum_names_t *names, int value + * + * @return printf hook functions + */ +printf_hook_functions_t enum_get_printf_hooks(); + +#endif /* ENUM_H_ @}*/ diff --git a/src/libstrongswan/fetcher/fetcher.h b/src/libstrongswan/fetcher/fetcher.h new file mode 100644 index 000000000..4fc37e35e --- /dev/null +++ b/src/libstrongswan/fetcher/fetcher.h @@ -0,0 +1,105 @@ +/* + * 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 fetcheri fetcher + * @{ @ingroup fetcher + */ + +#ifndef FETCHER_H_ +#define FETCHER_H_ + +typedef struct fetcher_t fetcher_t; +typedef enum fetcher_option_t fetcher_option_t; + +#include <stdarg.h> + +#include <library.h> + +/** + * Fetching options to use for fetcher_t.fetch() call. + */ +enum fetcher_option_t { + + /** + * Data to include in fetch request, e.g. on a HTTP post. + * Additional argument is a chunk_t + */ + FETCH_REQUEST_DATA, + + /** + * Mime-Type of data included in FETCH_REQUEST_DATA. + * Additional argument is a char*. + */ + FETCH_REQUEST_TYPE, + + /** + * Timeout to use for fetch, in seconds. + * Additional argument is u_int + */ + FETCH_TIMEOUT, + + /** + * end of fetching options + */ + FETCH_END, +}; + +/** + * Constructor function which creates fetcher instances. + * + * @return fetcher instance + */ +typedef fetcher_t* (*fetcher_constructor_t)(); + +/** + * Fetcher interface, an implementation fetches data from an URL. + */ +struct fetcher_t { + + /** + * Fetch data from URI into chunk. + * + * The fetcher returns NOT_SUPPORTED to indicate that it is uncappable + * to handle such URLs. Other return values indicate a failure, and + * fetching of that URL gets cancelled. + * + * @param uri URI to fetch from + * @param result chunk which receives allocated data + * @return + * - SUCCESS if fetch was successful + * - NOT_SUPPORTED if fetcher does not support such URLs + * - FAILED, NOT_FOUND, PARSE_ERROR on failure + */ + status_t (*fetch)(fetcher_t *this, char *uri, chunk_t *result); + + /** + * Set a fetcher option, as defined in fetcher_option_t. + * + * Arguments passed to options must stay in memory until fetch() returns. + * + * @param option option to set + * @param ... variable argument(s) to option + * @return TRUE if option supported, FALSE otherwise + */ + bool (*set_option)(fetcher_t *this, fetcher_option_t option, ...); + + /** + * Destroy the fetcher instance. + */ + void (*destroy)(fetcher_t *this); +}; + +#endif /* FETCHER_H_ @}*/ diff --git a/src/libstrongswan/fetcher/fetcher_manager.c b/src/libstrongswan/fetcher/fetcher_manager.c new file mode 100644 index 000000000..517c9dfc9 --- /dev/null +++ b/src/libstrongswan/fetcher/fetcher_manager.c @@ -0,0 +1,208 @@ +/* + * 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: fetcher_manager.c 3630 2008-03-20 11:27:55Z martin $ + */ + +#define _GNU_SOURCE + +#include "fetcher_manager.h" + +#include <debug.h> +#include <utils/linked_list.h> +#include <utils/mutex.h> + +typedef struct private_fetcher_manager_t private_fetcher_manager_t; + +/** + * private data of fetcher_manager + */ +struct private_fetcher_manager_t { + + /** + * public functions + */ + fetcher_manager_t public; + + /** + * list of registered fetchers, as entry_t + */ + linked_list_t *fetchers; + + /** + * read write lock to list + */ + pthread_rwlock_t lock; +}; + +typedef struct { + /** assocaited fetcher construction function */ + fetcher_constructor_t create; + /** URL this fetcher support */ + char *url; +} entry_t; + +/** + * destroy an entry_t + */ +static void entry_destroy(entry_t *entry) +{ + free(entry->url); + free(entry); +} + +/** + * Implementation of fetcher_manager_t.fetch. + */ +static status_t fetch(private_fetcher_manager_t *this, + char *url, chunk_t *response, ...) +{ + enumerator_t *enumerator; + status_t status = NOT_SUPPORTED; + entry_t *entry; + bool capable = FALSE; + + pthread_rwlock_rdlock(&this->lock); + enumerator = this->fetchers->create_enumerator(this->fetchers); + while (enumerator->enumerate(enumerator, &entry)) + { + fetcher_option_t opt; + fetcher_t *fetcher; + bool good = TRUE; + va_list args; + + /* check URL support of fetcher */ + if (strncasecmp(entry->url, url, strlen(entry->url))) + { + continue; + } + /* create fetcher instance and set options */ + fetcher = entry->create(); + if (!fetcher) + { + continue; + } + va_start(args, response); + while (good) + { + opt = va_arg(args, fetcher_option_t); + switch (opt) + { + case FETCH_REQUEST_DATA: + good = fetcher->set_option(fetcher, opt, va_arg(args, chunk_t)); + continue; + case FETCH_REQUEST_TYPE: + good = fetcher->set_option(fetcher, opt, va_arg(args, char*)); + continue; + case FETCH_TIMEOUT: + good = fetcher->set_option(fetcher, opt, va_arg(args, u_int)); + continue; + case FETCH_END: + break;; + } + break; + } + va_end(args); + if (!good) + { /* fetcher does not support supplied options, try another */ + fetcher->destroy(fetcher); + continue; + } + + status = fetcher->fetch(fetcher, url, response); + fetcher->destroy(fetcher); + /* try another fetcher only if this one does not support that URL */ + if (status == NOT_SUPPORTED) + { + continue; + } + capable = TRUE; + break; + } + enumerator->destroy(enumerator); + pthread_rwlock_unlock(&this->lock); + if (!capable) + { + DBG1("unable to fetch from %s, no capable fetcher found", url); + } + return status; +} + +/** + * Implementation of fetcher_manager_t.add_fetcher. + */ +static void add_fetcher(private_fetcher_manager_t *this, + fetcher_constructor_t create, char *url) +{ + entry_t *entry = malloc_thing(entry_t); + + entry->url = strdup(url); + entry->create = create; + + pthread_rwlock_wrlock(&this->lock); + this->fetchers->insert_last(this->fetchers, entry); + pthread_rwlock_unlock(&this->lock); +} + +/** + * Implementation of fetcher_manager_t.remove_fetcher. + */ +static void remove_fetcher(private_fetcher_manager_t *this, + fetcher_constructor_t create) +{ + enumerator_t *enumerator; + entry_t *entry; + + pthread_rwlock_wrlock(&this->lock); + enumerator = this->fetchers->create_enumerator(this->fetchers); + while (enumerator->enumerate(enumerator, &entry)) + { + if (entry->create == create) + { + this->fetchers->remove_at(this->fetchers, enumerator); + entry_destroy(entry); + } + } + enumerator->destroy(enumerator); + pthread_rwlock_unlock(&this->lock); +} + +/** + * Implementation of fetcher_manager_t.destroy + */ +static void destroy(private_fetcher_manager_t *this) +{ + this->fetchers->destroy_function(this->fetchers, (void*)entry_destroy); + pthread_rwlock_destroy(&this->lock); + free(this); +} + +/* + * see header file + */ +fetcher_manager_t *fetcher_manager_create() +{ + private_fetcher_manager_t *this = malloc_thing(private_fetcher_manager_t); + + this->public.fetch = (status_t(*)(fetcher_manager_t*, char *url, chunk_t *response, ...))fetch; + this->public.add_fetcher = (void(*)(fetcher_manager_t*, fetcher_constructor_t,char*))add_fetcher; + this->public.remove_fetcher = (void(*)(fetcher_manager_t*, fetcher_constructor_t))remove_fetcher; + this->public.destroy = (void(*)(fetcher_manager_t*))destroy; + + this->fetchers = linked_list_create(); + pthread_rwlock_init(&this->lock, NULL); + + return &this->public; +} + diff --git a/src/libstrongswan/fetcher/fetcher_manager.h b/src/libstrongswan/fetcher/fetcher_manager.h new file mode 100644 index 000000000..e94d44494 --- /dev/null +++ b/src/libstrongswan/fetcher/fetcher_manager.h @@ -0,0 +1,74 @@ +/* + * 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 fetcher_manager fetcher_manager + * @{ @ingroup fetcher + */ + +#ifndef FETCHER_MANAGER_H_ +#define FETCHER_MANAGER_H_ + +typedef struct fetcher_manager_t fetcher_manager_t; + +#include <fetcher/fetcher.h> + +/** + * Fetches from URIs using registerd fetcher_t instances. + */ +struct fetcher_manager_t { + + /** + * Fetch data from URI into chunk. + * + * The variable argument list contains fetcher_option_t's, followed + * by a option specific data argument. + * + * @param uri URI to fetch from + * @param result chunk which receives allocated data + * @param options FETCH_END terminated fetcher_option_t arguments + * @return status indicating result of fetch + */ + status_t (*fetch)(fetcher_manager_t *this, char *url, chunk_t *response, ...); + + /** + * Register a fetcher implementation. + * + * @param constructor fetcher constructor function + * @param url URL type this fetcher fetches, e.g. "http://" + */ + void (*add_fetcher)(fetcher_manager_t *this, + fetcher_constructor_t constructor, char *url); + + /** + * Unregister a previously registered fetcher implementation. + * + * @param constructor fetcher constructor function to unregister + */ + void (*remove_fetcher)(fetcher_manager_t *this, + fetcher_constructor_t constructor); + + /** + * Destroy a fetcher_manager instance. + */ + void (*destroy)(fetcher_manager_t *this); +}; + +/** + * Create a fetcher_manager instance. + */ +fetcher_manager_t *fetcher_manager_create(); + +#endif /* FETCHER_MANAGER_H_ @}*/ diff --git a/src/libstrongswan/fips/fips.c b/src/libstrongswan/fips/fips.c index aba292d81..c268a7429 100644 --- a/src/libstrongswan/fips/fips.c +++ b/src/libstrongswan/fips/fips.c @@ -1,10 +1,3 @@ -/** - * @file fips.c - * - * @brief Implementation of the libstrongswan integrity test. - * - */ - /* * Copyright (C) 2007 Bruno Krieg, Daniel Wydler * Hochschule fuer Technik Rapperswil @@ -18,12 +11,14 @@ * 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.c 3681 2008-03-28 10:21:04Z martin $ */ #include <stdio.h> #include <debug.h> -#include <crypto/signers/hmac_signer.h> +#include <crypto/signers/signer.h> #include "fips.h" extern const u_char FIPS_rodata_start[]; @@ -61,7 +56,7 @@ bool fips_compute_hmac_signature(const char *key, char *signature) DBG1(" RODATA: %p + %6d = %p", FIPS_rodata_start, (int)rodata_len, FIPS_rodata_end); - signer = (signer_t *)hmac_signer_create(HASH_SHA1, HASH_SIZE_SHA1); + signer = lib->crypto->create_signer(lib->crypto, AUTH_HMAC_SHA1_128); if (signer == NULL) { DBG1(" SHA-1 HMAC signer could not be created"); @@ -69,7 +64,7 @@ bool fips_compute_hmac_signature(const char *key, char *signature) } else { - chunk_t hmac_key = { key, strlen(key) }; + chunk_t hmac_key = { (u_char *)key, strlen(key) }; chunk_t text_chunk = { text_start, text_len }; chunk_t rodata_chunk = { (u_char *)FIPS_rodata_start, rodata_len }; chunk_t signature_chunk = chunk_empty; diff --git a/src/libstrongswan/fips/fips.h b/src/libstrongswan/fips/fips.h index decf73bfd..a4ff440ba 100644 --- a/src/libstrongswan/fips/fips.h +++ b/src/libstrongswan/fips/fips.h @@ -1,11 +1,3 @@ -/** - * @file fips.h - * - * @brief Interface of the libstrongswan integrity test - * - * @ingroup fips - */ - /* * Copyright (C) 2007 Bruno Krieg, Daniel Wydler * Hochschule fuer Technik Rapperswil @@ -19,6 +11,13 @@ * 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.h 3877 2008-04-26 09:40:22Z andreas $ + */ + +/** + * @defgroup fips1 fips + * @{ @ingroup fips */ #ifndef FIPS_H_ @@ -27,21 +26,21 @@ #include <library.h> /** - * @brief compute HMAC signature over RODATA and TEXT sections of libstrongswan + * compute HMAC signature over RODATA and TEXT sections of libstrongswan * - * @param key key used for HMAC signature in ASCII string format - * @param signature HMAC signature in HEX string format - * @return TRUE if HMAC signature computation was successful + * @param key key used for HMAC signature in ASCII string format + * @param signature HMAC signature in HEX string format + * @return TRUE if HMAC signature computation was successful */ bool fips_compute_hmac_signature(const char *key, char *signature); /** - * @brief verify HMAC signature over RODATA and TEXT sections of libstrongswan + * verify HMAC signature over RODATA and TEXT sections of libstrongswan * - * @param key key used for HMAC signature in ASCII string format - * @param signature signature value from fips_signature.h in HEX string format - * @return TRUE if signatures agree + * @param key key used for HMAC signature in ASCII string format + * @param signature signature value from fips_signature.h in HEX string format + * @return TRUE if signatures agree */ bool fips_verify_hmac_signature(const char *key, const char *signature); -#endif /*FIPS_H_*/ +#endif /*FIPS_H_ @} */ diff --git a/src/libstrongswan/fips/fips_canister_end.c b/src/libstrongswan/fips/fips_canister_end.c index 46d41a664..93f78e696 100644 --- a/src/libstrongswan/fips/fips_canister_end.c +++ b/src/libstrongswan/fips/fips_canister_end.c @@ -1,14 +1,9 @@ -/** - * @file fips_canister_end.c - * - * @brief Marks the end of TEXT and RODATA. - * - */ - /* ==================================================================== * Copyright (c) 2005 The OpenSSL Project. Rights for redistribution * and usage in source and binary forms are granted according to the * OpenSSL license. + * + * $Id: fips_canister_end.c 3589 2008-03-13 14:14:44Z martin $ */ #include <stdio.h> diff --git a/src/libstrongswan/fips/fips_canister_start.c b/src/libstrongswan/fips/fips_canister_start.c index eaf2571f8..a15517ec1 100644 --- a/src/libstrongswan/fips/fips_canister_start.c +++ b/src/libstrongswan/fips/fips_canister_start.c @@ -1,14 +1,9 @@ -/** - * @file fips_canister_start.c - * - * @brief Marks the start of TEXT and RODATA. - * - */ - /* ==================================================================== * Copyright (c) 2005 The OpenSSL Project. Rights for redistribution * and usage in source and binary forms are granted according to the * OpenSSL license. + * + * $Id: fips_canister_start.c 3589 2008-03-13 14:14:44Z martin $ */ #include <stdio.h> diff --git a/src/libstrongswan/fips/fips_signer.c b/src/libstrongswan/fips/fips_signer.c index 7fb61d5b7..81a5874f7 100644 --- a/src/libstrongswan/fips/fips_signer.c +++ b/src/libstrongswan/fips/fips_signer.c @@ -1,10 +1,3 @@ -/** - * @file fips_signer.c - * - * @brief Computes a HMAC signature and stores it in fips_signature.h. - * - */ - /* * Copyright (C) 2007 Bruno Krieg, Daniel Wydler * Hochschule fuer Technik Rapperswil, Switzerland @@ -18,6 +11,8 @@ * 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_signer.c 3964 2008-05-15 14:01:26Z martin $ */ #include <stdio.h> @@ -31,6 +26,10 @@ int main(int argc, char* argv[]) char *hmac_key = "strongSwan Version " VERSION; char hmac_signature[BUF_LEN]; + /* initialize library */ + library_init(STRONGSWAN_CONF); + lib->plugins->load(lib->plugins, IPSEC_PLUGINDIR, "sha1 hmac"); + if (!fips_compute_hmac_signature(hmac_key, hmac_signature)) { exit(1); @@ -57,7 +56,9 @@ int main(int argc, char* argv[]) fprintf(f, "const char *hmac_key = \"%s\";\n", hmac_key); fprintf(f, "const char *hmac_signature = \"%s\";\n", hmac_signature); fprintf(f, "\n"); - fprintf(f, "#endif /* FIPS_SIGNATURE_H_ */\n"); + fprintf(f, "#endif /* FIPS_SIGNATURE_H_ @} */\n"); fclose(f); + + library_deinit(); exit(0); } diff --git a/src/libstrongswan/library.c b/src/libstrongswan/library.c index f66818bc2..cc3ee6bd6 100644 --- a/src/libstrongswan/library.c +++ b/src/libstrongswan/library.c @@ -1,13 +1,5 @@ -/** - * @file library.c - * - * @brief Helper functions and definitions. - * - */ - /* - * Copyright (C) 2005-2006 Martin Willi - * Copyright (C) 2005 Jan Hutter + * Copyright (C) 2008 Martin Willi * Hochschule fuer Technik Rapperswil * * This program is free software; you can redistribute it and/or modify it @@ -19,175 +11,101 @@ * 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: library.c 3750 2008-04-04 11:38:16Z martin $ */ -#include <string.h> -#include <time.h> -#include <stdio.h> -#include <stdarg.h> -#include <pthread.h> - #include "library.h" -#include <printf_hook.h> +#include <stdlib.h> -ENUM(status_names, SUCCESS, DESTROY_ME, - "SUCCESS", - "FAILED", - "OUT_OF_RES", - "ALREADY_DONE", - "NOT_SUPPORTED", - "INVALID_ARG", - "NOT_FOUND", - "PARSE_ERROR", - "VERIFY_ERROR", - "INVALID_STATE", - "DESTROY_ME", - "NEED_MORE", -); +#include <utils.h> +#include <chunk.h> +#include <utils/identification.h> +#include <utils/host.h> +#ifdef LEAK_DETECTIVE +#include <utils/leak_detective.h> +#endif -/** - * Described in header. - */ -void *clalloc(void * pointer, size_t size) -{ - void *data; - data = malloc(size); - - memcpy(data, pointer,size); - - return (data); -} +typedef struct private_library_t private_library_t; /** - * Described in header. + * private data of library */ -void memxor(u_int8_t dest[], u_int8_t src[], size_t n) -{ - size_t i; - for (i = 0; i < n; i++) - { - dest[i] ^= src[i]; - } -} +struct private_library_t { -/** - * We use a single mutex for all refcount variables. This - * is not optimal for performance, but the critical section - * is not that long... - * TODO: Consider to include a mutex in each refcount_t variable. - */ -static pthread_mutex_t ref_mutex = PTHREAD_MUTEX_INITIALIZER; + /** + * public functions + */ + library_t public; -/** - * Described in header. - * - * TODO: May be implemented with atomic CPU instructions - * instead of a mutex. - */ -void ref_get(refcount_t *ref) -{ - pthread_mutex_lock(&ref_mutex); - (*ref)++; - pthread_mutex_unlock(&ref_mutex); -} +#ifdef LEAK_DETECTIVE + /** + * Memory leak detective, if enabled + */ + leak_detective_t *detective; +#endif /* LEAK_DETECTIVE */ +}; /** - * Described in header. - * - * TODO: May be implemented with atomic CPU instructions - * instead of a mutex. + * library instance */ -bool ref_put(refcount_t *ref) -{ - bool more_refs; - - pthread_mutex_lock(&ref_mutex); - more_refs = --(*ref); - pthread_mutex_unlock(&ref_mutex); - return !more_refs; -} +library_t *lib; /** - * output handler in printf() for time_t + * Implementation of library_t.destroy */ -static int print_time(FILE *stream, const struct printf_info *info, - const void *const *args) +void library_deinit() { - static const char* months[] = { - "Jan", "Feb", "Mar", "Apr", "May", "Jun", - "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" - }; - time_t *time = *((time_t**)(args[0])); - bool utc = TRUE; - struct tm t; + private_library_t *this = (private_library_t*)lib; + + this->public.plugins->destroy(this->public.plugins); + this->public.settings->destroy(this->public.settings); + this->public.creds->destroy(this->public.creds); + this->public.crypto->destroy(this->public.crypto); + this->public.fetcher->destroy(this->public.fetcher); + this->public.db->destroy(this->public.db); + this->public.printf_hook->destroy(this->public.printf_hook); - if (info->alt) - { - utc = *((bool*)(args[1])); - } - if (time == UNDEFINED_TIME) - { - return fprintf(stream, "--- -- --:--:--%s----", - info->alt ? " UTC " : " "); - } - if (utc) - { - gmtime_r(time, &t); - } - else +#ifdef LEAK_DETECTIVE + if (this->detective) { - localtime_r(time, &t); + this->detective->destroy(this->detective); } - return fprintf(stream, "%s %02d %02d:%02d:%02d%s%04d", - months[t.tm_mon], t.tm_mday, t.tm_hour, t.tm_min, - t.tm_sec, utc ? " UTC " : " ", t.tm_year + 1900); +#endif /* LEAK_DETECTIVE */ + free(this); + lib = NULL; } -/** - * output handler in printf() for time deltas +/* + * see header file */ -static int print_time_delta(FILE *stream, const struct printf_info *info, - const void *const *args) +void library_init(char *settings) { - char* unit = "second"; - time_t *arg1, *arg2; - time_t delta; + printf_hook_t *pfh; + private_library_t *this = malloc_thing(private_library_t); + lib = &this->public; - arg1 = *((time_t**)(args[0])); - if (info->alt) - { - arg2 = *((time_t**)(args[1])); - delta = abs(*arg1 - *arg2); - } - else - { - delta = *arg1; - } +#ifdef LEAK_DETECTIVE + this->detective = leak_detective_create(); +#endif /* LEAK_DETECTIVE */ - if (delta > 2 * 60 * 60 * 24) - { - delta /= 60 * 60 * 24; - unit = "day"; - } - else if (delta > 2 * 60 * 60) - { - delta /= 60 * 60; - unit = "hour"; - } - else if (delta > 2 * 60) - { - delta /= 60; - unit = "minute"; - } - return fprintf(stream, "%d %s%s", delta, unit, (delta == 1)? "":"s"); + pfh = printf_hook_create(); + this->public.printf_hook = pfh; + + pfh->add_handler(pfh, 'b', mem_get_printf_hooks()); + pfh->add_handler(pfh, 'B', chunk_get_printf_hooks()); + pfh->add_handler(pfh, 'D', identification_get_printf_hooks()); + pfh->add_handler(pfh, 'H', host_get_printf_hooks()); + pfh->add_handler(pfh, 'N', enum_get_printf_hooks()); + pfh->add_handler(pfh, 'T', time_get_printf_hooks()); + pfh->add_handler(pfh, 'V', time_delta_get_printf_hooks()); + + this->public.crypto = crypto_factory_create(); + this->public.creds = credential_factory_create(); + this->public.fetcher = fetcher_manager_create(); + this->public.db = database_factory_create(); + this->public.settings = settings_create(settings); + this->public.plugins = plugin_loader_create(); } -/** - * register printf() handlers for time_t - */ -static void __attribute__ ((constructor))print_register() -{ - register_printf_function(PRINTF_TIME, print_time, arginfo_ptr_alt_ptr_int); - register_printf_function(PRINTF_TIME_DELTA, print_time_delta, arginfo_ptr_alt_ptr_ptr); -} diff --git a/src/libstrongswan/library.h b/src/libstrongswan/library.h index 51b72bfce..6cb57ef20 100644 --- a/src/libstrongswan/library.h +++ b/src/libstrongswan/library.h @@ -1,12 +1,5 @@ -/** - * @file library.h - * - * @brief Helper functions and definitions. - * - */ - /* - * Copyright (C) 2006 Martin Willi + * Copyright (C) 2008 Martin Willi * Hochschule fuer Technik Rapperswil * * This program is free software; you can redistribute it and/or modify it @@ -19,318 +12,119 @@ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * - * RCSID $Id: library.h 3255 2007-10-07 13:35:42Z andreas $ + * $Id: library.h 3589 2008-03-13 14:14:44Z martin $ */ -#ifndef LIBRARY_H_ -#define LIBRARY_H_ - /** * @defgroup libstrongswan libstrongswan * - * libstrongswan: library with various cryptographic, X.509 trust chain and - * identity management functions. - */ - -/** * @defgroup asn1 asn1 - * - * ASN.1 definitions, parser and generator functions. - * * @ingroup libstrongswan - */ - -/** - * @defgroup crypto crypto - * - * Various cryptographic algorithms. * + * @defgroup credentials credentials * @ingroup libstrongswan - */ - -/** - * @defgroup crypters crypters - * - * Symmetric encryption algorithms, used for - * encryption and decryption. - * - * @ingroup crypto - */ - -/** - * @defgroup hashers hashers - * - * Hashing algorithms, such as MD5 or SHA1 - * - * @ingroup crypto - */ - -/** - * @defgroup prfs prfs - * - * Pseudo random functions, used to generate - * pseude random byte sequences. - * - * @ingroup crypto - */ - -/** - * @defgroup rsa rsa - * - * RSA private/public key algorithm. * - * @ingroup crypto - */ - -/** - * @defgroup signers signers + * @defgroup keys keys + * @ingroup credentials * - * Symmetric signing algorithms, - * used to ensure message integrity. + * @defgroup certificates certificates + * @ingroup credentials * - * @ingroup crypto - */ - -/** + * @defgroup crypto crypto + * @ingroup libstrongswan + + * @defgroup database database + * @ingroup libstrongswan + + * @defgroup fetcher fetcher + * @ingroup libstrongswan + * @defgroup fips fips - * - * Code integrity check of libstrongswan - * * @ingroup libstrongswan - */ - -/** + + * @defgroup plugins plugins + * @ingroup libstrongswan + * @defgroup utils utils - * - * Generic helper classes. - * * @ingroup libstrongswan */ -#include <gmp.h> -#include <sys/types.h> -#include <stdlib.h> -#include <stddef.h> -#include <printf.h> - -#include <enum.h> - -/** - * Number of bits in a byte - */ -#define BITS_PER_BYTE 8 - -/** - * Default length for various auxiliary text buffers - */ -#define BUF_LEN 512 - -/** - * Macro compares two strings for equality - */ -#define streq(x,y) (strcmp(x, y) == 0) - -/** - * Macro compares two strings for equality - */ -#define strneq(x,y,len) (strncmp(x, y, len) == 0) - -/** - * Macro compares two binary blobs for equality - */ -#define memeq(x,y,len) (memcmp(x, y, len) == 0) - -/** - * Macro gives back larger of two values. - */ -#define max(x,y) ((x) > (y) ? (x):(y)) - -/** - * Macro gives back smaller of two values. - */ -#define min(x,y) ((x) < (y) ? (x):(y)) - -/** - * Call destructor of an object, if object != NULL - */ -#define DESTROY_IF(obj) if (obj) obj->destroy(obj) - -/** - * Call offset destructor of an object, if object != NULL - */ -#define DESTROY_OFFSET_IF(obj, offset) if (obj) obj->destroy_offset(obj, offset); - /** - * Call function destructor of an object, if object != NULL + * @defgroup library library + * @{ @ingroup libstrongswan */ -#define DESTROY_FUNCTION_IF(obj, fn) if (obj) obj->destroy_function(obj, fn); -/** - * Debug macro to follow control flow - */ -#define POS printf("%s, line %d\n", __FILE__, __LINE__) - -/** - * Macro to allocate a sized type. - */ -#define malloc_thing(thing) ((thing*)malloc(sizeof(thing))) +#ifndef LIBRARY_H_ +#define LIBRARY_H_ -/** - * Assign a function as a class method - */ -#define ASSIGN(method, function) (method = (typeof(method))function) +#include <utils.h> +#include <chunk.h> +#include <settings.h> +#include <printf_hook.h> +#include <plugins/plugin_loader.h> +#include <crypto/crypto_factory.h> +#include <credentials/credential_factory.h> +#include <fetcher/fetcher_manager.h> +#include <database/database_factory.h> -/** - * time_t not defined - */ -#define UNDEFINED_TIME 0 +typedef struct library_t library_t; /** - * General purpose boolean type. + * Libstrongswan library context, contains library relevant globals. */ -typedef int bool; -#define FALSE 0 -#define TRUE 1 - -typedef enum status_t status_t; +struct library_t { -/** - * Return values of function calls. - */ -enum status_t { - /** - * Call succeeded. - */ - SUCCESS, - - /** - * Call failed. - */ - FAILED, - - /** - * Out of resources. - */ - OUT_OF_RES, - - /** - * The suggested operation is already done - */ - ALREADY_DONE, - /** - * Not supported. + * Printf hook registering facility */ - NOT_SUPPORTED, + printf_hook_t *printf_hook; /** - * One of the arguments is invalid. + * crypto algorithm registry and factory */ - INVALID_ARG, + crypto_factory_t *crypto; /** - * Something could not be found. + * credential constructor registry and factory */ - NOT_FOUND, + credential_factory_t *creds; /** - * Error while parsing. + * URL fetching facility */ - PARSE_ERROR, + fetcher_manager_t *fetcher; /** - * Error while verifying. + * database construction factory */ - VERIFY_ERROR, + database_factory_t *db; /** - * Object in invalid state. + * plugin loading facility */ - INVALID_STATE, + plugin_loader_t *plugins; /** - * Destroy object which called method belongs to. + * various settings loaded from settings file */ - DESTROY_ME, - - /** - * Another call to the method is required. - */ - NEED_MORE, + settings_t *settings; }; /** - * used by strict_crl_policy - */ -typedef enum { - STRICT_NO, - STRICT_YES, - STRICT_IFURI -} strict_t; - -/** - * enum_names for type status_t. - */ -extern enum_name_t *status_names; - -/** - * deprecated pluto style return value: - * error message, NULL for success - */ -typedef const char *err_t; - -/** - * Handle struct timeval like an own type. - */ -typedef struct timeval timeval_t; - -/** - * Handle struct timespec like an own type. - */ -typedef struct timespec timespec_t; - -/** - * Handle struct chunk_t like an own type. - */ -typedef struct sockaddr sockaddr_t; - -/** - * Clone a data to a newly allocated buffer - */ -void *clalloc(void *pointer, size_t size); - -/** - * Same as memcpy, but XORs src into dst instead of copy - */ -void memxor(u_int8_t dest[], u_int8_t src[], size_t n); - -/** - * Special type to count references + * Initialize library, creates "lib" instance. + * + * @param settings file to read settings from, may be NULL for none */ -typedef volatile u_int refcount_t; +void library_init(char *settings); /** - * @brief Get a new reference. - * - * Increments the reference counter atomic. - * - * @param ref pointer to ref counter + * Deinitialize library, destroys "lib" instance. */ -void ref_get(refcount_t *ref); +void library_deinit(); /** - * @brief Put back a unused reference. - * - * Decrements the reference counter atomic and - * says if more references available. - * - * @param ref pointer to ref counter - * @return TRUE if no more references counted + * Library instance, set after between library_init() and library_deinit() calls. */ -bool ref_put(refcount_t *ref); - - -#include <chunk.h> -#include <printf_hook.h> +extern library_t *lib; -#endif /* LIBRARY_H_ */ +#endif /* LIBRARY_H_ @}*/ 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/crypto/crypters/aes_cbc_crypter.c b/src/libstrongswan/plugins/aes/aes_crypter.c index 947188af3..ce4c6da99 100644 --- a/src/libstrongswan/crypto/crypters/aes_cbc_crypter.c +++ b/src/libstrongswan/plugins/aes/aes_crypter.c @@ -1,11 +1,4 @@ -/** - * @file aes_cbc_crypter.c - * - * @brief Implementation of aes_cbc_crypter_t - * - */ - - /* +/* * Copyright (C) 2001 Dr B. R. Gladman <brg@gladman.uk.net> * Copyright (C) 2005-2006 Martin Willi * Copyright (C) 2005 Jan Hutter @@ -20,11 +13,11 @@ * 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_cbc_crypter.h" - - +#include "aes_crypter.h" /* * The number of key schedule words for different block and key lengths @@ -43,19 +36,19 @@ #define AES_BLOCK_SIZE 16 -typedef struct private_aes_cbc_crypter_t private_aes_cbc_crypter_t; +typedef struct private_aes_crypter_t private_aes_crypter_t; /** - * @brief Class implementing the AES symmetric encryption algorithm. + * Class implementing the AES symmetric encryption algorithm. * * @ingroup crypters */ -struct private_aes_cbc_crypter_t { +struct private_aes_crypter_t { /** * Public part of this class. */ - aes_cbc_crypter_t public; + aes_crypter_t public; /** * Number of words in the key input block. @@ -81,28 +74,6 @@ struct private_aes_cbc_crypter_t { * Key size of this AES cypher object. */ u_int32_t key_size; - - /** - * Decrypts a block. - * - * No memory gets allocated. - * - * @param this calling object - * @param[in] in_blk block to decrypt - * @param[out] out_blk decrypted data are written to this location - */ - void (*decrypt_block) (const private_aes_cbc_crypter_t *this, const unsigned char in_blk[], unsigned char out_blk[]); - - /** - * Encrypts a block. - * - * No memory gets allocated. - * - * @param this calling object - * @param[in] in_blk block to encrypt - * @param[out] out_blk encrypted data are written to this location - */ - void (*encrypt_block) (const private_aes_cbc_crypter_t *this, const unsigned char in_blk[], unsigned char out_blk[]); }; @@ -1243,9 +1214,9 @@ switch(nc) \ #endif /** - * Implementation of private_aes_cbc_crypter_t.encrypt_block. + * Encrypt a single block of data. */ -static void encrypt_block(const private_aes_cbc_crypter_t *this, const unsigned char in_blk[], unsigned char out_blk[]) +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; @@ -1304,9 +1275,9 @@ static void encrypt_block(const private_aes_cbc_crypter_t *this, const unsigned } /** - * Implementation of private_aes_cbc_crypter_t.decrypt_block. + * Decrypt a single block of data. */ -static void decrypt_block(const private_aes_cbc_crypter_t *this, const unsigned char in_blk[], unsigned char out_blk[]) +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; @@ -1367,38 +1338,38 @@ static void decrypt_block(const private_aes_cbc_crypter_t *this, const unsigned /** * Implementation of crypter_t.decrypt. */ -static status_t decrypt (private_aes_cbc_crypter_t *this, chunk_t data, chunk_t iv, chunk_t *decrypted) +static void decrypt(private_aes_crypter_t *this, chunk_t data, chunk_t iv, + chunk_t *decrypted) { - int ret, pos; + int pos; const u_int32_t *iv_i; u_int8_t *in, *out; - ret = data.len; - if (((data.len) % 16) != 0) + if (decrypted) { - /* data length must be padded to a multiple of blocksize */ - return INVALID_ARG; + *decrypted = chunk_alloc(data.len); + out = decrypted->ptr; } - - decrypted->ptr = malloc(data.len); - if (decrypted->ptr == NULL) + else { - return OUT_OF_RES; + out = data.ptr; } - decrypted->len = data.len; - in = data.ptr; - out = decrypted->ptr; - pos=data.len-16; - in+=pos; - out+=pos; - while(pos>=0) { - this->decrypt_block(this,in,out); + 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]; @@ -1407,60 +1378,53 @@ static status_t decrypt (private_aes_cbc_crypter_t *this, chunk_t data, chunk_t out-=16; pos-=16; } - - return SUCCESS; } /** * Implementation of crypter_t.decrypt. */ -static status_t encrypt (private_aes_cbc_crypter_t *this, chunk_t data, chunk_t iv, chunk_t *encrypted) +static void encrypt (private_aes_crypter_t *this, chunk_t data, chunk_t iv, + chunk_t *encrypted) { - int ret, pos; + int pos; const u_int32_t *iv_i; u_int8_t *in, *out; - ret = data.len; - if (((data.len) % 16) != 0) + in = data.ptr; + out = data.ptr; + if (encrypted) { - /* data length must be padded to a multiple of blocksize */ - return INVALID_ARG; + *encrypted = chunk_alloc(data.len); + out = encrypted->ptr; } - encrypted->ptr = malloc(data.len); - if (encrypted->ptr == NULL) - { - return OUT_OF_RES; - } - encrypted->len = data.len; - - in = data.ptr; - 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])); - this->encrypt_block(this,out,out); + encrypt_block(this, out, out); in+=16; out+=16; pos+=16; } - return SUCCESS; } /** * Implementation of crypter_t.get_block_size. */ -static size_t get_block_size (private_aes_cbc_crypter_t *this) +static size_t get_block_size (private_aes_crypter_t *this) { return AES_BLOCK_SIZE; } @@ -1468,7 +1432,7 @@ static size_t get_block_size (private_aes_cbc_crypter_t *this) /** * Implementation of crypter_t.get_key_size. */ -static size_t get_key_size (private_aes_cbc_crypter_t *this) +static size_t get_key_size (private_aes_crypter_t *this) { return this->key_size; } @@ -1476,16 +1440,11 @@ static size_t get_key_size (private_aes_cbc_crypter_t *this) /** * Implementation of crypter_t.set_key. */ -static status_t set_key (private_aes_cbc_crypter_t *this, chunk_t 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; - if (key.len != this->key_size) - { - return INVALID_ARG; - } - this->aes_Nrnd = (this->aes_Nkey > (nc) ? this->aes_Nkey : (nc)) + 6; this->aes_e_key[0] = const_word_in(in_key ); @@ -1565,14 +1524,12 @@ static status_t set_key (private_aes_cbc_crypter_t *this, chunk_t key) } cpy(kt, kf); } - - return SUCCESS; } /** - * Implementation of crypter_t.destroy and aes_cbc_crypter_t.destroy. + * Implementation of crypter_t.destroy and aes_crypter_t.destroy. */ -static void destroy (private_aes_cbc_crypter_t *this) +static void destroy (private_aes_crypter_t *this) { free(this); } @@ -1580,16 +1537,24 @@ static void destroy (private_aes_cbc_crypter_t *this) /* * Described in header */ -aes_cbc_crypter_t *aes_cbc_crypter_create(size_t key_size) +aes_crypter_t *aes_crypter_create(encryption_algorithm_t algo, size_t key_size) { - private_aes_cbc_crypter_t *this = malloc_thing(private_aes_cbc_crypter_t); + 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) { + switch(key_size) + { case 32: /* bytes */ this->aes_Nkey = 8; break; @@ -1604,17 +1569,12 @@ aes_cbc_crypter_t *aes_cbc_crypter_create(size_t key_size) return NULL; } - /* functions of crypter_t interface */ - this->public.crypter_interface.encrypt = (status_t (*) (crypter_t *, chunk_t,chunk_t, chunk_t *)) encrypt; - this->public.crypter_interface.decrypt = (status_t (*) (crypter_t *, chunk_t , chunk_t, chunk_t *)) decrypt; + 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 = (status_t (*) (crypter_t *,chunk_t)) set_key; + this->public.crypter_interface.set_key = (void (*) (crypter_t *,chunk_t)) set_key; this->public.crypter_interface.destroy = (void (*) (crypter_t *)) destroy; - /* private functions */ - this->decrypt_block = decrypt_block; - this->encrypt_block = encrypt_block; - return &(this->public); } diff --git a/src/libstrongswan/crypto/crypters/aes_cbc_crypter.h b/src/libstrongswan/plugins/aes/aes_crypter.h index 5da248b8c..e42a6bc5b 100644 --- a/src/libstrongswan/crypto/crypters/aes_cbc_crypter.h +++ b/src/libstrongswan/plugins/aes/aes_crypter.h @@ -1,13 +1,5 @@ -/** - * @file aes_cbc_crypter.h - * - * @brief Interface of aes_cbc_crypter_t - * - */ - /* - * Copyright (C) 2001 Dr B. R. Gladman <brg@gladman.uk.net> - * Copyright (C) 2005-2006 Martin Willi + * Copyright (C) 2005-2008 Martin Willi * Copyright (C) 2005 Jan Hutter * Hochschule fuer Technik Rapperswil * @@ -22,22 +14,22 @@ * for more details. */ -#ifndef AES_CBC_CRYPTER_H_ -#define AES_CBC_CRYPTER_H_ +/** + * @defgroup aes_crypter aes_crypter + * @{ @ingroup aes_p + */ + +#ifndef AES_CRYPTER_H_ +#define AES_CRYPTER_H_ -typedef struct aes_cbc_crypter_t aes_cbc_crypter_t; +typedef struct aes_crypter_t aes_crypter_t; #include <crypto/crypters/crypter.h> /** - * @brief Class implementing the AES symmetric encryption algorithm. - * - * @b Constructors: - * - aes_cbc_crypter_create() - * - * @ingroup crypters + * Class implementing the AES encryption algorithm. */ -struct aes_cbc_crypter_t { +struct aes_crypter_t { /** * The crypter_t interface. @@ -46,16 +38,13 @@ struct aes_cbc_crypter_t { }; /** - * @brief Constructor to create aes_cbc_crypter_t objects. - * - * Supported key sizes are: 16, 24 or 32. + * Constructor to create aes_crypter_t objects. * * @param key_size key size in bytes - * @return - * - aes_cbc_crypter_t object - * - NULL if key size not supported + * @param algo algorithm to implement + * @return aes_crypter_t object, NULL if not supported */ -aes_cbc_crypter_t *aes_cbc_crypter_create(size_t key_size); - +aes_crypter_t *aes_crypter_create(encryption_algorithm_t algo, + size_t key_size); -#endif /* AES_CBC_CRYPTER_H_ */ +#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/crypto/crypters/des_crypter.c b/src/libstrongswan/plugins/des/des_crypter.c index 655cc03ce..43aff4dd1 100644 --- a/src/libstrongswan/crypto/crypters/des_crypter.c +++ b/src/libstrongswan/plugins/des/des_crypter.c @@ -1,10 +1,3 @@ -/** - * @file des_crypter.c - * - * @brief Implementation of des_crypter_t - * - */ - /* Copyright (C) 2006 Martin Willi * Hochschule fuer Technik Rapperswil * @@ -61,6 +54,8 @@ * 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" @@ -1365,84 +1360,84 @@ static void des_ede3_cbc_encrypt(des_cblock *input, des_cblock *output, long len /** * Implementation of crypter_t.decrypt for DES. */ -static status_t decrypt(private_des_crypter_t *this, chunk_t data, chunk_t iv, chunk_t *decrypted) +static void decrypt(private_des_crypter_t *this, chunk_t data, chunk_t iv, + chunk_t *decrypted) { des_cblock ivb; + u_int8_t *out; - if (data.len % sizeof(des_cblock) != 0 || - iv.len != sizeof(des_cblock)) + out = data.ptr; + if (decrypted) { - return INVALID_ARG; + *decrypted = chunk_alloc(data.len); + out = decrypted->ptr; } - - *decrypted = chunk_alloc(data.len); memcpy(&ivb, iv.ptr, sizeof(des_cblock)); - des_cbc_encrypt((des_cblock*)(data.ptr), (des_cblock*)(decrypted->ptr), + des_cbc_encrypt((des_cblock*)(data.ptr), (des_cblock*)out, data.len, this->ks, &ivb, DES_DECRYPT); - return SUCCESS; } /** * Implementation of crypter_t.decrypt for DES. */ -static status_t encrypt(private_des_crypter_t *this, chunk_t data, chunk_t iv, chunk_t *encrypted) +static void encrypt(private_des_crypter_t *this, chunk_t data, chunk_t iv, + chunk_t *encrypted) { des_cblock ivb; + u_int8_t *out; - if (data.len % sizeof(des_cblock) != 0 || - iv.len != sizeof(des_cblock)) + out = data.ptr; + if (encrypted) { - return INVALID_ARG; + *encrypted = chunk_alloc(data.len); + out = encrypted->ptr; } - - *encrypted = chunk_alloc(data.len); memcpy(&ivb, iv.ptr, sizeof(des_cblock)); - des_cbc_encrypt((des_cblock*)(data.ptr), (des_cblock*)(encrypted->ptr), + des_cbc_encrypt((des_cblock*)(data.ptr), (des_cblock*)out, data.len, this->ks, &ivb, DES_ENCRYPT); - return SUCCESS; } /** * Implementation of crypter_t.decrypt for 3DES. */ -static status_t decrypt3(private_des_crypter_t *this, chunk_t data, chunk_t iv, chunk_t *decrypted) +static void decrypt3(private_des_crypter_t *this, chunk_t data, chunk_t iv, + chunk_t *decrypted) { des_cblock ivb; + u_int8_t *out; - if (data.len % sizeof(des_cblock) != 0 || - iv.len != sizeof(des_cblock)) + out = data.ptr; + if (decrypted) { - return INVALID_ARG; + *decrypted = chunk_alloc(data.len); + out = decrypted->ptr; } - - *decrypted = chunk_alloc(data.len); memcpy(&ivb, iv.ptr, sizeof(des_cblock)); - des_ede3_cbc_encrypt((des_cblock*)(data.ptr), (des_cblock*)(decrypted->ptr), + 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); - return SUCCESS; } /** * Implementation of crypter_t.decrypt for 3DES. */ -static status_t encrypt3(private_des_crypter_t *this, chunk_t data, chunk_t iv, chunk_t *encrypted) +static void encrypt3(private_des_crypter_t *this, chunk_t data, chunk_t iv, + chunk_t *encrypted) { des_cblock ivb; + u_int8_t *out; - if (data.len % sizeof(des_cblock) != 0 || - iv.len != sizeof(des_cblock)) + out = data.ptr; + if (encrypted) { - return INVALID_ARG; + *encrypted = chunk_alloc(data.len); + out = encrypted->ptr; } - - *encrypted = chunk_alloc(data.len); memcpy(&ivb, iv.ptr, sizeof(des_cblock)); - des_ede3_cbc_encrypt((des_cblock*)(data.ptr), (des_cblock*)(encrypted->ptr), + 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); - return SUCCESS; } /** @@ -1464,33 +1459,19 @@ static size_t get_key_size (private_des_crypter_t *this) /** * Implementation of crypter_t.set_key for DES. */ -static status_t set_key(private_des_crypter_t *this, chunk_t key) +static void set_key(private_des_crypter_t *this, chunk_t key) { - if (key.len != sizeof(des_cblock)) - { - return INVALID_ARG; - } - des_set_key((des_cblock*)(key.ptr), &this->ks); - - return SUCCESS; } /** * Implementation of crypter_t.set_key for 3DES. */ -static status_t set_key3(private_des_crypter_t *this, chunk_t key) -{ - if (key.len != 3 * sizeof(des_cblock)) - { - return INVALID_ARG; - } - +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]); - - return SUCCESS; } /** @@ -1518,19 +1499,19 @@ des_crypter_t *des_crypter_create(encryption_algorithm_t algo) { case ENCR_DES: this->key_size = sizeof(des_cblock); - this->public.crypter_interface.set_key = (status_t (*) (crypter_t *,chunk_t)) set_key; - this->public.crypter_interface.encrypt = (status_t (*) (crypter_t *, chunk_t,chunk_t, chunk_t *)) encrypt; - this->public.crypter_interface.decrypt = (status_t (*) (crypter_t *, chunk_t , chunk_t, chunk_t *)) decrypt; + 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 = (status_t (*) (crypter_t *,chunk_t)) set_key3; - this->public.crypter_interface.encrypt = (status_t (*) (crypter_t *, chunk_t,chunk_t, chunk_t *)) encrypt3; - this->public.crypter_interface.decrypt = (status_t (*) (crypter_t *, chunk_t , chunk_t, chunk_t *)) decrypt3; + 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); + return &this->public; } diff --git a/src/libstrongswan/crypto/crypters/des_crypter.h b/src/libstrongswan/plugins/des/des_crypter.h index 0c87b0a9c..d40d9cf2f 100644 --- a/src/libstrongswan/crypto/crypters/des_crypter.h +++ b/src/libstrongswan/plugins/des/des_crypter.h @@ -1,12 +1,5 @@ -/** - * @file des_crypter.h - * - * @brief Interface of des_crypter_t - * - */ - /* - * Copyright (C) 2006 Martin Willi + * Copyright (C) 2006-2008 Martin Willi * Hochschule fuer Technik Rapperswil * * This program is free software; you can redistribute it and/or modify it @@ -20,6 +13,11 @@ * for more details. */ +/** + * @defgroup des_crypter des_crypter + * @{ @ingroup des_p + */ + #ifndef DES_CRYPTER_H_ #define DES_CRYPTER_H_ @@ -29,12 +27,7 @@ typedef struct des_crypter_t des_crypter_t; /** - * @brief Class implementing the DES and 3DES encryption algorithms. - * - * @b Constructors: - * - des_crypter_create() - * - * @ingroup crypters + * Class implementing the DES and 3DES encryption algorithms. */ struct des_crypter_t { @@ -45,14 +38,12 @@ struct des_crypter_t { }; /** - * @brief Constructor to create des_crypter_t objects. + * 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 + * @return des_crypter_t object, NULL if algo not supported */ des_crypter_t *des_crypter_create(encryption_algorithm_t algo); -#endif /* DES_CRYPTER_H_ */ +#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/crypto/prfs/fips_prf.c b/src/libstrongswan/plugins/fips_prf/fips_prf.c index 0ab80b089..df3d130a9 100644 --- a/src/libstrongswan/crypto/prfs/fips_prf.c +++ b/src/libstrongswan/plugins/fips_prf/fips_prf.c @@ -1,10 +1,3 @@ -/** - * @file fips_prf.c - * - * @brief Implementation for fips_prf_t. - * - */ - /* * Copyright (C) 2006 Martin Willi * Hochschule fuer Technik Rapperswil @@ -18,6 +11,8 @@ * 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" @@ -48,17 +43,14 @@ struct private_fips_prf_t { size_t b; /** + * Keyed SHA1 prf: It does not use SHA1Final operation + */ + prf_t *keyed_prf; + + /** * G function, either SHA1 or DES */ - void (*g)(u_int8_t t[], chunk_t c, u_int8_t res[]); -}; - -/** - * t used in G(), equals to initial SHA1 value - */ -static u_int8_t t[] = { - 0x67,0x45,0x23,0x01,0xEF,0xCD,0xAB,0x89,0x98,0xBA, - 0xDC,0xFE,0x10,0x32,0x54,0x76,0xC3,0xD2,0xE1,0xF0, + void (*g)(private_fips_prf_t *this, chunk_t c, u_int8_t res[]); }; /** @@ -139,7 +131,7 @@ static void get_bytes(private_fips_prf_t *this, chunk_t seed, u_int8_t w[]) add_mod(this->b, xkey, xseed, xval); DBG3("XVAL %b", xval, this->b); /* b. wi = G(t, XVAL ) */ - this->g(t, xval_chunk, &w[i * this->b]); + 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); @@ -186,12 +178,9 @@ static void set_key(private_fips_prf_t *this, chunk_t key) /** * Implementation of the G() function based on SHA1 */ -void g_sha1(u_int8_t t[], chunk_t c, u_int8_t res[]) +void g_sha1(private_fips_prf_t *this, chunk_t c, u_int8_t res[]) { - hasher_t *hasher; u_int8_t buf[64]; - chunk_t state_chunk; - u_int32_t *state, *iv, *hash; if (c.len < sizeof(buf)) { @@ -207,24 +196,9 @@ void g_sha1(u_int8_t t[], chunk_t c, u_int8_t res[]) c.len = sizeof(buf); } - /* our SHA1 hasher's state is 32-Bit integers in host order. We must - * convert them */ - hasher = hasher_create(HASH_SHA1); - state_chunk = hasher->get_state(hasher); - state = (u_int32_t*)state_chunk.ptr; - iv = (u_int32_t*)t; - hash = (u_int32_t*)res; - state[0] = htonl(iv[0]); - state[1] = htonl(iv[1]); - state[2] = htonl(iv[2]); - state[3] = htonl(iv[3]); - hasher->get_hash(hasher, c, NULL); - hash[0] = htonl(state[0]); - hash[1] = htonl(state[1]); - hash[2] = htonl(state[2]); - hash[3] = htonl(state[3]); - hash[4] = htonl(state[4]); - hasher->destroy(hasher); + /* 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); } /** @@ -232,6 +206,7 @@ void g_sha1(u_int8_t t[], chunk_t c, u_int8_t res[]) */ static void destroy(private_fips_prf_t *this) { + this->keyed_prf->destroy(this->keyed_prf); free(this->key); free(this); } @@ -239,7 +214,7 @@ static void destroy(private_fips_prf_t *this) /* * Described in header. */ -fips_prf_t *fips_prf_create(size_t b, void(*g)(u_int8_t[],chunk_t,u_int8_t[])) +fips_prf_t *fips_prf_create(pseudo_random_function_t algo) { private_fips_prf_t *this = malloc_thing(private_fips_prf_t); @@ -250,9 +225,28 @@ fips_prf_t *fips_prf_create(size_t b, void(*g)(u_int8_t[],chunk_t,u_int8_t[])) this->public.prf_interface.set_key = (void (*) (prf_t *,chunk_t))set_key; this->public.prf_interface.destroy = (void (*) (prf_t *))destroy; - this->g = g; - this->b = b; - this->key = malloc(b); + 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); + return &this->public; } + diff --git a/src/libstrongswan/crypto/prfs/fips_prf.h b/src/libstrongswan/plugins/fips_prf/fips_prf.h index 283ee1f61..3fead6b9b 100644 --- a/src/libstrongswan/crypto/prfs/fips_prf.h +++ b/src/libstrongswan/plugins/fips_prf/fips_prf.h @@ -1,12 +1,5 @@ -/** - * @file fips_prf.h - * - * @brief Interface of fips_prf_t. - * - */ - /* - * Copyright (C) 2006 Martin Willi + * Copyright (C) 2006-2008 Martin Willi * Hochschule fuer Technik Rapperswil * * This program is free software; you can redistribute it and/or modify it @@ -20,6 +13,11 @@ * for more details. */ +/** + * @defgroup fips_prf fips_prf + * @{ @ingroup fips_prf_p + */ + #ifndef FIPS_PRF_H_ #define FIPS_PRF_H_ @@ -30,19 +28,13 @@ typedef struct fips_prf_t fips_prf_t; #include <crypto/hashers/hasher.h> /** - * @brief Implementation of prf_t using the FIPS 186-2-change1 standard. + * 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. - * - * @b Constructors: - * - fips_prf_create() - * - prf_create() using one of the FIPS algorithms - * - * @ingroup prfs */ struct fips_prf_t { @@ -53,28 +45,15 @@ struct fips_prf_t { }; /** - * @brief Creates a new fips_prf_t object. + * 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 b size of b (in bytes, not bits) - * @param g G() function to use (e.g. g_sha1) - * @return - * - fips_prf_t object - * - NULL if b invalid not supported - * - * @ingroup prfs - */ -fips_prf_t *fips_prf_create(size_t b, void(*g)(u_int8_t[],chunk_t,u_int8_t[])); - -/** - * @brief Implementation of the G() function based on SHA1. - * - * @param t initialization vector for SHA1 hasher, 20 bytes long - * @param c value to hash, not longer than 512 bit - * @param res result of G(), requries 20 bytes + * @param algo specific FIPS PRF implementation, specifies G() function + * @return fips_prf_t object, NULL if not supported. */ -void g_sha1(u_int8_t t[], chunk_t c, u_int8_t res[]); +fips_prf_t *fips_prf_create(pseudo_random_function_t algo); -#endif /* FIPS_PRF_H_ */ +#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/crypto/hmac.c b/src/libstrongswan/plugins/hmac/hmac.c index df4f90bc8..b2f99bdc3 100644 --- a/src/libstrongswan/crypto/hmac.c +++ b/src/libstrongswan/plugins/hmac/hmac.c @@ -1,9 +1,3 @@ -/** - * @file hmac.c - * - * @brief Implementation of hmac_t. - */ - /* * Copyright (C) 2005-2006 Martin Willi * Copyright (C) 2005 Jan Hutter @@ -18,6 +12,8 @@ * 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> @@ -173,9 +169,7 @@ static void destroy(private_hmac_t *this) */ hmac_t *hmac_create(hash_algorithm_t hash_algorithm) { - private_hmac_t *this; - - this = malloc_thing(private_hmac_t); + 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; @@ -200,9 +194,14 @@ hmac_t *hmac_create(hash_algorithm_t hash_algorithm) free(this); return NULL; } - + /* build the hasher */ - this->h = hasher_create(hash_algorithm); + 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); diff --git a/src/libstrongswan/crypto/hmac.h b/src/libstrongswan/plugins/hmac/hmac.h index 06b75aaf9..5f266e133 100644 --- a/src/libstrongswan/crypto/hmac.h +++ b/src/libstrongswan/plugins/hmac/hmac.h @@ -1,11 +1,5 @@ -/** - * @file hmac.h - * - * @brief Interface of hmac_t. - */ - /* - * Copyright (C) 2005-2006 Martin Willi + * Copyright (C) 2005-2008 Martin Willi * Copyright (C) 2005 Jan Hutter * Hochschule fuer Technik Rapperswil * @@ -20,6 +14,11 @@ * for more details. */ +/** + * @defgroup hmac hmac + * @{ @ingroup hmac_p + */ + #ifndef HMAC_H_ #define HMAC_H_ @@ -28,90 +27,67 @@ typedef struct hmac_t hmac_t; #include <crypto/hashers/hasher.h> /** - * @brief Message authentication using hash functions. + * 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. - * - * See http://www.faqs.org/rfcs/rfc2104.html for RFC. - * @see - * - hasher_t - * - prf_hmac_t - * - * @b Constructors: - * - hmac_create() - * - * @ingroup crypto */ struct hmac_t { /** - * @brief Generate message authentication code. + * 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 this calling object - * @param data chunk of data to authenticate - * @param[out] buffer pointer where the generated bytes will be written + * @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); /** - * @brief Generates message authentication code and - * allocate space for them. + * 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 this calling object - * @param data chunk of data to authenticate - * @param[out] chunk chunk which will hold generated bytes + * @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); /** - * @brief Get the block size of this hmac_t object. + * Get the block size of this hmac_t object. * - * @param this calling object - * @return block size in bytes + * @return block size in bytes */ size_t (*get_block_size) (hmac_t *this); /** - * @brief Set the key for this hmac_t object. + * Set the key for this hmac_t object. * * Any key length is accepted. * - * @param this calling object - * @param key key to set + * @param key key to set */ void (*set_key) (hmac_t *this, chunk_t key); /** - * @brief Destroys a hmac_t object. - * - * @param this calling object + * Destroys a hmac_t object. */ void (*destroy) (hmac_t *this); }; /** - * @brief Creates a new hmac_t object. - * - * Creates a hasher_t object internally. - * - * @param hash_algorithm hash algorithm to use - * @return - * - hmac_t object - * - NULL if hash algorithm is not supported + * Creates a new hmac_t object. * - * @ingroup transforms + * @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_*/ +#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/crypto/prfs/hmac_prf.c b/src/libstrongswan/plugins/hmac/hmac_prf.c index f315f880d..8d843bc5a 100644 --- a/src/libstrongswan/crypto/prfs/hmac_prf.c +++ b/src/libstrongswan/plugins/hmac/hmac_prf.c @@ -1,10 +1,3 @@ -/** - * @file hmac_prf.c - * - * @brief Implementation for hmac_prf_t. - * - */ - /* * Copyright (C) 2005-2006 Martin Willi * Copyright (C) 2005 Jan Hutter @@ -19,11 +12,13 @@ * 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 <crypto/hmac.h> +#include "hmac.h" typedef struct private_hmac_prf_t private_hmac_prf_t; @@ -96,23 +91,47 @@ static void destroy(private_hmac_prf_t *this) /* * Described in header. */ -hmac_prf_t *hmac_prf_create(hash_algorithm_t hash_algorithm) +hmac_prf_t *hmac_prf_create(pseudo_random_function_t algo) { - private_hmac_prf_t *this = malloc_thing(private_hmac_prf_t); + private_hmac_prf_t *this; + hash_algorithm_t hash; - 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_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->hmac = hmac_create(hash_algorithm); + 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/crypto/prfs/hmac_prf.h b/src/libstrongswan/plugins/hmac/hmac_prf.h index 9b06ee3a2..46d05f03a 100644 --- a/src/libstrongswan/crypto/prfs/hmac_prf.h +++ b/src/libstrongswan/plugins/hmac/hmac_prf.h @@ -1,12 +1,5 @@ -/** - * @file hmac_prf.h - * - * @brief Interface of hmac_prf_t. - * - */ - /* - * Copyright (C) 2005-2006 Martin Willi + * Copyright (C) 2008 Martin Willi * Copyright (C) 2005 Jan Hutter * Hochschule fuer Technik Rapperswil * @@ -21,26 +14,23 @@ * 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 <library.h> #include <crypto/prfs/prf.h> -#include <crypto/hashers/hasher.h> /** - * @brief Implementation of prf_t interface using the - * HMAC algorithm. + * 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. - * - * @b Constructors: - * - hmac_prf_create() - * - * @ingroup prfs */ struct hmac_prf_t { @@ -51,15 +41,11 @@ struct hmac_prf_t { }; /** - * @brief Creates a new hmac_prf_t object. - * - * @param hash_algorithm hmac's hash algorithm - * @return - * - hmac_prf_t object - * - NULL if hash not supported + * Creates a new hmac_prf_t object. * - * @ingroup prfs + * @param algo algorithm to implement + * @return hmac_prf_t object, NULL if hash not supported */ -hmac_prf_t *hmac_prf_create(hash_algorithm_t hash_algorithm); +hmac_prf_t *hmac_prf_create(pseudo_random_function_t algo); -#endif /*PRF_HMAC_SHA1_H_*/ +#endif /*PRF_HMAC_SHA1_H_ @}*/ diff --git a/src/libstrongswan/crypto/signers/hmac_signer.c b/src/libstrongswan/plugins/hmac/hmac_signer.c index ad5b882a6..cdfc819f1 100644 --- a/src/libstrongswan/crypto/signers/hmac_signer.c +++ b/src/libstrongswan/plugins/hmac/hmac_signer.c @@ -1,12 +1,5 @@ -/** - * @file hmac_signer.c - * - * @brief Implementation of hmac_signer_t. - * - */ - /* - * Copyright (C) 2005-2006 Martin Willi + * Copyright (C) 2005-2008 Martin Willi * Copyright (C) 2005 Jan Hutter * Hochschule fuer Technik Rapperswil * @@ -19,13 +12,14 @@ * 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 <crypto/prfs/hmac_prf.h> +#include "hmac.h" typedef struct private_hmac_signer_t private_hmac_signer_t; @@ -41,7 +35,7 @@ struct private_hmac_signer_t { /** * Assigned hmac function. */ - prf_t *hmac_prf; + hmac_t *hmac; /** * Block size (truncation of HMAC Hash) @@ -52,69 +46,60 @@ struct private_hmac_signer_t { /** * Implementation of signer_t.get_signature. */ -static void get_signature(private_hmac_signer_t *this, chunk_t data, u_int8_t *buffer) +static void get_signature(private_hmac_signer_t *this, + chunk_t data, u_int8_t *buffer) { if (buffer == NULL) { /* append mode */ - this->hmac_prf->get_bytes(this->hmac_prf, data, NULL); + this->hmac->get_mac(this->hmac, data, NULL); } else { - u_int8_t full_mac[this->hmac_prf->get_block_size(this->hmac_prf)]; + u_int8_t mac[this->hmac->get_block_size(this->hmac)]; - this->hmac_prf->get_bytes(this->hmac_prf, data, full_mac); - memcpy(buffer, full_mac, this->block_size); + 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) +static void allocate_signature (private_hmac_signer_t *this, + chunk_t data, chunk_t *chunk) { if (chunk == NULL) { /* append mode */ - this->hmac_prf->get_bytes(this->hmac_prf, data, NULL); + this->hmac->get_mac(this->hmac, data, NULL); } else { - chunk_t signature; - u_int8_t full_mac[this->hmac_prf->get_block_size(this->hmac_prf)]; + u_int8_t mac[this->hmac->get_block_size(this->hmac)]; - this->hmac_prf->get_bytes(this->hmac_prf, data, full_mac); + this->hmac->get_mac(this->hmac, data, mac); - signature.ptr = malloc(this->block_size); - signature.len = this->block_size; + chunk->ptr = malloc(this->block_size); + chunk->len = this->block_size; - memcpy(signature.ptr, full_mac, this->block_size); - - *chunk = signature; + 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) +static bool verify_signature(private_hmac_signer_t *this, + chunk_t data, chunk_t signature) { - u_int8_t full_mac[this->hmac_prf->get_block_size(this->hmac_prf)]; + u_int8_t mac[this->hmac->get_block_size(this->hmac)]; - this->hmac_prf->get_bytes(this->hmac_prf, data, full_mac); + this->hmac->get_mac(this->hmac, data, mac); if (signature.len != this->block_size) { return FALSE; } - - /* compare mac aka signature :-) */ - if (memcmp(signature.ptr, full_mac, this->block_size) == 0) - { - return TRUE; - } - else - { - return FALSE; - } + return memeq(signature.ptr, mac, this->block_size); } /** @@ -122,8 +107,7 @@ static bool verify_signature(private_hmac_signer_t *this, chunk_t data, chunk_t */ static size_t get_key_size(private_hmac_signer_t *this) { - /* for HMAC signer, IKEv2 uses block size as key size */ - return this->hmac_prf->get_block_size(this->hmac_prf); + return this->hmac->get_block_size(this->hmac); } /** @@ -139,7 +123,7 @@ static size_t get_block_size(private_hmac_signer_t *this) */ static void set_key(private_hmac_signer_t *this, chunk_t key) { - this->hmac_prf->set_key(this->hmac_prf, key); + this->hmac->set_key(this->hmac, key); } /** @@ -147,7 +131,7 @@ static void set_key(private_hmac_signer_t *this, chunk_t key) */ static status_t destroy(private_hmac_signer_t *this) { - this->hmac_prf->destroy(this->hmac_prf); + this->hmac->destroy(this->hmac); free(this); return SUCCESS; } @@ -155,22 +139,51 @@ static status_t destroy(private_hmac_signer_t *this) /* * Described in header */ -hmac_signer_t *hmac_signer_create(hash_algorithm_t hash_algoritm, size_t block_size) +hmac_signer_t *hmac_signer_create(integrity_algorithm_t algo) { - size_t hmac_block_size; - private_hmac_signer_t *this = malloc_thing(private_hmac_signer_t); - - this->hmac_prf = (prf_t *) hmac_prf_create(hash_algoritm); - if (this->hmac_prf == NULL) + 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) { - /* algorithm not supported */ free(this); return NULL; } - /* prevent invalid truncation */ - hmac_block_size = this->hmac_prf->get_block_size(this->hmac_prf); - this->block_size = min(block_size, hmac_block_size); + 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; @@ -183,3 +196,4 @@ hmac_signer_t *hmac_signer_create(hash_algorithm_t hash_algoritm, size_t block_s return &(this->public); } + diff --git a/src/libstrongswan/crypto/signers/hmac_signer.h b/src/libstrongswan/plugins/hmac/hmac_signer.h index 2449069bd..969f482e7 100644 --- a/src/libstrongswan/crypto/signers/hmac_signer.h +++ b/src/libstrongswan/plugins/hmac/hmac_signer.h @@ -1,12 +1,5 @@ -/** - * @file hmac_signer.h - * - * @brief Interface of hmac_signer_t. - * - */ - /* - * Copyright (C) 2005-2006 Martin Willi + * Copyright (C) 2005-2008 Martin Willi * Copyright (C) 2005 Jan Hutter * Hochschule fuer Technik Rapperswil * @@ -21,21 +14,22 @@ * 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> -#include <crypto/hashers/hasher.h> /** - * @brief Implementation of signer_t interface using HMAC. + * Implementation of signer_t interface using HMAC. * - * HMAC uses a standard hash function implemented in a hasher_t to build - * a MAC. - * - * @ingroup signers + * HMAC uses a standard hash function implemented in a hasher_t to build a MAC. */ struct hmac_signer_t { @@ -46,23 +40,16 @@ struct hmac_signer_t { }; /** - * @brief Creates a new hmac_signer_t. + * 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 hash_algoritm Hash algorithm to use with signer - * @param block_size Size of resulting signature (truncated to block_size) - * @return - * - hmac_signer_t - * - NULL if hash algorithm not supported - * - * @ingroup signers + * @param algo algorithm to implement + * @return hmac_signer_t, NULL if not supported */ -hmac_signer_t *hmac_signer_create(hash_algorithm_t hash_algoritm, - size_t block_size); - +hmac_signer_t *hmac_signer_create(integrity_algorithm_t algo); -#endif /*HMAC_SIGNER_H_*/ +#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/crypto/hashers/md5_hasher.c b/src/libstrongswan/plugins/md5/md5_hasher.c index d4dde3693..2354139bb 100644 --- a/src/libstrongswan/crypto/hashers/md5_hasher.c +++ b/src/libstrongswan/plugins/md5/md5_hasher.c @@ -1,10 +1,3 @@ -/** - * @file md5_hasher.c - * - * @brief Implementation of md5_hasher_t. - * - */ - /* * Copyright (C) 2005-2006 Martin Willi * Copyright (C) 2005 Jan Hutter @@ -24,6 +17,8 @@ * 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> @@ -364,19 +359,6 @@ static void reset(private_md5_hasher_t *this) } /** - * Implementation of hasher_t.get_state - */ -static chunk_t get_state(private_md5_hasher_t *this) -{ - chunk_t chunk; - - chunk.ptr = (u_char*)&this->state[0]; - chunk.len = sizeof(this->state); - - return chunk; -} - -/** * Implementation of hasher_t.destroy. */ static void destroy(private_md5_hasher_t *this) @@ -387,15 +369,20 @@ static void destroy(private_md5_hasher_t *this) /* * Described in header. */ -md5_hasher_t *md5_hasher_create(void) +md5_hasher_t *md5_hasher_create(hash_algorithm_t algo) { - private_md5_hasher_t *this = malloc_thing(private_md5_hasher_t); - + 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.get_state = (chunk_t (*) (hasher_t*))get_state; this->public.hasher_interface.destroy = (void (*) (hasher_t*))destroy; /* initialize */ diff --git a/src/libstrongswan/crypto/hashers/md5_hasher.h b/src/libstrongswan/plugins/md5/md5_hasher.h index 715f11663..d4a0417ab 100644 --- a/src/libstrongswan/crypto/hashers/md5_hasher.h +++ b/src/libstrongswan/plugins/md5/md5_hasher.h @@ -1,12 +1,5 @@ -/** - * @file md5_hasher.h - * - * @brief Interface for md5_hasher_t. - * - */ - /* - * Copyright (C) 2005-2006 Martin Willi + * Copyright (C) 2008 Martin Willi * Copyright (C) 2005 Jan Hutter * Hochschule fuer Technik Rapperswil * @@ -21,6 +14,11 @@ * for more details. */ +/** + * @defgroup md5_hasher md5_hasher + * @{ @ingroup md5_p + */ + #ifndef MD5_HASHER_H_ #define MD5_HASHER_H_ @@ -29,16 +27,7 @@ typedef struct md5_hasher_t md5_hasher_t; #include <crypto/hashers/hasher.h> /** - * @brief Implementation of hasher_t interface using the - * MD5 algorithm. - * - * @b Constructors: - * - hasher_create() using HASH_MD5 as algorithm - * - md5_hasher_create() - * - * @see hasher_t - * - * @ingroup hashers + * Implementation of hasher_t interface using the MD5 algorithm. */ struct md5_hasher_t { @@ -49,12 +38,11 @@ struct md5_hasher_t { }; /** - * @brief Creates a new md5_hasher_t. - * - * @return md5_hasher_t object + * Creates a new md5_hasher_t. * - * @ingroup hashers + * @param algo hash algorithm, must be HASH_MD5 + * @return md5_hasher_t object, NULL if not supported */ -md5_hasher_t *md5_hasher_create(void); +md5_hasher_t *md5_hasher_create(hash_algorithm_t algo); -#endif /*MD5_HASHER_H_*/ +#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, ¤t)) + { + 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/crypto/hashers/sha1_hasher.h b/src/libstrongswan/plugins/openssl/openssl_hasher.h index 380fa9845..f776e9fd4 100644 --- a/src/libstrongswan/crypto/hashers/sha1_hasher.h +++ b/src/libstrongswan/plugins/openssl/openssl_hasher.h @@ -1,13 +1,5 @@ -/** - * @file sha1_hasher.h - * - * @brief Interface of sha1_hasher_t - * - */ - /* - * Copyright (C) 2005-2006 Martin Willi - * Copyright (C) 2005 Jan Hutter + * Copyright (C) 2008 Tobias Brunner * Hochschule fuer Technik Rapperswil * * This program is free software; you can redistribute it and/or modify it @@ -19,42 +11,40 @@ * 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 $ */ -#ifndef SHA1_HASHER_H_ -#define SHA1_HASHER_H_ +/** + * @defgroup openssl_hasher openssl_hasher + * @{ @ingroup openssl_p + */ + +#ifndef OPENSSL_HASHER_H_ +#define OPENSSL_HASHER_H_ -typedef struct sha1_hasher_t sha1_hasher_t; +typedef struct openssl_hasher_t openssl_hasher_t; #include <crypto/hashers/hasher.h> /** - * @brief Implementation of hasher_t interface using the - * SHA1 algorithm. - * - * @b Constructors: - * - hasher_create() using HASH_SHA1 as algorithm - * - sha1_hasher_create() - * - * @see hasher_t - * - * @ingroup hashers + * Implementation of hashers using OpenSSL. */ -struct sha1_hasher_t { +struct openssl_hasher_t { /** - * Generic hasher_t interface for this hasher. + * The hasher_t interface. */ hasher_t hasher_interface; }; /** - * @brief Creates a new sha1_hasher_t. - * - * @return sha1_hasher_t object + * Constructor to create openssl_hasher_t. * - * @ingroup hashers + * @param algo algorithm + * @param key_size key size in bytes + * @return openssl_hasher_t, NULL if not supported */ -sha1_hasher_t *sha1_hasher_create(void); +openssl_hasher_t *openssl_hasher_create(hash_algorithm_t algo); -#endif /*SHA1_HASHER_H_*/ +#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/crypto/hashers/sha1_hasher.c b/src/libstrongswan/plugins/sha1/sha1_hasher.c index 6a86937ae..c496be8f4 100644 --- a/src/libstrongswan/crypto/hashers/sha1_hasher.c +++ b/src/libstrongswan/plugins/sha1/sha1_hasher.c @@ -1,10 +1,3 @@ -/** - * @file sha1_hasher.c - * - * @brief Implementation of hasher_sha_t. - * - */ - /* * Copyright (C) 2005-2006 Martin Willi * Copyright (C) 2005 Jan Hutter @@ -22,9 +15,12 @@ * 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" @@ -51,6 +47,7 @@ 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. @@ -69,6 +66,21 @@ struct private_sha1_hasher_t { 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. * */ @@ -181,6 +193,19 @@ static void SHA1Final(private_sha1_hasher_t *this, u_int8_t *digest) } } +/** + * 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. @@ -191,28 +216,23 @@ static void get_hash(private_sha1_hasher_t *this, chunk_t chunk, u_int8_t *buffe if (buffer != NULL) { SHA1Final(this, buffer); - this->public.hasher_interface.reset(&(this->public.hasher_interface)); + reset(this); } } - /** * Implementation of hasher_t.allocate_hash. */ static void allocate_hash(private_sha1_hasher_t *this, chunk_t chunk, chunk_t *hash) { - chunk_t allocated_hash; - SHA1Update(this, chunk.ptr, chunk.len); if (hash != NULL) { - allocated_hash.ptr = malloc(HASH_SIZE_SHA1); - allocated_hash.len = HASH_SIZE_SHA1; + hash->ptr = malloc(HASH_SIZE_SHA1); + hash->len = HASH_SIZE_SHA1; - SHA1Final(this, allocated_hash.ptr); - this->public.hasher_interface.reset(&(this->public.hasher_interface)); - - *hash = allocated_hash; + SHA1Final(this, hash->ptr); + reset(this); } } @@ -225,33 +245,6 @@ static size_t get_hash_size(private_sha1_hasher_t *this) } /** - * 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_state - */ -static chunk_t get_state(private_sha1_hasher_t *this) -{ - chunk_t chunk; - - chunk.ptr = (u_char*)&this->state[0]; - chunk.len = sizeof(this->state); - - return chunk; -} - -/** * Implementation of hasher_t.destroy. */ static void destroy(private_sha1_hasher_t *this) @@ -262,15 +255,18 @@ static void destroy(private_sha1_hasher_t *this) /* * Described in header. */ -sha1_hasher_t *sha1_hasher_create(void) +sha1_hasher_t *sha1_hasher_create(hash_algorithm_t algo) { - private_sha1_hasher_t *this = malloc_thing(private_sha1_hasher_t); - + 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.get_state = (chunk_t (*) (hasher_t*))get_state; this->public.hasher_interface.destroy = (void (*) (hasher_t*))destroy; /* initialize */ @@ -278,3 +274,93 @@ sha1_hasher_t *sha1_hasher_create(void) 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/crypto/hashers/sha2_hasher.c b/src/libstrongswan/plugins/sha2/sha2_hasher.c index b68972cec..ca9c2f926 100644 --- a/src/libstrongswan/crypto/hashers/sha2_hasher.c +++ b/src/libstrongswan/plugins/sha2/sha2_hasher.c @@ -1,10 +1,3 @@ -/** - * @file sha2_hasher.c - * - * @brief Implementation of hasher_sha_t. - * - */ - /* * Copyright (C) 2006 Martin Willi * Hochschule fuer Technik Rapperswil @@ -21,6 +14,8 @@ * 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> @@ -587,38 +582,6 @@ static void reset512(private_sha512_hasher_t *ctx) } /** - * Implementation of hasher_t.get_state for SHA256 - */ -static chunk_t get_state256(private_sha256_hasher_t *ctx) -{ - chunk_t chunk; - chunk.ptr = (u_char*)&ctx->sha_H[0]; - chunk.len = HASH_SIZE_SHA256; - return chunk; -} - -/** - * Implementation of hasher_t.get_state for SHA384 - */ -static chunk_t get_state384(private_sha512_hasher_t *ctx) -{ - chunk_t chunk; - chunk.ptr = (u_char*)&ctx->sha_H[0]; - chunk.len = HASH_SIZE_SHA384; - return chunk; -} -/** - * Implementation of hasher_t.get_state for SHA512 - */ -static chunk_t get_state512(private_sha512_hasher_t *ctx) -{ - chunk_t chunk; - chunk.ptr = (u_char*)&ctx->sha_H[0]; - chunk.len = HASH_SIZE_SHA512; - return chunk; -} - -/** * Implementation of hasher_t.destroy. */ static void destroy(sha2_hasher_t *this) @@ -638,7 +601,6 @@ sha2_hasher_t *sha2_hasher_create(hash_algorithm_t 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_state = (chunk_t(*)(hasher_t*))get_state256; 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; @@ -647,7 +609,6 @@ sha2_hasher_t *sha2_hasher_create(hash_algorithm_t algorithm) /* 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_state = (chunk_t(*)(hasher_t*))get_state384; 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; @@ -655,7 +616,6 @@ sha2_hasher_t *sha2_hasher_create(hash_algorithm_t algorithm) 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_state = (chunk_t(*)(hasher_t*))get_state512; 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; diff --git a/src/libstrongswan/crypto/hashers/sha2_hasher.h b/src/libstrongswan/plugins/sha2/sha2_hasher.h index 91e82fedb..6d732495a 100644 --- a/src/libstrongswan/crypto/hashers/sha2_hasher.h +++ b/src/libstrongswan/plugins/sha2/sha2_hasher.h @@ -1,12 +1,5 @@ -/** - * @file sha2_hasher.h - * - * @brief Interface of sha2_hasher_t - * - */ - /* - * Copyright (C) 2006 Martin Willi + * Copyright (C) 2006-2008 Martin Willi * Hochschule fuer Technik Rapperswil * * This program is free software; you can redistribute it and/or modify it @@ -20,6 +13,11 @@ * for more details. */ +/** + * @defgroup sha2_hasher sha2_hasher + * @{ @ingroup sha2_p + */ + #ifndef SHA2_HASHER_H_ #define SHA2_HASHER_H_ @@ -28,18 +26,10 @@ typedef struct sha2_hasher_t sha2_hasher_t; #include <crypto/hashers/hasher.h> /** - * @brief Implementation of hasher_t interface using the SHA2 algorithms. + * 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. - * - * @b Constructors: - * - hasher_create() using HASH_SHA256, HASH_SHA384 or HASH_SHA512 as algorithm - * - sha2_hasher_create() - * - * @see hasher_t - * - * @ingroup hashers */ struct sha2_hasher_t { @@ -50,13 +40,11 @@ struct sha2_hasher_t { }; /** - * @brief Creates a new sha2_hasher_t. + * Creates a new sha2_hasher_t. * * @param algorithm HASH_SHA256, HASH_SHA384 or HASH_SHA512 - * @return sha2_hasher_t object - * - * @ingroup hashers + * @return sha2_hasher_t object, NULL if not supported */ sha2_hasher_t *sha2_hasher_create(hash_algorithm_t algorithm); -#endif /* SHA2_HASHER_H_ */ +#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/crypto/ietf_attr_list.c b/src/libstrongswan/plugins/x509/ietf_attr_list.c index 1ecadf679..17f6949b2 100644 --- a/src/libstrongswan/crypto/ietf_attr_list.c +++ b/src/libstrongswan/plugins/x509/ietf_attr_list.c @@ -1,10 +1,3 @@ -/** - * @file ietf_attr.c - * - * @brief Implementation of ietfAttr_t. - * - */ - /* * Copyright (C) 2007 Andreas Steffen, Hochschule fuer Technik Rapperswil * @@ -23,7 +16,11 @@ #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" @@ -227,7 +224,7 @@ void ietfAttr_list_list(linked_list_t *list, FILE *out) break; case IETF_ATTRIBUTE_OID: { - int oid = known_oid(attr->value); + int oid = asn1_known_oid(attr->value); if (oid == OID_UNKNOWN) { @@ -299,33 +296,27 @@ static const asn1Object_t ietfAttrSyntaxObjects[] = { 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 */ + { 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 -#define IETF_ATTR_ROOF 11 /* * Described in header. */ void ietfAttr_list_create_from_chunk(chunk_t chunk, linked_list_t *list, int level0) { - asn1_ctx_t ctx; + asn1_parser_t *parser; chunk_t object; - u_int level; - int objectID = 0; + int objectID; - asn1_init(&ctx, chunk, level0, FALSE, FALSE); + parser = asn1_parser_create(ietfAttrSyntaxObjects, chunk); + parser->set_top_level(parser, level0); - while (objectID < IETF_ATTR_ROOF) + while (parser->iterate(parser, &objectID, &object)) { - if (!extract_object(ietfAttrSyntaxObjects, &objectID, &object, &level, &ctx)) - { - return; - } - switch (objectID) { case IETF_ATTR_OCTETS: @@ -340,8 +331,8 @@ void ietfAttr_list_create_from_chunk(chunk_t chunk, linked_list_t *list, int lev default: break; } - objectID++; } + parser->destroy(parser); } /* @@ -364,7 +355,7 @@ chunk_t ietfAttr_list_encode(linked_list_t *list) } iterator->destroy(iterator); - pos = build_asn1_object(&ietfAttributes, ASN1_SEQUENCE, size); + pos = asn1_build_object(&ietfAttributes, ASN1_SEQUENCE, size); iterator = list->create_iterator(list, TRUE); while (iterator->iterate(iterator, (void **)&attr)) diff --git a/src/libstrongswan/crypto/ietf_attr_list.h b/src/libstrongswan/plugins/x509/ietf_attr_list.h index 75407bbf6..e3e4add61 100644 --- a/src/libstrongswan/crypto/ietf_attr_list.h +++ b/src/libstrongswan/plugins/x509/ietf_attr_list.h @@ -1,10 +1,3 @@ -/** - * @file ietf_attr_list.h - * - * @brief Handling of ietfAttr_t linked lists - * - */ - /* * Copyright (C) 2007 Andreas Steffen * @@ -19,6 +12,13 @@ * 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_ @@ -34,8 +34,6 @@ * @param list_a first alphabetically-sorted list * @param list_b second alphabetically-sorted list * @return TRUE if equal - * - * @ingroup crypto */ bool ietfAttr_list_equals(linked_list_t *list_a, linked_list_t *list_b); @@ -43,9 +41,7 @@ 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 - * - * @ingroup crypto + * @param out output file */ void ietfAttr_list_list(linked_list_t *list, FILE *out); @@ -54,9 +50,7 @@ void ietfAttr_list_list(linked_list_t *list, FILE *out); * * @param msg string with comma-separated group names * @param list alphabetically-sorted linked list of attributes - * - * @ingroup crypto - */ + */ void ietfAttr_list_create_from_string(char *msg, linked_list_t *list); /** @@ -80,10 +74,8 @@ chunk_t ietfAttr_list_encode(linked_list_t *list); * @brief Destroys a linked list of ietfAttr_t objects * * @param list list to be destroyed - * - * @ingroup crypto */ void ietfAttr_list_destroy(linked_list_t *list); -#endif /* IETF_ATTR_LIST_H_ */ +#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, ¤t)) + { + 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, ¤t)) + { + 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_ @}*/ diff --git a/src/libstrongswan/printf_hook.c b/src/libstrongswan/printf_hook.c index baf339640..d0046928f 100644 --- a/src/libstrongswan/printf_hook.c +++ b/src/libstrongswan/printf_hook.c @@ -1,12 +1,5 @@ -/** - * @file printf_hook.c - * - * @brief Printf hook definitions and arginfo functions. - * - */ - /* - * Copyright (C) 2006 Martin Willi + * Copyright (C) 2006-2008 Martin Willi * Hochschule fuer Technik Rapperswil * * This program is free software; you can redistribute it and/or modify it @@ -18,124 +11,55 @@ * 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: printf_hook.c 3589 2008-03-13 14:14:44Z martin $ */ #include "printf_hook.h" -/** - * arginfo handler in printf() pointer - */ -int arginfo_ptr(const struct printf_info *info, size_t n, int *argtypes) -{ - if (n > 0) - { - argtypes[0] = PA_POINTER; - } - return 1; -} +#include <utils.h> -/** - * arginfo handler for two prt arguments - */ -int arginfo_ptr_ptr(const struct printf_info *info, size_t n, int *argtypes) -{ - if (n > 1) - { - argtypes[0] = PA_POINTER; - argtypes[1] = PA_POINTER; - } - return 2; -} +typedef struct private_printf_hook_t private_printf_hook_t; /** - * arginfo handler for one ptr, one int + * private data of printf_hook */ -int arginfo_ptr_int(const struct printf_info *info, size_t n, int *argtypes) -{ - if (n > 1) - { - argtypes[0] = PA_POINTER; - argtypes[1] = PA_INT; - } - return 2; -} +struct private_printf_hook_t { -/** - * arginfo handler for two int arguments - */ -int arginfo_int_int(const struct printf_info *info, size_t n, int *argtypes) -{ - if (n > 1) - { - argtypes[0] = PA_INT; - argtypes[1] = PA_INT; - } - return 2; -} + /** + * public functions + */ + printf_hook_t public; +}; /** - * special arginfo handler respecting alt flag + * Implementation of printf_hook_t.add_handler. */ -int arginfo_int_alt_int_int(const struct printf_info *info, size_t n, int *argtypes) +static void add_handler(private_printf_hook_t *this, char spec, + printf_hook_functions_t hook) { - if (info->alt) - { - if (n > 1) - { - argtypes[0] = PA_INT; - argtypes[1] = PA_INT; - } - return 2; - } - - if (n > 0) - { - argtypes[0] = PA_INT; - } - return 1; + register_printf_function(spec, hook.print, hook.arginfo); } /** - * special arginfo handler respecting alt flag + * Implementation of printf_hook_t.destroy */ -int arginfo_ptr_alt_ptr_int(const struct printf_info *info, size_t n, int *argtypes) +static void destroy(private_printf_hook_t *this) { - if (info->alt) - { - if (n > 1) - { - argtypes[0] = PA_POINTER; - argtypes[1] = PA_INT; - } - return 2; - } - - if (n > 0) - { - argtypes[0] = PA_POINTER; - } - return 1; + free(this); } -/** - * special arginfo handler respecting alt flag +/* + * see header file */ -int arginfo_ptr_alt_ptr_ptr(const struct printf_info *info, size_t n, int *argtypes) +printf_hook_t *printf_hook_create() { - if (info->alt) - { - if (n > 1) - { - argtypes[0] = PA_POINTER; - argtypes[1] = PA_POINTER; - } - return 2; - } + private_printf_hook_t *this = malloc_thing(private_printf_hook_t); + + this->public.add_handler = (void(*)(printf_hook_t*, char, printf_hook_functions_t))add_handler; + this->public.destroy = (void(*)(printf_hook_t*))destroy; + - if (n > 0) - { - argtypes[0] = PA_POINTER; - } - return 1; + return &this->public; } diff --git a/src/libstrongswan/printf_hook.h b/src/libstrongswan/printf_hook.h index 77b228da0..416db1a7f 100644 --- a/src/libstrongswan/printf_hook.h +++ b/src/libstrongswan/printf_hook.h @@ -1,12 +1,5 @@ -/** - * @file printf_hook.h - * - * @brief Printf hook definitions and arginfo functions. - * - */ - /* - * Copyright (C) 2006 Martin Willi + * Copyright (C) 2006-2008 Martin Willi * Hochschule fuer Technik Rapperswil * * This program is free software; you can redistribute it and/or modify it @@ -18,44 +11,68 @@ * 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: printf_hook.h 3749 2008-04-04 11:37:19Z martin $ + */ + +/** + * @defgroup printf_hook printf_hook + * @{ @ingroup libstrongswan */ #ifndef PRINTF_HOOK_H_ #define PRINTF_HOOK_H_ +typedef struct printf_hook_t printf_hook_t; +typedef struct printf_hook_functions_t printf_hook_functions_t; + #include <printf.h> /** - * Printf() hook characters. - * We define all characters here to have them on a central place. + * Printf hook function set. + * + * A printf hook has two functions, one to print the string, one to read + * in the number of arguments. See <printf.h>. */ +struct printf_hook_functions_t { -/** 2 arguments: u_char *buffer, int size */ -#define PRINTF_BYTES 'b' -/** 1 argument: chunk_t *chunk; use #-modifier to print inline */ -#define PRINTF_CHUNK 'B' -/** 1 argument: identification_t *id */ -#define PRINTF_IDENTIFICATION 'D' -/** 1 argumnet: host_t *host; use #-modifier to include port number */ -#define PRINTF_HOST 'H' -/** 1 argument: ike_sa_t *ike_sa */ -#define PRINTF_ENUM 'N' -/** 1 argument: child_sa_t *child_sa */ -#define PRINTF_TRAFFIC_SELECTOR 'R' -/** 1 argument: time_t *time; with #-modifier 2 arguments: time_t *time, bool utc */ -#define PRINTF_TIME 'T' -/** 1 argument: time_t *delta; with #-modifier 2 arguments: time_t *begin, time_t *end */ -#define PRINTF_TIME_DELTA 'V' + /** + * Printf hook print function. This is actually of type "printf_function", + * however glibc does it typedef to function, but uclibc to a pointer. + * So we redefine it here. + */ + int (*print)(FILE *, const struct printf_info *info, const void *const *args); + + /** + * Printf hook arginfo function, which is actually of type + * "printf_arginfo_function". + */ + int (*arginfo)(const struct printf_info *info, size_t n, int *argtypes); +}; /** - * Generic arginfo handlers for printf() hooks + * Printf handler management. */ -int arginfo_ptr(const struct printf_info *info, size_t n, int *argtypes); -int arginfo_ptr_ptr(const struct printf_info *info, size_t n, int *argtypes); -int arginfo_ptr_int(const struct printf_info *info, size_t n, int *argtypes); -int arginfo_int_int(const struct printf_info *info, size_t n, int *argtypes); -int arginfo_ptr_alt_ptr_int(const struct printf_info *info, size_t n, int *argtypes); -int arginfo_ptr_alt_ptr_ptr(const struct printf_info *info, size_t n, int *argtypes); -int arginfo_int_alt_int_int(const struct printf_info *info, size_t n, int *argtypes); - -#endif /* PRINTF_HOOK_H_ */ +struct printf_hook_t { + + /** + * Register a printf handler. + * + * @param spec printf hook format character + * @param hook hook functions + */ + void (*add_handler)(printf_hook_t *this, char spec, + printf_hook_functions_t hook); + + /** + * Destroy a printf_hook instance. + */ + void (*destroy)(printf_hook_t *this); +}; + +/** + * Create a printf_hook instance. + */ +printf_hook_t *printf_hook_create(); + +#endif /* PRINTF_HOOK_H_ @}*/ diff --git a/src/libstrongswan/settings.c b/src/libstrongswan/settings.c new file mode 100644 index 000000000..7c87dccd8 --- /dev/null +++ b/src/libstrongswan/settings.c @@ -0,0 +1,411 @@ +/* + * 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$ + */ + +#define _GNU_SOURCE +#include <string.h> +#include <stdio.h> +#include <errno.h> + +#include "settings.h" + +#include <debug.h> +#include <utils/linked_list.h> + + +typedef struct private_settings_t private_settings_t; +typedef struct section_t section_t; +typedef struct kv_t kv_t; + +/** + * private data of settings + */ +struct private_settings_t { + + /** + * public functions + */ + settings_t public; + + /** + * top level section + */ + section_t *top; + + /** + * allocated file text + */ + char *text; +}; + +/** + * section containing subsections and key value pairs + */ +struct section_t { + + /** + * name of the section + */ + char *name; + + /** + * subsections, as section_t + */ + linked_list_t *sections; + + /** + * key value pairs, as kv_t + */ + linked_list_t *kv; +}; + +/** + * Key value pair + */ +struct kv_t { + + /** + * key string, relative + */ + char *key; + + /** + * value as string + */ + char *value; +}; + +static char *find(section_t *section, char *key) +{ + char *name, *pos, *value = NULL; + enumerator_t *enumerator; + kv_t *kv; + section_t *current, *found = NULL; + + if (section == NULL) + { + return NULL; + } + + name = strdupa(key); + + pos = strchr(name, '.'); + if (pos) + { + *pos = '\0'; + pos++; + enumerator = section->sections->create_enumerator(section->sections); + while (enumerator->enumerate(enumerator, ¤t)) + { + if (streq(current->name, name)) + { + found = current; + break; + } + } + enumerator->destroy(enumerator); + if (found) + { + return find(found, pos); + } + } + else + { + enumerator = section->kv->create_enumerator(section->kv); + while (enumerator->enumerate(enumerator, &kv)) + { + if (streq(kv->key, name)) + { + value = kv->value; + break; + } + } + enumerator->destroy(enumerator); + } + return value; +} + +/** + * Implementation of settings_t.get. + */ +static char* get_str(private_settings_t *this, char *key, char *def) +{ + char *value; + + value = find(this->top, key); + if (value) + { + return value; + } + return def; +} + +/** + * Implementation of settings_t.get_bool. + */ +static bool get_bool(private_settings_t *this, char *key, bool def) +{ + char *value; + + value = find(this->top, key); + if (value) + { + if (strcasecmp(value, "true") == 0 || + strcasecmp(value, "enabled") == 0 || + strcasecmp(value, "yes") == 0 || + strcasecmp(value, "1") == 0) + { + return TRUE; + } + else if (strcasecmp(value, "false") == 0 || + strcasecmp(value, "disabled") == 0 || + strcasecmp(value, "no") == 0 || + strcasecmp(value, "0") == 0) + { + return FALSE; + } + } + return def; +} + +/** + * Implementation of settings_t.get_int. + */ +static int get_int(private_settings_t *this, char *key, int def) +{ + char *value; + int intval; + + value = find(this->top, key); + if (value) + { + errno = 0; + intval = strtol(value, NULL, 10); + if (errno == 0) + { + return intval; + } + } + return def; +} + +/** + * destry a section +*/ +static void section_destroy(section_t *this) +{ + this->kv->destroy_function(this->kv, free); + this->sections->destroy_function(this->sections, (void*)section_destroy); + + free(this); +} + +/** + * parse text, truncate "skip" chars, delimited by term respecting brackets. + * + * Chars in "skip" are truncated at the beginning and the end of the resulting + * token. "term" contains a list of characters to read up to (first match), + * while "br" contains bracket counterparts found in "term" to skip. + */ +static char parse(char **text, char *skip, char *term, char *br, char **token) +{ + char *best = NULL; + char best_term = '\0'; + + /* skip leading chars */ + while (strchr(skip, **text)) + { + (*text)++; + if (!**text) + { + return 0; + } + } + /* mark begin of subtext */ + *token = *text; + while (*term) + { + char *pos = *text; + int level = 1; + + /* find terminator */ + while (*pos) + { + if (*pos == *term) + { + level--; + } + else if (br && *pos == *br) + { + level++; + } + if (level == 0) + { + if (best == NULL || best > pos) + { + best = pos; + best_term = *term; + } + break; + } + pos++; + } + /* try next terminator */ + term++; + if (br) + { + br++; + } + } + if (best) + { + /* update input */ + *text = best; + /* null trailing bytes */ + do + { + *best = '\0'; + best--; + } + while (best >= *token && strchr(skip, *best)); + /* return found terminator */ + return best_term; + } + return 0; +} + +/** + * Parse a section + */ +static section_t* parse_section(char **text, char *name) +{ + section_t *sub, *section; + bool finished = FALSE; + char *key, *value, *inner; + + static int lev = 0; + lev++; + + section = malloc_thing(section_t); + section->name = name; + section->sections = linked_list_create(); + section->kv = linked_list_create(); + + while (!finished) + { + switch (parse(text, "\t\n ", "{=#", NULL, &key)) + { + case '{': + if (parse(text, "\t ", "}", "{", &inner)) + { + sub = parse_section(&inner, key); + if (sub) + { + section->sections->insert_last(section->sections, sub); + continue; + } + } + DBG1("matching '}' not found near %s", *text); + break; + case '=': + if (parse(text, "\t ", "\n", NULL, &value)) + { + kv_t *kv = malloc_thing(kv_t); + kv->key = key; + kv->value = value; + section->kv->insert_last(section->kv, kv); + continue; + } + DBG1("parsing value failed near %s", *text); + break; + case '#': + parse(text, "", "\n", NULL, &value); + continue; + default: + finished = TRUE; + continue; + } + section_destroy(section); + return NULL; + } + return section; +} + +/** + * Implementation of settings_t.destroy + */ +static void destroy(private_settings_t *this) +{ + if (this->top) + { + section_destroy(this->top); + } + free(this->text); + free(this); +} + +/* + * see header file + */ +settings_t *settings_create(char *file) +{ + private_settings_t *this = malloc_thing(private_settings_t); + + this->public.get_str = (char*(*)(settings_t*, char *key, char* def))get_str; + this->public.get_int = (int(*)(settings_t*, char *key, bool def))get_int; + this->public.get_bool = (bool(*)(settings_t*, char *key, bool def))get_bool; + this->public.destroy = (void(*)(settings_t*))destroy; + + this->top = NULL; + this->text = NULL; + + if (file) + { + FILE *fd; + int len; + char *pos; + + fd = fopen(file, "r"); + if (fd == NULL) + { + DBG1("'%s' does not exist or is not readable", file); + return &this->public; + } + fseek(fd, 0, SEEK_END); + len = ftell(fd); + rewind(fd); + this->text = malloc(len + 1); + this->text[len] = '\0'; + if (fread(this->text, 1, len, fd) != len) + { + free(this->text); + this->text = NULL; + return &this->public; + } + fclose(fd); + + pos = this->text; + this->top = parse_section(&pos, NULL); + if (this->top == NULL) + { + free(this->text); + this->text = NULL; + return &this->public; + } + } + return &this->public; +} + diff --git a/src/libstrongswan/settings.h b/src/libstrongswan/settings.h new file mode 100644 index 000000000..91770973b --- /dev/null +++ b/src/libstrongswan/settings.h @@ -0,0 +1,96 @@ +/* + * 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 settings settings + * @{ @ingroup libstrongswan + */ + +#ifndef SETTINGS_H_ +#define SETTINGS_H_ + +typedef struct settings_t settings_t; + +#include <library.h> + +/** + * Generic configuration options read from a config file. + * + * The sytax is quite simple: + * + * settings := (section|keyvalue)* + * section := name { settings } + * keyvalue := key = value\n + * + * E.g.: + * @code + a = b + section-one { + somevalue = asdf + subsection { + othervalue = xxx + } + yetanother = zz + } + section-two { + } + @endcode + * + * The values are accesses using the get() functions using dotted keys, e.g. + * section-one.subsection.othervalue + */ +struct settings_t { + + /** + * Get a settings value as a string. + * + * @param key key including sections + * @param def value returned if key not found + * @return value pointing to internal string + */ + char* (*get_str)(settings_t *this, char *key, char *def); + + /** + * Get a boolean yes|no, true|false value. + * + * @param jey key including sections + * @param def default value returned if key not found + * @return value of the key + */ + bool (*get_bool)(settings_t *this, char *key, bool def); + + /** + * Get an integer value. + * + * @param key key including sections + * @param def default value to return if key not found + * @return value of the key + */ + int (*get_int)(settings_t *this, char *key, bool def); + + /** + * Destroy a settings instance. + */ + void (*destroy)(settings_t *this); +}; + +/** + * Load setings from a file. + */ +settings_t *settings_create(char *file); + +#endif /* SETTINGS_H_ @}*/ diff --git a/src/libstrongswan/utils.c b/src/libstrongswan/utils.c new file mode 100644 index 000000000..bd13b7c4d --- /dev/null +++ b/src/libstrongswan/utils.c @@ -0,0 +1,342 @@ +/* + * 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. + * + * $Id: utils.c 3820 2008-04-17 11:22:37Z martin $ + */ + +#include "utils.h" + +#include <string.h> +#include <pthread.h> +#include <stdio.h> + +#include <enum.h> + +ENUM(status_names, SUCCESS, DESTROY_ME, + "SUCCESS", + "FAILED", + "OUT_OF_RES", + "ALREADY_DONE", + "NOT_SUPPORTED", + "INVALID_ARG", + "NOT_FOUND", + "PARSE_ERROR", + "VERIFY_ERROR", + "INVALID_STATE", + "DESTROY_ME", + "NEED_MORE", +); + +/** + * Described in header. + */ +void *clalloc(void * pointer, size_t size) +{ + void *data; + data = malloc(size); + + memcpy(data, pointer, size); + + return (data); +} + +/** + * Described in header. + */ +void memxor(u_int8_t dest[], u_int8_t src[], size_t n) +{ + size_t i; + for (i = 0; i < n; i++) + { + dest[i] ^= src[i]; + } +} + +/** + * return null + */ +void *return_null() +{ + return NULL; +} + +/** + * nop operation + */ +void nop() +{ +} + +/** + * We use a single mutex for all refcount variables. This + * is not optimal for performance, but the critical section + * is not that long... + * TODO: Consider to include a mutex in each refcount_t variable. + */ +static pthread_mutex_t ref_mutex = PTHREAD_MUTEX_INITIALIZER; + +/** + * Described in header. + * + * TODO: May be implemented with atomic CPU instructions + * instead of a mutex. + */ +void ref_get(refcount_t *ref) +{ + pthread_mutex_lock(&ref_mutex); + (*ref)++; + pthread_mutex_unlock(&ref_mutex); +} + +/** + * Described in header. + * + * TODO: May be implemented with atomic CPU instructions + * instead of a mutex. + */ +bool ref_put(refcount_t *ref) +{ + bool more_refs; + + pthread_mutex_lock(&ref_mutex); + more_refs = --(*ref); + pthread_mutex_unlock(&ref_mutex); + return !more_refs; +} + +/** + * output handler in printf() for time_t + */ +static int time_print(FILE *stream, const struct printf_info *info, + const void *const *args) +{ + static const char* months[] = { + "Jan", "Feb", "Mar", "Apr", "May", "Jun", + "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" + }; + time_t *time = *((time_t**)(args[0])); + bool utc = TRUE; + struct tm t; + + if (info->alt) + { + utc = *((bool*)(args[1])); + } + if (time == UNDEFINED_TIME) + { + return fprintf(stream, "--- -- --:--:--%s----", + info->alt ? " UTC " : " "); + } + if (utc) + { + gmtime_r(time, &t); + } + else + { + localtime_r(time, &t); + } + return fprintf(stream, "%s %02d %02d:%02d:%02d%s%04d", + months[t.tm_mon], t.tm_mday, t.tm_hour, t.tm_min, + t.tm_sec, utc ? " UTC " : " ", t.tm_year + 1900); +} + +/** + * arginfo handler for printf() time + */ +static int time_arginfo(const struct printf_info *info, size_t n, int *argtypes) +{ + if (info->alt) + { + if (n > 1) + { + argtypes[0] = PA_POINTER; + argtypes[1] = PA_INT; + } + return 2; + } + + if (n > 0) + { + argtypes[0] = PA_POINTER; + } + return 1; +} + +/** + * output handler in printf() for time deltas + */ +static int time_delta_print(FILE *stream, const struct printf_info *info, + const void *const *args) +{ + char* unit = "second"; + time_t *arg1, *arg2; + time_t delta; + + arg1 = *((time_t**)(args[0])); + if (info->alt) + { + arg2 = *((time_t**)(args[1])); + delta = abs(*arg1 - *arg2); + } + else + { + delta = *arg1; + } + + if (delta > 2 * 60 * 60 * 24) + { + delta /= 60 * 60 * 24; + unit = "day"; + } + else if (delta > 2 * 60 * 60) + { + delta /= 60 * 60; + unit = "hour"; + } + else if (delta > 2 * 60) + { + delta /= 60; + unit = "minute"; + } + return fprintf(stream, "%d %s%s", delta, unit, (delta == 1)? "":"s"); +} + +/** + * arginfo handler for printf() time deltas + */ +int time_delta_arginfo(const struct printf_info *info, size_t n, int *argtypes) +{ + if (info->alt) + { + if (n > 1) + { + argtypes[0] = PA_POINTER; + argtypes[1] = PA_POINTER; + } + return 2; + } + + if (n > 0) + { + argtypes[0] = PA_POINTER; + } + return 1; +} + +/** + * Number of bytes per line to dump raw data + */ +#define BYTES_PER_LINE 16 + +static char hexdig_upper[] = "0123456789ABCDEF"; + +/** + * output handler in printf() for mem ranges + */ +static int mem_print(FILE *stream, const struct printf_info *info, + const void *const *args) +{ + char *bytes = *((void**)(args[0])); + int len = *((size_t*)(args[1])); + + char buffer[BYTES_PER_LINE * 3]; + char ascii_buffer[BYTES_PER_LINE + 1]; + char *buffer_pos = buffer; + char *bytes_pos = bytes; + char *bytes_roof = bytes + len; + int line_start = 0; + int i = 0; + int written = 0; + + written += fprintf(stream, "=> %d bytes @ %p", len, bytes); + + while (bytes_pos < bytes_roof) + { + *buffer_pos++ = hexdig_upper[(*bytes_pos >> 4) & 0xF]; + *buffer_pos++ = hexdig_upper[ *bytes_pos & 0xF]; + + ascii_buffer[i++] = + (*bytes_pos > 31 && *bytes_pos < 127) ? *bytes_pos : '.'; + + if (++bytes_pos == bytes_roof || i == BYTES_PER_LINE) + { + int padding = 3 * (BYTES_PER_LINE - i); + int written; + + while (padding--) + { + *buffer_pos++ = ' '; + } + *buffer_pos++ = '\0'; + ascii_buffer[i] = '\0'; + + written += fprintf(stream, "\n%4d: %s %s", + line_start, buffer, ascii_buffer); + + + buffer_pos = buffer; + line_start += BYTES_PER_LINE; + i = 0; + } + else + { + *buffer_pos++ = ' '; + } + } + return written; +} + +/** + * arginfo handler for printf() mem ranges + */ +int mem_arginfo(const struct printf_info *info, size_t n, int *argtypes) +{ + if (n > 1) + { + argtypes[0] = PA_POINTER; + argtypes[1] = PA_INT; + } + return 2; +} + +/** + * return printf hook functions for a time + */ +printf_hook_functions_t time_get_printf_hooks() +{ + printf_hook_functions_t hooks = {time_print, time_arginfo}; + + return hooks; +} + +/** + * return printf hook functions for a time delta + */ +printf_hook_functions_t time_delta_get_printf_hooks() +{ + printf_hook_functions_t hooks = {time_delta_print, time_delta_arginfo}; + + return hooks; +} + +/** + * return printf hook functions for mem ranges + */ +printf_hook_functions_t mem_get_printf_hooks() +{ + printf_hook_functions_t hooks = {mem_print, mem_arginfo}; + + return hooks; +} + diff --git a/src/libstrongswan/utils.h b/src/libstrongswan/utils.h new file mode 100644 index 000000000..ee3ebbd41 --- /dev/null +++ b/src/libstrongswan/utils.h @@ -0,0 +1,275 @@ +/* + * 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: utils.h 3820 2008-04-17 11:22:37Z martin $ + */ + +/** + * @defgroup utils utils + * @{ @ingroup libstrongswan + */ + +#ifndef UTILS_H_ +#define UTILS_H_ + +#include <sys/types.h> +#include <stdlib.h> +#include <stddef.h> + +#include <enum.h> + +/** + * Number of bits in a byte + */ +#define BITS_PER_BYTE 8 + +/** + * Default length for various auxiliary text buffers + */ +#define BUF_LEN 512 + +/** + * Macro compares two strings for equality + */ +#define streq(x,y) (strcmp(x, y) == 0) + +/** + * Macro compares two strings for equality + */ +#define strneq(x,y,len) (strncmp(x, y, len) == 0) + +/** + * Macro compares two binary blobs for equality + */ +#define memeq(x,y,len) (memcmp(x, y, len) == 0) + +/** + * Macro gives back larger of two values. + */ +#define max(x,y) ((x) > (y) ? (x):(y)) + +/** + * Macro gives back smaller of two values. + */ +#define min(x,y) ((x) < (y) ? (x):(y)) + +/** + * Call destructor of an object, if object != NULL + */ +#define DESTROY_IF(obj) if (obj) (obj)->destroy(obj) + +/** + * Call offset destructor of an object, if object != NULL + */ +#define DESTROY_OFFSET_IF(obj, offset) if (obj) obj->destroy_offset(obj, offset); + +/** + * Call function destructor of an object, if object != NULL + */ +#define DESTROY_FUNCTION_IF(obj, fn) if (obj) obj->destroy_function(obj, fn); + +/** + * Debug macro to follow control flow + */ +#define POS printf("%s, line %d\n", __FILE__, __LINE__) + +/** + * Macro to allocate a sized type. + */ +#define malloc_thing(thing) ((thing*)malloc(sizeof(thing))) + +/** + * Assign a function as a class method + */ +#define ASSIGN(method, function) (method = (typeof(method))function) + +/** + * time_t not defined + */ +#define UNDEFINED_TIME 0 + +/** + * General purpose boolean type. + */ +typedef int bool; +#define FALSE 0 +#define TRUE 1 + +typedef enum status_t status_t; + +/** + * Return values of function calls. + */ +enum status_t { + /** + * Call succeeded. + */ + SUCCESS, + + /** + * Call failed. + */ + FAILED, + + /** + * Out of resources. + */ + OUT_OF_RES, + + /** + * The suggested operation is already done + */ + ALREADY_DONE, + + /** + * Not supported. + */ + NOT_SUPPORTED, + + /** + * One of the arguments is invalid. + */ + INVALID_ARG, + + /** + * Something could not be found. + */ + NOT_FOUND, + + /** + * Error while parsing. + */ + PARSE_ERROR, + + /** + * Error while verifying. + */ + VERIFY_ERROR, + + /** + * Object in invalid state. + */ + INVALID_STATE, + + /** + * Destroy object which called method belongs to. + */ + DESTROY_ME, + + /** + * Another call to the method is required. + */ + NEED_MORE, +}; + +/** + * enum_names for type status_t. + */ +extern enum_name_t *status_names; + +/** + * deprecated pluto style return value: + * error message, NULL for success + */ +typedef const char *err_t; + +/** + * Handle struct timeval like an own type. + */ +typedef struct timeval timeval_t; + +/** + * Handle struct timespec like an own type. + */ +typedef struct timespec timespec_t; + +/** + * Handle struct chunk_t like an own type. + */ +typedef struct sockaddr sockaddr_t; + +/** + * Clone a data to a newly allocated buffer + */ +void *clalloc(void *pointer, size_t size); + +/** + * Same as memcpy, but XORs src into dst instead of copy + */ +void memxor(u_int8_t dest[], u_int8_t src[], size_t n); + +/** + * returns null + */ +void *return_null(); + +/** + * No-Operation function + */ +void nop(); + +/** + * Special type to count references + */ +typedef volatile u_int refcount_t; + +/** + * Get a new reference. + * + * Increments the reference counter atomic. + * + * @param ref pointer to ref counter + */ +void ref_get(refcount_t *ref); + +/** + * Put back a unused reference. + * + * Decrements the reference counter atomic and + * says if more references available. + * + * @param ref pointer to ref counter + * @return TRUE if no more references counted + */ +bool ref_put(refcount_t *ref); + +/** + * Get printf hooks for time. + * + * Arguments are: + * time_t* time + * Arguments using #-specificer + * time_t* time, bool utc + */ +printf_hook_functions_t time_get_printf_hooks(); + +/** + * Get printf hooks for time deltas. + * + * Arguments are: + * time_t* delta + * Arguments using #-specificer + * time_t* begin, time_t* end + */ +printf_hook_functions_t time_delta_get_printf_hooks(); + +/** + * Get printf hooks for time deltas. + * + * Arguments are: + * u_char *ptr, int len + */ +printf_hook_functions_t mem_get_printf_hooks(); + +#endif /* UTILS_H_ @}*/ diff --git a/src/libstrongswan/utils/enumerator.c b/src/libstrongswan/utils/enumerator.c index 842a2e997..cac5d73fa 100644 --- a/src/libstrongswan/utils/enumerator.c +++ b/src/libstrongswan/utils/enumerator.c @@ -1,10 +1,3 @@ -/** - * @file enumerator.c - * - * @brief Implementation of enumerator_t. - * - */ - /* * Copyright (C) 2007 Martin Willi * Hochschule fuer Technik Rapperswil @@ -18,10 +11,20 @@ * 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: enumerator.c 3589 2008-03-13 14:14:44Z martin $ */ #include "enumerator.h" +#include <sys/types.h> +#include <sys/stat.h> +#include <unistd.h> +#include <stdio.h> +#include <dirent.h> +#include <errno.h> + +#include <debug.h> /** * Implementation of enumerator_create_empty().enumerate @@ -42,3 +45,350 @@ enumerator_t* enumerator_create_empty() return this; } +/** + * Enumerator implementation for directory enumerator + */ +typedef struct { + /** implements enumerator_t */ + enumerator_t public; + /** directory handle */ + DIR *dir; + /** absolute path of current file */ + char full[PATH_MAX]; + /** where directory part of full ends and relative file gets written */ + char *full_end; +} dir_enum_t; + +/** + * Implementation of enumerator_create_directory().destroy + */ +static void destroy_dir_enum(dir_enum_t *this) +{ + closedir(this->dir); + free(this); +} + +/** + * Implementation of enumerator_create_directory().enumerate + */ +static bool enumerate_dir_enum(dir_enum_t *this, char **relative, + char **absolute, struct stat *st) +{ + struct dirent *entry = readdir(this->dir); + size_t len, remaining; + + if (!entry) + { + return FALSE; + } + if (streq(entry->d_name, ".") || streq(entry->d_name, "..")) + { + return enumerate_dir_enum(this, relative, absolute, st); + } + if (relative) + { + *relative = entry->d_name; + } + if (absolute || st) + { + remaining = sizeof(this->full) - (this->full_end - this->full); + len = snprintf(this->full_end, remaining, "%s", entry->d_name); + if (len < 0 || len >= remaining) + { + DBG1("buffer too small to enumerate file '%s'", entry->d_name); + return FALSE; + } + if (absolute) + { + *absolute = this->full; + } + if (st) + { + if (stat(this->full, st)) + { + DBG1("stat() on '%s' failed: %s", this->full, strerror(errno)); + return FALSE; + } + } + } + return TRUE; +} + +/** + * See header + */ +enumerator_t* enumerator_create_directory(char *path) +{ + size_t len; + dir_enum_t *this = malloc_thing(dir_enum_t); + this->public.enumerate = (void*)enumerate_dir_enum; + this->public.destroy = (void*)destroy_dir_enum; + + if (*path == '\0') + { + path = "./"; + } + len = snprintf(this->full, sizeof(this->full)-1, "%s", path); + if (len < 0 || len >= sizeof(this->full)-1) + { + DBG1("path string %s too long", path); + free(this); + return NULL; + } + /* append a '/' if not already done */ + if (this->full[len-1] != '/') + { + this->full[len++] = '/'; + this->full[len] = '\0'; + } + this->full_end = &this->full[len]; + + this->dir = opendir(path); + if (this->dir == NULL) + { + DBG1("opening directory %s failed: %s", path, strerror(errno)); + free(this); + return NULL; + } + return &this->public; +} + +/** + * enumerator for nested enumerations + */ +typedef struct { + /* implements enumerator_t */ + enumerator_t public; + /* outer enumerator */ + enumerator_t *outer; + /* inner enumerator */ + enumerator_t *inner; + /* constructor for inner enumerator */ + enumerator_t *(*create_inner)(void *outer, void *data); + /* data to pass to constructor above */ + void *data; + /* destructor for data */ + void (*destroy_data)(void *data); +} nested_enumerator_t; + + +/** + * Implementation of enumerator_create_nested().enumerate() + */ +static bool enumerate_nested(nested_enumerator_t *this, void *v1, void *v2, + void *v3, void *v4, void *v5) +{ + while (TRUE) + { + while (this->inner == NULL) + { + void *outer; + + if (!this->outer->enumerate(this->outer, &outer)) + { + return FALSE; + } + this->inner = this->create_inner(outer, this->data); + } + if (this->inner->enumerate(this->inner, v1, v2, v3, v4, v5)) + { + return TRUE; + } + this->inner->destroy(this->inner); + this->inner = NULL; + } +} + +/** + * Implementation of enumerator_create_nested().destroy() + **/ +static void destroy_nested(nested_enumerator_t *this) +{ + if (this->destroy_data) + { + this->destroy_data(this->data); + } + DESTROY_IF(this->inner); + this->outer->destroy(this->outer); + free(this); +} + +/** + * See header + */ +enumerator_t *enumerator_create_nested(enumerator_t *outer, + enumerator_t *(inner_constructor)(void *outer, void *data), + void *data, void (*destroy_data)(void *data)) +{ + nested_enumerator_t *enumerator = malloc_thing(nested_enumerator_t); + + enumerator->public.enumerate = (void*)enumerate_nested; + enumerator->public.destroy = (void*)destroy_nested; + enumerator->outer = outer; + enumerator->inner = NULL; + enumerator->create_inner = (void*)inner_constructor; + enumerator->data = data; + enumerator->destroy_data = destroy_data; + + return &enumerator->public; +} + +/** + * enumerator for filtered enumerator + */ +typedef struct { + enumerator_t public; + enumerator_t *unfiltered; + void *data; + bool (*filter)(void *data, ...); + void (*destructor)(void *data); +} filter_enumerator_t; + +/** + * Implementation of enumerator_create_filter().destroy + */ +void destroy_filter(filter_enumerator_t *this) +{ + if (this->destructor) + { + this->destructor(this->data); + } + this->unfiltered->destroy(this->unfiltered); + free(this); +} + +/** + * Implementation of enumerator_create_filter().enumerate + */ +bool enumerate_filter(filter_enumerator_t *this, void *o1, void *o2, + void *o3, void *o4, void *o5) +{ + void *i1, *i2, *i3, *i4, *i5; + + while (this->unfiltered->enumerate(this->unfiltered, &i1, &i2, &i3, &i4, &i5)) + { + if (this->filter(this->data, &i1, o1, &i2, o2, &i3, o3, &i4, o4, &i5, o5)) + { + return TRUE; + } + } + return FALSE; +} + +/** + * see header + */ +enumerator_t *enumerator_create_filter(enumerator_t *unfiltered, + bool (*filter)(void *data, ...), + void *data, void (*destructor)(void *data)) +{ + filter_enumerator_t *this = malloc_thing(filter_enumerator_t); + + this->public.enumerate = (void*)enumerate_filter; + this->public.destroy = (void*)destroy_filter; + this->unfiltered = unfiltered; + this->filter = filter; + this->data = data; + this->destructor = destructor; + + return &this->public; +} + +/** + * enumerator for cleaner enumerator + */ +typedef struct { + enumerator_t public; + enumerator_t *wrapped; + void (*cleanup)(void *data); + void *data; +} cleaner_enumerator_t; + +/** + * Implementation of enumerator_create_cleanup().destroy + */ +static void destroy_cleaner(cleaner_enumerator_t *this) +{ + this->cleanup(this->data); + this->wrapped->destroy(this->wrapped); + free(this); +} + +/** + * Implementation of enumerator_create_cleaner().enumerate + */ +static bool enumerate_cleaner(cleaner_enumerator_t *this, void *v1, void *v2, + void *v3, void *v4, void *v5) +{ + return this->wrapped->enumerate(this->wrapped, v1, v2, v3, v4, v5); +} + +/** + * see header + */ +enumerator_t *enumerator_create_cleaner(enumerator_t *wrapped, + void (*cleanup)(void *data), void *data) +{ + cleaner_enumerator_t *this = malloc_thing(cleaner_enumerator_t); + + this->public.enumerate = (void*)enumerate_cleaner; + this->public.destroy = (void*)destroy_cleaner; + this->wrapped = wrapped; + this->cleanup = cleanup; + this->data = data; + + return &this->public; +} + +/** + * enumerator for single enumerator + */ +typedef struct { + enumerator_t public; + void *item; + void (*cleanup)(void *item); + bool done; +} single_enumerator_t; + +/** + * Implementation of enumerator_create_single().destroy + */ +static void destroy_single(single_enumerator_t *this) +{ + if (this->cleanup) + { + this->cleanup(this->item); + } + free(this); +} + +/** + * Implementation of enumerator_create_single().enumerate + */ +static bool enumerate_single(single_enumerator_t *this, void **item) +{ + if (this->done) + { + return FALSE; + } + *item = this->item; + this->done = TRUE; + return TRUE; +} + +/** + * see header + */ +enumerator_t *enumerator_create_single(void *item, void (*cleanup)(void *item)) +{ + single_enumerator_t *this = malloc_thing(single_enumerator_t); + + this->public.enumerate = (void*)enumerate_single; + this->public.destroy = (void*)destroy_single; + this->item = item; + this->cleanup = cleanup; + this->done = FALSE; + + return &this->public; +} + diff --git a/src/libstrongswan/utils/enumerator.h b/src/libstrongswan/utils/enumerator.h index df1d78206..6b91fee72 100644 --- a/src/libstrongswan/utils/enumerator.h +++ b/src/libstrongswan/utils/enumerator.h @@ -1,10 +1,3 @@ -/** - * @file enumerator.h - * - * @brief Interface of enumerator_t. - * - */ - /* * Copyright (C) 2007 Martin Willi * Hochschule fuer Technik Rapperswil @@ -18,22 +11,29 @@ * 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: enumerator.h 3589 2008-03-13 14:14:44Z martin $ + */ + +/** + * @defgroup enumerator enumerator + * @{ @ingroup utils */ #ifndef ENUMERATOR_H_ #define ENUMERATOR_H_ -#include <library.h> - typedef struct enumerator_t enumerator_t; +#include <library.h> + /** - * @brief Enumerate is simpler, but more flexible than iterator. + * Enumerate is simpler, but more flexible than iterator. */ struct enumerator_t { /** - * @brief Enumerate collection. + * Enumerate collection. * * The enumerate function takes a variable argument list containing * pointers where the enumerated values get written. @@ -44,14 +44,104 @@ struct enumerator_t { bool (*enumerate)(enumerator_t *this, ...); /** - * @brief Destroy a enumerator instance. + * Destroy a enumerator instance. */ void (*destroy)(enumerator_t *this); }; /** - * @brief Create an enumerator which enumerates over nothing + * Create an enumerator which enumerates over nothing + * + * @return an enumerator over no values */ enumerator_t* enumerator_create_empty(); -#endif /* ENUMERATOR_H_ */ +/** + * Create an enumerator which enumerates over a single item + * + * @param item item to enumerate + * @param cleanup cleanup function called on destroy with the item + * @return an enumerator over a single value + */ +enumerator_t *enumerator_create_single(void *item, void (*cleanup)(void *item)); + +/** + * Create an enumerator over files/subdirectories in a directory. + * + * This enumerator_t.enumerate() function returns a (to the directory) relative + * filename (as a char*), an absolute filename (as a char*) and a file status + * (to a struct stat), which all may be NULL. "." and ".." entries are + * skipped. Example: + * + * @code + char *rel, *abs; + struct stat st; + enumerator_t *e; + + e = enumerator_create_directory("/tmp"); + if (e) + { + while (e->enumerate(e, &rel, &abs, &st)) + { + if (S_ISDIR(st.st_mode) && *rel != '.') + { + printf("%s\n", abs); + } + } + e->destroy(e); + } + @endcode + * + * @param path path of the directory + * @return the directory enumerator, NULL on failure + */ +enumerator_t* enumerator_create_directory(char *path); + +/** + * Creates an enumerator which enumerates over enumerated enumerators :-). + * + * The variable argument list of enumeration values is limit to 5. + * + * @param outer outer enumerator + * @param inner_constructor constructor to inner enumerator + * @param data data to pass to each inner_constructor call + * @param destroy_data destructor to pass to data + * @return the nested enumerator + */ +enumerator_t *enumerator_create_nested(enumerator_t *outer, + enumerator_t *(inner_constructor)(void *outer, void *data), + void *data, void (*destroy_data)(void *data)); + +/** + * Creates an enumerator which filters output of another enumerator. + * + * The filter function receives the user supplied "data" followed by a + * unfiltered enumeration item, followed by an output pointer where to write + * the filtered data. Then the next input/output pair follows. + * It returns TRUE to deliver the + * values to the caller of enumerate(), FALSE to filter this enumeration. + * + * The variable argument list of enumeration values is limit to 5. + * + * @param unfiltered unfiltered enumerator to wrap, gets destroyed + * @param filter filter function + * @param data user data to supply to filter + * @param destructor destructor function to clean up data after use + * @return the filtered enumerator + */ +enumerator_t *enumerator_create_filter(enumerator_t *unfiltered, + bool (*filter)(void *data, ...), + void *data, void (*destructor)(void *data)); + +/** + * Create an enumerator wrapper which does a cleanup on destroy. + * + * @param wrapped wrapped enumerator + * @param cleanup cleanup function called on destroy + * @param data user data to supply to cleanup + * @return the enumerator with cleanup + */ +enumerator_t *enumerator_create_cleaner(enumerator_t *wrapped, + void (*cleanup)(void *data), void *data); + +#endif /* ENUMERATOR_H_ @} */ diff --git a/src/libstrongswan/utils/fetcher.c b/src/libstrongswan/utils/fetcher.c deleted file mode 100644 index 7a06999aa..000000000 --- a/src/libstrongswan/utils/fetcher.c +++ /dev/null @@ -1,424 +0,0 @@ -/** - * @file fetcher.c - * - * @brief Implementation of fetcher_t. - * - */ - -/* - * 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 <fetcher://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. - */ - -#ifdef LIBCURL -#include <curl/curl.h> -#endif /* LIBCURL */ - -#ifdef LIBLDAP -#ifndef LDAP_DEPRECATED -#define LDAP_DEPRECATED 1 -#endif -#include <ldap.h> -#endif /* LIBLDAP */ - -#include <library.h> -#include <debug.h> - -#include "fetcher.h" - -typedef struct private_fetcher_t private_fetcher_t; - -/** - * @brief Private Data of a fetcher_t object. - */ -struct private_fetcher_t { - /** - * Public data - */ - fetcher_t public; - - /** - * URI of the information source - */ - const char *uri; - -#ifdef LIBCURL - /** - * we use libcurl from http://curl.haxx.se/ as a fetcher - */ - CURL* curl; -#endif /* LIBCURL */ - -#ifdef LIBLDAP - /** - * we use libldap from http://www.openssl.org/ as a fetcher - */ - LDAP *ldap; - LDAPURLDesc *lurl; -#endif /* LIBLDAP */ -}; - -/** - * writes data into a dynamically resizeable chunk_t - * needed for libcurl responses - */ -static size_t curl_write_buffer(void *ptr, size_t size, size_t nmemb, void *data) -{ - size_t realsize = size * nmemb; - chunk_t *mem = (chunk_t*)data; - - mem->ptr = (u_char *)realloc(mem->ptr, mem->len + realsize); - if (mem->ptr) { - memcpy(&(mem->ptr[mem->len]), ptr, realsize); - mem->len += realsize; - } - return realsize; -} - -/** - * Implements fetcher_t.get for curl methods - */ -static chunk_t curl_get(private_fetcher_t *this) -{ - chunk_t response = chunk_empty; - -#ifdef LIBCURL - if (this->curl) - { - CURLcode res; - chunk_t curl_response = chunk_empty; - char curl_error_buffer[CURL_ERROR_SIZE]; - - curl_easy_setopt(this->curl, CURLOPT_URL, this->uri); - curl_easy_setopt(this->curl, CURLOPT_WRITEFUNCTION, curl_write_buffer); - curl_easy_setopt(this->curl, CURLOPT_WRITEDATA, (void *)&curl_response); - curl_easy_setopt(this->curl, CURLOPT_ERRORBUFFER, &curl_error_buffer); - curl_easy_setopt(this->curl, CURLOPT_FAILONERROR, TRUE); - curl_easy_setopt(this->curl, CURLOPT_CONNECTTIMEOUT, FETCHER_TIMEOUT); - curl_easy_setopt(this->curl, CURLOPT_NOSIGNAL, TRUE); - - DBG1("sending curl request to '%s'...", this->uri); - res = curl_easy_perform(this->curl); - - if (res == CURLE_OK) - { - DBG1("received valid curl response"); - response = chunk_clone(curl_response); - } - else - { - DBG1("curl request failed: %s", curl_error_buffer); - } - curl_free(curl_response.ptr); - } -#else - DBG1("warning: libcurl fetching not compiled in"); -#endif /* LIBCURL */ - return response; -} - -/** - * Implements fetcher_t.post. - */ -static chunk_t http_post(private_fetcher_t *this, const char *request_type, chunk_t request) -{ - chunk_t response = chunk_empty; - -#ifdef LIBCURL - if (this->curl) - { - CURLcode res; - struct curl_slist *headers = NULL; - chunk_t curl_response = chunk_empty; - char curl_error_buffer[CURL_ERROR_SIZE]; - char content_type[BUF_LEN]; - - /* set content type header */ - snprintf(content_type, BUF_LEN, "Content-Type: %s", request_type); - headers = curl_slist_append(headers, content_type); - - /* set options */ - curl_easy_setopt(this->curl, CURLOPT_HTTPHEADER, headers); - curl_easy_setopt(this->curl, CURLOPT_URL, this->uri); - curl_easy_setopt(this->curl, CURLOPT_WRITEFUNCTION, curl_write_buffer); - curl_easy_setopt(this->curl, CURLOPT_WRITEDATA, (void *)&curl_response); - curl_easy_setopt(this->curl, CURLOPT_POSTFIELDS, request.ptr); - curl_easy_setopt(this->curl, CURLOPT_POSTFIELDSIZE, request.len); - curl_easy_setopt(this->curl, CURLOPT_ERRORBUFFER, &curl_error_buffer); - curl_easy_setopt(this->curl, CURLOPT_FAILONERROR, TRUE); - curl_easy_setopt(this->curl, CURLOPT_CONNECTTIMEOUT, FETCHER_TIMEOUT); - curl_easy_setopt(this->curl, CURLOPT_NOSIGNAL, TRUE); - - DBG1("sending http post request to '%s'...", this->uri); - res = curl_easy_perform(this->curl); - - if (res == CURLE_OK) - { - DBG1("received valid http response"); - response = chunk_clone(curl_response); - } - else - { - DBG1("http post request using libcurl failed: %s", curl_error_buffer); - } - curl_slist_free_all(headers); - curl_free(curl_response.ptr); - } -#else - DBG1("warning: libcurl fetching not compiled in"); -#endif /* LIBCURL */ - return response; -} - -#ifdef LIBLDAP -/** - * Parses the result returned by an ldap query - */ -static chunk_t ldap_parse(LDAP *ldap, LDAPMessage *result) -{ - chunk_t response = chunk_empty; - err_t ugh = NULL; - - LDAPMessage *entry = ldap_first_entry(ldap, result); - - if (entry != NULL) - { - BerElement *ber = NULL; - char *attr; - - attr = ldap_first_attribute(ldap, entry, &ber); - - if (attr != NULL) - { - struct berval **values = ldap_get_values_len(ldap, entry, attr); - - if (values != NULL) - { - if (values[0] != NULL) - { - response.len = values[0]->bv_len; - response.ptr = malloc(response.len); - memcpy(response.ptr, values[0]->bv_val, response.len); - - if (values[1] != NULL) - { - ugh = "more than one value was fetched - first selected"; - } - } - else - { - ugh = "no values in attribute"; - } - ldap_value_free_len(values); - } - else - { - ugh = ldap_err2string(ldap_result2error(ldap, entry, 0)); - } - ldap_memfree(attr); - } - else - { - ugh = ldap_err2string(ldap_result2error(ldap, entry, 0)); - } - ber_free(ber, 0); - } - else - { - ugh = ldap_err2string(ldap_result2error(ldap, result, 0)); - } - if (ugh) - { - DBG1("ldap request failed: %s", ugh); - } - return response; -} -#endif /* LIBLDAP */ - -/** - * Implements fetcher_t.get for curl methods - */ -static chunk_t ldap_get(private_fetcher_t *this) -{ - chunk_t response = chunk_empty; - -#ifdef LIBLDAP - if (this->ldap) - { - err_t ugh = NULL; - int rc; - int ldap_version = LDAP_VERSION3; - - struct timeval timeout; - - timeout.tv_sec = FETCHER_TIMEOUT; - timeout.tv_usec = 0; - - ldap_set_option(this->ldap, LDAP_OPT_PROTOCOL_VERSION, &ldap_version); - ldap_set_option(this->ldap, LDAP_OPT_NETWORK_TIMEOUT, &timeout); - - DBG1("sending ldap request to '%s'...", this->uri); - - rc = ldap_simple_bind_s(this->ldap, NULL, NULL); - if (rc == LDAP_SUCCESS) - { - LDAPMessage *result; - - timeout.tv_sec = FETCHER_TIMEOUT; - timeout.tv_usec = 0; - - rc = ldap_search_st(this->ldap, this->lurl->lud_dn, - this->lurl->lud_scope, - this->lurl->lud_filter, - this->lurl->lud_attrs, - 0, &timeout, &result); - - if (rc == LDAP_SUCCESS) - { - response = ldap_parse(this->ldap, result); - if (response.ptr) - { - DBG1("received valid ldap response"); - } - ldap_msgfree(result); - } - else - { - ugh = ldap_err2string(rc); - } - } - else - { - ugh = ldap_err2string(rc); - } - ldap_unbind_s(this->ldap); - - if (ugh) - { - DBG1("ldap request failed: %s", ugh); - } - } -#else /* !LIBLDAP */ - DBG1("warning: libldap fetching not compiled in"); -#endif /* !LIBLDAP */ - return response; -} - -/** - * Implements fetcher_t.destroy - */ -static void destroy(private_fetcher_t *this) -{ -#ifdef LIBCURL - if (this->curl) - { - curl_easy_cleanup(this->curl); - } -#endif /* LIBCURL */ - -#ifdef LIBLDAP - if (this->lurl) - { - ldap_free_urldesc(this->lurl); - } -#endif /* LIBLDAP */ - - free(this); -} - -/* - * Described in header. - */ -fetcher_t *fetcher_create(const char *uri) -{ - private_fetcher_t *this = malloc_thing(private_fetcher_t); - - /* initialize */ - this->uri = uri; - -#ifdef LIBCURL - this->curl = NULL; -#endif /* LIBCURL */ - -#ifdef LIBLDAP - this->lurl = NULL; - this->ldap = NULL; -#endif /* LIBLDAP */ - - if (strlen(uri) >= 4 && strncasecmp(uri, "ldap", 4) == 0) - { -#ifdef LIBLDAP - int rc = ldap_url_parse(uri, &this->lurl); - - if (rc == LDAP_SUCCESS) - { - this->ldap = ldap_init(this->lurl->lud_host, - this->lurl->lud_port); - } - else - { - DBG1("ldap: %s", ldap_err2string(rc)); - this->ldap = NULL; - } -#endif /* LIBLDAP */ - this->public.get = (chunk_t (*) (fetcher_t*))ldap_get; - } - else - { -#ifdef LIBCURL - this->curl = curl_easy_init(); - if (this->curl == NULL) - { - DBG1("curl_easy_init_failed()"); - } -#endif /* LIBCURL */ - this->public.get = (chunk_t (*) (fetcher_t*))curl_get; - } - - /* public functions */ - this->public.post = (chunk_t (*) (fetcher_t*,const char*,chunk_t))http_post; - this->public.destroy = (void (*) (fetcher_t*))destroy; - - return &this->public; -} - -/** - * Described in header. - */ -void fetcher_initialize(void) -{ -#ifdef LIBCURL - CURLcode res; - - /* initialize libcurl */ - DBG1("initializing libcurl"); - res = curl_global_init(CURL_GLOBAL_NOTHING); - if (res != CURLE_OK) - { - DBG1("libcurl could not be initialized: %s", curl_easy_strerror(res)); - } -#endif /* LIBCURL */ -} - -/** - * Described in header. - */ -void fetcher_finalize(void) -{ -#ifdef LIBCURL - /* finalize libcurl */ - DBG1("finalizing libcurl"); - curl_global_cleanup(); -#endif /* LIBCURL */ -} - diff --git a/src/libstrongswan/utils/fetcher.h b/src/libstrongswan/utils/fetcher.h deleted file mode 100644 index 47b43a0b7..000000000 --- a/src/libstrongswan/utils/fetcher.h +++ /dev/null @@ -1,95 +0,0 @@ -/** - * @file fetcher.h - * - * @brief Interface of fetcher_t. - * - */ - -/* - * 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 <fetcher://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. - */ - -#ifndef FETCHER_H_ -#define FETCHER_H_ - -typedef struct fetcher_t fetcher_t; - -#include <chunk.h> - -#define FETCHER_TIMEOUT 10 /* seconds */ - -/** - * @brief Fetches information from an URI (http, file, ftp, etc.) - * - * @ingroup utils - */ -struct fetcher_t { - - /** - * @brief Get information via a get request. - * - * @param this calling object - * @param uri uri specifying the information source - * @return chunk_t containing the information - */ - chunk_t (*get) (fetcher_t *this); - - /** - * @brief Get information via a get request. - * - * @param this calling object - * @param uri uri specifying the information source - * @param type content type of http post request - * @param request binary data for http post request - * @return chunk_t containing the information - */ - chunk_t (*post) (fetcher_t *this, const char *type, chunk_t request); - - /** - * @brief Destroys the fetcher_t object. - * - * @param this fetcher_t to destroy - */ - void (*destroy) (fetcher_t *this); - -}; - -/** - * @brief Create a fetcher_t object. - * - * @return created fetcher_t object - * - * @ingroup utils - */ -fetcher_t* fetcher_create(const char *uri); - -/** - * @brief Initializes the fetcher_t class - * - * call this function only once in the main program - * - * @ingroup utils - */ -void fetcher_initialize(void); - -/** - * @brief Finalizes the fetcher_t class - * - * call this function only once befor exiting the main program - * - * @ingroup utils - */ -void fetcher_finalize(void); - -#endif /*FETCHER_H_*/ diff --git a/src/libstrongswan/utils/host.c b/src/libstrongswan/utils/host.c index 68e9c9500..eb87f27bc 100644 --- a/src/libstrongswan/utils/host.c +++ b/src/libstrongswan/utils/host.c @@ -1,10 +1,3 @@ -/** - * @file host.c - * - * @brief Implementation of host_t. - * - */ - /* * Copyright (C) 2006-2007 Tobias Brunner * Copyright (C) 2006 Daniel Roethlisberger @@ -21,18 +14,23 @@ * 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: host.c 4056 2008-06-11 07:44:23Z martin $ */ +#define _GNU_SOURCE +#include <netdb.h> #include <string.h> #include <printf.h> #include "host.h" +#include <debug.h> typedef struct private_host_t private_host_t; /** - * @brief Private Data of a host object. + * Private Data of a host object. */ struct private_host_t { /** @@ -111,56 +109,79 @@ static int print(FILE *stream, const struct printf_info *info, const void *const *args) { private_host_t *this = *((private_host_t**)(args[0])); - char buffer[INET6_ADDRSTRLEN]; - void *address; - u_int16_t port; + char buffer[INET6_ADDRSTRLEN + 16]; if (this == NULL) { - return fprintf(stream, "(null)"); + snprintf(buffer, sizeof(buffer), "(null)"); } - - if (is_anyaddr(this)) + else if (is_anyaddr(this)) { - return fprintf(stream, "%%any"); + snprintf(buffer, sizeof(buffer), "%%any"); } - - switch (this->address.sa_family) + else { - case AF_INET: - address = &this->address4.sin_addr; - port = this->address4.sin_port; - break; - case AF_INET6: - address = &this->address6.sin6_addr; - port = this->address6.sin6_port; - break; - default: - return fprintf(stream, "(family not supported)"); - } + void *address; + u_int16_t port; + int len; + + address = &this->address6.sin6_addr; + port = this->address6.sin6_port; + + switch (this->address.sa_family) + { + case AF_INET: + address = &this->address4.sin_addr; + port = this->address4.sin_port; + /* fall */ + case AF_INET6: - if (inet_ntop(this->address.sa_family, address, - buffer, sizeof(buffer)) == NULL) - { - return fprintf(stream, "(address conversion failed)"); + if (inet_ntop(this->address.sa_family, address, + buffer, sizeof(buffer)) == NULL) + { + snprintf(buffer, sizeof(buffer), + "(address conversion failed)"); + } + else if (info->alt) + { + len = strlen(buffer); + snprintf(buffer + len, sizeof(buffer) - len, + "[%d]", ntohs(port)); + } + break; + default: + snprintf(buffer, sizeof(buffer), "(family not supported)"); + break; + } } - - if (info->alt) + if (info->left) { - return fprintf(stream, "%s[%d]", buffer, ntohs(port)); + return fprintf(stream, "%-*s", info->width, buffer); } - else + return fprintf(stream, "%*s", info->width, buffer); +} + + +/** + * arginfo handler for printf() hosts + */ +int arginfo(const struct printf_info *info, size_t n, int *argtypes) +{ + if (n > 0) { - return fprintf(stream, "%s", buffer); + argtypes[0] = PA_POINTER; } + return 1; } /** - * register printf() handlers + * return printf hook functions for a host */ -static void __attribute__ ((constructor))print_register() +printf_hook_functions_t host_get_printf_hooks() { - register_printf_function(PRINTF_HOST, print, arginfo_ptr); + printf_hook_functions_t hooks = {print, arginfo}; + + return hooks; } /** @@ -433,6 +454,61 @@ host_t *host_create_from_string(char *string, u_int16_t port) /* * Described in header. */ +host_t *host_create_from_dns(char *string, int af, u_int16_t port) +{ + private_host_t *this; + struct hostent host, *ptr; + char buf[512]; + int err, ret; + + if (strchr(string, ':')) + { /* gethostbyname does not like IPv6 addresses, fallback */ + return host_create_from_string(string, port); + } + + if (af) + { + ret = gethostbyname2_r(string, af, &host, buf, sizeof(buf), &ptr, &err); + } + else + { + ret = gethostbyname_r(string, &host, buf, sizeof(buf), &ptr, &err); + } + if (ret != 0) + { + DBG1("resolving '%s' failed: %s", string, hstrerror(err)); + return NULL; + } + if (ptr == NULL) + { + DBG1("resolving '%s' failed", string); + } + this = host_create_empty(); + this->address.sa_family = host.h_addrtype; + switch (this->address.sa_family) + { + case AF_INET: + memcpy(&this->address4.sin_addr.s_addr, + host.h_addr_list[0], host.h_length); + this->address4.sin_port = htons(port); + this->socklen = sizeof(struct sockaddr_in); + break; + case AF_INET6: + memcpy(&this->address6.sin6_addr.s6_addr, + host.h_addr_list[0], host.h_length); + this->address6.sin6_port = htons(port); + this->socklen = sizeof(struct sockaddr_in6); + break; + default: + free(this); + return NULL; + } + return &this->public; +} + +/* + * Described in header. + */ host_t *host_create_from_chunk(int family, chunk_t address, u_int16_t port) { private_host_t *this = host_create_empty(); diff --git a/src/libstrongswan/utils/host.h b/src/libstrongswan/utils/host.h index ee9aa457f..6a1d824c6 100644 --- a/src/libstrongswan/utils/host.h +++ b/src/libstrongswan/utils/host.h @@ -1,14 +1,7 @@ -/** - * @file host.h - * - * @brief Interface of host_t. - * - */ - /* + * Copyright (C) 2005-2008 Martin Willi * Copyright (C) 2006-2007 Tobias Brunner * Copyright (C) 2006 Daniel Roethlisberger - * Copyright (C) 2005-2006 Martin Willi * Copyright (C) 2005 Jan Hutter * Hochschule fuer Technik Rapperswil * @@ -23,6 +16,11 @@ * for more details. */ +/** + * @defgroup host host + * @{ @ingroup utils + */ + #ifndef HOST_H_ #define HOST_H_ @@ -49,42 +47,31 @@ enum host_diff_t { }; /** - * @brief Representates a Host + * Representates a Host * * Host object, identifies a address:port pair and defines some * useful functions on it. - * - * @b Constructors: - * - host_create() - * - host_create_from_chunk() - * - host_create_from_sockaddr() - * - * @todo Add IPv6 support - * - * @ingroup utils */ struct host_t { /** - * @brief Build a clone of this host object. + * Build a clone of this host object. * - * @param this object to clone - * @return cloned host + * @return cloned host */ host_t *(*clone) (host_t *this); /** - * @brief Get a pointer to the internal sockaddr struct. + * Get a pointer to the internal sockaddr struct. * * This is used for sending and receiving via sockets. * - * @param this object to clone - * @return pointer to the internal sockaddr structure + * @return pointer to the internal sockaddr structure */ sockaddr_t *(*get_sockaddr) (host_t *this); /** - * @brief Get the length of the sockaddr struct. + * Get the length of the sockaddr struct. * * Depending on the family, the length of the sockaddr struct * is different. Use this function to get the length of the sockaddr @@ -92,140 +79,129 @@ struct host_t { * * This is used for sending and receiving via sockets. * - * @param this object to clone - * @return length of the sockaddr struct + * @return length of the sockaddr struct */ socklen_t *(*get_sockaddr_len) (host_t *this); /** - * @brief Gets the family of the address + * Gets the family of the address * - * @param this calling object - * @return family + * @return family */ int (*get_family) (host_t *this); /** - * @brief Checks if the ip address of host is set to default route. + * Checks if the ip address of host is set to default route. * - * @param this calling object - * @return - * - TRUE if host has IP 0.0.0.0 for default route - * - FALSE otherwise + * @return TRUE if host is 0.0.0.0 or 0::0, FALSE otherwise */ bool (*is_anyaddr) (host_t *this); /** - * @brief get the address of this host as chunk_t + * Get the address of this host as chunk_t * * Returned chunk points to internal data. * - * @param this object - * @return address string, + * @return address string, */ chunk_t (*get_address) (host_t *this); /** - * @brief get the port of this host + * Get the port of this host * - * @param this object to clone - * @return port number + * @return port number */ u_int16_t (*get_port) (host_t *this); /** - * @brief set the port of this host + * Set the port of this host * - * @param this object to clone - * @param port port numer + * @param port port numer */ void (*set_port) (host_t *this, u_int16_t port); /** - * @brief Compare the ips of two hosts hosts. + * Compare the ips of two hosts hosts. * - * @param this object to compare - * @param other the other to compare - * @return TRUE if addresses are equal. + * @param other the other to compare + * @return TRUE if addresses are equal. */ bool (*ip_equals) (host_t *this, host_t *other); /** - * @brief Compare two hosts, with port. + * Compare two hosts, with port. * - * @param this object to compare - * @param other the other to compare - * @return TRUE if addresses and ports are equal. + * @param other the other to compare + * @return TRUE if addresses and ports are equal. */ bool (*equals) (host_t *this, host_t *other); /** - * @brief Compare two hosts and return the differences. + * Compare two hosts and return the differences. * - * @param this object to compare - * @param other the other to compare - * @return differences in a combination of host_diff_t's + * @param other the other to compare + * @return differences in a combination of host_diff_t's */ host_diff_t (*get_differences) (host_t *this, host_t *other); /** - * @brief Destroy this host object - * - * @param this calling - * @return SUCCESS in any case + * Destroy this host object. */ void (*destroy) (host_t *this); }; /** - * @brief Constructor to create a host_t object from an address string. + * Constructor to create a host_t object from an address string. * * @param string string of an address, such as "152.96.193.130" * @param port port number - * @return - * - host_t object - * - NULL, if string not an address. - * - * @ingroup network + * @return host_t, NULL if string not an address. */ host_t *host_create_from_string(char *string, u_int16_t port); /** - * @brief Constructor to create a host_t object from an address chunk + * Constructor to create a host_t from a DNS name. * - * @param family Address family to use for this object, such as AF_INET or AF_INET6 - * @param address address as 4 byte chunk_t in networ order + * @param string hostname to resolve + * @param family family to prefer, 0 for first match * @param port port number - * @return - * - host_t object - * - NULL, if family not supported or chunk_t length not 4 bytes. - * - * @ingroup network + * @return host_t, NULL lookup failed + */ +host_t *host_create_from_dns(char *string, int family, u_int16_t port); + +/** + * Constructor to create a host_t object from an address chunk + * + * @param family Address family, such as AF_INET or AF_INET6 + * @param address address as chunk_t in networ order + * @param port port number + * @return host_t, NULL if family not supported/chunk invalid */ host_t *host_create_from_chunk(int family, chunk_t address, u_int16_t port); /** - * @brief Constructor to create a host_t object from a sockaddr struct + * Constructor to create a host_t object from a sockaddr struct * * @param sockaddr sockaddr struct which contains family, address and port - * @return - * - host_t object - * - NULL, if family not supported. - * - * @ingroup network + * @return host_t, NULL if family not supported */ host_t *host_create_from_sockaddr(sockaddr_t *sockaddr); /** - * @brief Create a host without an address, a "any" host. + * Create a host without an address, a "any" host. * * @param family family of the any host - * @return - * - host_t object - * - NULL, if family not supported. - * - * @ingroup network + * @return host_t, NULL if family not supported */ host_t *host_create_any(int family); -#endif /*HOST_H_*/ +/** + * Get printf hooks for a host. + * + * Arguments are: + * host_t *host + * Use #-modifier to include port number + */ +printf_hook_functions_t host_get_printf_hooks(); + +#endif /* HOST_H_ @}*/ diff --git a/src/libstrongswan/utils/identification.c b/src/libstrongswan/utils/identification.c index 18f6d6824..39d49bf6c 100644 --- a/src/libstrongswan/utils/identification.c +++ b/src/libstrongswan/utils/identification.c @@ -1,12 +1,5 @@ -/** - * @file identification.c - * - * @brief Implementation of identification_t. - * - */ - /* - * Copyright (C) 2005-2006 Martin Willi + * Copyright (C) 2005-2008 Martin Willi * Copyright (C) 2005 Jan Hutter * Hochschule fuer Technik Rapperswil * @@ -20,7 +13,7 @@ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * - * RCSID $Id: identification.c 3256 2007-10-07 13:42:43Z andreas $ + * $Id: identification.c 4064 2008-06-13 15:10:01Z martin $ */ #define _GNU_SOURCE @@ -34,8 +27,17 @@ #include "identification.h" +#include <asn1/oid.h> #include <asn1/asn1.h> +ENUM_BEGIN(id_match_names, ID_MATCH_NONE, ID_MATCH_MAX_WILDCARDS, + "MATCH_NONE", + "MATCH_ANY", + "MATCH_MAX_WILDCARDS"); +ENUM_NEXT(id_match_names, ID_MATCH_PERFECT, ID_MATCH_PERFECT, ID_MATCH_MAX_WILDCARDS, + "MATCH_PERFECT"); +ENUM_END(id_match_names, ID_MATCH_PERFECT); + ENUM_BEGIN(id_type_names, ID_ANY, ID_KEY_ID, "ID_ANY", "ID_IPV4_ADDR", @@ -49,10 +51,12 @@ ENUM_BEGIN(id_type_names, ID_ANY, ID_KEY_ID, "ID_DER_ASN1_DN", "ID_DER_ASN1_GN", "ID_KEY_ID"); -ENUM_NEXT(id_type_names, ID_DER_ASN1_GN_URI, ID_DER_ASN1_GN_URI, ID_KEY_ID, - "ID_DER_ASN1_GN_URI"); -ENUM_END(id_type_names, ID_DER_ASN1_GN_URI); - +ENUM_NEXT(id_type_names, ID_DER_ASN1_GN_URI, ID_CERT_DER_SHA1, ID_KEY_ID, + "ID_DER_ASN1_GN_URI", + "ID_PUBKEY_INFO_SHA1", + "ID_PUBKEY_SHA1", + "ID_CERT_DER_SHA1"); +ENUM_END(id_type_names, ID_CERT_DER_SHA1); /** * X.501 acronyms for well known object identifiers (OIDs) @@ -237,7 +241,7 @@ static chunk_t sanitize_chunk(chunk_t chunk) /** * Pointer is set to the first RDN in a DN */ -static status_t init_rdn(chunk_t dn, chunk_t *rdn, chunk_t *attribute, bool *next) +static bool init_rdn(chunk_t dn, chunk_t *rdn, chunk_t *attribute, bool *next) { *rdn = chunk_empty; *attribute = chunk_empty; @@ -246,7 +250,7 @@ static status_t init_rdn(chunk_t dn, chunk_t *rdn, chunk_t *attribute, bool *nex if (*dn.ptr != ASN1_SEQUENCE) { /* DN is not a SEQUENCE */ - return FAILED; + return FALSE; } rdn->len = asn1_length(&dn); @@ -254,7 +258,7 @@ static status_t init_rdn(chunk_t dn, chunk_t *rdn, chunk_t *attribute, bool *nex if (rdn->len == ASN1_INVALID_LENGTH) { /* Invalid RDN length */ - return FAILED; + return FALSE; } rdn->ptr = dn.ptr; @@ -262,13 +266,13 @@ static status_t init_rdn(chunk_t dn, chunk_t *rdn, chunk_t *attribute, bool *nex /* are there any RDNs ? */ *next = rdn->len > 0; - return SUCCESS; + return TRUE; } /** * Fetches the next RDN in a DN */ -static status_t get_next_rdn(chunk_t *rdn, chunk_t * attribute, chunk_t *oid, chunk_t *value, asn1_t *type, bool *next) +static bool get_next_rdn(chunk_t *rdn, chunk_t * attribute, chunk_t *oid, chunk_t *value, asn1_t *type, bool *next) { chunk_t body; @@ -283,13 +287,13 @@ static status_t get_next_rdn(chunk_t *rdn, chunk_t * attribute, chunk_t *oid, ch if (*rdn->ptr != ASN1_SET) { /* RDN is not a SET */ - return FAILED; + return FALSE; } attribute->len = asn1_length(rdn); if (attribute->len == ASN1_INVALID_LENGTH) { /* Invalid attribute length */ - return FAILED; + return FALSE; } attribute->ptr = rdn->ptr; /* advance to start of next RDN */ @@ -301,7 +305,7 @@ static status_t get_next_rdn(chunk_t *rdn, chunk_t * attribute, chunk_t *oid, ch if (*attribute->ptr != ASN1_SEQUENCE) { /* attributeTypeAndValue is not a SEQUENCE */ - return FAILED; + return FALSE; } /* extract the attribute body */ @@ -310,7 +314,7 @@ static status_t get_next_rdn(chunk_t *rdn, chunk_t * attribute, chunk_t *oid, ch if (body.len == ASN1_INVALID_LENGTH) { /* Invalid attribute body length */ - return FAILED; + return FALSE; } body.ptr = attribute->ptr; @@ -323,7 +327,7 @@ static status_t get_next_rdn(chunk_t *rdn, chunk_t * attribute, chunk_t *oid, ch if (*body.ptr != ASN1_OID) { /* attributeType is not an OID */ - return FAILED; + return FALSE; } /* extract OID */ oid->len = asn1_length(&body); @@ -331,7 +335,7 @@ static status_t get_next_rdn(chunk_t *rdn, chunk_t * attribute, chunk_t *oid, ch if (oid->len == ASN1_INVALID_LENGTH) { /* Invalid attribute OID length */ - return FAILED; + return FALSE; } oid->ptr = body.ptr; @@ -348,19 +352,19 @@ static status_t get_next_rdn(chunk_t *rdn, chunk_t * attribute, chunk_t *oid, ch if (value->len == ASN1_INVALID_LENGTH) { /* Invalid attribute string length */ - return FAILED; + return FALSE; } value->ptr = body.ptr; /* are there any RDNs left? */ *next = rdn->len > 0 || attribute->len > 0; - return SUCCESS; + return TRUE; } /** * Parses an ASN.1 distinguished name int its OID/value pairs */ -static status_t dntoa(chunk_t dn, chunk_t *str) +static bool dntoa(chunk_t dn, chunk_t *str) { chunk_t rdn, oid, attribute, value, proper; asn1_t type; @@ -368,17 +372,17 @@ static status_t dntoa(chunk_t dn, chunk_t *str) bool next; bool first = TRUE; - status_t status = init_rdn(dn, &rdn, &attribute, &next); - - if (status != SUCCESS) - return status; + if (!init_rdn(dn, &rdn, &attribute, &next)) + { + return FALSE; + } while (next) { - status = get_next_rdn(&rdn, &attribute, &oid, &value, &type, &next); - - if (status != SUCCESS) - return status; + if (!get_next_rdn(&rdn, &attribute, &oid, &value, &type, &next)) + { + return FALSE; + } if (first) { /* first OID/value pair */ @@ -390,7 +394,7 @@ static status_t dntoa(chunk_t dn, chunk_t *str) } /* print OID */ - oid_code = known_oid(oid); + oid_code = asn1_known_oid(oid); if (oid_code == OID_UNKNOWN) { update_chunk(str, snprintf(str->ptr,str->len,"0x#B", &oid)); @@ -404,7 +408,7 @@ static status_t dntoa(chunk_t dn, chunk_t *str) update_chunk(str, snprintf(str->ptr,str->len,"=%.*s", (int)proper.len, proper.ptr)); chunk_free(&proper); } - return SUCCESS; + return TRUE; } /** @@ -420,15 +424,17 @@ static bool same_dn(chunk_t a, chunk_t b) /* same lengths for the DNs */ if (a.len != b.len) + { return FALSE; - + } /* try a binary comparison first */ if (memeq(a.ptr, b.ptr, b.len)) + { return TRUE; - + } /* initialize DN parsing */ - if (init_rdn(a, &rdn_a, &attribute_a, &next_a) != SUCCESS - || init_rdn(b, &rdn_b, &attribute_b, &next_b) != SUCCESS) + if (!init_rdn(a, &rdn_a, &attribute_a, &next_a) || + !init_rdn(b, &rdn_b, &attribute_b, &next_b)) { return FALSE; } @@ -437,23 +443,27 @@ static bool same_dn(chunk_t a, chunk_t b) while (next_a && next_b) { /* parse next RDNs and check for errors */ - if (get_next_rdn(&rdn_a, &attribute_a, &oid_a, &value_a, &type_a, &next_a) != SUCCESS - || get_next_rdn(&rdn_b, &attribute_b, &oid_b, &value_b, &type_b, &next_b) != SUCCESS) + if (!get_next_rdn(&rdn_a, &attribute_a, &oid_a, &value_a, &type_a, &next_a) || + !get_next_rdn(&rdn_b, &attribute_b, &oid_b, &value_b, &type_b, &next_b)) { return FALSE; } /* OIDs must agree */ - if (oid_a.len != oid_b.len || memcmp(oid_a.ptr, oid_b.ptr, oid_b.len) != 0) + if (oid_a.len != oid_b.len || !memeq(oid_a.ptr, oid_b.ptr, oid_b.len)) + { return FALSE; + } /* same lengths for values */ if (value_a.len != value_b.len) + { return FALSE; + } /* printableStrings and email RDNs require uppercase comparison */ - if (type_a == type_b && (type_a == ASN1_PRINTABLESTRING - || (type_a == ASN1_IA5STRING && known_oid(oid_a) == OID_PKCS9_EMAIL))) + if (type_a == type_b && (type_a == ASN1_PRINTABLESTRING || + (type_a == ASN1_IA5STRING && asn1_known_oid(oid_a) == OID_PKCS9_EMAIL))) { if (strncasecmp(value_a.ptr, value_b.ptr, value_b.len) != 0) { @@ -470,8 +480,9 @@ static bool same_dn(chunk_t a, chunk_t b) } /* both DNs must have same number of RDNs */ if (next_a || next_b) + { return FALSE; - + } /* the two DNs are equal! */ return TRUE; } @@ -490,14 +501,11 @@ bool match_dn(chunk_t a, chunk_t b, int *wildcards) bool next_a, next_b; /* initialize wildcard counter */ - if (wildcards) - { - *wildcards = 0; - } + *wildcards = 0; /* initialize DN parsing */ - if (init_rdn(a, &rdn_a, &attribute_a, &next_a) != SUCCESS - || init_rdn(b, &rdn_b, &attribute_b, &next_b) != SUCCESS) + if (!init_rdn(a, &rdn_a, &attribute_a, &next_a) || + !init_rdn(b, &rdn_b, &attribute_b, &next_b)) { return FALSE; } @@ -506,31 +514,32 @@ bool match_dn(chunk_t a, chunk_t b, int *wildcards) while (next_a && next_b) { /* parse next RDNs and check for errors */ - if (get_next_rdn(&rdn_a, &attribute_a, &oid_a, &value_a, &type_a, &next_a) != SUCCESS - || get_next_rdn(&rdn_b, &attribute_b, &oid_b, &value_b, &type_b, &next_b) != SUCCESS) + if (!get_next_rdn(&rdn_a, &attribute_a, &oid_a, &value_a, &type_a, &next_a) || + !get_next_rdn(&rdn_b, &attribute_b, &oid_b, &value_b, &type_b, &next_b)) { return FALSE; } /* OIDs must agree */ if (oid_a.len != oid_b.len || memcmp(oid_a.ptr, oid_b.ptr, oid_b.len) != 0) + { return FALSE; + } /* does rdn_b contain a wildcard? */ if (value_b.len == 1 && *value_b.ptr == '*') { - if (wildcards) - { - (*wildcards)++; - } + (*wildcards)++; continue; } /* same lengths for values */ if (value_a.len != value_b.len) + { return FALSE; + } /* printableStrings and email RDNs require uppercase comparison */ - if (type_a == type_b && (type_a == ASN1_PRINTABLESTRING - || (type_a == ASN1_IA5STRING && known_oid(oid_a) == OID_PKCS9_EMAIL))) + if (type_a == type_b && (type_a == ASN1_PRINTABLESTRING || + (type_a == ASN1_IA5STRING && asn1_known_oid(oid_a) == OID_PKCS9_EMAIL))) { if (strncasecmp(value_a.ptr, value_b.ptr, value_b.len) != 0) { @@ -550,12 +559,8 @@ bool match_dn(chunk_t a, chunk_t b, int *wildcards) { return FALSE; } - /* the two DNs match! */ - if (wildcards) - { - *wildcards = min(*wildcards, MAX_WILDCARDS); - } + *wildcards = min(*wildcards, ID_MATCH_ONE_WILDCARD - ID_MATCH_MAX_WILDCARDS); return TRUE; } @@ -645,7 +650,8 @@ static status_t atodn(char *src, chunk_t *dn) { name.len -= whitespace; rdn_type = (x501rdns[i].type == ASN1_PRINTABLESTRING - && !is_printablestring(name))? ASN1_T61STRING : x501rdns[i].type; + && !asn1_is_printablestring(name)) + ? ASN1_T61STRING : x501rdns[i].type; if (rdn_count < RDN_MAX) { @@ -675,7 +681,7 @@ static status_t atodn(char *src, chunk_t *dn) /* build the distinguished name sequence */ { int i; - u_char *pos = build_asn1_object(dn, ASN1_SEQUENCE, dn_len); + u_char *pos = asn1_build_object(dn, ASN1_SEQUENCE, dn_len); for (i = 0; i < rdn_count; i++) { @@ -776,198 +782,189 @@ static bool equals_strcasecmp(private_identification_t *this, /** * Default implementation of identification_t.matches. */ -static bool matches_binary(private_identification_t *this, - private_identification_t *other, int *wildcards) +static id_match_t matches_binary(private_identification_t *this, + private_identification_t *other) { if (other->type == ID_ANY) { - if (wildcards) - { - *wildcards = MAX_WILDCARDS; - } - return TRUE; + return ID_MATCH_ANY; } - if (wildcards) + if (this->type == other->type && + chunk_equals(this->encoded, other->encoded)) { - *wildcards = 0; + return ID_MATCH_PERFECT; } - return this->type == other->type && - chunk_equals(this->encoded, other->encoded); + return ID_MATCH_NONE; } /** * Special implementation of identification_t.matches for ID_RFC822_ADDR/ID_FQDN. * Checks for a wildcard in other-string, and compares it against this-string. */ -static bool matches_string(private_identification_t *this, - private_identification_t *other, int *wildcards) +static id_match_t matches_string(private_identification_t *this, + private_identification_t *other) { u_int len = other->encoded.len; if (other->type == ID_ANY) { - if (wildcards) - { - *wildcards = MAX_WILDCARDS; - } - return TRUE; + return ID_MATCH_ANY; } - if (this->type != other->type) - return FALSE; - - /* try a binary comparison first */ - if (equals_binary(this, other)) { - if (wildcards) - { - *wildcards = 0; - } - return TRUE; + return ID_MATCH_NONE; + } + /* try a equals check first */ + if (equals_strcasecmp(this, other)) + { + return ID_MATCH_PERFECT; } - if (len == 0 || this->encoded.len < len) - return FALSE; + { + return ID_MATCH_NONE; + } /* check for single wildcard at the head of the string */ if (*other->encoded.ptr == '*') { - if (wildcards) - { - *wildcards = 1; - } - /* single asterisk matches any string */ if (len-- == 1) - return TRUE; - - if (memeq(this->encoded.ptr + this->encoded.len - len, other->encoded.ptr + 1, len)) - return TRUE; + { /* not better than ID_ANY */ + return ID_MATCH_ANY; + } + if (strncasecmp(this->encoded.ptr + this->encoded.len - len, + other->encoded.ptr + 1, len) == 0) + { + return ID_MATCH_ONE_WILDCARD; + } } - - return FALSE; + return ID_MATCH_NONE; } /** * Special implementation of identification_t.matches for ID_ANY. * ANY matches only another ANY, but nothing other */ -static bool matches_any(private_identification_t *this, - private_identification_t *other, int *wildcards) +static id_match_t matches_any(private_identification_t *this, + private_identification_t *other) { - if (wildcards) + if (other->type == ID_ANY) { - *wildcards = 0; + return ID_MATCH_ANY; } - return other->type == ID_ANY; + return ID_MATCH_NONE; } /** - * Special implementation of identification_t.matches for ID_DER_ASN1_DN. - * ANY matches any, even ANY, thats why its there... + * Special implementation of identification_t.matches for ID_DER_ASN1_DN */ -static bool matches_dn(private_identification_t *this, - private_identification_t *other, int *wildcards) +static id_match_t matches_dn(private_identification_t *this, + private_identification_t *other) { + int wc; + if (other->type == ID_ANY) { - if (wildcards) - { - *wildcards = MAX_WILDCARDS; - } - return TRUE; + return ID_MATCH_ANY; } if (this->type == other->type) { - return match_dn(this->encoded, other->encoded, wildcards); + if (match_dn(this->encoded, other->encoded, &wc)) + { + return ID_MATCH_PERFECT - wc; + } } - return FALSE; + return ID_MATCH_NONE; } /** * output handler in printf() */ static int print(FILE *stream, const struct printf_info *info, - const void *const *args) + const void *const *args) { private_identification_t *this = *((private_identification_t**)(args[0])); char buf[BUF_LEN]; chunk_t proper, buf_chunk = chunk_from_buf(buf); - int written; if (this == NULL) { - return fprintf(stream, "(null)"); + return fprintf(stream, "%*s", info->width, "(null)"); } switch (this->type) { case ID_ANY: - return fprintf(stream, "%%any"); + snprintf(buf, sizeof(buf), "%%any"); + break; case ID_IPV4_ADDR: if (this->encoded.len < sizeof(struct in_addr) || inet_ntop(AF_INET, this->encoded.ptr, buf, sizeof(buf)) == NULL) { - return fprintf(stream, "(invalid ID_IPV4_ADDR)"); - } - else - { - return fprintf(stream, "%s", buf); + snprintf(buf, sizeof(buf), "(invalid ID_IPV4_ADDR)"); } + break; case ID_IPV6_ADDR: if (this->encoded.len < sizeof(struct in6_addr) || inet_ntop(AF_INET6, this->encoded.ptr, buf, INET6_ADDRSTRLEN) == NULL) { - return fprintf(stream, "(invalid ID_IPV6_ADDR)"); - } - else - { - return fprintf(stream, "%s", buf); + snprintf(buf, sizeof(buf), "(invalid ID_IPV6_ADDR)"); } + break; case ID_FQDN: - { - proper = sanitize_chunk(this->encoded); - written = fprintf(stream, "%.*s", proper.len, proper.ptr); - chunk_free(&proper); - return written; - } case ID_RFC822_ADDR: - { + case ID_DER_ASN1_GN_URI: proper = sanitize_chunk(this->encoded); - written = fprintf(stream, "%.*s", proper.len, proper.ptr); + snprintf(buf, sizeof(buf), "%.*s", proper.len, proper.ptr); chunk_free(&proper); - return written; - } + break; case ID_DER_ASN1_DN: - { - snprintf(buf, sizeof(buf), "%.*s", this->encoded.len, this->encoded.ptr); - /* TODO: whats returned on failure?*/ - dntoa(this->encoded, &buf_chunk); - return fprintf(stream, "%s", buf); - } + if (!dntoa(this->encoded, &buf_chunk)) + { + snprintf(buf, sizeof(buf), "(invalid ID_DER_ASN1_DN)"); + } + break; case ID_DER_ASN1_GN: - return fprintf(stream, "(ASN.1 general Name"); + snprintf(buf, sizeof(buf), "(ASN.1 general Name"); + break; case ID_KEY_ID: - return fprintf(stream, "(KEY_ID)"); - case ID_DER_ASN1_GN_URI: - { - proper = sanitize_chunk(this->encoded); - written = fprintf(stream, "%.*s", proper.len, proper.ptr); - chunk_free(&proper); - return written; - } + case ID_PUBKEY_INFO_SHA1: + case ID_PUBKEY_SHA1: + case ID_CERT_DER_SHA1: + snprintf(buf, sizeof(buf), "%#B", &this->encoded); + break; default: - return fprintf(stream, "(unknown ID type: %d)", this->type); + snprintf(buf, sizeof(buf), "(unknown ID type: %d)", this->type); + break; + } + if (info->left) + { + return fprintf(stream, "%-*s", info->width, buf); + } + return fprintf(stream, "%*s", info->width, buf); +} + +/** + * arginfo handler + */ +static int arginfo(const struct printf_info *info, size_t n, int *argtypes) +{ + if (n > 0) + { + argtypes[0] = PA_POINTER; } + return 1; } /** - * register printf() handlers + * Get printf hook functions */ -static void __attribute__ ((constructor))print_register() +printf_hook_functions_t identification_get_printf_hooks() { - register_printf_function(PRINTF_IDENTIFICATION, print, arginfo_ptr); + printf_hook_functions_t hook = {print, arginfo}; + + return hook; } /** @@ -1011,7 +1008,7 @@ static private_identification_t *identification_create(void) this->public.destroy = (void (*) (identification_t*))destroy; /* we use these as defaults, the may be overloaded for special ID types */ this->public.equals = (bool (*) (identification_t*,identification_t*))equals_binary; - this->public.matches = (bool (*) (identification_t*,identification_t*,int*))matches_binary; + this->public.matches = (id_match_t (*) (identification_t*,identification_t*))matches_binary; this->encoded = chunk_empty; @@ -1041,7 +1038,7 @@ identification_t *identification_create_from_string(char *string) } this->type = ID_DER_ASN1_DN; this->public.equals = (bool (*) (identification_t*,identification_t*))equals_dn; - this->public.matches = (bool (*) (identification_t*,identification_t*,int*))matches_dn; + this->public.matches = (id_match_t (*) (identification_t*,identification_t*))matches_dn; return &this->public; } else if (strchr(string, '@') == NULL) @@ -1054,8 +1051,8 @@ identification_t *identification_create_from_string(char *string) { /* any ID will be accepted */ this->type = ID_ANY; - this->public.matches = (bool (*) - (identification_t*,identification_t*,int*))matches_any; + this->public.matches = (id_match_t (*) + (identification_t*,identification_t*))matches_any; return &this->public; } else @@ -1072,8 +1069,8 @@ identification_t *identification_create_from_string(char *string) this->type = ID_FQDN; this->encoded.ptr = strdup(string); this->encoded.len = strlen(string); - this->public.matches = (bool (*) - (identification_t*,identification_t*,int*))matches_string; + this->public.matches = (id_match_t (*) + (identification_t*,identification_t*))matches_string; this->public.equals = (bool (*) (identification_t*,identification_t*))equals_strcasecmp; return &(this->public); @@ -1105,17 +1102,19 @@ identification_t *identification_create_from_string(char *string) { if (*(string + 1) == '#') { - /* TODO: Pluto handles '#' as hex encoded ID_KEY_ID. */ - free(this); - return NULL; + string += 2; + this->type = ID_KEY_ID; + this->encoded = chunk_from_hex( + chunk_create(string, strlen(string)), NULL); + return &(this->public); } else { this->type = ID_FQDN; this->encoded.ptr = strdup(string + 1); this->encoded.len = strlen(string + 1); - this->public.matches = (bool (*) - (identification_t*,identification_t*,int*))matches_string; + this->public.matches = (id_match_t (*) + (identification_t*,identification_t*))matches_string; this->public.equals = (bool (*) (identification_t*,identification_t*))equals_strcasecmp; return &(this->public); @@ -1126,8 +1125,8 @@ identification_t *identification_create_from_string(char *string) this->type = ID_RFC822_ADDR; this->encoded.ptr = strdup(string); this->encoded.len = strlen(string); - this->public.matches = (bool (*) - (identification_t*,identification_t*,int*))matches_string; + this->public.matches = (id_match_t (*) + (identification_t*,identification_t*))matches_string; this->public.equals = (bool (*) (identification_t*,identification_t*))equals_strcasecmp; return &(this->public); @@ -1146,27 +1145,30 @@ identification_t *identification_create_from_encoding(id_type_t type, chunk_t en switch (type) { case ID_ANY: - this->public.matches = (bool (*) - (identification_t*,identification_t*,int*))matches_any; + this->public.matches = (id_match_t (*) + (identification_t*,identification_t*))matches_any; break; case ID_FQDN: case ID_RFC822_ADDR: - this->public.matches = (bool (*) - (identification_t*,identification_t*,int*))matches_string; + this->public.matches = (id_match_t (*) + (identification_t*,identification_t*))matches_string; this->public.equals = (bool (*) (identification_t*,identification_t*))equals_strcasecmp; break; case ID_DER_ASN1_DN: this->public.equals = (bool (*) (identification_t*,identification_t*))equals_dn; - this->public.matches = (bool (*) - (identification_t*,identification_t*,int*))matches_dn; + this->public.matches = (id_match_t (*) + (identification_t*,identification_t*))matches_dn; break; case ID_IPV4_ADDR: case ID_IPV6_ADDR: case ID_DER_ASN1_GN: case ID_KEY_ID: case ID_DER_ASN1_GN_URI: + case ID_PUBKEY_INFO_SHA1: + case ID_PUBKEY_SHA1: + case ID_CERT_DER_SHA1: default: break; } diff --git a/src/libstrongswan/utils/identification.h b/src/libstrongswan/utils/identification.h index 59c568eaf..591909411 100644 --- a/src/libstrongswan/utils/identification.h +++ b/src/libstrongswan/utils/identification.h @@ -1,10 +1,3 @@ -/** - * @file identification.h - * - * @brief Interface of identification_t. - * - */ - /* * Copyright (C) 2005-2006 Martin Willi * Copyright (C) 2005 Jan Hutter @@ -19,6 +12,13 @@ * 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: identification.h 3838 2008-04-18 11:24:45Z tobias $ + */ + +/** + * @defgroup identification identification + * @{ @ingroup utils */ @@ -27,15 +27,33 @@ typedef enum id_type_t id_type_t; typedef struct identification_t identification_t; +typedef enum id_match_t id_match_t; #include <library.h> -#define MAX_WILDCARDS 14 +/** + * Matches returned from identification_t.match + */ +enum id_match_t { + /* no match */ + ID_MATCH_NONE = 0, + /* match to %any ID */ + ID_MATCH_ANY = 1, + /* match with maximum allowed wildcards */ + ID_MATCH_MAX_WILDCARDS = 2, + /* match with only one wildcard */ + ID_MATCH_ONE_WILDCARD = 19, + /* perfect match, won't get better */ + ID_MATCH_PERFECT = 20, +}; /** - * @brief ID Types in a ID payload. - * - * @ingroup utils + * enum names for id_match_t. + */ +extern enum_name_t *id_match_names; + +/** + * ID Types in a ID payload. */ enum id_type_t { @@ -109,7 +127,21 @@ enum id_type_t { * private type which represents a GeneralName of type URI */ ID_DER_ASN1_GN_URI = 201, - + + /** + * SHA1 hash over PKCS#1 subjectPublicKeyInfo + */ + ID_PUBKEY_INFO_SHA1, + + /** + * SHA1 hash over PKCS#1 subjectPublicKey + */ + ID_PUBKEY_SHA1, + + /** + * SHA1 hash of the binary DER encoding of a certificate + */ + ID_CERT_DER_SHA1, }; /** @@ -118,110 +150,84 @@ enum id_type_t { extern enum_name_t *id_type_names; /** - * @brief Generic identification, such as used in ID payload. - * - * The following types are possible: - * - ID_IPV4_ADDR - * - ID_FQDN - * - ID_RFC822_ADDR - * - ID_IPV6_ADDR - * - ID_DER_ASN1_DN - * - ID_DER_ASN1_GN - * - ID_KEY_ID - * - ID_DER_ASN1_GN_URI - * - * @b Constructors: - * - identification_create_from_string() - * - identification_create_from_encoding() + * Generic identification, such as used in ID payload. * * @todo Support for ID_DER_ASN1_GN is minimal right now. Comparison * between them and ID_IPV4_ADDR/RFC822_ADDR would be nice. - * - * @ingroup utils */ struct identification_t { /** - * @brief Get the encoding of this id, to send over + * Get the encoding of this id, to send over * the network. * - * @warning Result points to internal data, do NOT free! + * Result points to internal data, do not free. * - * @param this the identification_t object * @return a chunk containing the encoded bytes */ chunk_t (*get_encoding) (identification_t *this); /** - * @brief Get the type of this identification. + * Get the type of this identification. * - * @param this the identification_t object * @return id_type_t */ id_type_t (*get_type) (identification_t *this); /** - * @brief Check if two identification_t objects are equal. + * Check if two identification_t objects are equal. * - * @param this the identification_t object * @param other other identification_t object * @return TRUE if the IDs are equal */ bool (*equals) (identification_t *this, identification_t *other); /** - * @brief Check if an ID matches a wildcard ID. + * Check if an ID matches a wildcard ID. * * An identification_t may contain wildcards, such as * *@strongswan.org. This call checks if a given ID * (e.g. tester@strongswan.org) belongs to a such wildcard - * ID. Returns TRUE if + * ID. Returns > 0 if * - IDs are identical * - other is of type ID_ANY * - other contains a wildcard and matches this + * + * The larger the return value is, the better is the match. Zero means + * no match at all, 1 means a bad match, and 2 a slightly better match. * - * @param this the ID without wildcard - * @param other the ID containing a wildcard + * @param other the ID containing one or more wildcards * @param wildcards returns the number of wildcards, may be NULL - * @return TRUE if match is found + * @return match value as described above */ - bool (*matches) (identification_t *this, identification_t *other, int *wildcards); + id_match_t (*matches) (identification_t *this, identification_t *other); /** - * @brief Check if an ID is a wildcard ID. + * Check if an ID is a wildcard ID. * * If the ID represents multiple IDs (with wildcards, or * as the type ID_ANY), TRUE is returned. If it is unique, * FALSE is returned. * - * @param this identification_t object * @return TRUE if ID contains wildcards */ bool (*contains_wildcards) (identification_t *this); /** - * @brief Clone a identification_t instance. + * Clone a identification_t instance. * - * @param this the identification_t object to clone * @return clone of this */ identification_t *(*clone) (identification_t *this); /** - * @brief Destroys a identification_t object. - * - * @param this identification_t object + * Destroys a identification_t object. */ void (*destroy) (identification_t *this); }; /** - * @brief Creates an identification_t object from a string. - * - * @param string input string, which will be converted - * @return - * - created identification_t object, or - * - NULL if unsupported string supplied. + * Creates an identification_t object from a string. * * The input string may be e.g. one of the following: * - ID_IPV4_ADDR: 192.168.0.1 @@ -239,23 +245,29 @@ struct identification_t { * ND, UID, DC, CN, S, SN, serialNumber, C, L, ST, O, OU, T, D, * N, G, I, ID, EN, EmployeeNumber, E, Email, emailAddress, UN, * unstructuredName, TCGID. - * - * @ingroup utils + * + * @param string input string, which will be converted + * @return created identification_t, NULL if not supported. */ identification_t * identification_create_from_string(char *string); /** - * @brief Creates an identification_t object from an encoded chunk. - * - * @param type type of this id, such as ID_IPV4_ADDR - * @param encoded encoded bytes, such as from identification_t.get_encoding - * @return identification_t object + * Creates an identification_t object from an encoded chunk. * * In contrast to identification_create_from_string(), this constructor never * returns NULL, even when the conversion to a string representation fails. - * - * @ingroup utils + * + * @param type type of this id, such as ID_IPV4_ADDR + * @param encoded encoded bytes, such as from identification_t.get_encoding + * @return identification_t */ identification_t * identification_create_from_encoding(id_type_t type, chunk_t encoded); -#endif /* IDENTIFICATION_H_ */ +/** + * Get the printf hook functions. + * + * @return printf hook functions + */ +printf_hook_functions_t identification_get_printf_hooks(); + +#endif /* IDENTIFICATION_H_ @} */ diff --git a/src/libstrongswan/utils/iterator.h b/src/libstrongswan/utils/iterator.h index b4ff85bfb..a1bdad1d6 100644 --- a/src/libstrongswan/utils/iterator.h +++ b/src/libstrongswan/utils/iterator.h @@ -1,10 +1,3 @@ -/** - * @file iterator.h - * - * @brief Interface iterator_t. - * - */ - /* * Copyright (C) 2005-2006 Martin Willi * Copyright (C) 2005 Jan Hutter @@ -19,6 +12,13 @@ * 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: iterator.h 3589 2008-03-13 14:14:44Z martin $ + */ + +/** + * @defgroup iterator iterator + * @{ @ingroup utils */ #ifndef ITERATOR_H_ @@ -29,13 +29,11 @@ typedef enum hook_result_t hook_result_t; /** - * @brief Return value of an iterator hook. + * Return value of an iterator hook. * * Returning HOOK_AGAIN is useful to "inject" additional elements in an * iteration, HOOK_NEXT is the normal iterator behavior, and HOOK_SKIP may * be used to filter elements out. - * - * @ingroup utils */ enum hook_result_t { @@ -56,14 +54,12 @@ enum hook_result_t { }; /** - * @brief Iterator hook function prototype. + * Iterator hook function prototype. * * @param param user supplied parameter * @param in the value the hook receives from the iterator * @param out the value supplied as a result to the iterator * @return a hook_result_t - * - * @ingroup utils */ typedef hook_result_t (iterator_hook_t)(void *param, void *in, void **out); @@ -71,44 +67,34 @@ typedef hook_result_t (iterator_hook_t)(void *param, void *in, void **out); typedef struct iterator_t iterator_t; /** - * @brief Iterator interface, allows iteration over collections. + * Iterator interface, allows iteration over collections. * * iterator_t defines an interface for iterating over collections. * It allows searching, deleting, updating and inserting. * - * @b Constructors: - * - via linked_list_t.create_iterator, or - * - any other class which supports the iterator_t interface - * - * @see linked_list_t - * - * @ingroup utils + * @deprecated Use enumerator instead. */ struct iterator_t { /** - * @brief Return number of list items. + * Return number of list items. * - * @param this calling object * @return number of list items */ int (*get_count) (iterator_t *this); /** - * @brief Iterate over all items. + * Iterate over all items. * * The easy way to iterate over items. * - * @param this calling object - * @param[out] value item - * @return - * - TRUE, if there was an element available, - * - FALSE otherwise + * @param value item + * @return TRUE, if there was an element available, FALSE otherwise */ bool (*iterate) (iterator_t *this, void** value); /** - * @brief Hook a function into the iterator. + * Hook a function into the iterator. * * Sometimes it is useful to hook in an iterator. The hook function is * called before any successful return of iterate(). It takes the @@ -119,80 +105,67 @@ struct iterator_t { * If an iterator is hooked, only the iterate() method is valid, * all other methods behave undefined. * - * @param this calling object - * @param hook iterator hook which manipulates the iterated value - * @param param user supplied parameter to pass back to the hook + * @param hook iterator hook which manipulates the iterated value + * @param param user supplied parameter to pass back to the hook */ void (*set_iterator_hook) (iterator_t *this, iterator_hook_t *hook, void *param); /** - * @brief Inserts a new item before the given iterator position. + * Inserts a new item before the given iterator position. * * The iterator position is not changed after inserting * - * @param this calling iterator - * @param[in] item value to insert in list + * @param item value to insert in list */ void (*insert_before) (iterator_t *this, void *item); /** - * @brief Inserts a new item after the given iterator position. + * Inserts a new item after the given iterator position. * * The iterator position is not changed after inserting. * - * @param this calling iterator - * @param[in] item value to insert in list + * @param this calling iterator + * @param item value to insert in list */ void (*insert_after) (iterator_t *this, void *item); /** - * @brief Replace the current item at current iterator position. + * Replace the current item at current iterator position. * * The iterator position is not changed after replacing. * - * @param this calling iterator - * @param[out] old_item old value will be written here(can be NULL) - * @param[in] new_item new value - * - * @return - * - SUCCESS - * - FAILED if iterator is on an invalid position + * @param this calling iterator + * @param old old value will be written here(can be NULL) + * @param new new value + * @return SUCCESS, FAILED if iterator is on an invalid position */ - status_t (*replace) (iterator_t *this, void **old_item, void *new_item); + status_t (*replace) (iterator_t *this, void **old, void *new); /** - * @brief Removes an element from list at the given iterator position. + * Removes an element from list at the given iterator position. * * The iterator is set the the following position: * - to the item before, if available * - it gets reseted, otherwise * - * @param this calling object - * @return - * - SUCCESS - * - FAILED if iterator is on an invalid position + * @return SUCCESS, FAILED if iterator is on an invalid position */ status_t (*remove) (iterator_t *this); /** - * @brief Resets the iterator position. + * Resets the iterator position. * * After reset, the iterator_t objects doesn't point to an element. * A call to iterator_t.has_next is necessary to do any other operations * with the resetted iterator. - * - * @param this calling object */ void (*reset) (iterator_t *this); /** - * @brief Destroys an iterator. - * - * @param this iterator to destroy - * + * Destroys an iterator. */ void (*destroy) (iterator_t *this); }; -#endif /*ITERATOR_H_*/ +#endif /*ITERATOR_H_ @} */ diff --git a/src/libstrongswan/utils/leak_detective.c b/src/libstrongswan/utils/leak_detective.c index dab18fd5c..cff5a1c81 100644 --- a/src/libstrongswan/utils/leak_detective.c +++ b/src/libstrongswan/utils/leak_detective.c @@ -1,11 +1,5 @@ -/** - * @file leak_detective.c - * - * @brief Allocation hooks to find memory leaks. - */ - /* - * Copyright (C) 2006 Martin Willi + * Copyright (C) 2006-2008 Martin Willi * Hochschule fuer Technik Rapperswil * * This program is free software; you can redistribute it and/or modify it @@ -17,8 +11,15 @@ * 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: leak_detective.c 4044 2008-06-06 15:05:54Z martin $ */ +#ifdef HAVE_DLADDR +# define _GNU_SOURCE +# include <dlfcn.h> +#endif /* HAVE_DLADDR */ + #include <stddef.h> #include <string.h> #include <stdio.h> @@ -33,6 +34,7 @@ #include <pthread.h> #include <netdb.h> #include <printf.h> +#include <locale.h> #ifdef HAVE_BACKTRACE # include <execinfo.h> #endif /* HAVE_BACKTRACE */ @@ -42,7 +44,18 @@ #include <library.h> #include <debug.h> -#ifdef LEAK_DETECTIVE +typedef struct private_leak_detective_t private_leak_detective_t; + +/** + * private data of leak_detective + */ +struct private_leak_detective_t { + + /** + * public functions + */ + leak_detective_t public; +}; /** * Magic value which helps to detect memory corruption. Yummy! @@ -50,6 +63,11 @@ #define MEMORY_HEADER_MAGIC 0x7ac0be11 /** + * Magic written to tail of allocation + */ +#define MEMORY_TAIL_MAGIC 0xcafebabe + +/** * Pattern which is filled in memory before freeing it */ #define MEMORY_FREE_PATTERN 0xFF @@ -66,25 +84,26 @@ static void *malloc_hook(size_t, const void *); static void *realloc_hook(void *, size_t, const void *); static void free_hook(void*, const void *); +void *(*old_malloc_hook)(size_t, const void *); +void *(*old_realloc_hook)(void *, size_t, const void *); +void (*old_free_hook)(void*, const void *); + static u_int count_malloc = 0; static u_int count_free = 0; static u_int count_realloc = 0; typedef struct memory_header_t memory_header_t; +typedef struct memory_tail_t memory_tail_t; /** * Header which is prepended to each allocated memory block */ struct memory_header_t { - /** - * Magci byte which must(!) hold MEMORY_HEADER_MAGIC - */ - u_int32_t magic; /** * Number of bytes following after the header */ - size_t bytes; + u_int bytes; /** * Stack frames at the time of allocation @@ -105,7 +124,25 @@ struct memory_header_t { * Pointer to next entry in linked list */ memory_header_t *next; -}; + + /** + * magic bytes to detect bad free or heap underflow, MEMORY_HEADER_MAGIC + */ + u_int32_t magic; + +}__attribute__((__packed__)); + +/** + * tail appended to each allocated memory block + */ +struct memory_tail_t { + + /** + * Magic bytes to detect heap overflow, MEMORY_TAIL_MAGIC + */ + u_int32_t magic; + +}__attribute__((__packed__)); /** * first mem header is just a dummy to chain @@ -120,22 +157,11 @@ static memory_header_t first_header = { }; /** - * standard hooks, used to temparily remove hooking - */ -static void *old_malloc_hook, *old_realloc_hook, *old_free_hook; - -/** * are the hooks currently installed? */ static bool installed = FALSE; /** - * Mutex to exclusivly uninstall hooks, access heap list - */ -static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; - - -/** * log stack frames queried by backtrace() * TODO: Dump symbols of static functions. This could be done with * the addr2line utility or the GNU BFD Library... @@ -143,80 +169,140 @@ static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; static void log_stack_frames(void **stack_frames, int stack_frame_count) { #ifdef HAVE_BACKTRACE - char **strings; size_t i; + char **strings; + + strings = backtrace_symbols(stack_frames, stack_frame_count); - strings = backtrace_symbols (stack_frames, stack_frame_count); - - DBG1(" dumping %d stack frame addresses", stack_frame_count); - + fprintf(stderr, " dumping %d stack frame addresses:\n", stack_frame_count); for (i = 0; i < stack_frame_count; i++) { - DBG1(" %s", strings[i]); +#ifdef HAVE_DLADDR + Dl_info info; + + if (dladdr(stack_frames[i], &info)) + { + char cmd[1024]; + FILE *output; + char c; + void *ptr = stack_frames[i]; + + if (strstr(info.dli_fname, ".so")) + { + ptr = (void*)(stack_frames[i] - info.dli_fbase); + } + snprintf(cmd, sizeof(cmd), "addr2line -e %s %p", info.dli_fname, ptr); + if (info.dli_sname) + { + fprintf(stderr, " \e[33m%s\e[0m @ %p (\e[31m%s\e[0m+0x%x) [%p]\n", + info.dli_fname, info.dli_fbase, info.dli_sname, + stack_frames[i] - info.dli_saddr, stack_frames[i]); + } + else + { + fprintf(stderr, " \e[33m%s\e[0m @ %p [%p]\n", info.dli_fname, + info.dli_fbase, stack_frames[i]); + } + fprintf(stderr, " -> \e[32m"); + output = popen(cmd, "r"); + if (output) + { + while (TRUE) + { + c = getc(output); + if (c == '\n' || c == EOF) + { + break; + } + fputc(c, stderr); + } + } + else + { +#endif /* HAVE_DLADDR */ + fprintf(stderr, " %s\n", strings[i]); +#ifdef HAVE_DLADDR + } + fprintf(stderr, "\n\e[0m"); + } +#endif /* HAVE_DLADDR */ } free (strings); #endif /* HAVE_BACKTRACE */ } /** - * Whitelist, which contains address ranges in stack frames ignored when leaking. - * - * This is necessary, as some function use allocation hacks (static buffers) - * and so on, which we want to suppress on leak reports. + * Leak report white list * - * The range_size is calculated using the readelf utility, e.g.: - * readelf -s /lib/glibc.so.6 - * The values are for glibc-2.4 and may or may not be correct on other systems. + * List of functions using static allocation buffers or should be suppressed + * otherwise on leak report. */ -typedef struct whitelist_t whitelist_t; - -struct whitelist_t { - void* range_start; - size_t range_size; -}; - -#ifdef LIBCURL -/* dummy declaration for whitelisting */ -void *Curl_getaddrinfo(void); -#endif /* LIBCURL */ - -whitelist_t whitelist[] = { - {pthread_create, 2542}, - {pthread_setspecific, 217}, - {mktime, 60}, - {tzset, 123}, - {inet_ntoa, 249}, - {strerror, 180}, - {getprotobynumber, 291}, - {getservbyport, 311}, - {register_printf_function, 159}, - {syslog, 44}, - {vsyslog, 41}, - {dlopen, 109}, -# ifdef LIBCURL - /* from /usr/lib/libcurl.so.3 */ - {Curl_getaddrinfo, 480}, -# endif /* LIBCURL */ +char *whitelist[] = { + /* pthread stuff */ + "pthread_create", + "pthread_setspecific", + /* glibc functions */ + "mktime", + "__gmtime_r", + "tzset", + "inet_ntoa", + "strerror", + "getprotobynumber", + "getservbyport", + "getservbyname", + "gethostbyname_r", + "gethostbyname2_r", + "getpwnam_r", + "getgrnam_r", + "register_printf_function", + "syslog", + "vsyslog", + "getaddrinfo", + "setlocale", + /* ignore dlopen, as we do not dlclose to get proper leak reports */ + "dlopen", + "dlerror", + /* mysql functions */ + "mysql_init_character_set", + "init_client_errs", + "my_thread_init", + /* fastcgi library */ + "FCGX_Init", + /* libxml */ + "xmlInitCharEncodingHandlers", + "xmlInitParser", + "xmlInitParserCtxt", + /* ClearSilver */ + "nerr_init", + /* OpenSSL */ + "RSA_new_method", + "DH_new_method", }; /** - * Check if this stack frame is whitelisted. + * check if a stack frame contains functions listed above */ static bool is_whitelisted(void **stack_frames, int stack_frame_count) { int i, j; +#ifdef HAVE_DLADDR for (i=0; i< stack_frame_count; i++) { - for (j=0; j<sizeof(whitelist)/sizeof(whitelist_t); j++) - { - if (stack_frames[i] >= whitelist[j].range_start && - stack_frames[i] <= (whitelist[j].range_start + whitelist[j].range_size)) + Dl_info info; + + if (dladdr(stack_frames[i], &info) && info.dli_sname) + { + for (j = 0; j < sizeof(whitelist)/sizeof(char*); j++) { - return TRUE; + if (streq(info.dli_sname, whitelist[j])) + { + return TRUE; + } } } } +#endif /* HAVE_DLADDR */ return FALSE; } @@ -226,14 +312,19 @@ static bool is_whitelisted(void **stack_frames, int stack_frame_count) void report_leaks() { memory_header_t *hdr; - int leaks = 0; + int leaks = 0, whitelisted = 0; for (hdr = first_header.next; hdr != NULL; hdr = hdr->next) { - if (!is_whitelisted(hdr->stack_frames, hdr->stack_frame_count)) + if (is_whitelisted(hdr->stack_frames, hdr->stack_frame_count)) + { + whitelisted++; + } + else { - DBG1("Leak (%d bytes at %p):", hdr->bytes, hdr + 1); - log_stack_frames(hdr->stack_frames, hdr->stack_frame_count); + fprintf(stderr, "Leak (%d bytes at %p):\n", hdr->bytes, hdr + 1); + /* skip the first frame, contains leak detective logic */ + log_stack_frames(hdr->stack_frames + 1, hdr->stack_frame_count - 1); leaks++; } } @@ -241,15 +332,16 @@ void report_leaks() switch (leaks) { case 0: - DBG1("No leaks detected"); + fprintf(stderr, "No leaks detected"); break; case 1: - DBG1("One leak detected"); + fprintf(stderr, "One leak detected"); break; default: - DBG1("%d leaks detected", leaks); + fprintf(stderr, "%d leaks detected", leaks); break; } + fprintf(stderr, ", %d suppressed by whitelist\n", whitelisted); } /** @@ -289,17 +381,28 @@ static void uninstall_hooks() void *malloc_hook(size_t bytes, const void *caller) { memory_header_t *hdr; + memory_tail_t *tail; + pthread_t thread_id = pthread_self(); + int oldpolicy; + struct sched_param oldparams, params; + + pthread_getschedparam(thread_id, &oldpolicy, &oldparams); + + params.__sched_priority = sched_get_priority_max(SCHED_FIFO); + pthread_setschedparam(thread_id, SCHED_FIFO, ¶ms); - pthread_mutex_lock(&mutex); count_malloc++; uninstall_hooks(); - hdr = malloc(bytes + sizeof(memory_header_t)); + hdr = malloc(sizeof(memory_header_t) + bytes + sizeof(memory_tail_t)); + tail = ((void*)hdr) + bytes + sizeof(memory_header_t); /* set to something which causes crashes */ - memset(hdr, MEMORY_ALLOC_PATTERN, bytes + sizeof(memory_header_t)); + memset(hdr, MEMORY_ALLOC_PATTERN, + sizeof(memory_header_t) + bytes + sizeof(memory_tail_t)); hdr->magic = MEMORY_HEADER_MAGIC; hdr->bytes = bytes; hdr->stack_frame_count = backtrace(hdr->stack_frames, STACK_FRAMES_COUNT); + tail->magic = MEMORY_TAIL_MAGIC; install_hooks(); /* insert at the beginning of the list */ @@ -310,7 +413,9 @@ void *malloc_hook(size_t bytes, const void *caller) } hdr->previous = &first_header; first_header.next = hdr; - pthread_mutex_unlock(&mutex); + + pthread_setschedparam(thread_id, oldpolicy, &oldparams); + return hdr + 1; } @@ -321,41 +426,53 @@ void free_hook(void *ptr, const void *caller) { void *stack_frames[STACK_FRAMES_COUNT]; int stack_frame_count; - memory_header_t *hdr = ptr - sizeof(memory_header_t); - + memory_header_t *hdr; + memory_tail_t *tail; + pthread_t thread_id = pthread_self(); + int oldpolicy; + struct sched_param oldparams, params; + /* allow freeing of NULL */ if (ptr == NULL) { return; } + hdr = ptr - sizeof(memory_header_t); + tail = ptr + hdr->bytes; + + pthread_getschedparam(thread_id, &oldpolicy, &oldparams); + + params.__sched_priority = sched_get_priority_max(SCHED_FIFO); + pthread_setschedparam(thread_id, SCHED_FIFO, ¶ms); - pthread_mutex_lock(&mutex); count_free++; uninstall_hooks(); - if (hdr->magic != MEMORY_HEADER_MAGIC) + if (hdr->magic != MEMORY_HEADER_MAGIC || + tail->magic != MEMORY_TAIL_MAGIC) { - DBG1("freeing of invalid memory (%p, MAGIC 0x%x != 0x%x):", - ptr, hdr->magic, MEMORY_HEADER_MAGIC); + fprintf(stderr, "freeing invalid memory (%p): " + "header magic 0x%x, tail magic 0x%x:\n", + ptr, hdr->magic, tail->magic); stack_frame_count = backtrace(stack_frames, STACK_FRAMES_COUNT); log_stack_frames(stack_frames, stack_frame_count); - install_hooks(); - pthread_mutex_unlock(&mutex); - return; } - - /* remove item from list */ - if (hdr->next) + else { - hdr->next->previous = hdr->previous; - } - hdr->previous->next = hdr->next; + /* remove item from list */ + if (hdr->next) + { + hdr->next->previous = hdr->previous; + } + hdr->previous->next = hdr->next; + + /* clear MAGIC, set mem to something remarkable */ + memset(hdr, MEMORY_FREE_PATTERN, hdr->bytes + sizeof(memory_header_t)); - /* clear MAGIC, set mem to something remarkable */ - memset(hdr, MEMORY_FREE_PATTERN, hdr->bytes + sizeof(memory_header_t)); + free(hdr); + } - free(hdr); install_hooks(); - pthread_mutex_unlock(&mutex); + pthread_setschedparam(thread_id, oldpolicy, &oldparams); } /** @@ -366,7 +483,11 @@ void *realloc_hook(void *old, size_t bytes, const void *caller) memory_header_t *hdr; void *stack_frames[STACK_FRAMES_COUNT]; int stack_frame_count; - + memory_tail_t *tail; + pthread_t thread_id = pthread_self(); + int oldpolicy; + struct sched_param oldparams, params; + /* allow reallocation of NULL */ if (old == NULL) { @@ -374,27 +495,34 @@ void *realloc_hook(void *old, size_t bytes, const void *caller) } hdr = old - sizeof(memory_header_t); + tail = old + hdr->bytes; + + pthread_getschedparam(thread_id, &oldpolicy, &oldparams); + + params.__sched_priority = sched_get_priority_max(SCHED_FIFO); + pthread_setschedparam(thread_id, SCHED_FIFO, ¶ms); - pthread_mutex_lock(&mutex); count_realloc++; uninstall_hooks(); - if (hdr->magic != MEMORY_HEADER_MAGIC) + if (hdr->magic != MEMORY_HEADER_MAGIC || + tail->magic != MEMORY_TAIL_MAGIC) { - DBG1("reallocation of invalid memory (%p):", old); + fprintf(stderr, "reallocating invalid memory (%p): " + "header magic 0x%x, tail magic 0x%x:\n", + old, hdr->magic, tail->magic); stack_frame_count = backtrace(stack_frames, STACK_FRAMES_COUNT); log_stack_frames(stack_frames, stack_frame_count); - install_hooks(); - pthread_mutex_unlock(&mutex); - raise(SIGKILL); - return NULL; } - - hdr = realloc(hdr, bytes + sizeof(memory_header_t)); - + /* clear tail magic, allocate, set tail magic */ + memset(&tail->magic, MEMORY_ALLOC_PATTERN, sizeof(tail->magic)); + hdr = realloc(hdr, sizeof(memory_header_t) + bytes + sizeof(memory_tail_t)); + tail = ((void*)hdr) + bytes + sizeof(memory_header_t); + tail->magic = MEMORY_TAIL_MAGIC; + /* update statistics */ hdr->bytes = bytes; hdr->stack_frame_count = backtrace(hdr->stack_frames, STACK_FRAMES_COUNT); - + /* update header of linked list neighbours */ if (hdr->next) { @@ -402,70 +530,36 @@ void *realloc_hook(void *old, size_t bytes, const void *caller) } hdr->previous->next = hdr; install_hooks(); - pthread_mutex_unlock(&mutex); + pthread_setschedparam(thread_id, oldpolicy, &oldparams); return hdr + 1; } /** - * Setup leak detective - */ -void __attribute__ ((constructor)) leak_detective_init() -{ - if (getenv("LEAK_DETECTIVE_DISABLE") == NULL) - { - install_hooks(); - } -} - -/** - * Clean up leak detective + * Implementation of leak_detective_t.destroy */ -void __attribute__ ((destructor)) leak_detective_cleanup() +static void destroy(private_leak_detective_t *this) { - if (getenv("LEAK_DETECTIVE_DISABLE") == NULL) + if (installed) { uninstall_hooks(); report_leaks(); } + free(this); } -/** - * Log memory allocation statistics +/* + * see header file */ -void leak_detective_status(FILE *stream) +leak_detective_t *leak_detective_create() { - u_int blocks = 0; - size_t bytes = 0; - memory_header_t *hdr = &first_header; + private_leak_detective_t *this = malloc_thing(private_leak_detective_t); - if (getenv("LEAK_DETECTIVE_DISABLE")) - { - return; - } + this->public.destroy = (void(*)(leak_detective_t*))destroy; - pthread_mutex_lock(&mutex); - while ((hdr = hdr->next)) + if (getenv("LEAK_DETECTIVE_DISABLE") == NULL) { - blocks++; - bytes += hdr->bytes; + install_hooks(); } - pthread_mutex_unlock(&mutex); - - fprintf(stream, "allocation statistics:\n"); - fprintf(stream, " call stats: malloc: %d, free: %d, realloc: %d\n", - count_malloc, count_free, count_realloc); - fprintf(stream, " allocated %d blocks, total size %d bytes (avg. %d bytes)\n", - blocks, bytes, bytes/blocks); -} - -#else /* !LEAK_DETECTION */ - -/** - * Dummy when !using LEAK_DETECTIVE - */ -void leak_detective_status(FILE *stream) -{ - + return &this->public; } -#endif /* LEAK_DETECTION */ diff --git a/src/libstrongswan/utils/leak_detective.h b/src/libstrongswan/utils/leak_detective.h index d4016b06e..763814726 100644 --- a/src/libstrongswan/utils/leak_detective.h +++ b/src/libstrongswan/utils/leak_detective.h @@ -1,11 +1,5 @@ -/** - * @file leak_detective.h - * - * @brief malloc/free hooks to detect leaks. - */ - /* - * Copyright (C) 2006 Martin Willi + * Copyright (C) 2008 Martin Willi * Hochschule fuer Technik Rapperswil * * This program is free software; you can redistribute it and/or modify it @@ -19,17 +13,41 @@ * for more details. */ +/** + * @defgroup leak_detective leak_detective + * @{ @ingroup utils + */ + #ifndef LEAK_DETECTIVE_H_ #define LEAK_DETECTIVE_H_ /** - * Log status information about allocation + * Maximum depth stack frames to register */ -void leak_detective_status(FILE *stream); +#define STACK_FRAMES_COUNT 20 + +typedef struct leak_detective_t leak_detective_t; /** - * Max number of stack frames to include in a backtrace. + * Leak detective finds leaks and bad frees using malloc hooks. + * + * Currently leaks are reported to stderr on destruction. + * + * @todo Build an API for leak detective, allowing leak enumeration, statistics + * and dynamic whitelisting. + */ +struct leak_detective_t { + + /** + * Destroy a leak_detective instance. + */ + void (*destroy)(leak_detective_t *this); +}; + +/** + * Create a leak_detective instance. */ -#define STACK_FRAMES_COUNT 30 +leak_detective_t *leak_detective_create(); + +#endif /* LEAK_DETECTIVE_H_ @}*/ -#endif /* LEAK_DETECTIVE_H_ */ diff --git a/src/libstrongswan/utils/lexparser.c b/src/libstrongswan/utils/lexparser.c index 7cc89fc90..8b7b3b547 100644 --- a/src/libstrongswan/utils/lexparser.c +++ b/src/libstrongswan/utils/lexparser.c @@ -1,12 +1,5 @@ -/** - * @file lexparser.c - * - * @brief lexical parser for text-based configuration files - * - */ - /* - * Copyright (C) 2001-2006 Andreas Steffen, Zuercher Hochschule Winterthur + * Copyright (C) 2001-2006 Andreas Steffen * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the @@ -18,7 +11,7 @@ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * - * RCSID $Id: lexparser.c 3353 2007-11-19 12:27:08Z martin $ + * $Id: lexparser.c 3872 2008-04-25 07:04:59Z andreas $ */ /* memrchr is a GNU extension */ @@ -55,6 +48,14 @@ bool extract_token(chunk_t *token, const char termination, chunk_t *src) { u_char *eot = memchr(src->ptr, termination, src->len); + if (termination == ' ') + { + u_char *eot_tab = memchr(src->ptr, '\t', src->len); + + /* check if a tab instead of a space terminates the token */ + eot = ( eot_tab == NULL || (eot && eot < eot_tab) ) ? eot : eot_tab; + } + /* initialize empty token */ *token = chunk_empty; diff --git a/src/libstrongswan/utils/lexparser.h b/src/libstrongswan/utils/lexparser.h index 775898139..7d54ca22e 100644 --- a/src/libstrongswan/utils/lexparser.h +++ b/src/libstrongswan/utils/lexparser.h @@ -1,12 +1,7 @@ -/** - * @file lexparser.h - * - * @brief lexical parser for text-based configuration files - * - */ - /* - * Copyright (C) 2001-2006 Andreas Steffen, Zuercher Hochschule Winterthur + * Copyright (C) 2001-2008 Andreas Steffen + * + * Hochschule fuer Technik Rapperswil * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the @@ -18,47 +13,57 @@ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * - * RCSID $Id: lexparser.h 3346 2007-11-16 20:23:29Z andreas $ + * $Id: lexparser.h 3876 2008-04-26 09:24:14Z andreas $ + */ + +/** + * @defgroup lexparser lexparser + * @{ @ingroup utils */ +#ifndef LEXPARSER_H_ +#define LEXPARSER_H_ + #include <library.h> /** - * @brief Eats whitespace + * Eats whitespace */ bool eat_whitespace(chunk_t *src); /** - * @brief Compare null-terminated pattern with chunk + * Compare null-terminated pattern with chunk */ bool match(const char *pattern, const chunk_t *ch); /** - * @brief Extracts a token ending with the first occurence a given termination symbol + * Extracts a token ending with the first occurence a given termination symbol */ bool extract_token(chunk_t *token, const char termination, chunk_t *src); /** - * @brief Extracts a token ending with the last occurence a given termination symbol + * Extracts a token ending with the last occurence a given termination symbol */ bool extract_last_token(chunk_t *token, const char termination, chunk_t *src); /** - * @brief Fetches a new text line terminated by \n or \r\n + * Fetches a new text line terminated by \n or \r\n */ bool fetchline(chunk_t *src, chunk_t *line); /** - * @brief Extracts a value that might be single or double quoted + * Extracts a value that might be single or double quoted */ err_t extract_value(chunk_t *value, chunk_t *line); /** - * @brief extracts a name: value pair from a text line + * extracts a name: value pair from a text line */ err_t extract_name_value(chunk_t *name, chunk_t *value, chunk_t *line); /** - * @brief extracts a parameter: value from a text line + * extracts a parameter: value from a text line */ err_t extract_parameter_value(chunk_t *name, chunk_t *value, chunk_t *line); + +#endif /* LEXPARSER_H_ @} */ diff --git a/src/libstrongswan/utils/linked_list.c b/src/libstrongswan/utils/linked_list.c index 63e1bcfbf..80c4e6f9f 100644 --- a/src/libstrongswan/utils/linked_list.c +++ b/src/libstrongswan/utils/linked_list.c @@ -1,12 +1,5 @@ -/** - * @file linked_list.c - * - * @brief Implementation of linked_list_t. - * - */ - /* - * Copyright (C) 2007 Tobias Brunner + * Copyright (C) 2007-2008 Tobias Brunner * Copyright (C) 2005-2006 Martin Willi * Copyright (C) 2005 Jan Hutter * Hochschule fuer Technik Rapperswil @@ -20,6 +13,8 @@ * 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: linked_list.c 3841 2008-04-18 11:48:53Z tobias $ */ #include <stdlib.h> @@ -154,9 +149,14 @@ struct private_enumerator_t { enumerator_t enumerator; /** - * next item to enumerate + * associated linked list */ - element_t *next; + private_linked_list_t *list; + + /** + * current item + */ + element_t *current; }; /** @@ -164,12 +164,23 @@ struct private_enumerator_t { */ static bool enumerate(private_enumerator_t *this, void **item) { - if (this->next == NULL) + if (!this->current) { - return FALSE; + if (!this->list->first) + { + return FALSE; + } + this->current = this->list->first; } - *item = this->next->value; - this->next = this->next->next; + else + { + if (!this->current->next) + { + return FALSE; + } + this->current = this->current->next; + } + *item = this->current->value; return TRUE; } @@ -182,7 +193,8 @@ static enumerator_t* create_enumerator(private_linked_list_t *this) enumerator->enumerator.enumerate = (void*)enumerate; enumerator->enumerator.destroy = (void*)free; - enumerator->next = this->first; + enumerator->list = this; + enumerator->current = NULL; return &enumerator->enumerator; } @@ -459,34 +471,37 @@ static void insert_first(private_linked_list_t *this, void *item) } /** - * Implementation of linked_list_t.remove_first. + * unlink an element form the list, returns following element */ -static status_t remove_first(private_linked_list_t *this, void **item) +static element_t* remove_element(private_linked_list_t *this, element_t *element) { - element_t *element = this->first; - - if (element == NULL) + element_t *next, *previous; + + next = element->next; + previous = element->previous; + free(element); + if (next) { - return NOT_FOUND; + next->previous = previous; } - if (element->next != NULL) + else { - element->next->previous = NULL; + this->last = previous; } - this->first = element->next; - - if (item != NULL) + if (previous) + { + previous->next = next; + } + else { - *item = element->value; + this->first = next; } if (--this->count == 0) { + this->first = NULL; this->last = NULL; } - - free(element); - - return SUCCESS; + return next; } /** @@ -503,6 +518,19 @@ static status_t get_first(private_linked_list_t *this, void **item) } /** + * Implementation of linked_list_t.remove_first. + */ +static status_t remove_first(private_linked_list_t *this, void **item) +{ + if (get_first(this, item) == SUCCESS) + { + remove_element(this, this->first); + return SUCCESS; + } + return NOT_FOUND; +} + +/** * Implementation of linked_list_t.insert_last. */ static void insert_last(private_linked_list_t *this, void *item) @@ -529,151 +557,69 @@ static void insert_last(private_linked_list_t *this, void *item) } /** - * Implementation of linked_list_t.remove_last. + * Implementation of linked_list_t.get_last. */ -static status_t remove_last(private_linked_list_t *this, void **item) +static status_t get_last(private_linked_list_t *this, void **item) { - element_t *element = this->last; - - if (element == NULL) + if (this->count == 0) { return NOT_FOUND; } - if (element->previous != NULL) - { - element->previous->next = NULL; - } - this->last = element->previous; - - if (item != NULL) - { - *item = element->value; - } - if (--this->count == 0) - { - this->first = NULL; - } - - free(element); - + *item = this->last->value; return SUCCESS; } /** - * Implementation of linked_list_t.insert_at_position. + * Implementation of linked_list_t.remove_last. */ -static status_t insert_at_position (private_linked_list_t *this,size_t position, void *item) +static status_t remove_last(private_linked_list_t *this, void **item) { - element_t *current_element; - int i; - - if (this->count <= position) + if (get_last(this, item) == SUCCESS) { - return INVALID_ARG; - } - - current_element = this->first; - - for (i = 0; i < position;i++) - { - current_element = current_element->next; - } - - if (current_element == NULL) - { - this->public.insert_last(&(this->public),item); + remove_element(this, this->last); return SUCCESS; } - - element_t *element = element_create(item); - if (current_element->previous == NULL) - { - current_element->previous = element; - element->next = current_element; - this->first = element; - } - else - { - current_element->previous->next = element; - element->previous = current_element->previous; - current_element->previous = element; - element->next = current_element; - } - - - this->count++; - return SUCCESS; + return NOT_FOUND; } /** - * Implementation of linked_list_t.remove_at_position. + * Implementation of linked_list_t.remove. */ -static status_t remove_at_position(private_linked_list_t *this,size_t position, void **item) +static int remove(private_linked_list_t *this, void *item, + bool (*compare)(void *,void*)) { - iterator_t *iterator; - int i; - - if (this->count <= position) - { - return INVALID_ARG; - } + element_t *current = this->first; + int removed = 0; - iterator = this->public.create_iterator(&(this->public),TRUE); - iterator->iterate(iterator, item); - for (i = 0; i < position; i++) + while (current) { - if (!iterator->iterate(iterator, item)) + if ((compare && compare(current->value, item)) || + (!compare && current->value == item)) { - iterator->destroy(iterator); - return INVALID_ARG; + removed++; + current = remove_element(this, current); } - } - iterator->remove(iterator); - iterator->destroy(iterator); - - return SUCCESS; -} - -/** - * Implementation of linked_list_t.get_at_position. - */ -static status_t get_at_position(private_linked_list_t *this,size_t position, void **item) -{ - int i; - iterator_t *iterator; - - if (this->count <= position) - { - return INVALID_ARG; - } - - iterator = this->public.create_iterator(&(this->public),TRUE); - iterator->iterate(iterator, item); - for (i = 0; i < position; i++) - { - if (!iterator->iterate(iterator, item)) + else { - iterator->destroy(iterator); - return INVALID_ARG; + current = current->next; } } - iterator->destroy(iterator); - return SUCCESS; + return removed; } /** - * Implementation of linked_list_t.get_last. + * Implementation of linked_list_t.remove_at. */ -static status_t get_last(private_linked_list_t *this, void **item) +static void remove_at(private_linked_list_t *this, private_enumerator_t *enumerator) { - if (this->count == 0) + element_t *current; + + if (enumerator->current) { - return NOT_FOUND; + current = enumerator->current; + enumerator->current = current->previous; + remove_element(this, current); } - - *item = this->last->value; - - return SUCCESS; } /** @@ -725,14 +671,15 @@ static status_t find_last(private_linked_list_t *this, linked_list_match_t match /** * Implementation of linked_list_t.invoke_offset. */ -static void invoke_offset(private_linked_list_t *this, size_t offset) +static void invoke_offset(private_linked_list_t *this, size_t offset, + void *d1, void *d2, void *d3, void *d4, void *d5) { element_t *current = this->first; while (current) { - void (**method)(void*) = current->value + offset; - (*method)(current->value); + linked_list_invoke_t *method = current->value + offset; + (*method)(current->value, d1, d2, d3, d4, d5); current = current->next; } } @@ -740,13 +687,14 @@ static void invoke_offset(private_linked_list_t *this, size_t offset) /** * Implementation of linked_list_t.invoke_function. */ -static void invoke_function(private_linked_list_t *this, void(*fn)(void*)) +static void invoke_function(private_linked_list_t *this, linked_list_invoke_t fn, + void *d1, void *d2, void *d3, void *d4, void *d5) { element_t *current = this->first; while (current) { - fn(current->value); + fn(current->value, d1, d2, d3, d4, d5); current = current->next; } } @@ -895,11 +843,10 @@ linked_list_t *linked_list_create() this->public.insert_last = (void (*) (linked_list_t *, void *item))insert_last; this->public.remove_first = (status_t (*) (linked_list_t *, void **item))remove_first; this->public.remove_last = (status_t (*) (linked_list_t *, void **item))remove_last; - this->public.insert_at_position = (status_t (*) (linked_list_t *,size_t, void *))insert_at_position; - this->public.remove_at_position = (status_t (*) (linked_list_t *,size_t, void **))remove_at_position; - this->public.get_at_position = (status_t (*) (linked_list_t *,size_t, void **))get_at_position; - this->public.invoke_offset = (void (*)(linked_list_t*,size_t))invoke_offset; - this->public.invoke_function = (void (*)(linked_list_t*,void(*)(void*)))invoke_function; + this->public.remove = (int(*)(linked_list_t*, void *item, bool (*compare)(void *,void*)))remove; + this->public.remove_at = (void(*)(linked_list_t*, enumerator_t *enumerator))remove_at; + this->public.invoke_offset = (void (*)(linked_list_t*,size_t,...))invoke_offset; + this->public.invoke_function = (void (*)(linked_list_t*,linked_list_invoke_t,...))invoke_function; this->public.clone_offset = (linked_list_t * (*)(linked_list_t*,size_t))clone_offset; this->public.clone_function = (linked_list_t * (*)(linked_list_t*,void*(*)(void*)))clone_function; this->public.destroy = (void (*) (linked_list_t *))destroy; diff --git a/src/libstrongswan/utils/linked_list.h b/src/libstrongswan/utils/linked_list.h index ac36ef46d..310e91e3c 100644 --- a/src/libstrongswan/utils/linked_list.h +++ b/src/libstrongswan/utils/linked_list.h @@ -1,12 +1,5 @@ -/** - * @file linked_list.h - * - * @brief Interface of linked_list_t. - * - */ - /* - * Copyright (C) 2007 Tobias Brunner + * Copyright (C) 2007-2008 Tobias Brunner * Copyright (C) 2005-2006 Martin Willi * Copyright (C) 2005 Jan Hutter * Hochschule fuer Technik Rapperswil @@ -20,6 +13,13 @@ * 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: linked_list.h 3841 2008-04-18 11:48:53Z tobias $ + */ + +/** + * @defgroup linked_list linked_list + * @{ @ingroup utils */ #ifndef LINKED_LIST_H_ @@ -42,51 +42,50 @@ typedef struct linked_list_t linked_list_t; * @return * - TRUE, if the item matched * - FALSE, otherwise - * @ingroup utils */ typedef bool (*linked_list_match_t)(void *item, ...); /** - * @brief Class implementing a double linked list. - * - * General purpose linked list. This list is not synchronized. + * Method to be invoked on elements in a linked list (used in invoke_* functions) * - * @b Costructors: - * - linked_list_create() + * @param item current list item + * @param ... user supplied data (only pointers, at most 5) + */ +typedef void (*linked_list_invoke_t)(void *item, ...); + +/** + * Class implementing a double linked list. * - * @ingroup utils + * General purpose linked list. This list is not synchronized. */ struct linked_list_t { /** - * @brief Gets the count of items in the list. + * Gets the count of items in the list. * - * @param this calling object * @return number of items in list */ int (*get_count) (linked_list_t *this); /** - * @brief Creates a iterator for the given list. + * Creates a iterator for the given list. * * @warning Created iterator_t object has to get destroyed by the caller. * * @deprecated Iterator is obsolete and will disappear, it is too * complicated to implement. Use enumerator instead. * - * @param this calling object * @param forward iterator direction (TRUE: front to end) * @return new iterator_t object */ iterator_t *(*create_iterator) (linked_list_t *this, bool forward); /** - * @brief Creates a iterator, locking a mutex. + * Creates a iterator, locking a mutex. * * The supplied mutex is acquired immediately, and released * when the iterator gets destroyed. * - * @param this calling object * @param mutex mutex to use for exclusive access * @return new iterator_t object */ @@ -94,113 +93,86 @@ struct linked_list_t { pthread_mutex_t *mutex); /** - * @brief Create an enumerator over the list. + * Create an enumerator over the list. * * The enumerator is a "lightweight" iterator. It only has two methods * and should therefore be much easier to implement. * - * @param this calling object * @return enumerator over list items */ enumerator_t* (*create_enumerator)(linked_list_t *this); /** - * @brief Inserts a new item at the beginning of the list. + * Inserts a new item at the beginning of the list. * - * @param this calling object - * @param[in] item item value to insert in list + * @param item item value to insert in list */ void (*insert_first) (linked_list_t *this, void *item); /** - * @brief Removes the first item in the list and returns its value. + * Removes the first item in the list and returns its value. * - * @param this calling object - * @param[out] item returned value of first item, or NULL - * @return - * - SUCCESS - * - NOT_FOUND, if list is empty + * @param item returned value of first item, or NULL + * @return SUCCESS, or NOT_FOUND if list is empty */ status_t (*remove_first) (linked_list_t *this, void **item); - - /** - * @brief Returns the value of the first list item without removing it. - * - * @param this calling object - * @param[out] item returned value of first item - * @return - * - SUCCESS - * - NOT_FOUND, if list is empty - */ - status_t (*get_first) (linked_list_t *this, void **item); - + /** - * @brief Inserts a new item at the end of the list. - * - * @param this calling object - * @param[in] item value to insert into list + * Remove an item from the list where the enumerator points to. + * + * @param enumerator enumerator with position */ - void (*insert_last) (linked_list_t *this, void *item); + void (*remove_at)(linked_list_t *this, enumerator_t *enumerator); /** - * @brief Inserts a new item at a given position in the list. + * Remove items from the list matching item. * - * @param this calling object - * @param position position starting at 0 to insert new entry - * @param[in] item value to insert into list - * @return - * - SUCCESS - * - INVALID_ARG if position not existing + * If a compare function is given, it is called for each item, where + * the first parameter is the current list item and the second parameter + * is the supplied item parameter. + * If compare is NULL, compare is is done by pointer. + * + * @param item item to remove/pass to comparator + * @param compare compare function, or NULL + * @return number of removed items */ - status_t (*insert_at_position) (linked_list_t *this,size_t position, void *item); + int (*remove)(linked_list_t *this, void *item, bool (*compare)(void *,void*)); /** - * @brief Removes an item from a given position in the list. + * Returns the value of the first list item without removing it. * * @param this calling object - * @param position position starting at 0 to remove entry from - * @param[out] item removed item will be stored at this location - * @return - * - SUCCESS - * - INVALID_ARG if position not existing + * @param item returned value of first item + * @return SUCCESS, NOT_FOUND if list is empty */ - status_t (*remove_at_position) (linked_list_t *this, size_t position, void **item); + status_t (*get_first) (linked_list_t *this, void **item); /** - * @brief Get an item from a given position in the list. + * Inserts a new item at the end of the list. * - * @param this calling object - * @param position position starting at 0 to get entry from - * @param[out] item item will be stored at this location - * @return - * - SUCCESS - * - INVALID_ARG if position not existing + * @param item value to insert into list */ - status_t (*get_at_position) (linked_list_t *this, size_t position, void **item); + void (*insert_last) (linked_list_t *this, void *item); /** - * @brief Removes the last item in the list and returns its value. + * Removes the last item in the list and returns its value. * * @param this calling object - * @param[out] item returned value of last item, or NULL - * @return - * - SUCCESS - * - NOT_FOUND if list is empty + * @param item returned value of last item, or NULL + * @return SUCCESS, NOT_FOUND if list is empty */ status_t (*remove_last) (linked_list_t *this, void **item); /** - * @brief Returns the value of the last list item without removing it. + * Returns the value of the last list item without removing it. * * @param this calling object - * @param[out] item returned value of last item - * @return - * - SUCCESS - * - NOT_FOUND if list is empty + * @param item returned value of last item + * @return SUCCESS, NOT_FOUND if list is empty */ status_t (*get_last) (linked_list_t *this, void **item); - /** @brief Find the first matching element in the list. + /** Find the first matching element in the list. * * The first object passed to the match function is the current list item, * followed by the user supplied data. @@ -210,19 +182,15 @@ struct linked_list_t { * * @warning Only use pointers as user supplied data. * - * @param this calling object * @param match comparison function to call on each object - * @param[out] item - * - the list item, if found - * - NULL, otherwise + * @param item the list item, if found * @param ... user data to supply to match function (limited to 5 arguments) - * @return - * - SUCCESS, if found - * - NOT_FOUND, otherwise + * @return SUCCESS if found, NOT_FOUND otherwise */ - status_t (*find_first) (linked_list_t *this, linked_list_match_t match, void **item, ...); + status_t (*find_first) (linked_list_t *this, linked_list_match_t match, + void **item, ...); - /** @brief Find the last matching element in the list. + /** Find the last matching element in the list. * * The first object passed to the match function is the current list item, * followed by the user supplied data. @@ -232,20 +200,16 @@ struct linked_list_t { * * @warning Only use pointers as user supplied data. * - * @param this calling object * @param match comparison function to call on each object - * @param[out] item - * - the list item, if found - * - NULL, otherwise + * @param item the list item, if found * @param ... user data to supply to match function (limited to 5 arguments) - * @return - * - SUCCESS, if found - * - NOT_FOUND, otherwise + * @return SUCCESS if found, NOT_FOUND otherwise */ - status_t (*find_last) (linked_list_t *this, linked_list_match_t match, void **item, ...); + status_t (*find_last) (linked_list_t *this, linked_list_match_t match, + void **item, ...); /** - * @brief Invoke a method on all of the contained objects. + * Invoke a method on all of the contained objects. * * If a linked list contains objects with function pointers, * invoke() can call a method on each of the objects. The @@ -253,79 +217,70 @@ struct linked_list_t { * which can be evalutated at compile time using the offsetof * macro, e.g.: list->invoke(list, offsetof(object_t, method)); * - * @param this calling object * @param offset offset of the method to invoke on objects + * @param ... user data to supply to called function (limited to 5 arguments) */ - void (*invoke_offset) (linked_list_t *this, size_t offset); + void (*invoke_offset) (linked_list_t *this, size_t offset, ...); /** - * @brief Invoke a function on all of the contained objects. + * Invoke a function on all of the contained objects. * - * @param this calling object - * @param offset offset of the method to invoke on objects + * @param function offset of the method to invoke on objects + * @param ... user data to supply to called function (limited to 5 arguments) */ - void (*invoke_function) (linked_list_t *this, void (*)(void*)); + void (*invoke_function) (linked_list_t *this, linked_list_invoke_t function, ...); /** - * @brief Clones a list and its objects using the objects' clone method. + * Clones a list and its objects using the objects' clone method. * - * @param this calling object * @param offset offset ot the objects clone function * @return cloned list */ linked_list_t *(*clone_offset) (linked_list_t *this, size_t offset); /** - * @brief Clones a list and its objects using a given function. + * Clones a list and its objects using a given function. * - * @param this calling object * @param function function that clones an object * @return cloned list */ linked_list_t *(*clone_function) (linked_list_t *this, void*(*)(void*)); /** - * @brief Destroys a linked_list object. - * - * @param this calling object + * Destroys a linked_list object. */ void (*destroy) (linked_list_t *this); /** - * @brief Destroys a list and its objects using the destructor. + * Destroys a list and its objects using the destructor. * * If a linked list and the contained objects should be destroyed, use * destroy_offset. The supplied offset specifies the destructor to * call on each object. The offset may be calculated using the offsetof * macro, e.g.: list->destroy_offset(list, offsetof(object_t, destroy)); * - * @param this calling object * @param offset offset of the objects destructor */ void (*destroy_offset) (linked_list_t *this, size_t offset); /** - * @brief Destroys a list and its contents using a a cleanup function. + * Destroys a list and its contents using a a cleanup function. * * If a linked list and its contents should get destroyed using a specific * cleanup function, use destroy_function. This is useful when the * list contains malloc()-ed blocks which should get freed, * e.g.: list->destroy_function(list, free); * - * @param this calling object * @param function function to call on each object */ void (*destroy_function) (linked_list_t *this, void (*)(void*)); }; /** - * @brief Creates an empty linked list object. + * Creates an empty linked list object. * * @return linked_list_t object. - * - * @ingroup utils */ linked_list_t *linked_list_create(void); - -#endif /*LINKED_LIST_H_*/ +#endif /*LINKED_LIST_H_ @} */ diff --git a/src/libstrongswan/utils/mutex.c b/src/libstrongswan/utils/mutex.c new file mode 100644 index 000000000..425389b4f --- /dev/null +++ b/src/libstrongswan/utils/mutex.c @@ -0,0 +1,267 @@ +/* + * 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: mutex.c 3589 2008-03-13 14:14:44Z martin $ + */ + +#include "mutex.h" + +#include <library.h> +#include <debug.h> + +#include <pthread.h> +#include <sys/time.h> +#include <time.h> +#include <errno.h> + + +typedef struct private_mutex_t private_mutex_t; +typedef struct private_n_mutex_t private_n_mutex_t; +typedef struct private_r_mutex_t private_r_mutex_t; +typedef struct private_condvar_t private_condvar_t; + +/** + * private data of mutex + */ +struct private_mutex_t { + + /** + * public functions + */ + mutex_t public; + + /** + * wrapped pthread mutex + */ + pthread_mutex_t mutex; +}; + +/** + * private data of mutex, extended by recursive locking information + */ +struct private_r_mutex_t { + + /** + * public functions + */ + private_mutex_t generic; + + /** + * thread which currently owns mutex + */ + pthread_t thread; + + /** + * times we have locked the lock + */ + int times; +}; + +/** + * private data of condvar + */ +struct private_condvar_t { + + /** + * public functions + */ + condvar_t public; + + /** + * wrapped pthread condvar + */ + pthread_cond_t condvar; +}; + +/** + * Implementation of mutex_t.lock. + */ +static void lock(private_mutex_t *this) +{ + if (pthread_mutex_lock(&this->mutex)) + { + DBG1("!!!! MUTEX %sLOCK ERROR, your code is buggy !!!", ""); + } +} + +/** + * Implementation of mutex_t.unlock. + */ +static void unlock(private_mutex_t *this) +{ + if (pthread_mutex_unlock(&this->mutex)) + { + DBG1("!!!! MUTEX %sLOCK ERROR, your code is buggy !!!", "UN"); + } +} + +/** + * Implementation of mutex_t.lock. + */ +static void lock_r(private_r_mutex_t *this) +{ + pthread_t self = pthread_self(); + + if (this->thread == self) + { + this->times++; + return; + } + lock(&this->generic); + this->thread = self; + this->times = 1; +} + +/** + * Implementation of mutex_t.unlock. + */ +static void unlock_r(private_r_mutex_t *this) +{ + if (--this->times == 0) + { + this->thread = 0; + unlock(&this->generic); + } +} + +/** + * Implementation of mutex_t.destroy + */ +static void mutex_destroy(private_mutex_t *this) +{ + pthread_mutex_destroy(&this->mutex); + free(this); +} + +/* + * see header file + */ +mutex_t *mutex_create(mutex_type_t type) +{ + switch (type) + { + case MUTEX_RECURSIVE: + { + private_r_mutex_t *this = malloc_thing(private_r_mutex_t); + + this->generic.public.lock = (void(*)(mutex_t*))lock_r; + this->generic.public.unlock = (void(*)(mutex_t*))unlock_r; + this->generic.public.destroy = (void(*)(mutex_t*))mutex_destroy; + + pthread_mutex_init(&this->generic.mutex, NULL); + this->thread = 0; + this->times = 0; + + return &this->generic.public; + } + case MUTEX_DEFAULT: + default: + { + private_mutex_t *this = malloc_thing(private_mutex_t); + + this->public.lock = (void(*)(mutex_t*))lock; + this->public.unlock = (void(*)(mutex_t*))unlock; + this->public.destroy = (void(*)(mutex_t*))mutex_destroy; + + pthread_mutex_init(&this->mutex, NULL); + + return &this->public; + } + } +} + +/** + * Implementation of condvar_t.wait. + */ +static void wait(private_condvar_t *this, private_mutex_t *mutex) +{ + pthread_cond_wait(&this->condvar, &mutex->mutex); +} + +/** + * Implementation of condvar_t.timed_wait. + */ +static bool timed_wait(private_condvar_t *this, private_mutex_t *mutex, + u_int timeout) +{ + struct timespec ts; + struct timeval tv; + u_int s, ms; + + gettimeofday(&tv, NULL); + + s = timeout / 1000; + ms = timeout % 1000; + + ts.tv_sec = tv.tv_sec + s; + ts.tv_nsec = tv.tv_usec * 1000 + ms * 1000000; + if (ts.tv_nsec > 1000000000 /* 1s */) + { + ts.tv_nsec -= 1000000000; + ts.tv_sec++; + } + return (pthread_cond_timedwait(&this->condvar, &mutex->mutex, + &ts) == ETIMEDOUT); +} + +/** + * Implementation of condvar_t.signal. + */ +static void signal(private_condvar_t *this) +{ + pthread_cond_signal(&this->condvar); +} + +/** + * Implementation of condvar_t.broadcast. + */ +static void broadcast(private_condvar_t *this) +{ + pthread_cond_broadcast(&this->condvar); +} + +/** + * Implementation of condvar_t.destroy + */ +static void condvar_destroy(private_condvar_t *this) +{ + pthread_cond_destroy(&this->condvar); + free(this); +} + +/* + * see header file + */ +condvar_t *condvar_create(condvar_type_t type) +{ + switch (type) + { + case CONDVAR_DEFAULT: + default: + { + private_condvar_t *this = malloc_thing(private_condvar_t); + + this->public.wait = (void(*)(condvar_t*, mutex_t *mutex))wait; + this->public.timed_wait = (bool(*)(condvar_t*, mutex_t *mutex, u_int timeout))timed_wait; + this->public.signal = (void(*)(condvar_t*))signal; + this->public.broadcast = (void(*)(condvar_t*))broadcast; + this->public.destroy = (void(*)(condvar_t*))condvar_destroy; + + pthread_cond_init(&this->condvar, NULL); + + return &this->public; + } + } +} + diff --git a/src/libstrongswan/utils/mutex.h b/src/libstrongswan/utils/mutex.h new file mode 100644 index 000000000..cf557c35c --- /dev/null +++ b/src/libstrongswan/utils/mutex.h @@ -0,0 +1,123 @@ +/* + * 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 mutex mutex + * @{ @ingroup utils + */ + +#ifndef MUTEX_H_ +#define MUTEX_H_ + +typedef struct mutex_t mutex_t; +typedef struct condvar_t condvar_t; +typedef enum mutex_type_t mutex_type_t; +typedef enum condvar_type_t condvar_type_t; + +#include <library.h> + +/** + * Type of mutex. + */ +enum mutex_type_t { + /** default mutex */ + MUTEX_DEFAULT = 0, + /** allow recursive locking of the mutex */ + MUTEX_RECURSIVE = 1, +}; + +/** + * Type of condvar. + */ +enum condvar_type_t { + /** default condvar */ + CONDVAR_DEFAULT = 0, +}; + +/** + * Mutex wrapper implements simple, portable and advanced mutex functions. + */ +struct mutex_t { + + /** + * Acquire the lock to the mutex. + */ + void (*lock)(mutex_t *this); + + /** + * Release the lock on the mutex. + */ + void (*unlock)(mutex_t *this); + + /** + * Destroy a mutex instance. + */ + void (*destroy)(mutex_t *this); +}; + +/** + * Condvar wrapper to use in conjunction with mutex_t. + */ +struct condvar_t { + + /** + * Wait on a condvar until it gets signalized. + * + * @param mutex mutex to release while waiting + */ + void (*wait)(condvar_t *this, mutex_t *mutex); + + /** + * Wait on a condvar until it gets signalized, or times out. + * + * @param mutex mutex to release while waiting + * @param timeout timeout im ms + * @return TRUE if timed out, FALSE otherwise + */ + bool (*timed_wait)(condvar_t *this, mutex_t *mutex, u_int timeout); + + /** + * Wake up a single thread in a condvar. + */ + void (*signal)(condvar_t *this); + + /** + * Wake up all threads in a condvar. + */ + void (*broadcast)(condvar_t *this); + + /** + * Destroy a condvar and free its resources. + */ + void (*destroy)(condvar_t *this); +}; + +/** + * Create a mutex instance. + * + * @param type type of mutex to create + * @return unlocked mutex instance + */ +mutex_t *mutex_create(mutex_type_t type); + +/** + * Create a condvar instance. + * + * @param type type of condvar to create + * @return condvar instance + */ +condvar_t *condvar_create(condvar_type_t type); + +#endif /* MUTEX_H_ @}*/ diff --git a/src/libstrongswan/utils/optionsfrom.c b/src/libstrongswan/utils/optionsfrom.c index 39e38cc58..18427e197 100644 --- a/src/libstrongswan/utils/optionsfrom.c +++ b/src/libstrongswan/utils/optionsfrom.c @@ -1,13 +1,5 @@ -/** - * @file optionsfrom.c - * - * @brief read command line options from a file - * - */ - /* * Copyright (C) 2007-2008 Andreas Steffen - * * Hochschule fuer Technik Rapperswil * * This library is free software; you can redistribute it and/or modify it @@ -20,7 +12,7 @@ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public * License for more details. * - * RCSID $Id$ + * $Id: optionsfrom.c 3589 2008-03-13 14:14:44Z martin $ */ #include <stdio.h> diff --git a/src/libstrongswan/utils/optionsfrom.h b/src/libstrongswan/utils/optionsfrom.h index 0014cec36..424b9dc61 100644 --- a/src/libstrongswan/utils/optionsfrom.h +++ b/src/libstrongswan/utils/optionsfrom.h @@ -1,10 +1,3 @@ -/** - * @file optionsfrom.h - * - * @brief Read command line options from a file - * - */ - /* * Copyright (C) 2007-2008 Andreas Steffen * @@ -20,7 +13,12 @@ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * - * RCSID $Id$ + * $Id: optionsfrom.h 3589 2008-03-13 14:14:44Z martin $ + */ + +/** + * @defgroup optionsfrom optionsfrom + * @{ @ingroup utils */ #ifndef OPTIONSFROM_H_ @@ -29,41 +27,33 @@ typedef struct options_t options_t; /** - * @brief options object. - * - * @b Constructors: - * - options_create() - * - * @ingroup utils + * Reads additional command line arguments from a file */ struct options_t { + /** - * @brief Check if the PKCS#7 contentType is data + * Check if the PKCS#7 contentType is data * - * @param this calling object * @param filename file containing the options * @param argcp pointer to argc * @param argvp pointer to argv[] * @param optind current optind, number of next argument * @return TRUE if optionsfrom parsing successful */ - bool (*from) (options_t * this, char *filename, int *argcp, char **argvp[], int optind); + bool (*from) (options_t * this, char *filename, + int *argcp, char **argvp[], int optind); /** - * @brief Destroys the options_t object. - * - * @param this options_t object to destroy + * Destroys the options_t object. */ void (*destroy) (options_t *this); }; /** - * @brief Create an options object. + * Create an options object. * * @return created options_t object - * - * @ingroup utils */ options_t *options_create(void); -#endif /*OPTIONSFROM_H_*/ +#endif /*OPTIONSFROM_H_ @} */ diff --git a/src/libstrongswan/utils/randomizer.c b/src/libstrongswan/utils/randomizer.c deleted file mode 100644 index c15d108c7..000000000 --- a/src/libstrongswan/utils/randomizer.c +++ /dev/null @@ -1,165 +0,0 @@ -/** - * @file randomizer.c - * - * @brief Implementation of randomizer_t. - * - */ - -/* - * 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. - */ - -#include <string.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <fcntl.h> -#include <unistd.h> - -#include "randomizer.h" - - -typedef struct private_randomizer_t private_randomizer_t; - -/** - * Private data of an randomizer_t object. - */ -struct private_randomizer_t { - - /** - * Public randomizer_t interface. - */ - randomizer_t public; - - /** - * @brief Reads a specific number of bytes from random or pseudo random device. - * - * @param this calling object - * @param pseudo_random TRUE, if from pseudo random bytes should be read, - * FALSE for true random bytes - * @param bytes number of bytes to read - * @param[out] buffer pointer to buffer where to write the data in. - * Size of buffer has to be at least bytes. - */ - status_t (*get_bytes_from_device) (private_randomizer_t *this,bool pseudo_random, size_t bytes, u_int8_t *buffer); -}; - - -/** - * Implementation of private_randomizer_t.get_bytes_from_device. - */ -static status_t get_bytes_from_device(private_randomizer_t *this,bool pseudo_random, size_t bytes, u_int8_t *buffer) -{ - size_t ndone; - int device; - size_t got; - char * device_name; - - device_name = pseudo_random ? DEV_URANDOM : DEV_RANDOM; - - device = open(device_name, 0); - if (device < 0) { - return FAILED; - } - ndone = 0; - - /* read until nbytes are read */ - while (ndone < bytes) - { - got = read(device, buffer + ndone, bytes - ndone); - if (got <= 0) { - close(device); - return FAILED; - } - ndone += got; - } - close(device); - return SUCCESS; -} - -/** - * Implementation of randomizer_t.get_random_bytes. - */ -static status_t get_random_bytes(private_randomizer_t *this,size_t bytes, u_int8_t *buffer) -{ - return this->get_bytes_from_device(this, FALSE, bytes, buffer); -} - -/** - * Implementation of randomizer_t.allocate_random_bytes. - */ -static status_t allocate_random_bytes(private_randomizer_t *this, size_t bytes, chunk_t *chunk) -{ - status_t status; - chunk->len = bytes; - chunk->ptr = malloc(bytes); - status = this->get_bytes_from_device(this, FALSE, bytes, chunk->ptr); - if (status != SUCCESS) - { - free(chunk->ptr); - } - return status; -} - -/** - * Implementation of randomizer_t.get_pseudo_random_bytes. - */ -static status_t get_pseudo_random_bytes(private_randomizer_t *this,size_t bytes, u_int8_t *buffer) -{ - return (this->get_bytes_from_device(this, TRUE, bytes, buffer)); -} - -/** - * Implementation of randomizer_t.allocate_pseudo_random_bytes. - */ -static status_t allocate_pseudo_random_bytes(private_randomizer_t *this, size_t bytes, chunk_t *chunk) -{ - status_t status; - chunk->len = bytes; - chunk->ptr = malloc(bytes); - status = this->get_bytes_from_device(this, TRUE, bytes, chunk->ptr); - if (status != SUCCESS) - { - free(chunk->ptr); - } - return status; -} - -/** - * Implementation of randomizer_t.destroy. - */ -static void destroy(private_randomizer_t *this) -{ - free(this); -} - -/* - * Described in header. - */ -randomizer_t *randomizer_create(void) -{ - private_randomizer_t *this = malloc_thing(private_randomizer_t); - - /* public functions */ - this->public.get_random_bytes = (status_t (*) (randomizer_t *,size_t, u_int8_t *)) get_random_bytes; - this->public.allocate_random_bytes = (status_t (*) (randomizer_t *,size_t, chunk_t *)) allocate_random_bytes; - this->public.get_pseudo_random_bytes = (status_t (*) (randomizer_t *,size_t, u_int8_t *)) get_pseudo_random_bytes; - this->public.allocate_pseudo_random_bytes = (status_t (*) (randomizer_t *,size_t, chunk_t *)) allocate_pseudo_random_bytes; - this->public.destroy = (void (*) (randomizer_t *))destroy; - - /* private functions */ - this->get_bytes_from_device = get_bytes_from_device; - - return &(this->public); -} diff --git a/src/libstrongswan/utils/randomizer.h b/src/libstrongswan/utils/randomizer.h deleted file mode 100644 index afbade059..000000000 --- a/src/libstrongswan/utils/randomizer.h +++ /dev/null @@ -1,114 +0,0 @@ -/** - * @file randomizer.h - * - * @brief Interface of randomizer_t. - * - */ - -/* - * 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. - */ - -#ifndef RANDOMIZER_H_ -#define RANDOMIZER_H_ - -typedef struct randomizer_t randomizer_t; - -#include <library.h> - -#ifndef DEV_RANDOM -/** - * Device to read real random bytes - */ -# define DEV_RANDOM "/dev/random" -#endif - -#ifndef DEV_URANDOM -/** - * Device to read pseudo random bytes - */ -# define DEV_URANDOM "/dev/urandom" -#endif - -/** - * @brief Class used to get random and pseudo random values. - * - * @b Constructors: - * - randomizer_create() - * - * @ingroup utils - */ -struct randomizer_t { - - /** - * @brief Reads a specific number of bytes from random device. - * - * @param this calling randomizer_t object - * @param bytes number of bytes to read - * @param[out] buffer pointer to buffer where to write the data in. - * Size of buffer has to be at least bytes. - * @return SUCCESS, or FAILED - */ - status_t (*get_random_bytes) (randomizer_t *this, size_t bytes, u_int8_t *buffer); - - /** - * @brief Allocates space and writes in random bytes. - * - * @param this calling randomizer_t object - * @param bytes number of bytes to allocate - * @param[out] chunk chunk which will hold the allocated random bytes - * @return SUCCESS, or FAILED - */ - status_t (*allocate_random_bytes) (randomizer_t *this, size_t bytes, chunk_t *chunk); - - /** - * @brief Reads a specific number of bytes from pseudo random device. - * - * @param this calling randomizer_t object - * @param bytes number of bytes to read - * @param[out] buffer pointer to buffer where to write the data in. - * size of buffer has to be at least bytes. - * @return SUCCESS, or FAILED - */ - status_t (*get_pseudo_random_bytes) (randomizer_t *this,size_t bytes, u_int8_t *buffer); - - /** - * @brief Allocates space and writes in pseudo random bytes. - * - * @param this calling randomizer_t object - * @param bytes number of bytes to allocate - * @param[out] chunk chunk which will hold the allocated random bytes - * @return SUCCESS, or FAILED - */ - status_t (*allocate_pseudo_random_bytes) (randomizer_t *this, size_t bytes, chunk_t *chunk); - - /** - * @brief Destroys a randomizer_t object. - * - * @param this randomizer_t object to destroy - */ - void (*destroy) (randomizer_t *this); -}; - -/** - * @brief Creates a randomizer_t object. - * - * @return created randomizer_t, or - * - * @ingroup utils - */ -randomizer_t *randomizer_create(void); - -#endif /*RANDOMIZER_H_*/ |