From fc4f8fc30e9b384775f28391c7ded984afeb872d Mon Sep 17 00:00:00 2001 From: Tobias Brunner Date: Thu, 27 Feb 2014 17:00:09 +0100 Subject: [PATCH 01/19] tnc-pdp: Fix monolithic build --- src/libcharon/plugins/tnc_pdp/Makefile.am | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/libcharon/plugins/tnc_pdp/Makefile.am b/src/libcharon/plugins/tnc_pdp/Makefile.am index cc7c934d8..48de82571 100644 --- a/src/libcharon/plugins/tnc_pdp/Makefile.am +++ b/src/libcharon/plugins/tnc_pdp/Makefile.am @@ -15,12 +15,13 @@ if MONOLITHIC noinst_LTLIBRARIES = libstrongswan-tnc-pdp.la else plugin_LTLIBRARIES = libstrongswan-tnc-pdp.la +endif + libstrongswan_tnc_pdp_la_LIBADD = \ $(top_builddir)/src/libradius/libradius.la \ $(top_builddir)/src/libpttls/libpttls.la \ $(top_builddir)/src/libtls/libtls.la \ $(top_builddir)/src/libtnccs/libtnccs.la -endif libstrongswan_tnc_pdp_la_SOURCES = \ tnc_pdp_plugin.h tnc_pdp_plugin.c \ From 48ac56e2aaea6cb1cae15c78644f3cfd4ed74e28 Mon Sep 17 00:00:00 2001 From: Tobias Brunner Date: Thu, 27 Feb 2014 14:07:06 +0100 Subject: [PATCH 02/19] unit-tests: Generate weak keys with gcrypt plugin (but quickly) --- src/libstrongswan/tests/test_runner.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/libstrongswan/tests/test_runner.c b/src/libstrongswan/tests/test_runner.c index 0b26ee128..d1d0a62c6 100644 --- a/src/libstrongswan/tests/test_runner.c +++ b/src/libstrongswan/tests/test_runner.c @@ -185,6 +185,9 @@ static bool pre_test(test_runner_init_t init) "libstrongswan.plugins.random.random", lib->settings->get_str(lib->settings, "libstrongswan.plugins.random.urandom", "/dev/urandom")); + /* same for the gcrypt plugin */ + lib->settings->set_default_str(lib->settings, + "libstrongswan.plugins.gcrypt.quick_random", "yes"); if (lib->leak_detective) { From 1c26ce2dc339c3676f639ad3830935bc0fc36eb4 Mon Sep 17 00:00:00 2001 From: Tobias Brunner Date: Thu, 27 Feb 2014 15:37:01 +0100 Subject: [PATCH 03/19] configure: Reorder and group feature options --- configure.ac | 201 +++++++++++++++++++++++++++------------------------ 1 file changed, 107 insertions(+), 94 deletions(-) diff --git a/configure.ac b/configure.ac index e4d5bc17a..d39dbb4c7 100644 --- a/configure.ac +++ b/configure.ac @@ -118,53 +118,56 @@ AC_SUBST(ipsec_script_upper, [`echo -n "$ipsec_script" | tr a-z A-Z`]) m4_include(m4/macros/enable-disable.m4) -ARG_ENABL_SET([curl], [enable CURL fetcher plugin to fetch files via libcurl. Requires libcurl.]) -ARG_ENABL_SET([unbound], [enable UNBOUND resolver plugin to perform DNS queries via libunbound. Requires libldns and libunbound.]) -ARG_ENABL_SET([soup], [enable soup fetcher plugin to fetch from HTTP via libsoup. Requires libsoup.]) -ARG_ENABL_SET([ldap], [enable LDAP fetching plugin to fetch files via libldap. Requires openLDAP.]) +# crypto plugins ARG_DISBL_SET([aes], [disable AES software implementation plugin.]) -ARG_DISBL_SET([des], [disable DES/3DES software implementation plugin.]) +ARG_ENABL_SET([af-alg], [enable AF_ALG crypto interface to Linux Crypto API.]) ARG_ENABL_SET([blowfish], [enable Blowfish software implementation plugin.]) -ARG_DISBL_SET([rc2], [disable RC2 software implementation plugin.]) +ARG_ENABL_SET([ccm], [enables the CCM AEAD wrapper crypto plugin.]) +ARG_DISBL_SET([cmac], [disable CMAC crypto implementation plugin.]) +ARG_ENABL_SET([ctr], [enables the Counter Mode wrapper crypto plugin.]) +ARG_DISBL_SET([des], [disable DES/3DES software implementation plugin.]) +ARG_DISBL_SET([fips-prf], [disable FIPS PRF software implementation plugin.]) +ARG_ENABL_SET([gcm], [enables the GCM AEAD wrapper crypto plugin.]) +ARG_ENABL_SET([gcrypt], [enables the libgcrypt plugin.]) +ARG_DISBL_SET([gmp], [disable GNU MP (libgmp) based crypto implementation plugin.]) +ARG_DISBL_SET([hmac], [disable HMAC crypto implementation plugin.]) ARG_ENABL_SET([md4], [enable MD4 software implementation plugin.]) ARG_DISBL_SET([md5], [disable MD5 software implementation plugin.]) +ARG_DISBL_SET([nonce], [disable nonce generation plugin.]) +ARG_ENABL_SET([ntru], [enables the NTRU crypto plugin.]) +ARG_ENABL_SET([openssl], [enables the OpenSSL crypto plugin.]) +ARG_ENABL_SET([padlock], [enables VIA Padlock crypto plugin.]) +ARG_DISBL_SET([random], [disable RNG implementation on top of /dev/(u)random.]) +ARG_DISBL_SET([rc2], [disable RC2 software implementation plugin.]) +ARG_ENABL_SET([rdrand], [enable Intel RDRAND random generator plugin.]) ARG_DISBL_SET([sha1], [disable SHA1 software implementation plugin.]) ARG_DISBL_SET([sha2], [disable SHA256/SHA384/SHA512 software implementation plugin.]) -ARG_DISBL_SET([fips-prf], [disable FIPS PRF software implementation plugin.]) -ARG_DISBL_SET([gmp], [disable GNU MP (libgmp) based crypto implementation plugin.]) -ARG_ENABL_SET([rdrand], [enable Intel RDRAND random generator plugin.]) -ARG_DISBL_SET([random], [disable RNG implementation on top of /dev/(u)random.]) -ARG_DISBL_SET([nonce], [disable nonce generation plugin.]) -ARG_DISBL_SET([x509], [disable X509 certificate implementation plugin.]) -ARG_DISBL_SET([revocation], [disable X509 CRL/OCSP revocation check plugin.]) -ARG_DISBL_SET([constraints], [disable advanced X509 constraint checking plugin.]) -ARG_DISBL_SET([pubkey], [disable RAW public key support plugin.]) +ARG_DISBL_SET([xcbc], [disable xcbc crypto implementation plugin.]) +# encoding/decoding plugins +ARG_DISBL_SET([dnskey], [disable DNS RR key decoding plugin.]) +ARG_DISBL_SET([pem], [disable PEM decoding plugin.]) +ARG_DISBL_SET([pgp], [disable PGP key decoding plugin.]) ARG_DISBL_SET([pkcs1], [disable PKCS1 key decoding plugin.]) ARG_DISBL_SET([pkcs7], [disable PKCS7 container support plugin.]) ARG_DISBL_SET([pkcs8], [disable PKCS8 private key decoding plugin.]) ARG_DISBL_SET([pkcs12], [disable PKCS12 container support plugin.]) -ARG_DISBL_SET([pgp], [disable PGP key decoding plugin.]) -ARG_DISBL_SET([dnskey], [disable DNS RR key decoding plugin.]) +ARG_DISBL_SET([pubkey], [disable RAW public key support plugin.]) ARG_DISBL_SET([sshkey], [disable SSH key decoding plugin.]) -ARG_ENABL_SET([dnscert], [enable DNSCERT authentication plugin.]) -ARG_ENABL_SET([ipseckey], [enable IPSECKEY authentication plugin.]) -ARG_DISBL_SET([pem], [disable PEM decoding plugin.]) -ARG_DISBL_SET([hmac], [disable HMAC crypto implementation plugin.]) -ARG_DISBL_SET([cmac], [disable CMAC crypto implementation plugin.]) -ARG_DISBL_SET([xcbc], [disable xcbc crypto implementation plugin.]) -ARG_ENABL_SET([af-alg], [enable AF_ALG crypto interface to Linux Crypto API.]) -ARG_ENABL_SET([test-vectors], [enable plugin providing crypto test vectors.]) +ARG_DISBL_SET([x509], [disable X509 certificate implementation plugin.]) +# fetcher/resolver plugins +ARG_ENABL_SET([curl], [enable CURL fetcher plugin to fetch files via libcurl. Requires libcurl.]) +ARG_ENABL_SET([ldap], [enable LDAP fetching plugin to fetch files via libldap. Requires openLDAP.]) +ARG_ENABL_SET([soup], [enable soup fetcher plugin to fetch from HTTP via libsoup. Requires libsoup.]) +ARG_ENABL_SET([unbound], [enable UNBOUND resolver plugin to perform DNS queries via libunbound. Requires libldns and libunbound.]) +# database plugins ARG_ENABL_SET([mysql], [enable MySQL database support. Requires libmysqlclient_r.]) ARG_ENABL_SET([sqlite], [enable SQLite database support. Requires libsqlite3.]) -ARG_DISBL_SET([stroke], [disable charons stroke configuration backend.]) -ARG_ENABL_SET([medsrv], [enable mediation server web frontend and daemon plugin.]) -ARG_ENABL_SET([medcli], [enable mediation client configuration database plugin.]) -ARG_ENABL_SET([smp], [enable SMP configuration and control interface. Requires libxml.]) -ARG_ENABL_SET([sql], [enable SQL database configuration backend.]) -ARG_ENABL_SET([leak-detective], [enable malloc hooks to find memory leaks.]) -ARG_ENABL_SET([lock-profiler], [enable lock/mutex profiling code.]) -ARG_ENABL_SET([unit-tester], [enable unit tests on IKEv2 daemon startup.]) -ARG_ENABL_SET([load-tester], [enable load testing plugin for IKEv2 daemon.]) +# authentication/credential plugins +ARG_ENABL_SET([addrblock], [enables RFC 3779 address block constraint support.]) +ARG_ENABL_SET([agent], [enables the ssh-agent signing plugin.]) +ARG_DISBL_SET([constraints], [disable advanced X509 constraint checking plugin.]) +ARG_ENABL_SET([coupling], [enable IKEv2 plugin to couple peer certificates permanently to authentication.]) +ARG_ENABL_SET([dnscert], [enable DNSCERT authentication plugin.]) ARG_ENABL_SET([eap-sim], [enable SIM authentication module for EAP.]) ARG_ENABL_SET([eap-sim-file], [enable EAP-SIM backend based on a triplet file.]) ARG_ENABL_SET([eap-sim-pcsc], [enable EAP-SIM backend based on a smartcard reader. Requires libpcsclite.]) @@ -183,17 +186,37 @@ ARG_ENABL_SET([eap-peap], [enable EAP PEAP authentication module.]) ARG_ENABL_SET([eap-tnc], [enable EAP TNC trusted network connect module.]) ARG_ENABL_SET([eap-dynamic], [enable dynamic EAP proxy module.]) ARG_ENABL_SET([eap-radius], [enable RADIUS proxy authentication module.]) +ARG_ENABL_SET([ipseckey], [enable IPSECKEY authentication plugin.]) +ARG_ENABL_SET([keychain], [enables OS X Keychain Services credential set.]) +ARG_ENABL_SET([pkcs11], [enables the PKCS11 token support plugin.]) +ARG_DISBL_SET([revocation], [disable X509 CRL/OCSP revocation check plugin.]) +ARG_ENABL_SET([whitelist], [enable peer identity whitelisting plugin.]) ARG_DISBL_SET([xauth-generic], [disable generic XAuth backend.]) ARG_ENABL_SET([xauth-eap], [enable XAuth backend using EAP methods to verify passwords.]) ARG_ENABL_SET([xauth-pam], [enable XAuth backend using PAM to verify passwords.]) ARG_ENABL_SET([xauth-noauth], [enable XAuth pseudo-backend that does not actually verify or even request any credentials.]) -ARG_ENABL_SET([tnc-ifmap], [enable TNC IF-MAP module. Requires libxml]) -ARG_ENABL_SET([tnc-pdp], [enable TNC policy decision point module.]) -ARG_ENABL_SET([tnc-imc], [enable TNC IMC module.]) -ARG_ENABL_SET([tnc-imv], [enable TNC IMV module.]) -ARG_ENABL_SET([tnccs-11], [enable TNCCS 1.1 protocol module. Requires libxml]) -ARG_ENABL_SET([tnccs-20], [enable TNCCS 2.0 protocol module.]) -ARG_ENABL_SET([tnccs-dynamic], [enable dynamic TNCCS protocol discovery module.]) +# kernel interfaces / sockets +ARG_DISBL_SET([kernel-netlink], [disable the netlink kernel interface.]) +ARG_ENABL_SET([kernel-pfkey], [enable the PF_KEY kernel interface.]) +ARG_ENABL_SET([kernel-pfroute], [enable the PF_ROUTE kernel interface.]) +ARG_ENABL_SET([kernel-klips], [enable the KLIPS kernel interface.]) +ARG_ENABL_SET([kernel-libipsec],[enable the libipsec kernel interface.]) +ARG_DISBL_SET([socket-default], [disable default socket implementation for charon.]) +ARG_ENABL_SET([socket-dynamic], [enable dynamic socket implementation for charon]) +# configuration/control plugins +ARG_DISBL_SET([stroke], [disable charons stroke configuration backend.]) +ARG_ENABL_SET([smp], [enable SMP configuration and control interface. Requires libxml.]) +ARG_ENABL_SET([sql], [enable SQL database configuration backend.]) +ARG_ENABL_SET([uci], [enable OpenWRT UCI configuration plugin.]) +# attribute provider/consumer plugins +ARG_ENABL_SET([android-dns], [enable Android specific DNS handler.]) +ARG_DISBL_SET([attr], [disable strongswan.conf based configuration attribute plugin.]) +ARG_ENABL_SET([attr-sql], [enable SQL based configuration attribute plugin.]) +ARG_ENABL_SET([dhcp], [enable DHCP based attribute provider plugin.]) +ARG_ENABL_SET([osx-attr], [enable OS X SystemConfiguration attribute handler.]) +ARG_DISBL_SET([resolve], [disable resolve DNS handler plugin.]) +ARG_ENABL_SET([unity], [enables Cisco Unity extension plugin.]) +# TNC modules/plugins ARG_ENABL_SET([imc-test], [enable IMC test module.]) ARG_ENABL_SET([imv-test], [enable IMV test module.]) ARG_ENABL_SET([imc-scanner], [enable IMC port scanner module.]) @@ -204,67 +227,57 @@ ARG_ENABL_SET([imc-attestation],[enable IMC attestation module.]) ARG_ENABL_SET([imv-attestation],[enable IMV attestation module.]) ARG_ENABL_SET([imc-swid], [enable IMC swid module.]) ARG_ENABL_SET([imv-swid], [enable IMV swid module.]) -ARG_DISBL_SET([kernel-netlink], [disable the netlink kernel interface.]) -ARG_ENABL_SET([kernel-pfkey], [enable the PF_KEY kernel interface.]) -ARG_ENABL_SET([kernel-pfroute], [enable the PF_ROUTE kernel interface.]) -ARG_ENABL_SET([kernel-klips], [enable the KLIPS kernel interface.]) -ARG_ENABL_SET([kernel-libipsec],[enable the libipsec kernel interface.]) -ARG_ENABL_SET([libipsec], [enable user space IPsec implementation.]) -ARG_DISBL_SET([socket-default], [disable default socket implementation for charon.]) -ARG_ENABL_SET([socket-dynamic], [enable dynamic socket implementation for charon]) +ARG_ENABL_SET([tnc-ifmap], [enable TNC IF-MAP module. Requires libxml]) +ARG_ENABL_SET([tnc-imc], [enable TNC IMC module.]) +ARG_ENABL_SET([tnc-imv], [enable TNC IMV module.]) +ARG_ENABL_SET([tnc-pdp], [enable TNC policy decision point module.]) +ARG_ENABL_SET([tnccs-11], [enable TNCCS 1.1 protocol module. Requires libxml]) +ARG_ENABL_SET([tnccs-20], [enable TNCCS 2.0 protocol module.]) +ARG_ENABL_SET([tnccs-dynamic], [enable dynamic TNCCS protocol discovery module.]) +# misc plugins +ARG_ENABL_SET([android-log], [enable Android specific logger plugin.]) +ARG_ENABL_SET([certexpire], [enable CSV export of expiration dates of used certificates.]) +ARG_ENABL_SET([duplicheck], [advanced duplicate checking plugin using liveness checks.]) +ARG_ENABL_SET([error-notify], [enable error notification plugin.]) ARG_ENABL_SET([farp], [enable ARP faking plugin that responds to ARP requests to peers virtual IP]) +ARG_ENABL_SET([ha], [enable high availability cluster plugin.]) +ARG_ENABL_SET([led], [enable plugin to control LEDs on IKEv2 activity using the Linux kernel LED subsystem.]) +ARG_ENABL_SET([load-tester], [enable load testing plugin for IKEv2 daemon.]) +ARG_ENABL_SET([lookip], [enable fast virtual IP lookup and notification plugin.]) +ARG_ENABL_SET([maemo], [enable Maemo specific plugin.]) +ARG_ENABL_SET([radattr], [enable plugin to inject and process custom RADIUS attributes as IKEv2 client.]) +ARG_ENABL_SET([systime-fix], [enable plugin to handle cert lifetimes with invalid system time gracefully.]) +ARG_ENABL_SET([test-vectors], [enable plugin providing crypto test vectors.]) +ARG_ENABL_SET([unit-tester], [enable unit tests on IKEv2 daemon startup.]) +ARG_DISBL_SET([updown], [disable updown firewall script plugin.]) +# programs/components +ARG_DISBL_SET([charon], [disable the IKEv1/IKEv2 keying daemon charon.]) +ARG_ENABL_SET([cmd], [enable the command line IKE client charon-cmd.]) +ARG_ENABL_SET([conftest], [enforce Suite B conformance test framework.]) ARG_ENABL_SET([dumm], [enable the DUMM UML test framework.]) ARG_ENABL_SET([fast], [enable libfast (FastCGI Application Server w/ templates.]) +ARG_ENABL_SET([libipsec], [enable user space IPsec implementation.]) ARG_ENABL_SET([manager], [enable web management console (proof of concept).]) -ARG_ENABL_SET([mediation], [enable IKEv2 Mediation Extension.]) -ARG_ENABL_SET([integrity-test], [enable integrity testing of libstrongswan and plugins.]) -ARG_DISBL_SET([load-warning], [disable the charon plugin load option warning in starter.]) +ARG_ENABL_SET([medcli], [enable mediation client configuration database plugin.]) +ARG_ENABL_SET([medsrv], [enable mediation server web frontend and daemon plugin.]) +ARG_ENABL_SET([nm], [enable NetworkManager backend.]) +ARG_DISBL_SET([scripts], [disable additional utilities (found in directory scripts).]) +ARG_ENABL_SET([tkm], [enable Trusted Key Manager support.]) +ARG_DISBL_SET([tools], [disable additional utilities (openac, scepclient and pki).]) +# optional features +ARG_ENABL_SET([bfd-backtraces], [use binutils libbfd to resolve backtraces for memory leaks and segfaults.]) ARG_DISBL_SET([ikev1], [disable IKEv1 protocol support in charon.]) ARG_DISBL_SET([ikev2], [disable IKEv2 protocol support in charon.]) -ARG_DISBL_SET([charon], [disable the IKEv1/IKEv2 keying daemon charon.]) -ARG_DISBL_SET([tools], [disable additional utilities (openac, scepclient and pki).]) -ARG_DISBL_SET([scripts], [disable additional utilities (found in directory scripts).]) -ARG_ENABL_SET([conftest], [enforce Suite B conformance test framework.]) -ARG_DISBL_SET([updown], [disable updown firewall script plugin.]) -ARG_DISBL_SET([attr], [disable strongswan.conf based configuration attribute plugin.]) -ARG_ENABL_SET([attr-sql], [enable SQL based configuration attribute plugin.]) -ARG_ENABL_SET([dhcp], [enable DHCP based attribute provider plugin.]) -ARG_DISBL_SET([resolve], [disable resolve DNS handler plugin.]) -ARG_ENABL_SET([padlock], [enables VIA Padlock crypto plugin.]) -ARG_ENABL_SET([openssl], [enables the OpenSSL crypto plugin.]) -ARG_ENABL_SET([gcrypt], [enables the libgcrypt plugin.]) -ARG_ENABL_SET([agent], [enables the ssh-agent signing plugin.]) -ARG_ENABL_SET([keychain], [enables OS X Keychain Services credential set.]) -ARG_ENABL_SET([pkcs11], [enables the PKCS11 token support plugin.]) -ARG_ENABL_SET([ctr], [enables the Counter Mode wrapper crypto plugin.]) -ARG_ENABL_SET([ccm], [enables the CCM AEAD wrapper crypto plugin.]) -ARG_ENABL_SET([gcm], [enables the GCM AEAD wrapper crypto plugin.]) -ARG_ENABL_SET([ntru], [enables the NTRU crypto plugin.]) -ARG_ENABL_SET([addrblock], [enables RFC 3779 address block constraint support.]) -ARG_ENABL_SET([unity], [enables Cisco Unity extension plugin.]) -ARG_ENABL_SET([uci], [enable OpenWRT UCI configuration plugin.]) -ARG_ENABL_SET([osx-attr], [enable OS X SystemConfiguration attribute handler.]) -ARG_ENABL_SET([android-dns], [enable Android specific DNS handler.]) -ARG_ENABL_SET([android-log], [enable Android specific logger plugin.]) -ARG_ENABL_SET([maemo], [enable Maemo specific plugin.]) -ARG_ENABL_SET([nm], [enable NetworkManager backend.]) -ARG_ENABL_SET([ha], [enable high availability cluster plugin.]) -ARG_ENABL_SET([whitelist], [enable peer identity whitelisting plugin.]) -ARG_ENABL_SET([lookip], [enable fast virtual IP lookup and notification plugin.]) -ARG_ENABL_SET([error-notify], [enable error notification plugin.]) -ARG_ENABL_SET([certexpire], [enable CSV export of expiration dates of used certificates.]) -ARG_ENABL_SET([systime-fix], [enable plugin to handle cert lifetimes with invalid system time gracefully.]) -ARG_ENABL_SET([led], [enable plugin to control LEDs on IKEv2 activity using the Linux kernel LED subsystem.]) -ARG_ENABL_SET([duplicheck], [advanced duplicate checking plugin using liveness checks.]) -ARG_ENABL_SET([coupling], [enable IKEv2 plugin to couple peer certificates permanently to authentication.]) -ARG_ENABL_SET([radattr], [enable plugin to inject and process custom RADIUS attributes as IKEv2 client.]) -ARG_ENABL_SET([vstr], [enforce using the Vstr string library to replace glibc-like printf hooks.]) -ARG_ENABL_SET([monolithic], [build monolithic version of libstrongswan that includes all enabled plugins. Similarly, the plugins of charon are assembled in libcharon.]) -ARG_ENABL_SET([bfd-backtraces], [use binutils libbfd to resolve backtraces for memory leaks and segfaults.]) +ARG_ENABL_SET([integrity-test], [enable integrity testing of libstrongswan and plugins.]) +ARG_DISBL_SET([load-warning], [disable the charon plugin load option warning in starter.]) +ARG_ENABL_SET([mediation], [enable IKEv2 Mediation Extension.]) ARG_ENABL_SET([unwind-backtraces],[use libunwind to create backtraces for memory leaks and segfaults.]) +ARG_ENABL_SET([vstr], [enforce using the Vstr string library to replace glibc-like printf hooks.]) +# compile options ARG_ENABL_SET([coverage], [enable lcov coverage report generation.]) -ARG_ENABL_SET([tkm], [enable Trusted Key Manager support.]) -ARG_ENABL_SET([cmd], [enable the command line IKE client charon-cmd.]) +ARG_ENABL_SET([leak-detective], [enable malloc hooks to find memory leaks.]) +ARG_ENABL_SET([lock-profiler], [enable lock/mutex profiling code.]) +ARG_ENABL_SET([monolithic], [build monolithic version of libstrongswan that includes all enabled plugins. Similarly, the plugins of charon are assembled in libcharon.]) # =================================== # option to disable default options From 0e6f3a380ae96877b46a9b420ecf70a6aa86f4c5 Mon Sep 17 00:00:00 2001 From: Tobias Brunner Date: Thu, 27 Feb 2014 16:28:00 +0100 Subject: [PATCH 04/19] configure: Add an option to enable all optional features/plugins This has probably no real practical use, but it simplifies testing. --- configure.ac | 15 ++++++++++++++- m4/macros/enable-disable.m4 | 4 +++- 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/configure.ac b/configure.ac index d39dbb4c7..b6a5e0148 100644 --- a/configure.ac +++ b/configure.ac @@ -288,7 +288,20 @@ ARG_DISBL_SET([defaults], [disable all default plugins (they can be enable if test x$defaults = xfalse; then for option in $enabled_by_default; do eval test x\${${option}_given} = xtrue && continue - let $option=false + eval $option=false + done +fi + +# ============================== +# option to enable all options +# ============================== + +ARG_ENABL_SET([all], [enable all plugins and features (they can be disabled with their respective --disable options). Mainly for testing.]) + +if test x$all_given = xtrue; then + for option in $disabled_by_default; do + eval test x\${${option}_given} = xtrue && continue + eval $option=true done fi diff --git a/m4/macros/enable-disable.m4 b/m4/macros/enable-disable.m4 index 2e4552068..9d51cb9b2 100644 --- a/m4/macros/enable-disable.m4 +++ b/m4/macros/enable-disable.m4 @@ -2,6 +2,7 @@ # ARG_ENABL_SET(option, help) # --------------------------- # Create a --enable-$1 option with helptext, set a variable $1 to true/false +# All $1 are collected in the variable $disabled_by_default AC_DEFUN([ARG_ENABL_SET], [AC_ARG_ENABLE( [$1], @@ -14,7 +15,8 @@ AC_DEFUN([ARG_ENABL_SET], fi], [patsubst([$1], [-], [_])=false patsubst([$1], [-], [_])_given=false] - )] + ) + disabled_by_default=${disabled_by_default}" patsubst([$1], [-], [_])"] ) # ARG_DISBL_SET(option, help) From d151cd283e1f7368f4c9e92665b6aad6efbc38f1 Mon Sep 17 00:00:00 2001 From: Tobias Brunner Date: Wed, 26 Feb 2014 17:49:07 +0100 Subject: [PATCH 05/19] Add Travis CI config and build script --- .travis.yml | 38 ++++++++++++++++++++++++++++++++++++++ scripts/test.sh | 49 +++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 87 insertions(+) create mode 100644 .travis.yml create mode 100755 scripts/test.sh diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 000000000..c5812b524 --- /dev/null +++ b/.travis.yml @@ -0,0 +1,38 @@ +language: c + +compiler: + - gcc + +before_install: + - sudo apt-get update -qq + - sudo apt-get install -qq bison flex gperf gettext + # TODO: modularize this to speed up builds (e.g. call 'test.sh deps' to do this for the current TEST) + - sudo apt-get install -qq libgmp-dev libssl-dev libgcrypt11-dev + - sudo apt-get install -qq libcurl4-gnutls-dev libsoup2.4-dev + - sudo apt-get install -qq libunbound-dev libldns-dev + - sudo apt-get install -qq libmysqlclient-dev libsqlite3-dev + - sudo apt-get install -qq clearsilver-dev libfcgi-dev + - sudo apt-get install -qq libnm-glib-dev libnm-glib-vpn-dev + - sudo apt-get install -qq libpcsclite-dev libpam0g-dev + - sudo apt-get install -qq binutils-dev libunwind7-dev + +script: + - ./autogen.sh + - ./scripts/test.sh + +env: + global: + - TESTS_REDUCED_KEYLENGTHS=yes + - LEAK_DETECTIVE=no + - MONOLITHIC=no + matrix: + - TEST=default + - TEST=default MONOLITHIC=yes + - TEST=default LEAK_DETECTIVE=yes + - TEST=openssl + - TEST=openssl LEAK_DETECTIVE=yes + # libgcrypt can't be deinitialized so we can't test it with leak detective + - TEST=gcrypt + - TEST=all + - TEST=all MONOLITHIC=yes + - TEST=dist diff --git a/scripts/test.sh b/scripts/test.sh new file mode 100755 index 000000000..9b38c1136 --- /dev/null +++ b/scripts/test.sh @@ -0,0 +1,49 @@ +#!/bin/sh +# Build script for Travis CI + +if test -z $TRAVIS_BUILD_DIR; then + TRAVIS_BUILD_DIR=$PWD +fi + +cd $TRAVIS_BUILD_DIR + +TARGET=check + +case "$TEST" in +default) + ;; +openssl) + CONFIG="--disable-defaults --enable-tools --enable-openssl" + ;; +gcrypt) + CONFIG="--disable-defaults --enable-tools --enable-gcrypt --enable-pkcs1" + ;; +all) + CONFIG="--enable-all --disable-android-dns --disable-android-log + --disable-dumm --disable-kernel-pfroute --disable-keychain + --disable-lock-profiler --disable-maemo --disable-padlock + --disable-osx-attr --disable-tkm --disable-uci" + # not enabled on the build server + CONFIG="$CONFIG --disable-af-alg" + # TODO: add tests for different printf implementations? + CONFIG="$CONFIG --disable-vstr" + # TODO: enable? perhaps via coveralls.io (cpp-coveralls)? + CONFIG="$CONFIG --disable-coverage" + ;; +dist) + TARGET=distcheck + ;; +*) + echo "$0: unknown test $TEST" >&2 + exit 1 + ;; +esac + +CONFIG="$CONFIG + --enable-silent-rules + --enable-test-vectors + --enable-monolithic=${MONOLITHIC-no} + --enable-leak-detective=${LEAK_DETECTIVE-no}" + +echo "$ ./configure $CONFIG && make $TARGET" +./configure $CONFIG && make $TARGET From f51169eb095304039e770b779ee0b9a8484f6b02 Mon Sep 17 00:00:00 2001 From: Tobias Brunner Date: Fri, 28 Feb 2014 17:08:39 +0100 Subject: [PATCH 06/19] unit-tests: Change how hashtable for testable functions is created Because GCC does not adhere to the priorities defined for constructors when building with --enable-monolithic (not sure if it was just luck that it worked in non-monolithic mode - anyway, it's not very portable) function registration would fail because the hashtable would not be created yet. --- src/libstrongswan/tests/test_runner.c | 22 ++++++----- src/libstrongswan/utils/test.c | 53 ++++++++++++++++++--------- src/libstrongswan/utils/test.h | 2 +- 3 files changed, 49 insertions(+), 28 deletions(-) diff --git a/src/libstrongswan/tests/test_runner.c b/src/libstrongswan/tests/test_runner.c index d1d0a62c6..dc6fcf3dd 100644 --- a/src/libstrongswan/tests/test_runner.c +++ b/src/libstrongswan/tests/test_runner.c @@ -32,26 +32,30 @@ #define TTY(color) tty_escape_get(2, TTY_FG_##color) /** - * Initialize the lookup table for testable functions (defined in libstrongswan) + * Initialize the lookup table for testable functions (defined in + * libstrongswan). We don't use the constructor attribute as the order can't + * really be defined (clang does not support it and gcc does not adhere to it in + * the monolithic build). The function here is a weak symbol in libstrongswan. */ -static void testable_functions_create() __attribute__ ((constructor(1000))); -static void testable_functions_create() +void testable_functions_create() { - testable_functions = hashtable_create(hashtable_hash_str, - hashtable_equals_str, 8); + if (!testable_functions) + { + testable_functions = hashtable_create(hashtable_hash_str, + hashtable_equals_str, 8); + } } /** * Destroy the lookup table for testable functions */ -static void testable_functions_destroy() __attribute__ ((destructor(1000))); +static void testable_functions_destroy() __attribute__ ((destructor)); static void testable_functions_destroy() { - testable_functions->destroy(testable_functions); + DESTROY_IF(testable_functions); /* if leak detective is enabled plugins are not actually unloaded, which * means their destructor is called AFTER this one when the process - * terminates, even though the priority says differently, make sure this - * does not crash */ + * terminates, make sure this does not crash */ testable_functions = NULL; } diff --git a/src/libstrongswan/utils/test.c b/src/libstrongswan/utils/test.c index 7de5a7661..624ac4b34 100644 --- a/src/libstrongswan/utils/test.c +++ b/src/libstrongswan/utils/test.c @@ -22,29 +22,46 @@ */ hashtable_t *testable_functions; +/** + * The function that actually initializes the hash table above. Provided + * by the test runner. + */ +void testable_functions_create() __attribute__((weak)); + /* * Described in header. */ void testable_function_register(char *name, void *fn) { - if (testable_functions) + bool old = FALSE; + + if (!testable_functions_create) + { /* not linked to the test runner */ + return; + } + else if (!fn && !testable_functions) + { /* ignore as testable_functions has already been destroyed */ + return; + } + + if (lib && lib->leak_detective) { - bool old = FALSE; - if (lib->leak_detective) - { - old = lib->leak_detective->set_state(lib->leak_detective, FALSE); - } - if (fn) - { - testable_functions->put(testable_functions, name, fn); - } - else - { - testable_functions->remove(testable_functions, name); - } - if (lib->leak_detective) - { - lib->leak_detective->set_state(lib->leak_detective, old); - } + old = lib->leak_detective->set_state(lib->leak_detective, FALSE); + } + if (!testable_functions) + { + testable_functions_create(); + } + if (fn) + { + testable_functions->put(testable_functions, name, fn); + } + else + { + testable_functions->remove(testable_functions, name); + } + if (lib && lib->leak_detective) + { + lib->leak_detective->set_state(lib->leak_detective, old); } } diff --git a/src/libstrongswan/utils/test.h b/src/libstrongswan/utils/test.h index 5b7289244..b43a92b1f 100644 --- a/src/libstrongswan/utils/test.h +++ b/src/libstrongswan/utils/test.h @@ -51,7 +51,7 @@ void testable_function_register(char *name, void *fn); * @param fn function to register */ #define EXPORT_FUNCTION_FOR_TESTS(ns, fn) \ -static void testable_function_register_##fn() __attribute__ ((constructor(2000))); \ +static void testable_function_register_##fn() __attribute__ ((constructor)); \ static void testable_function_register_##fn() \ { \ testable_function_register(#ns "/" #fn, fn); \ From 2c687b3cb3fe15fd2cd9f39025075c469f416e70 Mon Sep 17 00:00:00 2001 From: Tobias Brunner Date: Fri, 28 Feb 2014 17:13:33 +0100 Subject: [PATCH 07/19] unit-tests: Prefix imported testable functions with TEST_ This avoids any clashes with existing functions in the monolithic build. --- src/libstrongswan/utils/test.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/libstrongswan/utils/test.h b/src/libstrongswan/utils/test.h index b43a92b1f..38887946d 100644 --- a/src/libstrongswan/utils/test.h +++ b/src/libstrongswan/utils/test.h @@ -65,8 +65,8 @@ static void testable_function_unregister_##fn() \ /** * Import a registered function so that it can be called from tests. * - * @note If the imported function is static (or no conflicting header files - * are included) ret can be prefixed with static to declare the function static. + * The function name is prefixed with TEST_ to avoid clashes when building + * monolithically. * * @note We allocate an arbitrary amount of stack space, hopefully enough for * all arguments. @@ -77,7 +77,7 @@ static void testable_function_unregister_##fn() \ * @param ... arguments of the function */ #define IMPORT_FUNCTION_FOR_TESTS(ns, name, ret, ...) \ -ret name(__VA_ARGS__) \ +static ret TEST_##name(__VA_ARGS__) \ { \ void (*fn)() = NULL; \ if (testable_functions) \ From 31b3bb2211cac3eb685f083aa9003d7bf6e16bab Mon Sep 17 00:00:00 2001 From: Tobias Brunner Date: Fri, 28 Feb 2014 17:15:47 +0100 Subject: [PATCH 08/19] unit-tests: Call functions with TEST_ prefix in ntru test --- src/libstrongswan/tests/suites/test_ntru.c | 74 +++++++++++----------- 1 file changed, 38 insertions(+), 36 deletions(-) diff --git a/src/libstrongswan/tests/suites/test_ntru.c b/src/libstrongswan/tests/suites/test_ntru.c index 3204c89a8..8c17fdfde 100644 --- a/src/libstrongswan/tests/suites/test_ntru.c +++ b/src/libstrongswan/tests/suites/test_ntru.c @@ -94,7 +94,7 @@ START_TEST(test_ntru_drbg_strength) entropy = lib->crypto->create_rng(lib->crypto, RNG_STRONG); ck_assert(entropy != NULL); - drbg = ntru_drbg_create(strengths[_i].requested, chunk_empty, entropy); + drbg = TEST_ntru_drbg_create(strengths[_i].requested, chunk_empty, entropy); if (strengths[_i].standard) { ck_assert(drbg != NULL); @@ -251,7 +251,7 @@ START_TEST(test_ntru_drbg) out = chunk_alloc(128); entropy = test_rng_create(drbg_tests[_i].entropy); - drbg = ntru_drbg_create(256, drbg_tests[_i].pers_str, entropy); + drbg = TEST_ntru_drbg_create(256, drbg_tests[_i].pers_str, entropy); ck_assert(drbg != NULL); ck_assert(drbg->reseed(drbg)); ck_assert(drbg->generate(drbg, 256, 128, out.ptr)); @@ -273,7 +273,7 @@ START_TEST(test_ntru_drbg_reseed) "libstrongswan.plugins.ntru.max_drbg_requests", 2); out = chunk_alloc(128); entropy = test_rng_create(drbg_tests[0].entropy); - drbg = ntru_drbg_create(256, chunk_empty, entropy); + drbg = TEST_ntru_drbg_create(256, chunk_empty, entropy); /* bad output parameters */ ck_assert(!drbg->generate(drbg, 256, 0, out.ptr)); @@ -291,13 +291,13 @@ START_TEST(test_ntru_drbg_reseed) drbg->destroy(drbg); /* no entropy available for DRBG instantiation */ - drbg = ntru_drbg_create(256, chunk_empty, entropy); + drbg = TEST_ntru_drbg_create(256, chunk_empty, entropy); ck_assert(drbg == NULL); entropy->destroy(entropy); /* one automatic reseeding occurs */ entropy = test_rng_create(drbg_tests[0].entropy); - drbg = ntru_drbg_create(256, chunk_empty, entropy); + drbg = TEST_ntru_drbg_create(256, chunk_empty, entropy); ck_assert(drbg->generate(drbg, 256, 128, out.ptr)); ck_assert(drbg->generate(drbg, 256, 128, out.ptr)); ck_assert(drbg->generate(drbg, 256, 128, out.ptr)); @@ -382,7 +382,7 @@ uint16_t indices_ees1171ep1[] = { */ mgf1_test_t mgf1_tests[] = { { HASH_SHA1, 20, 60, 20, 15, 24, - chunk_from_chars( + chunk_from_chars( 0xED, 0xA5, 0xC3, 0xBC, 0xAF, 0xB3, 0x20, 0x7D, 0x14, 0xA1, 0x54, 0xF7, 0x8B, 0x37, 0xF2, 0x8D, 0x8C, 0x9B, 0xD5, 0x63, 0x57, 0x38, 0x11, 0xC2, @@ -416,7 +416,7 @@ mgf1_test_t mgf1_tests[] = { 0x40, 0x4B, 0xE7, 0x22, 0x3A, 0x56, 0x10, 0x6D, 0x4D, 0x29, 0x0B, 0xCE, 0xA6, 0x21, 0xB5, 0x5C, 0x71, 0x66, 0x2F, 0x70, 0x35, 0xD8, 0x8A, 0x92, - 0x33, 0xF0, 0x16, 0xD4, 0x0E, 0x43, 0x8A, 0x14), + 0x33, 0xF0, 0x16, 0xD4, 0x0E, 0x43, 0x8A, 0x14), chunk_from_chars( 1, 2, 1, 0, 0, 1, 1, 1, 2, 0, 1, 0, 1, 1, 1, 0, 2, 0, 1, 1, 0, 0, 0, 1, 1, 0, 2, 0, 2, 2, 1, 2, 2, 2, 1, 2, 1, 1, 0, 0, @@ -474,7 +474,7 @@ mgf1_test_t mgf1_tests[] = { 0x76, 0x89, 0x8B, 0x1B, 0x60, 0xEC, 0x10, 0x9D, 0x8F, 0x13, 0xF2, 0xFE, 0xD9, 0x85, 0xC1, 0xAB, 0x7E, 0xEE, 0xB1, 0x31, 0xDD, 0xF7, 0x7F, 0x0C, - 0x7D, 0xF9, 0x6B, 0x7B, 0x19, 0x80, 0xBD, 0x28), + 0x7D, 0xF9, 0x6B, 0x7B, 0x19, 0x80, 0xBD, 0x28), chunk_from_chars( 0xF1, 0x19, 0x02, 0x4F, 0xDA, 0x58, 0x05, 0x9A, 0x07, 0xDF, 0x61, 0x81, 0x22, 0x0E, 0x15, 0x46, @@ -550,14 +550,14 @@ START_TEST(test_ntru_mgf1) mask2.len = mgf1_tests[_i].ml2; mask3.len = mgf1_tests[_i].ml3; - mgf1 = ntru_mgf1_create(HASH_UNKNOWN, mgf1_tests[_i].seed, TRUE); + mgf1 = TEST_ntru_mgf1_create(HASH_UNKNOWN, mgf1_tests[_i].seed, TRUE); ck_assert(mgf1 == NULL); - mgf1 = ntru_mgf1_create(mgf1_tests[_i].alg, chunk_empty, TRUE); + mgf1 = TEST_ntru_mgf1_create(mgf1_tests[_i].alg, chunk_empty, TRUE); ck_assert(mgf1 == NULL); /* return mask in allocated chunk */ - mgf1 = ntru_mgf1_create(mgf1_tests[_i].alg, mgf1_tests[_i].seed, TRUE); + mgf1 = TEST_ntru_mgf1_create(mgf1_tests[_i].alg, mgf1_tests[_i].seed, TRUE); ck_assert(mgf1); /* check hash size */ @@ -573,14 +573,15 @@ START_TEST(test_ntru_mgf1) mgf1->destroy(mgf1); /* copy mask to pre-allocated buffer */ - mgf1 = ntru_mgf1_create(mgf1_tests[_i].alg, mgf1_tests[_i].seed, TRUE); + mgf1 = TEST_ntru_mgf1_create(mgf1_tests[_i].alg, mgf1_tests[_i].seed, TRUE); ck_assert(mgf1); ck_assert(mgf1->get_mask(mgf1, mgf1_tests[_i].mask.len, mask.ptr)); ck_assert(chunk_equals(mask, mgf1_tests[_i].mask)); mgf1->destroy(mgf1); /* get mask in batches without hashing the seed */ - mgf1 = ntru_mgf1_create(mgf1_tests[_i].alg, mgf1_tests[_i].hashed_seed, FALSE); + mgf1 = TEST_ntru_mgf1_create(mgf1_tests[_i].alg, mgf1_tests[_i].hashed_seed, + FALSE); ck_assert(mgf1); /* first batch */ @@ -608,16 +609,16 @@ START_TEST(test_ntru_trits) ntru_trits_t *mask; chunk_t trits; - mask = ntru_trits_create(mgf1_tests[_i].trits.len, HASH_UNKNOWN, - mgf1_tests[_i].seed); + mask = TEST_ntru_trits_create(mgf1_tests[_i].trits.len, HASH_UNKNOWN, + mgf1_tests[_i].seed); ck_assert(mask == NULL); - mask = ntru_trits_create(mgf1_tests[_i].trits.len, mgf1_tests[_i].alg, - chunk_empty); + mask = TEST_ntru_trits_create(mgf1_tests[_i].trits.len, mgf1_tests[_i].alg, + chunk_empty); ck_assert(mask == NULL); - mask = ntru_trits_create(mgf1_tests[_i].trits.len, mgf1_tests[_i].alg, - mgf1_tests[_i].seed); + mask = TEST_ntru_trits_create(mgf1_tests[_i].trits.len, mgf1_tests[_i].alg, + mgf1_tests[_i].seed); ck_assert(mask); trits = chunk_create(mask->get_trits(mask), mask->get_size(mask)); @@ -625,7 +626,7 @@ START_TEST(test_ntru_trits) mask->destroy(mask); /* generate a multiple of 5 trits */ - mask = ntru_trits_create(10, mgf1_tests[_i].alg, mgf1_tests[_i].seed); + mask = TEST_ntru_trits_create(10, mgf1_tests[_i].alg, mgf1_tests[_i].seed); ck_assert(mask); trits = chunk_create(mask->get_trits(mask), mask->get_size(mask)); @@ -646,17 +647,17 @@ START_TEST(test_ntru_poly) seed.len = mgf1_tests[_i].seed_len; p = &mgf1_tests[_i].poly_test[0]; - poly = ntru_poly_create_from_seed(HASH_UNKNOWN, seed, p->c_bits, p->N, p->q, - p->indices_len, p->indices_len, - p->is_product_form); + poly = TEST_ntru_poly_create_from_seed(HASH_UNKNOWN, seed, p->c_bits, p->N, + p->q, p->indices_len, p->indices_len, + p->is_product_form); ck_assert(poly == NULL); for (n = 0; n < 2; n++) { p = &mgf1_tests[_i].poly_test[n]; - poly = ntru_poly_create_from_seed(mgf1_tests[_i].alg, seed, p->c_bits, - p->N, p->q, p->indices_len, - p->indices_len, p->is_product_form); + poly = TEST_ntru_poly_create_from_seed(mgf1_tests[_i].alg, seed, + p->c_bits, p->N, p->q, p->indices_len, + p->indices_len, p->is_product_form); ck_assert(poly != NULL && poly->get_size(poly) == p->indices_size); indices = poly->get_indices(poly); @@ -756,8 +757,8 @@ START_TEST(test_ntru_ring_mult) int i; t = &ring_mult_tests[_i]; - poly = ntru_poly_create_from_data(t->indices, t->N, t->q, t->indices_len_p, - t->indices_len_m, t->is_product_form); + poly = TEST_ntru_poly_create_from_data(t->indices, t->N, t->q, + t->indices_len_p, t->indices_len_m, t->is_product_form); ck_assert(poly != NULL); c = malloc(t->N * sizeof(uint16_t)); @@ -784,8 +785,8 @@ START_TEST(test_ntru_array) t = &ring_mult_tests[array_tests[_i]]; - poly = ntru_poly_create_from_data(t->indices, t->N, t->q, t->indices_len_p, - t->indices_len_m, t->is_product_form); + poly = TEST_ntru_poly_create_from_data(t->indices, t->N, t->q, + t->indices_len_p, t->indices_len_m, t->is_product_form); ck_assert(poly != NULL); c = malloc(t->N * sizeof(uint16_t)); @@ -803,8 +804,8 @@ END_TEST START_TEST(test_ntru_param_set) { - ck_assert(ntru_param_set_get_by_id(-1) == NULL); - ck_assert(ntru_param_set_get_by_id(16) == NULL); + ck_assert(TEST_ntru_param_set_get_by_id(-1) == NULL); + ck_assert(TEST_ntru_param_set_get_by_id(16) == NULL); } END_TEST @@ -964,7 +965,7 @@ privkey_test_t privkey_tests[] = { 0xB1, 0x6D, 0x88, 0x41, 0x62, 0x4D, 0x18, 0xB6, 0x3F, 0x12, 0x81, 0xDE, 0xE6, 0xDC, 0x4A, 0x31, 0x61, 0x26, 0xB1, 0x4B, 0x95, 0xC1, 0x69, 0xDC, - 0xDC, 0xAC, 0xD0, 0x15, 0xFC, 0x21, 0xC5, 0x20, + 0xDC, 0xAC, 0xD0, 0x15, 0xFC, 0x21, 0xC5, 0x20, 0x5F, 0x97, 0x76, 0x41, 0xC1, 0xF2, 0xD7, 0x95, 0x1D, 0x25, 0x23, 0x36, 0x86, 0xFA, 0x7E, 0xF4, 0x14, 0x9F, 0x9D, 0x9F, 0xB2, 0xBB, 0x25, 0x1D, @@ -1066,13 +1067,14 @@ START_TEST(test_ntru_privkey) uint32_t strength; chunk_t encoding, privkey_encoding, pubkey_encoding; - params = ntru_param_set_get_by_id(privkey_tests[_i].id); + params = TEST_ntru_param_set_get_by_id(privkey_tests[_i].id); strength = params->sec_strength_len * BITS_PER_BYTE; entropy = test_rng_create(privkey_tests[_i].entropy); - drbg = ntru_drbg_create(strength, chunk_from_str("IKE NTRU-KE"), entropy); + drbg = TEST_ntru_drbg_create(strength, chunk_from_str("IKE NTRU-KE"), + entropy); ck_assert(drbg != NULL); - privkey = ntru_private_key_create(drbg, params); + privkey = TEST_ntru_private_key_create(drbg, params); ck_assert(privkey); privkey_encoding = privkey->get_encoding(privkey); From b751f6f25a176cd773fbe73f7739f24cb2745d4f Mon Sep 17 00:00:00 2001 From: Tobias Brunner Date: Sat, 1 Mar 2014 08:35:59 +0100 Subject: [PATCH 09/19] unit-tests: Implement registered functions without __builtin_apply() This makes the tests work with clang, which does not implement said builtin. --- src/libstrongswan/utils/test.h | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/src/libstrongswan/utils/test.h b/src/libstrongswan/utils/test.h index 38887946d..51362a15b 100644 --- a/src/libstrongswan/utils/test.h +++ b/src/libstrongswan/utils/test.h @@ -65,32 +65,32 @@ static void testable_function_unregister_##fn() \ /** * Import a registered function so that it can be called from tests. * - * The function name is prefixed with TEST_ to avoid clashes when building - * monolithically. - * - * @note We allocate an arbitrary amount of stack space, hopefully enough for - * all arguments. - * * @param ns namespace of the function * @param name name of the function * @param ret return type of the function * @param ... arguments of the function */ #define IMPORT_FUNCTION_FOR_TESTS(ns, name, ret, ...) \ -static ret TEST_##name(__VA_ARGS__) \ -{ \ - void (*fn)() = NULL; \ - if (testable_functions) \ +static ret (*TEST_##ns##name)(__VA_ARGS__); + +/** + * Call a registered function from tests. + * + * @param ns namespace of the function + * @param name name of the function + * @param ... arguments for the function + */ +#define TEST_FUNCTION(ns, name, ...) \ +({ \ + if (!TEST_##ns##name && testable_functions) \ { \ - fn = testable_functions->get(testable_functions, #ns "/" #name); \ + TEST_##ns##name = testable_functions->get(testable_functions, #ns "/" #name); \ } \ - if (fn) \ + if (!TEST_##ns##name) \ { \ - void *args = __builtin_apply_args(); \ - __builtin_return(__builtin_apply(fn, args, 16*sizeof(void*))); \ + test_fail_msg(__FILE__, __LINE__, "function " #name " (" #ns ") not found"); \ } \ - test_fail_msg(__FILE__, __LINE__, "function " #name " (" #ns ") not found"); \ - __builtin_return(NULL); \ -} + TEST_##ns##name(__VA_ARGS__); \ +}) #endif /** TEST_H_ @}*/ From 6ce5aee0b2dbc63c69f53f96386e4bbb9b00e21d Mon Sep 17 00:00:00 2001 From: Tobias Brunner Date: Sat, 1 Mar 2014 08:39:50 +0100 Subject: [PATCH 10/19] unit-tests: Use TEST_FUNCTION macro in ntru tests --- src/libstrongswan/tests/suites/test_ntru.c | 78 ++++++++++++---------- 1 file changed, 44 insertions(+), 34 deletions(-) diff --git a/src/libstrongswan/tests/suites/test_ntru.c b/src/libstrongswan/tests/suites/test_ntru.c index 8c17fdfde..9e6c5d74d 100644 --- a/src/libstrongswan/tests/suites/test_ntru.c +++ b/src/libstrongswan/tests/suites/test_ntru.c @@ -94,7 +94,8 @@ START_TEST(test_ntru_drbg_strength) entropy = lib->crypto->create_rng(lib->crypto, RNG_STRONG); ck_assert(entropy != NULL); - drbg = TEST_ntru_drbg_create(strengths[_i].requested, chunk_empty, entropy); + drbg = TEST_FUNCTION(ntru, ntru_drbg_create, strengths[_i].requested, + chunk_empty, entropy); if (strengths[_i].standard) { ck_assert(drbg != NULL); @@ -251,7 +252,8 @@ START_TEST(test_ntru_drbg) out = chunk_alloc(128); entropy = test_rng_create(drbg_tests[_i].entropy); - drbg = TEST_ntru_drbg_create(256, drbg_tests[_i].pers_str, entropy); + drbg = TEST_FUNCTION(ntru, ntru_drbg_create, 256, drbg_tests[_i].pers_str, + entropy); ck_assert(drbg != NULL); ck_assert(drbg->reseed(drbg)); ck_assert(drbg->generate(drbg, 256, 128, out.ptr)); @@ -273,7 +275,7 @@ START_TEST(test_ntru_drbg_reseed) "libstrongswan.plugins.ntru.max_drbg_requests", 2); out = chunk_alloc(128); entropy = test_rng_create(drbg_tests[0].entropy); - drbg = TEST_ntru_drbg_create(256, chunk_empty, entropy); + drbg = TEST_FUNCTION(ntru, ntru_drbg_create, 256, chunk_empty, entropy); /* bad output parameters */ ck_assert(!drbg->generate(drbg, 256, 0, out.ptr)); @@ -291,13 +293,13 @@ START_TEST(test_ntru_drbg_reseed) drbg->destroy(drbg); /* no entropy available for DRBG instantiation */ - drbg = TEST_ntru_drbg_create(256, chunk_empty, entropy); + drbg = TEST_FUNCTION(ntru, ntru_drbg_create, 256, chunk_empty, entropy); ck_assert(drbg == NULL); entropy->destroy(entropy); /* one automatic reseeding occurs */ entropy = test_rng_create(drbg_tests[0].entropy); - drbg = TEST_ntru_drbg_create(256, chunk_empty, entropy); + drbg = TEST_FUNCTION(ntru, ntru_drbg_create, 256, chunk_empty, entropy); ck_assert(drbg->generate(drbg, 256, 128, out.ptr)); ck_assert(drbg->generate(drbg, 256, 128, out.ptr)); ck_assert(drbg->generate(drbg, 256, 128, out.ptr)); @@ -550,14 +552,17 @@ START_TEST(test_ntru_mgf1) mask2.len = mgf1_tests[_i].ml2; mask3.len = mgf1_tests[_i].ml3; - mgf1 = TEST_ntru_mgf1_create(HASH_UNKNOWN, mgf1_tests[_i].seed, TRUE); + mgf1 = TEST_FUNCTION(ntru, ntru_mgf1_create, HASH_UNKNOWN, + mgf1_tests[_i].seed, TRUE); ck_assert(mgf1 == NULL); - mgf1 = TEST_ntru_mgf1_create(mgf1_tests[_i].alg, chunk_empty, TRUE); + mgf1 = TEST_FUNCTION(ntru, ntru_mgf1_create, mgf1_tests[_i].alg, + chunk_empty, TRUE); ck_assert(mgf1 == NULL); /* return mask in allocated chunk */ - mgf1 = TEST_ntru_mgf1_create(mgf1_tests[_i].alg, mgf1_tests[_i].seed, TRUE); + mgf1 = TEST_FUNCTION(ntru, ntru_mgf1_create, mgf1_tests[_i].alg, + mgf1_tests[_i].seed, TRUE); ck_assert(mgf1); /* check hash size */ @@ -573,15 +578,16 @@ START_TEST(test_ntru_mgf1) mgf1->destroy(mgf1); /* copy mask to pre-allocated buffer */ - mgf1 = TEST_ntru_mgf1_create(mgf1_tests[_i].alg, mgf1_tests[_i].seed, TRUE); + mgf1 = TEST_FUNCTION(ntru, ntru_mgf1_create, mgf1_tests[_i].alg, + mgf1_tests[_i].seed, TRUE); ck_assert(mgf1); ck_assert(mgf1->get_mask(mgf1, mgf1_tests[_i].mask.len, mask.ptr)); ck_assert(chunk_equals(mask, mgf1_tests[_i].mask)); mgf1->destroy(mgf1); /* get mask in batches without hashing the seed */ - mgf1 = TEST_ntru_mgf1_create(mgf1_tests[_i].alg, mgf1_tests[_i].hashed_seed, - FALSE); + mgf1 = TEST_FUNCTION(ntru, ntru_mgf1_create, mgf1_tests[_i].alg, + mgf1_tests[_i].hashed_seed, FALSE); ck_assert(mgf1); /* first batch */ @@ -609,16 +615,16 @@ START_TEST(test_ntru_trits) ntru_trits_t *mask; chunk_t trits; - mask = TEST_ntru_trits_create(mgf1_tests[_i].trits.len, HASH_UNKNOWN, - mgf1_tests[_i].seed); + mask = TEST_FUNCTION(ntru, ntru_trits_create, mgf1_tests[_i].trits.len, + HASH_UNKNOWN, mgf1_tests[_i].seed); ck_assert(mask == NULL); - mask = TEST_ntru_trits_create(mgf1_tests[_i].trits.len, mgf1_tests[_i].alg, - chunk_empty); + mask = TEST_FUNCTION(ntru, ntru_trits_create, mgf1_tests[_i].trits.len, + mgf1_tests[_i].alg, chunk_empty); ck_assert(mask == NULL); - mask = TEST_ntru_trits_create(mgf1_tests[_i].trits.len, mgf1_tests[_i].alg, - mgf1_tests[_i].seed); + mask = TEST_FUNCTION(ntru, ntru_trits_create, mgf1_tests[_i].trits.len, + mgf1_tests[_i].alg, mgf1_tests[_i].seed); ck_assert(mask); trits = chunk_create(mask->get_trits(mask), mask->get_size(mask)); @@ -626,7 +632,8 @@ START_TEST(test_ntru_trits) mask->destroy(mask); /* generate a multiple of 5 trits */ - mask = TEST_ntru_trits_create(10, mgf1_tests[_i].alg, mgf1_tests[_i].seed); + mask = TEST_FUNCTION(ntru, ntru_trits_create, 10, mgf1_tests[_i].alg, + mgf1_tests[_i].seed); ck_assert(mask); trits = chunk_create(mask->get_trits(mask), mask->get_size(mask)); @@ -647,17 +654,17 @@ START_TEST(test_ntru_poly) seed.len = mgf1_tests[_i].seed_len; p = &mgf1_tests[_i].poly_test[0]; - poly = TEST_ntru_poly_create_from_seed(HASH_UNKNOWN, seed, p->c_bits, p->N, - p->q, p->indices_len, p->indices_len, - p->is_product_form); + poly = TEST_FUNCTION(ntru, ntru_poly_create_from_seed, HASH_UNKNOWN, seed, + p->c_bits, p->N, p->q, p->indices_len, p->indices_len, + p->is_product_form); ck_assert(poly == NULL); for (n = 0; n < 2; n++) { p = &mgf1_tests[_i].poly_test[n]; - poly = TEST_ntru_poly_create_from_seed(mgf1_tests[_i].alg, seed, - p->c_bits, p->N, p->q, p->indices_len, - p->indices_len, p->is_product_form); + poly = TEST_FUNCTION(ntru, ntru_poly_create_from_seed, + mgf1_tests[_i].alg, seed, p->c_bits, p->N, p->q, + p->indices_len, p->indices_len, p->is_product_form); ck_assert(poly != NULL && poly->get_size(poly) == p->indices_size); indices = poly->get_indices(poly); @@ -757,8 +764,9 @@ START_TEST(test_ntru_ring_mult) int i; t = &ring_mult_tests[_i]; - poly = TEST_ntru_poly_create_from_data(t->indices, t->N, t->q, - t->indices_len_p, t->indices_len_m, t->is_product_form); + poly = TEST_FUNCTION(ntru, ntru_poly_create_from_data, t->indices, t->N, + t->q, t->indices_len_p, t->indices_len_m, + t->is_product_form); ck_assert(poly != NULL); c = malloc(t->N * sizeof(uint16_t)); @@ -785,8 +793,9 @@ START_TEST(test_ntru_array) t = &ring_mult_tests[array_tests[_i]]; - poly = TEST_ntru_poly_create_from_data(t->indices, t->N, t->q, - t->indices_len_p, t->indices_len_m, t->is_product_form); + poly = TEST_FUNCTION(ntru, ntru_poly_create_from_data, t->indices, t->N, + t->q, t->indices_len_p, t->indices_len_m, + t->is_product_form); ck_assert(poly != NULL); c = malloc(t->N * sizeof(uint16_t)); @@ -804,8 +813,8 @@ END_TEST START_TEST(test_ntru_param_set) { - ck_assert(TEST_ntru_param_set_get_by_id(-1) == NULL); - ck_assert(TEST_ntru_param_set_get_by_id(16) == NULL); + ck_assert(TEST_FUNCTION(ntru, ntru_param_set_get_by_id, -1) == NULL); + ck_assert(TEST_FUNCTION(ntru, ntru_param_set_get_by_id, 16) == NULL); } END_TEST @@ -1067,14 +1076,15 @@ START_TEST(test_ntru_privkey) uint32_t strength; chunk_t encoding, privkey_encoding, pubkey_encoding; - params = TEST_ntru_param_set_get_by_id(privkey_tests[_i].id); + params = TEST_FUNCTION(ntru, ntru_param_set_get_by_id, + privkey_tests[_i].id); strength = params->sec_strength_len * BITS_PER_BYTE; entropy = test_rng_create(privkey_tests[_i].entropy); - drbg = TEST_ntru_drbg_create(strength, chunk_from_str("IKE NTRU-KE"), - entropy); + drbg = TEST_FUNCTION(ntru, ntru_drbg_create, strength, + chunk_from_str("IKE NTRU-KE"), entropy); ck_assert(drbg != NULL); - privkey = TEST_ntru_private_key_create(drbg, params); + privkey = TEST_FUNCTION(ntru, ntru_private_key_create, drbg, params); ck_assert(privkey); privkey_encoding = privkey->get_encoding(privkey); From d62b66364684042cc9c5edc4d97101bdd597c00b Mon Sep 17 00:00:00 2001 From: Tobias Brunner Date: Sat, 1 Mar 2014 08:40:22 +0100 Subject: [PATCH 11/19] travis: Enable clang build But build the distribution only once. --- .travis.yml | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index c5812b524..8209ca9f1 100644 --- a/.travis.yml +++ b/.travis.yml @@ -2,6 +2,7 @@ language: c compiler: - gcc + - clang before_install: - sudo apt-get update -qq @@ -35,4 +36,8 @@ env: - TEST=gcrypt - TEST=all - TEST=all MONOLITHIC=yes - - TEST=dist + +matrix: + include: + - compiler: gcc + env: TEST=dist From 60a0bb67674bb472ce69564ebd0cc98c8ca6256c Mon Sep 17 00:00:00 2001 From: Tobias Brunner Date: Sat, 1 Mar 2014 08:49:52 +0100 Subject: [PATCH 12/19] travis: Install dependencies for each test dynamically Since the installation of all packages alone takes several minutes this should speed up some test cases. --- .travis.yml | 10 +--------- scripts/test.sh | 13 +++++++++++++ 2 files changed, 14 insertions(+), 9 deletions(-) diff --git a/.travis.yml b/.travis.yml index 8209ca9f1..affab27fb 100644 --- a/.travis.yml +++ b/.travis.yml @@ -7,15 +7,7 @@ compiler: before_install: - sudo apt-get update -qq - sudo apt-get install -qq bison flex gperf gettext - # TODO: modularize this to speed up builds (e.g. call 'test.sh deps' to do this for the current TEST) - - sudo apt-get install -qq libgmp-dev libssl-dev libgcrypt11-dev - - sudo apt-get install -qq libcurl4-gnutls-dev libsoup2.4-dev - - sudo apt-get install -qq libunbound-dev libldns-dev - - sudo apt-get install -qq libmysqlclient-dev libsqlite3-dev - - sudo apt-get install -qq clearsilver-dev libfcgi-dev - - sudo apt-get install -qq libnm-glib-dev libnm-glib-vpn-dev - - sudo apt-get install -qq libpcsclite-dev libpam0g-dev - - sudo apt-get install -qq binutils-dev libunwind7-dev + - ./scripts/test.sh deps script: - ./autogen.sh diff --git a/scripts/test.sh b/scripts/test.sh index 9b38c1136..30e851e31 100755 --- a/scripts/test.sh +++ b/scripts/test.sh @@ -9,14 +9,18 @@ cd $TRAVIS_BUILD_DIR TARGET=check +DEPS="libgmp-dev" + case "$TEST" in default) ;; openssl) CONFIG="--disable-defaults --enable-tools --enable-openssl" + DEPS="libssl-dev" ;; gcrypt) CONFIG="--disable-defaults --enable-tools --enable-gcrypt --enable-pkcs1" + DEPS="libgcrypt11-dev" ;; all) CONFIG="--enable-all --disable-android-dns --disable-android-log @@ -29,6 +33,10 @@ all) CONFIG="$CONFIG --disable-vstr" # TODO: enable? perhaps via coveralls.io (cpp-coveralls)? CONFIG="$CONFIG --disable-coverage" + DEPS="$DEPS libcurl4-gnutls-dev libsoup2.4-dev libunbound-dev libldns-dev + libmysqlclient-dev libsqlite3-dev clearsilver-dev libfcgi-dev + libnm-glib-dev libnm-glib-vpn-dev libpcsclite-dev libpam0g-dev + binutils-dev libunwind7-dev" ;; dist) TARGET=distcheck @@ -39,6 +47,11 @@ dist) ;; esac +if test "$1" = "deps"; then + sudo apt-get install -qq $DEPS + exit $? +fi + CONFIG="$CONFIG --enable-silent-rules --enable-test-vectors From 4ffe02a75d4ed5cb4f698c2c96068f380060899c Mon Sep 17 00:00:00 2001 From: Tobias Brunner Date: Mon, 3 Mar 2014 18:18:47 +0100 Subject: [PATCH 13/19] configure: Add an option to select a specific printf hook implementation --- configure.ac | 59 ++++++++++++++++++++++++++++++++-------------------- 1 file changed, 37 insertions(+), 22 deletions(-) diff --git a/configure.ac b/configure.ac index b6a5e0148..568b9e2cd 100644 --- a/configure.ac +++ b/configure.ac @@ -66,6 +66,7 @@ ARG_WITH_SET([tss], [no], [set implementation of the Trusted Co ARG_WITH_SET([capabilities], [no], [set capability dropping library. Currently supported values are "libcap" and "native"]) ARG_WITH_SET([mpz_powm_sec], [yes], [use the more side-channel resistant mpz_powm_sec in libgmp, if available]) ARG_WITH_SET([dev-headers], [no], [install strongSwan development headers to directory.]) +ARG_WITH_SET([printf-hooks], [auto], [force the use of a specific printf hook implementation (auto, builtin, glibc, vstr).]) if test -n "$PKG_CONFIG"; then systemdsystemunitdir_default=$($PKG_CONFIG --variable=systemdsystemunitdir systemd) @@ -272,7 +273,6 @@ ARG_ENABL_SET([integrity-test], [enable integrity testing of libstrongswan and p ARG_DISBL_SET([load-warning], [disable the charon plugin load option warning in starter.]) ARG_ENABL_SET([mediation], [enable IKEv2 Mediation Extension.]) ARG_ENABL_SET([unwind-backtraces],[use libunwind to create backtraces for memory leaks and segfaults.]) -ARG_ENABL_SET([vstr], [enforce using the Vstr string library to replace glibc-like printf hooks.]) # compile options ARG_ENABL_SET([coverage], [enable lcov coverage report generation.]) ARG_ENABL_SET([leak-detective], [enable malloc hooks to find memory leaks.]) @@ -685,28 +685,43 @@ AC_RUN_IFELSE([AC_LANG_SOURCE( [AC_MSG_RESULT([no])] ) -# check for the new register_printf_specifier function with len argument, -# or the deprecated register_printf_function without -AC_CHECK_FUNC( - [register_printf_specifier], - [AC_DEFINE([HAVE_PRINTF_SPECIFIER], [], [have register_printf_specifier()])], - [AC_CHECK_FUNC( - [register_printf_function], - [AC_DEFINE([HAVE_PRINTF_FUNCTION], [], [have register_printf_function()])], - [ - AC_MSG_NOTICE([printf does not support custom format specifiers!]) - builtin_printf=true - ] - )] -) +case "$printf_hooks" in +auto|builtin|glibc|vstr) + ;; +*) + AC_MSG_NOTICE([invalid printf hook implementation, defaulting to 'auto']) + printf_hooks=auto + ;; +esac -if test x$vstr = xtrue; then - AC_CHECK_LIB([vstr],[main],[LIBS="$LIBS"],[AC_MSG_ERROR([Vstr string library not found])],[]) - AC_DEFINE([USE_VSTR], [], [use Vstr string library for printf hooks]) - builtin_printf=false +if test x$printf_hooks = xauto -o x$printf_hooks = xglibc; then + # check for the new register_printf_specifier function with len argument, + # or the deprecated register_printf_function without + AC_CHECK_FUNC( + [register_printf_specifier], + [AC_DEFINE([HAVE_PRINTF_SPECIFIER], [], [have register_printf_specifier()])], + [AC_CHECK_FUNC( + [register_printf_function], + [AC_DEFINE([HAVE_PRINTF_FUNCTION], [], [have register_printf_function()])], + [ + AC_MSG_NOTICE([printf(3) does not support custom format specifiers!]) + if test x$printf_hooks = xglibc; then + AC_MSG_ERROR([please select a different printf hook implementation]) + else + # fallback to builtin printf hook implementation + printf_hooks=builtin + fi + ] + )] + ) fi -if test x$builtin_printf = xtrue; then +if test x$printf_hooks = xvstr; then + AC_CHECK_LIB([vstr],[main],[LIBS="$LIBS"],[AC_MSG_ERROR([Vstr string library not found])],[]) + AC_DEFINE([USE_VSTR], [], [use Vstr string library for printf hooks]) +fi + +if test x$printf_hooks = xbuiltin; then AC_DEFINE([USE_BUILTIN_PRINTF], [], [using builtin printf for printf hooks]) fi @@ -1354,8 +1369,8 @@ AM_CONDITIONAL(USE_LIBPTTLS, test x$tnc_tnccs = xtrue) AM_CONDITIONAL(USE_FILE_CONFIG, test x$stroke = xtrue) AM_CONDITIONAL(USE_IPSEC_SCRIPT, test x$stroke = xtrue -o x$tools = xtrue -o x$conftest = xtrue) AM_CONDITIONAL(USE_LIBCAP, test x$capabilities = xlibcap) -AM_CONDITIONAL(USE_VSTR, test x$vstr = xtrue) -AM_CONDITIONAL(USE_BUILTIN_PRINTF, test x$builtin_printf = xtrue) +AM_CONDITIONAL(USE_VSTR, test x$printf_hooks = xvstr) +AM_CONDITIONAL(USE_BUILTIN_PRINTF, test x$printf_hooks = xbuiltin) AM_CONDITIONAL(USE_SIMAKA, test x$simaka = xtrue) AM_CONDITIONAL(USE_TLS, test x$tls = xtrue) AM_CONDITIONAL(USE_RADIUS, test x$radius = xtrue) From 316aa4b43b8ced4169f3887603d588028c9411a2 Mon Sep 17 00:00:00 2001 From: Tobias Brunner Date: Mon, 3 Mar 2014 18:44:29 +0100 Subject: [PATCH 14/19] travis: Add tests for builtin printf hook implementation We can't test Vstr as it does not properly handle negative int arguments for custom format callbacks, so some of the enum tests would fail. --- .travis.yml | 3 +++ scripts/test.sh | 7 +++++-- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index affab27fb..e7b0f7e51 100644 --- a/.travis.yml +++ b/.travis.yml @@ -26,6 +26,9 @@ env: - TEST=openssl LEAK_DETECTIVE=yes # libgcrypt can't be deinitialized so we can't test it with leak detective - TEST=gcrypt + # we can't test Vstr as negative int args are not properly passed to CBs + - TEST=printf-builtin + - TEST=printf-builtin LEAK_DETECTIVE=yes - TEST=all - TEST=all MONOLITHIC=yes diff --git a/scripts/test.sh b/scripts/test.sh index 30e851e31..80d04d1d5 100755 --- a/scripts/test.sh +++ b/scripts/test.sh @@ -13,6 +13,8 @@ DEPS="libgmp-dev" case "$TEST" in default) + # should be the default, but lets make sure + CONFIG="--with-printf-hooks=glibc" ;; openssl) CONFIG="--disable-defaults --enable-tools --enable-openssl" @@ -22,6 +24,9 @@ gcrypt) CONFIG="--disable-defaults --enable-tools --enable-gcrypt --enable-pkcs1" DEPS="libgcrypt11-dev" ;; +printf-builtin) + CONFIG="--with-printf-hooks=builtin" + ;; all) CONFIG="--enable-all --disable-android-dns --disable-android-log --disable-dumm --disable-kernel-pfroute --disable-keychain @@ -29,8 +34,6 @@ all) --disable-osx-attr --disable-tkm --disable-uci" # not enabled on the build server CONFIG="$CONFIG --disable-af-alg" - # TODO: add tests for different printf implementations? - CONFIG="$CONFIG --disable-vstr" # TODO: enable? perhaps via coveralls.io (cpp-coveralls)? CONFIG="$CONFIG --disable-coverage" DEPS="$DEPS libcurl4-gnutls-dev libsoup2.4-dev libunbound-dev libldns-dev From 636076d45d6879c8679c721714451bfe89617e15 Mon Sep 17 00:00:00 2001 From: Tobias Brunner Date: Thu, 13 Mar 2014 16:03:05 +0100 Subject: [PATCH 15/19] unit-tests: Actually verify registered algorithms against test vectors Previously, the {ns}.crypto_test.on_add option had to be enabled to actually test the algorithms, which we can't enforce for the tests in the test_runner as the option is already read when the crypto factory is initialized. Even so, we wouldn't want to do this for every unit test, which would be the result of enabling that option. --- src/libstrongswan/crypto/crypto_factory.c | 39 ++++++++++++++++++- src/libstrongswan/tests/suites/test_vectors.c | 13 +++++-- 2 files changed, 47 insertions(+), 5 deletions(-) diff --git a/src/libstrongswan/crypto/crypto_factory.c b/src/libstrongswan/crypto/crypto_factory.c index dba3f6f6d..69225bd1e 100644 --- a/src/libstrongswan/crypto/crypto_factory.c +++ b/src/libstrongswan/crypto/crypto_factory.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2013 Tobias Brunner + * Copyright (C) 2013-2014 Tobias Brunner * Copyright (C) 2008 Martin Willi * Hochschule fuer Technik Rapperswil * @@ -20,6 +20,7 @@ #include #include #include +#include const char *default_plugin_name = "default"; @@ -976,3 +977,39 @@ crypto_factory_t *crypto_factory_create() return &this->public; } + +/** + * Manually verify all registered algorithms against test vectors + */ +static u_int verify_registered_algorithms(crypto_factory_t *factory) +{ + private_crypto_factory_t *this = (private_crypto_factory_t*)factory; + enumerator_t *enumerator; + entry_t *entry; + u_int failures = 0; + +#define TEST_ALGORITHMS(test, ...) do { \ + enumerator = this->test##s->create_enumerator(this->test##s); \ + while (enumerator->enumerate(enumerator, &entry)) \ + { \ + if (!this->tester->test_##test(this->tester, entry->algo, ##__VA_ARGS__, \ + entry->create_##test, NULL, entry->plugin_name)) \ + { \ + failures++; \ + } \ + } \ + enumerator->destroy(enumerator); \ +} while (0) + + this->lock->read_lock(this->lock); + TEST_ALGORITHMS(crypter, 0); + TEST_ALGORITHMS(aead, 0); + TEST_ALGORITHMS(signer); + TEST_ALGORITHMS(hasher); + TEST_ALGORITHMS(prf); + TEST_ALGORITHMS(rng); + this->lock->unlock(this->lock); + return failures; +} + +EXPORT_FUNCTION_FOR_TESTS(crypto, verify_registered_algorithms); diff --git a/src/libstrongswan/tests/suites/test_vectors.c b/src/libstrongswan/tests/suites/test_vectors.c index 242ac9d09..a1205d0be 100644 --- a/src/libstrongswan/tests/suites/test_vectors.c +++ b/src/libstrongswan/tests/suites/test_vectors.c @@ -1,4 +1,7 @@ /* + * Copyright (C) 2014 Tobias Brunner + * Hochschule fuer Technik Rapperswil + * * Copyright (C) 2013 Martin Willi * Copyright (C) 2013 revosec AG * @@ -15,13 +18,15 @@ #include "test_suite.h" -/******************************************************************************* - * Check if test vectors have been successful during transform registration - */ +#include + +IMPORT_FUNCTION_FOR_TESTS(crypto, verify_registered_algorithms, u_int, + crypto_factory_t *factory); START_TEST(test_vectors) { - u_int failed = lib->crypto->get_test_vector_failures(lib->crypto); + u_int failed = TEST_FUNCTION(crypto, verify_registered_algorithms, + lib->crypto); fail_if(failed > 0, "%u test vectors failed", failed); } END_TEST From 77603e98a38dc4b88bab934c77edabe8267a6907 Mon Sep 17 00:00:00 2001 From: Tobias Brunner Date: Fri, 14 Mar 2014 09:35:50 +0100 Subject: [PATCH 16/19] unit-tests: Add an option to run only a subset of all test suites The TESTS_SUITES environment variable can contain a comma separated list of names of test suites to run. --- src/libstrongswan/tests/test_runner.c | 62 +++++++++++++++++++++++---- 1 file changed, 54 insertions(+), 8 deletions(-) diff --git a/src/libstrongswan/tests/test_runner.c b/src/libstrongswan/tests/test_runner.c index dc6fcf3dd..0b8830df4 100644 --- a/src/libstrongswan/tests/test_runner.c +++ b/src/libstrongswan/tests/test_runner.c @@ -22,6 +22,7 @@ #include #include +#include #include #include #include @@ -60,7 +61,57 @@ static void testable_functions_destroy() } /** - * Load all available test suites + * Destroy a single test suite and associated data + */ +static void destroy_suite(test_suite_t *suite) +{ + test_case_t *tcase; + + while (array_remove(suite->tcases, 0, &tcase)) + { + array_destroy(tcase->functions); + array_destroy(tcase->fixtures); + } + free(suite); +} + +/** + * Removes and destroys test suites that are not selected. + */ +static void filter_suites(array_t *loaded) +{ + enumerator_t *enumerator, *names; + hashtable_t *selected; + test_suite_t *suite; + char *suites, *name; + + suites = getenv("TESTS_SUITES"); + if (!suites) + { + return; + } + selected = hashtable_create(hashtable_hash_str, hashtable_equals_str, 8); + names = enumerator_create_token(suites, ",", " "); + while (names->enumerate(names, &name)) + { + selected->put(selected, name, name); + } + enumerator = array_create_enumerator(loaded); + while (enumerator->enumerate(enumerator, &suite)) + { + if (!selected->get(selected, suite->name)) + { + array_remove_at(loaded, enumerator); + destroy_suite(suite); + } + } + enumerator->destroy(enumerator); + selected->destroy(selected); + names->destroy(names); +} + +/** + * Load all available test suites, or optionally only selected ones. */ static array_t *load_suites(test_configuration_t configs[], test_runner_init_t init) @@ -95,6 +146,7 @@ static array_t *load_suites(test_configuration_t configs[], array_insert(suites, -1, configs[i].suite()); } } + filter_suites(suites); if (lib->leak_detective) { @@ -116,16 +168,10 @@ static array_t *load_suites(test_configuration_t configs[], static void unload_suites(array_t *suites) { test_suite_t *suite; - test_case_t *tcase; while (array_remove(suites, 0, &suite)) { - while (array_remove(suite->tcases, 0, &tcase)) - { - array_destroy(tcase->functions); - array_destroy(tcase->fixtures); - } - free(suite); + destroy_suite(suite); } array_destroy(suites); } From 5dd638f45c374eb69b4d644e9de28cb3d34d1e42 Mon Sep 17 00:00:00 2001 From: Tobias Brunner Date: Fri, 14 Mar 2014 09:41:50 +0100 Subject: [PATCH 17/19] unit-tests: Add an option to increase the verbosity when running tests The TESTS_VERBOSITY option takes an integer from -1 to 4 that sets the default debug level. --- src/libstrongswan/tests/test_runner.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/libstrongswan/tests/test_runner.c b/src/libstrongswan/tests/test_runner.c index 0b8830df4..6bb1b290c 100644 --- a/src/libstrongswan/tests/test_runner.c +++ b/src/libstrongswan/tests/test_runner.c @@ -228,6 +228,9 @@ static bool call_fixture(test_case_t *tcase, bool up) */ static bool pre_test(test_runner_init_t init) { + level_t level = LEVEL_SILENT; + char *verbosity; + library_init(NULL, "test-runner"); /* use non-blocking RNG to generate keys fast */ @@ -250,7 +253,12 @@ static bool pre_test(test_runner_init_t init) library_deinit(); return FALSE; } - dbg_default_set_level(LEVEL_SILENT); + verbosity = getenv("TESTS_VERBOSITY"); + if (verbosity) + { + level = atoi(verbosity); + } + dbg_default_set_level(level); return TRUE; } From 510c9004793adea388a7e70ff1d36e7ae9266060 Mon Sep 17 00:00:00 2001 From: Tobias Brunner Date: Fri, 14 Mar 2014 09:56:23 +0100 Subject: [PATCH 18/19] crypto-tester: Don't fail if key size is not supported The Blowfish and Twofish implementations provided by the gcrypt plugin only support specific key lengths, which we don't know when testing against vectors (either during unit tests or during algorithm registration). The on_create test with a specific key length will be skipped anyway, so there is no point in treating this failure differently. --- src/libstrongswan/crypto/crypto_tester.c | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/src/libstrongswan/crypto/crypto_tester.c b/src/libstrongswan/crypto/crypto_tester.c index 30724b16d..40c4fd362 100644 --- a/src/libstrongswan/crypto/crypto_tester.c +++ b/src/libstrongswan/crypto/crypto_tester.c @@ -204,16 +204,13 @@ METHOD(crypto_tester_t, test_crypter, bool, continue; } - tested++; - failed = TRUE; crypter = create(alg, vector->key_size); if (!crypter) - { - DBG1(DBG_LIB, "%N[%s]: %u bit key size not supported", - encryption_algorithm_names, alg, plugin_name, - BITS_PER_BYTE * vector->key_size); + { /* key size not supported */ continue; } + tested++; + failed = TRUE; key = chunk_create(vector->key, crypter->get_key_size(crypter)); if (!crypter->set_key(crypter, key)) From 6548f50cf920867b3eac58e9e6c9d0213d9fe7ab Mon Sep 17 00:00:00 2001 From: Tobias Brunner Date: Tue, 18 Mar 2014 15:25:56 +0100 Subject: [PATCH 19/19] travis: Use parallel build Not sure if 4 jobs is optimal, but according to the docs each build host has 1.5 virtual cores available (although "getconf _NPROCESSORS_ONLN" returns 32, which is probably the number of real cores underneath), so more jobs might not actually reduce the build time much more. --- scripts/test.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/test.sh b/scripts/test.sh index 80d04d1d5..4785d0603 100755 --- a/scripts/test.sh +++ b/scripts/test.sh @@ -62,4 +62,4 @@ CONFIG="$CONFIG --enable-leak-detective=${LEAK_DETECTIVE-no}" echo "$ ./configure $CONFIG && make $TARGET" -./configure $CONFIG && make $TARGET +./configure $CONFIG && make -j4 $TARGET