diff options
Diffstat (limited to 'src/libstrongswan')
253 files changed, 11455 insertions, 4270 deletions
diff --git a/src/libstrongswan/Android.mk b/src/libstrongswan/Android.mk index d33bee6c7..4912576df 100644 --- a/src/libstrongswan/Android.mk +++ b/src/libstrongswan/Android.mk @@ -3,81 +3,43 @@ include $(CLEAR_VARS) # copy-n-paste from Makefile.am LOCAL_SRC_FILES := \ -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 \ -bio/bio_reader.h bio/bio_reader.c bio/bio_writer.h bio/bio_writer.c \ -crypto/crypters/crypter.c crypto/crypters/crypter.h \ -crypto/hashers/hasher.h crypto/hashers/hasher.c \ -crypto/pkcs9.c crypto/pkcs9.h \ -crypto/proposal/proposal_keywords.c crypto/proposal/proposal_keywords.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/crypto_factory.c crypto/crypto_factory.h \ -crypto/crypto_tester.c crypto/crypto_tester.h \ -crypto/diffie_hellman.c crypto/diffie_hellman.h \ -crypto/aead.c crypto/aead.h \ -crypto/transform.c crypto/transform.h \ -credentials/credential_factory.c credentials/credential_factory.h \ -credentials/builder.c credentials/builder.h \ -credentials/cred_encoding.c credentials/cred_encoding.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/ac.h \ -credentials/certificates/crl.h credentials/certificates/crl.c \ -credentials/certificates/pkcs10.h \ -credentials/certificates/ocsp_request.h \ -credentials/certificates/ocsp_response.h credentials/certificates/ocsp_response.c \ -credentials/certificates/pgp_certificate.h \ -credentials/ietf_attributes/ietf_attributes.c credentials/ietf_attributes/ietf_attributes.h \ -credentials/credential_manager.c credentials/credential_manager.h \ -credentials/sets/auth_cfg_wrapper.c credentials/sets/auth_cfg_wrapper.h \ -credentials/sets/ocsp_response_wrapper.c credentials/sets/ocsp_response_wrapper.h \ -credentials/sets/cert_cache.c credentials/sets/cert_cache.h \ -credentials/sets/mem_cred.c credentials/sets/mem_cred.h \ -credentials/sets/callback_cred.c credentials/sets/callback_cred.h \ -credentials/auth_cfg.c credentials/auth_cfg.h credentials/credential_set.h \ -credentials/cert_validator.h database/database.h database/database.c \ -database/database_factory.h database/database_factory.c \ -fetcher/fetcher.h fetcher/fetcher.c fetcher/fetcher_manager.h fetcher/fetcher_manager.c \ -eap/eap.h eap/eap.c \ -pen/pen.h pen/pen.c \ -plugins/plugin_loader.c plugins/plugin_loader.h plugins/plugin.h \ -plugins/plugin_feature.c plugins/plugin_feature.h \ -processing/jobs/job.h processing/jobs/job.c \ -processing/jobs/callback_job.c processing/jobs/callback_job.h \ -processing/processor.c processing/processor.h \ -processing/scheduler.c processing/scheduler.h \ -selectors/traffic_selector.c selectors/traffic_selector.h \ -threading/thread.h threading/thread.c \ -threading/thread_value.h threading/thread_value.c \ -threading/mutex.h threading/mutex.c threading/condvar.h \ -threading/rwlock.h threading/rwlock.c \ -threading/lock_profiler.h \ -utils.h utils.c \ -utils/host.c utils/host.h \ -utils/identification.c utils/identification.h \ -utils/lexparser.c utils/lexparser.h \ -utils/linked_list.c utils/linked_list.h \ -utils/hashtable.c utils/hashtable.h \ -utils/enumerator.c utils/enumerator.h \ -utils/optionsfrom.c utils/optionsfrom.h \ -utils/backtrace.c utils/backtrace.h +library.c chunk.c debug.c enum.c settings.c printf_hook.c asn1/asn1.c \ +asn1/asn1_parser.c asn1/oid.c bio/bio_reader.c bio/bio_writer.c \ +crypto/crypters/crypter.c crypto/hashers/hasher.c crypto/pkcs7.c crypto/pkcs9.c \ +crypto/proposal/proposal_keywords.c crypto/proposal/proposal_keywords_static.c \ +crypto/prfs/prf.c crypto/prfs/mac_prf.c \ +crypto/rngs/rng.c crypto/prf_plus.c crypto/signers/signer.c \ +crypto/signers/mac_signer.c crypto/crypto_factory.c crypto/crypto_tester.c \ +crypto/diffie_hellman.c crypto/aead.c crypto/transform.c \ +credentials/credential_factory.c credentials/builder.c \ +credentials/cred_encoding.c credentials/keys/private_key.c \ +credentials/keys/public_key.c credentials/keys/shared_key.c \ +credentials/certificates/certificate.c credentials/certificates/crl.c \ +credentials/certificates/ocsp_response.c \ +credentials/ietf_attributes/ietf_attributes.c credentials/credential_manager.c \ +credentials/sets/auth_cfg_wrapper.c credentials/sets/ocsp_response_wrapper.c \ +credentials/sets/cert_cache.c credentials/sets/mem_cred.c \ +credentials/sets/callback_cred.c credentials/auth_cfg.c database/database.c \ +database/database_factory.c fetcher/fetcher.c fetcher/fetcher_manager.c eap/eap.c \ +ipsec/ipsec_types.c \ +pen/pen.c plugins/plugin_loader.c plugins/plugin_feature.c processing/jobs/job.c \ +processing/jobs/callback_job.c processing/processor.c processing/scheduler.c \ +selectors/traffic_selector.c threading/thread.c threading/thread_value.c \ +threading/mutex.c threading/semaphore.c threading/rwlock.c threading/spinlock.c \ +utils.c utils/host.c utils/packet.c utils/identification.c utils/lexparser.c \ +utils/linked_list.c utils/blocking_queue.c utils/hashtable.c utils/enumerator.c \ +utils/optionsfrom.c utils/capabilities.c utils/backtrace.c utils/tun_device.c # adding the plugin source files LOCAL_SRC_FILES += $(call add_plugin, aes) +LOCAL_SRC_FILES += $(call add_plugin, curl) +ifneq ($(call plugin_enabled, curl),) +LOCAL_C_INCLUDES += $(libcurl_PATH) +LOCAL_SHARED_LIBRARIES += libcurl +endif + LOCAL_SRC_FILES += $(call add_plugin, des) LOCAL_SRC_FILES += $(call add_plugin, fips-prf) @@ -94,9 +56,11 @@ LOCAL_SRC_FILES += $(call add_plugin, md4) LOCAL_SRC_FILES += $(call add_plugin, md5) +LOCAL_SRC_FILES += $(call add_plugin, nonce) + LOCAL_SRC_FILES += $(call add_plugin, openssl) ifneq ($(call plugin_enabled, openssl),) -LOCAL_C_INCLUDES += external/openssl/include +LOCAL_C_INCLUDES += $(openssl_PATH) LOCAL_SHARED_LIBRARIES += libcrypto endif @@ -104,6 +68,8 @@ LOCAL_SRC_FILES += $(call add_plugin, pem) LOCAL_SRC_FILES += $(call add_plugin, pkcs1) +LOCAL_SRC_FILES += $(call add_plugin, pkcs8) + LOCAL_SRC_FILES += $(call add_plugin, pkcs11) LOCAL_SRC_FILES += $(call add_plugin, pubkey) diff --git a/src/libstrongswan/AndroidConfigLocal.h b/src/libstrongswan/AndroidConfigLocal.h index a6da3276a..ee29c1693 100644 --- a/src/libstrongswan/AndroidConfigLocal.h +++ b/src/libstrongswan/AndroidConfigLocal.h @@ -1,3 +1,18 @@ +/* + * Copyright (C) 2010 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. + */ + /* stuff defined in AndroidConfig.h, which is included using the -include * command-line option, thus cannot be undefined using -U CFLAGS options. * the reason we have to undefine these flags in the first place, is that diff --git a/src/libstrongswan/Makefile.am b/src/libstrongswan/Makefile.am index 7bb0812bd..463d57d95 100644 --- a/src/libstrongswan/Makefile.am +++ b/src/libstrongswan/Makefile.am @@ -1,81 +1,75 @@ ipseclib_LTLIBRARIES = libstrongswan.la libstrongswan_la_SOURCES = \ -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 \ -bio/bio_reader.h bio/bio_reader.c bio/bio_writer.h bio/bio_writer.c \ -crypto/crypters/crypter.c crypto/crypters/crypter.h \ -crypto/hashers/hasher.h crypto/hashers/hasher.c \ -crypto/pkcs9.c crypto/pkcs9.h \ -crypto/proposal/proposal_keywords.c crypto/proposal/proposal_keywords.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/crypto_factory.c crypto/crypto_factory.h \ -crypto/crypto_tester.c crypto/crypto_tester.h \ -crypto/diffie_hellman.c crypto/diffie_hellman.h \ -crypto/aead.c crypto/aead.h \ -crypto/transform.c crypto/transform.h \ -credentials/credential_factory.c credentials/credential_factory.h \ -credentials/builder.c credentials/builder.h \ -credentials/cred_encoding.c credentials/cred_encoding.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/ac.h \ -credentials/certificates/crl.h credentials/certificates/crl.c \ -credentials/certificates/pkcs10.h \ -credentials/certificates/ocsp_request.h \ -credentials/certificates/ocsp_response.h credentials/certificates/ocsp_response.c \ +library.c chunk.c debug.c enum.c settings.c printf_hook.c asn1/asn1.c \ +asn1/asn1_parser.c asn1/oid.c bio/bio_reader.c bio/bio_writer.c \ +crypto/crypters/crypter.c crypto/hashers/hasher.c crypto/pkcs7.c crypto/pkcs9.c \ +crypto/proposal/proposal_keywords.c crypto/proposal/proposal_keywords_static.c \ +crypto/prfs/prf.c crypto/prfs/mac_prf.c \ +crypto/rngs/rng.c crypto/prf_plus.c crypto/signers/signer.c \ +crypto/signers/mac_signer.c crypto/crypto_factory.c crypto/crypto_tester.c \ +crypto/diffie_hellman.c crypto/aead.c crypto/transform.c \ +credentials/credential_factory.c credentials/builder.c \ +credentials/cred_encoding.c credentials/keys/private_key.c \ +credentials/keys/public_key.c credentials/keys/shared_key.c \ +credentials/certificates/certificate.c credentials/certificates/crl.c \ +credentials/certificates/ocsp_response.c \ +credentials/ietf_attributes/ietf_attributes.c credentials/credential_manager.c \ +credentials/sets/auth_cfg_wrapper.c credentials/sets/ocsp_response_wrapper.c \ +credentials/sets/cert_cache.c credentials/sets/mem_cred.c \ +credentials/sets/callback_cred.c credentials/auth_cfg.c database/database.c \ +database/database_factory.c fetcher/fetcher.c fetcher/fetcher_manager.c eap/eap.c \ +ipsec/ipsec_types.c \ +pen/pen.c plugins/plugin_loader.c plugins/plugin_feature.c processing/jobs/job.c \ +processing/jobs/callback_job.c processing/processor.c processing/scheduler.c \ +selectors/traffic_selector.c threading/thread.c threading/thread_value.c \ +threading/mutex.c threading/semaphore.c threading/rwlock.c threading/spinlock.c \ +utils.c utils/host.c utils/packet.c utils/identification.c utils/lexparser.c \ +utils/linked_list.c utils/blocking_queue.c utils/hashtable.c utils/enumerator.c \ +utils/optionsfrom.c utils/capabilities.c utils/backtrace.c utils/tun_device.c + +if USE_DEV_HEADERS +strongswan_includedir = ${dev_headers} +nobase_strongswan_include_HEADERS = \ +library.h chunk.h debug.h enum.h settings.h printf_hook.h \ +asn1/asn1.h asn1/asn1_parser.h asn1/oid.h bio/bio_reader.h bio/bio_writer.h \ +crypto/crypters/crypter.h crypto/hashers/hasher.h crypto/mac.h \ +crypto/pkcs7.h crypto/pkcs9.h crypto/proposal/proposal_keywords.h \ +crypto/proposal/proposal_keywords_static.h \ +crypto/prfs/prf.h crypto/prfs/mac_prf.h crypto/rngs/rng.h crypto/nonce_gen.h \ +crypto/prf_plus.h crypto/signers/signer.h crypto/signers/mac_signer.h \ +crypto/crypto_factory.h crypto/crypto_tester.h crypto/diffie_hellman.h \ +crypto/aead.h crypto/transform.h \ +credentials/credential_factory.h credentials/builder.h \ +credentials/cred_encoding.h credentials/keys/private_key.h \ +credentials/keys/public_key.h credentials/keys/shared_key.h \ +credentials/certificates/certificate.h credentials/certificates/x509.h \ +credentials/certificates/ac.h credentials/certificates/crl.h \ +credentials/certificates/pkcs10.h credentials/certificates/ocsp_request.h \ +credentials/certificates/ocsp_response.h \ credentials/certificates/pgp_certificate.h \ -credentials/ietf_attributes/ietf_attributes.c credentials/ietf_attributes/ietf_attributes.h \ -credentials/credential_manager.c credentials/credential_manager.h \ -credentials/sets/auth_cfg_wrapper.c credentials/sets/auth_cfg_wrapper.h \ -credentials/sets/ocsp_response_wrapper.c credentials/sets/ocsp_response_wrapper.h \ -credentials/sets/cert_cache.c credentials/sets/cert_cache.h \ -credentials/sets/mem_cred.c credentials/sets/mem_cred.h \ -credentials/sets/callback_cred.c credentials/sets/callback_cred.h \ -credentials/auth_cfg.c credentials/auth_cfg.h credentials/credential_set.h \ -credentials/cert_validator.h database/database.h database/database.c \ -database/database_factory.h database/database_factory.c \ -fetcher/fetcher.h fetcher/fetcher.c fetcher/fetcher_manager.h fetcher/fetcher_manager.c \ -eap/eap.h eap/eap.c \ -pen/pen.h pen/pen.c \ -plugins/plugin_loader.c plugins/plugin_loader.h plugins/plugin.h \ -plugins/plugin_feature.c plugins/plugin_feature.h \ -processing/jobs/job.h processing/jobs/job.c \ -processing/jobs/callback_job.c processing/jobs/callback_job.h \ -processing/processor.c processing/processor.h \ -processing/scheduler.c processing/scheduler.h \ -selectors/traffic_selector.c selectors/traffic_selector.h \ -threading/thread.h threading/thread.c \ -threading/thread_value.h threading/thread_value.c \ -threading/mutex.h threading/mutex.c threading/condvar.h \ -threading/rwlock.h threading/rwlock.c \ -threading/lock_profiler.h \ -utils.h utils.c \ -utils/host.c utils/host.h \ -utils/identification.c utils/identification.h \ -utils/lexparser.c utils/lexparser.h \ -utils/linked_list.c utils/linked_list.h \ -utils/hashtable.c utils/hashtable.h \ -utils/enumerator.c utils/enumerator.h \ -utils/optionsfrom.c utils/optionsfrom.h \ -utils/backtrace.c utils/backtrace.h - +credentials/ietf_attributes/ietf_attributes.h \ +credentials/credential_manager.h credentials/sets/auth_cfg_wrapper.h \ +credentials/sets/ocsp_response_wrapper.h credentials/sets/cert_cache.h \ +credentials/sets/mem_cred.h credentials/sets/callback_cred.h \ +credentials/auth_cfg.h credentials/credential_set.h credentials/cert_validator.h \ +database/database.h database/database_factory.h fetcher/fetcher.h \ +fetcher/fetcher_manager.h eap/eap.h pen/pen.h ipsec/ipsec_types.h \ +plugins/plugin_loader.h plugins/plugin.h plugins/plugin_feature.h \ +processing/jobs/job.h processing/jobs/callback_job.h processing/processor.h \ +processing/scheduler.h selectors/traffic_selector.h \ +threading/thread.h threading/thread_value.h \ +threading/mutex.h threading/condvar.h threading/spinlock.h threading/semaphore.h \ +threading/rwlock.h threading/rwlock_condvar.h threading/lock_profiler.h \ +utils.h utils/host.h utils/packet.h utils/identification.h utils/lexparser.h \ +utils/linked_list.h utils/blocking_queue.h utils/hashtable.h utils/enumerator.h \ +utils/optionsfrom.h utils/capabilities.h utils/backtrace.h utils/tun_device.h \ +utils/leak_detective.h integrity_checker.h +endif library.lo : $(top_builddir)/config.status -libstrongswan_la_LIBADD = $(PTHREADLIB) $(DLLIB) $(BTLIB) $(SOCKLIB) $(RTLIB) +libstrongswan_la_LIBADD = $(PTHREADLIB) $(DLLIB) $(BTLIB) $(SOCKLIB) $(RTLIB) $(BFDLIB) INCLUDES = -I$(top_srcdir)/src/libstrongswan AM_CFLAGS = \ @@ -86,8 +80,7 @@ AM_CFLAGS = \ if USE_LEAK_DETECTIVE AM_CFLAGS += -DLEAK_DETECTIVE - libstrongswan_la_SOURCES += \ - utils/leak_detective.c utils/leak_detective.h + libstrongswan_la_SOURCES += utils/leak_detective.c endif if USE_LOCK_PROFILER @@ -96,26 +89,29 @@ endif if USE_INTEGRITY_TEST AM_CFLAGS += -DINTEGRITY_TEST - libstrongswan_la_SOURCES += \ - integrity_checker.c integrity_checker.h + libstrongswan_la_SOURCES += integrity_checker.c endif if USE_VSTR libstrongswan_la_LIBADD += -lvstr endif +if USE_LIBCAP + libstrongswan_la_LIBADD += -lcap +endif + EXTRA_DIST = \ asn1/oid.txt asn1/oid.pl \ -crypto/proposal/proposal_keywords.txt \ +crypto/proposal/proposal_keywords_static.txt \ Android.mk AndroidConfigLocal.h BUILT_SOURCES = \ $(srcdir)/asn1/oid.c $(srcdir)/asn1/oid.h \ -$(srcdir)/crypto/proposal/proposal_keywords.c +$(srcdir)/crypto/proposal/proposal_keywords_static.c MAINTAINERCLEANFILES = \ $(srcdir)/asn1/oid.c $(srcdir)/asn1/oid.h \ -$(srcdir)/crypto/proposal/proposal_keywords.c +$(srcdir)/crypto/proposal/proposal_keywords_static.c $(srcdir)/asn1/oid.c : $(srcdir)/asn1/oid.pl $(srcdir)/asn1/oid.txt (cd $(srcdir)/asn1/ && $(PERL) oid.pl) @@ -123,10 +119,10 @@ $(srcdir)/asn1/oid.c : $(srcdir)/asn1/oid.pl $(srcdir)/asn1/oid.txt $(srcdir)/asn1/oid.h : $(srcdir)/asn1/oid.pl $(srcdir)/asn1/oid.txt (cd $(srcdir)/asn1/ && $(PERL) oid.pl) -$(srcdir)/crypto/proposal/proposal_keywords.c: $(srcdir)/crypto/proposal/proposal_keywords.txt \ - $(srcdir)/crypto/proposal/proposal_keywords.h - $(GPERF) -N proposal_get_token -m 10 -C -G -c -t -D < \ - $(srcdir)/crypto/proposal/proposal_keywords.txt > $@ +$(srcdir)/crypto/proposal/proposal_keywords_static.c: $(srcdir)/crypto/proposal/proposal_keywords_static.txt \ + $(srcdir)/crypto/proposal/proposal_keywords_static.h + $(GPERF) -N proposal_get_token_static -m 10 -C -G -c -t -D < \ + $(srcdir)/crypto/proposal/proposal_keywords_static.txt > $@ # build plugins with their own Makefile @@ -208,6 +204,13 @@ if MONOLITHIC endif endif +if USE_NONCE + SUBDIRS += plugins/nonce +if MONOLITHIC + libstrongswan_la_LIBADD += plugins/nonce/libstrongswan-nonce.la +endif +endif + if USE_HMAC SUBDIRS += plugins/hmac if MONOLITHIC diff --git a/src/libstrongswan/Makefile.in b/src/libstrongswan/Makefile.in index 68c83a5aa..aeebb25c0 100644 --- a/src/libstrongswan/Makefile.in +++ b/src/libstrongswan/Makefile.in @@ -15,6 +15,7 @@ @SET_MAKE@ + VPATH = @srcdir@ pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ @@ -35,91 +36,91 @@ POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ @USE_LEAK_DETECTIVE_TRUE@am__append_1 = -DLEAK_DETECTIVE -@USE_LEAK_DETECTIVE_TRUE@am__append_2 = \ -@USE_LEAK_DETECTIVE_TRUE@ utils/leak_detective.c utils/leak_detective.h - +@USE_LEAK_DETECTIVE_TRUE@am__append_2 = utils/leak_detective.c @USE_LOCK_PROFILER_TRUE@am__append_3 = -DLOCK_PROFILER @USE_INTEGRITY_TEST_TRUE@am__append_4 = -DINTEGRITY_TEST -@USE_INTEGRITY_TEST_TRUE@am__append_5 = \ -@USE_INTEGRITY_TEST_TRUE@ integrity_checker.c integrity_checker.h - +@USE_INTEGRITY_TEST_TRUE@am__append_5 = integrity_checker.c @USE_VSTR_TRUE@am__append_6 = -lvstr -@USE_AF_ALG_TRUE@am__append_7 = plugins/af_alg -@MONOLITHIC_TRUE@@USE_AF_ALG_TRUE@am__append_8 = plugins/af_alg/libstrongswan-af-alg.la -@USE_AES_TRUE@am__append_9 = plugins/aes -@MONOLITHIC_TRUE@@USE_AES_TRUE@am__append_10 = plugins/aes/libstrongswan-aes.la -@USE_DES_TRUE@am__append_11 = plugins/des -@MONOLITHIC_TRUE@@USE_DES_TRUE@am__append_12 = plugins/des/libstrongswan-des.la -@USE_BLOWFISH_TRUE@am__append_13 = plugins/blowfish -@MONOLITHIC_TRUE@@USE_BLOWFISH_TRUE@am__append_14 = plugins/blowfish/libstrongswan-blowfish.la -@USE_MD4_TRUE@am__append_15 = plugins/md4 -@MONOLITHIC_TRUE@@USE_MD4_TRUE@am__append_16 = plugins/md4/libstrongswan-md4.la -@USE_MD5_TRUE@am__append_17 = plugins/md5 -@MONOLITHIC_TRUE@@USE_MD5_TRUE@am__append_18 = plugins/md5/libstrongswan-md5.la -@USE_SHA1_TRUE@am__append_19 = plugins/sha1 -@MONOLITHIC_TRUE@@USE_SHA1_TRUE@am__append_20 = plugins/sha1/libstrongswan-sha1.la -@USE_SHA2_TRUE@am__append_21 = plugins/sha2 -@MONOLITHIC_TRUE@@USE_SHA2_TRUE@am__append_22 = plugins/sha2/libstrongswan-sha2.la -@USE_GMP_TRUE@am__append_23 = plugins/gmp -@MONOLITHIC_TRUE@@USE_GMP_TRUE@am__append_24 = plugins/gmp/libstrongswan-gmp.la -@USE_RANDOM_TRUE@am__append_25 = plugins/random -@MONOLITHIC_TRUE@@USE_RANDOM_TRUE@am__append_26 = plugins/random/libstrongswan-random.la -@USE_HMAC_TRUE@am__append_27 = plugins/hmac -@MONOLITHIC_TRUE@@USE_HMAC_TRUE@am__append_28 = plugins/hmac/libstrongswan-hmac.la -@USE_CMAC_TRUE@am__append_29 = plugins/cmac -@MONOLITHIC_TRUE@@USE_CMAC_TRUE@am__append_30 = plugins/cmac/libstrongswan-cmac.la -@USE_XCBC_TRUE@am__append_31 = plugins/xcbc -@MONOLITHIC_TRUE@@USE_XCBC_TRUE@am__append_32 = plugins/xcbc/libstrongswan-xcbc.la -@USE_X509_TRUE@am__append_33 = plugins/x509 -@MONOLITHIC_TRUE@@USE_X509_TRUE@am__append_34 = plugins/x509/libstrongswan-x509.la -@USE_REVOCATION_TRUE@am__append_35 = plugins/revocation -@MONOLITHIC_TRUE@@USE_REVOCATION_TRUE@am__append_36 = plugins/revocation/libstrongswan-revocation.la -@USE_CONSTRAINTS_TRUE@am__append_37 = plugins/constraints -@MONOLITHIC_TRUE@@USE_CONSTRAINTS_TRUE@am__append_38 = plugins/constraints/libstrongswan-constraints.la -@USE_PUBKEY_TRUE@am__append_39 = plugins/pubkey -@MONOLITHIC_TRUE@@USE_PUBKEY_TRUE@am__append_40 = plugins/pubkey/libstrongswan-pubkey.la -@USE_PKCS1_TRUE@am__append_41 = plugins/pkcs1 -@MONOLITHIC_TRUE@@USE_PKCS1_TRUE@am__append_42 = plugins/pkcs1/libstrongswan-pkcs1.la -@USE_PKCS8_TRUE@am__append_43 = plugins/pkcs8 -@MONOLITHIC_TRUE@@USE_PKCS8_TRUE@am__append_44 = plugins/pkcs8/libstrongswan-pkcs8.la -@USE_PGP_TRUE@am__append_45 = plugins/pgp -@MONOLITHIC_TRUE@@USE_PGP_TRUE@am__append_46 = plugins/pgp/libstrongswan-pgp.la -@USE_DNSKEY_TRUE@am__append_47 = plugins/dnskey -@MONOLITHIC_TRUE@@USE_DNSKEY_TRUE@am__append_48 = plugins/dnskey/libstrongswan-dnskey.la -@USE_PEM_TRUE@am__append_49 = plugins/pem -@MONOLITHIC_TRUE@@USE_PEM_TRUE@am__append_50 = plugins/pem/libstrongswan-pem.la -@USE_CURL_TRUE@am__append_51 = plugins/curl -@MONOLITHIC_TRUE@@USE_CURL_TRUE@am__append_52 = plugins/curl/libstrongswan-curl.la -@USE_SOUP_TRUE@am__append_53 = plugins/soup -@MONOLITHIC_TRUE@@USE_SOUP_TRUE@am__append_54 = plugins/soup/libstrongswan-soup.la -@USE_LDAP_TRUE@am__append_55 = plugins/ldap -@MONOLITHIC_TRUE@@USE_LDAP_TRUE@am__append_56 = plugins/ldap/libstrongswan-ldap.la -@USE_MYSQL_TRUE@am__append_57 = plugins/mysql -@MONOLITHIC_TRUE@@USE_MYSQL_TRUE@am__append_58 = plugins/mysql/libstrongswan-mysql.la -@USE_SQLITE_TRUE@am__append_59 = plugins/sqlite -@MONOLITHIC_TRUE@@USE_SQLITE_TRUE@am__append_60 = plugins/sqlite/libstrongswan-sqlite.la -@USE_PADLOCK_TRUE@am__append_61 = plugins/padlock -@MONOLITHIC_TRUE@@USE_PADLOCK_TRUE@am__append_62 = plugins/padlock/libstrongswan-padlock.la -@USE_OPENSSL_TRUE@am__append_63 = plugins/openssl -@MONOLITHIC_TRUE@@USE_OPENSSL_TRUE@am__append_64 = plugins/openssl/libstrongswan-openssl.la -@USE_GCRYPT_TRUE@am__append_65 = plugins/gcrypt -@MONOLITHIC_TRUE@@USE_GCRYPT_TRUE@am__append_66 = plugins/gcrypt/libstrongswan-gcrypt.la -@USE_FIPS_PRF_TRUE@am__append_67 = plugins/fips_prf -@MONOLITHIC_TRUE@@USE_FIPS_PRF_TRUE@am__append_68 = plugins/fips_prf/libstrongswan-fips-prf.la -@USE_AGENT_TRUE@am__append_69 = plugins/agent -@MONOLITHIC_TRUE@@USE_AGENT_TRUE@am__append_70 = plugins/agent/libstrongswan-agent.la -@USE_PKCS11_TRUE@am__append_71 = plugins/pkcs11 -@MONOLITHIC_TRUE@@USE_PKCS11_TRUE@am__append_72 = plugins/pkcs11/libstrongswan-pkcs11.la -@USE_CTR_TRUE@am__append_73 = plugins/ctr -@MONOLITHIC_TRUE@@USE_CTR_TRUE@am__append_74 = plugins/ctr/libstrongswan-ctr.la -@USE_CCM_TRUE@am__append_75 = plugins/ccm -@MONOLITHIC_TRUE@@USE_CCM_TRUE@am__append_76 = plugins/ccm/libstrongswan-ccm.la -@USE_GCM_TRUE@am__append_77 = plugins/gcm -@MONOLITHIC_TRUE@@USE_GCM_TRUE@am__append_78 = plugins/gcm/libstrongswan-gcm.la -@USE_TEST_VECTORS_TRUE@am__append_79 = plugins/test_vectors -@MONOLITHIC_TRUE@@USE_TEST_VECTORS_TRUE@am__append_80 = plugins/test_vectors/libstrongswan-test-vectors.la +@USE_LIBCAP_TRUE@am__append_7 = -lcap +@USE_AF_ALG_TRUE@am__append_8 = plugins/af_alg +@MONOLITHIC_TRUE@@USE_AF_ALG_TRUE@am__append_9 = plugins/af_alg/libstrongswan-af-alg.la +@USE_AES_TRUE@am__append_10 = plugins/aes +@MONOLITHIC_TRUE@@USE_AES_TRUE@am__append_11 = plugins/aes/libstrongswan-aes.la +@USE_DES_TRUE@am__append_12 = plugins/des +@MONOLITHIC_TRUE@@USE_DES_TRUE@am__append_13 = plugins/des/libstrongswan-des.la +@USE_BLOWFISH_TRUE@am__append_14 = plugins/blowfish +@MONOLITHIC_TRUE@@USE_BLOWFISH_TRUE@am__append_15 = plugins/blowfish/libstrongswan-blowfish.la +@USE_MD4_TRUE@am__append_16 = plugins/md4 +@MONOLITHIC_TRUE@@USE_MD4_TRUE@am__append_17 = plugins/md4/libstrongswan-md4.la +@USE_MD5_TRUE@am__append_18 = plugins/md5 +@MONOLITHIC_TRUE@@USE_MD5_TRUE@am__append_19 = plugins/md5/libstrongswan-md5.la +@USE_SHA1_TRUE@am__append_20 = plugins/sha1 +@MONOLITHIC_TRUE@@USE_SHA1_TRUE@am__append_21 = plugins/sha1/libstrongswan-sha1.la +@USE_SHA2_TRUE@am__append_22 = plugins/sha2 +@MONOLITHIC_TRUE@@USE_SHA2_TRUE@am__append_23 = plugins/sha2/libstrongswan-sha2.la +@USE_GMP_TRUE@am__append_24 = plugins/gmp +@MONOLITHIC_TRUE@@USE_GMP_TRUE@am__append_25 = plugins/gmp/libstrongswan-gmp.la +@USE_RANDOM_TRUE@am__append_26 = plugins/random +@MONOLITHIC_TRUE@@USE_RANDOM_TRUE@am__append_27 = plugins/random/libstrongswan-random.la +@USE_NONCE_TRUE@am__append_28 = plugins/nonce +@MONOLITHIC_TRUE@@USE_NONCE_TRUE@am__append_29 = plugins/nonce/libstrongswan-nonce.la +@USE_HMAC_TRUE@am__append_30 = plugins/hmac +@MONOLITHIC_TRUE@@USE_HMAC_TRUE@am__append_31 = plugins/hmac/libstrongswan-hmac.la +@USE_CMAC_TRUE@am__append_32 = plugins/cmac +@MONOLITHIC_TRUE@@USE_CMAC_TRUE@am__append_33 = plugins/cmac/libstrongswan-cmac.la +@USE_XCBC_TRUE@am__append_34 = plugins/xcbc +@MONOLITHIC_TRUE@@USE_XCBC_TRUE@am__append_35 = plugins/xcbc/libstrongswan-xcbc.la +@USE_X509_TRUE@am__append_36 = plugins/x509 +@MONOLITHIC_TRUE@@USE_X509_TRUE@am__append_37 = plugins/x509/libstrongswan-x509.la +@USE_REVOCATION_TRUE@am__append_38 = plugins/revocation +@MONOLITHIC_TRUE@@USE_REVOCATION_TRUE@am__append_39 = plugins/revocation/libstrongswan-revocation.la +@USE_CONSTRAINTS_TRUE@am__append_40 = plugins/constraints +@MONOLITHIC_TRUE@@USE_CONSTRAINTS_TRUE@am__append_41 = plugins/constraints/libstrongswan-constraints.la +@USE_PUBKEY_TRUE@am__append_42 = plugins/pubkey +@MONOLITHIC_TRUE@@USE_PUBKEY_TRUE@am__append_43 = plugins/pubkey/libstrongswan-pubkey.la +@USE_PKCS1_TRUE@am__append_44 = plugins/pkcs1 +@MONOLITHIC_TRUE@@USE_PKCS1_TRUE@am__append_45 = plugins/pkcs1/libstrongswan-pkcs1.la +@USE_PKCS8_TRUE@am__append_46 = plugins/pkcs8 +@MONOLITHIC_TRUE@@USE_PKCS8_TRUE@am__append_47 = plugins/pkcs8/libstrongswan-pkcs8.la +@USE_PGP_TRUE@am__append_48 = plugins/pgp +@MONOLITHIC_TRUE@@USE_PGP_TRUE@am__append_49 = plugins/pgp/libstrongswan-pgp.la +@USE_DNSKEY_TRUE@am__append_50 = plugins/dnskey +@MONOLITHIC_TRUE@@USE_DNSKEY_TRUE@am__append_51 = plugins/dnskey/libstrongswan-dnskey.la +@USE_PEM_TRUE@am__append_52 = plugins/pem +@MONOLITHIC_TRUE@@USE_PEM_TRUE@am__append_53 = plugins/pem/libstrongswan-pem.la +@USE_CURL_TRUE@am__append_54 = plugins/curl +@MONOLITHIC_TRUE@@USE_CURL_TRUE@am__append_55 = plugins/curl/libstrongswan-curl.la +@USE_SOUP_TRUE@am__append_56 = plugins/soup +@MONOLITHIC_TRUE@@USE_SOUP_TRUE@am__append_57 = plugins/soup/libstrongswan-soup.la +@USE_LDAP_TRUE@am__append_58 = plugins/ldap +@MONOLITHIC_TRUE@@USE_LDAP_TRUE@am__append_59 = plugins/ldap/libstrongswan-ldap.la +@USE_MYSQL_TRUE@am__append_60 = plugins/mysql +@MONOLITHIC_TRUE@@USE_MYSQL_TRUE@am__append_61 = plugins/mysql/libstrongswan-mysql.la +@USE_SQLITE_TRUE@am__append_62 = plugins/sqlite +@MONOLITHIC_TRUE@@USE_SQLITE_TRUE@am__append_63 = plugins/sqlite/libstrongswan-sqlite.la +@USE_PADLOCK_TRUE@am__append_64 = plugins/padlock +@MONOLITHIC_TRUE@@USE_PADLOCK_TRUE@am__append_65 = plugins/padlock/libstrongswan-padlock.la +@USE_OPENSSL_TRUE@am__append_66 = plugins/openssl +@MONOLITHIC_TRUE@@USE_OPENSSL_TRUE@am__append_67 = plugins/openssl/libstrongswan-openssl.la +@USE_GCRYPT_TRUE@am__append_68 = plugins/gcrypt +@MONOLITHIC_TRUE@@USE_GCRYPT_TRUE@am__append_69 = plugins/gcrypt/libstrongswan-gcrypt.la +@USE_FIPS_PRF_TRUE@am__append_70 = plugins/fips_prf +@MONOLITHIC_TRUE@@USE_FIPS_PRF_TRUE@am__append_71 = plugins/fips_prf/libstrongswan-fips-prf.la +@USE_AGENT_TRUE@am__append_72 = plugins/agent +@MONOLITHIC_TRUE@@USE_AGENT_TRUE@am__append_73 = plugins/agent/libstrongswan-agent.la +@USE_PKCS11_TRUE@am__append_74 = plugins/pkcs11 +@MONOLITHIC_TRUE@@USE_PKCS11_TRUE@am__append_75 = plugins/pkcs11/libstrongswan-pkcs11.la +@USE_CTR_TRUE@am__append_76 = plugins/ctr +@MONOLITHIC_TRUE@@USE_CTR_TRUE@am__append_77 = plugins/ctr/libstrongswan-ctr.la +@USE_CCM_TRUE@am__append_78 = plugins/ccm +@MONOLITHIC_TRUE@@USE_CCM_TRUE@am__append_79 = plugins/ccm/libstrongswan-ccm.la +@USE_GCM_TRUE@am__append_80 = plugins/gcm +@MONOLITHIC_TRUE@@USE_GCM_TRUE@am__append_81 = plugins/gcm/libstrongswan-gcm.la +@USE_TEST_VECTORS_TRUE@am__append_82 = plugins/test_vectors +@MONOLITHIC_TRUE@@USE_TEST_VECTORS_TRUE@am__append_83 = plugins/test_vectors/libstrongswan-test-vectors.la subdir = src/libstrongswan -DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in +DIST_COMMON = $(am__nobase_strongswan_include_HEADERS_DIST) \ + $(srcdir)/Makefile.am $(srcdir)/Makefile.in ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/config/libtool.m4 \ $(top_srcdir)/m4/config/ltoptions.m4 \ @@ -133,6 +134,7 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/config/libtool.m4 \ am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; @@ -156,101 +158,70 @@ am__nobase_list = $(am__nobase_strip_setup); \ am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' -am__installdirs = "$(DESTDIR)$(ipseclibdir)" +am__installdirs = "$(DESTDIR)$(ipseclibdir)" \ + "$(DESTDIR)$(strongswan_includedir)" LTLIBRARIES = $(ipseclib_LTLIBRARIES) am__DEPENDENCIES_1 = libstrongswan_la_DEPENDENCIES = $(am__DEPENDENCIES_1) \ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \ - $(am__DEPENDENCIES_1) $(am__append_8) $(am__append_10) \ - $(am__append_12) $(am__append_14) $(am__append_16) \ - $(am__append_18) $(am__append_20) $(am__append_22) \ - $(am__append_24) $(am__append_26) $(am__append_28) \ - $(am__append_30) $(am__append_32) $(am__append_34) \ - $(am__append_36) $(am__append_38) $(am__append_40) \ - $(am__append_42) $(am__append_44) $(am__append_46) \ - $(am__append_48) $(am__append_50) $(am__append_52) \ - $(am__append_54) $(am__append_56) $(am__append_58) \ - $(am__append_60) $(am__append_62) $(am__append_64) \ - $(am__append_66) $(am__append_68) $(am__append_70) \ - $(am__append_72) $(am__append_74) $(am__append_76) \ - $(am__append_78) $(am__append_80) -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 \ - bio/bio_reader.h bio/bio_reader.c bio/bio_writer.h \ - bio/bio_writer.c crypto/crypters/crypter.c \ - crypto/crypters/crypter.h crypto/hashers/hasher.h \ - crypto/hashers/hasher.c crypto/pkcs9.c crypto/pkcs9.h \ + $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) $(am__append_9) $(am__append_11) \ + $(am__append_13) $(am__append_15) $(am__append_17) \ + $(am__append_19) $(am__append_21) $(am__append_23) \ + $(am__append_25) $(am__append_27) $(am__append_29) \ + $(am__append_31) $(am__append_33) $(am__append_35) \ + $(am__append_37) $(am__append_39) $(am__append_41) \ + $(am__append_43) $(am__append_45) $(am__append_47) \ + $(am__append_49) $(am__append_51) $(am__append_53) \ + $(am__append_55) $(am__append_57) $(am__append_59) \ + $(am__append_61) $(am__append_63) $(am__append_65) \ + $(am__append_67) $(am__append_69) $(am__append_71) \ + $(am__append_73) $(am__append_75) $(am__append_77) \ + $(am__append_79) $(am__append_81) $(am__append_83) +am__libstrongswan_la_SOURCES_DIST = library.c chunk.c debug.c enum.c \ + settings.c printf_hook.c asn1/asn1.c asn1/asn1_parser.c \ + asn1/oid.c bio/bio_reader.c bio/bio_writer.c \ + crypto/crypters/crypter.c crypto/hashers/hasher.c \ + crypto/pkcs7.c crypto/pkcs9.c \ crypto/proposal/proposal_keywords.c \ - crypto/proposal/proposal_keywords.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/crypto_factory.c \ - crypto/crypto_factory.h crypto/crypto_tester.c \ - crypto/crypto_tester.h crypto/diffie_hellman.c \ - crypto/diffie_hellman.h crypto/aead.c crypto/aead.h \ - crypto/transform.c crypto/transform.h \ - credentials/credential_factory.c \ - credentials/credential_factory.h credentials/builder.c \ - credentials/builder.h credentials/cred_encoding.c \ - credentials/cred_encoding.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 \ + crypto/proposal/proposal_keywords_static.c crypto/prfs/prf.c \ + crypto/prfs/mac_prf.c crypto/rngs/rng.c crypto/prf_plus.c \ + crypto/signers/signer.c crypto/signers/mac_signer.c \ + crypto/crypto_factory.c crypto/crypto_tester.c \ + crypto/diffie_hellman.c crypto/aead.c crypto/transform.c \ + credentials/credential_factory.c credentials/builder.c \ + credentials/cred_encoding.c credentials/keys/private_key.c \ + credentials/keys/public_key.c credentials/keys/shared_key.c \ credentials/certificates/certificate.c \ - credentials/certificates/certificate.h \ - credentials/certificates/x509.h credentials/certificates/ac.h \ - credentials/certificates/crl.h credentials/certificates/crl.c \ - credentials/certificates/pkcs10.h \ - credentials/certificates/ocsp_request.h \ - credentials/certificates/ocsp_response.h \ + credentials/certificates/crl.c \ credentials/certificates/ocsp_response.c \ - credentials/certificates/pgp_certificate.h \ credentials/ietf_attributes/ietf_attributes.c \ - credentials/ietf_attributes/ietf_attributes.h \ credentials/credential_manager.c \ - credentials/credential_manager.h \ credentials/sets/auth_cfg_wrapper.c \ - credentials/sets/auth_cfg_wrapper.h \ credentials/sets/ocsp_response_wrapper.c \ - credentials/sets/ocsp_response_wrapper.h \ - credentials/sets/cert_cache.c credentials/sets/cert_cache.h \ - credentials/sets/mem_cred.c credentials/sets/mem_cred.h \ - credentials/sets/callback_cred.c \ - credentials/sets/callback_cred.h credentials/auth_cfg.c \ - credentials/auth_cfg.h credentials/credential_set.h \ - credentials/cert_validator.h database/database.h \ - database/database.c database/database_factory.h \ - database/database_factory.c fetcher/fetcher.h \ - fetcher/fetcher.c fetcher/fetcher_manager.h \ - fetcher/fetcher_manager.c eap/eap.h eap/eap.c pen/pen.h \ - pen/pen.c plugins/plugin_loader.c plugins/plugin_loader.h \ - plugins/plugin.h plugins/plugin_feature.c \ - plugins/plugin_feature.h processing/jobs/job.h \ - processing/jobs/job.c processing/jobs/callback_job.c \ - processing/jobs/callback_job.h processing/processor.c \ - processing/processor.h processing/scheduler.c \ - processing/scheduler.h selectors/traffic_selector.c \ - selectors/traffic_selector.h threading/thread.h \ - threading/thread.c threading/thread_value.h \ - threading/thread_value.c threading/mutex.h threading/mutex.c \ - threading/condvar.h threading/rwlock.h threading/rwlock.c \ - threading/lock_profiler.h utils.h utils.c utils/host.c \ - utils/host.h utils/identification.c utils/identification.h \ - utils/lexparser.c utils/lexparser.h utils/linked_list.c \ - utils/linked_list.h utils/hashtable.c utils/hashtable.h \ - utils/enumerator.c utils/enumerator.h utils/optionsfrom.c \ - utils/optionsfrom.h utils/backtrace.c utils/backtrace.h \ - utils/leak_detective.c utils/leak_detective.h \ - integrity_checker.c integrity_checker.h + credentials/sets/cert_cache.c credentials/sets/mem_cred.c \ + credentials/sets/callback_cred.c credentials/auth_cfg.c \ + database/database.c database/database_factory.c \ + fetcher/fetcher.c fetcher/fetcher_manager.c eap/eap.c \ + ipsec/ipsec_types.c pen/pen.c plugins/plugin_loader.c \ + plugins/plugin_feature.c processing/jobs/job.c \ + processing/jobs/callback_job.c processing/processor.c \ + processing/scheduler.c selectors/traffic_selector.c \ + threading/thread.c threading/thread_value.c threading/mutex.c \ + threading/semaphore.c threading/rwlock.c threading/spinlock.c \ + utils.c utils/host.c utils/packet.c utils/identification.c \ + utils/lexparser.c utils/linked_list.c utils/blocking_queue.c \ + utils/hashtable.c utils/enumerator.c utils/optionsfrom.c \ + utils/capabilities.c utils/backtrace.c utils/tun_device.c \ + utils/leak_detective.c integrity_checker.c @USE_LEAK_DETECTIVE_TRUE@am__objects_1 = leak_detective.lo @USE_INTEGRITY_TEST_TRUE@am__objects_2 = integrity_checker.lo am_libstrongswan_la_OBJECTS = library.lo chunk.lo debug.lo enum.lo \ settings.lo printf_hook.lo asn1.lo asn1_parser.lo oid.lo \ - bio_reader.lo bio_writer.lo crypter.lo hasher.lo pkcs9.lo \ - proposal_keywords.lo prf.lo rng.lo prf_plus.lo signer.lo \ + bio_reader.lo bio_writer.lo crypter.lo hasher.lo pkcs7.lo \ + pkcs9.lo proposal_keywords.lo proposal_keywords_static.lo \ + prf.lo mac_prf.lo rng.lo prf_plus.lo signer.lo mac_signer.lo \ crypto_factory.lo crypto_tester.lo diffie_hellman.lo aead.lo \ transform.lo credential_factory.lo builder.lo cred_encoding.lo \ private_key.lo public_key.lo shared_key.lo certificate.lo \ @@ -258,14 +229,16 @@ am_libstrongswan_la_OBJECTS = library.lo chunk.lo debug.lo enum.lo \ credential_manager.lo auth_cfg_wrapper.lo \ ocsp_response_wrapper.lo cert_cache.lo mem_cred.lo \ callback_cred.lo auth_cfg.lo database.lo database_factory.lo \ - fetcher.lo fetcher_manager.lo eap.lo pen.lo plugin_loader.lo \ - plugin_feature.lo job.lo callback_job.lo processor.lo \ - scheduler.lo traffic_selector.lo thread.lo thread_value.lo \ - mutex.lo rwlock.lo utils.lo host.lo identification.lo \ - lexparser.lo linked_list.lo hashtable.lo enumerator.lo \ - optionsfrom.lo backtrace.lo $(am__objects_1) $(am__objects_2) + fetcher.lo fetcher_manager.lo eap.lo ipsec_types.lo pen.lo \ + plugin_loader.lo plugin_feature.lo job.lo callback_job.lo \ + processor.lo scheduler.lo traffic_selector.lo thread.lo \ + thread_value.lo mutex.lo semaphore.lo rwlock.lo spinlock.lo \ + utils.lo host.lo packet.lo identification.lo lexparser.lo \ + linked_list.lo blocking_queue.lo hashtable.lo enumerator.lo \ + optionsfrom.lo capabilities.lo backtrace.lo tun_device.lo \ + $(am__objects_1) $(am__objects_2) libstrongswan_la_OBJECTS = $(am_libstrongswan_la_OBJECTS) -DEFAULT_INCLUDES = -I.@am__isrc@ +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles am__mv = mv -f @@ -287,6 +260,51 @@ RECURSIVE_TARGETS = all-recursive check-recursive dvi-recursive \ install-pdf-recursive install-ps-recursive install-recursive \ installcheck-recursive installdirs-recursive pdf-recursive \ ps-recursive uninstall-recursive +am__nobase_strongswan_include_HEADERS_DIST = library.h chunk.h debug.h \ + enum.h settings.h printf_hook.h asn1/asn1.h asn1/asn1_parser.h \ + asn1/oid.h bio/bio_reader.h bio/bio_writer.h \ + crypto/crypters/crypter.h crypto/hashers/hasher.h crypto/mac.h \ + crypto/pkcs7.h crypto/pkcs9.h \ + crypto/proposal/proposal_keywords.h \ + crypto/proposal/proposal_keywords_static.h crypto/prfs/prf.h \ + crypto/prfs/mac_prf.h crypto/rngs/rng.h crypto/nonce_gen.h \ + crypto/prf_plus.h crypto/signers/signer.h \ + crypto/signers/mac_signer.h crypto/crypto_factory.h \ + crypto/crypto_tester.h crypto/diffie_hellman.h crypto/aead.h \ + crypto/transform.h credentials/credential_factory.h \ + credentials/builder.h credentials/cred_encoding.h \ + credentials/keys/private_key.h credentials/keys/public_key.h \ + credentials/keys/shared_key.h \ + credentials/certificates/certificate.h \ + credentials/certificates/x509.h credentials/certificates/ac.h \ + credentials/certificates/crl.h \ + credentials/certificates/pkcs10.h \ + credentials/certificates/ocsp_request.h \ + credentials/certificates/ocsp_response.h \ + credentials/certificates/pgp_certificate.h \ + credentials/ietf_attributes/ietf_attributes.h \ + credentials/credential_manager.h \ + credentials/sets/auth_cfg_wrapper.h \ + credentials/sets/ocsp_response_wrapper.h \ + credentials/sets/cert_cache.h credentials/sets/mem_cred.h \ + credentials/sets/callback_cred.h credentials/auth_cfg.h \ + credentials/credential_set.h credentials/cert_validator.h \ + database/database.h database/database_factory.h \ + fetcher/fetcher.h fetcher/fetcher_manager.h eap/eap.h \ + pen/pen.h ipsec/ipsec_types.h plugins/plugin_loader.h \ + plugins/plugin.h plugins/plugin_feature.h \ + processing/jobs/job.h processing/jobs/callback_job.h \ + processing/processor.h processing/scheduler.h \ + selectors/traffic_selector.h threading/thread.h \ + threading/thread_value.h threading/mutex.h threading/condvar.h \ + threading/spinlock.h threading/semaphore.h threading/rwlock.h \ + threading/rwlock_condvar.h threading/lock_profiler.h utils.h \ + utils/host.h utils/packet.h utils/identification.h \ + utils/lexparser.h utils/linked_list.h utils/blocking_queue.h \ + utils/hashtable.h utils/enumerator.h utils/optionsfrom.h \ + utils/capabilities.h utils/backtrace.h utils/tun_device.h \ + utils/leak_detective.h integrity_checker.h +HEADERS = $(nobase_strongswan_include_HEADERS) RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ distclean-recursive maintainer-clean-recursive AM_RECURSIVE_TARGETS = $(RECURSIVE_TARGETS:-recursive=) \ @@ -296,14 +314,14 @@ ETAGS = etags CTAGS = ctags DIST_SUBDIRS = . plugins/af_alg plugins/aes plugins/des \ plugins/blowfish plugins/md4 plugins/md5 plugins/sha1 \ - plugins/sha2 plugins/gmp plugins/random plugins/hmac \ - plugins/cmac plugins/xcbc plugins/x509 plugins/revocation \ - plugins/constraints plugins/pubkey plugins/pkcs1 plugins/pkcs8 \ - plugins/pgp plugins/dnskey plugins/pem plugins/curl \ - plugins/soup plugins/ldap plugins/mysql plugins/sqlite \ - plugins/padlock plugins/openssl plugins/gcrypt \ - plugins/fips_prf plugins/agent plugins/pkcs11 plugins/ctr \ - plugins/ccm plugins/gcm plugins/test_vectors + plugins/sha2 plugins/gmp plugins/random plugins/nonce \ + plugins/hmac plugins/cmac plugins/xcbc plugins/x509 \ + plugins/revocation plugins/constraints plugins/pubkey \ + plugins/pkcs1 plugins/pkcs8 plugins/pgp plugins/dnskey \ + plugins/pem plugins/curl plugins/soup plugins/ldap \ + plugins/mysql plugins/sqlite plugins/padlock plugins/openssl \ + plugins/gcrypt plugins/fips_prf plugins/agent plugins/pkcs11 \ + plugins/ctr plugins/ccm plugins/gcm plugins/test_vectors DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) am__relativize = \ dir0=`pwd`; \ @@ -338,6 +356,7 @@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ +BFDLIB = @BFDLIB@ BTLIB = @BTLIB@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ @@ -432,11 +451,14 @@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ c_plugins = @c_plugins@ +charon_natt_port = @charon_natt_port@ +charon_plugins = @charon_plugins@ +charon_udp_port = @charon_udp_port@ clearsilver_LIBS = @clearsilver_LIBS@ datadir = @datadir@ datarootdir = @datarootdir@ dbusservicedir = @dbusservicedir@ -default_pkcs11 = @default_pkcs11@ +dev_headers = @dev_headers@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ @@ -453,11 +475,12 @@ imcvdir = @imcvdir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ +ipsec_script = @ipsec_script@ +ipsec_script_upper = @ipsec_script_upper@ ipsecdir = @ipsecdir@ ipsecgroup = @ipsecgroup@ ipseclibdir = @ipseclibdir@ ipsecuser = @ipsecuser@ -libcharon_plugins = @libcharon_plugins@ libdir = @libdir@ libexecdir = @libexecdir@ linux_headers = @linux_headers@ @@ -473,6 +496,7 @@ mkdir_p = @mkdir_p@ nm_CFLAGS = @nm_CFLAGS@ nm_LIBS = @nm_LIBS@ nm_ca_dir = @nm_ca_dir@ +nm_plugins = @nm_plugins@ oldincludedir = @oldincludedir@ openac_plugins = @openac_plugins@ p_plugins = @p_plugins@ @@ -482,7 +506,6 @@ pdfdir = @pdfdir@ piddir = @piddir@ pki_plugins = @pki_plugins@ plugindir = @plugindir@ -pluto_plugins = @pluto_plugins@ pool_plugins = @pool_plugins@ prefix = @prefix@ program_transform_name = @program_transform_name@ @@ -511,88 +534,93 @@ urandom_device = @urandom_device@ xml_CFLAGS = @xml_CFLAGS@ xml_LIBS = @xml_LIBS@ ipseclib_LTLIBRARIES = libstrongswan.la -libstrongswan_la_SOURCES = 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 bio/bio_reader.h \ - bio/bio_reader.c bio/bio_writer.h bio/bio_writer.c \ - crypto/crypters/crypter.c crypto/crypters/crypter.h \ - crypto/hashers/hasher.h crypto/hashers/hasher.c crypto/pkcs9.c \ - crypto/pkcs9.h crypto/proposal/proposal_keywords.c \ - crypto/proposal/proposal_keywords.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/crypto_factory.c \ - crypto/crypto_factory.h crypto/crypto_tester.c \ - crypto/crypto_tester.h crypto/diffie_hellman.c \ - crypto/diffie_hellman.h crypto/aead.c crypto/aead.h \ - crypto/transform.c crypto/transform.h \ - credentials/credential_factory.c \ - credentials/credential_factory.h credentials/builder.c \ - credentials/builder.h credentials/cred_encoding.c \ - credentials/cred_encoding.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 \ +libstrongswan_la_SOURCES = library.c chunk.c debug.c enum.c settings.c \ + printf_hook.c asn1/asn1.c asn1/asn1_parser.c asn1/oid.c \ + bio/bio_reader.c bio/bio_writer.c crypto/crypters/crypter.c \ + crypto/hashers/hasher.c crypto/pkcs7.c crypto/pkcs9.c \ + crypto/proposal/proposal_keywords.c \ + crypto/proposal/proposal_keywords_static.c crypto/prfs/prf.c \ + crypto/prfs/mac_prf.c crypto/rngs/rng.c crypto/prf_plus.c \ + crypto/signers/signer.c crypto/signers/mac_signer.c \ + crypto/crypto_factory.c crypto/crypto_tester.c \ + crypto/diffie_hellman.c crypto/aead.c crypto/transform.c \ + credentials/credential_factory.c credentials/builder.c \ + credentials/cred_encoding.c credentials/keys/private_key.c \ + credentials/keys/public_key.c credentials/keys/shared_key.c \ credentials/certificates/certificate.c \ - credentials/certificates/certificate.h \ - credentials/certificates/x509.h credentials/certificates/ac.h \ - credentials/certificates/crl.h credentials/certificates/crl.c \ - credentials/certificates/pkcs10.h \ - credentials/certificates/ocsp_request.h \ - credentials/certificates/ocsp_response.h \ + credentials/certificates/crl.c \ credentials/certificates/ocsp_response.c \ - credentials/certificates/pgp_certificate.h \ credentials/ietf_attributes/ietf_attributes.c \ - credentials/ietf_attributes/ietf_attributes.h \ credentials/credential_manager.c \ - credentials/credential_manager.h \ credentials/sets/auth_cfg_wrapper.c \ - credentials/sets/auth_cfg_wrapper.h \ credentials/sets/ocsp_response_wrapper.c \ - credentials/sets/ocsp_response_wrapper.h \ - credentials/sets/cert_cache.c credentials/sets/cert_cache.h \ - credentials/sets/mem_cred.c credentials/sets/mem_cred.h \ - credentials/sets/callback_cred.c \ - credentials/sets/callback_cred.h credentials/auth_cfg.c \ - credentials/auth_cfg.h credentials/credential_set.h \ - credentials/cert_validator.h database/database.h \ - database/database.c database/database_factory.h \ - database/database_factory.c fetcher/fetcher.h \ - fetcher/fetcher.c fetcher/fetcher_manager.h \ - fetcher/fetcher_manager.c eap/eap.h eap/eap.c pen/pen.h \ - pen/pen.c plugins/plugin_loader.c plugins/plugin_loader.h \ - plugins/plugin.h plugins/plugin_feature.c \ - plugins/plugin_feature.h processing/jobs/job.h \ - processing/jobs/job.c processing/jobs/callback_job.c \ - processing/jobs/callback_job.h processing/processor.c \ - processing/processor.h processing/scheduler.c \ - processing/scheduler.h selectors/traffic_selector.c \ - selectors/traffic_selector.h threading/thread.h \ - threading/thread.c threading/thread_value.h \ - threading/thread_value.c threading/mutex.h threading/mutex.c \ - threading/condvar.h threading/rwlock.h threading/rwlock.c \ - threading/lock_profiler.h utils.h utils.c utils/host.c \ - utils/host.h utils/identification.c utils/identification.h \ - utils/lexparser.c utils/lexparser.h utils/linked_list.c \ - utils/linked_list.h utils/hashtable.c utils/hashtable.h \ - utils/enumerator.c utils/enumerator.h utils/optionsfrom.c \ - utils/optionsfrom.h utils/backtrace.c utils/backtrace.h \ + credentials/sets/cert_cache.c credentials/sets/mem_cred.c \ + credentials/sets/callback_cred.c credentials/auth_cfg.c \ + database/database.c database/database_factory.c \ + fetcher/fetcher.c fetcher/fetcher_manager.c eap/eap.c \ + ipsec/ipsec_types.c pen/pen.c plugins/plugin_loader.c \ + plugins/plugin_feature.c processing/jobs/job.c \ + processing/jobs/callback_job.c processing/processor.c \ + processing/scheduler.c selectors/traffic_selector.c \ + threading/thread.c threading/thread_value.c threading/mutex.c \ + threading/semaphore.c threading/rwlock.c threading/spinlock.c \ + utils.c utils/host.c utils/packet.c utils/identification.c \ + utils/lexparser.c utils/linked_list.c utils/blocking_queue.c \ + utils/hashtable.c utils/enumerator.c utils/optionsfrom.c \ + utils/capabilities.c utils/backtrace.c utils/tun_device.c \ $(am__append_2) $(am__append_5) +@USE_DEV_HEADERS_TRUE@strongswan_includedir = ${dev_headers} +@USE_DEV_HEADERS_TRUE@nobase_strongswan_include_HEADERS = \ +@USE_DEV_HEADERS_TRUE@library.h chunk.h debug.h enum.h settings.h printf_hook.h \ +@USE_DEV_HEADERS_TRUE@asn1/asn1.h asn1/asn1_parser.h asn1/oid.h bio/bio_reader.h bio/bio_writer.h \ +@USE_DEV_HEADERS_TRUE@crypto/crypters/crypter.h crypto/hashers/hasher.h crypto/mac.h \ +@USE_DEV_HEADERS_TRUE@crypto/pkcs7.h crypto/pkcs9.h crypto/proposal/proposal_keywords.h \ +@USE_DEV_HEADERS_TRUE@crypto/proposal/proposal_keywords_static.h \ +@USE_DEV_HEADERS_TRUE@crypto/prfs/prf.h crypto/prfs/mac_prf.h crypto/rngs/rng.h crypto/nonce_gen.h \ +@USE_DEV_HEADERS_TRUE@crypto/prf_plus.h crypto/signers/signer.h crypto/signers/mac_signer.h \ +@USE_DEV_HEADERS_TRUE@crypto/crypto_factory.h crypto/crypto_tester.h crypto/diffie_hellman.h \ +@USE_DEV_HEADERS_TRUE@crypto/aead.h crypto/transform.h \ +@USE_DEV_HEADERS_TRUE@credentials/credential_factory.h credentials/builder.h \ +@USE_DEV_HEADERS_TRUE@credentials/cred_encoding.h credentials/keys/private_key.h \ +@USE_DEV_HEADERS_TRUE@credentials/keys/public_key.h credentials/keys/shared_key.h \ +@USE_DEV_HEADERS_TRUE@credentials/certificates/certificate.h credentials/certificates/x509.h \ +@USE_DEV_HEADERS_TRUE@credentials/certificates/ac.h credentials/certificates/crl.h \ +@USE_DEV_HEADERS_TRUE@credentials/certificates/pkcs10.h credentials/certificates/ocsp_request.h \ +@USE_DEV_HEADERS_TRUE@credentials/certificates/ocsp_response.h \ +@USE_DEV_HEADERS_TRUE@credentials/certificates/pgp_certificate.h \ +@USE_DEV_HEADERS_TRUE@credentials/ietf_attributes/ietf_attributes.h \ +@USE_DEV_HEADERS_TRUE@credentials/credential_manager.h credentials/sets/auth_cfg_wrapper.h \ +@USE_DEV_HEADERS_TRUE@credentials/sets/ocsp_response_wrapper.h credentials/sets/cert_cache.h \ +@USE_DEV_HEADERS_TRUE@credentials/sets/mem_cred.h credentials/sets/callback_cred.h \ +@USE_DEV_HEADERS_TRUE@credentials/auth_cfg.h credentials/credential_set.h credentials/cert_validator.h \ +@USE_DEV_HEADERS_TRUE@database/database.h database/database_factory.h fetcher/fetcher.h \ +@USE_DEV_HEADERS_TRUE@fetcher/fetcher_manager.h eap/eap.h pen/pen.h ipsec/ipsec_types.h \ +@USE_DEV_HEADERS_TRUE@plugins/plugin_loader.h plugins/plugin.h plugins/plugin_feature.h \ +@USE_DEV_HEADERS_TRUE@processing/jobs/job.h processing/jobs/callback_job.h processing/processor.h \ +@USE_DEV_HEADERS_TRUE@processing/scheduler.h selectors/traffic_selector.h \ +@USE_DEV_HEADERS_TRUE@threading/thread.h threading/thread_value.h \ +@USE_DEV_HEADERS_TRUE@threading/mutex.h threading/condvar.h threading/spinlock.h threading/semaphore.h \ +@USE_DEV_HEADERS_TRUE@threading/rwlock.h threading/rwlock_condvar.h threading/lock_profiler.h \ +@USE_DEV_HEADERS_TRUE@utils.h utils/host.h utils/packet.h utils/identification.h utils/lexparser.h \ +@USE_DEV_HEADERS_TRUE@utils/linked_list.h utils/blocking_queue.h utils/hashtable.h utils/enumerator.h \ +@USE_DEV_HEADERS_TRUE@utils/optionsfrom.h utils/capabilities.h utils/backtrace.h utils/tun_device.h \ +@USE_DEV_HEADERS_TRUE@utils/leak_detective.h integrity_checker.h + libstrongswan_la_LIBADD = $(PTHREADLIB) $(DLLIB) $(BTLIB) $(SOCKLIB) \ - $(RTLIB) $(am__append_6) $(am__append_8) $(am__append_10) \ - $(am__append_12) $(am__append_14) $(am__append_16) \ - $(am__append_18) $(am__append_20) $(am__append_22) \ - $(am__append_24) $(am__append_26) $(am__append_28) \ - $(am__append_30) $(am__append_32) $(am__append_34) \ - $(am__append_36) $(am__append_38) $(am__append_40) \ - $(am__append_42) $(am__append_44) $(am__append_46) \ - $(am__append_48) $(am__append_50) $(am__append_52) \ - $(am__append_54) $(am__append_56) $(am__append_58) \ - $(am__append_60) $(am__append_62) $(am__append_64) \ - $(am__append_66) $(am__append_68) $(am__append_70) \ - $(am__append_72) $(am__append_74) $(am__append_76) \ - $(am__append_78) $(am__append_80) + $(RTLIB) $(BFDLIB) $(am__append_6) $(am__append_7) \ + $(am__append_9) $(am__append_11) $(am__append_13) \ + $(am__append_15) $(am__append_17) $(am__append_19) \ + $(am__append_21) $(am__append_23) $(am__append_25) \ + $(am__append_27) $(am__append_29) $(am__append_31) \ + $(am__append_33) $(am__append_35) $(am__append_37) \ + $(am__append_39) $(am__append_41) $(am__append_43) \ + $(am__append_45) $(am__append_47) $(am__append_49) \ + $(am__append_51) $(am__append_53) $(am__append_55) \ + $(am__append_57) $(am__append_59) $(am__append_61) \ + $(am__append_63) $(am__append_65) $(am__append_67) \ + $(am__append_69) $(am__append_71) $(am__append_73) \ + $(am__append_75) $(am__append_77) $(am__append_79) \ + $(am__append_81) $(am__append_83) INCLUDES = -I$(top_srcdir)/src/libstrongswan AM_CFLAGS = -DIPSEC_DIR=\"${ipsecdir}\" \ -DIPSEC_LIB_DIR=\"${ipseclibdir}\" \ @@ -601,58 +629,58 @@ AM_CFLAGS = -DIPSEC_DIR=\"${ipsecdir}\" \ $(am__append_3) $(am__append_4) EXTRA_DIST = \ asn1/oid.txt asn1/oid.pl \ -crypto/proposal/proposal_keywords.txt \ +crypto/proposal/proposal_keywords_static.txt \ Android.mk AndroidConfigLocal.h BUILT_SOURCES = \ $(srcdir)/asn1/oid.c $(srcdir)/asn1/oid.h \ -$(srcdir)/crypto/proposal/proposal_keywords.c +$(srcdir)/crypto/proposal/proposal_keywords_static.c MAINTAINERCLEANFILES = \ $(srcdir)/asn1/oid.c $(srcdir)/asn1/oid.h \ -$(srcdir)/crypto/proposal/proposal_keywords.c - -@MONOLITHIC_FALSE@SUBDIRS = . $(am__append_7) $(am__append_9) \ -@MONOLITHIC_FALSE@ $(am__append_11) $(am__append_13) \ -@MONOLITHIC_FALSE@ $(am__append_15) $(am__append_17) \ -@MONOLITHIC_FALSE@ $(am__append_19) $(am__append_21) \ -@MONOLITHIC_FALSE@ $(am__append_23) $(am__append_25) \ -@MONOLITHIC_FALSE@ $(am__append_27) $(am__append_29) \ -@MONOLITHIC_FALSE@ $(am__append_31) $(am__append_33) \ -@MONOLITHIC_FALSE@ $(am__append_35) $(am__append_37) \ -@MONOLITHIC_FALSE@ $(am__append_39) $(am__append_41) \ -@MONOLITHIC_FALSE@ $(am__append_43) $(am__append_45) \ -@MONOLITHIC_FALSE@ $(am__append_47) $(am__append_49) \ -@MONOLITHIC_FALSE@ $(am__append_51) $(am__append_53) \ -@MONOLITHIC_FALSE@ $(am__append_55) $(am__append_57) \ -@MONOLITHIC_FALSE@ $(am__append_59) $(am__append_61) \ -@MONOLITHIC_FALSE@ $(am__append_63) $(am__append_65) \ -@MONOLITHIC_FALSE@ $(am__append_67) $(am__append_69) \ -@MONOLITHIC_FALSE@ $(am__append_71) $(am__append_73) \ -@MONOLITHIC_FALSE@ $(am__append_75) $(am__append_77) \ -@MONOLITHIC_FALSE@ $(am__append_79) +$(srcdir)/crypto/proposal/proposal_keywords_static.c + +@MONOLITHIC_FALSE@SUBDIRS = . $(am__append_8) $(am__append_10) \ +@MONOLITHIC_FALSE@ $(am__append_12) $(am__append_14) \ +@MONOLITHIC_FALSE@ $(am__append_16) $(am__append_18) \ +@MONOLITHIC_FALSE@ $(am__append_20) $(am__append_22) \ +@MONOLITHIC_FALSE@ $(am__append_24) $(am__append_26) \ +@MONOLITHIC_FALSE@ $(am__append_28) $(am__append_30) \ +@MONOLITHIC_FALSE@ $(am__append_32) $(am__append_34) \ +@MONOLITHIC_FALSE@ $(am__append_36) $(am__append_38) \ +@MONOLITHIC_FALSE@ $(am__append_40) $(am__append_42) \ +@MONOLITHIC_FALSE@ $(am__append_44) $(am__append_46) \ +@MONOLITHIC_FALSE@ $(am__append_48) $(am__append_50) \ +@MONOLITHIC_FALSE@ $(am__append_52) $(am__append_54) \ +@MONOLITHIC_FALSE@ $(am__append_56) $(am__append_58) \ +@MONOLITHIC_FALSE@ $(am__append_60) $(am__append_62) \ +@MONOLITHIC_FALSE@ $(am__append_64) $(am__append_66) \ +@MONOLITHIC_FALSE@ $(am__append_68) $(am__append_70) \ +@MONOLITHIC_FALSE@ $(am__append_72) $(am__append_74) \ +@MONOLITHIC_FALSE@ $(am__append_76) $(am__append_78) \ +@MONOLITHIC_FALSE@ $(am__append_80) $(am__append_82) # build plugins with their own Makefile ####################################### -@MONOLITHIC_TRUE@SUBDIRS = $(am__append_7) $(am__append_9) \ -@MONOLITHIC_TRUE@ $(am__append_11) $(am__append_13) \ -@MONOLITHIC_TRUE@ $(am__append_15) $(am__append_17) \ -@MONOLITHIC_TRUE@ $(am__append_19) $(am__append_21) \ -@MONOLITHIC_TRUE@ $(am__append_23) $(am__append_25) \ -@MONOLITHIC_TRUE@ $(am__append_27) $(am__append_29) \ -@MONOLITHIC_TRUE@ $(am__append_31) $(am__append_33) \ -@MONOLITHIC_TRUE@ $(am__append_35) $(am__append_37) \ -@MONOLITHIC_TRUE@ $(am__append_39) $(am__append_41) \ -@MONOLITHIC_TRUE@ $(am__append_43) $(am__append_45) \ -@MONOLITHIC_TRUE@ $(am__append_47) $(am__append_49) \ -@MONOLITHIC_TRUE@ $(am__append_51) $(am__append_53) \ -@MONOLITHIC_TRUE@ $(am__append_55) $(am__append_57) \ -@MONOLITHIC_TRUE@ $(am__append_59) $(am__append_61) \ -@MONOLITHIC_TRUE@ $(am__append_63) $(am__append_65) \ -@MONOLITHIC_TRUE@ $(am__append_67) $(am__append_69) \ -@MONOLITHIC_TRUE@ $(am__append_71) $(am__append_73) \ -@MONOLITHIC_TRUE@ $(am__append_75) $(am__append_77) \ -@MONOLITHIC_TRUE@ $(am__append_79) +@MONOLITHIC_TRUE@SUBDIRS = $(am__append_8) $(am__append_10) \ +@MONOLITHIC_TRUE@ $(am__append_12) $(am__append_14) \ +@MONOLITHIC_TRUE@ $(am__append_16) $(am__append_18) \ +@MONOLITHIC_TRUE@ $(am__append_20) $(am__append_22) \ +@MONOLITHIC_TRUE@ $(am__append_24) $(am__append_26) \ +@MONOLITHIC_TRUE@ $(am__append_28) $(am__append_30) \ +@MONOLITHIC_TRUE@ $(am__append_32) $(am__append_34) \ +@MONOLITHIC_TRUE@ $(am__append_36) $(am__append_38) \ +@MONOLITHIC_TRUE@ $(am__append_40) $(am__append_42) \ +@MONOLITHIC_TRUE@ $(am__append_44) $(am__append_46) \ +@MONOLITHIC_TRUE@ $(am__append_48) $(am__append_50) \ +@MONOLITHIC_TRUE@ $(am__append_52) $(am__append_54) \ +@MONOLITHIC_TRUE@ $(am__append_56) $(am__append_58) \ +@MONOLITHIC_TRUE@ $(am__append_60) $(am__append_62) \ +@MONOLITHIC_TRUE@ $(am__append_64) $(am__append_66) \ +@MONOLITHIC_TRUE@ $(am__append_68) $(am__append_70) \ +@MONOLITHIC_TRUE@ $(am__append_72) $(am__append_74) \ +@MONOLITHIC_TRUE@ $(am__append_76) $(am__append_78) \ +@MONOLITHIC_TRUE@ $(am__append_80) $(am__append_82) all: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) all-recursive @@ -736,9 +764,11 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/backtrace.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bio_reader.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bio_writer.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/blocking_queue.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/builder.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/callback_cred.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/callback_job.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/capabilities.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cert_cache.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@ @@ -764,18 +794,23 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/identification.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ietf_attributes.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/integrity_checker.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ipsec_types.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/job.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)/mac_prf.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mac_signer.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mem_cred.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)/ocsp_response_wrapper.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)/packet.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pen.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_feature.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/plugin_loader.Plo@am__quote@ @@ -785,17 +820,21 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/private_key.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/processor.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/proposal_keywords.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/proposal_keywords_static.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)/rwlock.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/scheduler.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/semaphore.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)/spinlock.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/thread.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/thread_value.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/traffic_selector.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/transform.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tun_device.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/utils.Plo@am__quote@ .c.o: @@ -868,6 +907,13 @@ 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 +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@ $(am__mv) $(DEPDIR)/pkcs7.Tpo $(DEPDIR)/pkcs7.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='crypto/pkcs7.c' object='pkcs7.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 + 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@ $(am__mv) $(DEPDIR)/pkcs9.Tpo $(DEPDIR)/pkcs9.Plo @@ -882,6 +928,13 @@ proposal_keywords.lo: crypto/proposal/proposal_keywords.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 proposal_keywords.lo `test -f 'crypto/proposal/proposal_keywords.c' || echo '$(srcdir)/'`crypto/proposal/proposal_keywords.c +proposal_keywords_static.lo: crypto/proposal/proposal_keywords_static.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT proposal_keywords_static.lo -MD -MP -MF $(DEPDIR)/proposal_keywords_static.Tpo -c -o proposal_keywords_static.lo `test -f 'crypto/proposal/proposal_keywords_static.c' || echo '$(srcdir)/'`crypto/proposal/proposal_keywords_static.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/proposal_keywords_static.Tpo $(DEPDIR)/proposal_keywords_static.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='crypto/proposal/proposal_keywords_static.c' object='proposal_keywords_static.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 proposal_keywords_static.lo `test -f 'crypto/proposal/proposal_keywords_static.c' || echo '$(srcdir)/'`crypto/proposal/proposal_keywords_static.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@ $(am__mv) $(DEPDIR)/prf.Tpo $(DEPDIR)/prf.Plo @@ -889,6 +942,13 @@ prf.lo: crypto/prfs/prf.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 prf.lo `test -f 'crypto/prfs/prf.c' || echo '$(srcdir)/'`crypto/prfs/prf.c +mac_prf.lo: crypto/prfs/mac_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 mac_prf.lo -MD -MP -MF $(DEPDIR)/mac_prf.Tpo -c -o mac_prf.lo `test -f 'crypto/prfs/mac_prf.c' || echo '$(srcdir)/'`crypto/prfs/mac_prf.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/mac_prf.Tpo $(DEPDIR)/mac_prf.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='crypto/prfs/mac_prf.c' object='mac_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 mac_prf.lo `test -f 'crypto/prfs/mac_prf.c' || echo '$(srcdir)/'`crypto/prfs/mac_prf.c + 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@ $(am__mv) $(DEPDIR)/rng.Tpo $(DEPDIR)/rng.Plo @@ -910,6 +970,13 @@ signer.lo: crypto/signers/signer.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 signer.lo `test -f 'crypto/signers/signer.c' || echo '$(srcdir)/'`crypto/signers/signer.c +mac_signer.lo: crypto/signers/mac_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 mac_signer.lo -MD -MP -MF $(DEPDIR)/mac_signer.Tpo -c -o mac_signer.lo `test -f 'crypto/signers/mac_signer.c' || echo '$(srcdir)/'`crypto/signers/mac_signer.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/mac_signer.Tpo $(DEPDIR)/mac_signer.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='crypto/signers/mac_signer.c' object='mac_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 mac_signer.lo `test -f 'crypto/signers/mac_signer.c' || echo '$(srcdir)/'`crypto/signers/mac_signer.c + 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@ $(am__mv) $(DEPDIR)/crypto_factory.Tpo $(DEPDIR)/crypto_factory.Plo @@ -1099,6 +1166,13 @@ eap.lo: eap/eap.c @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o eap.lo `test -f 'eap/eap.c' || echo '$(srcdir)/'`eap/eap.c +ipsec_types.lo: ipsec/ipsec_types.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT ipsec_types.lo -MD -MP -MF $(DEPDIR)/ipsec_types.Tpo -c -o ipsec_types.lo `test -f 'ipsec/ipsec_types.c' || echo '$(srcdir)/'`ipsec/ipsec_types.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/ipsec_types.Tpo $(DEPDIR)/ipsec_types.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='ipsec/ipsec_types.c' object='ipsec_types.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 ipsec_types.lo `test -f 'ipsec/ipsec_types.c' || echo '$(srcdir)/'`ipsec/ipsec_types.c + pen.lo: pen/pen.c @am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT pen.lo -MD -MP -MF $(DEPDIR)/pen.Tpo -c -o pen.lo `test -f 'pen/pen.c' || echo '$(srcdir)/'`pen/pen.c @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pen.Tpo $(DEPDIR)/pen.Plo @@ -1176,6 +1250,13 @@ mutex.lo: threading/mutex.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 mutex.lo `test -f 'threading/mutex.c' || echo '$(srcdir)/'`threading/mutex.c +semaphore.lo: threading/semaphore.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT semaphore.lo -MD -MP -MF $(DEPDIR)/semaphore.Tpo -c -o semaphore.lo `test -f 'threading/semaphore.c' || echo '$(srcdir)/'`threading/semaphore.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/semaphore.Tpo $(DEPDIR)/semaphore.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='threading/semaphore.c' object='semaphore.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 semaphore.lo `test -f 'threading/semaphore.c' || echo '$(srcdir)/'`threading/semaphore.c + rwlock.lo: threading/rwlock.c @am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT rwlock.lo -MD -MP -MF $(DEPDIR)/rwlock.Tpo -c -o rwlock.lo `test -f 'threading/rwlock.c' || echo '$(srcdir)/'`threading/rwlock.c @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/rwlock.Tpo $(DEPDIR)/rwlock.Plo @@ -1183,6 +1264,13 @@ rwlock.lo: threading/rwlock.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 rwlock.lo `test -f 'threading/rwlock.c' || echo '$(srcdir)/'`threading/rwlock.c +spinlock.lo: threading/spinlock.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT spinlock.lo -MD -MP -MF $(DEPDIR)/spinlock.Tpo -c -o spinlock.lo `test -f 'threading/spinlock.c' || echo '$(srcdir)/'`threading/spinlock.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/spinlock.Tpo $(DEPDIR)/spinlock.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='threading/spinlock.c' object='spinlock.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 spinlock.lo `test -f 'threading/spinlock.c' || echo '$(srcdir)/'`threading/spinlock.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 @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/host.Tpo $(DEPDIR)/host.Plo @@ -1190,6 +1278,13 @@ host.lo: utils/host.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 host.lo `test -f 'utils/host.c' || echo '$(srcdir)/'`utils/host.c +packet.lo: utils/packet.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT packet.lo -MD -MP -MF $(DEPDIR)/packet.Tpo -c -o packet.lo `test -f 'utils/packet.c' || echo '$(srcdir)/'`utils/packet.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/packet.Tpo $(DEPDIR)/packet.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='utils/packet.c' object='packet.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 packet.lo `test -f 'utils/packet.c' || echo '$(srcdir)/'`utils/packet.c + identification.lo: utils/identification.c @am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT identification.lo -MD -MP -MF $(DEPDIR)/identification.Tpo -c -o identification.lo `test -f 'utils/identification.c' || echo '$(srcdir)/'`utils/identification.c @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/identification.Tpo $(DEPDIR)/identification.Plo @@ -1211,6 +1306,13 @@ linked_list.lo: utils/linked_list.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 linked_list.lo `test -f 'utils/linked_list.c' || echo '$(srcdir)/'`utils/linked_list.c +blocking_queue.lo: utils/blocking_queue.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT blocking_queue.lo -MD -MP -MF $(DEPDIR)/blocking_queue.Tpo -c -o blocking_queue.lo `test -f 'utils/blocking_queue.c' || echo '$(srcdir)/'`utils/blocking_queue.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/blocking_queue.Tpo $(DEPDIR)/blocking_queue.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='utils/blocking_queue.c' object='blocking_queue.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 blocking_queue.lo `test -f 'utils/blocking_queue.c' || echo '$(srcdir)/'`utils/blocking_queue.c + hashtable.lo: utils/hashtable.c @am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT hashtable.lo -MD -MP -MF $(DEPDIR)/hashtable.Tpo -c -o hashtable.lo `test -f 'utils/hashtable.c' || echo '$(srcdir)/'`utils/hashtable.c @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/hashtable.Tpo $(DEPDIR)/hashtable.Plo @@ -1232,6 +1334,13 @@ 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 +capabilities.lo: utils/capabilities.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT capabilities.lo -MD -MP -MF $(DEPDIR)/capabilities.Tpo -c -o capabilities.lo `test -f 'utils/capabilities.c' || echo '$(srcdir)/'`utils/capabilities.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/capabilities.Tpo $(DEPDIR)/capabilities.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='utils/capabilities.c' object='capabilities.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 capabilities.lo `test -f 'utils/capabilities.c' || echo '$(srcdir)/'`utils/capabilities.c + backtrace.lo: utils/backtrace.c @am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT backtrace.lo -MD -MP -MF $(DEPDIR)/backtrace.Tpo -c -o backtrace.lo `test -f 'utils/backtrace.c' || echo '$(srcdir)/'`utils/backtrace.c @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/backtrace.Tpo $(DEPDIR)/backtrace.Plo @@ -1239,6 +1348,13 @@ backtrace.lo: utils/backtrace.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 backtrace.lo `test -f 'utils/backtrace.c' || echo '$(srcdir)/'`utils/backtrace.c +tun_device.lo: utils/tun_device.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT tun_device.lo -MD -MP -MF $(DEPDIR)/tun_device.Tpo -c -o tun_device.lo `test -f 'utils/tun_device.c' || echo '$(srcdir)/'`utils/tun_device.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/tun_device.Tpo $(DEPDIR)/tun_device.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='utils/tun_device.c' object='tun_device.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 tun_device.lo `test -f 'utils/tun_device.c' || echo '$(srcdir)/'`utils/tun_device.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@ $(am__mv) $(DEPDIR)/leak_detective.Tpo $(DEPDIR)/leak_detective.Plo @@ -1251,6 +1367,29 @@ mostlyclean-libtool: clean-libtool: -rm -rf .libs _libs +install-nobase_strongswan_includeHEADERS: $(nobase_strongswan_include_HEADERS) + @$(NORMAL_INSTALL) + test -z "$(strongswan_includedir)" || $(MKDIR_P) "$(DESTDIR)$(strongswan_includedir)" + @list='$(nobase_strongswan_include_HEADERS)'; test -n "$(strongswan_includedir)" || list=; \ + $(am__nobase_list) | while read dir files; do \ + xfiles=; for file in $$files; do \ + if test -f "$$file"; then xfiles="$$xfiles $$file"; \ + else xfiles="$$xfiles $(srcdir)/$$file"; fi; done; \ + test -z "$$xfiles" || { \ + test "x$$dir" = x. || { \ + echo "$(MKDIR_P) '$(DESTDIR)$(strongswan_includedir)/$$dir'"; \ + $(MKDIR_P) "$(DESTDIR)$(strongswan_includedir)/$$dir"; }; \ + echo " $(INSTALL_HEADER) $$xfiles '$(DESTDIR)$(strongswan_includedir)/$$dir'"; \ + $(INSTALL_HEADER) $$xfiles "$(DESTDIR)$(strongswan_includedir)/$$dir" || exit $$?; }; \ + done + +uninstall-nobase_strongswan_includeHEADERS: + @$(NORMAL_UNINSTALL) + @list='$(nobase_strongswan_include_HEADERS)'; test -n "$(strongswan_includedir)" || list=; \ + $(am__nobase_strip_setup); files=`$(am__nobase_strip)`; \ + test -n "$$files" || exit 0; \ + echo " ( cd '$(DESTDIR)$(strongswan_includedir)' && rm -f" $$files ")"; \ + cd "$(DESTDIR)$(strongswan_includedir)" && rm -f $$files # This directory's subdirectories are mostly independent; you can cd # into them and run `make' without going through this Makefile. @@ -1448,10 +1587,10 @@ distdir: $(DISTFILES) check-am: all-am check: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) check-recursive -all-am: Makefile $(LTLIBRARIES) +all-am: Makefile $(LTLIBRARIES) $(HEADERS) installdirs: installdirs-recursive installdirs-am: - for dir in "$(DESTDIR)$(ipseclibdir)"; do \ + for dir in "$(DESTDIR)$(ipseclibdir)" "$(DESTDIR)$(strongswan_includedir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: $(BUILT_SOURCES) @@ -1505,7 +1644,8 @@ info: info-recursive info-am: -install-data-am: install-ipseclibLTLIBRARIES +install-data-am: install-ipseclibLTLIBRARIES \ + install-nobase_strongswan_includeHEADERS install-dvi: install-dvi-recursive @@ -1551,7 +1691,8 @@ ps: ps-recursive ps-am: -uninstall-am: uninstall-ipseclibLTLIBRARIES +uninstall-am: uninstall-ipseclibLTLIBRARIES \ + uninstall-nobase_strongswan_includeHEADERS .MAKE: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) all check \ ctags-recursive install install-am install-strip \ @@ -1566,12 +1707,14 @@ uninstall-am: uninstall-ipseclibLTLIBRARIES install-data-am install-dvi install-dvi-am install-exec \ install-exec-am install-html install-html-am install-info \ install-info-am install-ipseclibLTLIBRARIES install-man \ - install-pdf install-pdf-am install-ps install-ps-am \ - install-strip 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-ipseclibLTLIBRARIES + install-nobase_strongswan_includeHEADERS install-pdf \ + install-pdf-am install-ps install-ps-am install-strip \ + 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-ipseclibLTLIBRARIES \ + uninstall-nobase_strongswan_includeHEADERS library.lo : $(top_builddir)/config.status @@ -1582,10 +1725,10 @@ $(srcdir)/asn1/oid.c : $(srcdir)/asn1/oid.pl $(srcdir)/asn1/oid.txt $(srcdir)/asn1/oid.h : $(srcdir)/asn1/oid.pl $(srcdir)/asn1/oid.txt (cd $(srcdir)/asn1/ && $(PERL) oid.pl) -$(srcdir)/crypto/proposal/proposal_keywords.c: $(srcdir)/crypto/proposal/proposal_keywords.txt \ - $(srcdir)/crypto/proposal/proposal_keywords.h - $(GPERF) -N proposal_get_token -m 10 -C -G -c -t -D < \ - $(srcdir)/crypto/proposal/proposal_keywords.txt > $@ +$(srcdir)/crypto/proposal/proposal_keywords_static.c: $(srcdir)/crypto/proposal/proposal_keywords_static.txt \ + $(srcdir)/crypto/proposal/proposal_keywords_static.h + $(GPERF) -N proposal_get_token_static -m 10 -C -G -c -t -D < \ + $(srcdir)/crypto/proposal/proposal_keywords_static.txt > $@ # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. diff --git a/src/libstrongswan/asn1/asn1.c b/src/libstrongswan/asn1/asn1.c index 4cb38d126..c9f6fce25 100644 --- a/src/libstrongswan/asn1/asn1.c +++ b/src/libstrongswan/asn1/asn1.c @@ -28,7 +28,7 @@ /** * Commonly used ASN1 values. */ -const chunk_t ASN1_INTEGER_0 = chunk_from_chars(0x02, 0x00); +const chunk_t ASN1_INTEGER_0 = chunk_from_chars(0x02, 0x01, 0x00); const chunk_t ASN1_INTEGER_1 = chunk_from_chars(0x02, 0x01, 0x01); const chunk_t ASN1_INTEGER_2 = chunk_from_chars(0x02, 0x01, 0x02); @@ -228,7 +228,8 @@ size_t asn1_length(chunk_t *blob) /* read length field, skip tag and length */ n = blob->ptr[1]; - *blob = chunk_skip(*blob, 2); + blob->ptr += 2; + blob->len -= 2; if ((n & 0x80) == 0) { /* single length octet */ @@ -760,16 +761,13 @@ chunk_t asn1_integer(const char *mode, chunk_t content) size_t len; u_char *pos; - if (content.len == 0 || (content.len == 1 && *content.ptr == 0x00)) - { - /* a zero ASN.1 integer does not have a value field */ - len = 0; - } - else - { - /* ASN.1 integers must be positive numbers in two's complement */ - len = content.len + ((*content.ptr & 0x80) ? 1 : 0); + if (content.len == 0) + { /* make sure 0 is encoded properly */ + content = chunk_from_chars(0x00); } + + /* ASN.1 integers must be positive numbers in two's complement */ + len = content.len + ((*content.ptr & 0x80) ? 1 : 0); pos = asn1_build_object(&object, ASN1_INTEGER, len); if (len > content.len) { diff --git a/src/libstrongswan/asn1/oid.c b/src/libstrongswan/asn1/oid.c index bfc985c25..b21299620 100644 --- a/src/libstrongswan/asn1/oid.c +++ b/src/libstrongswan/asn1/oid.c @@ -179,8 +179,8 @@ const oid_t oid_names[] = { { 0x02, 167, 0, 7, "ecdsa-with-SHA256" }, /* 166 */ { 0x03, 168, 0, 7, "ecdsa-with-SHA384" }, /* 167 */ { 0x04, 0, 0, 7, "ecdsa-with-SHA512" }, /* 168 */ - {0x2B, 320, 1, 0, "" }, /* 169 */ - { 0x06, 234, 1, 1, "dod" }, /* 170 */ + {0x2B, 323, 1, 0, "" }, /* 169 */ + { 0x06, 237, 1, 1, "dod" }, /* 170 */ { 0x01, 0, 1, 2, "internet" }, /* 171 */ { 0x04, 194, 1, 3, "private" }, /* 172 */ { 0x01, 0, 1, 4, "enterprise" }, /* 173 */ @@ -206,7 +206,7 @@ const oid_t oid_names[] = { { 0x4B, 0, 0, 11, "TCGID" }, /* 193 */ { 0x05, 0, 1, 3, "security" }, /* 194 */ { 0x05, 0, 1, 4, "mechanisms" }, /* 195 */ - { 0x07, 0, 1, 5, "id-pkix" }, /* 196 */ + { 0x07, 234, 1, 5, "id-pkix" }, /* 196 */ { 0x01, 201, 1, 6, "id-pe" }, /* 197 */ { 0x01, 199, 0, 7, "authorityInfoAccess" }, /* 198 */ { 0x03, 200, 0, 7, "qcStatements" }, /* 199 */ @@ -244,144 +244,147 @@ const oid_t oid_names[] = { { 0x02, 232, 0, 7, "caIssuers" }, /* 231 */ { 0x03, 233, 0, 7, "timeStamping" }, /* 232 */ { 0x05, 0, 0, 7, "caRepository" }, /* 233 */ - { 0x0E, 240, 1, 1, "oiw" }, /* 234 */ - { 0x03, 0, 1, 2, "secsig" }, /* 235 */ - { 0x02, 0, 1, 3, "algorithms" }, /* 236 */ - { 0x07, 238, 0, 4, "des-cbc" }, /* 237 */ - { 0x1A, 239, 0, 4, "sha-1" }, /* 238 */ - { 0x1D, 0, 0, 4, "sha-1WithRSASignature" }, /* 239 */ - { 0x24, 286, 1, 1, "TeleTrusT" }, /* 240 */ - { 0x03, 0, 1, 2, "algorithm" }, /* 241 */ - { 0x03, 0, 1, 3, "signatureAlgorithm" }, /* 242 */ - { 0x01, 247, 1, 4, "rsaSignature" }, /* 243 */ - { 0x02, 245, 0, 5, "rsaSigWithripemd160" }, /* 244 */ - { 0x03, 246, 0, 5, "rsaSigWithripemd128" }, /* 245 */ - { 0x04, 0, 0, 5, "rsaSigWithripemd256" }, /* 246 */ - { 0x02, 0, 1, 4, "ecSign" }, /* 247 */ - { 0x01, 249, 0, 5, "ecSignWithsha1" }, /* 248 */ - { 0x02, 250, 0, 5, "ecSignWithripemd160" }, /* 249 */ - { 0x03, 251, 0, 5, "ecSignWithmd2" }, /* 250 */ - { 0x04, 252, 0, 5, "ecSignWithmd5" }, /* 251 */ - { 0x05, 269, 1, 5, "ttt-ecg" }, /* 252 */ - { 0x01, 257, 1, 6, "fieldType" }, /* 253 */ - { 0x01, 0, 1, 7, "characteristictwoField" }, /* 254 */ - { 0x01, 0, 1, 8, "basisType" }, /* 255 */ - { 0x01, 0, 0, 9, "ipBasis" }, /* 256 */ - { 0x02, 259, 1, 6, "keyType" }, /* 257 */ - { 0x01, 0, 0, 7, "ecgPublicKey" }, /* 258 */ - { 0x03, 260, 0, 6, "curve" }, /* 259 */ - { 0x04, 267, 1, 6, "signatures" }, /* 260 */ - { 0x01, 262, 0, 7, "ecgdsa-with-RIPEMD160" }, /* 261 */ - { 0x02, 263, 0, 7, "ecgdsa-with-SHA1" }, /* 262 */ - { 0x03, 264, 0, 7, "ecgdsa-with-SHA224" }, /* 263 */ - { 0x04, 265, 0, 7, "ecgdsa-with-SHA256" }, /* 264 */ - { 0x05, 266, 0, 7, "ecgdsa-with-SHA384" }, /* 265 */ - { 0x06, 0, 0, 7, "ecgdsa-with-SHA512" }, /* 266 */ - { 0x05, 0, 1, 6, "module" }, /* 267 */ - { 0x01, 0, 0, 7, "1" }, /* 268 */ - { 0x08, 0, 1, 5, "ecStdCurvesAndGeneration" }, /* 269 */ - { 0x01, 0, 1, 6, "ellipticCurve" }, /* 270 */ - { 0x01, 0, 1, 7, "versionOne" }, /* 271 */ - { 0x01, 273, 0, 8, "brainpoolP160r1" }, /* 272 */ - { 0x02, 274, 0, 8, "brainpoolP160t1" }, /* 273 */ - { 0x03, 275, 0, 8, "brainpoolP192r1" }, /* 274 */ - { 0x04, 276, 0, 8, "brainpoolP192t1" }, /* 275 */ - { 0x05, 277, 0, 8, "brainpoolP224r1" }, /* 276 */ - { 0x06, 278, 0, 8, "brainpoolP224t1" }, /* 277 */ - { 0x07, 279, 0, 8, "brainpoolP256r1" }, /* 278 */ - { 0x08, 280, 0, 8, "brainpoolP256t1" }, /* 279 */ - { 0x09, 281, 0, 8, "brainpoolP320r1" }, /* 280 */ - { 0x0A, 282, 0, 8, "brainpoolP320t1" }, /* 281 */ - { 0x0B, 283, 0, 8, "brainpoolP384r1" }, /* 282 */ - { 0x0C, 284, 0, 8, "brainpoolP384t1" }, /* 283 */ - { 0x0D, 285, 0, 8, "brainpoolP512r1" }, /* 284 */ - { 0x0E, 0, 0, 8, "brainpoolP512t1" }, /* 285 */ - { 0x81, 0, 1, 1, "" }, /* 286 */ - { 0x04, 0, 1, 2, "Certicom" }, /* 287 */ - { 0x00, 0, 1, 3, "curve" }, /* 288 */ - { 0x01, 290, 0, 4, "sect163k1" }, /* 289 */ - { 0x02, 291, 0, 4, "sect163r1" }, /* 290 */ - { 0x03, 292, 0, 4, "sect239k1" }, /* 291 */ - { 0x04, 293, 0, 4, "sect113r1" }, /* 292 */ - { 0x05, 294, 0, 4, "sect113r2" }, /* 293 */ - { 0x06, 295, 0, 4, "secp112r1" }, /* 294 */ - { 0x07, 296, 0, 4, "secp112r2" }, /* 295 */ - { 0x08, 297, 0, 4, "secp160r1" }, /* 296 */ - { 0x09, 298, 0, 4, "secp160k1" }, /* 297 */ - { 0x0A, 299, 0, 4, "secp256k1" }, /* 298 */ - { 0x0F, 300, 0, 4, "sect163r2" }, /* 299 */ - { 0x10, 301, 0, 4, "sect283k1" }, /* 300 */ - { 0x11, 302, 0, 4, "sect283r1" }, /* 301 */ - { 0x16, 303, 0, 4, "sect131r1" }, /* 302 */ - { 0x17, 304, 0, 4, "sect131r2" }, /* 303 */ - { 0x18, 305, 0, 4, "sect193r1" }, /* 304 */ - { 0x19, 306, 0, 4, "sect193r2" }, /* 305 */ - { 0x1A, 307, 0, 4, "sect233k1" }, /* 306 */ - { 0x1B, 308, 0, 4, "sect233r1" }, /* 307 */ - { 0x1C, 309, 0, 4, "secp128r1" }, /* 308 */ - { 0x1D, 310, 0, 4, "secp128r2" }, /* 309 */ - { 0x1E, 311, 0, 4, "secp160r2" }, /* 310 */ - { 0x1F, 312, 0, 4, "secp192k1" }, /* 311 */ - { 0x20, 313, 0, 4, "secp224k1" }, /* 312 */ - { 0x21, 314, 0, 4, "secp224r1" }, /* 313 */ - { 0x22, 315, 0, 4, "secp384r1" }, /* 314 */ - { 0x23, 316, 0, 4, "secp521r1" }, /* 315 */ - { 0x24, 317, 0, 4, "sect409k1" }, /* 316 */ - { 0x25, 318, 0, 4, "sect409r1" }, /* 317 */ - { 0x26, 319, 0, 4, "sect571k1" }, /* 318 */ - { 0x27, 0, 0, 4, "sect571r1" }, /* 319 */ - {0x60, 366, 1, 0, "" }, /* 320 */ - { 0x86, 0, 1, 1, "" }, /* 321 */ - { 0x48, 0, 1, 2, "" }, /* 322 */ - { 0x01, 0, 1, 3, "organization" }, /* 323 */ - { 0x65, 342, 1, 4, "gov" }, /* 324 */ - { 0x03, 0, 1, 5, "csor" }, /* 325 */ - { 0x04, 0, 1, 6, "nistalgorithm" }, /* 326 */ - { 0x01, 337, 1, 7, "aes" }, /* 327 */ - { 0x02, 329, 0, 8, "id-aes128-CBC" }, /* 328 */ - { 0x06, 330, 0, 8, "id-aes128-GCM" }, /* 329 */ - { 0x07, 331, 0, 8, "id-aes128-CCM" }, /* 330 */ - { 0x16, 332, 0, 8, "id-aes192-CBC" }, /* 331 */ - { 0x1A, 333, 0, 8, "id-aes192-GCM" }, /* 332 */ - { 0x1B, 334, 0, 8, "id-aes192-CCM" }, /* 333 */ - { 0x2A, 335, 0, 8, "id-aes256-CBC" }, /* 334 */ - { 0x2E, 336, 0, 8, "id-aes256-GCM" }, /* 335 */ - { 0x2F, 0, 0, 8, "id-aes256-CCM" }, /* 336 */ - { 0x02, 0, 1, 7, "hashalgs" }, /* 337 */ - { 0x01, 339, 0, 8, "id-SHA-256" }, /* 338 */ - { 0x02, 340, 0, 8, "id-SHA-384" }, /* 339 */ - { 0x03, 341, 0, 8, "id-SHA-512" }, /* 340 */ - { 0x04, 0, 0, 8, "id-SHA-224" }, /* 341 */ - { 0x86, 0, 1, 4, "" }, /* 342 */ - { 0xf8, 0, 1, 5, "" }, /* 343 */ - { 0x42, 356, 1, 6, "netscape" }, /* 344 */ - { 0x01, 351, 1, 7, "" }, /* 345 */ - { 0x01, 347, 0, 8, "nsCertType" }, /* 346 */ - { 0x03, 348, 0, 8, "nsRevocationUrl" }, /* 347 */ - { 0x04, 349, 0, 8, "nsCaRevocationUrl" }, /* 348 */ - { 0x08, 350, 0, 8, "nsCaPolicyUrl" }, /* 349 */ - { 0x0d, 0, 0, 8, "nsComment" }, /* 350 */ - { 0x03, 354, 1, 7, "directory" }, /* 351 */ - { 0x01, 0, 1, 8, "" }, /* 352 */ - { 0x03, 0, 0, 9, "employeeNumber" }, /* 353 */ - { 0x04, 0, 1, 7, "policy" }, /* 354 */ - { 0x01, 0, 0, 8, "nsSGC" }, /* 355 */ - { 0x45, 0, 1, 6, "verisign" }, /* 356 */ - { 0x01, 0, 1, 7, "pki" }, /* 357 */ - { 0x09, 0, 1, 8, "attributes" }, /* 358 */ - { 0x02, 360, 0, 9, "messageType" }, /* 359 */ - { 0x03, 361, 0, 9, "pkiStatus" }, /* 360 */ - { 0x04, 362, 0, 9, "failInfo" }, /* 361 */ - { 0x05, 363, 0, 9, "senderNonce" }, /* 362 */ - { 0x06, 364, 0, 9, "recipientNonce" }, /* 363 */ - { 0x07, 365, 0, 9, "transID" }, /* 364 */ - { 0x08, 0, 0, 9, "extensionReq" }, /* 365 */ - {0x67, 0, 1, 0, "" }, /* 366 */ - { 0x81, 0, 1, 1, "" }, /* 367 */ - { 0x05, 0, 1, 2, "" }, /* 368 */ - { 0x02, 0, 1, 3, "tcg-attribute" }, /* 369 */ - { 0x01, 371, 0, 4, "tcg-at-tpmManufacturer" }, /* 370 */ - { 0x02, 372, 0, 4, "tcg-at-tpmModel" }, /* 371 */ - { 0x03, 373, 0, 4, "tcg-at-tpmVersion" }, /* 372 */ - { 0x0F, 0, 0, 4, "tcg-at-tpmIdLabel" } /* 373 */ + { 0x08, 0, 1, 5, "ipsec" }, /* 234 */ + { 0x02, 0, 1, 6, "certificate" }, /* 235 */ + { 0x02, 0, 0, 7, "iKEIntermediate" }, /* 236 */ + { 0x0E, 243, 1, 1, "oiw" }, /* 237 */ + { 0x03, 0, 1, 2, "secsig" }, /* 238 */ + { 0x02, 0, 1, 3, "algorithms" }, /* 239 */ + { 0x07, 241, 0, 4, "des-cbc" }, /* 240 */ + { 0x1A, 242, 0, 4, "sha-1" }, /* 241 */ + { 0x1D, 0, 0, 4, "sha-1WithRSASignature" }, /* 242 */ + { 0x24, 289, 1, 1, "TeleTrusT" }, /* 243 */ + { 0x03, 0, 1, 2, "algorithm" }, /* 244 */ + { 0x03, 0, 1, 3, "signatureAlgorithm" }, /* 245 */ + { 0x01, 250, 1, 4, "rsaSignature" }, /* 246 */ + { 0x02, 248, 0, 5, "rsaSigWithripemd160" }, /* 247 */ + { 0x03, 249, 0, 5, "rsaSigWithripemd128" }, /* 248 */ + { 0x04, 0, 0, 5, "rsaSigWithripemd256" }, /* 249 */ + { 0x02, 0, 1, 4, "ecSign" }, /* 250 */ + { 0x01, 252, 0, 5, "ecSignWithsha1" }, /* 251 */ + { 0x02, 253, 0, 5, "ecSignWithripemd160" }, /* 252 */ + { 0x03, 254, 0, 5, "ecSignWithmd2" }, /* 253 */ + { 0x04, 255, 0, 5, "ecSignWithmd5" }, /* 254 */ + { 0x05, 272, 1, 5, "ttt-ecg" }, /* 255 */ + { 0x01, 260, 1, 6, "fieldType" }, /* 256 */ + { 0x01, 0, 1, 7, "characteristictwoField" }, /* 257 */ + { 0x01, 0, 1, 8, "basisType" }, /* 258 */ + { 0x01, 0, 0, 9, "ipBasis" }, /* 259 */ + { 0x02, 262, 1, 6, "keyType" }, /* 260 */ + { 0x01, 0, 0, 7, "ecgPublicKey" }, /* 261 */ + { 0x03, 263, 0, 6, "curve" }, /* 262 */ + { 0x04, 270, 1, 6, "signatures" }, /* 263 */ + { 0x01, 265, 0, 7, "ecgdsa-with-RIPEMD160" }, /* 264 */ + { 0x02, 266, 0, 7, "ecgdsa-with-SHA1" }, /* 265 */ + { 0x03, 267, 0, 7, "ecgdsa-with-SHA224" }, /* 266 */ + { 0x04, 268, 0, 7, "ecgdsa-with-SHA256" }, /* 267 */ + { 0x05, 269, 0, 7, "ecgdsa-with-SHA384" }, /* 268 */ + { 0x06, 0, 0, 7, "ecgdsa-with-SHA512" }, /* 269 */ + { 0x05, 0, 1, 6, "module" }, /* 270 */ + { 0x01, 0, 0, 7, "1" }, /* 271 */ + { 0x08, 0, 1, 5, "ecStdCurvesAndGeneration" }, /* 272 */ + { 0x01, 0, 1, 6, "ellipticCurve" }, /* 273 */ + { 0x01, 0, 1, 7, "versionOne" }, /* 274 */ + { 0x01, 276, 0, 8, "brainpoolP160r1" }, /* 275 */ + { 0x02, 277, 0, 8, "brainpoolP160t1" }, /* 276 */ + { 0x03, 278, 0, 8, "brainpoolP192r1" }, /* 277 */ + { 0x04, 279, 0, 8, "brainpoolP192t1" }, /* 278 */ + { 0x05, 280, 0, 8, "brainpoolP224r1" }, /* 279 */ + { 0x06, 281, 0, 8, "brainpoolP224t1" }, /* 280 */ + { 0x07, 282, 0, 8, "brainpoolP256r1" }, /* 281 */ + { 0x08, 283, 0, 8, "brainpoolP256t1" }, /* 282 */ + { 0x09, 284, 0, 8, "brainpoolP320r1" }, /* 283 */ + { 0x0A, 285, 0, 8, "brainpoolP320t1" }, /* 284 */ + { 0x0B, 286, 0, 8, "brainpoolP384r1" }, /* 285 */ + { 0x0C, 287, 0, 8, "brainpoolP384t1" }, /* 286 */ + { 0x0D, 288, 0, 8, "brainpoolP512r1" }, /* 287 */ + { 0x0E, 0, 0, 8, "brainpoolP512t1" }, /* 288 */ + { 0x81, 0, 1, 1, "" }, /* 289 */ + { 0x04, 0, 1, 2, "Certicom" }, /* 290 */ + { 0x00, 0, 1, 3, "curve" }, /* 291 */ + { 0x01, 293, 0, 4, "sect163k1" }, /* 292 */ + { 0x02, 294, 0, 4, "sect163r1" }, /* 293 */ + { 0x03, 295, 0, 4, "sect239k1" }, /* 294 */ + { 0x04, 296, 0, 4, "sect113r1" }, /* 295 */ + { 0x05, 297, 0, 4, "sect113r2" }, /* 296 */ + { 0x06, 298, 0, 4, "secp112r1" }, /* 297 */ + { 0x07, 299, 0, 4, "secp112r2" }, /* 298 */ + { 0x08, 300, 0, 4, "secp160r1" }, /* 299 */ + { 0x09, 301, 0, 4, "secp160k1" }, /* 300 */ + { 0x0A, 302, 0, 4, "secp256k1" }, /* 301 */ + { 0x0F, 303, 0, 4, "sect163r2" }, /* 302 */ + { 0x10, 304, 0, 4, "sect283k1" }, /* 303 */ + { 0x11, 305, 0, 4, "sect283r1" }, /* 304 */ + { 0x16, 306, 0, 4, "sect131r1" }, /* 305 */ + { 0x17, 307, 0, 4, "sect131r2" }, /* 306 */ + { 0x18, 308, 0, 4, "sect193r1" }, /* 307 */ + { 0x19, 309, 0, 4, "sect193r2" }, /* 308 */ + { 0x1A, 310, 0, 4, "sect233k1" }, /* 309 */ + { 0x1B, 311, 0, 4, "sect233r1" }, /* 310 */ + { 0x1C, 312, 0, 4, "secp128r1" }, /* 311 */ + { 0x1D, 313, 0, 4, "secp128r2" }, /* 312 */ + { 0x1E, 314, 0, 4, "secp160r2" }, /* 313 */ + { 0x1F, 315, 0, 4, "secp192k1" }, /* 314 */ + { 0x20, 316, 0, 4, "secp224k1" }, /* 315 */ + { 0x21, 317, 0, 4, "secp224r1" }, /* 316 */ + { 0x22, 318, 0, 4, "secp384r1" }, /* 317 */ + { 0x23, 319, 0, 4, "secp521r1" }, /* 318 */ + { 0x24, 320, 0, 4, "sect409k1" }, /* 319 */ + { 0x25, 321, 0, 4, "sect409r1" }, /* 320 */ + { 0x26, 322, 0, 4, "sect571k1" }, /* 321 */ + { 0x27, 0, 0, 4, "sect571r1" }, /* 322 */ + {0x60, 369, 1, 0, "" }, /* 323 */ + { 0x86, 0, 1, 1, "" }, /* 324 */ + { 0x48, 0, 1, 2, "" }, /* 325 */ + { 0x01, 0, 1, 3, "organization" }, /* 326 */ + { 0x65, 345, 1, 4, "gov" }, /* 327 */ + { 0x03, 0, 1, 5, "csor" }, /* 328 */ + { 0x04, 0, 1, 6, "nistalgorithm" }, /* 329 */ + { 0x01, 340, 1, 7, "aes" }, /* 330 */ + { 0x02, 332, 0, 8, "id-aes128-CBC" }, /* 331 */ + { 0x06, 333, 0, 8, "id-aes128-GCM" }, /* 332 */ + { 0x07, 334, 0, 8, "id-aes128-CCM" }, /* 333 */ + { 0x16, 335, 0, 8, "id-aes192-CBC" }, /* 334 */ + { 0x1A, 336, 0, 8, "id-aes192-GCM" }, /* 335 */ + { 0x1B, 337, 0, 8, "id-aes192-CCM" }, /* 336 */ + { 0x2A, 338, 0, 8, "id-aes256-CBC" }, /* 337 */ + { 0x2E, 339, 0, 8, "id-aes256-GCM" }, /* 338 */ + { 0x2F, 0, 0, 8, "id-aes256-CCM" }, /* 339 */ + { 0x02, 0, 1, 7, "hashalgs" }, /* 340 */ + { 0x01, 342, 0, 8, "id-SHA-256" }, /* 341 */ + { 0x02, 343, 0, 8, "id-SHA-384" }, /* 342 */ + { 0x03, 344, 0, 8, "id-SHA-512" }, /* 343 */ + { 0x04, 0, 0, 8, "id-SHA-224" }, /* 344 */ + { 0x86, 0, 1, 4, "" }, /* 345 */ + { 0xf8, 0, 1, 5, "" }, /* 346 */ + { 0x42, 359, 1, 6, "netscape" }, /* 347 */ + { 0x01, 354, 1, 7, "" }, /* 348 */ + { 0x01, 350, 0, 8, "nsCertType" }, /* 349 */ + { 0x03, 351, 0, 8, "nsRevocationUrl" }, /* 350 */ + { 0x04, 352, 0, 8, "nsCaRevocationUrl" }, /* 351 */ + { 0x08, 353, 0, 8, "nsCaPolicyUrl" }, /* 352 */ + { 0x0d, 0, 0, 8, "nsComment" }, /* 353 */ + { 0x03, 357, 1, 7, "directory" }, /* 354 */ + { 0x01, 0, 1, 8, "" }, /* 355 */ + { 0x03, 0, 0, 9, "employeeNumber" }, /* 356 */ + { 0x04, 0, 1, 7, "policy" }, /* 357 */ + { 0x01, 0, 0, 8, "nsSGC" }, /* 358 */ + { 0x45, 0, 1, 6, "verisign" }, /* 359 */ + { 0x01, 0, 1, 7, "pki" }, /* 360 */ + { 0x09, 0, 1, 8, "attributes" }, /* 361 */ + { 0x02, 363, 0, 9, "messageType" }, /* 362 */ + { 0x03, 364, 0, 9, "pkiStatus" }, /* 363 */ + { 0x04, 365, 0, 9, "failInfo" }, /* 364 */ + { 0x05, 366, 0, 9, "senderNonce" }, /* 365 */ + { 0x06, 367, 0, 9, "recipientNonce" }, /* 366 */ + { 0x07, 368, 0, 9, "transID" }, /* 367 */ + { 0x08, 0, 0, 9, "extensionReq" }, /* 368 */ + {0x67, 0, 1, 0, "" }, /* 369 */ + { 0x81, 0, 1, 1, "" }, /* 370 */ + { 0x05, 0, 1, 2, "" }, /* 371 */ + { 0x02, 0, 1, 3, "tcg-attribute" }, /* 372 */ + { 0x01, 374, 0, 4, "tcg-at-tpmManufacturer" }, /* 373 */ + { 0x02, 375, 0, 4, "tcg-at-tpmModel" }, /* 374 */ + { 0x03, 376, 0, 4, "tcg-at-tpmVersion" }, /* 375 */ + { 0x0F, 0, 0, 4, "tcg-at-tpmIdLabel" } /* 376 */ }; diff --git a/src/libstrongswan/asn1/oid.h b/src/libstrongswan/asn1/oid.h index a01c434a9..5e30a3675 100644 --- a/src/libstrongswan/asn1/oid.h +++ b/src/libstrongswan/asn1/oid.h @@ -150,76 +150,77 @@ extern const oid_t oid_names[]; #define OID_ARCHIVE_CUTOFF 229 #define OID_SERVICE_LOCATOR 230 #define OID_CA_ISSUERS 231 -#define OID_DES_CBC 237 -#define OID_SHA1 238 -#define OID_SHA1_WITH_RSA_OIW 239 -#define OID_ECGDSA_PUBKEY 258 -#define OID_ECGDSA_SIG_WITH_RIPEMD160 261 -#define OID_ECGDSA_SIG_WITH_SHA1 262 -#define OID_ECGDSA_SIG_WITH_SHA224 263 -#define OID_ECGDSA_SIG_WITH_SHA256 264 -#define OID_ECGDSA_SIG_WITH_SHA384 265 -#define OID_ECGDSA_SIG_WITH_SHA512 266 -#define OID_SECT163K1 289 -#define OID_SECT163R1 290 -#define OID_SECT239K1 291 -#define OID_SECT113R1 292 -#define OID_SECT113R2 293 -#define OID_SECT112R1 294 -#define OID_SECT112R2 295 -#define OID_SECT160R1 296 -#define OID_SECT160K1 297 -#define OID_SECT256K1 298 -#define OID_SECT163R2 299 -#define OID_SECT283K1 300 -#define OID_SECT283R1 301 -#define OID_SECT131R1 302 -#define OID_SECT131R2 303 -#define OID_SECT193R1 304 -#define OID_SECT193R2 305 -#define OID_SECT233K1 306 -#define OID_SECT233R1 307 -#define OID_SECT128R1 308 -#define OID_SECT128R2 309 -#define OID_SECT160R2 310 -#define OID_SECT192K1 311 -#define OID_SECT224K1 312 -#define OID_SECT224R1 313 -#define OID_SECT384R1 314 -#define OID_SECT521R1 315 -#define OID_SECT409K1 316 -#define OID_SECT409R1 317 -#define OID_SECT571K1 318 -#define OID_SECT571R1 319 -#define OID_AES128_CBC 328 -#define OID_AES128_GCM 329 -#define OID_AES128_CCM 330 -#define OID_AES192_CBC 331 -#define OID_AES192_GCM 332 -#define OID_AES192_CCM 333 -#define OID_AES256_CBC 334 -#define OID_AES256_GCM 335 -#define OID_AES256_CCM 336 -#define OID_SHA256 338 -#define OID_SHA384 339 -#define OID_SHA512 340 -#define OID_SHA224 341 -#define OID_NS_REVOCATION_URL 347 -#define OID_NS_CA_REVOCATION_URL 348 -#define OID_NS_CA_POLICY_URL 349 -#define OID_NS_COMMENT 350 -#define OID_EMPLOYEE_NUMBER 353 -#define OID_PKI_MESSAGE_TYPE 359 -#define OID_PKI_STATUS 360 -#define OID_PKI_FAIL_INFO 361 -#define OID_PKI_SENDER_NONCE 362 -#define OID_PKI_RECIPIENT_NONCE 363 -#define OID_PKI_TRANS_ID 364 -#define OID_TPM_MANUFACTURER 370 -#define OID_TPM_MODEL 371 -#define OID_TPM_VERSION 372 -#define OID_TPM_ID_LABEL 373 +#define OID_IKE_INTERMEDIATE 236 +#define OID_DES_CBC 240 +#define OID_SHA1 241 +#define OID_SHA1_WITH_RSA_OIW 242 +#define OID_ECGDSA_PUBKEY 261 +#define OID_ECGDSA_SIG_WITH_RIPEMD160 264 +#define OID_ECGDSA_SIG_WITH_SHA1 265 +#define OID_ECGDSA_SIG_WITH_SHA224 266 +#define OID_ECGDSA_SIG_WITH_SHA256 267 +#define OID_ECGDSA_SIG_WITH_SHA384 268 +#define OID_ECGDSA_SIG_WITH_SHA512 269 +#define OID_SECT163K1 292 +#define OID_SECT163R1 293 +#define OID_SECT239K1 294 +#define OID_SECT113R1 295 +#define OID_SECT113R2 296 +#define OID_SECT112R1 297 +#define OID_SECT112R2 298 +#define OID_SECT160R1 299 +#define OID_SECT160K1 300 +#define OID_SECT256K1 301 +#define OID_SECT163R2 302 +#define OID_SECT283K1 303 +#define OID_SECT283R1 304 +#define OID_SECT131R1 305 +#define OID_SECT131R2 306 +#define OID_SECT193R1 307 +#define OID_SECT193R2 308 +#define OID_SECT233K1 309 +#define OID_SECT233R1 310 +#define OID_SECT128R1 311 +#define OID_SECT128R2 312 +#define OID_SECT160R2 313 +#define OID_SECT192K1 314 +#define OID_SECT224K1 315 +#define OID_SECT224R1 316 +#define OID_SECT384R1 317 +#define OID_SECT521R1 318 +#define OID_SECT409K1 319 +#define OID_SECT409R1 320 +#define OID_SECT571K1 321 +#define OID_SECT571R1 322 +#define OID_AES128_CBC 331 +#define OID_AES128_GCM 332 +#define OID_AES128_CCM 333 +#define OID_AES192_CBC 334 +#define OID_AES192_GCM 335 +#define OID_AES192_CCM 336 +#define OID_AES256_CBC 337 +#define OID_AES256_GCM 338 +#define OID_AES256_CCM 339 +#define OID_SHA256 341 +#define OID_SHA384 342 +#define OID_SHA512 343 +#define OID_SHA224 344 +#define OID_NS_REVOCATION_URL 350 +#define OID_NS_CA_REVOCATION_URL 351 +#define OID_NS_CA_POLICY_URL 352 +#define OID_NS_COMMENT 353 +#define OID_EMPLOYEE_NUMBER 356 +#define OID_PKI_MESSAGE_TYPE 362 +#define OID_PKI_STATUS 363 +#define OID_PKI_FAIL_INFO 364 +#define OID_PKI_SENDER_NONCE 365 +#define OID_PKI_RECIPIENT_NONCE 366 +#define OID_PKI_TRANS_ID 367 +#define OID_TPM_MANUFACTURER 373 +#define OID_TPM_MODEL 374 +#define OID_TPM_VERSION 375 +#define OID_TPM_ID_LABEL 376 -#define OID_MAX 374 +#define OID_MAX 377 #endif /* OID_H_ */ diff --git a/src/libstrongswan/asn1/oid.txt b/src/libstrongswan/asn1/oid.txt index c3ff1a9e7..51a29eb33 100644 --- a/src/libstrongswan/asn1/oid.txt +++ b/src/libstrongswan/asn1/oid.txt @@ -232,6 +232,9 @@ 0x02 "caIssuers" OID_CA_ISSUERS 0x03 "timeStamping" 0x05 "caRepository" + 0x08 "ipsec" + 0x02 "certificate" + 0x02 "iKEIntermediate" OID_IKE_INTERMEDIATE 0x0E "oiw" 0x03 "secsig" 0x02 "algorithms" diff --git a/src/libstrongswan/bio/bio_reader.c b/src/libstrongswan/bio/bio_reader.c index fce0d1aef..3a62bb541 100644 --- a/src/libstrongswan/bio/bio_reader.c +++ b/src/libstrongswan/bio/bio_reader.c @@ -1,4 +1,7 @@ /* + * Copyright (C) 2012 Tobias Brunner + * Hochschule fuer Technik Rapperswil + * * Copyright (C) 2010 Martin Willi * Copyright (C) 2010 revosec AG * @@ -47,8 +50,38 @@ METHOD(bio_reader_t, peek, chunk_t, return this->buf; } -METHOD(bio_reader_t, read_uint8, bool, - private_bio_reader_t *this, u_int8_t *res) +/** + * A version of chunk_skip() that supports skipping from the end (i.e. simply + * reducing the size) + */ +static inline chunk_t chunk_skip_end(chunk_t chunk, size_t bytes, bool from_end) +{ + if (chunk.len > bytes) + { + if (!from_end) + { + chunk.ptr += bytes; + } + chunk.len -= bytes; + return chunk; + } + return chunk_empty; +} + +/** + * Returns a pointer to the data to read, optionally from the end + */ +static inline u_char *get_ptr_end(private_bio_reader_t *this, u_int32_t len, + bool from_end) +{ + return from_end ? this->buf.ptr + (this->buf.len - len) : this->buf.ptr; +} + +/** + * Read an u_int8_t from the buffer, optionally from the end of the buffer + */ +static bool read_uint8_internal(private_bio_reader_t *this, u_int8_t *res, + bool from_end) { if (this->buf.len < 1) { @@ -56,13 +89,16 @@ METHOD(bio_reader_t, read_uint8, bool, this->buf.len); return FALSE; } - *res = this->buf.ptr[0]; - this->buf = chunk_skip(this->buf, 1); + *res = *get_ptr_end(this, 1, from_end); + this->buf = chunk_skip_end(this->buf, 1, from_end); return TRUE; } -METHOD(bio_reader_t, read_uint16, bool, - private_bio_reader_t *this, u_int16_t *res) +/** + * Read an u_int16_t from the buffer, optionally from the end + */ +static bool read_uint16_internal(private_bio_reader_t *this, u_int16_t *res, + bool from_end) { if (this->buf.len < 2) { @@ -70,13 +106,16 @@ METHOD(bio_reader_t, read_uint16, bool, this->buf.len); return FALSE; } - *res = untoh16(this->buf.ptr); - this->buf = chunk_skip(this->buf, 2); + *res = untoh16(get_ptr_end(this, 2, from_end)); + this->buf = chunk_skip_end(this->buf, 2, from_end); return TRUE; } -METHOD(bio_reader_t, read_uint24, bool, - private_bio_reader_t *this, u_int32_t *res) +/** + * Read an u_int32_t (only 24-bit) from the buffer, optionally from the end + */ +static bool read_uint24_internal(private_bio_reader_t *this, u_int32_t *res, + bool from_end) { if (this->buf.len < 3) { @@ -84,13 +123,16 @@ METHOD(bio_reader_t, read_uint24, bool, this->buf.len); return FALSE; } - *res = untoh32(this->buf.ptr) >> 8; - this->buf = chunk_skip(this->buf, 3); + *res = untoh32(get_ptr_end(this, 3, from_end)) >> 8; + this->buf = chunk_skip_end(this->buf, 3, from_end); return TRUE; } -METHOD(bio_reader_t, read_uint32, bool, - private_bio_reader_t *this, u_int32_t *res) +/** + * Read an u_int32_t from the buffer, optionally from the end + */ +static bool read_uint32_internal(private_bio_reader_t *this, u_int32_t *res, + bool from_end) { if (this->buf.len < 4) { @@ -98,13 +140,16 @@ METHOD(bio_reader_t, read_uint32, bool, this->buf.len); return FALSE; } - *res = untoh32(this->buf.ptr); - this->buf = chunk_skip(this->buf, 4); + *res = untoh32(get_ptr_end(this, 4, from_end)); + this->buf = chunk_skip_end(this->buf, 4, from_end); return TRUE; } -METHOD(bio_reader_t, read_uint64, bool, - private_bio_reader_t *this, u_int64_t *res) +/** + * Read an u_int64_t from the buffer, optionally from the end + */ +static bool read_uint64_internal(private_bio_reader_t *this, u_int64_t *res, + bool from_end) { if (this->buf.len < 8) { @@ -112,13 +157,16 @@ METHOD(bio_reader_t, read_uint64, bool, this->buf.len); return FALSE; } - *res = untoh64(this->buf.ptr); - this->buf = chunk_skip(this->buf, 8); + *res = untoh64(get_ptr_end(this, 8, from_end)); + this->buf = chunk_skip_end(this->buf, 8, from_end); return TRUE; } -METHOD(bio_reader_t, read_data, bool, - private_bio_reader_t *this, u_int32_t len, chunk_t *res) +/** + * Read a chunk of data from the buffer, optionally from the end + */ +static bool read_data_internal(private_bio_reader_t *this, u_int32_t len, + chunk_t *res, bool from_end) { if (this->buf.len < len) { @@ -126,11 +174,83 @@ METHOD(bio_reader_t, read_data, bool, this->buf.len, len); return FALSE; } - *res = chunk_create(this->buf.ptr, len); - this->buf = chunk_skip(this->buf, len); + *res = chunk_create(get_ptr_end(this, len, from_end), len); + this->buf = chunk_skip_end(this->buf, len, from_end); return TRUE; } +METHOD(bio_reader_t, read_uint8, bool, + private_bio_reader_t *this, u_int8_t *res) +{ + return read_uint8_internal(this, res, FALSE); +} + +METHOD(bio_reader_t, read_uint16, bool, + private_bio_reader_t *this, u_int16_t *res) +{ + return read_uint16_internal(this, res, FALSE); +} + +METHOD(bio_reader_t, read_uint24, bool, + private_bio_reader_t *this, u_int32_t *res) +{ + return read_uint24_internal(this, res, FALSE); +} + +METHOD(bio_reader_t, read_uint32, bool, + private_bio_reader_t *this, u_int32_t *res) +{ + return read_uint32_internal(this, res, FALSE); +} + +METHOD(bio_reader_t, read_uint64, bool, + private_bio_reader_t *this, u_int64_t *res) +{ + return read_uint64_internal(this, res, FALSE); +} + +METHOD(bio_reader_t, read_data, bool, + private_bio_reader_t *this, u_int32_t len, chunk_t *res) +{ + return read_data_internal(this, len, res, FALSE); +} + +METHOD(bio_reader_t, read_uint8_end, bool, + private_bio_reader_t *this, u_int8_t *res) +{ + return read_uint8_internal(this, res, TRUE); +} + +METHOD(bio_reader_t, read_uint16_end, bool, + private_bio_reader_t *this, u_int16_t *res) +{ + return read_uint16_internal(this, res, TRUE); +} + +METHOD(bio_reader_t, read_uint24_end, bool, + private_bio_reader_t *this, u_int32_t *res) +{ + return read_uint24_internal(this, res, TRUE); +} + +METHOD(bio_reader_t, read_uint32_end, bool, + private_bio_reader_t *this, u_int32_t *res) +{ + return read_uint32_internal(this, res, TRUE); +} + +METHOD(bio_reader_t, read_uint64_end, bool, + private_bio_reader_t *this, u_int64_t *res) +{ + return read_uint64_internal(this, res, TRUE); +} + +METHOD(bio_reader_t, read_data_end, bool, + private_bio_reader_t *this, u_int32_t len, chunk_t *res) +{ + return read_data_internal(this, len, res, TRUE); +} + METHOD(bio_reader_t, read_data8, bool, private_bio_reader_t *this, chunk_t *res) { @@ -202,6 +322,12 @@ bio_reader_t *bio_reader_create(chunk_t data) .read_uint32 = _read_uint32, .read_uint64 = _read_uint64, .read_data = _read_data, + .read_uint8_end = _read_uint8_end, + .read_uint16_end = _read_uint16_end, + .read_uint24_end = _read_uint24_end, + .read_uint32_end = _read_uint32_end, + .read_uint64_end = _read_uint64_end, + .read_data_end = _read_data_end, .read_data8 = _read_data8, .read_data16 = _read_data16, .read_data24 = _read_data24, diff --git a/src/libstrongswan/bio/bio_reader.h b/src/libstrongswan/bio/bio_reader.h index 85434a784..3162f3eda 100644 --- a/src/libstrongswan/bio/bio_reader.h +++ b/src/libstrongswan/bio/bio_reader.h @@ -1,4 +1,7 @@ /* + * Copyright (C) 2012 Tobias Brunner + * Hochschule fuer Technik Rapperswil + * * Copyright (C) 2010 Martin Willi * Copyright (C) 2010 revosec AG * @@ -27,6 +30,8 @@ typedef struct bio_reader_t bio_reader_t; /** * Buffered input parser. + * + * @note Integers are returned in host byte order. */ struct bio_reader_t { @@ -94,6 +99,55 @@ struct bio_reader_t { bool (*read_data)(bio_reader_t *this, u_int32_t len, chunk_t *res); /** + * Read a 8-bit integer from the end of the buffer, reduce remaining. + * + * @param res pointer to result + * @return TRUE if integer read successfully + */ + bool (*read_uint8_end)(bio_reader_t *this, u_int8_t *res); + + /** + * Read a 16-bit integer from the end of the buffer, reduce remaining. + * + * @param res pointer to result + * @return TRUE if integer read successfully + */ + bool (*read_uint16_end)(bio_reader_t *this, u_int16_t *res); + + /** + * Read a 24-bit integer from the end of the buffer, reduce remaining. + * + * @param res pointer to result + * @return TRUE if integer read successfully + */ + bool (*read_uint24_end)(bio_reader_t *this, u_int32_t *res); + + /** + * Read a 32-bit integer from the end of the buffer, reduce remaining. + * + * @param res pointer to result + * @return TRUE if integer read successfully + */ + bool (*read_uint32_end)(bio_reader_t *this, u_int32_t *res); + + /** + * Read a 64-bit integer from the end of the buffer, reduce remaining. + * + * @param res pointer to result + * @return TRUE if integer read successfully + */ + bool (*read_uint64_end)(bio_reader_t *this, u_int64_t *res); + + /** + * Read a chunk of len bytes from the end of the buffer, reduce remaining. + * + * @param len number of bytes to read + * @param res ponter to result, not cloned + * @return TRUE if data read successfully + */ + bool (*read_data_end)(bio_reader_t *this, u_int32_t len, chunk_t *res); + + /** * Read a chunk of bytes with a 8-bit length header, advance. * * @param res pointer to result, not cloned diff --git a/src/libstrongswan/bio/bio_writer.c b/src/libstrongswan/bio/bio_writer.c index bf373d6ac..8576843ee 100644 --- a/src/libstrongswan/bio/bio_writer.c +++ b/src/libstrongswan/bio/bio_writer.c @@ -1,4 +1,7 @@ /* + * Copyright (C) 2012 Tobias Brunner + * Hochschule fuer Technik Rapperswil + * * Copyright (C) 2010 Martin Willi * Copyright (C) 2010 revosec AG * @@ -199,12 +202,35 @@ METHOD(bio_writer_t, wrap32, void, this->used += 4; } +METHOD(bio_writer_t, skip, chunk_t, + private_bio_writer_t *this, size_t len) +{ + chunk_t skipped; + + while (this->used + len > this->buf.len) + { + increase(this); + } + skipped = chunk_create(this->buf.ptr + this->used, len); + this->used += len; + return skipped; +} + METHOD(bio_writer_t, get_buf, chunk_t, private_bio_writer_t *this) { return chunk_create(this->buf.ptr, this->used); } +METHOD(bio_writer_t, extract_buf, chunk_t, + private_bio_writer_t *this) +{ + chunk_t buf = get_buf(this); + this->buf = chunk_empty; + this->used = 0; + return buf; +} + METHOD(bio_writer_t, destroy, void, private_bio_writer_t *this) { @@ -235,7 +261,9 @@ bio_writer_t *bio_writer_create(u_int32_t bufsize) .wrap16 = _wrap16, .wrap24 = _wrap24, .wrap32 = _wrap32, + .skip = _skip, .get_buf = _get_buf, + .extract_buf = _extract_buf, .destroy = _destroy, }, .increase = bufsize ? max(bufsize, 4) : 32, diff --git a/src/libstrongswan/bio/bio_writer.h b/src/libstrongswan/bio/bio_writer.h index 0b50f7882..57a5c3d38 100644 --- a/src/libstrongswan/bio/bio_writer.h +++ b/src/libstrongswan/bio/bio_writer.h @@ -1,4 +1,7 @@ /* + * Copyright (C) 2012 Tobias Brunner + * Hochschule fuer Technik Rapperswil + * * Copyright (C) 2010 Martin Willi * Copyright (C) 2010 revosec AG * @@ -27,6 +30,8 @@ typedef struct bio_writer_t bio_writer_t; /** * Buffered output generator. + * + * @note Integers are converted to network byte order before writing. */ struct bio_writer_t { @@ -121,6 +126,15 @@ struct bio_writer_t { void (*wrap32)(bio_writer_t *this); /** + * Skips len bytes in the buffer before the next data is written, returns + * a chunk covering the skipped bytes. + * + * @param len number of bytes to skip + * @return chunk pointing to skipped bytes in the internal buffer + */ + chunk_t (*skip)(bio_writer_t *this, size_t len); + + /** * Get the encoded data buffer. * * @return chunk to internal buffer @@ -128,6 +142,14 @@ struct bio_writer_t { chunk_t (*get_buf)(bio_writer_t *this); /** + * Return the encoded data buffer and detach it from the writer (resets + * the internal buffer). + * + * @return chunk to internal buffer (has to be freed) + */ + chunk_t (*extract_buf)(bio_writer_t *this); + + /** * Destroy a bio_writer_t. */ void (*destroy)(bio_writer_t *this); @@ -136,6 +158,9 @@ struct bio_writer_t { /** * Create a bio_writer instance. * + * The size of the internal buffer is increased automatically by bufsize (or a + * default if not given) if the initial size does not suffice. + * * @param bufsize initially allocated buffer size */ bio_writer_t *bio_writer_create(u_int32_t bufsize); diff --git a/src/libstrongswan/chunk.c b/src/libstrongswan/chunk.c index 9397c4e44..d7f1c31d9 100644 --- a/src/libstrongswan/chunk.c +++ b/src/libstrongswan/chunk.c @@ -658,7 +658,7 @@ u_int32_t chunk_hash(chunk_t chunk) /** * Described in header. */ -int chunk_printf_hook(char *dst, size_t len, printf_hook_spec_t *spec, +int chunk_printf_hook(printf_hook_data_t *data, printf_hook_spec_t *spec, const void *const *args) { chunk_t *chunk = *((chunk_t**)(args[0])); @@ -670,7 +670,7 @@ int chunk_printf_hook(char *dst, size_t len, printf_hook_spec_t *spec, { u_int chunk_len = chunk->len; const void *new_args[] = {&chunk->ptr, &chunk_len}; - return mem_printf_hook(dst, len, spec, new_args); + return mem_printf_hook(data, spec, new_args); } while (copy.len > 0) @@ -681,9 +681,9 @@ int chunk_printf_hook(char *dst, size_t len, printf_hook_spec_t *spec, } else { - written += print_in_hook(dst, len, ":"); + written += print_in_hook(data, ":"); } - written += print_in_hook(dst, len, "%02x", *copy.ptr++); + written += print_in_hook(data, "%02x", *copy.ptr++); copy.len--; } return written; diff --git a/src/libstrongswan/chunk.h b/src/libstrongswan/chunk.h index 3de02eee7..91b23da3b 100644 --- a/src/libstrongswan/chunk.h +++ b/src/libstrongswan/chunk.h @@ -265,6 +265,15 @@ static inline bool chunk_equals(chunk_t a, chunk_t b) } /** + * Compare two chunks (given as pointers) for equality (useful as callback), + * NULL chunks are never equal. + */ +static inline bool chunk_equals_ptr(chunk_t *a, chunk_t *b) +{ + return a != NULL && b != NULL && chunk_equals(*a, *b); +} + +/** * Increment a chunk, as it would reprensent a network order integer. * * @param chunk chunk to increment @@ -303,7 +312,7 @@ u_int32_t chunk_hash_inc(chunk_t chunk, u_int32_t hash); * chunk_t *chunk * Use #-modifier to print a compact version */ -int chunk_printf_hook(char *dst, size_t len, printf_hook_spec_t *spec, +int chunk_printf_hook(printf_hook_data_t *data, printf_hook_spec_t *spec, const void *const *args); #endif /** CHUNK_H_ @}*/ diff --git a/src/libstrongswan/credentials/auth_cfg.c b/src/libstrongswan/credentials/auth_cfg.c index 12f75b240..6ee4f9b6e 100644 --- a/src/libstrongswan/credentials/auth_cfg.c +++ b/src/libstrongswan/credentials/auth_cfg.c @@ -23,20 +23,24 @@ #include <eap/eap.h> #include <credentials/certificates/certificate.h> -ENUM(auth_class_names, AUTH_CLASS_ANY, AUTH_CLASS_EAP, +ENUM(auth_class_names, AUTH_CLASS_ANY, AUTH_CLASS_XAUTH, "any", "public key", "pre-shared key", "EAP", + "XAuth", ); ENUM(auth_rule_names, AUTH_RULE_IDENTITY, AUTH_HELPER_REVOCATION_CERT, "RULE_IDENTITY", + "RULE_IDENTITY_LOOSE", "RULE_AUTH_CLASS", "RULE_AAA_IDENTITY", "RULE_EAP_IDENTITY", "RULE_EAP_TYPE", "RULE_EAP_VENDOR", + "RULE_XAUTH_BACKEND", + "RULE_XAUTH_IDENTITY", "RULE_CA_CERT", "RULE_IM_CERT", "RULE_SUBJECT_CERT", @@ -45,6 +49,7 @@ ENUM(auth_rule_names, AUTH_RULE_IDENTITY, AUTH_HELPER_REVOCATION_CERT, "RULE_GROUP", "RULE_RSA_STRENGTH", "RULE_ECDSA_STRENGTH", + "RULE_SIGNATURE_SCHEME", "RULE_CERT_POLICY", "HELPER_IM_CERT", "HELPER_SUBJECT_CERT", @@ -66,8 +71,11 @@ static inline bool is_multi_value_rule(auth_rule_t type) case AUTH_RULE_RSA_STRENGTH: case AUTH_RULE_ECDSA_STRENGTH: case AUTH_RULE_IDENTITY: + case AUTH_RULE_IDENTITY_LOOSE: case AUTH_RULE_EAP_IDENTITY: case AUTH_RULE_AAA_IDENTITY: + case AUTH_RULE_XAUTH_IDENTITY: + case AUTH_RULE_XAUTH_BACKEND: case AUTH_RULE_SUBJECT_CERT: case AUTH_HELPER_SUBJECT_CERT: case AUTH_HELPER_SUBJECT_HASH_URL: @@ -79,6 +87,7 @@ static inline bool is_multi_value_rule(auth_rule_t type) case AUTH_RULE_CA_CERT: case AUTH_RULE_IM_CERT: case AUTH_RULE_CERT_POLICY: + case AUTH_RULE_SIGNATURE_SCHEME: case AUTH_HELPER_IM_CERT: case AUTH_HELPER_IM_HASH_URL: case AUTH_HELPER_REVOCATION_CERT: @@ -190,6 +199,7 @@ static entry_t *entry_create(auth_rule_t type, va_list args) this->type = type; switch (type) { + case AUTH_RULE_IDENTITY_LOOSE: case AUTH_RULE_AUTH_CLASS: case AUTH_RULE_EAP_TYPE: case AUTH_RULE_EAP_VENDOR: @@ -197,12 +207,15 @@ static entry_t *entry_create(auth_rule_t type, va_list args) case AUTH_RULE_OCSP_VALIDATION: case AUTH_RULE_RSA_STRENGTH: case AUTH_RULE_ECDSA_STRENGTH: + case AUTH_RULE_SIGNATURE_SCHEME: /* integer type */ this->value = (void*)(uintptr_t)va_arg(args, u_int); break; case AUTH_RULE_IDENTITY: case AUTH_RULE_EAP_IDENTITY: case AUTH_RULE_AAA_IDENTITY: + case AUTH_RULE_XAUTH_BACKEND: + case AUTH_RULE_XAUTH_IDENTITY: case AUTH_RULE_GROUP: case AUTH_RULE_CA_CERT: case AUTH_RULE_IM_CERT: @@ -234,6 +247,7 @@ static bool entry_equals(entry_t *e1, entry_t *e2) } switch (e1->type) { + case AUTH_RULE_IDENTITY_LOOSE: case AUTH_RULE_AUTH_CLASS: case AUTH_RULE_EAP_TYPE: case AUTH_RULE_EAP_VENDOR: @@ -241,6 +255,7 @@ static bool entry_equals(entry_t *e1, entry_t *e2) case AUTH_RULE_OCSP_VALIDATION: case AUTH_RULE_RSA_STRENGTH: case AUTH_RULE_ECDSA_STRENGTH: + case AUTH_RULE_SIGNATURE_SCHEME: { return e1->value == e2->value; } @@ -261,6 +276,7 @@ static bool entry_equals(entry_t *e1, entry_t *e2) case AUTH_RULE_IDENTITY: case AUTH_RULE_EAP_IDENTITY: case AUTH_RULE_AAA_IDENTITY: + case AUTH_RULE_XAUTH_IDENTITY: case AUTH_RULE_GROUP: { identification_t *id1, *id2; @@ -271,6 +287,7 @@ static bool entry_equals(entry_t *e1, entry_t *e2) return id1->equals(id1, id2); } case AUTH_RULE_CERT_POLICY: + case AUTH_RULE_XAUTH_BACKEND: case AUTH_HELPER_IM_HASH_URL: case AUTH_HELPER_SUBJECT_HASH_URL: { @@ -293,6 +310,7 @@ static void destroy_entry_value(entry_t *entry) case AUTH_RULE_EAP_IDENTITY: case AUTH_RULE_AAA_IDENTITY: case AUTH_RULE_GROUP: + case AUTH_RULE_XAUTH_IDENTITY: { identification_t *id = (identification_t*)entry->value; id->destroy(id); @@ -310,12 +328,14 @@ static void destroy_entry_value(entry_t *entry) break; } case AUTH_RULE_CERT_POLICY: + case AUTH_RULE_XAUTH_BACKEND: case AUTH_HELPER_IM_HASH_URL: case AUTH_HELPER_SUBJECT_HASH_URL: { free(entry->value); break; } + case AUTH_RULE_IDENTITY_LOOSE: case AUTH_RULE_AUTH_CLASS: case AUTH_RULE_EAP_TYPE: case AUTH_RULE_EAP_VENDOR: @@ -323,6 +343,7 @@ static void destroy_entry_value(entry_t *entry) case AUTH_RULE_OCSP_VALIDATION: case AUTH_RULE_RSA_STRENGTH: case AUTH_RULE_ECDSA_STRENGTH: + case AUTH_RULE_SIGNATURE_SCHEME: case AUTH_RULE_MAX: break; } @@ -345,6 +366,7 @@ static void replace(private_auth_cfg_t *this, entry_enumerator_t *enumerator, entry->type = type; switch (type) { + case AUTH_RULE_IDENTITY_LOOSE: case AUTH_RULE_AUTH_CLASS: case AUTH_RULE_EAP_TYPE: case AUTH_RULE_EAP_VENDOR: @@ -352,12 +374,15 @@ static void replace(private_auth_cfg_t *this, entry_enumerator_t *enumerator, case AUTH_RULE_OCSP_VALIDATION: case AUTH_RULE_RSA_STRENGTH: case AUTH_RULE_ECDSA_STRENGTH: + case AUTH_RULE_SIGNATURE_SCHEME: /* integer type */ entry->value = (void*)(uintptr_t)va_arg(args, u_int); break; case AUTH_RULE_IDENTITY: case AUTH_RULE_EAP_IDENTITY: case AUTH_RULE_AAA_IDENTITY: + case AUTH_RULE_XAUTH_BACKEND: + case AUTH_RULE_XAUTH_IDENTITY: case AUTH_RULE_GROUP: case AUTH_RULE_CA_CERT: case AUTH_RULE_IM_CERT: @@ -423,12 +448,18 @@ METHOD(auth_cfg_t, get, void*, case AUTH_RULE_RSA_STRENGTH: case AUTH_RULE_ECDSA_STRENGTH: return (void*)0; + case AUTH_RULE_SIGNATURE_SCHEME: + return HASH_UNKNOWN; case AUTH_RULE_CRL_VALIDATION: case AUTH_RULE_OCSP_VALIDATION: return (void*)VALIDATION_FAILED; + case AUTH_RULE_IDENTITY_LOOSE: + return (void*)FALSE; case AUTH_RULE_IDENTITY: case AUTH_RULE_EAP_IDENTITY: case AUTH_RULE_AAA_IDENTITY: + case AUTH_RULE_XAUTH_BACKEND: + case AUTH_RULE_XAUTH_IDENTITY: case AUTH_RULE_GROUP: case AUTH_RULE_CA_CERT: case AUTH_RULE_IM_CERT: @@ -472,7 +503,10 @@ METHOD(auth_cfg_t, complies, bool, private_auth_cfg_t *this, auth_cfg_t *constraints, bool log_error) { enumerator_t *e1, *e2; - bool success = TRUE, has_group = FALSE, group_match = FALSE; + bool success = TRUE, group_match = FALSE; + identification_t *require_group = NULL; + signature_scheme_t scheme = SIGN_UNKNOWN; + u_int strength = 0; auth_rule_t t1, t2; void *value; @@ -571,6 +605,7 @@ METHOD(auth_cfg_t, complies, bool, case AUTH_RULE_IDENTITY: case AUTH_RULE_EAP_IDENTITY: case AUTH_RULE_AAA_IDENTITY: + case AUTH_RULE_XAUTH_IDENTITY: { identification_t *id1, *id2; @@ -578,6 +613,17 @@ METHOD(auth_cfg_t, complies, bool, id2 = get(this, t1); if (!id2 || !id2->matches(id2, id1)) { + if (t1 == AUTH_RULE_IDENTITY && + constraints->get(constraints, AUTH_RULE_IDENTITY_LOOSE)) + { /* also verify identity against subjectAltNames */ + certificate_t *cert; + + cert = get(this, AUTH_HELPER_SUBJECT_CERT); + if (cert && cert->has_subject(cert, id1)) + { + break; + } + } success = FALSE; if (log_error) { @@ -633,15 +679,15 @@ METHOD(auth_cfg_t, complies, bool, } case AUTH_RULE_GROUP: { - identification_t *id1, *id2; + identification_t *group; /* for groups, a match of a single group is sufficient */ - has_group = TRUE; - id1 = (identification_t*)value; + require_group = (identification_t*)value; e2 = create_enumerator(this); - while (e2->enumerate(e2, &t2, &id2)) + while (e2->enumerate(e2, &t2, &group)) { - if (t2 == AUTH_RULE_GROUP && id2->matches(id2, id1)) + if (t2 == AUTH_RULE_GROUP && + group->matches(group, require_group)) { group_match = TRUE; } @@ -652,44 +698,12 @@ METHOD(auth_cfg_t, complies, bool, case AUTH_RULE_RSA_STRENGTH: case AUTH_RULE_ECDSA_STRENGTH: { - uintptr_t strength; - - e2 = create_enumerator(this); - while (e2->enumerate(e2, &t2, &strength)) - { - if (t2 == t1) - { - if ((uintptr_t)value > strength) - { - success = FALSE; - if (log_error) - { - DBG1(DBG_CFG, "constraint requires %d bit " - "public keys, but %d bit key used", - (uintptr_t)value, strength); - } - } - } - else if (t2 == AUTH_RULE_RSA_STRENGTH) - { - success = FALSE; - if (log_error) - { - DBG1(DBG_CFG, "constraint requires %d bit ECDSA, " - "but RSA used", (uintptr_t)value); - } - } - else if (t2 == AUTH_RULE_ECDSA_STRENGTH) - { - success = FALSE; - if (log_error) - { - DBG1(DBG_CFG, "constraint requires %d bit RSA, " - "but ECDSA used", (uintptr_t)value); - } - } - } - e2->destroy(e2); + strength = (uintptr_t)value; + break; + } + case AUTH_RULE_SIGNATURE_SCHEME: + { + scheme = (uintptr_t)value; break; } case AUTH_RULE_CERT_POLICY: @@ -714,6 +728,10 @@ METHOD(auth_cfg_t, complies, bool, } break; } + case AUTH_RULE_IDENTITY_LOOSE: + /* just an indication when verifying AUTH_RULE_IDENTITY */ + case AUTH_RULE_XAUTH_BACKEND: + /* not enforced, just a hint for local authentication */ case AUTH_HELPER_IM_CERT: case AUTH_HELPER_SUBJECT_CERT: case AUTH_HELPER_IM_HASH_URL: @@ -730,11 +748,83 @@ METHOD(auth_cfg_t, complies, bool, } e1->destroy(e1); - if (has_group && !group_match) + /* Check if we have a matching constraint (or none at all) for used + * signature schemes. */ + if (success && scheme != SIGN_UNKNOWN) + { + e2 = create_enumerator(this); + while (e2->enumerate(e2, &t2, &scheme)) + { + if (t2 == AUTH_RULE_SIGNATURE_SCHEME) + { + success = FALSE; + e1 = constraints->create_enumerator(constraints); + while (e1->enumerate(e1, &t1, &value)) + { + if (t1 == AUTH_RULE_SIGNATURE_SCHEME && + (uintptr_t)value == scheme) + { + success = TRUE; + break; + } + } + e1->destroy(e1); + if (!success) + { + if (log_error) + { + DBG1(DBG_CFG, "signature scheme %N not acceptable", + signature_scheme_names, (int)scheme); + } + break; + } + } + } + e2->destroy(e2); + } + + /* Check if we have a matching constraint (or none at all) for used + * public key strength */ + if (success && strength) + { + e2 = create_enumerator(this); + while (e2->enumerate(e2, &t2, &strength)) + { + if (t2 == AUTH_RULE_RSA_STRENGTH || + t2 == AUTH_RULE_ECDSA_STRENGTH) + { + success = FALSE; + e1 = constraints->create_enumerator(constraints); + while (e1->enumerate(e1, &t1, &value)) + { + if (t1 == t2 && (uintptr_t)value <= strength) + { + success = TRUE; + break; + } + } + e1->destroy(e1); + if (!success) + { + if (log_error) + { + DBG1(DBG_CFG, "%s-%d signatures not acceptable", + t2 == AUTH_RULE_RSA_STRENGTH ? "RSA" : "ECDSA", + strength); + } + break; + } + } + } + e2->destroy(e2); + } + + if (require_group && !group_match) { if (log_error) { - DBG1(DBG_CFG, "constraint check failed: group membership required"); + DBG1(DBG_CFG, "constraint check failed: group membership to " + "'%Y' required", require_group); } return FALSE; } @@ -774,6 +864,7 @@ static void merge(private_auth_cfg_t *this, private_auth_cfg_t *other, bool copy add(this, type, cert->get_ref(cert)); break; } + case AUTH_RULE_IDENTITY_LOOSE: case AUTH_RULE_CRL_VALIDATION: case AUTH_RULE_OCSP_VALIDATION: case AUTH_RULE_AUTH_CLASS: @@ -781,6 +872,7 @@ static void merge(private_auth_cfg_t *this, private_auth_cfg_t *other, bool copy case AUTH_RULE_EAP_VENDOR: case AUTH_RULE_RSA_STRENGTH: case AUTH_RULE_ECDSA_STRENGTH: + case AUTH_RULE_SIGNATURE_SCHEME: { add(this, type, (uintptr_t)value); break; @@ -789,12 +881,14 @@ static void merge(private_auth_cfg_t *this, private_auth_cfg_t *other, bool copy case AUTH_RULE_EAP_IDENTITY: case AUTH_RULE_AAA_IDENTITY: case AUTH_RULE_GROUP: + case AUTH_RULE_XAUTH_IDENTITY: { identification_t *id = (identification_t*)value; add(this, type, id->clone(id)); break; } + case AUTH_RULE_XAUTH_BACKEND: case AUTH_RULE_CERT_POLICY: case AUTH_HELPER_IM_HASH_URL: case AUTH_HELPER_SUBJECT_HASH_URL: @@ -821,9 +915,9 @@ static void merge(private_auth_cfg_t *this, private_auth_cfg_t *other, bool copy } /** - * Implementation of auth_cfg_t.equals. + * Compare two auth_cfg_t objects for equality. */ -static bool equals(private_auth_cfg_t *this, private_auth_cfg_t *other) +static bool auth_cfg_equals(private_auth_cfg_t *this, private_auth_cfg_t *other) { enumerator_t *e1, *e2; entry_t *i1, *i2; @@ -860,6 +954,20 @@ static bool equals(private_auth_cfg_t *this, private_auth_cfg_t *other) return equal; } +/** + * Implementation of auth_cfg_t.equals. + */ +static bool equals(private_auth_cfg_t *this, private_auth_cfg_t *other) +{ + if (auth_cfg_equals(this, other)) + { + /* as 'other' might contain entries that 'this' doesn't we also check + * the other way around */ + return auth_cfg_equals(other, this); + } + return FALSE; +} + METHOD(auth_cfg_t, purge, void, private_auth_cfg_t *this, bool keep_ca) { @@ -904,6 +1012,7 @@ METHOD(auth_cfg_t, clone_, auth_cfg_t*, case AUTH_RULE_EAP_IDENTITY: case AUTH_RULE_AAA_IDENTITY: case AUTH_RULE_GROUP: + case AUTH_RULE_XAUTH_IDENTITY: { identification_t *id = (identification_t*)entry->value; clone->add(clone, entry->type, id->clone(id)); @@ -920,6 +1029,7 @@ METHOD(auth_cfg_t, clone_, auth_cfg_t*, clone->add(clone, entry->type, cert->get_ref(cert)); break; } + case AUTH_RULE_XAUTH_BACKEND: case AUTH_RULE_CERT_POLICY: case AUTH_HELPER_IM_HASH_URL: case AUTH_HELPER_SUBJECT_HASH_URL: @@ -927,6 +1037,7 @@ METHOD(auth_cfg_t, clone_, auth_cfg_t*, clone->add(clone, entry->type, strdup(entry->value)); break; } + case AUTH_RULE_IDENTITY_LOOSE: case AUTH_RULE_AUTH_CLASS: case AUTH_RULE_EAP_TYPE: case AUTH_RULE_EAP_VENDOR: @@ -934,6 +1045,7 @@ METHOD(auth_cfg_t, clone_, auth_cfg_t*, case AUTH_RULE_OCSP_VALIDATION: case AUTH_RULE_RSA_STRENGTH: case AUTH_RULE_ECDSA_STRENGTH: + case AUTH_RULE_SIGNATURE_SCHEME: clone->add(clone, entry->type, (uintptr_t)entry->value); break; case AUTH_RULE_MAX: diff --git a/src/libstrongswan/credentials/auth_cfg.h b/src/libstrongswan/credentials/auth_cfg.h index 4d12a9c14..79484a04c 100644 --- a/src/libstrongswan/credentials/auth_cfg.h +++ b/src/libstrongswan/credentials/auth_cfg.h @@ -42,6 +42,8 @@ enum auth_class_t { AUTH_CLASS_PSK = 2, /** authentication using EAP */ AUTH_CLASS_EAP = 3, + /** authentication using IKEv1 XAUTH */ + AUTH_CLASS_XAUTH = 4, }; /** @@ -65,6 +67,9 @@ extern enum_name_t *auth_class_names; enum auth_rule_t { /** identity to use for IKEv2 authentication exchange, identification_t* */ AUTH_RULE_IDENTITY, + /** if TRUE don't send IDr as initiator, but verify the identity after + * receiving IDr (but also verify it against subjectAltNames), bool */ + AUTH_RULE_IDENTITY_LOOSE, /** authentication class, auth_class_t */ AUTH_RULE_AUTH_CLASS, /** AAA-backend identity for EAP methods supporting it, identification_t* */ @@ -75,6 +80,10 @@ enum auth_rule_t { AUTH_RULE_EAP_TYPE, /** EAP vendor for vendor specific type, u_int32_t */ AUTH_RULE_EAP_VENDOR, + /** XAUTH backend name to use, char* */ + AUTH_RULE_XAUTH_BACKEND, + /** XAuth identity to use or require, identification_t* */ + AUTH_RULE_XAUTH_IDENTITY, /** certificate authority, certificate_t* */ AUTH_RULE_CA_CERT, /** intermediate certificate in trustchain, certificate_t* */ @@ -93,6 +102,8 @@ enum auth_rule_t { AUTH_RULE_RSA_STRENGTH, /** required ECDSA public key strength, u_int in bits */ AUTH_RULE_ECDSA_STRENGTH, + /** required signature scheme, signature_scheme_t */ + AUTH_RULE_SIGNATURE_SCHEME, /** certificatePolicy constraint, numerical OID as char* */ AUTH_RULE_CERT_POLICY, @@ -172,7 +183,7 @@ struct auth_cfg_t { * For rules we expect only once the latest value is returned. * * @param rule rule type - * @return bool if item has been found + * @return rule or NULL (or an appropriate default) if not found */ void* (*get)(auth_cfg_t *this, auth_rule_t rule); diff --git a/src/libstrongswan/credentials/certificates/certificate.h b/src/libstrongswan/credentials/certificates/certificate.h index 2f471da5b..b7a88ffbd 100644 --- a/src/libstrongswan/credentials/certificates/certificate.h +++ b/src/libstrongswan/credentials/certificates/certificate.h @@ -143,9 +143,11 @@ struct certificate_t { * Check if this certificate is issued and signed by a specific issuer. * * @param issuer issuer's certificate + * @param scheme receives signature scheme used during verification * @return TRUE if certificate issued by issuer and trusted */ - bool (*issued_by)(certificate_t *this, certificate_t *issuer); + bool (*issued_by)(certificate_t *this, certificate_t *issuer, + signature_scheme_t *scheme); /** * Get the public key associated to this certificate. diff --git a/src/libstrongswan/credentials/certificates/x509.h b/src/libstrongswan/credentials/certificates/x509.h index 5125aca26..00171a718 100644 --- a/src/libstrongswan/credentials/certificates/x509.h +++ b/src/libstrongswan/credentials/certificates/x509.h @@ -56,6 +56,8 @@ enum x509_flag_t { X509_IP_ADDR_BLOCKS = (1<<6), /** cert has CRL sign key usage */ X509_CRL_SIGN = (1<<7), + /** cert has iKEIntermediate key usage */ + X509_IKE_INTERMEDIATE = (1<<8), }; /** diff --git a/src/libstrongswan/credentials/credential_manager.c b/src/libstrongswan/credentials/credential_manager.c index b3461b810..a96abdc69 100644 --- a/src/libstrongswan/credentials/credential_manager.c +++ b/src/libstrongswan/credentials/credential_manager.c @@ -53,6 +53,11 @@ struct private_credential_manager_t { thread_value_t *local_sets; /** + * Exclusive local sets, linked_list_t with credential_set_t + */ + thread_value_t *exclusive_local_sets; + + /** * trust relationship and certificate cache */ cert_cache_t *cache; @@ -117,12 +122,23 @@ typedef struct { enumerator_t *global; /** enumerator over local sets */ enumerator_t *local; + /** enumerator over exclusive local sets */ + enumerator_t *exclusive; } sets_enumerator_t; METHOD(enumerator_t, sets_enumerate, bool, sets_enumerator_t *this, credential_set_t **set) { + if (this->exclusive) + { + if (this->exclusive->enumerate(this->exclusive, set)) + { /* only enumerate last added */ + this->exclusive->destroy(this->exclusive); + this->exclusive = NULL; + return TRUE; + } + } if (this->global) { if (this->global->enumerate(this->global, set)) @@ -145,6 +161,7 @@ METHOD(enumerator_t, sets_destroy, void, { DESTROY_IF(this->global); DESTROY_IF(this->local); + DESTROY_IF(this->exclusive); free(this); } @@ -154,19 +171,28 @@ METHOD(enumerator_t, sets_destroy, void, static enumerator_t *create_sets_enumerator(private_credential_manager_t *this) { sets_enumerator_t *enumerator; - linked_list_t *local; + linked_list_t *list; INIT(enumerator, .public = { .enumerate = (void*)_sets_enumerate, .destroy = _sets_destroy, }, - .global = this->sets->create_enumerator(this->sets), ); - local = this->local_sets->get(this->local_sets); - if (local) + + list = this->exclusive_local_sets->get(this->exclusive_local_sets); + if (list && list->get_count(list)) + { + enumerator->exclusive = list->create_enumerator(list); + } + else { - enumerator->local = local->create_enumerator(local); + enumerator->global = this->sets->create_enumerator(this->sets); + list = this->local_sets->get(this->local_sets); + if (list) + { + enumerator->local = list->create_enumerator(list); + } } return &enumerator->public; } @@ -373,26 +399,66 @@ METHOD(credential_manager_t, get_shared, shared_key_t*, } METHOD(credential_manager_t, add_local_set, void, - private_credential_manager_t *this, credential_set_t *set) + private_credential_manager_t *this, credential_set_t *set, bool exclusive) { linked_list_t *sets; + thread_value_t *tv; - sets = this->local_sets->get(this->local_sets); + if (exclusive) + { + tv = this->exclusive_local_sets; + } + else + { + tv = this->local_sets; + } + sets = tv->get(tv); if (!sets) - { /* first invocation */ + { sets = linked_list_create(); - this->local_sets->set(this->local_sets, sets); + tv->set(tv, sets); + } + if (exclusive) + { + sets->insert_first(sets, set); + } + else + { + sets->insert_last(sets, set); } - sets->insert_last(sets, set); } METHOD(credential_manager_t, remove_local_set, void, private_credential_manager_t *this, credential_set_t *set) { linked_list_t *sets; + thread_value_t *tv; - sets = this->local_sets->get(this->local_sets); - sets->remove(sets, set, NULL); + tv = this->local_sets; + sets = tv->get(tv); + if (sets && sets->remove(sets, set, NULL) && sets->get_count(sets) == 0) + { + tv->set(tv, NULL); + sets->destroy(sets); + } + tv = this->exclusive_local_sets; + sets = tv->get(tv); + if (sets && sets->remove(sets, set, NULL) && sets->get_count(sets) == 0) + { + tv->set(tv, NULL); + sets->destroy(sets); + } +} + +METHOD(credential_manager_t, issued_by, bool, + private_credential_manager_t *this, certificate_t *subject, + certificate_t *issuer, signature_scheme_t *scheme) +{ + if (this->cache) + { + return this->cache->issued_by(this->cache, subject, issuer, scheme); + } + return subject->issued_by(subject, issuer, scheme); } METHOD(credential_manager_t, cache_cert, void, @@ -514,7 +580,8 @@ static certificate_t *get_pretrusted_cert(private_credential_manager_t *this, * Get the issuing certificate of a subject certificate */ static certificate_t *get_issuer_cert(private_credential_manager_t *this, - certificate_t *subject, bool trusted) + certificate_t *subject, bool trusted, + signature_scheme_t *scheme) { enumerator_t *enumerator; certificate_t *issuer = NULL, *candidate; @@ -523,7 +590,7 @@ static certificate_t *get_issuer_cert(private_credential_manager_t *this, subject->get_issuer(subject), trusted); while (enumerator->enumerate(enumerator, &candidate)) { - if (this->cache->issued_by(this->cache, subject, candidate)) + if (issued_by(this, subject, candidate, scheme)) { issuer = candidate->get_ref(candidate); break; @@ -573,6 +640,7 @@ static bool verify_trust_chain(private_credential_manager_t *this, { certificate_t *current, *issuer; auth_cfg_t *auth; + signature_scheme_t scheme; int pathlen; auth = auth_cfg_create(); @@ -582,11 +650,11 @@ static bool verify_trust_chain(private_credential_manager_t *this, for (pathlen = 0; pathlen <= MAX_TRUST_PATH_LEN; pathlen++) { - issuer = get_issuer_cert(this, current, TRUE); + issuer = get_issuer_cert(this, current, TRUE, &scheme); if (issuer) { /* accept only self-signed CAs as trust anchor */ - if (this->cache->issued_by(this->cache, issuer, issuer)) + if (issued_by(this, issuer, issuer, NULL)) { auth->add(auth, AUTH_RULE_CA_CERT, issuer->get_ref(issuer)); DBG1(DBG_CFG, " using trusted ca certificate \"%Y\"", @@ -599,10 +667,11 @@ static bool verify_trust_chain(private_credential_manager_t *this, DBG1(DBG_CFG, " using trusted intermediate ca certificate " "\"%Y\"", issuer->get_subject(issuer)); } + auth->add(auth, AUTH_RULE_SIGNATURE_SCHEME, scheme); } else { - issuer = get_issuer_cert(this, current, FALSE); + issuer = get_issuer_cert(this, current, FALSE, &scheme); if (issuer) { if (current->equals(current, issuer)) @@ -615,6 +684,7 @@ static bool verify_trust_chain(private_credential_manager_t *this, auth->add(auth, AUTH_RULE_IM_CERT, issuer->get_ref(issuer)); DBG1(DBG_CFG, " using untrusted intermediate certificate " "\"%Y\"", issuer->get_subject(issuer)); + auth->add(auth, AUTH_RULE_SIGNATURE_SCHEME, scheme); } else { @@ -708,8 +778,7 @@ METHOD(enumerator_t, trusted_enumerate, bool, /* if we find a trusted self signed certificate, we just accept it. * However, in order to fulfill authorization rules, we try to build * the trust chain if it is not self signed */ - if (this->this->cache->issued_by(this->this->cache, - this->pretrusted, this->pretrusted) || + if (issued_by(this->this, this->pretrusted, this->pretrusted, NULL) || verify_trust_chain(this->this, this->pretrusted, this->auth, TRUE, this->online)) { @@ -859,7 +928,7 @@ METHOD(credential_manager_t, create_public_enumerator, enumerator_t*, if (auth) { enumerator->wrapper = auth_cfg_wrapper_create(auth); - add_local_set(this, &enumerator->wrapper->set); + add_local_set(this, &enumerator->wrapper->set, FALSE); } this->lock->read_lock(this->lock); return &enumerator->public; @@ -916,8 +985,7 @@ static auth_cfg_t *build_trustchain(private_credential_manager_t *this, } else { - if (!has_anchor && - this->cache->issued_by(this->cache, current, current)) + if (!has_anchor && issued_by(this, current, current, NULL)) { /* If no trust anchor specified, accept any CA */ trustchain->add(trustchain, AUTH_RULE_CA_CERT, current); return trustchain; @@ -928,7 +996,7 @@ static auth_cfg_t *build_trustchain(private_credential_manager_t *this, { break; } - issuer = get_issuer_cert(this, current, FALSE); + issuer = get_issuer_cert(this, current, FALSE, NULL); if (!issuer) { if (!has_anchor) @@ -992,42 +1060,45 @@ METHOD(credential_manager_t, get_private, private_key_t*, } } - /* if a specific certificate is preferred, check for a matching key */ - cert = auth->get(auth, AUTH_RULE_SUBJECT_CERT); - if (cert) + if (auth) { - private = get_private_by_cert(this, cert, type); - if (private) + /* if a specific certificate is preferred, check for a matching key */ + cert = auth->get(auth, AUTH_RULE_SUBJECT_CERT); + if (cert) { - trustchain = build_trustchain(this, cert, auth); - if (trustchain) + private = get_private_by_cert(this, cert, type); + if (private) { - auth->merge(auth, trustchain, FALSE); - trustchain->destroy(trustchain); + trustchain = build_trustchain(this, cert, auth); + if (trustchain) + { + auth->merge(auth, trustchain, FALSE); + trustchain->destroy(trustchain); + } + return private; } - return private; } - } - /* try to build a trust chain for each certificate found */ - enumerator = create_cert_enumerator(this, CERT_ANY, type, id, FALSE); - while (enumerator->enumerate(enumerator, &cert)) - { - private = get_private_by_cert(this, cert, type); - if (private) + /* try to build a trust chain for each certificate found */ + enumerator = create_cert_enumerator(this, CERT_ANY, type, id, FALSE); + while (enumerator->enumerate(enumerator, &cert)) { - trustchain = build_trustchain(this, cert, auth); - if (trustchain) + private = get_private_by_cert(this, cert, type); + if (private) { - auth->merge(auth, trustchain, FALSE); - trustchain->destroy(trustchain); - break; + trustchain = build_trustchain(this, cert, auth); + if (trustchain) + { + auth->merge(auth, trustchain, FALSE); + trustchain->destroy(trustchain); + break; + } + private->destroy(private); + private = NULL; } - private->destroy(private); - private = NULL; } + enumerator->destroy(enumerator); } - enumerator->destroy(enumerator); /* if no valid trustchain was found, fall back to the first usable cert */ if (!private) @@ -1038,7 +1109,10 @@ METHOD(credential_manager_t, get_private, private_key_t*, private = get_private_by_cert(this, cert, type); if (private) { - auth->add(auth, AUTH_RULE_SUBJECT_CERT, cert->get_ref(cert)); + if (auth) + { + auth->add(auth, AUTH_RULE_SUBJECT_CERT, cert->get_ref(cert)); + } break; } } @@ -1050,14 +1124,10 @@ METHOD(credential_manager_t, get_private, private_key_t*, METHOD(credential_manager_t, flush_cache, void, private_credential_manager_t *this, certificate_type_t type) { - this->cache->flush(this->cache, type); -} - -METHOD(credential_manager_t, issued_by, bool, - private_credential_manager_t *this, certificate_t *subject, - certificate_t *issuer) -{ - return this->cache->issued_by(this->cache, subject, issuer); + if (this->cache) + { + this->cache->flush(this->cache, type); + } } METHOD(credential_manager_t, add_set, void, @@ -1097,10 +1167,14 @@ METHOD(credential_manager_t, destroy, void, { cache_queue(this); this->cache_queue->destroy(this->cache_queue); - this->sets->remove(this->sets, this->cache, NULL); + if (this->cache) + { + this->sets->remove(this->sets, this->cache, NULL); + this->cache->destroy(this->cache); + } this->sets->destroy(this->sets); this->local_sets->destroy(this->local_sets); - this->cache->destroy(this->cache); + this->exclusive_local_sets->destroy(this->exclusive_local_sets); this->validators->destroy(this->validators); this->lock->destroy(this->lock); this->queue_mutex->destroy(this->queue_mutex); @@ -1137,14 +1211,18 @@ credential_manager_t *credential_manager_create() }, .sets = linked_list_create(), .validators = linked_list_create(), - .cache = cert_cache_create(), .cache_queue = linked_list_create(), .lock = rwlock_create(RWLOCK_TYPE_DEFAULT), .queue_mutex = mutex_create(MUTEX_TYPE_DEFAULT), ); this->local_sets = thread_value_create((thread_cleanup_t)this->sets->destroy); - this->sets->insert_first(this->sets, this->cache); + this->exclusive_local_sets = thread_value_create((thread_cleanup_t)this->sets->destroy); + if (lib->settings->get_bool(lib->settings, "libstrongswan.cert_cache", TRUE)) + { + this->cache = cert_cache_create(); + this->sets->insert_first(this->sets, this->cache); + } return &this->public; } diff --git a/src/libstrongswan/credentials/credential_manager.h b/src/libstrongswan/credentials/credential_manager.h index 8e8f04b8c..d9a47b7d7 100644 --- a/src/libstrongswan/credentials/credential_manager.h +++ b/src/libstrongswan/credentials/credential_manager.h @@ -89,7 +89,7 @@ struct credential_manager_t { * @param type kind of requested shared key * @param first first subject between key is shared * @param second second subject between key is shared - * @return enumerator over shared keys + * @return enumerator over (shared_key_t*,id_match_t,id_match_t) */ enumerator_t *(*create_shared_enumerator)(credential_manager_t *this, shared_key_type_t type, @@ -204,10 +204,12 @@ struct credential_manager_t { * * @param subject subject certificate to check * @param issuer issuer certificate that potentially has signed subject + * @param scheme receives used signature scheme, if given * @return TRUE if issuer signed subject */ bool (*issued_by)(credential_manager_t *this, - certificate_t *subject, certificate_t *issuer); + certificate_t *subject, certificate_t *issuer, + signature_scheme_t *scheme); /** * Register a credential set to the manager. @@ -230,10 +232,14 @@ struct credential_manager_t { * operation, sets may be added for the calling thread only. This * does not require a write lock and is therefore a much cheaper * operation. + * The exclusive option allows to disable all other credential sets + * until the set is deregistered. * * @param set set to register + * @param exclusive TRUE to disable all other sets for this thread */ - void (*add_local_set)(credential_manager_t *this, credential_set_t *set); + void (*add_local_set)(credential_manager_t *this, credential_set_t *set, + bool exclusive); /** * Unregister a thread local credential set from the manager. diff --git a/src/libstrongswan/credentials/sets/cert_cache.c b/src/libstrongswan/credentials/sets/cert_cache.c index 968c3e31e..a7d0ed8f9 100644 --- a/src/libstrongswan/credentials/sets/cert_cache.c +++ b/src/libstrongswan/credentials/sets/cert_cache.c @@ -47,6 +47,11 @@ struct relation_t { certificate_t *issuer; /** + * Signature scheme used to sign this relation + */ + signature_scheme_t scheme; + + /** * Cache hits */ u_int hits; @@ -77,7 +82,8 @@ struct private_cert_cache_t { * Cache relation in a free slot/replace an other */ static void cache(private_cert_cache_t *this, - certificate_t *subject, certificate_t *issuer) + certificate_t *subject, certificate_t *issuer, + signature_scheme_t scheme) { relation_t *rel; int i, offset, try; @@ -95,6 +101,7 @@ static void cache(private_cert_cache_t *this, { rel->subject = subject->get_ref(subject); rel->issuer = issuer->get_ref(issuer); + rel->scheme = scheme; return rel->lock->unlock(rel->lock); } rel->lock->unlock(rel->lock); @@ -123,6 +130,7 @@ static void cache(private_cert_cache_t *this, } rel->subject = subject->get_ref(subject); rel->issuer = issuer->get_ref(issuer); + rel->scheme = scheme; rel->hits = 0; return rel->lock->unlock(rel->lock); } @@ -133,9 +141,11 @@ static void cache(private_cert_cache_t *this, } METHOD(cert_cache_t, issued_by, bool, - private_cert_cache_t *this, certificate_t *subject, certificate_t *issuer) + private_cert_cache_t *this, certificate_t *subject, certificate_t *issuer, + signature_scheme_t *schemep) { relation_t *found = NULL, *current; + signature_scheme_t scheme; int i; for (i = 0; i < CACHE_SIZE; i++) @@ -154,7 +164,11 @@ METHOD(cert_cache_t, issued_by, bool, { /* write hit counter is not locked, but not critical */ current->hits++; - found = current; + found = current;; + if (schemep) + { + *schemep = current->scheme; + } } } } @@ -165,9 +179,13 @@ METHOD(cert_cache_t, issued_by, bool, } } /* no cache hit, check and cache signature */ - if (subject->issued_by(subject, issuer)) + if (subject->issued_by(subject, issuer, &scheme)) { - cache(this, subject, issuer); + cache(this, subject, issuer, scheme); + if (schemep) + { + *schemep = scheme; + } return TRUE; } return FALSE; diff --git a/src/libstrongswan/credentials/sets/cert_cache.h b/src/libstrongswan/credentials/sets/cert_cache.h index d2721866e..2bcdbe464 100644 --- a/src/libstrongswan/credentials/sets/cert_cache.h +++ b/src/libstrongswan/credentials/sets/cert_cache.h @@ -45,10 +45,12 @@ struct cert_cache_t { * * @param subject certificate to verify * @param issuer issuing certificate to verify subject + * @param scheme receives used signature scheme, if given * @return TRUE if subject issued by issuer */ bool (*issued_by)(cert_cache_t *this, - certificate_t *subject, certificate_t *issuer); + certificate_t *subject, certificate_t *issuer, + signature_scheme_t *scheme); /** * Flush the certificate cache. diff --git a/src/libstrongswan/crypto/aead.c b/src/libstrongswan/crypto/aead.c index 51cb05909..02fb8d50a 100644 --- a/src/libstrongswan/crypto/aead.c +++ b/src/libstrongswan/crypto/aead.c @@ -40,26 +40,41 @@ struct private_aead_t { signer_t *signer; }; -METHOD(aead_t, encrypt, void, +METHOD(aead_t, encrypt, bool, private_aead_t *this, chunk_t plain, chunk_t assoc, chunk_t iv, chunk_t *encrypted) { chunk_t encr, sig; - this->signer->get_signature(this->signer, assoc, NULL); - this->signer->get_signature(this->signer, iv, NULL); + if (!this->signer->get_signature(this->signer, assoc, NULL) || + !this->signer->get_signature(this->signer, iv, NULL)) + { + return FALSE; + } if (encrypted) { - this->crypter->encrypt(this->crypter, plain, iv, &encr); - this->signer->allocate_signature(this->signer, encr, &sig); + if (!this->crypter->encrypt(this->crypter, plain, iv, &encr)) + { + return FALSE; + } + if (!this->signer->allocate_signature(this->signer, encr, &sig)) + { + free(encr.ptr); + return FALSE; + } *encrypted = chunk_cat("cmm", iv, encr, sig); } else { - this->crypter->encrypt(this->crypter, plain, iv, NULL); - this->signer->get_signature(this->signer, plain, plain.ptr + plain.len); + if (!this->crypter->encrypt(this->crypter, plain, iv, NULL) || + !this->signer->get_signature(this->signer, + plain, plain.ptr + plain.len)) + { + return FALSE; + } } + return TRUE; } METHOD(aead_t, decrypt, bool, @@ -80,15 +95,17 @@ METHOD(aead_t, decrypt, bool, chunk_split(encrypted, "mm", encrypted.len - sig.len, &encrypted, sig.len, &sig); - this->signer->get_signature(this->signer, assoc, NULL); - this->signer->get_signature(this->signer, iv, NULL); + if (!this->signer->get_signature(this->signer, assoc, NULL) || + !this->signer->get_signature(this->signer, iv, NULL)) + { + return FALSE; + } if (!this->signer->verify_signature(this->signer, encrypted, sig)) { DBG1(DBG_LIB, "MAC verification failed"); return FALSE; } - this->crypter->decrypt(this->crypter, encrypted, iv, plain); - return TRUE; + return this->crypter->decrypt(this->crypter, encrypted, iv, plain); } METHOD(aead_t, get_block_size, size_t, @@ -116,7 +133,7 @@ METHOD(aead_t, get_key_size, size_t, this->signer->get_key_size(this->signer); } -METHOD(aead_t, set_key, void, +METHOD(aead_t, set_key, bool, private_aead_t *this, chunk_t key) { chunk_t sig, enc; @@ -124,8 +141,8 @@ METHOD(aead_t, set_key, void, chunk_split(key, "mm", this->signer->get_key_size(this->signer), &sig, this->crypter->get_key_size(this->crypter), &enc); - this->signer->set_key(this->signer, sig); - this->crypter->set_key(this->crypter, enc); + return this->signer->set_key(this->signer, sig) && + this->crypter->set_key(this->crypter, enc); } METHOD(aead_t, destroy, void, diff --git a/src/libstrongswan/crypto/aead.h b/src/libstrongswan/crypto/aead.h index 3f6abb4f9..ec526a3d9 100644 --- a/src/libstrongswan/crypto/aead.h +++ b/src/libstrongswan/crypto/aead.h @@ -45,9 +45,10 @@ struct aead_t { * @param assoc associated data to sign * @param iv initialization vector * @param encrypted allocated encryption result + * @return TRUE if successfully encrypted */ - void (*encrypt)(aead_t *this, chunk_t plain, chunk_t assoc, chunk_t iv, - chunk_t *encrypted); + bool (*encrypt)(aead_t *this, chunk_t plain, chunk_t assoc, chunk_t iv, + chunk_t *encrypted) __attribute__((warn_unused_result)); /** * Decrypt and verify data, verify associated data. @@ -98,8 +99,10 @@ struct aead_t { * Set the key for encryption and authentication. * * @param key encryption and authentication key + * @return TRUE if key set successfully */ - void (*set_key)(aead_t *this, chunk_t key); + bool (*set_key)(aead_t *this, + chunk_t key) __attribute__((warn_unused_result)); /** * Destroy a aead_t. diff --git a/src/libstrongswan/crypto/crypters/crypter.h b/src/libstrongswan/crypto/crypters/crypter.h index 3bf039681..fe854f53d 100644 --- a/src/libstrongswan/crypto/crypters/crypter.h +++ b/src/libstrongswan/crypto/crypters/crypter.h @@ -90,9 +90,10 @@ struct crypter_t { * @param data data to encrypt * @param iv initializing vector * @param encrypted chunk to allocate encrypted data, or NULL + * @return TRUE if encryption successful */ - void (*encrypt) (crypter_t *this, chunk_t data, chunk_t iv, - chunk_t *encrypted); + bool (*encrypt)(crypter_t *this, chunk_t data, chunk_t iv, + chunk_t *encrypted) __attribute__((warn_unused_result)); /** * Decrypt a chunk of data and allocate space for the decrypted value. @@ -104,9 +105,10 @@ struct crypter_t { * @param data data to decrypt * @param iv initializing vector * @param encrypted chunk to allocate decrypted data, or NULL + * @return TRUE if decryption successful */ - void (*decrypt) (crypter_t *this, chunk_t data, chunk_t iv, - chunk_t *decrypted); + bool (*decrypt)(crypter_t *this, chunk_t data, chunk_t iv, + chunk_t *decrypted) __attribute__((warn_unused_result)); /** * Get the block size of the crypto algorithm. @@ -117,7 +119,7 @@ struct crypter_t { * * @return block size in bytes */ - size_t (*get_block_size) (crypter_t *this); + size_t (*get_block_size)(crypter_t *this); /** * Get the IV size of the crypto algorithm. @@ -135,7 +137,7 @@ struct crypter_t { * * @return key size in bytes */ - size_t (*get_key_size) (crypter_t *this); + size_t (*get_key_size)(crypter_t *this); /** * Set the key. @@ -143,13 +145,15 @@ struct crypter_t { * The length of the key must match get_key_size(). * * @param key key to set + * @return TRUE if key set successfully */ - void (*set_key) (crypter_t *this, chunk_t key); + bool (*set_key)(crypter_t *this, + chunk_t key) __attribute__((warn_unused_result)); /** * Destroys a crypter_t object. */ - void (*destroy) (crypter_t *this); + void (*destroy)(crypter_t *this); }; /** diff --git a/src/libstrongswan/crypto/crypto_factory.c b/src/libstrongswan/crypto/crypto_factory.c index 2d13896d6..3736ae38f 100644 --- a/src/libstrongswan/crypto/crypto_factory.c +++ b/src/libstrongswan/crypto/crypto_factory.c @@ -50,6 +50,7 @@ struct entry_t { hasher_constructor_t create_hasher; prf_constructor_t create_prf; rng_constructor_t create_rng; + nonce_gen_constructor_t create_nonce_gen; dh_constructor_t create_dh; void *create; }; @@ -98,6 +99,11 @@ struct private_crypto_factory_t { linked_list_t *rngs; /** + * registered nonce generators, as entry_t + */ + linked_list_t *nonce_gens; + + /** * registered diffie hellman, as entry_t */ linked_list_t *dhs; @@ -329,34 +335,49 @@ METHOD(crypto_factory_t, create_rng, rng_t*, return NULL; } +METHOD(crypto_factory_t, create_nonce_gen, nonce_gen_t*, + private_crypto_factory_t *this) +{ + enumerator_t *enumerator; + entry_t *entry; + nonce_gen_t *nonce_gen = NULL; + + this->lock->read_lock(this->lock); + enumerator = this->nonce_gens->create_enumerator(this->nonce_gens); + while (enumerator->enumerate(enumerator, &entry)) + { + nonce_gen = entry->create_nonce_gen(); + } + enumerator->destroy(enumerator); + this->lock->unlock(this->lock); + + return nonce_gen; +} + METHOD(crypto_factory_t, create_dh, diffie_hellman_t*, private_crypto_factory_t *this, diffie_hellman_group_t group, ...) { enumerator_t *enumerator; entry_t *entry; + va_list args; + chunk_t g = chunk_empty, p = chunk_empty; diffie_hellman_t *diffie_hellman = NULL; + if (group == MODP_CUSTOM) + { + va_start(args, group); + g = va_arg(args, chunk_t); + p = va_arg(args, chunk_t); + va_end(args); + } + this->lock->read_lock(this->lock); enumerator = this->dhs->create_enumerator(this->dhs); while (enumerator->enumerate(enumerator, &entry)) { if (entry->algo == group) { - if (group == MODP_CUSTOM) - { - va_list args; - chunk_t g, p; - - va_start(args, group); - g = va_arg(args, chunk_t); - p = va_arg(args, chunk_t); - va_end(args); - diffie_hellman = entry->create_dh(MODP_CUSTOM, g, p); - } - else - { - diffie_hellman = entry->create_dh(group); - } + diffie_hellman = entry->create_dh(group, g, p); if (diffie_hellman) { break; @@ -618,6 +639,33 @@ METHOD(crypto_factory_t, remove_rng, void, this->lock->unlock(this->lock); } +METHOD(crypto_factory_t, add_nonce_gen, void, + private_crypto_factory_t *this, const char *plugin_name, + nonce_gen_constructor_t create) +{ + add_entry(this, this->nonce_gens, 0, plugin_name, 0, create); +} + +METHOD(crypto_factory_t, remove_nonce_gen, void, + private_crypto_factory_t *this, nonce_gen_constructor_t create) +{ + entry_t *entry; + enumerator_t *enumerator; + + this->lock->write_lock(this->lock); + enumerator = this->nonce_gens->create_enumerator(this->nonce_gens); + while (enumerator->enumerate(enumerator, &entry)) + { + if (entry->create_nonce_gen == create) + { + this->nonce_gens->remove_at(this->nonce_gens, enumerator); + free(entry); + } + } + enumerator->destroy(enumerator); + this->lock->unlock(this->lock); +} + METHOD(crypto_factory_t, add_dh, void, private_crypto_factory_t *this, diffie_hellman_group_t group, const char *plugin_name, dh_constructor_t create) @@ -756,7 +804,7 @@ METHOD(crypto_factory_t, create_prf_enumerator, enumerator_t*, } /** - * Filter function to enumerate algorithm, not entry + * Filter function to enumerate group, not entry */ static bool dh_filter(void *n, entry_t **entry, diffie_hellman_group_t *group, void *i2, const char **plugin_name) @@ -773,7 +821,7 @@ METHOD(crypto_factory_t, create_dh_enumerator, enumerator_t*, } /** - * Filter function to enumerate algorithm, not entry + * Filter function to enumerate strength, not entry */ static bool rng_filter(void *n, entry_t **entry, rng_quality_t *quality, void *i2, const char **plugin_name) @@ -788,6 +836,22 @@ METHOD(crypto_factory_t, create_rng_enumerator, enumerator_t*, { return create_enumerator(this, this->rngs, rng_filter); } + +/** + * Filter function to enumerate plugin name, not entry + */ +static bool nonce_gen_filter(void *n, entry_t **entry, const char **plugin_name) +{ + *plugin_name = (*entry)->plugin_name; + return TRUE; +} + +METHOD(crypto_factory_t, create_nonce_gen_enumerator, enumerator_t*, + private_crypto_factory_t *this) +{ + return create_enumerator(this, this->nonce_gens, nonce_gen_filter); +} + METHOD(crypto_factory_t, add_test_vector, void, private_crypto_factory_t *this, transform_type_t type, void *vector) { @@ -820,6 +884,7 @@ METHOD(crypto_factory_t, destroy, void, this->hashers->destroy(this->hashers); this->prfs->destroy(this->prfs); this->rngs->destroy(this->rngs); + this->nonce_gens->destroy(this->nonce_gens); this->dhs->destroy(this->dhs); this->tester->destroy(this->tester); this->lock->destroy(this->lock); @@ -841,6 +906,7 @@ crypto_factory_t *crypto_factory_create() .create_hasher = _create_hasher, .create_prf = _create_prf, .create_rng = _create_rng, + .create_nonce_gen = _create_nonce_gen, .create_dh = _create_dh, .add_crypter = _add_crypter, .remove_crypter = _remove_crypter, @@ -854,6 +920,8 @@ crypto_factory_t *crypto_factory_create() .remove_prf = _remove_prf, .add_rng = _add_rng, .remove_rng = _remove_rng, + .add_nonce_gen = _add_nonce_gen, + .remove_nonce_gen = _remove_nonce_gen, .add_dh = _add_dh, .remove_dh = _remove_dh, .create_crypter_enumerator = _create_crypter_enumerator, @@ -863,6 +931,7 @@ crypto_factory_t *crypto_factory_create() .create_prf_enumerator = _create_prf_enumerator, .create_dh_enumerator = _create_dh_enumerator, .create_rng_enumerator = _create_rng_enumerator, + .create_nonce_gen_enumerator = _create_nonce_gen_enumerator, .add_test_vector = _add_test_vector, .destroy = _destroy, }, @@ -872,6 +941,7 @@ crypto_factory_t *crypto_factory_create() .hashers = linked_list_create(), .prfs = linked_list_create(), .rngs = linked_list_create(), + .nonce_gens = linked_list_create(), .dhs = linked_list_create(), .lock = rwlock_create(RWLOCK_TYPE_DEFAULT), .tester = crypto_tester_create(), diff --git a/src/libstrongswan/crypto/crypto_factory.h b/src/libstrongswan/crypto/crypto_factory.h index 8e5db6355..611ca0bbb 100644 --- a/src/libstrongswan/crypto/crypto_factory.h +++ b/src/libstrongswan/crypto/crypto_factory.h @@ -30,6 +30,7 @@ typedef struct crypto_factory_t crypto_factory_t; #include <crypto/hashers/hasher.h> #include <crypto/prfs/prf.h> #include <crypto/rngs/rng.h> +#include <crypto/nonce_gen.h> #include <crypto/diffie_hellman.h> #include <crypto/transform.h> @@ -66,6 +67,11 @@ typedef prf_t* (*prf_constructor_t)(pseudo_random_function_t algo); typedef rng_t* (*rng_constructor_t)(rng_quality_t quality); /** + * Constructor function for nonce generators + */ +typedef nonce_gen_t* (*nonce_gen_constructor_t)(); + +/** * Constructor function for diffie hellman * * The DH constructor accepts additional arguments for: @@ -132,6 +138,13 @@ struct crypto_factory_t { rng_t* (*create_rng)(crypto_factory_t *this, rng_quality_t quality); /** + * Create a nonce generator instance. + * + * @return nonce_gen_t instance, NULL if not supported + */ + nonce_gen_t* (*create_nonce_gen)(crypto_factory_t *this); + + /** * Create a diffie hellman instance. * * Additional arguments are passed to the DH constructor. @@ -253,6 +266,23 @@ struct crypto_factory_t { void (*remove_rng)(crypto_factory_t *this, rng_constructor_t create); /** + * Register a nonce generator. + * + * @param plugin_name plugin that registered this algorithm + * @param create constructor function for that nonce generator + */ + void (*add_nonce_gen)(crypto_factory_t *this, const char *plugin_name, + nonce_gen_constructor_t create); + + /** + * Unregister a nonce generator. + * + * @param create constructor function to unregister + */ + void (*remove_nonce_gen)(crypto_factory_t *this, + nonce_gen_constructor_t create); + + /** * Register a diffie hellman constructor. * * @param group dh group to constructor @@ -273,53 +303,60 @@ struct crypto_factory_t { /** * Create an enumerator over all registered crypter algorithms. * - * @return enumerator over encryption_algorithm_t + * @return enumerator over encryption_algorithm_t, plugin */ enumerator_t* (*create_crypter_enumerator)(crypto_factory_t *this); /** * Create an enumerator over all registered aead algorithms. * - * @return enumerator over encryption_algorithm_t + * @return enumerator over encryption_algorithm_t, plugin */ enumerator_t* (*create_aead_enumerator)(crypto_factory_t *this); /** * Create an enumerator over all registered signer algorithms. * - * @return enumerator over integrity_algorithm_t + * @return enumerator over integrity_algorithm_t, plugin */ enumerator_t* (*create_signer_enumerator)(crypto_factory_t *this); /** * Create an enumerator over all registered hasher algorithms. * - * @return enumerator over hash_algorithm_t + * @return enumerator over hash_algorithm_t, plugin */ enumerator_t* (*create_hasher_enumerator)(crypto_factory_t *this); /** * Create an enumerator over all registered PRFs. * - * @return enumerator over pseudo_random_function_t + * @return enumerator over pseudo_random_function_t, plugin */ enumerator_t* (*create_prf_enumerator)(crypto_factory_t *this); /** * Create an enumerator over all registered diffie hellman groups. * - * @return enumerator over diffie_hellman_group_t + * @return enumerator over diffie_hellman_group_t, plugin */ enumerator_t* (*create_dh_enumerator)(crypto_factory_t *this); /** * Create an enumerator over all registered random generators. * - * @return enumerator over rng_quality_t + * @return enumerator over rng_quality_t, plugin */ enumerator_t* (*create_rng_enumerator)(crypto_factory_t *this); /** + * Create an enumerator over all registered nonce generators. + * + * @return enumerator over plugin + */ + enumerator_t* (*create_nonce_gen_enumerator)(crypto_factory_t *this); + + /** * Add a test vector to the crypto factory. * * @param type type of the test vector diff --git a/src/libstrongswan/crypto/crypto_tester.c b/src/libstrongswan/crypto/crypto_tester.c index 8b1daa885..01e84a133 100644 --- a/src/libstrongswan/crypto/crypto_tester.c +++ b/src/libstrongswan/crypto/crypto_tester.c @@ -151,7 +151,10 @@ static u_int bench_crypter(private_crypto_tester_t *this, memset(iv, 0x56, sizeof(iv)); memset(key, 0x12, sizeof(key)); - crypter->set_key(crypter, chunk_from_thing(key)); + if (!crypter->set_key(crypter, chunk_from_thing(key))) + { + return 0; + } buf = chunk_alloc(this->bench_size); memset(buf.ptr, 0x34, buf.len); @@ -160,10 +163,14 @@ static u_int bench_crypter(private_crypto_tester_t *this, start_timing(&start); while (end_timing(&start) < this->bench_time) { - crypter->encrypt(crypter, buf, chunk_from_thing(iv), NULL); - runs++; - crypter->decrypt(crypter, buf, chunk_from_thing(iv), NULL); - runs++; + if (crypter->encrypt(crypter, buf, chunk_from_thing(iv), NULL)) + { + runs++; + } + if (crypter->decrypt(crypter, buf, chunk_from_thing(iv), NULL)) + { + runs++; + } } free(buf.ptr); crypter->destroy(crypter); @@ -186,7 +193,7 @@ METHOD(crypto_tester_t, test_crypter, bool, while (enumerator->enumerate(enumerator, &vector)) { crypter_t *crypter; - chunk_t key, plain, cipher, iv; + chunk_t key, iv, plain = chunk_empty, cipher = chunk_empty; if (vector->alg != alg) { @@ -196,53 +203,69 @@ METHOD(crypto_tester_t, test_crypter, bool, { /* test only vectors with a specific key size, if key size given */ 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); - failed = TRUE; continue; } - failed = FALSE; - tested++; - key = chunk_create(vector->key, crypter->get_key_size(crypter)); - crypter->set_key(crypter, key); + if (!crypter->set_key(crypter, key)) + { + goto failure; + } iv = chunk_create(vector->iv, crypter->get_iv_size(crypter)); /* allocated encryption */ plain = chunk_create(vector->plain, vector->len); - crypter->encrypt(crypter, plain, iv, &cipher); + if (!crypter->encrypt(crypter, plain, iv, &cipher)) + { + goto failure; + } if (!memeq(vector->cipher, cipher.ptr, cipher.len)) { - failed = TRUE; + goto failure; } /* inline decryption */ - crypter->decrypt(crypter, cipher, iv, NULL); + if (!crypter->decrypt(crypter, cipher, iv, NULL)) + { + goto failure; + } if (!memeq(vector->plain, cipher.ptr, cipher.len)) { - failed = TRUE; + goto failure; } - free(cipher.ptr); /* allocated decryption */ - cipher = chunk_create(vector->cipher, vector->len); - crypter->decrypt(crypter, cipher, iv, &plain); + if (!crypter->decrypt(crypter, + chunk_create(vector->cipher, vector->len), iv, &plain)) + { + goto failure; + } if (!memeq(vector->plain, plain.ptr, plain.len)) { - failed = TRUE; + goto failure; } /* inline encryption */ - crypter->encrypt(crypter, plain, iv, NULL); + if (!crypter->encrypt(crypter, plain, iv, NULL)) + { + goto failure; + } if (!memeq(vector->cipher, plain.ptr, plain.len)) { - failed = TRUE; + goto failure; } - free(plain.ptr); + failed = FALSE; +failure: crypter->destroy(crypter); + chunk_free(&cipher); + chunk_free(&plain); if (failed) { DBG1(DBG_LIB, "disabled %N[%s]: %s test vector failed", @@ -306,7 +329,10 @@ static u_int bench_aead(private_crypto_tester_t *this, memset(iv, 0x56, sizeof(iv)); memset(key, 0x12, sizeof(key)); memset(assoc, 0x78, sizeof(assoc)); - aead->set_key(aead, chunk_from_thing(key)); + if (!aead->set_key(aead, chunk_from_thing(key))) + { + return 0; + } icv = aead->get_icv_size(aead); buf = chunk_alloc(this->bench_size + icv); @@ -317,12 +343,16 @@ static u_int bench_aead(private_crypto_tester_t *this, start_timing(&start); while (end_timing(&start) < this->bench_time) { - aead->encrypt(aead, buf, chunk_from_thing(assoc), - chunk_from_thing(iv), NULL); - runs += 2; - aead->decrypt(aead, chunk_create(buf.ptr, buf.len + icv), - chunk_from_thing(assoc), chunk_from_thing(iv), NULL); - runs += 2; + if (aead->encrypt(aead, buf, chunk_from_thing(assoc), + chunk_from_thing(iv), NULL)) + { + runs += 2; + } + if (aead->decrypt(aead, chunk_create(buf.ptr, buf.len + icv), + chunk_from_thing(assoc), chunk_from_thing(iv), NULL)) + { + runs += 2; + } } free(buf.ptr); aead->destroy(aead); @@ -345,7 +375,7 @@ METHOD(crypto_tester_t, test_aead, bool, while (enumerator->enumerate(enumerator, &vector)) { aead_t *aead; - chunk_t key, plain, cipher, iv, assoc; + chunk_t key, iv, assoc, plain = chunk_empty, cipher = chunk_empty; size_t icv; if (vector->alg != alg) @@ -356,63 +386,72 @@ METHOD(crypto_tester_t, test_aead, bool, { /* test only vectors with a specific key size, if key size given */ continue; } + + tested++; + failed = TRUE; aead = create(alg, vector->key_size); if (!aead) { DBG1(DBG_LIB, "%N[%s]: %u bit key size not supported", encryption_algorithm_names, alg, plugin_name, BITS_PER_BYTE * vector->key_size); - failed = TRUE; continue; } - failed = FALSE; - tested++; - key = chunk_create(vector->key, aead->get_key_size(aead)); - aead->set_key(aead, key); + if (!aead->set_key(aead, key)) + { + goto failure; + } iv = chunk_create(vector->iv, aead->get_iv_size(aead)); assoc = chunk_create(vector->adata, vector->alen); icv = aead->get_icv_size(aead); /* allocated encryption */ plain = chunk_create(vector->plain, vector->len); - aead->encrypt(aead, plain, assoc, iv, &cipher); + if (!aead->encrypt(aead, plain, assoc, iv, &cipher)) + { + goto failure; + } if (!memeq(vector->cipher, cipher.ptr, cipher.len)) { - failed = TRUE; + goto failure; } /* inline decryption */ if (!aead->decrypt(aead, cipher, assoc, iv, NULL)) { - failed = TRUE; + goto failure; } if (!memeq(vector->plain, cipher.ptr, cipher.len - icv)) { - failed = TRUE; + goto failure; } - free(cipher.ptr); /* allocated decryption */ - cipher = chunk_create(vector->cipher, vector->len + icv); - if (!aead->decrypt(aead, cipher, assoc, iv, &plain)) + if (!aead->decrypt(aead, chunk_create(vector->cipher, vector->len + icv), + assoc, iv, &plain)) { - plain = chunk_empty; - failed = TRUE; + goto failure; } - else if (!memeq(vector->plain, plain.ptr, plain.len)) + if (!memeq(vector->plain, plain.ptr, plain.len)) { - failed = TRUE; + goto failure; } plain.ptr = realloc(plain.ptr, plain.len + icv); /* inline encryption */ - aead->encrypt(aead, plain, assoc, iv, NULL); + if (!aead->encrypt(aead, plain, assoc, iv, NULL)) + { + goto failure; + } if (!memeq(vector->cipher, plain.ptr, plain.len + icv)) { - failed = TRUE; + goto failure; } - free(plain.ptr); + failed = FALSE; +failure: aead->destroy(aead); + chunk_free(&cipher); + chunk_free(&plain); if (failed) { DBG1(DBG_LIB, "disabled %N[%s]: %s test vector failed", @@ -458,7 +497,7 @@ METHOD(crypto_tester_t, test_aead, bool, * Benchmark a signer */ static u_int bench_signer(private_crypto_tester_t *this, - encryption_algorithm_t alg, signer_constructor_t create) + integrity_algorithm_t alg, signer_constructor_t create) { signer_t *signer; @@ -472,7 +511,10 @@ static u_int bench_signer(private_crypto_tester_t *this, u_int runs; memset(key, 0x12, sizeof(key)); - signer->set_key(signer, chunk_from_thing(key)); + if (!signer->set_key(signer, chunk_from_thing(key))) + { + return 0; + } buf = chunk_alloc(this->bench_size); memset(buf.ptr, 0x34, buf.len); @@ -481,10 +523,14 @@ static u_int bench_signer(private_crypto_tester_t *this, start_timing(&start); while (end_timing(&start) < this->bench_time) { - signer->get_signature(signer, buf, mac); - runs++; - signer->verify_signature(signer, buf, chunk_from_thing(mac)); - runs++; + if (signer->get_signature(signer, buf, mac)) + { + runs++; + } + if (signer->verify_signature(signer, buf, chunk_from_thing(mac))) + { + runs++; + } } free(buf.ptr); signer->destroy(signer); @@ -507,7 +553,7 @@ METHOD(crypto_tester_t, test_signer, bool, while (enumerator->enumerate(enumerator, &vector)) { signer_t *signer; - chunk_t key, data, mac; + chunk_t key, data, mac = chunk_empty; if (vector->alg != alg) { @@ -515,63 +561,79 @@ METHOD(crypto_tester_t, test_signer, bool, } tested++; + failed = TRUE; signer = create(alg); if (!signer) { DBG1(DBG_LIB, "disabled %N[%s]: creating instance failed", integrity_algorithm_names, alg, plugin_name); - failed = TRUE; break; } - failed = FALSE; - key = chunk_create(vector->key, signer->get_key_size(signer)); - signer->set_key(signer, key); - + if (!signer->set_key(signer, key)) + { + goto failure; + } /* allocated signature */ data = chunk_create(vector->data, vector->len); - signer->allocate_signature(signer, data, &mac); + if (!signer->allocate_signature(signer, data, &mac)) + { + goto failure; + } if (mac.len != signer->get_block_size(signer)) { - failed = TRUE; + goto failure; } if (!memeq(vector->mac, mac.ptr, mac.len)) { - failed = TRUE; + goto failure; } /* signature to existing buffer */ memset(mac.ptr, 0, mac.len); - signer->get_signature(signer, data, mac.ptr); + if (!signer->get_signature(signer, data, mac.ptr)) + { + goto failure; + } if (!memeq(vector->mac, mac.ptr, mac.len)) { - failed = TRUE; + goto failure; } /* signature verification, good case */ if (!signer->verify_signature(signer, data, mac)) { - failed = TRUE; + goto failure; } /* signature verification, bad case */ *(mac.ptr + mac.len - 1) += 1; if (signer->verify_signature(signer, data, mac)) { - failed = TRUE; + goto failure; } /* signature to existing buffer, using append mode */ if (data.len > 2) { - signer->allocate_signature(signer, chunk_create(data.ptr, 1), NULL); - signer->get_signature(signer, chunk_create(data.ptr + 1, 1), NULL); + if (!signer->allocate_signature(signer, + chunk_create(data.ptr, 1), NULL)) + { + goto failure; + } + if (!signer->get_signature(signer, + chunk_create(data.ptr + 1, 1), NULL)) + { + goto failure; + } if (!signer->verify_signature(signer, chunk_skip(data, 2), chunk_create(vector->mac, mac.len))) { - failed = TRUE; + goto failure; } } - free(mac.ptr); + failed = FALSE; +failure: signer->destroy(signer); + chunk_free(&mac); if (failed) { DBG1(DBG_LIB, "disabled %N[%s]: %s test vector failed", @@ -627,8 +689,10 @@ static u_int bench_hasher(private_crypto_tester_t *this, start_timing(&start); while (end_timing(&start) < this->bench_time) { - hasher->get_hash(hasher, buf, hash); - runs++; + if (hasher->get_hash(hasher, buf, hash)) + { + runs++; + } } free(buf.ptr); hasher->destroy(hasher); @@ -659,50 +723,73 @@ METHOD(crypto_tester_t, test_hasher, bool, } tested++; + failed = TRUE; hasher = create(alg); if (!hasher) { DBG1(DBG_LIB, "disabled %N[%s]: creating instance failed", hash_algorithm_names, alg, plugin_name); - failed = TRUE; break; } - failed = FALSE; - /* allocated hash */ data = chunk_create(vector->data, vector->len); - hasher->allocate_hash(hasher, data, &hash); + if (!hasher->allocate_hash(hasher, data, &hash)) + { + goto failure; + } if (hash.len != hasher->get_hash_size(hasher)) { - failed = TRUE; + goto failure; } if (!memeq(vector->hash, hash.ptr, hash.len)) { - failed = TRUE; + goto failure; } - /* hash to existing buffer */ + /* hash to existing buffer, with a reset */ memset(hash.ptr, 0, hash.len); - hasher->get_hash(hasher, data, hash.ptr); + if (!hasher->get_hash(hasher, data, NULL)) + { + goto failure; + } + if (!hasher->reset(hasher)) + { + goto failure; + } + if (!hasher->get_hash(hasher, data, hash.ptr)) + { + goto failure; + } if (!memeq(vector->hash, hash.ptr, hash.len)) { - failed = TRUE; + goto failure; } /* hasher to existing buffer, using append mode */ if (data.len > 2) { memset(hash.ptr, 0, hash.len); - hasher->allocate_hash(hasher, chunk_create(data.ptr, 1), NULL); - hasher->get_hash(hasher, chunk_create(data.ptr + 1, 1), NULL); - hasher->get_hash(hasher, chunk_skip(data, 2), hash.ptr); + if (!hasher->allocate_hash(hasher, chunk_create(data.ptr, 1), NULL)) + { + goto failure; + } + if (!hasher->get_hash(hasher, chunk_create(data.ptr + 1, 1), NULL)) + { + goto failure; + } + if (!hasher->get_hash(hasher, chunk_skip(data, 2), hash.ptr)) + { + goto failure; + } if (!memeq(vector->hash, hash.ptr, hash.len)) { - failed = TRUE; + goto failure; } } - free(hash.ptr); + failed = FALSE; +failure: hasher->destroy(hasher); + chunk_free(&hash); if (failed) { DBG1(DBG_LIB, "disabled %N[%s]: %s test vector failed", @@ -746,11 +833,18 @@ static u_int bench_prf(private_crypto_tester_t *this, prf = create(alg); if (prf) { - char bytes[prf->get_block_size(prf)]; + char bytes[prf->get_block_size(prf)], key[prf->get_block_size(prf)]; chunk_t buf; struct timespec start; u_int runs; + memset(key, 0x56, prf->get_block_size(prf)); + if (!prf->set_key(prf, chunk_create(key, prf->get_block_size(prf)))) + { + prf->destroy(prf); + return 0; + } + buf = chunk_alloc(this->bench_size); memset(buf.ptr, 0x34, buf.len); @@ -758,8 +852,10 @@ static u_int bench_prf(private_crypto_tester_t *this, start_timing(&start); while (end_timing(&start) < this->bench_time) { - prf->get_bytes(prf, buf, bytes); - runs++; + if (prf->get_bytes(prf, buf, bytes)) + { + runs++; + } } free(buf.ptr); prf->destroy(prf); @@ -782,7 +878,7 @@ METHOD(crypto_tester_t, test_prf, bool, while (enumerator->enumerate(enumerator, &vector)) { prf_t *prf; - chunk_t key, seed, out; + chunk_t key, seed, out = chunk_empty; if (vector->alg != alg) { @@ -790,41 +886,50 @@ METHOD(crypto_tester_t, test_prf, bool, } tested++; + failed = TRUE; prf = create(alg); if (!prf) { DBG1(DBG_LIB, "disabled %N[%s]: creating instance failed", pseudo_random_function_names, alg, plugin_name); - failed = TRUE; break; } - failed = FALSE; - key = chunk_create(vector->key, vector->key_size); - prf->set_key(prf, key); - + if (!prf->set_key(prf, key)) + { + goto failure; + } /* allocated bytes */ seed = chunk_create(vector->seed, vector->len); - prf->allocate_bytes(prf, seed, &out); + if (!prf->allocate_bytes(prf, seed, &out)) + { + goto failure; + } if (out.len != prf->get_block_size(prf)) { - failed = TRUE; + goto failure; } if (!memeq(vector->out, out.ptr, out.len)) { - failed = TRUE; + goto failure; } /* bytes to existing buffer */ memset(out.ptr, 0, out.len); if (vector->stateful) { - prf->set_key(prf, key); + if (!prf->set_key(prf, key)) + { + goto failure; + } + } + if (!prf->get_bytes(prf, seed, out.ptr)) + { + goto failure; } - prf->get_bytes(prf, seed, out.ptr); if (!memeq(vector->out, out.ptr, out.len)) { - failed = TRUE; + goto failure; } /* bytes to existing buffer, using append mode */ if (seed.len > 2) @@ -832,19 +937,33 @@ METHOD(crypto_tester_t, test_prf, bool, memset(out.ptr, 0, out.len); if (vector->stateful) { - prf->set_key(prf, key); + if (!prf->set_key(prf, key)) + { + goto failure; + } + } + if (!prf->allocate_bytes(prf, chunk_create(seed.ptr, 1), NULL)) + { + goto failure; + } + if (!prf->get_bytes(prf, chunk_create(seed.ptr + 1, 1), NULL)) + { + goto failure; + } + if (!prf->get_bytes(prf, chunk_skip(seed, 2), out.ptr)) + { + goto failure; } - prf->allocate_bytes(prf, chunk_create(seed.ptr, 1), NULL); - prf->get_bytes(prf, chunk_create(seed.ptr + 1, 1), NULL); - prf->get_bytes(prf, chunk_skip(seed, 2), out.ptr); if (!memeq(vector->out, out.ptr, out.len)) { - failed = TRUE; + goto failure; } } - free(out.ptr); + failed = FALSE; +failure: prf->destroy(prf); + chunk_free(&out); if (failed) { DBG1(DBG_LIB, "disabled %N[%s]: %s test vector failed", @@ -897,7 +1016,11 @@ static u_int bench_rng(private_crypto_tester_t *this, start_timing(&start); while (end_timing(&start) < this->bench_time) { - rng->get_bytes(rng, buf.len, buf.ptr); + if (!rng->get_bytes(rng, buf.len, buf.ptr)) + { + runs = 0; + break; + } runs++; } free(buf.ptr); @@ -927,8 +1050,8 @@ METHOD(crypto_tester_t, test_rng, bool, enumerator = this->rng->create_enumerator(this->rng); while (enumerator->enumerate(enumerator, &vector)) { + chunk_t data = chunk_empty; rng_t *rng; - chunk_t data; if (vector->quality != quality) { @@ -936,37 +1059,37 @@ METHOD(crypto_tester_t, test_rng, bool, } tested++; + failed = TRUE; rng = create(quality); if (!rng) { DBG1(DBG_LIB, "disabled %N[%s]: creating instance failed", rng_quality_names, quality, plugin_name); - failed = TRUE; break; } - failed = FALSE; - /* allocated bytes */ - rng->allocate_bytes(rng, vector->len, &data); - if (data.len != vector->len) + if (!rng->allocate_bytes(rng, vector->len, &data) || + data.len != vector->len || + !vector->test(vector->user, data)) { - failed = TRUE; + goto failure; } - if (!vector->test(vector->user, data)) + /* write bytes into existing buffer */ + memset(data.ptr, 0, data.len); + if (!rng->get_bytes(rng, vector->len, data.ptr)) { - failed = TRUE; + goto failure; } - /* bytes to existing buffer */ - memset(data.ptr, 0, data.len); - rng->get_bytes(rng, vector->len, data.ptr); if (!vector->test(vector->user, data)) { - failed = TRUE; + goto failure; } - free(data.ptr); + failed = FALSE; +failure: rng->destroy(rng); + chunk_free(&data); if (failed) { DBG1(DBG_LIB, "disabled %N[%s]: %s test vector failed", diff --git a/src/libstrongswan/crypto/hashers/hasher.c b/src/libstrongswan/crypto/hashers/hasher.c index 81750a519..dc73d5223 100644 --- a/src/libstrongswan/crypto/hashers/hasher.c +++ b/src/libstrongswan/crypto/hashers/hasher.c @@ -1,7 +1,7 @@ /* - * Copyright (C) 2005 Jan Hutter + * Copyright (C) 2012 Tobias Brunner * Copyright (C) 2005-2006 Martin Willi - * + * Copyright (C) 2005 Jan Hutter * Hochschule fuer Technik Rapperswil * * This program is free software; you can redistribute it and/or modify it @@ -32,6 +32,19 @@ ENUM(hash_algorithm_names, HASH_UNKNOWN, HASH_SHA512, "HASH_SHA512" ); +ENUM(hash_algorithm_short_names, HASH_UNKNOWN, HASH_SHA512, + "unknown", + "preferred", + "md2", + "md4", + "md5", + "sha1", + "sha224", + "sha256", + "sha384", + "sha512" +); + /* * Described in header. */ @@ -68,6 +81,105 @@ hash_algorithm_t hasher_algorithm_from_oid(int oid) /* * Described in header. */ +hash_algorithm_t hasher_algorithm_from_prf(pseudo_random_function_t alg) +{ + switch (alg) + { + case PRF_HMAC_MD5: + return HASH_MD5; + case PRF_HMAC_SHA1: + case PRF_FIPS_SHA1_160: + case PRF_KEYED_SHA1: + return HASH_SHA1; + case PRF_HMAC_SHA2_256: + return HASH_SHA256; + case PRF_HMAC_SHA2_384: + return HASH_SHA384; + case PRF_HMAC_SHA2_512: + return HASH_SHA512; + case PRF_HMAC_TIGER: + case PRF_AES128_XCBC: + case PRF_AES128_CMAC: + case PRF_FIPS_DES: + case PRF_CAMELLIA128_XCBC: + case PRF_UNDEFINED: + break; + } + return HASH_UNKNOWN; +} + +/* + * Described in header. + */ +hash_algorithm_t hasher_algorithm_from_integrity(integrity_algorithm_t alg, + size_t *length) +{ + if (length) + { + switch (alg) + { + case AUTH_HMAC_MD5_96: + case AUTH_HMAC_SHA1_96: + case AUTH_HMAC_SHA2_256_96: + *length = 12; + break; + case AUTH_HMAC_MD5_128: + case AUTH_HMAC_SHA1_128: + case AUTH_HMAC_SHA2_256_128: + *length = 16; + break; + case AUTH_HMAC_SHA1_160: + *length = 20; + break; + case AUTH_HMAC_SHA2_384_192: + *length = 24; + break; + case AUTH_HMAC_SHA2_256_256: + case AUTH_HMAC_SHA2_512_256: + *length = 32; + break; + case AUTH_HMAC_SHA2_384_384: + *length = 48; + break; + default: + break; + } + } + switch (alg) + { + case AUTH_HMAC_MD5_96: + case AUTH_HMAC_MD5_128: + case AUTH_KPDK_MD5: + return HASH_MD5; + case AUTH_HMAC_SHA1_96: + case AUTH_HMAC_SHA1_128: + case AUTH_HMAC_SHA1_160: + return HASH_SHA1; + case AUTH_HMAC_SHA2_256_96: + case AUTH_HMAC_SHA2_256_128: + case AUTH_HMAC_SHA2_256_256: + return HASH_SHA256; + case AUTH_HMAC_SHA2_384_192: + case AUTH_HMAC_SHA2_384_384: + return HASH_SHA384; + case AUTH_HMAC_SHA2_512_256: + return HASH_SHA512; + case AUTH_AES_CMAC_96: + case AUTH_AES_128_GMAC: + case AUTH_AES_192_GMAC: + case AUTH_AES_256_GMAC: + case AUTH_AES_XCBC_96: + case AUTH_DES_MAC: + case AUTH_CAMELLIA_XCBC_96: + case AUTH_UNDEFINED: + break; + } + return HASH_UNKNOWN; +} + +/* + * Described in header. + */ int hasher_algorithm_to_oid(hash_algorithm_t alg) { int oid; diff --git a/src/libstrongswan/crypto/hashers/hasher.h b/src/libstrongswan/crypto/hashers/hasher.h index 9fa043c7e..759f6a23c 100644 --- a/src/libstrongswan/crypto/hashers/hasher.h +++ b/src/libstrongswan/crypto/hashers/hasher.h @@ -1,7 +1,7 @@ /* - * Copyright (C) 2005 Jan Hutter + * Copyright (C) 2012 Tobias Brunner * Copyright (C) 2005-2006 Martin Willi - * + * Copyright (C) 2005 Jan Hutter * Hochschule fuer Technik Rapperswil * * This program is free software; you can redistribute it and/or modify it @@ -27,6 +27,8 @@ typedef enum hash_algorithm_t hash_algorithm_t; typedef struct hasher_t hasher_t; #include <library.h> +#include <crypto/prfs/prf.h> +#include <crypto/signers/signer.h> #include <credentials/keys/public_key.h> /** @@ -62,9 +64,15 @@ enum hash_algorithm_t { extern enum_name_t *hash_algorithm_names; /** + * Short names for hash_algorithm_names + */ +extern enum_name_t *hash_algorithm_short_names; + +/** * Generic interface for all hash functions. */ struct hasher_t { + /** * Hash data and write it in the buffer. * @@ -77,8 +85,10 @@ struct hasher_t { * * @param data data to hash * @param hash pointer where the hash will be written + * @return TRUE if hash created successfully */ - void (*get_hash) (hasher_t *this, chunk_t data, u_int8_t *hash); + bool (*get_hash)(hasher_t *this, chunk_t data, + u_int8_t *hash) __attribute__((warn_unused_result)); /** * Hash data and allocate space for the hash. @@ -89,36 +99,61 @@ struct hasher_t { * * @param data chunk with data to hash * @param hash chunk which will hold allocated hash + * @return TRUE if hash allocated successfully */ - void (*allocate_hash) (hasher_t *this, chunk_t data, chunk_t *hash); + bool (*allocate_hash)(hasher_t *this, chunk_t data, + chunk_t *hash) __attribute__((warn_unused_result)); /** * Get the size of the resulting hash. * * @return hash size in bytes */ - size_t (*get_hash_size) (hasher_t *this); + size_t (*get_hash_size)(hasher_t *this); /** - * Resets the hashers state. + * Resets the hasher's state. + * + * @return TRUE if hasher reset successfully */ - void (*reset) (hasher_t *this); + bool (*reset)(hasher_t *this) __attribute__((warn_unused_result)); /** * Destroys a hasher object. */ - void (*destroy) (hasher_t *this); + void (*destroy)(hasher_t *this); }; /** * Conversion of ASN.1 OID to hash algorithm. * * @param oid ASN.1 OID - * @return hash algorithm, HASH_UNKNOWN if OID unsuported + * @return hash algorithm, HASH_UNKNOWN if OID unsupported */ hash_algorithm_t hasher_algorithm_from_oid(int oid); /** + * Conversion of PRF algorithm to hash algorithm (if based on one). + * + * @param alg prf algorithm + * @return hash algorithm, HASH_UNKNOWN if not based on a hash + */ +hash_algorithm_t hasher_algorithm_from_prf(pseudo_random_function_t alg); + +/** + * Conversion of integrity algorithm to hash algorithm (if based on one). + * + * If length is not NULL the length of the resulting signature is returned, + * which might be smaller than the output size of the underlying hash. + * + * @param alg integrity algorithm + * @param length returns signature length, if not NULL + * @return hash algorithm, HASH_UNKNOWN if not based on a hash + */ +hash_algorithm_t hasher_algorithm_from_integrity(integrity_algorithm_t alg, + size_t *length); + +/** * Conversion of hash algorithm into ASN.1 OID. * * @param alg hash algorithm diff --git a/src/libstrongswan/crypto/mac.h b/src/libstrongswan/crypto/mac.h new file mode 100644 index 000000000..f7b43ba39 --- /dev/null +++ b/src/libstrongswan/crypto/mac.h @@ -0,0 +1,76 @@ +/* + * Copyright (C) 2012 Tobias Brunner + * 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 mac mac + * @{ @ingroup crypto + */ + +#ifndef MAC_H_ +#define MAC_H_ + +typedef struct mac_t mac_t; + +#include <library.h> + +/** + * Generic interface for message authentication codes. + * + * Classes implementing this interface can use the PRF and signer wrappers. + */ +struct mac_t { + + /** + * Generate message authentication code. + * + * If out is NULL, no result is given back. A next call will + * append the data to already supplied data. If out is not NULL, + * the mac of all apended data is calculated, written to out and the + * internal state is reset. + * + * @param data chunk of data to authenticate + * @param out pointer where the generated bytes will be written + * @return TRUE if mac generated successfully + */ + bool (*get_mac)(mac_t *this, chunk_t data, + u_int8_t *out) __attribute__((warn_unused_result)); + + /** + * Get the size of the resulting MAC. + * + * @return block size in bytes + */ + size_t (*get_mac_size)(mac_t *this); + + /** + * Set the key to be used for the MAC. + * + * Any key length must be accepted. + * + * @param key key to set + * @return TRUE if key set successfully + */ + bool (*set_key)(mac_t *this, + chunk_t key) __attribute__((warn_unused_result)); + + /** + * Destroys a mac_t object. + */ + void (*destroy) (mac_t *this); +}; + +#endif /** MAC_H_ @}*/ diff --git a/src/libstrongswan/crypto/nonce_gen.h b/src/libstrongswan/crypto/nonce_gen.h new file mode 100644 index 000000000..50f3c0090 --- /dev/null +++ b/src/libstrongswan/crypto/nonce_gen.h @@ -0,0 +1,59 @@ +/* + * Copyright (C) 2012 Adrian-Ken Rueegsegger + * Hochschule fuer Technik Rapperswil + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT 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 nonce_gen nonce_gen + * @{ @ingroup crypto + */ + +#ifndef NONCE_GEN_H_ +#define NONCE_GEN_H_ + +typedef struct nonce_gen_t nonce_gen_t; + +#include <library.h> + +/** + * Generic interface for nonce generators. + */ +struct nonce_gen_t { + + /** + * Generates a nonce and writes it into the buffer. + * + * @param size size of nonce in bytes + * @param buffer pointer where the generated nonce will be written + * @return TRUE if nonce allocation was succesful, FALSE otherwise + */ + bool (*get_nonce)(nonce_gen_t *this, size_t size, + u_int8_t *buffer) __attribute__((warn_unused_result)); + + /** + * Generates a nonce and allocates space for it. + * + * @param size size of nonce in bytes + * @param chunk chunk which will hold the generated nonce + * @return TRUE if nonce allocation was succesful, FALSE otherwise + */ + bool (*allocate_nonce)(nonce_gen_t *this, size_t size, + chunk_t *chunk) __attribute__((warn_unused_result)); + + /** + * Destroys a nonce generator object. + */ + void (*destroy)(nonce_gen_t *this); +}; + +#endif /** NONCE_GEN_H_ @}*/ diff --git a/src/libstrongswan/crypto/pkcs7.c b/src/libstrongswan/crypto/pkcs7.c new file mode 100644 index 000000000..0ec19f2cd --- /dev/null +++ b/src/libstrongswan/crypto/pkcs7.c @@ -0,0 +1,1061 @@ +/* + * Copyright (C) 2012 Tobias Brunner + * Copyright (C) 2002-2008 Andreas Steffen + * Copyright (C) 2005 Jan Hutter, Martin Willi + * 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. + */ + +#include <stdlib.h> +#include <string.h> +#include <time.h> + +#include <library.h> +#include <debug.h> + +#include <asn1/oid.h> +#include <asn1/asn1.h> +#include <asn1/asn1_parser.h> +#include <credentials/certificates/x509.h> +#include <credentials/keys/public_key.h> +#include <crypto/pkcs9.h> +#include <crypto/hashers/hasher.h> +#include <crypto/crypters/crypter.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; + + /** + * 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; +}; + +METHOD(pkcs7_t, is_data, bool, + private_pkcs7_t *this) +{ + return this->type == OID_PKCS7_DATA; +} + +METHOD(pkcs7_t, is_signedData, bool, + private_pkcs7_t *this) +{ + return this->type == OID_PKCS7_SIGNED_DATA; +} + +METHOD(pkcs7_t, is_envelopedData, bool, + private_pkcs7_t *this) +{ + return this->type == OID_PKCS7_ENVELOPED_DATA; +} + +/** + * 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 */ + { 0, "exit", ASN1_EOC, ASN1_EXIT } +}; +#define PKCS7_INFO_TYPE 1 +#define PKCS7_INFO_CONTENT 2 + +/** + * Parse PKCS#7 contentInfo object + */ +static bool parse_contentInfo(private_pkcs7_t *this) +{ + asn1_parser_t *parser; + chunk_t object; + int objectID; + bool success = FALSE; + + if (!this->data.ptr) + { + return FALSE; + } + + parser = asn1_parser_create(contentInfoObjects, this->data); + parser->set_top_level(parser, this->level); + + while (parser->iterate(parser, &objectID, &object)) + { + if (objectID == PKCS7_INFO_TYPE) + { + this->type = asn1_known_oid(object); + if (this->type < OID_PKCS7_DATA || + this->type > OID_PKCS7_ENCRYPTED_DATA) + { + DBG1(DBG_LIB, "unknown pkcs7 content type"); + goto end; + } + } + else if (objectID == PKCS7_INFO_CONTENT && object.len > 0) + { + chunk_free(&this->content); + this->content = chunk_clone(object); + } + } + success = parser->success(parser); + + if (success) + { + this->level += 2; + chunk_free(&this->data); + } + +end: + parser->destroy(parser); + return success; +} + +/** + * Check whether to abort the requested parsing + */ +static bool abort_parsing(private_pkcs7_t *this, int type) +{ + if (this->type != type) + { + DBG1(DBG_LIB, "pkcs7 content to be parsed is not of type '%s'", + oid_names[type].name); + return TRUE; + } + return FALSE; +} + +METHOD(pkcs7_t, parse_data, bool, + private_pkcs7_t *this) +{ + chunk_t data; + + if (!parse_contentInfo(this) || + abort_parsing(this, OID_PKCS7_DATA)) + { + return FALSE; + } + data = this->content; + if (data.len == 0) + { + this->data = chunk_empty; + return TRUE; + } + if (asn1_parse_simple_object(&data, ASN1_OCTET_STRING, + this->level, "data")) + { + this->data = chunk_clone(data); + return TRUE; + } + return FALSE; +} + +/** + * 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 */ + { 0, "exit", ASN1_EOC, ASN1_EXIT } +}; +#define PKCS7_SIGNED_VERSION 1 +#define PKCS7_DIGEST_ALG 3 +#define PKCS7_SIGNED_CONTENT_INFO 5 +#define PKCS7_SIGNED_CERT 7 +#define PKCS7_SIGNER_INFO 13 +#define PKCS7_SIGNER_INFO_VERSION 14 +#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 + +METHOD(pkcs7_t, parse_signedData, bool, + private_pkcs7_t *this, certificate_t *cacert) +{ + asn1_parser_t *parser; + chunk_t object; + int objectID, version; + int digest_alg = OID_UNKNOWN; + int enc_alg = OID_UNKNOWN; + int signerInfos = 0; + bool success = FALSE; + + chunk_t encrypted_digest = chunk_empty; + + if (!parse_contentInfo(this) || + abort_parsing(this, OID_PKCS7_SIGNED_DATA)) + { + return FALSE; + } + + parser = asn1_parser_create(signedDataObjects, this->content); + parser->set_top_level(parser, this->level); + + while (parser->iterate(parser, &objectID, &object)) + { + u_int level = parser->get_level(parser); + + switch (objectID) + { + case PKCS7_SIGNED_VERSION: + version = object.len ? (int)*object.ptr : 0; + DBG2(DBG_LIB, " v%d", version); + break; + case PKCS7_DIGEST_ALG: + digest_alg = asn1_parse_algorithmIdentifier(object, level, NULL); + break; + case PKCS7_SIGNED_CONTENT_INFO: + { + pkcs7_t *data = pkcs7_create_from_chunk(object, level+1); + + if (!data || !data->parse_data(data)) + { + DESTROY_IF(data); + goto end; + } + this->data = chunk_clone(data->get_data(data)); + data->destroy(data); + break; + } + case PKCS7_SIGNED_CERT: + { + certificate_t *cert; + + DBG2(DBG_LIB, " parsing pkcs7-wrapped certificate"); + cert = lib->creds->create(lib->creds, + CRED_CERTIFICATE, CERT_X509, + BUILD_BLOB_ASN1_DER, object, + BUILD_END); + if (cert) + { + this->certs->insert_last(this->certs, cert); + } + break; + } + case PKCS7_SIGNER_INFO: + signerInfos++; + DBG2(DBG_LIB, " signer #%d", signerInfos); + break; + case PKCS7_SIGNER_INFO_VERSION: + version = object.len ? (int)*object.ptr : 0; + DBG2(DBG_LIB, " v%d", version); + break; + case PKCS7_SIGNED_ISSUER: + { + identification_t *issuer; + + issuer = identification_create_from_encoding(ID_DER_ASN1_DN, object); + DBG2(DBG_LIB, " '%Y'", 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 = asn1_parse_algorithmIdentifier(object, level, NULL); + break; + case PKCS7_DIGEST_ENC_ALGORITHM: + enc_alg = asn1_parse_algorithmIdentifier(object, level, NULL); + break; + case PKCS7_ENCRYPTED_DIGEST: + encrypted_digest = object; + } + } + success = parser->success(parser); + +end: + parser->destroy(parser); + if (!success) + { + return FALSE; + } + + /* check the signature only if a cacert is available */ + if (cacert != NULL) + { + signature_scheme_t scheme; + public_key_t *key; + + scheme = signature_scheme_from_oid(digest_alg); + if (scheme == SIGN_UNKNOWN) + { + DBG1(DBG_LIB, "unsupported signature scheme"); + return FALSE; + } + if (signerInfos == 0) + { + DBG1(DBG_LIB, "no signerInfo object found"); + return FALSE; + } + else if (signerInfos > 1) + { + DBG1(DBG_LIB, "more than one signerInfo object found"); + return FALSE; + } + if (this->attributes == NULL) + { + DBG1(DBG_LIB, "no authenticatedAttributes object found"); + return FALSE; + } + if (enc_alg != OID_RSA_ENCRYPTION) + { + DBG1(DBG_LIB, "only RSA digest encryption supported"); + return FALSE; + } + + /* verify the signature */ + key = cacert->get_public_key(cacert); + if (key == NULL) + { + DBG1(DBG_LIB, "no public key found in CA certificate"); + return FALSE; + } + if (key->verify(key, scheme, + this->attributes->get_encoding(this->attributes), encrypted_digest)) + { + DBG2(DBG_LIB, "signature is valid"); + } + else + { + DBG1(DBG_LIB, "invalid signature"); + key->destroy(key); + return FALSE; + } + key->destroy(key); + + if (this->data.ptr != NULL) + { + chunk_t messageDigest; + + messageDigest = this->attributes->get_attribute(this->attributes, + OID_PKCS9_MESSAGE_DIGEST); + if (messageDigest.ptr == NULL) + { + DBG1(DBG_LIB, "messageDigest attribute not found"); + return FALSE; + } + else + { + hash_algorithm_t algorithm; + hasher_t *hasher; + chunk_t hash; + bool valid; + + algorithm = hasher_algorithm_from_oid(digest_alg); + hasher = lib->crypto->create_hasher(lib->crypto, algorithm); + if (!hasher || !hasher->allocate_hash(hasher, this->data, &hash)) + { + DESTROY_IF(hasher); + DBG1(DBG_LIB, "hash algorithm %N not supported", + hash_algorithm_names, algorithm); + return FALSE; + } + hasher->destroy(hasher); + DBG3(DBG_LIB, "hash: %B", &hash); + + valid = chunk_equals(messageDigest, hash); + free(hash.ptr); + if (valid) + { + DBG2(DBG_LIB, "messageDigest is valid"); + } + else + { + DBG1(DBG_LIB, "invalid messageDigest"); + return FALSE; + } + } + } + } + return TRUE; +} + +/** + * 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 */ + { 0, "exit", ASN1_EOC, ASN1_EXIT } +}; +#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 + +METHOD(pkcs7_t, parse_envelopedData, bool, + private_pkcs7_t *this, chunk_t serialNumber, private_key_t *key) +{ + asn1_parser_t *parser; + chunk_t object; + int objectID, version; + bool success = FALSE; + + chunk_t iv = chunk_empty; + chunk_t symmetric_key = chunk_empty; + chunk_t encrypted_content = chunk_empty; + + crypter_t *crypter = NULL; + + if (!parse_contentInfo(this) || + abort_parsing(this, OID_PKCS7_ENVELOPED_DATA)) + { + return FALSE; + } + + parser = asn1_parser_create(envelopedDataObjects, this->content); + parser->set_top_level(parser, this->level); + + while (parser->iterate(parser, &objectID, &object)) + { + u_int level = parser->get_level(parser); + + switch (objectID) + { + case PKCS7_ENVELOPED_VERSION: + { + version = object.len ? (int)*object.ptr : 0; + DBG2(DBG_LIB, " v%d", version); + if (version != 0) + { + DBG1(DBG_LIB, "envelopedData version is not 0"); + goto end; + } + break; + } + case PKCS7_RECIPIENT_INFO_VERSION: + { + version = object.len ? (int)*object.ptr : 0; + DBG2(DBG_LIB, " v%d", version); + if (version != 0) + { + DBG1(DBG_LIB, "recipient info version is not 0"); + goto end; + } + break; + } + case PKCS7_ISSUER: + { + identification_t *issuer; + + issuer = identification_create_from_encoding(ID_DER_ASN1_DN, + object); + DBG2(DBG_LIB, " '%Y'", issuer); + issuer->destroy(issuer); + break; + } + case PKCS7_SERIAL_NUMBER: + { + if (!chunk_equals(serialNumber, object)) + { + DBG1(DBG_LIB, "serial numbers do not match"); + goto end; + } + break; + } + case PKCS7_ENCRYPTION_ALG: + { + int alg; + + alg = asn1_parse_algorithmIdentifier(object, level, NULL); + if (alg != OID_RSA_ENCRYPTION) + { + DBG1(DBG_LIB, "only rsa encryption supported"); + goto end; + } + break; + } + case PKCS7_ENCRYPTED_KEY: + { + if (!key->decrypt(key, ENCRYPT_RSA_PKCS1, object, &symmetric_key)) + { + DBG1(DBG_LIB, "symmetric key could not be decrypted with rsa"); + goto end; + } + DBG4(DBG_LIB, "symmetric key %B", &symmetric_key); + break; + } + case PKCS7_CONTENT_TYPE: + { + if (asn1_known_oid(object) != OID_PKCS7_DATA) + { + DBG1(DBG_LIB, "encrypted content not of type pkcs7 data"); + goto end; + } + break; + } + case PKCS7_CONTENT_ENC_ALGORITHM: + { + encryption_algorithm_t enc_alg; + size_t key_size; + int alg; + + alg = asn1_parse_algorithmIdentifier(object, level, &iv); + enc_alg = encryption_algorithm_from_oid(alg, &key_size); + if (enc_alg == ENCR_UNDEFINED) + { + DBG1(DBG_LIB, "unsupported content encryption algorithm"); + goto end; + } + crypter = lib->crypto->create_crypter(lib->crypto, enc_alg, + key_size); + if (crypter == NULL) + { + DBG1(DBG_LIB, "crypter %N not available", + encryption_algorithm_names, enc_alg); + goto end; + } + if (symmetric_key.len != crypter->get_key_size(crypter)) + { + DBG1(DBG_LIB, "symmetric key length %d is wrong", + symmetric_key.len); + goto end; + } + if (!asn1_parse_simple_object(&iv, ASN1_OCTET_STRING, + level + 1, "IV")) + { + DBG1(DBG_LIB, "IV could not be parsed"); + goto end; + } + if (iv.len != crypter->get_iv_size(crypter)) + { + DBG1(DBG_LIB, "IV length %d is wrong", iv.len); + goto end; + } + break; + } + case PKCS7_ENCRYPTED_CONTENT: + { + encrypted_content = object; + break; + } + } + } + success = parser->success(parser); + +end: + parser->destroy(parser); + if (!success) + { + goto failed; + } + success = FALSE; + + /* decrypt the content */ + if (!crypter->set_key(crypter, symmetric_key) || + !crypter->decrypt(crypter, encrypted_content, iv, &this->data)) + { + success = FALSE; + goto failed; + } + DBG4(DBG_LIB, "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(DBG_LIB, "padding greater than data length"); + goto failed; + } + this->data.len -= padding; + + while (padding-- > 0) + { + if (*pos-- != pattern) + { + DBG1(DBG_LIB, "wrong padding pattern"); + goto failed; + } + } + } + success = TRUE; + +failed: + DESTROY_IF(crypter); + chunk_clear(&symmetric_key); + if (!success) + { + chunk_free(&this->data); + } + return success; +} + +METHOD(pkcs7_t, get_data, chunk_t, + private_pkcs7_t *this) +{ + return this->data; +} + +METHOD(pkcs7_t, get_contentInfo, chunk_t, + private_pkcs7_t *this) +{ + chunk_t content_type; + + /* create DER-encoded OID for pkcs7_contentInfo type */ + switch(this->type) + { + case OID_PKCS7_DATA: + case OID_PKCS7_SIGNED_DATA: + case OID_PKCS7_ENVELOPED_DATA: + case OID_PKCS7_SIGNED_ENVELOPED_DATA: + case OID_PKCS7_DIGESTED_DATA: + case OID_PKCS7_ENCRYPTED_DATA: + content_type = asn1_build_known_oid(this->type); + break; + case OID_UNKNOWN: + default: + DBG1(DBG_LIB, "invalid pkcs7 contentInfo type"); + return chunk_empty; + } + + return this->content.ptr == NULL + ? asn1_wrap(ASN1_SEQUENCE, "m", content_type) + : asn1_wrap(ASN1_SEQUENCE, "mm", content_type, + asn1_simple_object(ASN1_CONTEXT_C_0, this->content)); +} + +METHOD(pkcs7_t, create_certificate_enumerator, enumerator_t*, + private_pkcs7_t *this) +{ + return this->certs->create_enumerator(this->certs); +} + +METHOD(pkcs7_t, set_certificate, void, + private_pkcs7_t *this, certificate_t *cert) +{ + if (cert) + { + this->certs->insert_last(this->certs, cert); + } +} + +METHOD(pkcs7_t, set_attributes, void, + private_pkcs7_t *this, pkcs9_t *attributes) +{ + this->attributes = attributes; +} + +METHOD(pkcs7_t, get_attributes, pkcs9_t*, + private_pkcs7_t *this) +{ + return this->attributes; +} + +/** + * build a DER-encoded issuerAndSerialNumber object + */ +chunk_t pkcs7_build_issuerAndSerialNumber(certificate_t *cert) +{ + identification_t *issuer = cert->get_issuer(cert); + chunk_t serial = chunk_empty; + + if (cert->get_type(cert) == CERT_X509) + { + x509_t *x509 = (x509_t*)cert; + serial = x509->get_serial(x509); + } + + return asn1_wrap(ASN1_SEQUENCE, "cm", + issuer->get_encoding(issuer), + asn1_integer("c", serial)); +} + +METHOD(pkcs7_t, build_envelopedData, bool, + private_pkcs7_t *this, certificate_t *cert, encryption_algorithm_t alg, + size_t key_size) +{ + chunk_t iv, symmetricKey, protectedKey, in, out; + crypter_t *crypter; + int alg_oid; + + /* select OID of symmetric encryption algorithm */ + alg_oid = encryption_algorithm_to_oid(alg, key_size); + if (alg_oid == OID_UNKNOWN) + { + DBG1(DBG_LIB, " encryption algorithm %N not supported", + encryption_algorithm_names, alg); + return FALSE; + } + crypter = lib->crypto->create_crypter(lib->crypto, alg, key_size / 8); + if (crypter == NULL) + { + DBG1(DBG_LIB, " 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 + */ + { + rng_t *rng; + + rng = lib->crypto->create_rng(lib->crypto, RNG_TRUE); + if (!rng || !rng->allocate_bytes(rng, crypter->get_key_size(crypter), + &symmetricKey)) + { + DBG1(DBG_LIB, " failed to allocate symmetric encryption key"); + DESTROY_IF(rng); + return FALSE; + } + DBG4(DBG_LIB, " symmetric encryption key: %B", &symmetricKey); + rng->destroy(rng); + + rng = lib->crypto->create_rng(lib->crypto, RNG_WEAK); + if (!rng || !rng->allocate_bytes(rng, crypter->get_iv_size(crypter), + &iv)) + { + DBG1(DBG_LIB, " failed to allocate initialization vector"); + DESTROY_IF(rng); + return FALSE; + } + DBG4(DBG_LIB, " initialization vector: %B", &iv); + rng->destroy(rng); + } + + /* 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(DBG_LIB, " 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(DBG_LIB, " padded unencrypted data: %B", &in); + + /* symmetric encryption of data object */ + if (!crypter->set_key(crypter, symmetricKey) || + !crypter->encrypt(crypter, in, iv, &out)) + { + crypter->destroy(crypter); + chunk_clear(&in); + chunk_clear(&symmetricKey); + chunk_free(&iv); + return FALSE; + } + crypter->destroy(crypter); + chunk_clear(&in); + DBG3(DBG_LIB, " encrypted data: %B", &out); + + /* protect symmetric key by public key encryption */ + { + public_key_t *key = cert->get_public_key(cert); + + if (key == NULL) + { + DBG1(DBG_LIB, " public key not found in encryption certificate"); + chunk_clear(&symmetricKey); + chunk_free(&iv); + chunk_free(&out); + return FALSE; + } + key->encrypt(key, ENCRYPT_RSA_PKCS1, symmetricKey, &protectedKey); + key->destroy(key); + chunk_clear(&symmetricKey); + } + + /* build pkcs7 enveloped data object */ + { + chunk_t contentEncryptionAlgorithm = asn1_wrap(ASN1_SEQUENCE, "mm", + asn1_build_known_oid(alg_oid), + asn1_wrap(ASN1_OCTET_STRING, "m", iv)); + + chunk_t encryptedContentInfo = asn1_wrap(ASN1_SEQUENCE, "mmm", + asn1_build_known_oid(OID_PKCS7_DATA), + contentEncryptionAlgorithm, + asn1_wrap(ASN1_CONTEXT_S_0, "m", out)); + + chunk_t encryptedKey = asn1_wrap(ASN1_OCTET_STRING, "m", protectedKey); + + chunk_t recipientInfo = asn1_wrap(ASN1_SEQUENCE, "cmmm", + 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); + chunk_free(&this->data); + this->type = OID_PKCS7_ENVELOPED_DATA; + this->data = get_contentInfo(this); + } + return TRUE; +} + +METHOD(pkcs7_t, build_signedData, bool, + private_pkcs7_t *this, private_key_t *private_key, hash_algorithm_t alg) +{ + chunk_t authenticatedAttributes = chunk_empty; + chunk_t encryptedDigest = chunk_empty; + chunk_t signerInfo, encoding = chunk_empty; + signature_scheme_t scheme; + int digest_oid; + certificate_t *cert; + + if (this->certs->get_first(this->certs, (void**)&cert) != SUCCESS) + { + DBG1(DBG_LIB, " no pkcs7 signer certificate found"); + return FALSE; + } + digest_oid = hasher_algorithm_to_oid(alg); + scheme = signature_scheme_from_oid(digest_oid); + + if (this->attributes != NULL) + { + if (this->data.ptr != NULL) + { + chunk_t messageDigest, signingTime, attributes; + hasher_t *hasher; + time_t now; + + hasher = lib->crypto->create_hasher(lib->crypto, alg); + if (!hasher || + !hasher->allocate_hash(hasher, this->data, &messageDigest)) + { + DESTROY_IF(hasher); + DBG1(DBG_LIB, " hash algorithm %N not support", + hash_algorithm_names, alg); + return FALSE; + } + hasher->destroy(hasher); + this->attributes->set_attribute(this->attributes, + OID_PKCS9_MESSAGE_DIGEST, + messageDigest); + free(messageDigest.ptr); + + /* take the current time as signingTime */ + now = time(NULL); + signingTime = asn1_from_time(&now, ASN1_UTCTIME); + this->attributes->set_attribute_raw(this->attributes, + OID_PKCS9_SIGNING_TIME, signingTime); + this->attributes->set_attribute_raw(this->attributes, + OID_PKCS9_CONTENT_TYPE, + asn1_build_known_oid(OID_PKCS7_DATA)); + + attributes = this->attributes->get_encoding(this->attributes); + + private_key->sign(private_key, scheme, attributes, &encryptedDigest); + authenticatedAttributes = chunk_clone(attributes); + *authenticatedAttributes.ptr = ASN1_CONTEXT_C_0; + } + } + else if (this->data.ptr != NULL) + { + private_key->sign(private_key, scheme, this->data, &encryptedDigest); + } + if (encryptedDigest.ptr) + { + encryptedDigest = asn1_wrap(ASN1_OCTET_STRING, "m", encryptedDigest); + } + signerInfo = asn1_wrap(ASN1_SEQUENCE, "cmmmmm", + ASN1_INTEGER_1, + pkcs7_build_issuerAndSerialNumber(cert), + asn1_algorithmIdentifier(digest_oid), + authenticatedAttributes, + asn1_algorithmIdentifier(OID_RSA_ENCRYPTION), + encryptedDigest); + + if (this->data.ptr != NULL) + { + chunk_free(&this->content); + 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); + + cert->get_encoding(cert, CERT_ASN1_DER, &encoding); + + this->content = asn1_wrap(ASN1_SEQUENCE, "cmcmm", + ASN1_INTEGER_1, + asn1_wrap(ASN1_SET, "m", asn1_algorithmIdentifier(digest_oid)), + this->data, + asn1_wrap(ASN1_CONTEXT_C_0, "m", encoding), + asn1_wrap(ASN1_SET, "m", signerInfo)); + chunk_free(&this->data); + this->type = OID_PKCS7_SIGNED_DATA; + this->data = get_contentInfo(this); + + return TRUE; +} + +METHOD(pkcs7_t, destroy, void, + private_pkcs7_t *this) +{ + DESTROY_IF(this->attributes); + this->certs->destroy_offset(this->certs, offsetof(certificate_t, destroy)); + free(this->content.ptr); + free(this->data.ptr); + free(this); +} + +/** + * Generic private constructor + */ +static private_pkcs7_t *pkcs7_create_empty(void) +{ + private_pkcs7_t *this; + + INIT(this, + .public = { + .is_data = _is_data, + .is_signedData = _is_signedData, + .is_envelopedData = _is_envelopedData, + .parse_data = _parse_data, + .parse_signedData = _parse_signedData, + .parse_envelopedData = _parse_envelopedData, + .get_data = _get_data, + .get_contentInfo = _get_contentInfo, + .create_certificate_enumerator = _create_certificate_enumerator, + .set_certificate = _set_certificate, + .set_attributes = _set_attributes, + .get_attributes = _get_attributes, + .build_envelopedData = _build_envelopedData, + .build_signedData = _build_signedData, + .destroy = _destroy, + }, + .type = OID_UNKNOWN, + .certs = linked_list_create(), + ); + + 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; + this->data = chunk_clone(chunk); + + 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); + + return &this->public; +} + diff --git a/src/libstrongswan/crypto/pkcs7.h b/src/libstrongswan/crypto/pkcs7.h new file mode 100644 index 000000000..7c9a6b037 --- /dev/null +++ b/src/libstrongswan/crypto/pkcs7.h @@ -0,0 +1,178 @@ +/* + * 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. + */ + +/** + * @defgroup pkcs7 pkcs7 + * @{ @ingroup crypto + */ + +#ifndef PKCS7_H_ +#define PKCS7_H_ + +typedef struct pkcs7_t pkcs7_t; + +#include <library.h> +#include <credentials/keys/private_key.h> +#include <crypto/pkcs9.h> +#include <crypto/crypters/crypter.h> +#include <utils/enumerator.h> + +/** + * PKCS#7 contentInfo object. + */ +struct pkcs7_t { + + /** + * Check if the PKCS#7 contentType is data + * + * @return TRUE if the contentType is data + */ + bool (*is_data) (pkcs7_t *this); + + /** + * Check if the PKCS#7 contentType is signedData + * + * @return TRUE if the contentType is signedData + */ + bool (*is_signedData) (pkcs7_t *this); + + /** + * Check if the PKCS#7 contentType is envelopedData + * + * @return TRUE if the contentType is envelopedData + */ + bool (*is_envelopedData) (pkcs7_t *this); + + /** + * Parse a PKCS#7 data content. + * + * @return TRUE if parsing was successful + */ + bool (*parse_data) (pkcs7_t *this); + + /** + * Parse a PKCS#7 signedData content. The contained PKCS#7 data is parsed + * and verified. + * + * @param cacert cacert used to verify the signature + * @return TRUE if parsing was successful + */ + bool (*parse_signedData) (pkcs7_t *this, certificate_t *cacert); + + /** + * Parse a PKCS#7 envelopedData content. + * + * @param serialNumber serialNumber of the request + * @param key private key used to decrypt the symmetric key + * @return TRUE if parsing was successful + */ + bool (*parse_envelopedData) (pkcs7_t *this, chunk_t serialNumber, + private_key_t *key); + + /** + * Returns the parsed data object + * + * @return chunk containing the data object + */ + chunk_t (*get_data) (pkcs7_t *this); + + /** + * Returns the a DER-encoded contentInfo object + * + * @return chunk containing the contentInfo object + */ + chunk_t (*get_contentInfo) (pkcs7_t *this); + + /** + * Create an enumerator for the certificates. + * + * @return enumerator for the certificates + */ + enumerator_t *(*create_certificate_enumerator) (pkcs7_t *this); + + /** + * Add a certificate. + * + * @param cert certificate to be included (gets adopted) + */ + void (*set_certificate) (pkcs7_t *this, certificate_t *cert); + + /** + * Add authenticated attributes. + * + * @param attributes attributes to be included (gets adopted) + */ + void (*set_attributes) (pkcs7_t *this, pkcs9_t *attributes); + + /** + * Get attributes. + * + * @return attributes (internal data) + */ + pkcs9_t *(*get_attributes) (pkcs7_t *this); + + /** + * Build a data object + * + * @return TRUE if build was successful + */ + bool (*build_data) (pkcs7_t *this); + + /** + * Build an envelopedData object + * + * @param cert receivers's certificate + * @param alg encryption algorithm + * @param key_size key size to use + * @return TRUE if build was successful + */ + bool (*build_envelopedData) (pkcs7_t *this, certificate_t *cert, + encryption_algorithm_t alg, size_t key_size); + + /** + * Build an signedData object + * + * @param key signer's private key + * @param alg digest algorithm used for signature + * @return TRUE if build was successful + */ + bool (*build_signedData) (pkcs7_t *this, private_key_t *key, + hash_algorithm_t alg); + + /** + * Destroys the contentInfo object. + */ + void (*destroy) (pkcs7_t *this); +}; + +/** + * 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. + */ +pkcs7_t *pkcs7_create_from_chunk(chunk_t chunk, u_int level); + +/** + * Create a PKCS#7 contentInfo object + * + * @param data chunk containing data + * @return created pkcs7_contentInfo object. + */ +pkcs7_t *pkcs7_create_from_data(chunk_t data); + +#endif /** PKCS7_H_ @}*/ diff --git a/src/libstrongswan/crypto/pkcs9.c b/src/libstrongswan/crypto/pkcs9.c index 63a615238..d24ab1b80 100644 --- a/src/libstrongswan/crypto/pkcs9.c +++ b/src/libstrongswan/crypto/pkcs9.c @@ -1,5 +1,6 @@ /* - * Copyright (C)2008 Andreas Steffen + * Copyright (C) 2012 Tobias Brunner + * Copyright (C) 2008 Andreas Steffen * Hochschule fuer Technik Rapperswil, Switzerland * * This program is free software; you can redistribute it and/or modify it @@ -74,58 +75,6 @@ struct attribute_t { }; /** - * PKCS#9 attribute type OIDs - */ -static chunk_t ASN1_contentType_oid = chunk_from_chars( - 0x06, 0x09, - 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x09, 0x03 -); -static chunk_t ASN1_messageDigest_oid = chunk_from_chars( - 0x06, 0x09, - 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x09, 0x04 -); -static chunk_t ASN1_signingTime_oid = chunk_from_chars( - 0x06, 0x09, - 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x09, 0x05 -); -static chunk_t ASN1_messageType_oid = chunk_from_chars( - 0x06, 0x0A, - 0x60, 0x86, 0x48, 0x01, 0x86, 0xF8, 0x45, 0x01, 0x09, 0x02 -); -static chunk_t ASN1_senderNonce_oid = chunk_from_chars( - 0x06, 0x0A, - 0x60, 0x86, 0x48, 0x01, 0x86, 0xF8, 0x45, 0x01, 0x09, 0x05 -); -static chunk_t ASN1_transId_oid = chunk_from_chars( - 0x06, 0x0A, - 0x60, 0x86, 0x48, 0x01, 0x86, 0xF8, 0x45, 0x01, 0x09, 0x07 -); - -/** - * return the ASN.1 encoded OID of a PKCS#9 attribute - */ -static chunk_t asn1_attributeIdentifier(int oid) -{ - switch (oid) - { - case OID_PKCS9_CONTENT_TYPE: - return ASN1_contentType_oid; - case OID_PKCS9_MESSAGE_DIGEST: - return ASN1_messageDigest_oid; - case OID_PKCS9_SIGNING_TIME: - return ASN1_signingTime_oid; - case OID_PKI_MESSAGE_TYPE: - return ASN1_messageType_oid; - case OID_PKI_SENDER_NONCE: - return ASN1_senderNonce_oid; - case OID_PKI_TRANS_ID: - return ASN1_transId_oid;; - default: - return chunk_empty; - } -} - -/** * return the ASN.1 encoding of a PKCS#9 attribute */ static asn1_t asn1_attributeType(int oid) @@ -188,8 +137,8 @@ static attribute_t *attribute_create(int oid, chunk_t value) .destroy = attribute_destroy, .oid = oid, .value = chunk_clone(value), - .encoding = asn1_wrap(ASN1_SEQUENCE, "cm", - asn1_attributeIdentifier(oid), + .encoding = asn1_wrap(ASN1_SEQUENCE, "mm", + asn1_build_known_oid(oid), asn1_simple_object(ASN1_SET, value)), ); @@ -263,43 +212,30 @@ METHOD(pkcs9_t, get_attribute, chunk_t, } } enumerator->destroy(enumerator); + if (value.ptr && + !asn1_parse_simple_object(&value, asn1_attributeType(oid), 0, + oid_names[oid].name)) + { + return chunk_empty; + } return value; } -METHOD(pkcs9_t, set_attribute, void, +METHOD(pkcs9_t, set_attribute_raw, void, private_pkcs9_t *this, int oid, chunk_t value) { attribute_t *attribute = attribute_create(oid, value); - this->attributes->insert_last(this->attributes, (void*)attribute); -} - -METHOD(pkcs9_t, get_messageDigest, chunk_t, - private_pkcs9_t *this) -{ - const int oid = OID_PKCS9_MESSAGE_DIGEST; - chunk_t value = get_attribute(this, oid); - - if (value.ptr == NULL) - { - return chunk_empty; - } - if (!asn1_parse_simple_object(&value, asn1_attributeType(oid), 0, - oid_names[oid].name)) - { - return chunk_empty; - } - return chunk_clone(value); + this->attributes->insert_last(this->attributes, attribute); + chunk_free(&value); } -METHOD(pkcs9_t, set_messageDigest, void, - private_pkcs9_t *this, chunk_t value) +METHOD(pkcs9_t, set_attribute, void, + private_pkcs9_t *this, int oid, chunk_t value) { - const int oid = OID_PKCS9_MESSAGE_DIGEST; - chunk_t messageDigest = asn1_simple_object(asn1_attributeType(oid), value); + chunk_t attr = asn1_simple_object(asn1_attributeType(oid), value); - set_attribute(this, oid, messageDigest); - free(messageDigest.ptr); + set_attribute_raw(this, oid, attr); } METHOD(pkcs9_t, destroy, void, @@ -323,8 +259,7 @@ static private_pkcs9_t *pkcs9_create_empty(void) .get_encoding = _get_encoding, .get_attribute = _get_attribute, .set_attribute = _set_attribute, - .get_messageDigest = _get_messageDigest, - .set_messageDigest = _set_messageDigest, + .set_attribute_raw = _set_attribute_raw, .destroy = _destroy, }, .attributes = linked_list_create(), diff --git a/src/libstrongswan/crypto/pkcs9.h b/src/libstrongswan/crypto/pkcs9.h index 5b85692d6..c442d4441 100644 --- a/src/libstrongswan/crypto/pkcs9.h +++ b/src/libstrongswan/crypto/pkcs9.h @@ -1,4 +1,5 @@ /* + * Copyright (C) 2012 Tobias Brunner * Copyright (C) 2008 Andreas Steffen * Hochschule fuer Technik Rapperswil, Switzerland * @@ -46,7 +47,7 @@ struct pkcs9_t { * Gets a PKCS#9 attribute * * @param oid OID of the attribute - * @return ASN.1 encoded value of the attribute + * @return value of the attribute (internal data) */ chunk_t (*get_attribute) (pkcs9_t *this, int oid); @@ -54,23 +55,17 @@ struct pkcs9_t { * Adds a PKCS#9 attribute * * @param oid OID of the attribute - * @param value ASN.1 encoded value of the attribute + * @param value value of the attribute (gets cloned) */ void (*set_attribute) (pkcs9_t *this, int oid, chunk_t value); /** - * Gets a PKCS#9 messageDigest attribute + * Adds a ASN.1 encoded PKCS#9 attribute * - * @return messageDigest - */ - chunk_t (*get_messageDigest) (pkcs9_t *this); - - /** - * Add a PKCS#9 messageDigest attribute - * - * @param value messageDigest + * @param oid OID of the attribute + * @param value ASN.1 encoded value of the attribute (gets adopted) */ - void (*set_messageDigest) (pkcs9_t *this, chunk_t value); + void (*set_attribute_raw) (pkcs9_t *this, int oid, chunk_t value); /** * Destroys the PKCS#9 attribute list. diff --git a/src/libstrongswan/crypto/prf_plus.c b/src/libstrongswan/crypto/prf_plus.c index 8e815e608..94be1d5bf 100644 --- a/src/libstrongswan/crypto/prf_plus.c +++ b/src/libstrongswan/crypto/prf_plus.c @@ -25,6 +25,7 @@ typedef struct private_prf_plus_t private_prf_plus_t; * */ struct private_prf_plus_t { + /** * Public interface of prf_plus_t. */ @@ -41,65 +42,74 @@ struct private_prf_plus_t { chunk_t seed; /** - * Buffer to store current PRF result. + * Octet which will be appended to the seed, 0 if not used */ - chunk_t buffer; + u_int8_t counter; /** * Already given out bytes in current buffer. */ - size_t given_out; + size_t used; /** - * Octet which will be appended to the seed. + * Buffer to store current PRF result. */ - u_int8_t appending_octet; + chunk_t buffer; }; -METHOD(prf_plus_t, get_bytes, void, +METHOD(prf_plus_t, get_bytes, bool, private_prf_plus_t *this, size_t length, u_int8_t *buffer) { - chunk_t appending_chunk; - size_t bytes_in_round; - size_t total_bytes_written = 0; - - appending_chunk.ptr = &(this->appending_octet); - appending_chunk.len = 1; + size_t round, written = 0; while (length > 0) - { /* still more to do... */ - if (this->buffer.len == this->given_out) - { /* no bytes left in buffer, get next*/ - this->prf->get_bytes(this->prf, this->buffer, NULL); - this->prf->get_bytes(this->prf, this->seed, NULL); - this->prf->get_bytes(this->prf, appending_chunk, this->buffer.ptr); - this->given_out = 0; - this->appending_octet++; + { + if (this->buffer.len == this->used) + { /* buffer used, get next round */ + if (!this->prf->get_bytes(this->prf, this->buffer, NULL)) + { + return FALSE; + } + if (this->counter) + { + if (!this->prf->get_bytes(this->prf, this->seed, NULL) || + !this->prf->get_bytes(this->prf, + chunk_from_thing(this->counter), this->buffer.ptr)) + { + return FALSE; + } + this->counter++; + } + else + { + if (!this->prf->get_bytes(this->prf, this->seed, + this->buffer.ptr)) + { + return FALSE; + } + } + this->used = 0; } - /* how many bytes can we write in this round ? */ - bytes_in_round = min(length, this->buffer.len - this->given_out); - /* copy bytes from buffer with offset */ - memcpy(buffer + total_bytes_written, this->buffer.ptr + this->given_out, bytes_in_round); - - length -= bytes_in_round; - this->given_out += bytes_in_round; - total_bytes_written += bytes_in_round; + round = min(length, this->buffer.len - this->used); + memcpy(buffer + written, this->buffer.ptr + this->used, round); + + length -= round; + this->used += round; + written += round; } + return TRUE; } -METHOD(prf_plus_t, allocate_bytes, void, +METHOD(prf_plus_t, allocate_bytes, bool, private_prf_plus_t *this, size_t length, chunk_t *chunk) { if (length) { - chunk->ptr = malloc(length); - chunk->len = length; - get_bytes(this, length, chunk->ptr); - } - else - { - *chunk = chunk_empty; + *chunk = chunk_alloc(length); + return get_bytes(this, length, chunk->ptr); } + *chunk = chunk_empty; + return TRUE; } METHOD(prf_plus_t, destroy, void, @@ -113,10 +123,9 @@ METHOD(prf_plus_t, destroy, void, /* * Description in header. */ -prf_plus_t *prf_plus_create(prf_t *prf, chunk_t seed) +prf_plus_t *prf_plus_create(prf_t *prf, bool counter, chunk_t seed) { private_prf_plus_t *this; - chunk_t appending_chunk; INIT(this, .public = { @@ -125,25 +134,30 @@ prf_plus_t *prf_plus_create(prf_t *prf, chunk_t seed) .destroy = _destroy, }, .prf = prf, + .seed = chunk_clone(seed), + .buffer = chunk_alloc(prf->get_block_size(prf)), ); - /* allocate buffer for prf output */ - this->buffer.len = prf->get_block_size(prf); - this->buffer.ptr = malloc(this->buffer.len); - - this->appending_octet = 0x01; - - /* clone seed */ - this->seed.ptr = clalloc(seed.ptr, seed.len); - this->seed.len = seed.len; - - /* do the first run */ - appending_chunk.ptr = &(this->appending_octet); - appending_chunk.len = 1; - this->prf->get_bytes(this->prf, this->seed, NULL); - this->prf->get_bytes(this->prf, appending_chunk, this->buffer.ptr); - this->given_out = 0; - this->appending_octet++; + if (counter) + { + this->counter = 0x01; + if (!this->prf->get_bytes(this->prf, this->seed, NULL) || + !this->prf->get_bytes(this->prf, chunk_from_thing(this->counter), + this->buffer.ptr)) + { + destroy(this); + return NULL; + } + this->counter++; + } + else + { + if (!this->prf->get_bytes(this->prf, this->seed, this->buffer.ptr)) + { + destroy(this); + return NULL; + } + } - return &(this->public); + return &this->public; } diff --git a/src/libstrongswan/crypto/prf_plus.h b/src/libstrongswan/crypto/prf_plus.h index 4179f2695..f994dce16 100644 --- a/src/libstrongswan/crypto/prf_plus.h +++ b/src/libstrongswan/crypto/prf_plus.h @@ -27,52 +27,44 @@ typedef struct prf_plus_t prf_plus_t; #include <crypto/prfs/prf.h> /** - * 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. + * Implementation of the prf+ function used in IKEv1/IKEv2 keymat extension. */ struct prf_plus_t { + /** * Get pseudo random bytes. * - * Get the next few bytes of the prf+ output. Space - * must be allocated by the caller. - * * @param length number of bytes to get * @param buffer pointer where the generated bytes will be written + * @return TRUE if bytes generated successfully */ - void (*get_bytes) (prf_plus_t *this, size_t length, u_int8_t *buffer); + bool (*get_bytes)(prf_plus_t *this, size_t length, + u_int8_t *buffer) __attribute__((warn_unused_result)); /** * Allocate pseudo random bytes. * - * Get the next few bytes of the prf+ output. This function - * will allocate the required space. - * * @param length number of bytes to get * @param chunk chunk which will hold generated bytes + * @return TRUE if bytes allocated successfully */ - void (*allocate_bytes) (prf_plus_t *this, size_t length, chunk_t *chunk); + bool (*allocate_bytes)(prf_plus_t *this, size_t length, + chunk_t *chunk) __attribute__((warn_unused_result)); /** * Destroys a prf_plus_t object. */ - void (*destroy) (prf_plus_t *this); + void (*destroy)(prf_plus_t *this); }; /** * Creates a new prf_plus_t object. * - * Seed will be cloned. prf will - * not be cloned, must be destroyed outside after - * prf_plus_t usage. - * - * @param prf prf object to use + * @param prf prf object to use, must be destroyd after prf+. + * @param counter use an appending counter byte (for IKEv2 variant) * @param seed input seed for prf - * @return prf_plus_t object + * @return prf_plus_t object, NULL on failure */ -prf_plus_t *prf_plus_create(prf_t *prf, chunk_t seed); +prf_plus_t *prf_plus_create(prf_t *prf, bool counter, chunk_t seed); #endif /** PRF_PLUS_H_ @}*/ diff --git a/src/libstrongswan/crypto/prfs/mac_prf.c b/src/libstrongswan/crypto/prfs/mac_prf.c new file mode 100644 index 000000000..b5f6be982 --- /dev/null +++ b/src/libstrongswan/crypto/prfs/mac_prf.c @@ -0,0 +1,101 @@ +/* + * Copyright (C) 2012 Tobias Brunner + * Copyright (C) 2005-2006 Martin Willi + * Copyright (C) 2005 Jan Hutter + * Hochschule fuer Technik Rapperswil + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT 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 "mac_prf.h" + +typedef struct private_prf_t private_prf_t; + +/** + * Private data of a mac_prf_t object. + */ +struct private_prf_t { + + /** + * Public interface + */ + prf_t public; + + /** + * MAC to use + */ + mac_t *mac; +}; + +METHOD(prf_t, get_bytes, bool, + private_prf_t *this, chunk_t seed, u_int8_t *buffer) +{ + return this->mac->get_mac(this->mac, seed, buffer); +} + +METHOD(prf_t, allocate_bytes, bool, + private_prf_t *this, chunk_t seed, chunk_t *chunk) +{ + if (chunk) + { + *chunk = chunk_alloc(this->mac->get_mac_size(this->mac)); + return this->mac->get_mac(this->mac, seed, chunk->ptr); + } + return this->mac->get_mac(this->mac, seed, NULL); +} + +METHOD(prf_t, get_block_size, size_t, + private_prf_t *this) +{ + return this->mac->get_mac_size(this->mac); +} + +METHOD(prf_t, get_key_size, size_t, + private_prf_t *this) +{ + /* IKEv2 uses MAC size as key size */ + return this->mac->get_mac_size(this->mac); +} + +METHOD(prf_t, set_key, bool, + private_prf_t *this, chunk_t key) +{ + return this->mac->set_key(this->mac, key); +} + +METHOD(prf_t, destroy, void, + private_prf_t *this) +{ + this->mac->destroy(this->mac); + free(this); +} + +/* + * Described in header. + */ +prf_t *mac_prf_create(mac_t *mac) +{ + private_prf_t *this; + + INIT(this, + .public = { + .get_bytes = _get_bytes, + .allocate_bytes = _allocate_bytes, + .get_block_size = _get_block_size, + .get_key_size = _get_key_size, + .set_key = _set_key, + .destroy = _destroy, + }, + .mac = mac, + ); + + return &this->public; +} diff --git a/src/libstrongswan/plugins/xcbc/xcbc_prf.h b/src/libstrongswan/crypto/prfs/mac_prf.h index 294a853b4..b2c0c6e17 100644 --- a/src/libstrongswan/plugins/xcbc/xcbc_prf.h +++ b/src/libstrongswan/crypto/prfs/mac_prf.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2008 Martin Willi + * Copyright (C) 2012 Tobias Brunner * Hochschule fuer Technik Rapperswil * * This program is free software; you can redistribute it and/or modify it @@ -14,37 +14,23 @@ */ /** - * @defgroup xcbc_prf xcbc_prf - * @{ @ingroup xcbc_p + * @defgroup mac_prf mac_prf + * @{ @ingroup crypto */ -#ifndef PRF_XCBC_H_ -#define PRF_XCBC_H_ - -typedef struct xcbc_prf_t xcbc_prf_t; +#ifndef MAC_PRF_H_ +#define MAC_PRF_H_ +#include <crypto/mac.h> #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 { - - /** - * Implements prf_t interface. - */ - prf_t prf; -}; - -/** - * Creates a new xcbc_prf_t object. + * Creates an implementation of the prf_t interface using the provided mac_t + * implementation. Basically a simple wrapper to map the interface. * - * @param algo algorithm to implement - * @return xcbc_prf_t object, NULL if hash not supported + * @param mac mac_t implementation + * @return prf_t object */ -xcbc_prf_t *xcbc_prf_create(pseudo_random_function_t algo); +prf_t *mac_prf_create(mac_t *mac); -#endif /** PRF_XCBC_SHA1_H_ @}*/ +#endif /** MAC_PRF_H_ @}*/ diff --git a/src/libstrongswan/crypto/prfs/prf.h b/src/libstrongswan/crypto/prfs/prf.h index ad15205d3..46e23b244 100644 --- a/src/libstrongswan/crypto/prfs/prf.h +++ b/src/libstrongswan/crypto/prfs/prf.h @@ -71,28 +71,33 @@ extern enum_name_t *pseudo_random_function_names; * Generic interface for pseudo-random-functions. */ struct prf_t { + /** * Generates pseudo random bytes and writes them in the buffer. * * @param seed a chunk containing the seed for the next bytes * @param buffer pointer where the generated bytes will be written + * @return TRUE if bytes generated successfully */ - void (*get_bytes) (prf_t *this, chunk_t seed, u_int8_t *buffer); + bool (*get_bytes)(prf_t *this, chunk_t seed, + u_int8_t *buffer) __attribute__((warn_unused_result)); /** * Generates pseudo random bytes and allocate space for them. * * @param seed a chunk containing the seed for the next bytes * @param chunk chunk which will hold generated bytes + * @return TRUE if bytes allocated and generated successfully */ - void (*allocate_bytes) (prf_t *this, chunk_t seed, chunk_t *chunk); + bool (*allocate_bytes)(prf_t *this, chunk_t seed, + chunk_t *chunk) __attribute__((warn_unused_result)); /** * Get the block size of this prf_t object. * * @return block size in bytes */ - size_t (*get_block_size) (prf_t *this); + size_t (*get_block_size)(prf_t *this); /** * Get the key size of this prf_t object. @@ -102,19 +107,21 @@ struct prf_t { * * @return key size in bytes */ - size_t (*get_key_size) (prf_t *this); + size_t (*get_key_size)(prf_t *this); /** * Set the key for this prf_t object. * * @param key key to set + * @return TRUE if key set successfully */ - void (*set_key) (prf_t *this, chunk_t key); + bool (*set_key)(prf_t *this, + chunk_t key) __attribute__((warn_unused_result)); /** * Destroys a prf object. */ - void (*destroy) (prf_t *this); + void (*destroy)(prf_t *this); }; #endif /** PRF_H_ @}*/ diff --git a/src/libstrongswan/crypto/proposal/proposal_keywords.c b/src/libstrongswan/crypto/proposal/proposal_keywords.c index 2060864a5..7356dc367 100644 --- a/src/libstrongswan/crypto/proposal/proposal_keywords.c +++ b/src/libstrongswan/crypto/proposal/proposal_keywords.c @@ -1,38 +1,6 @@ -/* C code produced by gperf version 3.0.3 */ -/* Command-line: /usr/bin/gperf -N proposal_get_token -m 10 -C -G -c -t -D */ -/* Computed positions: -k'1,5,7,10,15,$' */ - -#if !((' ' == 32) && ('!' == 33) && ('"' == 34) && ('#' == 35) \ - && ('%' == 37) && ('&' == 38) && ('\'' == 39) && ('(' == 40) \ - && (')' == 41) && ('*' == 42) && ('+' == 43) && (',' == 44) \ - && ('-' == 45) && ('.' == 46) && ('/' == 47) && ('0' == 48) \ - && ('1' == 49) && ('2' == 50) && ('3' == 51) && ('4' == 52) \ - && ('5' == 53) && ('6' == 54) && ('7' == 55) && ('8' == 56) \ - && ('9' == 57) && (':' == 58) && (';' == 59) && ('<' == 60) \ - && ('=' == 61) && ('>' == 62) && ('?' == 63) && ('A' == 65) \ - && ('B' == 66) && ('C' == 67) && ('D' == 68) && ('E' == 69) \ - && ('F' == 70) && ('G' == 71) && ('H' == 72) && ('I' == 73) \ - && ('J' == 74) && ('K' == 75) && ('L' == 76) && ('M' == 77) \ - && ('N' == 78) && ('O' == 79) && ('P' == 80) && ('Q' == 81) \ - && ('R' == 82) && ('S' == 83) && ('T' == 84) && ('U' == 85) \ - && ('V' == 86) && ('W' == 87) && ('X' == 88) && ('Y' == 89) \ - && ('Z' == 90) && ('[' == 91) && ('\\' == 92) && (']' == 93) \ - && ('^' == 94) && ('_' == 95) && ('a' == 97) && ('b' == 98) \ - && ('c' == 99) && ('d' == 100) && ('e' == 101) && ('f' == 102) \ - && ('g' == 103) && ('h' == 104) && ('i' == 105) && ('j' == 106) \ - && ('k' == 107) && ('l' == 108) && ('m' == 109) && ('n' == 110) \ - && ('o' == 111) && ('p' == 112) && ('q' == 113) && ('r' == 114) \ - && ('s' == 115) && ('t' == 116) && ('u' == 117) && ('v' == 118) \ - && ('w' == 119) && ('x' == 120) && ('y' == 121) && ('z' == 122) \ - && ('{' == 123) && ('|' == 124) && ('}' == 125) && ('~' == 126)) -/* The character set is not based on ISO-646. */ -error "gperf generated tables don't work with this execution character set. Please report a bug to <bug-gnu-gperf@gnu.org>." -#endif - - -/* proposal keywords - * Copyright (C) 2009 Andreas Steffen - * Hochschule fuer Technik Rapperswil, Switzerland +/* + * Copyright (C) 2012 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 @@ -45,280 +13,134 @@ error "gperf generated tables don't work with this execution character set. Plea * for more details. */ -#include <string.h> +/* + * Copyright (c) 2012 Nanoteq Pty Ltd + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "proposal_keywords.h" +#include "proposal_keywords_static.h" -#include <crypto/transform.h> -#include <crypto/crypters/crypter.h> -#include <crypto/signers/signer.h> -#include <crypto/diffie_hellman.h> +#include <utils/linked_list.h> +#include <threading/rwlock.h> -struct proposal_token { - char *name; - transform_type_t type; - u_int16_t algorithm; - u_int16_t keysize; -}; +typedef struct private_proposal_keywords_t private_proposal_keywords_t; + +struct private_proposal_keywords_t { + + /** + * public interface + */ + proposal_keywords_t public; + + /** + * registered tokens, as proposal_token_t + */ + linked_list_t * tokens; -#define TOTAL_KEYWORDS 122 -#define MIN_WORD_LENGTH 3 -#define MAX_WORD_LENGTH 17 -#define MIN_HASH_VALUE 9 -#define MAX_HASH_VALUE 213 -/* maximum key range = 205, duplicates = 0 */ + /** + * rwlock to lock access to modules + */ + rwlock_t *lock; +}; -#ifdef __GNUC__ -__inline -#else -#ifdef __cplusplus -inline -#endif -#endif -static unsigned int -hash (str, len) - register const char *str; - register unsigned int len; +/** + * Find the token object for the algorithm specified. + */ +static const proposal_token_t* find_token(private_proposal_keywords_t *this, + const char *str) { - static const unsigned char asso_values[] = - { - 214, 214, 214, 214, 214, 214, 214, 214, 214, 214, - 214, 214, 214, 214, 214, 214, 214, 214, 214, 214, - 214, 214, 214, 214, 214, 214, 214, 214, 214, 214, - 214, 214, 214, 214, 214, 214, 214, 214, 214, 214, - 214, 214, 214, 214, 214, 214, 214, 214, 14, 9, - 4, 34, 66, 19, 8, 4, 5, 3, 214, 214, - 214, 214, 214, 214, 214, 214, 214, 214, 214, 214, - 214, 214, 214, 214, 214, 214, 214, 214, 214, 214, - 214, 214, 214, 214, 214, 214, 214, 214, 214, 214, - 214, 214, 214, 214, 214, 131, 214, 3, 22, 21, - 3, 1, 101, 48, 3, 4, 214, 214, 3, 10, - 57, 4, 214, 214, 94, 6, 3, 32, 214, 214, - 214, 214, 214, 214, 214, 214, 214, 214, 214, 214, - 214, 214, 214, 214, 214, 214, 214, 214, 214, 214, - 214, 214, 214, 214, 214, 214, 214, 214, 214, 214, - 214, 214, 214, 214, 214, 214, 214, 214, 214, 214, - 214, 214, 214, 214, 214, 214, 214, 214, 214, 214, - 214, 214, 214, 214, 214, 214, 214, 214, 214, 214, - 214, 214, 214, 214, 214, 214, 214, 214, 214, 214, - 214, 214, 214, 214, 214, 214, 214, 214, 214, 214, - 214, 214, 214, 214, 214, 214, 214, 214, 214, 214, - 214, 214, 214, 214, 214, 214, 214, 214, 214, 214, - 214, 214, 214, 214, 214, 214, 214, 214, 214, 214, - 214, 214, 214, 214, 214, 214, 214, 214, 214, 214, - 214, 214, 214, 214, 214, 214, 214, 214, 214, 214, - 214, 214, 214, 214, 214, 214, 214 - }; - register int hval = len; + proposal_token_t *token, *found = NULL; + enumerator_t *enumerator; + + this->lock->read_lock(this->lock); + enumerator = this->tokens->create_enumerator(this->tokens); + while (enumerator->enumerate(enumerator, &token)) + { + if (streq(token->name, str)) + { + found = token; + break; + } + } + enumerator->destroy(enumerator); + this->lock->unlock(this->lock); + return found; +} - switch (hval) - { - default: - hval += asso_values[(unsigned char)str[14]]; - /*FALLTHROUGH*/ - case 14: - case 13: - case 12: - case 11: - case 10: - hval += asso_values[(unsigned char)str[9]]; - /*FALLTHROUGH*/ - case 9: - case 8: - case 7: - hval += asso_values[(unsigned char)str[6]]; - /*FALLTHROUGH*/ - case 6: - case 5: - hval += asso_values[(unsigned char)str[4]]; - /*FALLTHROUGH*/ - case 4: - case 3: - case 2: - case 1: - hval += asso_values[(unsigned char)str[0]+1]; - break; - } - return hval + asso_values[(unsigned char)str[len - 1]]; +METHOD(proposal_keywords_t, get_token, const proposal_token_t*, + private_proposal_keywords_t *this, const char *str) +{ + const proposal_token_t *token = proposal_get_token_static(str, strlen(str)); + return token ?: find_token(this, str); } -static const struct proposal_token wordlist[] = - { - {"sha", INTEGRITY_ALGORITHM, AUTH_HMAC_SHA1_96, 0}, - {"des", ENCRYPTION_ALGORITHM, ENCR_DES, 0}, - {"null", ENCRYPTION_ALGORITHM, ENCR_NULL, 0}, - {"sha1", INTEGRITY_ALGORITHM, AUTH_HMAC_SHA1_96, 0}, - {"serpent", ENCRYPTION_ALGORITHM, ENCR_SERPENT_CBC, 128}, - {"camellia", ENCRYPTION_ALGORITHM, ENCR_CAMELLIA_CBC, 128}, - {"sha512", INTEGRITY_ALGORITHM, AUTH_HMAC_SHA2_512_256, 0}, - {"serpent192", ENCRYPTION_ALGORITHM, ENCR_SERPENT_CBC, 192}, - {"serpent128", ENCRYPTION_ALGORITHM, ENCR_SERPENT_CBC, 128}, - {"camellia192", ENCRYPTION_ALGORITHM, ENCR_CAMELLIA_CBC, 192}, - {"cast128", ENCRYPTION_ALGORITHM, ENCR_CAST, 128}, - {"camellia128", ENCRYPTION_ALGORITHM, ENCR_CAMELLIA_CBC, 128}, - {"aes", ENCRYPTION_ALGORITHM, ENCR_AES_CBC, 128}, - {"serpent256", ENCRYPTION_ALGORITHM, ENCR_SERPENT_CBC, 256}, - {"aes192", ENCRYPTION_ALGORITHM, ENCR_AES_CBC, 192}, - {"sha256", INTEGRITY_ALGORITHM, AUTH_HMAC_SHA2_256_128, 0}, - {"aes128", ENCRYPTION_ALGORITHM, ENCR_AES_CBC, 128}, - {"camellia192ccm8", ENCRYPTION_ALGORITHM, ENCR_CAMELLIA_CCM_ICV8, 192}, - {"camellia128ccm8", ENCRYPTION_ALGORITHM, ENCR_CAMELLIA_CCM_ICV8, 128}, - {"camellia192ccm96", ENCRYPTION_ALGORITHM, ENCR_CAMELLIA_CCM_ICV12, 192}, - {"camellia128ccm96", ENCRYPTION_ALGORITHM, ENCR_CAMELLIA_CCM_ICV12, 128}, - {"camellia192ccm12", ENCRYPTION_ALGORITHM, ENCR_CAMELLIA_CCM_ICV12, 192}, - {"camellia128ccm12", ENCRYPTION_ALGORITHM, ENCR_CAMELLIA_CCM_ICV12, 128}, - {"camellia192ccm128",ENCRYPTION_ALGORITHM, ENCR_CAMELLIA_CCM_ICV16, 192}, - {"camellia128ccm128",ENCRYPTION_ALGORITHM, ENCR_CAMELLIA_CCM_ICV16, 128}, - {"camellia192ccm16", ENCRYPTION_ALGORITHM, ENCR_CAMELLIA_CCM_ICV16, 192}, - {"camellia128ccm16", ENCRYPTION_ALGORITHM, ENCR_CAMELLIA_CCM_ICV16, 128}, - {"camellia256", ENCRYPTION_ALGORITHM, ENCR_CAMELLIA_CBC, 256}, - {"twofish", ENCRYPTION_ALGORITHM, ENCR_TWOFISH_CBC, 128}, - {"camellia256ccm8", ENCRYPTION_ALGORITHM, ENCR_CAMELLIA_CCM_ICV8, 256}, - {"aes256", ENCRYPTION_ALGORITHM, ENCR_AES_CBC, 256}, - {"camellia256ccm96", ENCRYPTION_ALGORITHM, ENCR_CAMELLIA_CCM_ICV12, 256}, - {"twofish192", ENCRYPTION_ALGORITHM, ENCR_TWOFISH_CBC, 192}, - {"camellia256ccm12", ENCRYPTION_ALGORITHM, ENCR_CAMELLIA_CCM_ICV12, 256}, - {"twofish128", ENCRYPTION_ALGORITHM, ENCR_TWOFISH_CBC, 128}, - {"camellia256ccm128",ENCRYPTION_ALGORITHM, ENCR_CAMELLIA_CCM_ICV16, 256}, - {"camellia256ccm16", ENCRYPTION_ALGORITHM, ENCR_CAMELLIA_CCM_ICV16, 256}, - {"camelliaxcbc", INTEGRITY_ALGORITHM, AUTH_CAMELLIA_XCBC_96, 0}, - {"twofish256", ENCRYPTION_ALGORITHM, ENCR_TWOFISH_CBC, 256}, - {"aes192ccm8", ENCRYPTION_ALGORITHM, ENCR_AES_CCM_ICV8, 192}, - {"aes128ccm8", ENCRYPTION_ALGORITHM, ENCR_AES_CCM_ICV8, 128}, - {"aes192ccm96", ENCRYPTION_ALGORITHM, ENCR_AES_CCM_ICV12, 192}, - {"aes128ccm96", ENCRYPTION_ALGORITHM, ENCR_AES_CCM_ICV12, 128}, - {"aes192ccm12", ENCRYPTION_ALGORITHM, ENCR_AES_CCM_ICV12, 192}, - {"aes128ccm12", ENCRYPTION_ALGORITHM, ENCR_AES_CCM_ICV12, 128}, - {"aes192ccm128", ENCRYPTION_ALGORITHM, ENCR_AES_CCM_ICV16, 192}, - {"aes128ccm128", ENCRYPTION_ALGORITHM, ENCR_AES_CCM_ICV16, 128}, - {"aes192ccm16", ENCRYPTION_ALGORITHM, ENCR_AES_CCM_ICV16, 192}, - {"aes128ccm16", ENCRYPTION_ALGORITHM, ENCR_AES_CCM_ICV16, 128}, - {"3des", ENCRYPTION_ALGORITHM, ENCR_3DES, 0}, - {"modp8192", DIFFIE_HELLMAN_GROUP, MODP_8192_BIT, 0}, - {"modp768", DIFFIE_HELLMAN_GROUP, MODP_768_BIT, 0}, - {"md5", INTEGRITY_ALGORITHM, AUTH_HMAC_MD5_96, 0}, - {"sha384", INTEGRITY_ALGORITHM, AUTH_HMAC_SHA2_384_192, 0}, - {"aescmac", INTEGRITY_ALGORITHM, AUTH_AES_CMAC_96, 0}, - {"aes256ccm8", ENCRYPTION_ALGORITHM, ENCR_AES_CCM_ICV8, 256}, - {"md5_128", INTEGRITY_ALGORITHM, AUTH_HMAC_MD5_128, 0}, - {"aes256ccm96", ENCRYPTION_ALGORITHM, ENCR_AES_CCM_ICV12, 256}, - {"aes256ccm12", ENCRYPTION_ALGORITHM, ENCR_AES_CCM_ICV12, 256}, - {"aes256ccm128", ENCRYPTION_ALGORITHM, ENCR_AES_CCM_ICV16, 256}, - {"aes256ccm16", ENCRYPTION_ALGORITHM, ENCR_AES_CCM_ICV16, 256}, - {"aesxcbc", INTEGRITY_ALGORITHM, AUTH_AES_XCBC_96, 0}, - {"aes192gcm8", ENCRYPTION_ALGORITHM, ENCR_AES_GCM_ICV8, 192}, - {"aes128gcm8", ENCRYPTION_ALGORITHM, ENCR_AES_GCM_ICV8, 128}, - {"aes192gcm96", ENCRYPTION_ALGORITHM, ENCR_AES_GCM_ICV12, 192}, - {"aes128gcm96", ENCRYPTION_ALGORITHM, ENCR_AES_GCM_ICV12, 128}, - {"aes192gcm12", ENCRYPTION_ALGORITHM, ENCR_AES_GCM_ICV12, 192}, - {"aes128gcm12", ENCRYPTION_ALGORITHM, ENCR_AES_GCM_ICV12, 128}, - {"aes192gcm128", ENCRYPTION_ALGORITHM, ENCR_AES_GCM_ICV16, 192}, - {"aes128gcm128", ENCRYPTION_ALGORITHM, ENCR_AES_GCM_ICV16, 128}, - {"aes192gcm16", ENCRYPTION_ALGORITHM, ENCR_AES_GCM_ICV16, 192}, - {"aes128gcm16", ENCRYPTION_ALGORITHM, ENCR_AES_GCM_ICV16, 128}, - {"camellia192ccm64", ENCRYPTION_ALGORITHM, ENCR_CAMELLIA_CCM_ICV8, 192}, - {"camellia128ccm64", ENCRYPTION_ALGORITHM, ENCR_CAMELLIA_CCM_ICV8, 128}, - {"modp1024s160", DIFFIE_HELLMAN_GROUP, MODP_1024_160, 0}, - {"modp3072", DIFFIE_HELLMAN_GROUP, MODP_3072_BIT, 0}, - {"aes256gcm8", ENCRYPTION_ALGORITHM, ENCR_AES_GCM_ICV8, 256}, - {"aes256gcm96", ENCRYPTION_ALGORITHM, ENCR_AES_GCM_ICV12, 256}, - {"aes256gcm12", ENCRYPTION_ALGORITHM, ENCR_AES_GCM_ICV12, 256}, - {"ecp192", DIFFIE_HELLMAN_GROUP, ECP_192_BIT, 0}, - {"aes256gcm128", ENCRYPTION_ALGORITHM, ENCR_AES_GCM_ICV16, 256}, - {"modp1536", DIFFIE_HELLMAN_GROUP, MODP_1536_BIT, 0}, - {"aes256gcm16", ENCRYPTION_ALGORITHM, ENCR_AES_GCM_ICV16, 256}, - {"camellia256ccm64", ENCRYPTION_ALGORITHM, ENCR_CAMELLIA_CCM_ICV8, 256}, - {"ecp521", DIFFIE_HELLMAN_GROUP, ECP_521_BIT, 0}, - {"camellia192ctr", ENCRYPTION_ALGORITHM, ENCR_CAMELLIA_CTR, 192}, - {"camellia128ctr", ENCRYPTION_ALGORITHM, ENCR_CAMELLIA_CTR, 128}, - {"noesn", EXTENDED_SEQUENCE_NUMBERS, NO_EXT_SEQ_NUMBERS, 0}, - {"aes192gmac", ENCRYPTION_ALGORITHM, ENCR_NULL_AUTH_AES_GMAC, 192}, - {"aes128gmac", ENCRYPTION_ALGORITHM, ENCR_NULL_AUTH_AES_GMAC, 128}, - {"modpnull", DIFFIE_HELLMAN_GROUP, MODP_NULL, 0}, - {"aes192ccm64", ENCRYPTION_ALGORITHM, ENCR_AES_CCM_ICV8, 192}, - {"aes128ccm64", ENCRYPTION_ALGORITHM, ENCR_AES_CCM_ICV8, 128}, - {"ecp256", DIFFIE_HELLMAN_GROUP, ECP_256_BIT, 0}, - {"camellia256ctr", ENCRYPTION_ALGORITHM, ENCR_CAMELLIA_CTR, 256}, - {"blowfish", ENCRYPTION_ALGORITHM, ENCR_BLOWFISH, 128}, - {"modp2048", DIFFIE_HELLMAN_GROUP, MODP_2048_BIT, 0}, - {"aes256gmac", ENCRYPTION_ALGORITHM, ENCR_NULL_AUTH_AES_GMAC, 256}, - {"modp4096", DIFFIE_HELLMAN_GROUP, MODP_4096_BIT, 0}, - {"modp1024", DIFFIE_HELLMAN_GROUP, MODP_1024_BIT, 0}, - {"blowfish192", ENCRYPTION_ALGORITHM, ENCR_BLOWFISH, 192}, - {"aes256ccm64", ENCRYPTION_ALGORITHM, ENCR_AES_CCM_ICV8, 256}, - {"blowfish128", ENCRYPTION_ALGORITHM, ENCR_BLOWFISH, 128}, - {"aes192ctr", ENCRYPTION_ALGORITHM, ENCR_AES_CTR, 192}, - {"aes128ctr", ENCRYPTION_ALGORITHM, ENCR_AES_CTR, 128}, - {"modp2048s256", DIFFIE_HELLMAN_GROUP, MODP_2048_256, 0}, - {"sha2_512", INTEGRITY_ALGORITHM, AUTH_HMAC_SHA2_512_256, 0}, - {"aes192gcm64", ENCRYPTION_ALGORITHM, ENCR_AES_GCM_ICV8, 192}, - {"aes128gcm64", ENCRYPTION_ALGORITHM, ENCR_AES_GCM_ICV8, 128}, - {"esn", EXTENDED_SEQUENCE_NUMBERS, EXT_SEQ_NUMBERS, 0}, - {"sha1_160", INTEGRITY_ALGORITHM, AUTH_HMAC_SHA1_160, 0}, - {"aes256ctr", ENCRYPTION_ALGORITHM, ENCR_AES_CTR, 256}, - {"blowfish256", ENCRYPTION_ALGORITHM, ENCR_BLOWFISH, 256}, - {"sha2_256", INTEGRITY_ALGORITHM, AUTH_HMAC_SHA2_256_128, 0}, - {"sha256_96", INTEGRITY_ALGORITHM, AUTH_HMAC_SHA2_256_96, 0}, - {"aes256gcm64", ENCRYPTION_ALGORITHM, ENCR_AES_GCM_ICV8, 256}, - {"sha2_256_96", INTEGRITY_ALGORITHM, AUTH_HMAC_SHA2_256_96, 0}, - {"ecp224", DIFFIE_HELLMAN_GROUP, ECP_224_BIT, 0}, - {"ecp384", DIFFIE_HELLMAN_GROUP, ECP_384_BIT, 0}, - {"modp6144", DIFFIE_HELLMAN_GROUP, MODP_6144_BIT, 0}, - {"modp2048s224", DIFFIE_HELLMAN_GROUP, MODP_2048_224, 0}, - {"sha2_384", INTEGRITY_ALGORITHM, AUTH_HMAC_SHA2_384_192, 0} - }; +METHOD(proposal_keywords_t, register_token, void, + private_proposal_keywords_t *this, const char *name, transform_type_t type, + u_int16_t algorithm, u_int16_t keysize) +{ + proposal_token_t *token; + + INIT(token, + .name = strdup(name), + .type = type, + .algorithm = algorithm, + .keysize = keysize, + ); -static const short lookup[] = - { - -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, - 1, 2, -1, -1, -1, -1, 3, 4, -1, -1, - -1, 5, 6, -1, -1, 7, -1, 8, 9, 10, - 11, 12, -1, 13, -1, 14, 15, 16, 17, 18, - 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, - -1, -1, -1, -1, 29, 30, 31, 32, 33, 34, - 35, -1, 36, -1, 37, 38, 39, 40, 41, 42, - 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, - 53, 54, 55, 56, 57, -1, 58, -1, 59, -1, - 60, -1, 61, 62, 63, 64, 65, 66, 67, 68, - 69, 70, 71, 72, 73, 74, -1, 75, -1, 76, - -1, 77, -1, 78, 79, 80, 81, 82, -1, 83, - 84, 85, 86, 87, -1, 88, 89, -1, 90, -1, - -1, 91, 92, -1, 93, -1, -1, 94, -1, 95, - 96, 97, 98, -1, 99, -1, 100, 101, 102, 103, - 104, 105, -1, -1, -1, 106, -1, -1, 107, 108, - -1, 109, -1, -1, 110, 111, 112, -1, -1, 113, - 114, -1, -1, -1, 115, 116, -1, 117, 118, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, 119, -1, -1, -1, 120, - -1, -1, -1, 121 - }; + this->lock->write_lock(this->lock); + this->tokens->insert_first(this->tokens, token); + this->lock->unlock(this->lock); +} -#ifdef __GNUC__ -__inline -#ifdef __GNUC_STDC_INLINE__ -__attribute__ ((__gnu_inline__)) -#endif -#endif -const struct proposal_token * -proposal_get_token (str, len) - register const char *str; - register unsigned int len; +METHOD(proposal_keywords_t, destroy, void, + private_proposal_keywords_t *this) { - if (len <= MAX_WORD_LENGTH && len >= MIN_WORD_LENGTH) - { - register int key = hash (str, len); + proposal_token_t *token; + + while (this->tokens->remove_first(this->tokens, (void**)&token) == SUCCESS) + { + free(token->name); + free(token); + } + this->tokens->destroy(this->tokens); + this->lock->destroy(this->lock); + free(this); +} - if (key <= MAX_HASH_VALUE && key >= 0) - { - register int index = lookup[key]; +/* + * Described in header. + */ +proposal_keywords_t *proposal_keywords_create() +{ + private_proposal_keywords_t *this; - if (index >= 0) - { - register const char *s = wordlist[index].name; + INIT(this, + .public = { + .get_token = _get_token, + .register_token = _register_token, + .destroy = _destroy, + }, + .tokens = linked_list_create(), + .lock = rwlock_create(RWLOCK_TYPE_DEFAULT), + ); - if (*str == *s && !strncmp (str + 1, s + 1, len - 1) && s[len] == '\0') - return &wordlist[index]; - } - } - } - return 0; + return &this->public; } diff --git a/src/libstrongswan/crypto/proposal/proposal_keywords.h b/src/libstrongswan/crypto/proposal/proposal_keywords.h index 53fa1728f..d6107abc0 100644 --- a/src/libstrongswan/crypto/proposal/proposal_keywords.h +++ b/src/libstrongswan/crypto/proposal/proposal_keywords.h @@ -1,6 +1,6 @@ -/* proposal keywords - * Copyright (C) 2009 Andreas Steffen - * Hochschule fuer Technik Rapperswil, Switzerland +/* + * Copyright (C) 2012 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 @@ -13,22 +13,103 @@ * for more details. */ -#ifndef _PROPOSAL_KEYWORDS_H_ -#define _PROPOSAL_KEYWORDS_H_ +/* + * Copyright (c) 2012 Nanoteq Pty Ltd + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +/** + * @defgroup proposal_keywords proposal_keywords + * @{ @ingroup crypto + */ + +#ifndef PROPOSAL_KEYWORDS_H_ +#define PROPOSAL_KEYWORDS_H_ + +typedef struct proposal_token_t proposal_token_t; +typedef struct proposal_keywords_t proposal_keywords_t; + +#include <library.h> #include <crypto/transform.h> -typedef struct proposal_token proposal_token_t; +/** + * Class representing a proposal token. + */ +struct proposal_token_t { + + /** + * The name of the token. + */ + char *name; + + /** + * The type of transform in the token. + */ + transform_type_t type; + + /** + * The IKE id of the algorithm. + */ + u_int16_t algorithm; -struct proposal_token { - char *name; - transform_type_t type; - u_int16_t algorithm; - u_int16_t keysize; + /** + * The key size associated with the specific algorithm. + */ + u_int16_t keysize; }; -extern const proposal_token_t* proposal_get_token(register const char *str, - register unsigned int len); +/** + * Class to manage proposal keywords + */ +struct proposal_keywords_t { + + /** + * Returns the proposal token for the specified string if a token exists. + * + * @param str the string containing the name of the token + * @return proposal_token if found, NULL otherwise + */ + const proposal_token_t *(*get_token)(proposal_keywords_t *this, + const char *str); -#endif /* _PROPOSAL_KEYWORDS_H_ */ + /** + * Register a new proposal token for an algorithm. + * + * @param name the string containing the name of the token + * @param type the transform_type_t for the token + * @param algorithm the IKE id of the algorithm + * @param keysize the key size associated with the specific algorithm + */ + void (*register_token)(proposal_keywords_t *this, const char *name, + transform_type_t type, u_int16_t algorithm, + u_int16_t keysize); + + /** + * Destroy a proposal_keywords_t instance. + */ + void (*destroy)(proposal_keywords_t *this); +}; + +/** + * Create a proposal_keywords_t instance. + */ +proposal_keywords_t *proposal_keywords_create(); +#endif /** PROPOSAL_KEYWORDS_H_ @}*/ diff --git a/src/libstrongswan/crypto/proposal/proposal_keywords_static.c b/src/libstrongswan/crypto/proposal/proposal_keywords_static.c new file mode 100644 index 000000000..ce52bc2ce --- /dev/null +++ b/src/libstrongswan/crypto/proposal/proposal_keywords_static.c @@ -0,0 +1,324 @@ +/* C code produced by gperf version 3.0.3 */ +/* Command-line: /usr/bin/gperf -N proposal_get_token_static -m 10 -C -G -c -t -D */ +/* Computed positions: -k'1,5,7,10,15,$' */ + +#if !((' ' == 32) && ('!' == 33) && ('"' == 34) && ('#' == 35) \ + && ('%' == 37) && ('&' == 38) && ('\'' == 39) && ('(' == 40) \ + && (')' == 41) && ('*' == 42) && ('+' == 43) && (',' == 44) \ + && ('-' == 45) && ('.' == 46) && ('/' == 47) && ('0' == 48) \ + && ('1' == 49) && ('2' == 50) && ('3' == 51) && ('4' == 52) \ + && ('5' == 53) && ('6' == 54) && ('7' == 55) && ('8' == 56) \ + && ('9' == 57) && (':' == 58) && (';' == 59) && ('<' == 60) \ + && ('=' == 61) && ('>' == 62) && ('?' == 63) && ('A' == 65) \ + && ('B' == 66) && ('C' == 67) && ('D' == 68) && ('E' == 69) \ + && ('F' == 70) && ('G' == 71) && ('H' == 72) && ('I' == 73) \ + && ('J' == 74) && ('K' == 75) && ('L' == 76) && ('M' == 77) \ + && ('N' == 78) && ('O' == 79) && ('P' == 80) && ('Q' == 81) \ + && ('R' == 82) && ('S' == 83) && ('T' == 84) && ('U' == 85) \ + && ('V' == 86) && ('W' == 87) && ('X' == 88) && ('Y' == 89) \ + && ('Z' == 90) && ('[' == 91) && ('\\' == 92) && (']' == 93) \ + && ('^' == 94) && ('_' == 95) && ('a' == 97) && ('b' == 98) \ + && ('c' == 99) && ('d' == 100) && ('e' == 101) && ('f' == 102) \ + && ('g' == 103) && ('h' == 104) && ('i' == 105) && ('j' == 106) \ + && ('k' == 107) && ('l' == 108) && ('m' == 109) && ('n' == 110) \ + && ('o' == 111) && ('p' == 112) && ('q' == 113) && ('r' == 114) \ + && ('s' == 115) && ('t' == 116) && ('u' == 117) && ('v' == 118) \ + && ('w' == 119) && ('x' == 120) && ('y' == 121) && ('z' == 122) \ + && ('{' == 123) && ('|' == 124) && ('}' == 125) && ('~' == 126)) +/* The character set is not based on ISO-646. */ +error "gperf generated tables don't work with this execution character set. Please report a bug to <bug-gnu-gperf@gnu.org>." +#endif + + +/* + * Copyright (C) 2009 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. + */ + +#include <string.h> + +#include <crypto/transform.h> +#include <crypto/crypters/crypter.h> +#include <crypto/signers/signer.h> +#include <crypto/diffie_hellman.h> + +struct proposal_token { + char *name; + transform_type_t type; + u_int16_t algorithm; + u_int16_t keysize; +}; + +#define TOTAL_KEYWORDS 122 +#define MIN_WORD_LENGTH 3 +#define MAX_WORD_LENGTH 17 +#define MIN_HASH_VALUE 9 +#define MAX_HASH_VALUE 213 +/* maximum key range = 205, duplicates = 0 */ + +#ifdef __GNUC__ +__inline +#else +#ifdef __cplusplus +inline +#endif +#endif +static unsigned int +hash (str, len) + register const char *str; + register unsigned int len; +{ + static const unsigned char asso_values[] = + { + 214, 214, 214, 214, 214, 214, 214, 214, 214, 214, + 214, 214, 214, 214, 214, 214, 214, 214, 214, 214, + 214, 214, 214, 214, 214, 214, 214, 214, 214, 214, + 214, 214, 214, 214, 214, 214, 214, 214, 214, 214, + 214, 214, 214, 214, 214, 214, 214, 214, 14, 9, + 4, 34, 66, 19, 8, 4, 5, 3, 214, 214, + 214, 214, 214, 214, 214, 214, 214, 214, 214, 214, + 214, 214, 214, 214, 214, 214, 214, 214, 214, 214, + 214, 214, 214, 214, 214, 214, 214, 214, 214, 214, + 214, 214, 214, 214, 214, 131, 214, 3, 22, 21, + 3, 1, 101, 48, 3, 4, 214, 214, 3, 10, + 57, 4, 214, 214, 94, 6, 3, 32, 214, 214, + 214, 214, 214, 214, 214, 214, 214, 214, 214, 214, + 214, 214, 214, 214, 214, 214, 214, 214, 214, 214, + 214, 214, 214, 214, 214, 214, 214, 214, 214, 214, + 214, 214, 214, 214, 214, 214, 214, 214, 214, 214, + 214, 214, 214, 214, 214, 214, 214, 214, 214, 214, + 214, 214, 214, 214, 214, 214, 214, 214, 214, 214, + 214, 214, 214, 214, 214, 214, 214, 214, 214, 214, + 214, 214, 214, 214, 214, 214, 214, 214, 214, 214, + 214, 214, 214, 214, 214, 214, 214, 214, 214, 214, + 214, 214, 214, 214, 214, 214, 214, 214, 214, 214, + 214, 214, 214, 214, 214, 214, 214, 214, 214, 214, + 214, 214, 214, 214, 214, 214, 214, 214, 214, 214, + 214, 214, 214, 214, 214, 214, 214, 214, 214, 214, + 214, 214, 214, 214, 214, 214, 214 + }; + register int hval = len; + + switch (hval) + { + default: + hval += asso_values[(unsigned char)str[14]]; + /*FALLTHROUGH*/ + case 14: + case 13: + case 12: + case 11: + case 10: + hval += asso_values[(unsigned char)str[9]]; + /*FALLTHROUGH*/ + case 9: + case 8: + case 7: + hval += asso_values[(unsigned char)str[6]]; + /*FALLTHROUGH*/ + case 6: + case 5: + hval += asso_values[(unsigned char)str[4]]; + /*FALLTHROUGH*/ + case 4: + case 3: + case 2: + case 1: + hval += asso_values[(unsigned char)str[0]+1]; + break; + } + return hval + asso_values[(unsigned char)str[len - 1]]; +} + +static const struct proposal_token wordlist[] = + { + {"sha", INTEGRITY_ALGORITHM, AUTH_HMAC_SHA1_96, 0}, + {"des", ENCRYPTION_ALGORITHM, ENCR_DES, 0}, + {"null", ENCRYPTION_ALGORITHM, ENCR_NULL, 0}, + {"sha1", INTEGRITY_ALGORITHM, AUTH_HMAC_SHA1_96, 0}, + {"serpent", ENCRYPTION_ALGORITHM, ENCR_SERPENT_CBC, 128}, + {"camellia", ENCRYPTION_ALGORITHM, ENCR_CAMELLIA_CBC, 128}, + {"sha512", INTEGRITY_ALGORITHM, AUTH_HMAC_SHA2_512_256, 0}, + {"serpent192", ENCRYPTION_ALGORITHM, ENCR_SERPENT_CBC, 192}, + {"serpent128", ENCRYPTION_ALGORITHM, ENCR_SERPENT_CBC, 128}, + {"camellia192", ENCRYPTION_ALGORITHM, ENCR_CAMELLIA_CBC, 192}, + {"cast128", ENCRYPTION_ALGORITHM, ENCR_CAST, 128}, + {"camellia128", ENCRYPTION_ALGORITHM, ENCR_CAMELLIA_CBC, 128}, + {"aes", ENCRYPTION_ALGORITHM, ENCR_AES_CBC, 128}, + {"serpent256", ENCRYPTION_ALGORITHM, ENCR_SERPENT_CBC, 256}, + {"aes192", ENCRYPTION_ALGORITHM, ENCR_AES_CBC, 192}, + {"sha256", INTEGRITY_ALGORITHM, AUTH_HMAC_SHA2_256_128, 0}, + {"aes128", ENCRYPTION_ALGORITHM, ENCR_AES_CBC, 128}, + {"camellia192ccm8", ENCRYPTION_ALGORITHM, ENCR_CAMELLIA_CCM_ICV8, 192}, + {"camellia128ccm8", ENCRYPTION_ALGORITHM, ENCR_CAMELLIA_CCM_ICV8, 128}, + {"camellia192ccm96", ENCRYPTION_ALGORITHM, ENCR_CAMELLIA_CCM_ICV12, 192}, + {"camellia128ccm96", ENCRYPTION_ALGORITHM, ENCR_CAMELLIA_CCM_ICV12, 128}, + {"camellia192ccm12", ENCRYPTION_ALGORITHM, ENCR_CAMELLIA_CCM_ICV12, 192}, + {"camellia128ccm12", ENCRYPTION_ALGORITHM, ENCR_CAMELLIA_CCM_ICV12, 128}, + {"camellia192ccm128",ENCRYPTION_ALGORITHM, ENCR_CAMELLIA_CCM_ICV16, 192}, + {"camellia128ccm128",ENCRYPTION_ALGORITHM, ENCR_CAMELLIA_CCM_ICV16, 128}, + {"camellia192ccm16", ENCRYPTION_ALGORITHM, ENCR_CAMELLIA_CCM_ICV16, 192}, + {"camellia128ccm16", ENCRYPTION_ALGORITHM, ENCR_CAMELLIA_CCM_ICV16, 128}, + {"camellia256", ENCRYPTION_ALGORITHM, ENCR_CAMELLIA_CBC, 256}, + {"twofish", ENCRYPTION_ALGORITHM, ENCR_TWOFISH_CBC, 128}, + {"camellia256ccm8", ENCRYPTION_ALGORITHM, ENCR_CAMELLIA_CCM_ICV8, 256}, + {"aes256", ENCRYPTION_ALGORITHM, ENCR_AES_CBC, 256}, + {"camellia256ccm96", ENCRYPTION_ALGORITHM, ENCR_CAMELLIA_CCM_ICV12, 256}, + {"twofish192", ENCRYPTION_ALGORITHM, ENCR_TWOFISH_CBC, 192}, + {"camellia256ccm12", ENCRYPTION_ALGORITHM, ENCR_CAMELLIA_CCM_ICV12, 256}, + {"twofish128", ENCRYPTION_ALGORITHM, ENCR_TWOFISH_CBC, 128}, + {"camellia256ccm128",ENCRYPTION_ALGORITHM, ENCR_CAMELLIA_CCM_ICV16, 256}, + {"camellia256ccm16", ENCRYPTION_ALGORITHM, ENCR_CAMELLIA_CCM_ICV16, 256}, + {"camelliaxcbc", INTEGRITY_ALGORITHM, AUTH_CAMELLIA_XCBC_96, 0}, + {"twofish256", ENCRYPTION_ALGORITHM, ENCR_TWOFISH_CBC, 256}, + {"aes192ccm8", ENCRYPTION_ALGORITHM, ENCR_AES_CCM_ICV8, 192}, + {"aes128ccm8", ENCRYPTION_ALGORITHM, ENCR_AES_CCM_ICV8, 128}, + {"aes192ccm96", ENCRYPTION_ALGORITHM, ENCR_AES_CCM_ICV12, 192}, + {"aes128ccm96", ENCRYPTION_ALGORITHM, ENCR_AES_CCM_ICV12, 128}, + {"aes192ccm12", ENCRYPTION_ALGORITHM, ENCR_AES_CCM_ICV12, 192}, + {"aes128ccm12", ENCRYPTION_ALGORITHM, ENCR_AES_CCM_ICV12, 128}, + {"aes192ccm128", ENCRYPTION_ALGORITHM, ENCR_AES_CCM_ICV16, 192}, + {"aes128ccm128", ENCRYPTION_ALGORITHM, ENCR_AES_CCM_ICV16, 128}, + {"aes192ccm16", ENCRYPTION_ALGORITHM, ENCR_AES_CCM_ICV16, 192}, + {"aes128ccm16", ENCRYPTION_ALGORITHM, ENCR_AES_CCM_ICV16, 128}, + {"3des", ENCRYPTION_ALGORITHM, ENCR_3DES, 0}, + {"modp8192", DIFFIE_HELLMAN_GROUP, MODP_8192_BIT, 0}, + {"modp768", DIFFIE_HELLMAN_GROUP, MODP_768_BIT, 0}, + {"md5", INTEGRITY_ALGORITHM, AUTH_HMAC_MD5_96, 0}, + {"sha384", INTEGRITY_ALGORITHM, AUTH_HMAC_SHA2_384_192, 0}, + {"aescmac", INTEGRITY_ALGORITHM, AUTH_AES_CMAC_96, 0}, + {"aes256ccm8", ENCRYPTION_ALGORITHM, ENCR_AES_CCM_ICV8, 256}, + {"md5_128", INTEGRITY_ALGORITHM, AUTH_HMAC_MD5_128, 0}, + {"aes256ccm96", ENCRYPTION_ALGORITHM, ENCR_AES_CCM_ICV12, 256}, + {"aes256ccm12", ENCRYPTION_ALGORITHM, ENCR_AES_CCM_ICV12, 256}, + {"aes256ccm128", ENCRYPTION_ALGORITHM, ENCR_AES_CCM_ICV16, 256}, + {"aes256ccm16", ENCRYPTION_ALGORITHM, ENCR_AES_CCM_ICV16, 256}, + {"aesxcbc", INTEGRITY_ALGORITHM, AUTH_AES_XCBC_96, 0}, + {"aes192gcm8", ENCRYPTION_ALGORITHM, ENCR_AES_GCM_ICV8, 192}, + {"aes128gcm8", ENCRYPTION_ALGORITHM, ENCR_AES_GCM_ICV8, 128}, + {"aes192gcm96", ENCRYPTION_ALGORITHM, ENCR_AES_GCM_ICV12, 192}, + {"aes128gcm96", ENCRYPTION_ALGORITHM, ENCR_AES_GCM_ICV12, 128}, + {"aes192gcm12", ENCRYPTION_ALGORITHM, ENCR_AES_GCM_ICV12, 192}, + {"aes128gcm12", ENCRYPTION_ALGORITHM, ENCR_AES_GCM_ICV12, 128}, + {"aes192gcm128", ENCRYPTION_ALGORITHM, ENCR_AES_GCM_ICV16, 192}, + {"aes128gcm128", ENCRYPTION_ALGORITHM, ENCR_AES_GCM_ICV16, 128}, + {"aes192gcm16", ENCRYPTION_ALGORITHM, ENCR_AES_GCM_ICV16, 192}, + {"aes128gcm16", ENCRYPTION_ALGORITHM, ENCR_AES_GCM_ICV16, 128}, + {"camellia192ccm64", ENCRYPTION_ALGORITHM, ENCR_CAMELLIA_CCM_ICV8, 192}, + {"camellia128ccm64", ENCRYPTION_ALGORITHM, ENCR_CAMELLIA_CCM_ICV8, 128}, + {"modp1024s160", DIFFIE_HELLMAN_GROUP, MODP_1024_160, 0}, + {"modp3072", DIFFIE_HELLMAN_GROUP, MODP_3072_BIT, 0}, + {"aes256gcm8", ENCRYPTION_ALGORITHM, ENCR_AES_GCM_ICV8, 256}, + {"aes256gcm96", ENCRYPTION_ALGORITHM, ENCR_AES_GCM_ICV12, 256}, + {"aes256gcm12", ENCRYPTION_ALGORITHM, ENCR_AES_GCM_ICV12, 256}, + {"ecp192", DIFFIE_HELLMAN_GROUP, ECP_192_BIT, 0}, + {"aes256gcm128", ENCRYPTION_ALGORITHM, ENCR_AES_GCM_ICV16, 256}, + {"modp1536", DIFFIE_HELLMAN_GROUP, MODP_1536_BIT, 0}, + {"aes256gcm16", ENCRYPTION_ALGORITHM, ENCR_AES_GCM_ICV16, 256}, + {"camellia256ccm64", ENCRYPTION_ALGORITHM, ENCR_CAMELLIA_CCM_ICV8, 256}, + {"ecp521", DIFFIE_HELLMAN_GROUP, ECP_521_BIT, 0}, + {"camellia192ctr", ENCRYPTION_ALGORITHM, ENCR_CAMELLIA_CTR, 192}, + {"camellia128ctr", ENCRYPTION_ALGORITHM, ENCR_CAMELLIA_CTR, 128}, + {"noesn", EXTENDED_SEQUENCE_NUMBERS, NO_EXT_SEQ_NUMBERS, 0}, + {"aes192gmac", ENCRYPTION_ALGORITHM, ENCR_NULL_AUTH_AES_GMAC, 192}, + {"aes128gmac", ENCRYPTION_ALGORITHM, ENCR_NULL_AUTH_AES_GMAC, 128}, + {"modpnull", DIFFIE_HELLMAN_GROUP, MODP_NULL, 0}, + {"aes192ccm64", ENCRYPTION_ALGORITHM, ENCR_AES_CCM_ICV8, 192}, + {"aes128ccm64", ENCRYPTION_ALGORITHM, ENCR_AES_CCM_ICV8, 128}, + {"ecp256", DIFFIE_HELLMAN_GROUP, ECP_256_BIT, 0}, + {"camellia256ctr", ENCRYPTION_ALGORITHM, ENCR_CAMELLIA_CTR, 256}, + {"blowfish", ENCRYPTION_ALGORITHM, ENCR_BLOWFISH, 128}, + {"modp2048", DIFFIE_HELLMAN_GROUP, MODP_2048_BIT, 0}, + {"aes256gmac", ENCRYPTION_ALGORITHM, ENCR_NULL_AUTH_AES_GMAC, 256}, + {"modp4096", DIFFIE_HELLMAN_GROUP, MODP_4096_BIT, 0}, + {"modp1024", DIFFIE_HELLMAN_GROUP, MODP_1024_BIT, 0}, + {"blowfish192", ENCRYPTION_ALGORITHM, ENCR_BLOWFISH, 192}, + {"aes256ccm64", ENCRYPTION_ALGORITHM, ENCR_AES_CCM_ICV8, 256}, + {"blowfish128", ENCRYPTION_ALGORITHM, ENCR_BLOWFISH, 128}, + {"aes192ctr", ENCRYPTION_ALGORITHM, ENCR_AES_CTR, 192}, + {"aes128ctr", ENCRYPTION_ALGORITHM, ENCR_AES_CTR, 128}, + {"modp2048s256", DIFFIE_HELLMAN_GROUP, MODP_2048_256, 0}, + {"sha2_512", INTEGRITY_ALGORITHM, AUTH_HMAC_SHA2_512_256, 0}, + {"aes192gcm64", ENCRYPTION_ALGORITHM, ENCR_AES_GCM_ICV8, 192}, + {"aes128gcm64", ENCRYPTION_ALGORITHM, ENCR_AES_GCM_ICV8, 128}, + {"esn", EXTENDED_SEQUENCE_NUMBERS, EXT_SEQ_NUMBERS, 0}, + {"sha1_160", INTEGRITY_ALGORITHM, AUTH_HMAC_SHA1_160, 0}, + {"aes256ctr", ENCRYPTION_ALGORITHM, ENCR_AES_CTR, 256}, + {"blowfish256", ENCRYPTION_ALGORITHM, ENCR_BLOWFISH, 256}, + {"sha2_256", INTEGRITY_ALGORITHM, AUTH_HMAC_SHA2_256_128, 0}, + {"sha256_96", INTEGRITY_ALGORITHM, AUTH_HMAC_SHA2_256_96, 0}, + {"aes256gcm64", ENCRYPTION_ALGORITHM, ENCR_AES_GCM_ICV8, 256}, + {"sha2_256_96", INTEGRITY_ALGORITHM, AUTH_HMAC_SHA2_256_96, 0}, + {"ecp224", DIFFIE_HELLMAN_GROUP, ECP_224_BIT, 0}, + {"ecp384", DIFFIE_HELLMAN_GROUP, ECP_384_BIT, 0}, + {"modp6144", DIFFIE_HELLMAN_GROUP, MODP_6144_BIT, 0}, + {"modp2048s224", DIFFIE_HELLMAN_GROUP, MODP_2048_224, 0}, + {"sha2_384", INTEGRITY_ALGORITHM, AUTH_HMAC_SHA2_384_192, 0} + }; + +static const short lookup[] = + { + -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, + 1, 2, -1, -1, -1, -1, 3, 4, -1, -1, + -1, 5, 6, -1, -1, 7, -1, 8, 9, 10, + 11, 12, -1, 13, -1, 14, 15, 16, 17, 18, + 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, + -1, -1, -1, -1, 29, 30, 31, 32, 33, 34, + 35, -1, 36, -1, 37, 38, 39, 40, 41, 42, + 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, + 53, 54, 55, 56, 57, -1, 58, -1, 59, -1, + 60, -1, 61, 62, 63, 64, 65, 66, 67, 68, + 69, 70, 71, 72, 73, 74, -1, 75, -1, 76, + -1, 77, -1, 78, 79, 80, 81, 82, -1, 83, + 84, 85, 86, 87, -1, 88, 89, -1, 90, -1, + -1, 91, 92, -1, 93, -1, -1, 94, -1, 95, + 96, 97, 98, -1, 99, -1, 100, 101, 102, 103, + 104, 105, -1, -1, -1, 106, -1, -1, 107, 108, + -1, 109, -1, -1, 110, 111, 112, -1, -1, 113, + 114, -1, -1, -1, 115, 116, -1, 117, 118, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 119, -1, -1, -1, 120, + -1, -1, -1, 121 + }; + +#ifdef __GNUC__ +__inline +#ifdef __GNUC_STDC_INLINE__ +__attribute__ ((__gnu_inline__)) +#endif +#endif +const struct proposal_token * +proposal_get_token_static (str, len) + register const char *str; + register unsigned int len; +{ + if (len <= MAX_WORD_LENGTH && len >= MIN_WORD_LENGTH) + { + register int key = hash (str, len); + + if (key <= MAX_HASH_VALUE && key >= 0) + { + register int index = lookup[key]; + + if (index >= 0) + { + register const char *s = wordlist[index].name; + + if (*str == *s && !strncmp (str + 1, s + 1, len - 1) && s[len] == '\0') + return &wordlist[index]; + } + } + } + return 0; +} diff --git a/src/libstrongswan/crypto/proposal/proposal_keywords_static.h b/src/libstrongswan/crypto/proposal/proposal_keywords_static.h new file mode 100644 index 000000000..bc421dcc5 --- /dev/null +++ b/src/libstrongswan/crypto/proposal/proposal_keywords_static.h @@ -0,0 +1,25 @@ +/* + * Copyright (C) 2009 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. + */ + +#ifndef PROPOSAL_KEYWORDS_STATIC_H_ +#define PROPOSAL_KEYWORDS_STATIC_H_ + +#include "proposal_keywords.h" + +const proposal_token_t* proposal_get_token_static(register const char *str, + register unsigned int len); + +#endif /* PROPOSAL_KEYWORDS_STATIC_H_ */ + diff --git a/src/libstrongswan/crypto/proposal/proposal_keywords.txt b/src/libstrongswan/crypto/proposal/proposal_keywords_static.txt index 1d04f2dc4..7f8c95757 100644 --- a/src/libstrongswan/crypto/proposal/proposal_keywords.txt +++ b/src/libstrongswan/crypto/proposal/proposal_keywords_static.txt @@ -1,5 +1,5 @@ %{ -/* proposal keywords +/* * Copyright (C) 2009 Andreas Steffen * Hochschule fuer Technik Rapperswil, Switzerland * @@ -23,10 +23,10 @@ %} struct proposal_token { - char *name; - transform_type_t type; + char *name; + transform_type_t type; u_int16_t algorithm; - u_int16_t keysize; + u_int16_t keysize; }; %% null, ENCRYPTION_ALGORITHM, ENCR_NULL, 0 diff --git a/src/libstrongswan/crypto/rngs/rng.c b/src/libstrongswan/crypto/rngs/rng.c index 67fd76910..f8fd50d3f 100644 --- a/src/libstrongswan/crypto/rngs/rng.c +++ b/src/libstrongswan/crypto/rngs/rng.c @@ -1,4 +1,5 @@ /* + * Copyright (C) 2012 Tobias Brunner * Copyright (C) 2008 Martin Willi * Hochschule fuer Technik Rapperswil * @@ -20,3 +21,43 @@ ENUM(rng_quality_names, RNG_WEAK, RNG_TRUE, "RNG_STRONG", "RNG_TRUE", ); + +/* + * Described in header. + */ +bool rng_get_bytes_not_zero(rng_t *rng, size_t len, u_int8_t *buffer, bool all) +{ + u_int8_t *pos = buffer, *check = buffer + (all ? len : min(1, len)); + + if (!rng->get_bytes(rng, len, pos)) + { + return FALSE; + } + + for (; pos < check; pos++) + { + while (*pos == 0) + { + if (!rng->get_bytes(rng, 1, pos)) + { + return FALSE; + } + } + } + return TRUE; +} + +/* + * Described in header. + */ +bool rng_allocate_bytes_not_zero(rng_t *rng, size_t len, chunk_t *chunk, + bool all) +{ + *chunk = chunk_alloc(len); + if (!rng_get_bytes_not_zero(rng, len, chunk->ptr, all)) + { + chunk_clear(chunk); + return FALSE; + } + return TRUE; +} diff --git a/src/libstrongswan/crypto/rngs/rng.h b/src/libstrongswan/crypto/rngs/rng.h index 36ef52bb4..aee829d71 100644 --- a/src/libstrongswan/crypto/rngs/rng.h +++ b/src/libstrongswan/crypto/rngs/rng.h @@ -1,4 +1,5 @@ /* + * Copyright (C) 2012 Tobias Brunner * Copyright (C) 2008 Martin Willi * Hochschule fuer Technik Rapperswil * @@ -53,21 +54,53 @@ struct rng_t { * * @param len number of bytes to get * @param buffer pointer where the generated bytes will be written + * @return TRUE if bytes successfully written */ - void (*get_bytes) (rng_t *this, size_t len, u_int8_t *buffer); + bool (*get_bytes)(rng_t *this, size_t len, + u_int8_t *buffer) __attribute__((warn_unused_result)); /** * Generates random bytes and allocate space for them. * * @param len number of bytes to get * @param chunk chunk which will hold generated bytes + * @return TRUE if allocation succeeded */ - void (*allocate_bytes) (rng_t *this, size_t len, chunk_t *chunk); + bool (*allocate_bytes)(rng_t *this, size_t len, + chunk_t *chunk) __attribute__((warn_unused_result)); /** * Destroys a rng object. */ - void (*destroy) (rng_t *this); + void (*destroy)(rng_t *this); }; +/** + * Wrapper around rng_t.get_bytes() ensuring that either all bytes or at least + * the first byte is not zero. + * + * @param rng rng_t object + * @param len number of bytes to get + * @param buffer pointer where the generated bytes will be written + * @param all TRUE if all bytes have to be non-zero, FALSE for first + * @return TRUE if bytes successfully written + */ +bool rng_get_bytes_not_zero(rng_t *rng, size_t len, u_int8_t *buffer, + bool all) __attribute__((warn_unused_result)); + +/** + * Wrapper around rng_t.allocate_bytes() ensuring that either all bytes or at + * least the first byte is not zero. + * + * @param rng rng_t object + * @param len number of bytes to get + * @param chunk chunk that stores the generated bytes (allocated) + * @param all TRUE if all bytes have to be non-zero, FALSE for first + * @return TRUE if bytes successfully written + */ +bool rng_allocate_bytes_not_zero(rng_t *rng, size_t len, chunk_t *chunk, + bool all) __attribute__((warn_unused_result)); + + + #endif /** RNG_H_ @}*/ diff --git a/src/libstrongswan/crypto/signers/mac_signer.c b/src/libstrongswan/crypto/signers/mac_signer.c new file mode 100644 index 000000000..7c52aa305 --- /dev/null +++ b/src/libstrongswan/crypto/signers/mac_signer.c @@ -0,0 +1,139 @@ +/* + * Copyright (C) 2012 Tobias Brunner + * 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. + */ + +#include "mac_signer.h" + +typedef struct private_signer_t private_signer_t; + +/** + * Private data of a mac_signer_t object. + */ +struct private_signer_t { + + /** + * Public interface + */ + signer_t public; + + /** + * MAC to use + */ + mac_t *mac; + + /** + * Truncation of MAC output + */ + size_t truncation; +}; + +METHOD(signer_t, get_signature, bool, + private_signer_t *this, chunk_t data, u_int8_t *buffer) +{ + if (buffer) + { + u_int8_t mac[this->mac->get_mac_size(this->mac)]; + + if (!this->mac->get_mac(this->mac, data, mac)) + { + return FALSE; + } + memcpy(buffer, mac, this->truncation); + return TRUE; + } + return this->mac->get_mac(this->mac, data, NULL); +} + +METHOD(signer_t, allocate_signature, bool, + private_signer_t *this, chunk_t data, chunk_t *chunk) +{ + if (chunk) + { + u_int8_t mac[this->mac->get_mac_size(this->mac)]; + + if (!this->mac->get_mac(this->mac, data, mac)) + { + return FALSE; + } + *chunk = chunk_alloc(this->truncation); + memcpy(chunk->ptr, mac, this->truncation); + return TRUE; + } + return this->mac->get_mac(this->mac, data, NULL); +} + +METHOD(signer_t, verify_signature, bool, + private_signer_t *this, chunk_t data, chunk_t signature) +{ + u_int8_t mac[this->mac->get_mac_size(this->mac)]; + + if (signature.len != this->truncation) + { + return FALSE; + } + return this->mac->get_mac(this->mac, data, mac) && + memeq(signature.ptr, mac, this->truncation); +} + +METHOD(signer_t, get_key_size, size_t, + private_signer_t *this) +{ + return this->mac->get_mac_size(this->mac); +} + +METHOD(signer_t, get_block_size, size_t, + private_signer_t *this) +{ + return this->truncation; +} + +METHOD(signer_t, set_key, bool, + private_signer_t *this, chunk_t key) +{ + return this->mac->set_key(this->mac, key); +} + +METHOD(signer_t, destroy, void, + private_signer_t *this) +{ + this->mac->destroy(this->mac); + free(this); +} + +/* + * Described in header + */ +signer_t *mac_signer_create(mac_t *mac, size_t len) +{ + private_signer_t *this; + + INIT(this, + .public = { + .get_signature = _get_signature, + .allocate_signature = _allocate_signature, + .verify_signature = _verify_signature, + .get_block_size = _get_block_size, + .get_key_size = _get_key_size, + .set_key = _set_key, + .destroy = _destroy, + }, + .truncation = min(len, mac->get_mac_size(mac)), + .mac = mac, + ); + + return &this->public; +} + diff --git a/src/libstrongswan/plugins/cmac/cmac_signer.h b/src/libstrongswan/crypto/signers/mac_signer.h index 2e3724471..a50c8cadf 100644 --- a/src/libstrongswan/plugins/cmac/cmac_signer.h +++ b/src/libstrongswan/crypto/signers/mac_signer.h @@ -14,34 +14,28 @@ */ /** - * @defgroup cmac_signer cmac_signer - * @{ @ingroup cmac_p + * @defgroup mac_signer mac_signer + * @{ @ingroup crypto */ -#ifndef CMAC_SIGNER_H_ -#define CMAC_SIGNER_H_ +#ifndef MAC_SIGNER_H_ +#define MAC_SIGNER_H_ -typedef struct cmac_signer_t cmac_signer_t; +typedef struct mac_signer_t mac_signer_t; +#include <crypto/mac.h> #include <crypto/signers/signer.h> /** - * Implementation of signer_t on CBC symmetric cipher using CMAC, RFC 4494. - */ -struct cmac_signer_t { - - /** - * Implements signer_t interface. - */ - signer_t signer; -}; - -/** - * Creates a new cmac_signer_t. + * Creates an implementation of the signer_t interface using the provided mac_t + * implementation and truncation length. + * + * @note len will be set to mac_t.get_mac_size() if it is greater than that. * - * @param algo algorithm to implement - * @return cmac_signer_t, NULL if not supported + * @param mac mac_t implementation + * @param len length of resulting signature + * @return mac_signer_t */ -cmac_signer_t *cmac_signer_create(integrity_algorithm_t algo); +signer_t *mac_signer_create(mac_t *mac, size_t len); -#endif /** CMAC_SIGNER_H_ @}*/ +#endif /** MAC_SIGNER_H_ @}*/ diff --git a/src/libstrongswan/crypto/signers/signer.h b/src/libstrongswan/crypto/signers/signer.h index c6870e475..9b6bd479a 100644 --- a/src/libstrongswan/crypto/signers/signer.h +++ b/src/libstrongswan/crypto/signers/signer.h @@ -91,8 +91,10 @@ struct signer_t { * * @param data a chunk containing the data to sign * @param buffer pointer where the signature will be written + * @return TRUE if signature created successfully */ - void (*get_signature) (signer_t *this, chunk_t data, u_int8_t *buffer); + bool (*get_signature)(signer_t *this, chunk_t data, + u_int8_t *buffer) __attribute__((warn_unused_result)); /** * Generate a signature and allocate space for it. @@ -102,8 +104,10 @@ struct signer_t { * * @param data a chunk containing the data to sign * @param chunk chunk which will hold the allocated signature + * @return TRUE if signature allocated successfully */ - void (*allocate_signature) (signer_t *this, chunk_t data, chunk_t *chunk); + bool (*allocate_signature)(signer_t *this, chunk_t data, + chunk_t *chunk) __attribute__((warn_unused_result)); /** * Verify a signature. @@ -116,33 +120,35 @@ struct signer_t { * @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); + bool (*verify_signature)(signer_t *this, chunk_t data, chunk_t signature); /** * Get the block size of this signature algorithm. * * @return block size in bytes */ - size_t (*get_block_size) (signer_t *this); + size_t (*get_block_size)(signer_t *this); /** * Get the key size of the signature algorithm. * * @return key size in bytes */ - size_t (*get_key_size) (signer_t *this); + size_t (*get_key_size)(signer_t *this); /** * Set the key for this object. * * @param key key to set + * @return TRUE if key set */ - void (*set_key) (signer_t *this, chunk_t key); + bool (*set_key)(signer_t *this, + chunk_t key) __attribute__((warn_unused_result)); /** * Destroys a signer_t object. */ - void (*destroy) (signer_t *this); + void (*destroy)(signer_t *this); }; #endif /** SIGNER_H_ @}*/ diff --git a/src/libstrongswan/crypto/transform.c b/src/libstrongswan/crypto/transform.c index 1e108f1de..56252971a 100644 --- a/src/libstrongswan/crypto/transform.c +++ b/src/libstrongswan/crypto/transform.c @@ -15,12 +15,13 @@ #include <crypto/transform.h> -ENUM_BEGIN(transform_type_names, UNDEFINED_TRANSFORM_TYPE, AEAD_ALGORITHM, +ENUM_BEGIN(transform_type_names, UNDEFINED_TRANSFORM_TYPE, COMPRESSION_ALGORITHM, "UNDEFINED_TRANSFORM_TYPE", "HASH_ALGORITHM", "RANDOM_NUMBER_GENERATOR", - "AEAD_ALGORITHM"); -ENUM_NEXT(transform_type_names, ENCRYPTION_ALGORITHM, EXTENDED_SEQUENCE_NUMBERS, AEAD_ALGORITHM, + "AEAD_ALGORITHM", + "COMPRESSION_ALGORITHM"); +ENUM_NEXT(transform_type_names, ENCRYPTION_ALGORITHM, EXTENDED_SEQUENCE_NUMBERS, COMPRESSION_ALGORITHM, "ENCRYPTION_ALGORITHM", "PSEUDO_RANDOM_FUNCTION", "INTEGRITY_ALGORITHM", diff --git a/src/libstrongswan/crypto/transform.h b/src/libstrongswan/crypto/transform.h index 1393c674c..311df068f 100644 --- a/src/libstrongswan/crypto/transform.h +++ b/src/libstrongswan/crypto/transform.h @@ -23,7 +23,7 @@ typedef enum transform_type_t transform_type_t; -#include <library.h> +#include <enum.h> /** * Type of a transform, as in IKEv2 RFC 3.3.2. @@ -33,6 +33,7 @@ enum transform_type_t { HASH_ALGORITHM = 242, RANDOM_NUMBER_GENERATOR = 243, AEAD_ALGORITHM = 244, + COMPRESSION_ALGORITHM = 245, ENCRYPTION_ALGORITHM = 1, PSEUDO_RANDOM_FUNCTION = 2, INTEGRITY_ALGORITHM = 3, diff --git a/src/libstrongswan/debug.c b/src/libstrongswan/debug.c index d6c5b06b6..e8c9e6b98 100644 --- a/src/libstrongswan/debug.c +++ b/src/libstrongswan/debug.c @@ -33,6 +33,8 @@ ENUM(debug_names, DBG_DMN, DBG_LIB, "IMV", "PTS", "TLS", + "APP", + "ESP", "LIB", ); @@ -52,6 +54,8 @@ ENUM(debug_lower_names, DBG_DMN, DBG_LIB, "imv", "pts", "tls", + "app", + "esp", "lib", ); diff --git a/src/libstrongswan/debug.h b/src/libstrongswan/debug.h index 2a6ff98ad..ff4b4a1e9 100644 --- a/src/libstrongswan/debug.h +++ b/src/libstrongswan/debug.h @@ -62,6 +62,10 @@ enum debug_t { DBG_PTS, /** libtls */ DBG_TLS, + /** applications other than daemons */ + DBG_APP, + /** libipsec */ + DBG_ESP, /** libstrongswan */ DBG_LIB, /** number of groups */ diff --git a/src/libstrongswan/eap/eap.c b/src/libstrongswan/eap/eap.c index efd3ee981..1e4cf11bf 100644 --- a/src/libstrongswan/eap/eap.c +++ b/src/libstrongswan/eap/eap.c @@ -1,4 +1,5 @@ /* + * Copyright (C) 2012 Tobias Brunner * Copyright (C) 2006 Martin Willi * Hochschule fuer Technik Rapperswil * @@ -13,8 +14,13 @@ * for more details. */ +#include <stdlib.h> +#include <errno.h> + #include "eap.h" +#include <debug.h> + ENUM(eap_code_names, EAP_REQUEST, EAP_FAILURE, "EAP_REQUEST", "EAP_RESPONSE", @@ -51,12 +57,12 @@ ENUM_NEXT(eap_type_names, EAP_MSTLV, EAP_MSTLV, EAP_MSCHAPV2, "EAP_MSTLV"); ENUM_NEXT(eap_type_names, EAP_TNC, EAP_TNC, EAP_MSTLV, "EAP_TNC"); -ENUM_NEXT(eap_type_names, EAP_DYNAMIC, EAP_EXPERIMENTAL, EAP_TNC, - "EAP_DYNAMIC", - "EAP_RADIUS", +ENUM_NEXT(eap_type_names, EAP_EXPANDED, EAP_DYNAMIC, EAP_TNC, "EAP_EXPANDED", - "EAP_EXPERIMENTAL"); -ENUM_END(eap_type_names, EAP_EXPERIMENTAL); + "EAP_EXPERIMENTAL", + "EAP_RADIUS", + "EAP_DYNAMIC"); +ENUM_END(eap_type_names, EAP_DYNAMIC); ENUM_BEGIN(eap_type_short_names, EAP_IDENTITY, EAP_GTC, "ID", @@ -80,12 +86,12 @@ ENUM_NEXT(eap_type_short_names, EAP_MSTLV, EAP_MSTLV, EAP_MSCHAPV2, "MSTLV"); ENUM_NEXT(eap_type_short_names, EAP_TNC, EAP_TNC, EAP_MSTLV, "TNC"); -ENUM_NEXT(eap_type_short_names, EAP_DYNAMIC, EAP_EXPERIMENTAL, EAP_TNC, - "DYN", - "RAD", +ENUM_NEXT(eap_type_short_names, EAP_EXPANDED, EAP_DYNAMIC, EAP_TNC, "EXP", - "XP"); -ENUM_END(eap_type_short_names, EAP_EXPERIMENTAL); + "XP", + "RAD", + "DYN"); +ENUM_END(eap_type_short_names, EAP_DYNAMIC); /* * See header @@ -108,6 +114,7 @@ eap_type_t eap_type_from_string(char *name) {"peap", EAP_PEAP}, {"mschapv2", EAP_MSCHAPV2}, {"tnc", EAP_TNC}, + {"dynamic", EAP_DYNAMIC}, {"radius", EAP_RADIUS}, }; @@ -120,3 +127,56 @@ eap_type_t eap_type_from_string(char *name) } return 0; } + +/* + * See header + */ +eap_vendor_type_t *eap_vendor_type_from_string(char *str) +{ + enumerator_t *enumerator; + eap_vendor_type_t *result = NULL; + eap_type_t type = 0; + u_int32_t vendor = 0; + char *part, *end; + + /* parse EAP method string of the form: [eap-]type[-vendor] */ + enumerator = enumerator_create_token(str, "-", " "); + while (enumerator->enumerate(enumerator, &part)) + { + if (!type) + { + if (streq(part, "eap")) + { /* skip 'eap' at the beginning */ + continue; + } + type = eap_type_from_string(part); + if (!type) + { + type = strtoul(part, &end, 0); + if (*end != '\0' || errno) + { + DBG1(DBG_LIB, "unknown or invalid EAP method: %s", part); + break; + } + } + continue; + } + vendor = strtoul(part, &end, 0); + if (*end != '\0' || errno) + { + DBG1(DBG_LIB, "invalid EAP vendor: %s", part); + type = 0; + } + break; + } + enumerator->destroy(enumerator); + + if (type) + { + INIT(result, + .type = type, + .vendor = vendor, + ); + } + return result; +} diff --git a/src/libstrongswan/eap/eap.h b/src/libstrongswan/eap/eap.h index 945e4bc59..0e144b123 100644 --- a/src/libstrongswan/eap/eap.h +++ b/src/libstrongswan/eap/eap.h @@ -1,6 +1,8 @@ /* + * Copyright (C) 2012 Tobias Brunner * Copyright (C) 2010 Martin Willi * Copyright (C) 2010 revosec AG + * Hochschule fuer Technik Rapperswil * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the @@ -14,7 +16,7 @@ */ /** - * @defgroup eap eap + * @defgroup leap eap * @{ @ingroup libstrongswan */ @@ -23,6 +25,7 @@ typedef enum eap_code_t eap_code_t; typedef enum eap_type_t eap_type_t; +typedef struct eap_vendor_type_t eap_vendor_type_t; #include <library.h> @@ -62,14 +65,14 @@ enum eap_type_t { EAP_AKA = 23, EAP_PEAP = 25, EAP_MSCHAPV2 = 26, - EAP_MSTLV = 33, + EAP_MSTLV = 33, EAP_TNC = 38, - /** select EAP method dynamically based on i.e. EAP-Identity */ - EAP_DYNAMIC = 252, - /** not a method, but an implementation providing different methods */ - EAP_RADIUS = 253, EAP_EXPANDED = 254, EAP_EXPERIMENTAL = 255, + /** not a method, but an implementation providing different methods */ + EAP_RADIUS = 256, + /** not a method, select method dynamically based on client selection */ + EAP_DYNAMIC = 257, }; /** @@ -83,6 +86,22 @@ extern enum_name_t *eap_type_names; extern enum_name_t *eap_type_short_names; /** + * Struct that stores EAP type and vendor ID + */ +struct eap_vendor_type_t { + + /** + * EAP type + */ + eap_type_t type; + + /** + * Vendor Id + */ + u_int32_t vendor; +}; + +/** * EAP packet format */ typedef struct __attribute__((packed)) { @@ -101,4 +120,12 @@ typedef struct __attribute__((packed)) { */ eap_type_t eap_type_from_string(char *name); +/** + * Parse a string of the form [eap-]type[-vendor]. + * + * @param str EAP method string + * @return parsed type (gets allocated), NULL if unknown or failed + */ +eap_vendor_type_t *eap_vendor_type_from_string(char *str); + #endif /** EAP_H_ @}*/ diff --git a/src/libstrongswan/enum.c b/src/libstrongswan/enum.c index 5c811bd17..2dc7c5dde 100644 --- a/src/libstrongswan/enum.c +++ b/src/libstrongswan/enum.c @@ -60,7 +60,7 @@ int enum_from_name(enum_name_t *e, char *name) /** * Described in header. */ -int enum_printf_hook(char *dst, size_t len, printf_hook_spec_t *spec, +int enum_printf_hook(printf_hook_data_t *data, printf_hook_spec_t *spec, const void *const *args) { enum_name_t *ed = *((enum_name_t**)(args[0])); @@ -70,10 +70,10 @@ int enum_printf_hook(char *dst, size_t len, printf_hook_spec_t *spec, if (name == NULL) { - return print_in_hook(dst, len, "(%d)", val); + return print_in_hook(data, "(%d)", val); } else { - return print_in_hook(dst, len, "%s", name); + return print_in_hook(data, "%s", name); } } diff --git a/src/libstrongswan/enum.h b/src/libstrongswan/enum.h index d5f169772..840371245 100644 --- a/src/libstrongswan/enum.h +++ b/src/libstrongswan/enum.h @@ -130,7 +130,7 @@ int enum_from_name(enum_name_t *e, char *name); * Arguments are: * enum_names_t *names, int value */ -int enum_printf_hook(char *dst, size_t len, printf_hook_spec_t *spec, +int enum_printf_hook(printf_hook_data_t *data, printf_hook_spec_t *spec, const void *const *args); #endif /** ENUM_H_ @}*/ diff --git a/src/libstrongswan/ipsec/ipsec_types.c b/src/libstrongswan/ipsec/ipsec_types.c new file mode 100644 index 000000000..e4e927313 --- /dev/null +++ b/src/libstrongswan/ipsec/ipsec_types.c @@ -0,0 +1,38 @@ +/* + * Copyright (C) 2012 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. + */ + +#include "ipsec_types.h" + +ENUM(ipsec_mode_names, MODE_TRANSPORT, MODE_DROP, + "TRANSPORT", + "TUNNEL", + "BEET", + "PASS", + "DROP" +); + +ENUM(policy_dir_names, POLICY_IN, POLICY_FWD, + "in", + "out", + "fwd" +); + +ENUM(ipcomp_transform_names, IPCOMP_NONE, IPCOMP_LZJH, + "IPCOMP_NONE", + "IPCOMP_OUI", + "IPCOMP_DEFLATE", + "IPCOMP_LZS", + "IPCOMP_LZJH" +); diff --git a/src/libstrongswan/ipsec/ipsec_types.h b/src/libstrongswan/ipsec/ipsec_types.h new file mode 100644 index 000000000..32e55bc50 --- /dev/null +++ b/src/libstrongswan/ipsec/ipsec_types.h @@ -0,0 +1,172 @@ +/* + * Copyright (C) 2012 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. + */ + +/** + * @defgroup ipsec_types ipsec_types + * @{ @ingroup ipsec + */ + +#ifndef IPSEC_TYPES_H_ +#define IPSEC_TYPES_H_ + +typedef enum ipsec_mode_t ipsec_mode_t; +typedef enum policy_dir_t policy_dir_t; +typedef enum policy_type_t policy_type_t; +typedef enum policy_priority_t policy_priority_t; +typedef enum ipcomp_transform_t ipcomp_transform_t; +typedef struct ipsec_sa_cfg_t ipsec_sa_cfg_t; +typedef struct lifetime_cfg_t lifetime_cfg_t; +typedef struct mark_t mark_t; + +#include <library.h> + +/** + * Mode of an IPsec SA. + */ +enum ipsec_mode_t { + /** not using any encapsulation */ + MODE_NONE = 0, + /** transport mode, no inner address */ + MODE_TRANSPORT = 1, + /** tunnel mode, inner and outer addresses */ + MODE_TUNNEL, + /** BEET mode, tunnel mode but fixed, bound inner addresses */ + MODE_BEET, + /** passthrough policy for traffic without an IPsec SA */ + MODE_PASS, + /** drop policy discarding traffic */ + MODE_DROP +}; + +/** + * enum names for ipsec_mode_t. + */ +extern enum_name_t *ipsec_mode_names; + +/** + * Direction of a policy. These are equal to those + * defined in xfrm.h, but we want to stay implementation + * neutral here. + */ +enum policy_dir_t { + /** Policy for inbound traffic */ + POLICY_IN = 0, + /** Policy for outbound traffic */ + POLICY_OUT = 1, + /** Policy for forwarded traffic */ + POLICY_FWD = 2, +}; + +/** + * enum names for policy_dir_t. + */ +extern enum_name_t *policy_dir_names; + +/** + * Type of a policy. + */ +enum policy_type_t { + /** Normal IPsec policy */ + POLICY_IPSEC = 1, + /** Passthrough policy (traffic is ignored by IPsec) */ + POLICY_PASS, + /** Drop policy (traffic is discarded) */ + POLICY_DROP, +}; + +/** + * High-level priority of a policy. + */ +enum policy_priority_t { + /** Default priority */ + POLICY_PRIORITY_DEFAULT, + /** Priority for trap policies */ + POLICY_PRIORITY_ROUTED, + /** Priority for fallback drop policies */ + POLICY_PRIORITY_FALLBACK, +}; + +/** + * IPComp transform IDs, as in RFC 4306 + */ +enum ipcomp_transform_t { + IPCOMP_NONE = 0, + IPCOMP_OUI = 1, + IPCOMP_DEFLATE = 2, + IPCOMP_LZS = 3, + IPCOMP_LZJH = 4, +}; + +/** + * enum strings for ipcomp_transform_t. + */ +extern enum_name_t *ipcomp_transform_names; + +/** + * This struct contains details about IPsec SA(s) tied to a policy. + */ +struct ipsec_sa_cfg_t { + /** mode of SA (tunnel, transport) */ + ipsec_mode_t mode; + /** unique ID */ + u_int32_t reqid; + /** details about ESP/AH */ + struct { + /** TRUE if this protocol is used */ + bool use; + /** SPI for ESP/AH */ + u_int32_t spi; + } esp, ah; + /** details about IPComp */ + struct { + /** the IPComp transform used */ + u_int16_t transform; + /** CPI for IPComp */ + u_int16_t cpi; + } ipcomp; +}; + +/** + * A lifetime_cfg_t defines the lifetime limits of an SA. + * + * Set any of these values to 0 to ignore. + */ +struct lifetime_cfg_t { + struct { + /** Limit before the SA gets invalid. */ + u_int64_t life; + /** Limit before the SA gets rekeyed. */ + u_int64_t rekey; + /** The range of a random value subtracted from rekey. */ + u_int64_t jitter; + } time, bytes, packets; +}; + +/** + * A mark_t defines an optional mark in an IPsec SA. + */ +struct mark_t { + /** Mark value */ + u_int32_t value; + /** Mark mask */ + u_int32_t mask; +}; + +/** + * Special mark value that uses the reqid of the CHILD_SA as mark + */ +#define MARK_REQID (0xFFFFFFFF) + +#endif /** IPSEC_TYPES_H_ @}*/ diff --git a/src/libstrongswan/library.c b/src/libstrongswan/library.c index cd6a41f44..1179b468c 100644 --- a/src/libstrongswan/library.c +++ b/src/libstrongswan/library.c @@ -23,6 +23,7 @@ #include <utils/identification.h> #include <utils/host.h> #include <utils/hashtable.h> +#include <utils/backtrace.h> #include <selectors/traffic_selector.h> #define CHECKSUM_LIBRARY IPSEC_LIB_DIR"/libchecksum.so" @@ -72,6 +73,7 @@ void library_deinit() this->public.creds->destroy(this->public.creds); this->public.encoding->destroy(this->public.encoding); this->public.crypto->destroy(this->public.crypto); + this->public.proposal->destroy(this->public.proposal); this->public.fetcher->destroy(this->public.fetcher); this->public.db->destroy(this->public.db); this->public.printf_hook->destroy(this->public.printf_hook); @@ -88,6 +90,7 @@ void library_deinit() } threads_deinit(); + backtrace_deinit(); free(this); lib = NULL; @@ -146,6 +149,7 @@ bool library_init(char *settings) ); lib = &this->public; + backtrace_init(); threads_init(); #ifdef LEAK_DETECTIVE @@ -179,6 +183,7 @@ bool library_init(char *settings) this->objects = hashtable_create((hashtable_hash_t)hash, (hashtable_equals_t)equals, 4); this->public.settings = settings_create(settings); + this->public.proposal = proposal_keywords_create(); this->public.crypto = crypto_factory_create(); this->public.creds = credential_factory_create(); this->public.credmgr = credential_manager_create(); @@ -204,6 +209,7 @@ bool library_init(char *settings) return FALSE; #endif /* INTEGRITY_TEST */ } + return TRUE; } diff --git a/src/libstrongswan/library.h b/src/libstrongswan/library.h index 7e76e1927..b79bd91be 100644 --- a/src/libstrongswan/library.h +++ b/src/libstrongswan/library.h @@ -43,6 +43,9 @@ * @defgroup fetcher fetcher * @ingroup libstrongswan * + * @defgroup ipsec ipsec + * @ingroup libstrongswan + * * @defgroup plugins plugins * @ingroup libstrongswan * @@ -67,6 +70,10 @@ #ifndef LIBRARY_H_ #define LIBRARY_H_ +#ifndef CONFIG_H_INCLUDED +# error config.h not included, pass "-include [...]/config.h" to gcc +#endif + #include "printf_hook.h" #include "utils.h" #include "chunk.h" @@ -75,6 +82,7 @@ #include "processing/processor.h" #include "processing/scheduler.h" #include "crypto/crypto_factory.h" +#include "crypto/proposal/proposal_keywords.h" #include "fetcher/fetcher_manager.h" #include "database/database_factory.h" #include "credentials/credential_factory.h" @@ -113,6 +121,11 @@ struct library_t { printf_hook_t *printf_hook; /** + * Proposal keywords registry + */ + proposal_keywords_t *proposal; + + /** * crypto algorithm registry and factory */ crypto_factory_t *crypto; diff --git a/src/libstrongswan/pen/pen.c b/src/libstrongswan/pen/pen.c index 3dd92218d..a80e949e3 100644 --- a/src/libstrongswan/pen/pen.c +++ b/src/libstrongswan/pen/pen.c @@ -17,7 +17,9 @@ ENUM_BEGIN(pen_names, PEN_IETF, PEN_IETF, "IETF"); -ENUM_NEXT(pen_names, PEN_MICROSOFT, PEN_MICROSOFT, PEN_IETF, +ENUM_NEXT(pen_names, PEN_IBM, PEN_IBM, PEN_IETF, + "IBM"); +ENUM_NEXT(pen_names, PEN_MICROSOFT, PEN_MICROSOFT, PEN_IBM, "Microsoft"); ENUM_NEXT(pen_names, PEN_OSC, PEN_OSC, PEN_MICROSOFT, "OSC"); @@ -27,7 +29,9 @@ ENUM_NEXT(pen_names, PEN_FHH, PEN_FHH, PEN_TCG, "FHH"); ENUM_NEXT(pen_names, PEN_ITA, PEN_ITA, PEN_FHH, "ITA-HSR"); -ENUM_NEXT(pen_names, PEN_RESERVED, PEN_RESERVED, PEN_ITA, +ENUM_NEXT(pen_names, PEN_OPENPTS, PEN_OPENPTS, PEN_ITA, + "OpenPTS"); +ENUM_NEXT(pen_names, PEN_RESERVED, PEN_RESERVED, PEN_OPENPTS, "Reserved"); ENUM_END(pen_names, PEN_RESERVED); diff --git a/src/libstrongswan/pen/pen.h b/src/libstrongswan/pen/pen.h index 396cc7199..78b6e4df2 100644 --- a/src/libstrongswan/pen/pen.h +++ b/src/libstrongswan/pen/pen.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2011 Andreas Steffen + * Copyright (C) 2011-2012 Andreas Steffen * HSR Hochschule fuer Technik Rapperswil * * This program is free software; you can redistribute it and/or modify it @@ -27,18 +27,38 @@ #include <library.h> typedef enum pen_t pen_t; +typedef struct pen_type_t pen_type_t; enum pen_t { PEN_IETF = 0x000000, /* 0 */ + PEN_IBM = 0x000002, /* 2 */ PEN_MICROSOFT = 0x000137, /* 311 */ PEN_OSC = 0x002358, /* 9048 */ PEN_TCG = 0x005597, /* 21911 */ PEN_FHH = 0x0080ab, /* 32939 */ PEN_ITA = 0x00902a, /* 36906 */ + PEN_OPENPTS = 0x00950e, /* 38158 */ PEN_RESERVED = 0xffffff, /* 16777215 */ }; /** + * Vendor specific type + */ +struct pen_type_t { + pen_t vendor_id; + u_int32_t type; +}; + +/** + * Create a pen_type_t struct + */ +static inline pen_type_t pen_type_create(pen_t vendor_id, u_int32_t type) +{ + pen_type_t pen_type = {vendor_id, type}; + return pen_type; +} + +/** * enum names for pen_t. */ extern enum_name_t *pen_names; diff --git a/src/libstrongswan/plugins/aes/Makefile.in b/src/libstrongswan/plugins/aes/Makefile.in index 53eecbe8d..c09cf66a7 100644 --- a/src/libstrongswan/plugins/aes/Makefile.in +++ b/src/libstrongswan/plugins/aes/Makefile.in @@ -49,6 +49,7 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/config/libtool.m4 \ am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; @@ -82,7 +83,7 @@ libstrongswan_aes_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \ $(libstrongswan_aes_la_LDFLAGS) $(LDFLAGS) -o $@ @MONOLITHIC_FALSE@am_libstrongswan_aes_la_rpath = -rpath $(plugindir) @MONOLITHIC_TRUE@am_libstrongswan_aes_la_rpath = -DEFAULT_INCLUDES = -I.@am__isrc@ +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles am__mv = mv -f @@ -108,6 +109,7 @@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ +BFDLIB = @BFDLIB@ BTLIB = @BTLIB@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ @@ -202,11 +204,14 @@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ c_plugins = @c_plugins@ +charon_natt_port = @charon_natt_port@ +charon_plugins = @charon_plugins@ +charon_udp_port = @charon_udp_port@ clearsilver_LIBS = @clearsilver_LIBS@ datadir = @datadir@ datarootdir = @datarootdir@ dbusservicedir = @dbusservicedir@ -default_pkcs11 = @default_pkcs11@ +dev_headers = @dev_headers@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ @@ -223,11 +228,12 @@ imcvdir = @imcvdir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ +ipsec_script = @ipsec_script@ +ipsec_script_upper = @ipsec_script_upper@ ipsecdir = @ipsecdir@ ipsecgroup = @ipsecgroup@ ipseclibdir = @ipseclibdir@ ipsecuser = @ipsecuser@ -libcharon_plugins = @libcharon_plugins@ libdir = @libdir@ libexecdir = @libexecdir@ linux_headers = @linux_headers@ @@ -243,6 +249,7 @@ mkdir_p = @mkdir_p@ nm_CFLAGS = @nm_CFLAGS@ nm_LIBS = @nm_LIBS@ nm_ca_dir = @nm_ca_dir@ +nm_plugins = @nm_plugins@ oldincludedir = @oldincludedir@ openac_plugins = @openac_plugins@ p_plugins = @p_plugins@ @@ -252,7 +259,6 @@ pdfdir = @pdfdir@ piddir = @piddir@ pki_plugins = @pki_plugins@ plugindir = @plugindir@ -pluto_plugins = @pluto_plugins@ pool_plugins = @pool_plugins@ prefix = @prefix@ program_transform_name = @program_transform_name@ diff --git a/src/libstrongswan/plugins/aes/aes_crypter.c b/src/libstrongswan/plugins/aes/aes_crypter.c index 2a1fed944..6b3d03cea 100644 --- a/src/libstrongswan/plugins/aes/aes_crypter.c +++ b/src/libstrongswan/plugins/aes/aes_crypter.c @@ -1331,7 +1331,7 @@ static void decrypt_block(const private_aes_crypter_t *this, const unsigned char state_out(out_blk, b0); } -METHOD(crypter_t, decrypt, void, +METHOD(crypter_t, decrypt, bool, private_aes_crypter_t *this, chunk_t data, chunk_t iv, chunk_t *decrypted) { int pos; @@ -1371,9 +1371,10 @@ METHOD(crypter_t, decrypt, void, out-=16; pos-=16; } + return TRUE; } -METHOD(crypter_t, encrypt, void, +METHOD(crypter_t, encrypt, bool, private_aes_crypter_t *this, chunk_t data, chunk_t iv, chunk_t *encrypted) { int pos; @@ -1408,6 +1409,7 @@ METHOD(crypter_t, encrypt, void, out+=16; pos+=16; } + return TRUE; } METHOD(crypter_t, get_block_size, size_t, @@ -1428,7 +1430,7 @@ METHOD(crypter_t, get_key_size, size_t, return this->key_size; } -METHOD(crypter_t, set_key, void, +METHOD(crypter_t, set_key, bool, private_aes_crypter_t *this, chunk_t key) { u_int32_t *kf, *kt, rci, f = 0; @@ -1513,6 +1515,7 @@ METHOD(crypter_t, set_key, void, } cpy(kt, kf); } + return TRUE; } METHOD(crypter_t, destroy, void, diff --git a/src/libstrongswan/plugins/af_alg/Makefile.in b/src/libstrongswan/plugins/af_alg/Makefile.in index 679e883e1..d3da24718 100644 --- a/src/libstrongswan/plugins/af_alg/Makefile.in +++ b/src/libstrongswan/plugins/af_alg/Makefile.in @@ -49,6 +49,7 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/config/libtool.m4 \ am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; @@ -86,7 +87,7 @@ libstrongswan_af_alg_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \ @MONOLITHIC_FALSE@am_libstrongswan_af_alg_la_rpath = -rpath \ @MONOLITHIC_FALSE@ $(plugindir) @MONOLITHIC_TRUE@am_libstrongswan_af_alg_la_rpath = -DEFAULT_INCLUDES = -I.@am__isrc@ +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles am__mv = mv -f @@ -112,6 +113,7 @@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ +BFDLIB = @BFDLIB@ BTLIB = @BTLIB@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ @@ -206,11 +208,14 @@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ c_plugins = @c_plugins@ +charon_natt_port = @charon_natt_port@ +charon_plugins = @charon_plugins@ +charon_udp_port = @charon_udp_port@ clearsilver_LIBS = @clearsilver_LIBS@ datadir = @datadir@ datarootdir = @datarootdir@ dbusservicedir = @dbusservicedir@ -default_pkcs11 = @default_pkcs11@ +dev_headers = @dev_headers@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ @@ -227,11 +232,12 @@ imcvdir = @imcvdir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ +ipsec_script = @ipsec_script@ +ipsec_script_upper = @ipsec_script_upper@ ipsecdir = @ipsecdir@ ipsecgroup = @ipsecgroup@ ipseclibdir = @ipseclibdir@ ipsecuser = @ipsecuser@ -libcharon_plugins = @libcharon_plugins@ libdir = @libdir@ libexecdir = @libexecdir@ linux_headers = @linux_headers@ @@ -247,6 +253,7 @@ mkdir_p = @mkdir_p@ nm_CFLAGS = @nm_CFLAGS@ nm_LIBS = @nm_LIBS@ nm_ca_dir = @nm_ca_dir@ +nm_plugins = @nm_plugins@ oldincludedir = @oldincludedir@ openac_plugins = @openac_plugins@ p_plugins = @p_plugins@ @@ -256,7 +263,6 @@ pdfdir = @pdfdir@ piddir = @piddir@ pki_plugins = @pki_plugins@ plugindir = @plugindir@ -pluto_plugins = @pluto_plugins@ pool_plugins = @pool_plugins@ prefix = @prefix@ program_transform_name = @program_transform_name@ diff --git a/src/libstrongswan/plugins/af_alg/af_alg_crypter.c b/src/libstrongswan/plugins/af_alg/af_alg_crypter.c index 9c547140d..5d0976d95 100644 --- a/src/libstrongswan/plugins/af_alg/af_alg_crypter.c +++ b/src/libstrongswan/plugins/af_alg/af_alg_crypter.c @@ -131,32 +131,26 @@ static size_t lookup_alg(encryption_algorithm_t algo, char **name, return 0; } -METHOD(crypter_t, decrypt, void, +METHOD(crypter_t, decrypt, bool, private_af_alg_crypter_t *this, chunk_t data, chunk_t iv, chunk_t *dst) { if (dst) { *dst = chunk_alloc(data.len); - this->ops->crypt(this->ops, ALG_OP_DECRYPT, iv, data, dst->ptr); - } - else - { - this->ops->crypt(this->ops, ALG_OP_DECRYPT, iv, data, data.ptr); + return this->ops->crypt(this->ops, ALG_OP_DECRYPT, iv, data, dst->ptr); } + return this->ops->crypt(this->ops, ALG_OP_DECRYPT, iv, data, data.ptr); } -METHOD(crypter_t, encrypt, void, +METHOD(crypter_t, encrypt, bool, private_af_alg_crypter_t *this, chunk_t data, chunk_t iv, chunk_t *dst) { if (dst) { *dst = chunk_alloc(data.len); - this->ops->crypt(this->ops, ALG_OP_ENCRYPT, iv, data, dst->ptr); - } - else - { - this->ops->crypt(this->ops, ALG_OP_ENCRYPT, iv, data, data.ptr); + return this->ops->crypt(this->ops, ALG_OP_ENCRYPT, iv, data, dst->ptr); } + return this->ops->crypt(this->ops, ALG_OP_ENCRYPT, iv, data, data.ptr); } METHOD(crypter_t, get_block_size, size_t, @@ -177,10 +171,10 @@ METHOD(crypter_t, get_key_size, size_t, return this->keymat_size; } -METHOD(crypter_t, set_key, void, +METHOD(crypter_t, set_key, bool, private_af_alg_crypter_t *this, chunk_t key) { - this->ops->set_key(this->ops, key); + return this->ops->set_key(this->ops, key); } METHOD(crypter_t, destroy, void, diff --git a/src/libstrongswan/plugins/af_alg/af_alg_hasher.c b/src/libstrongswan/plugins/af_alg/af_alg_hasher.c index ef2350497..47a6e5e0e 100644 --- a/src/libstrongswan/plugins/af_alg/af_alg_hasher.c +++ b/src/libstrongswan/plugins/af_alg/af_alg_hasher.c @@ -99,30 +99,28 @@ METHOD(hasher_t, get_hash_size, size_t, return this->size; } -METHOD(hasher_t, reset, void, +METHOD(hasher_t, reset, bool, private_af_alg_hasher_t *this) { this->ops->reset(this->ops); + return TRUE; } -METHOD(hasher_t, get_hash, void, +METHOD(hasher_t, get_hash, bool, private_af_alg_hasher_t *this, chunk_t chunk, u_int8_t *hash) { - this->ops->hash(this->ops, chunk, hash, this->size); + return this->ops->hash(this->ops, chunk, hash, this->size); } -METHOD(hasher_t, allocate_hash, void, +METHOD(hasher_t, allocate_hash, bool, private_af_alg_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); + return get_hash(this, chunk, hash->ptr); } + return get_hash(this, chunk, NULL); } METHOD(hasher_t, destroy, void, diff --git a/src/libstrongswan/plugins/af_alg/af_alg_ops.c b/src/libstrongswan/plugins/af_alg/af_alg_ops.c index a7b5de264..7fe47c578 100644 --- a/src/libstrongswan/plugins/af_alg/af_alg_ops.c +++ b/src/libstrongswan/plugins/af_alg/af_alg_ops.c @@ -54,7 +54,7 @@ METHOD(af_alg_ops_t, reset, void, } } -METHOD(af_alg_ops_t, hash, void, +METHOD(af_alg_ops_t, hash, bool, private_af_alg_ops_t *this, chunk_t data, char *out, size_t outlen) { ssize_t len; @@ -62,39 +62,52 @@ METHOD(af_alg_ops_t, hash, void, while (this->op == -1) { this->op = accept(this->tfm, NULL, 0); - if (this->op == -1) + if (this->op == -1 && errno != EINTR) { DBG1(DBG_LIB, "opening AF_ALG hasher failed: %s", strerror(errno)); - sleep(1); + return FALSE; } } + do { len = send(this->op, data.ptr, data.len, out ? 0 : MSG_MORE); if (len == -1) { + if (errno == EINTR) + { + continue; + } DBG1(DBG_LIB, "writing to AF_ALG hasher failed: %s", strerror(errno)); - sleep(1); - } - else - { - data = chunk_skip(data, len); + return FALSE; } + data = chunk_skip(data, len); } while (data.len); if (out) { - while (read(this->op, out, outlen) != outlen) + while (outlen) { - DBG1(DBG_LIB, "reading AF_ALG hasher failed: %s", strerror(errno)); - sleep(1); + len = read(this->op, out, outlen); + if (len == -1) + { + if (errno == EINTR) + { + continue; + } + DBG1(DBG_LIB, "reading AF_ALG hasher failed: %s", strerror(errno)); + return FALSE; + } + outlen -= len; + out += len; } reset(this); } + return TRUE; } -METHOD(af_alg_ops_t, crypt, void, +METHOD(af_alg_ops_t, crypt, bool, private_af_alg_ops_t *this, u_int32_t type, chunk_t iv, chunk_t data, char *out) { @@ -107,11 +120,16 @@ METHOD(af_alg_ops_t, crypt, void, ssize_t len; int op; - while ((op = accept(this->tfm, NULL, 0)) == -1) + do { - DBG1(DBG_LIB, "accepting AF_ALG crypter failed: %s", strerror(errno)); - sleep(1); + op = accept(this->tfm, NULL, 0); + if (op == -1 && errno != EINTR) + { + DBG1(DBG_LIB, "accepting AF_ALG crypter failed: %s", strerror(errno)); + return FALSE; + } } + while (op == -1); memset(buf, 0, sizeof(buf)); @@ -143,30 +161,39 @@ METHOD(af_alg_ops_t, crypt, void, len = sendmsg(op, &msg, 0); if (len == -1) { - DBG1(DBG_LIB, "writing to AF_ALG crypter failed: %s", - strerror(errno)); - sleep(1); - continue; + if (errno == EINTR) + { + continue; + } + DBG1(DBG_LIB, "writing to AF_ALG crypter failed: %s", strerror(errno)); + return FALSE; } - if (read(op, out, len) != len) + while (read(op, out, len) != len) { - DBG1(DBG_LIB, "reading from AF_ALG crypter failed: %s", - strerror(errno)); + if (errno != EINTR) + { + DBG1(DBG_LIB, "reading from AF_ALG crypter failed: %s", + strerror(errno)); + return FALSE; + } } data = chunk_skip(data, len); /* no IV for subsequent data chunks */ msg.msg_controllen = 0; } close(op); + return TRUE; } -METHOD(af_alg_ops_t, set_key, void, +METHOD(af_alg_ops_t, set_key, bool, private_af_alg_ops_t *this, chunk_t key) { if (setsockopt(this->tfm, SOL_ALG, ALG_SET_KEY, key.ptr, key.len) == -1) { DBG1(DBG_LIB, "setting AF_ALG key failed: %s", strerror(errno)); + return FALSE; } + return TRUE; } METHOD(af_alg_ops_t, destroy, void, diff --git a/src/libstrongswan/plugins/af_alg/af_alg_ops.h b/src/libstrongswan/plugins/af_alg/af_alg_ops.h index ad164029f..e34f22977 100644 --- a/src/libstrongswan/plugins/af_alg/af_alg_ops.h +++ b/src/libstrongswan/plugins/af_alg/af_alg_ops.h @@ -46,8 +46,9 @@ struct af_alg_ops_t { * @param data data to hash * @param out buffer to write hash to, NULL for append mode * @param outlen number of bytes to read into out + * @return TRUE if successful */ - void (*hash)(af_alg_ops_t *this, chunk_t data, char *out, size_t outlen); + bool (*hash)(af_alg_ops_t *this, chunk_t data, char *out, size_t outlen); /** * Reset hasher state. @@ -61,16 +62,18 @@ struct af_alg_ops_t { * @param iv iv to use * @param data data to encrypt/decrypt * @param out buffer write processed data to + * @return TRUE if successful */ - void (*crypt)(af_alg_ops_t *this, u_int32_t type, chunk_t iv, chunk_t data, + bool (*crypt)(af_alg_ops_t *this, u_int32_t type, chunk_t iv, chunk_t data, char *out); /** * Set the key for en-/decryption or HMAC/XCBC operations. * * @param key key to set for transform + * @return TRUE if successful */ - void (*set_key)(af_alg_ops_t *this, chunk_t key); + bool (*set_key)(af_alg_ops_t *this, chunk_t key); /** * Destroy a af_alg_ops_t. diff --git a/src/libstrongswan/plugins/af_alg/af_alg_prf.c b/src/libstrongswan/plugins/af_alg/af_alg_prf.c index a7912291f..720738a84 100644 --- a/src/libstrongswan/plugins/af_alg/af_alg_prf.c +++ b/src/libstrongswan/plugins/af_alg/af_alg_prf.c @@ -105,24 +105,21 @@ static size_t lookup_alg(pseudo_random_function_t algo, char **name, bool *xcbc) return 0; } -METHOD(prf_t, get_bytes, void, +METHOD(prf_t, get_bytes, bool, private_af_alg_prf_t *this, chunk_t seed, u_int8_t *buffer) { - this->ops->hash(this->ops, seed, buffer, this->block_size); + return this->ops->hash(this->ops, seed, buffer, this->block_size); } -METHOD(prf_t, allocate_bytes, void, +METHOD(prf_t, allocate_bytes, bool, private_af_alg_prf_t *this, chunk_t seed, chunk_t *chunk) { if (chunk) { *chunk = chunk_alloc(this->block_size); - get_bytes(this, seed, chunk->ptr); - } - else - { - get_bytes(this, seed, NULL); + return get_bytes(this, seed, chunk->ptr); } + return get_bytes(this, seed, NULL); } METHOD(prf_t, get_block_size, size_t, @@ -137,7 +134,7 @@ METHOD(prf_t, get_key_size, size_t, return this->block_size; } -METHOD(prf_t, set_key, void, +METHOD(prf_t, set_key, bool, private_af_alg_prf_t *this, chunk_t key) { char buf[this->block_size]; @@ -155,12 +152,15 @@ METHOD(prf_t, set_key, void, else if (key.len > this->block_size) { memset(buf, 0, this->block_size); - this->ops->set_key(this->ops, chunk_from_thing(buf)); - this->ops->hash(this->ops, key, buf, this->block_size); + if (!this->ops->set_key(this->ops, chunk_from_thing(buf)) || + !this->ops->hash(this->ops, key, buf, this->block_size)) + { + return FALSE; + } key = chunk_from_thing(buf); } } - this->ops->set_key(this->ops, key); + return this->ops->set_key(this->ops, key); } METHOD(prf_t, destroy, void, diff --git a/src/libstrongswan/plugins/af_alg/af_alg_signer.c b/src/libstrongswan/plugins/af_alg/af_alg_signer.c index 6cd79f8f2..d995b1351 100644 --- a/src/libstrongswan/plugins/af_alg/af_alg_signer.c +++ b/src/libstrongswan/plugins/af_alg/af_alg_signer.c @@ -107,24 +107,21 @@ static size_t lookup_alg(integrity_algorithm_t algo, char **name, return 0; } -METHOD(signer_t, get_signature, void, +METHOD(signer_t, get_signature, bool, private_af_alg_signer_t *this, chunk_t data, u_int8_t *buffer) { - this->ops->hash(this->ops, data, buffer, this->block_size); + return this->ops->hash(this->ops, data, buffer, this->block_size); } -METHOD(signer_t, allocate_signature, void, +METHOD(signer_t, allocate_signature, bool, private_af_alg_signer_t *this, chunk_t data, chunk_t *chunk) { if (chunk) { *chunk = chunk_alloc(this->block_size); - get_signature(this, data, chunk->ptr); - } - else - { - get_signature(this, data, NULL); + return get_signature(this, data, chunk->ptr); } + return get_signature(this, data, NULL); } METHOD(signer_t, verify_signature, bool, @@ -136,7 +133,10 @@ METHOD(signer_t, verify_signature, bool, { return FALSE; } - get_signature(this, data, sig); + if (!get_signature(this, data, sig)) + { + return FALSE; + } return memeq(signature.ptr, sig, signature.len); } @@ -152,10 +152,10 @@ METHOD(signer_t, get_block_size, size_t, return this->block_size; } -METHOD(signer_t, set_key, void, +METHOD(signer_t, set_key, bool, private_af_alg_signer_t *this, chunk_t key) { - this->ops->set_key(this->ops, key); + return this->ops->set_key(this->ops, key); } METHOD(signer_t, destroy, void, diff --git a/src/libstrongswan/plugins/agent/Makefile.in b/src/libstrongswan/plugins/agent/Makefile.in index 452233b85..8e606bf39 100644 --- a/src/libstrongswan/plugins/agent/Makefile.in +++ b/src/libstrongswan/plugins/agent/Makefile.in @@ -49,6 +49,7 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/config/libtool.m4 \ am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; @@ -84,7 +85,7 @@ libstrongswan_agent_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \ @MONOLITHIC_FALSE@am_libstrongswan_agent_la_rpath = -rpath \ @MONOLITHIC_FALSE@ $(plugindir) @MONOLITHIC_TRUE@am_libstrongswan_agent_la_rpath = -DEFAULT_INCLUDES = -I.@am__isrc@ +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles am__mv = mv -f @@ -110,6 +111,7 @@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ +BFDLIB = @BFDLIB@ BTLIB = @BTLIB@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ @@ -204,11 +206,14 @@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ c_plugins = @c_plugins@ +charon_natt_port = @charon_natt_port@ +charon_plugins = @charon_plugins@ +charon_udp_port = @charon_udp_port@ clearsilver_LIBS = @clearsilver_LIBS@ datadir = @datadir@ datarootdir = @datarootdir@ dbusservicedir = @dbusservicedir@ -default_pkcs11 = @default_pkcs11@ +dev_headers = @dev_headers@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ @@ -225,11 +230,12 @@ imcvdir = @imcvdir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ +ipsec_script = @ipsec_script@ +ipsec_script_upper = @ipsec_script_upper@ ipsecdir = @ipsecdir@ ipsecgroup = @ipsecgroup@ ipseclibdir = @ipseclibdir@ ipsecuser = @ipsecuser@ -libcharon_plugins = @libcharon_plugins@ libdir = @libdir@ libexecdir = @libexecdir@ linux_headers = @linux_headers@ @@ -245,6 +251,7 @@ mkdir_p = @mkdir_p@ nm_CFLAGS = @nm_CFLAGS@ nm_LIBS = @nm_LIBS@ nm_ca_dir = @nm_ca_dir@ +nm_plugins = @nm_plugins@ oldincludedir = @oldincludedir@ openac_plugins = @openac_plugins@ p_plugins = @p_plugins@ @@ -254,7 +261,6 @@ pdfdir = @pdfdir@ piddir = @piddir@ pki_plugins = @pki_plugins@ plugindir = @plugindir@ -pluto_plugins = @pluto_plugins@ pool_plugins = @pool_plugins@ prefix = @prefix@ program_transform_name = @program_transform_name@ diff --git a/src/libstrongswan/plugins/blowfish/Makefile.in b/src/libstrongswan/plugins/blowfish/Makefile.in index 52f5fa98a..c8b904eb9 100644 --- a/src/libstrongswan/plugins/blowfish/Makefile.in +++ b/src/libstrongswan/plugins/blowfish/Makefile.in @@ -49,6 +49,7 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/config/libtool.m4 \ am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; @@ -86,7 +87,7 @@ libstrongswan_blowfish_la_LINK = $(LIBTOOL) --tag=CC \ @MONOLITHIC_FALSE@am_libstrongswan_blowfish_la_rpath = -rpath \ @MONOLITHIC_FALSE@ $(plugindir) @MONOLITHIC_TRUE@am_libstrongswan_blowfish_la_rpath = -DEFAULT_INCLUDES = -I.@am__isrc@ +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles am__mv = mv -f @@ -112,6 +113,7 @@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ +BFDLIB = @BFDLIB@ BTLIB = @BTLIB@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ @@ -206,11 +208,14 @@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ c_plugins = @c_plugins@ +charon_natt_port = @charon_natt_port@ +charon_plugins = @charon_plugins@ +charon_udp_port = @charon_udp_port@ clearsilver_LIBS = @clearsilver_LIBS@ datadir = @datadir@ datarootdir = @datarootdir@ dbusservicedir = @dbusservicedir@ -default_pkcs11 = @default_pkcs11@ +dev_headers = @dev_headers@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ @@ -227,11 +232,12 @@ imcvdir = @imcvdir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ +ipsec_script = @ipsec_script@ +ipsec_script_upper = @ipsec_script_upper@ ipsecdir = @ipsecdir@ ipsecgroup = @ipsecgroup@ ipseclibdir = @ipseclibdir@ ipsecuser = @ipsecuser@ -libcharon_plugins = @libcharon_plugins@ libdir = @libdir@ libexecdir = @libexecdir@ linux_headers = @linux_headers@ @@ -247,6 +253,7 @@ mkdir_p = @mkdir_p@ nm_CFLAGS = @nm_CFLAGS@ nm_LIBS = @nm_LIBS@ nm_ca_dir = @nm_ca_dir@ +nm_plugins = @nm_plugins@ oldincludedir = @oldincludedir@ openac_plugins = @openac_plugins@ p_plugins = @p_plugins@ @@ -256,7 +263,6 @@ pdfdir = @pdfdir@ piddir = @piddir@ pki_plugins = @pki_plugins@ plugindir = @plugindir@ -pluto_plugins = @pluto_plugins@ pool_plugins = @pool_plugins@ prefix = @prefix@ program_transform_name = @program_transform_name@ diff --git a/src/libstrongswan/plugins/blowfish/blowfish_crypter.c b/src/libstrongswan/plugins/blowfish/blowfish_crypter.c index fc3649b36..253f9b4a4 100644 --- a/src/libstrongswan/plugins/blowfish/blowfish_crypter.c +++ b/src/libstrongswan/plugins/blowfish/blowfish_crypter.c @@ -87,7 +87,7 @@ struct private_blowfish_crypter_t { u_int32_t key_size; }; -METHOD(crypter_t, decrypt, void, +METHOD(crypter_t, decrypt, bool, private_blowfish_crypter_t *this, chunk_t data, chunk_t iv, chunk_t *decrypted) { @@ -108,9 +108,11 @@ METHOD(crypter_t, decrypt, void, BF_cbc_encrypt(in, out, data.len, &this->schedule, iv.ptr, 0); free(iv.ptr); + + return TRUE; } -METHOD(crypter_t, encrypt, void, +METHOD(crypter_t, encrypt, bool, private_blowfish_crypter_t *this, chunk_t data, chunk_t iv, chunk_t *encrypted) { @@ -131,6 +133,8 @@ METHOD(crypter_t, encrypt, void, BF_cbc_encrypt(in, out, data.len, &this->schedule, iv.ptr, 1); free(iv.ptr); + + return TRUE; } METHOD(crypter_t, get_block_size, size_t, @@ -151,10 +155,11 @@ METHOD(crypter_t, get_key_size, size_t, return this->key_size; } -METHOD(crypter_t, set_key, void, +METHOD(crypter_t, set_key, bool, private_blowfish_crypter_t *this, chunk_t key) { BF_set_key(&this->schedule, key.len , key.ptr); + return TRUE; } METHOD(crypter_t, destroy, void, diff --git a/src/libstrongswan/plugins/ccm/Makefile.in b/src/libstrongswan/plugins/ccm/Makefile.in index 2ffe6194b..bb094f04c 100644 --- a/src/libstrongswan/plugins/ccm/Makefile.in +++ b/src/libstrongswan/plugins/ccm/Makefile.in @@ -49,6 +49,7 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/config/libtool.m4 \ am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; @@ -82,7 +83,7 @@ libstrongswan_ccm_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \ $(libstrongswan_ccm_la_LDFLAGS) $(LDFLAGS) -o $@ @MONOLITHIC_FALSE@am_libstrongswan_ccm_la_rpath = -rpath $(plugindir) @MONOLITHIC_TRUE@am_libstrongswan_ccm_la_rpath = -DEFAULT_INCLUDES = -I.@am__isrc@ +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles am__mv = mv -f @@ -108,6 +109,7 @@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ +BFDLIB = @BFDLIB@ BTLIB = @BTLIB@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ @@ -202,11 +204,14 @@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ c_plugins = @c_plugins@ +charon_natt_port = @charon_natt_port@ +charon_plugins = @charon_plugins@ +charon_udp_port = @charon_udp_port@ clearsilver_LIBS = @clearsilver_LIBS@ datadir = @datadir@ datarootdir = @datarootdir@ dbusservicedir = @dbusservicedir@ -default_pkcs11 = @default_pkcs11@ +dev_headers = @dev_headers@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ @@ -223,11 +228,12 @@ imcvdir = @imcvdir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ +ipsec_script = @ipsec_script@ +ipsec_script_upper = @ipsec_script_upper@ ipsecdir = @ipsecdir@ ipsecgroup = @ipsecgroup@ ipseclibdir = @ipseclibdir@ ipsecuser = @ipsecuser@ -libcharon_plugins = @libcharon_plugins@ libdir = @libdir@ libexecdir = @libexecdir@ linux_headers = @linux_headers@ @@ -243,6 +249,7 @@ mkdir_p = @mkdir_p@ nm_CFLAGS = @nm_CFLAGS@ nm_LIBS = @nm_LIBS@ nm_ca_dir = @nm_ca_dir@ +nm_plugins = @nm_plugins@ oldincludedir = @oldincludedir@ openac_plugins = @openac_plugins@ p_plugins = @p_plugins@ @@ -252,7 +259,6 @@ pdfdir = @pdfdir@ piddir = @piddir@ pki_plugins = @pki_plugins@ plugindir = @plugindir@ -pluto_plugins = @pluto_plugins@ pool_plugins = @pool_plugins@ prefix = @prefix@ program_transform_name = @program_transform_name@ diff --git a/src/libstrongswan/plugins/ccm/ccm_aead.c b/src/libstrongswan/plugins/ccm/ccm_aead.c index 0d2a56a49..0e2f9b75f 100644 --- a/src/libstrongswan/plugins/ccm/ccm_aead.c +++ b/src/libstrongswan/plugins/ccm/ccm_aead.c @@ -126,7 +126,7 @@ static void build_ctr(private_ccm_aead_t *this, u_int32_t i, chunk_t iv, /** * En-/Decrypt data */ -static void crypt_data(private_ccm_aead_t *this, chunk_t iv, +static bool crypt_data(private_ccm_aead_t *this, chunk_t iv, chunk_t in, chunk_t out) { char ctr[BLOCK_SIZE]; @@ -139,8 +139,11 @@ static void crypt_data(private_ccm_aead_t *this, chunk_t iv, while (in.len > 0) { memcpy(block, ctr, BLOCK_SIZE); - this->crypter->encrypt(this->crypter, chunk_from_thing(block), - chunk_from_thing(zero), NULL); + if (!this->crypter->encrypt(this->crypter, chunk_from_thing(block), + chunk_from_thing(zero), NULL)) + { + return FALSE; + } chunk_increment(chunk_from_thing(ctr)); if (in.ptr != out.ptr) @@ -151,12 +154,13 @@ static void crypt_data(private_ccm_aead_t *this, chunk_t iv, in = chunk_skip(in, BLOCK_SIZE); out = chunk_skip(out, BLOCK_SIZE); } + return TRUE; } /** * En-/Decrypt the ICV */ -static void crypt_icv(private_ccm_aead_t *this, chunk_t iv, char *icv) +static bool crypt_icv(private_ccm_aead_t *this, chunk_t iv, char *icv) { char ctr[BLOCK_SIZE]; char zero[BLOCK_SIZE]; @@ -164,15 +168,19 @@ static void crypt_icv(private_ccm_aead_t *this, chunk_t iv, char *icv) build_ctr(this, 0, iv, ctr); memset(zero, 0, BLOCK_SIZE); - this->crypter->encrypt(this->crypter, chunk_from_thing(ctr), - chunk_from_thing(zero), NULL); + if (!this->crypter->encrypt(this->crypter, chunk_from_thing(ctr), + chunk_from_thing(zero), NULL)) + { + return FALSE; + } memxor(icv, ctr, this->icv_size); + return TRUE; } /** * Create the ICV */ -static void create_icv(private_ccm_aead_t *this, chunk_t plain, chunk_t assoc, +static bool create_icv(private_ccm_aead_t *this, chunk_t plain, chunk_t assoc, chunk_t iv, char *icv) { char zero[BLOCK_SIZE]; @@ -217,14 +225,19 @@ static void create_icv(private_ccm_aead_t *this, chunk_t plain, chunk_t assoc, memset(pos, 0, len); /* encrypt inline with CBC, zero IV */ - this->crypter->encrypt(this->crypter, chunk, chunk_from_thing(zero), NULL); + if (!this->crypter->encrypt(this->crypter, chunk, + chunk_from_thing(zero), NULL)) + { + free(chunk.ptr); + return FALSE; + } /* copy last icv_size bytes as ICV to output */ memcpy(icv, chunk.ptr + chunk.len - BLOCK_SIZE, this->icv_size); - /* encrypt the ICV value */ - crypt_icv(this, iv, icv); - free(chunk.ptr); + + /* encrypt the ICV value */ + return crypt_icv(this, iv, icv); } /** @@ -235,26 +248,22 @@ static bool verify_icv(private_ccm_aead_t *this, chunk_t plain, chunk_t assoc, { char buf[this->icv_size]; - create_icv(this, plain, assoc, iv, buf); - - return memeq(buf, icv, this->icv_size); + return create_icv(this, plain, assoc, iv, buf) && + memeq(buf, icv, this->icv_size); } -METHOD(aead_t, encrypt, void, +METHOD(aead_t, encrypt, bool, private_ccm_aead_t *this, chunk_t plain, chunk_t assoc, chunk_t iv, chunk_t *encrypted) { if (encrypted) { *encrypted = chunk_alloc(plain.len + this->icv_size); - create_icv(this, plain, assoc, iv, encrypted->ptr + plain.len); - crypt_data(this, iv, plain, *encrypted); - } - else - { - create_icv(this, plain, assoc, iv, plain.ptr + plain.len); - crypt_data(this, iv, plain, plain); + return create_icv(this, plain, assoc, iv, encrypted->ptr + plain.len) && + crypt_data(this, iv, plain, *encrypted); } + return create_icv(this, plain, assoc, iv, plain.ptr + plain.len) && + crypt_data(this, iv, plain, plain); } METHOD(aead_t, decrypt, bool, @@ -269,16 +278,13 @@ METHOD(aead_t, decrypt, bool, if (plain) { *plain = chunk_alloc(encrypted.len); - crypt_data(this, iv, encrypted, *plain); - return verify_icv(this, *plain, assoc, iv, - encrypted.ptr + encrypted.len); - } - else - { - crypt_data(this, iv, encrypted, encrypted); - return verify_icv(this, encrypted, assoc, iv, + return crypt_data(this, iv, encrypted, *plain) && + verify_icv(this, *plain, assoc, iv, encrypted.ptr + encrypted.len); } + return crypt_data(this, iv, encrypted, encrypted) && + verify_icv(this, encrypted, assoc, iv, + encrypted.ptr + encrypted.len); } METHOD(aead_t, get_block_size, size_t, @@ -305,12 +311,12 @@ METHOD(aead_t, get_key_size, size_t, return this->crypter->get_key_size(this->crypter) + SALT_SIZE; } -METHOD(aead_t, set_key, void, +METHOD(aead_t, set_key, bool, private_ccm_aead_t *this, chunk_t key) { memcpy(this->salt, key.ptr + key.len - SALT_SIZE, SALT_SIZE); key.len -= SALT_SIZE; - this->crypter->set_key(this->crypter, key); + return this->crypter->set_key(this->crypter, key); } METHOD(aead_t, destroy, void, diff --git a/src/libstrongswan/plugins/cmac/Makefile.am b/src/libstrongswan/plugins/cmac/Makefile.am index ce0104f11..5cac3959c 100644 --- a/src/libstrongswan/plugins/cmac/Makefile.am +++ b/src/libstrongswan/plugins/cmac/Makefile.am @@ -10,7 +10,6 @@ plugin_LTLIBRARIES = libstrongswan-cmac.la endif libstrongswan_cmac_la_SOURCES = \ - cmac_plugin.h cmac_plugin.c cmac.h cmac.c \ - cmac_prf.h cmac_prf.c cmac_signer.h cmac_signer.c + cmac_plugin.h cmac_plugin.c cmac.h cmac.c libstrongswan_cmac_la_LDFLAGS = -module -avoid-version diff --git a/src/libstrongswan/plugins/cmac/Makefile.in b/src/libstrongswan/plugins/cmac/Makefile.in index 093e63f32..eba059a29 100644 --- a/src/libstrongswan/plugins/cmac/Makefile.in +++ b/src/libstrongswan/plugins/cmac/Makefile.in @@ -49,6 +49,7 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/config/libtool.m4 \ am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; @@ -75,15 +76,14 @@ am__base_list = \ am__installdirs = "$(DESTDIR)$(plugindir)" LTLIBRARIES = $(noinst_LTLIBRARIES) $(plugin_LTLIBRARIES) libstrongswan_cmac_la_LIBADD = -am_libstrongswan_cmac_la_OBJECTS = cmac_plugin.lo cmac.lo cmac_prf.lo \ - cmac_signer.lo +am_libstrongswan_cmac_la_OBJECTS = cmac_plugin.lo cmac.lo libstrongswan_cmac_la_OBJECTS = $(am_libstrongswan_cmac_la_OBJECTS) libstrongswan_cmac_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(libstrongswan_cmac_la_LDFLAGS) $(LDFLAGS) -o $@ @MONOLITHIC_FALSE@am_libstrongswan_cmac_la_rpath = -rpath $(plugindir) @MONOLITHIC_TRUE@am_libstrongswan_cmac_la_rpath = -DEFAULT_INCLUDES = -I.@am__isrc@ +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles am__mv = mv -f @@ -109,6 +109,7 @@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ +BFDLIB = @BFDLIB@ BTLIB = @BTLIB@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ @@ -203,11 +204,14 @@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ c_plugins = @c_plugins@ +charon_natt_port = @charon_natt_port@ +charon_plugins = @charon_plugins@ +charon_udp_port = @charon_udp_port@ clearsilver_LIBS = @clearsilver_LIBS@ datadir = @datadir@ datarootdir = @datarootdir@ dbusservicedir = @dbusservicedir@ -default_pkcs11 = @default_pkcs11@ +dev_headers = @dev_headers@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ @@ -224,11 +228,12 @@ imcvdir = @imcvdir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ +ipsec_script = @ipsec_script@ +ipsec_script_upper = @ipsec_script_upper@ ipsecdir = @ipsecdir@ ipsecgroup = @ipsecgroup@ ipseclibdir = @ipseclibdir@ ipsecuser = @ipsecuser@ -libcharon_plugins = @libcharon_plugins@ libdir = @libdir@ libexecdir = @libexecdir@ linux_headers = @linux_headers@ @@ -244,6 +249,7 @@ mkdir_p = @mkdir_p@ nm_CFLAGS = @nm_CFLAGS@ nm_LIBS = @nm_LIBS@ nm_ca_dir = @nm_ca_dir@ +nm_plugins = @nm_plugins@ oldincludedir = @oldincludedir@ openac_plugins = @openac_plugins@ p_plugins = @p_plugins@ @@ -253,7 +259,6 @@ pdfdir = @pdfdir@ piddir = @piddir@ pki_plugins = @pki_plugins@ plugindir = @plugindir@ -pluto_plugins = @pluto_plugins@ pool_plugins = @pool_plugins@ prefix = @prefix@ program_transform_name = @program_transform_name@ @@ -286,8 +291,7 @@ AM_CFLAGS = -rdynamic @MONOLITHIC_TRUE@noinst_LTLIBRARIES = libstrongswan-cmac.la @MONOLITHIC_FALSE@plugin_LTLIBRARIES = libstrongswan-cmac.la libstrongswan_cmac_la_SOURCES = \ - cmac_plugin.h cmac_plugin.c cmac.h cmac.c \ - cmac_prf.h cmac_prf.c cmac_signer.h cmac_signer.c + cmac_plugin.h cmac_plugin.c cmac.h cmac.c libstrongswan_cmac_la_LDFLAGS = -module -avoid-version all: all-am @@ -375,8 +379,6 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cmac.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cmac_plugin.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cmac_prf.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cmac_signer.Plo@am__quote@ .c.o: @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< diff --git a/src/libstrongswan/plugins/cmac/cmac.c b/src/libstrongswan/plugins/cmac/cmac.c index 5ec7073c7..725d02d76 100644 --- a/src/libstrongswan/plugins/cmac/cmac.c +++ b/src/libstrongswan/plugins/cmac/cmac.c @@ -18,20 +18,23 @@ #include "cmac.h" #include <debug.h> +#include <crypto/mac.h> +#include <crypto/prfs/mac_prf.h> +#include <crypto/signers/mac_signer.h> -typedef struct private_cmac_t private_cmac_t; +typedef struct private_mac_t private_mac_t; /** - * Private data of a cmac_t object. + * Private data of a mac_t object. * * The variable names are the same as in the RFC. */ -struct private_cmac_t { +struct private_mac_t { /** * Public interface. */ - cmac_t public; + mac_t public; /** * Block size, in bytes @@ -72,7 +75,7 @@ struct private_cmac_t { /** * process supplied data, but do not run final operation */ -static void update(private_cmac_t *this, chunk_t data) +static bool update(private_mac_t *this, chunk_t data) { chunk_t iv; @@ -80,7 +83,7 @@ static void update(private_cmac_t *this, chunk_t data) { /* no complete block (or last block), just copy into remaining */ memcpy(this->remaining + this->remaining_bytes, data.ptr, data.len); this->remaining_bytes += data.len; - return; + return TRUE; } iv = chunk_alloca(this->b); @@ -97,7 +100,10 @@ static void update(private_cmac_t *this, chunk_t data) this->b - this->remaining_bytes); data = chunk_skip(data, this->b - this->remaining_bytes); memxor(this->t, this->remaining, this->b); - this->k->encrypt(this->k, chunk_create(this->t, this->b), iv, NULL); + if (!this->k->encrypt(this->k, chunk_create(this->t, this->b), iv, NULL)) + { + return FALSE; + } /* process blocks M_2 ... M_n-1 */ while (data.len > this->b) @@ -105,18 +111,23 @@ static void update(private_cmac_t *this, chunk_t data) memcpy(this->remaining, data.ptr, this->b); data = chunk_skip(data, this->b); memxor(this->t, this->remaining, this->b); - this->k->encrypt(this->k, chunk_create(this->t, this->b), iv, NULL); + if (!this->k->encrypt(this->k, chunk_create(this->t, this->b), iv, NULL)) + { + return FALSE; + } } /* store remaining bytes of block M_n */ memcpy(this->remaining, data.ptr, data.len); this->remaining_bytes = data.len; + + return TRUE; } /** * process last block M_last */ -static void final(private_cmac_t *this, u_int8_t *out) +static bool final(private_mac_t *this, u_int8_t *out) { chunk_t iv; @@ -153,29 +164,38 @@ static void final(private_cmac_t *this, u_int8_t *out) * T := AES-128(K,T); */ memxor(this->t, this->remaining, this->b); - this->k->encrypt(this->k, chunk_create(this->t, this->b), iv, NULL); + if (!this->k->encrypt(this->k, chunk_create(this->t, this->b), iv, NULL)) + { + return FALSE; + } memcpy(out, this->t, this->b); /* reset state */ memset(this->t, 0, this->b); this->remaining_bytes = 0; + + return TRUE; } -METHOD(cmac_t, get_mac, void, - private_cmac_t *this, chunk_t data, u_int8_t *out) +METHOD(mac_t, get_mac, bool, + private_mac_t *this, chunk_t data, u_int8_t *out) { /* update T, do not process last block */ - update(this, data); + if (!update(this, data)) + { + return FALSE; + } if (out) { /* if not in append mode, process last block and output result */ - final(this, out); + return final(this, out); } + return TRUE; } -METHOD(cmac_t, get_block_size, size_t, - private_cmac_t *this) +METHOD(mac_t, get_mac_size, size_t, + private_mac_t *this) { return this->b; } @@ -222,8 +242,8 @@ static void derive_key(chunk_t chunk) } } -METHOD(cmac_t, set_key, void, - private_cmac_t *this, chunk_t key) +METHOD(mac_t, set_key, bool, + private_mac_t *this, chunk_t key) { chunk_t resized, iv, l; @@ -236,8 +256,11 @@ METHOD(cmac_t, set_key, void, { /* use cmac recursively to resize longer or shorter keys */ resized = chunk_alloca(this->b); memset(resized.ptr, 0, resized.len); - set_key(this, resized); - get_mac(this, key, resized.ptr); + if (!set_key(this, resized) || + !get_mac(this, key, resized.ptr)) + { + return FALSE; + } } /* @@ -256,17 +279,22 @@ METHOD(cmac_t, set_key, void, memset(iv.ptr, 0, iv.len); l = chunk_alloca(this->b); memset(l.ptr, 0, l.len); - this->k->set_key(this->k, resized); - this->k->encrypt(this->k, l, iv, NULL); + if (!this->k->set_key(this->k, resized) || + !this->k->encrypt(this->k, l, iv, NULL)) + { + return FALSE; + } derive_key(l); memcpy(this->k1, l.ptr, l.len); derive_key(l); memcpy(this->k2, l.ptr, l.len); memwipe(l.ptr, l.len); + + return TRUE; } -METHOD(cmac_t, destroy, void, - private_cmac_t *this) +METHOD(mac_t, destroy, void, + private_mac_t *this) { this->k->destroy(this->k); memwipe(this->k1, this->b); @@ -281,9 +309,9 @@ METHOD(cmac_t, destroy, void, /* * Described in header */ -cmac_t *cmac_create(encryption_algorithm_t algo, size_t key_size) +mac_t *cmac_create(encryption_algorithm_t algo, size_t key_size) { - private_cmac_t *this; + private_mac_t *this; crypter_t *crypter; u_int8_t b; @@ -303,7 +331,7 @@ cmac_t *cmac_create(encryption_algorithm_t algo, size_t key_size) INIT(this, .public = { .get_mac = _get_mac, - .get_block_size = _get_block_size, + .get_mac_size = _get_mac_size, .set_key = _set_key, .destroy = _destroy, }, @@ -319,3 +347,48 @@ cmac_t *cmac_create(encryption_algorithm_t algo, size_t key_size) return &this->public; } +/* + * Described in header. + */ +prf_t *cmac_prf_create(pseudo_random_function_t algo) +{ + mac_t *cmac; + + switch (algo) + { + case PRF_AES128_CMAC: + cmac = cmac_create(ENCR_AES_CBC, 16); + break; + default: + return NULL; + } + if (cmac) + { + return mac_prf_create(cmac); + } + return NULL; +} + +/* + * Described in header + */ +signer_t *cmac_signer_create(integrity_algorithm_t algo) +{ + size_t truncation; + mac_t *cmac; + + switch (algo) + { + case AUTH_AES_CMAC_96: + cmac = cmac_create(ENCR_AES_CBC, 16); + truncation = 12; + break; + default: + return NULL; + } + if (cmac) + { + return mac_signer_create(cmac, truncation); + } + return NULL; +} diff --git a/src/libstrongswan/plugins/cmac/cmac.h b/src/libstrongswan/plugins/cmac/cmac.h index 061609127..dc85e3bc3 100644 --- a/src/libstrongswan/plugins/cmac/cmac.h +++ b/src/libstrongswan/plugins/cmac/cmac.h @@ -14,6 +14,11 @@ */ /** + * Cipher-based Message Authentication Code (CMAC). + * + * This class implements the message authentication algorithm + * described in RFC 4493. + * * @defgroup cmac cmac * @{ @ingroup cmac_p */ @@ -21,58 +26,23 @@ #ifndef CMAC_H_ #define CMAC_H_ -#include <crypto/crypters/crypter.h> - -typedef struct cmac_t cmac_t; +#include <crypto/prfs/prf.h> +#include <crypto/signers/signer.h> /** - * Cipher-based Message Authentication Code (CMAC). + * Creates a new prf_t object based on a CMAC. * - * This class implements the message authentication algorithm - * described in RFC 4493. + * @param algo algorithm to implement + * @return prf_t object, NULL if not supported */ -struct cmac_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 internal - * state is reset. - * - * @param data chunk of data to authenticate - * @param buffer pointer where the generated bytes will be written - */ - void (*get_mac) (cmac_t *this, chunk_t data, u_int8_t *buffer); - - /** - * Get the block size of this cmac_t object. - * - * @return block size in bytes - */ - size_t (*get_block_size) (cmac_t *this); - - /** - * Set the key for this cmac_t object. - * - * @param key key to set - */ - void (*set_key) (cmac_t *this, chunk_t key); - - /** - * Destroys a cmac_t object. - */ - void (*destroy) (cmac_t *this); -}; +prf_t *cmac_prf_create(pseudo_random_function_t algo); /** - * Creates a new cmac_t object. + * Creates a new signer_t object based on a CMAC. * - * @param algo underlying crypto algorithm - * @param key_size key size to use, if required for algorithm - * @return cmac_t object, NULL if not supported + * @param algo algorithm to implement + * @return signer_t, NULL if not supported */ -cmac_t *cmac_create(encryption_algorithm_t algo, size_t key_size); +signer_t *cmac_signer_create(integrity_algorithm_t algo); #endif /** CMAC_H_ @}*/ diff --git a/src/libstrongswan/plugins/cmac/cmac_plugin.c b/src/libstrongswan/plugins/cmac/cmac_plugin.c index 5b42c5002..694e598a5 100644 --- a/src/libstrongswan/plugins/cmac/cmac_plugin.c +++ b/src/libstrongswan/plugins/cmac/cmac_plugin.c @@ -16,8 +16,7 @@ #include "cmac_plugin.h" #include <library.h> -#include "cmac_prf.h" -#include "cmac_signer.h" +#include "cmac.h" typedef struct private_cmac_plugin_t private_cmac_plugin_t; diff --git a/src/libstrongswan/plugins/cmac/cmac_prf.c b/src/libstrongswan/plugins/cmac/cmac_prf.c deleted file mode 100644 index 17affe439..000000000 --- a/src/libstrongswan/plugins/cmac/cmac_prf.c +++ /dev/null @@ -1,121 +0,0 @@ -/* - * Copyright (C) 2012 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. - */ - -#include "cmac_prf.h" - -#include "cmac.h" - -typedef struct private_cmac_prf_t private_cmac_prf_t; - -/** - * Private data of a cmac_prf_t object. - */ -struct private_cmac_prf_t { - - /** - * Public cmac_prf_t interface. - */ - cmac_prf_t public; - - /** - * cmac to use for generation. - */ - cmac_t *cmac; -}; - -METHOD(prf_t, get_bytes, void, - private_cmac_prf_t *this, chunk_t seed, u_int8_t *buffer) -{ - this->cmac->get_mac(this->cmac, seed, buffer); -} - -METHOD(prf_t, allocate_bytes, void, - private_cmac_prf_t *this, chunk_t seed, chunk_t *chunk) -{ - if (chunk) - { - *chunk = chunk_alloc(this->cmac->get_block_size(this->cmac)); - get_bytes(this, seed, chunk->ptr); - } - else - { - get_bytes(this, seed, NULL); - } -} - -METHOD(prf_t, get_block_size, size_t, - private_cmac_prf_t *this) -{ - return this->cmac->get_block_size(this->cmac); -} - -METHOD(prf_t, get_key_size, size_t, - private_cmac_prf_t *this) -{ - /* in cmac, block and key size are always equal */ - return this->cmac->get_block_size(this->cmac); -} - -METHOD(prf_t, set_key, void, - private_cmac_prf_t *this, chunk_t key) -{ - this->cmac->set_key(this->cmac, key); -} - -METHOD(prf_t, destroy, void, - private_cmac_prf_t *this) -{ - this->cmac->destroy(this->cmac); - free(this); -} - -/* - * Described in header. - */ -cmac_prf_t *cmac_prf_create(pseudo_random_function_t algo) -{ - private_cmac_prf_t *this; - cmac_t *cmac; - - switch (algo) - { - case PRF_AES128_CMAC: - cmac = cmac_create(ENCR_AES_CBC, 16); - break; - default: - return NULL; - } - if (!cmac) - { - return NULL; - } - - INIT(this, - .public = { - .prf = { - .get_bytes = _get_bytes, - .allocate_bytes = _allocate_bytes, - .get_block_size = _get_block_size, - .get_key_size = _get_key_size, - .set_key = _set_key, - .destroy = _destroy, - }, - }, - .cmac = cmac, - ); - - return &this->public; -} - diff --git a/src/libstrongswan/plugins/cmac/cmac_signer.c b/src/libstrongswan/plugins/cmac/cmac_signer.c deleted file mode 100644 index 82e8885d6..000000000 --- a/src/libstrongswan/plugins/cmac/cmac_signer.c +++ /dev/null @@ -1,159 +0,0 @@ -/* - * Copyright (C) 2012 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. - */ - -#include <string.h> - -#include "cmac_signer.h" -#include "cmac.h" - -typedef struct private_cmac_signer_t private_cmac_signer_t; - -/** - * Private data structure with signing context. - */ -struct private_cmac_signer_t { - - /** - * Public interface. - */ - cmac_signer_t public; - - /** - * Assigned cmac function. - */ - cmac_t *cmac; - - /** - * Block size (truncation of CMAC MAC) - */ - size_t block_size; -}; - -METHOD(signer_t, get_signature, void, - private_cmac_signer_t *this, chunk_t data, u_int8_t *buffer) -{ - if (buffer == NULL) - { /* append mode */ - this->cmac->get_mac(this->cmac, data, NULL); - } - else - { - u_int8_t mac[this->cmac->get_block_size(this->cmac)]; - - this->cmac->get_mac(this->cmac, data, mac); - memcpy(buffer, mac, this->block_size); - } -} - -METHOD(signer_t, allocate_signature, void, - private_cmac_signer_t *this, chunk_t data, chunk_t *chunk) -{ - if (chunk == NULL) - { /* append mode */ - this->cmac->get_mac(this->cmac, data, NULL); - } - else - { - u_int8_t mac[this->cmac->get_block_size(this->cmac)]; - - this->cmac->get_mac(this->cmac, data, mac); - - chunk->ptr = malloc(this->block_size); - chunk->len = this->block_size; - - memcpy(chunk->ptr, mac, this->block_size); - } -} - -METHOD(signer_t, verify_signature, bool, - private_cmac_signer_t *this, chunk_t data, chunk_t signature) -{ - u_int8_t mac[this->cmac->get_block_size(this->cmac)]; - - if (signature.len != this->block_size) - { - return FALSE; - } - - this->cmac->get_mac(this->cmac, data, mac); - return memeq(signature.ptr, mac, this->block_size); -} - -METHOD(signer_t, get_key_size, size_t, - private_cmac_signer_t *this) -{ - return this->cmac->get_block_size(this->cmac); -} - -METHOD(signer_t, get_block_size, size_t, - private_cmac_signer_t *this) -{ - return this->block_size; -} - -METHOD(signer_t, set_key, void, - private_cmac_signer_t *this, chunk_t key) -{ - this->cmac->set_key(this->cmac, key); -} - -METHOD(signer_t, destroy, void, - private_cmac_signer_t *this) -{ - this->cmac->destroy(this->cmac); - free(this); -} - -/* - * Described in header - */ -cmac_signer_t *cmac_signer_create(integrity_algorithm_t algo) -{ - private_cmac_signer_t *this; - size_t truncation; - cmac_t *cmac; - - switch (algo) - { - case AUTH_AES_CMAC_96: - cmac = cmac_create(ENCR_AES_CBC, 16); - truncation = 12; - break; - default: - return NULL; - } - if (cmac == NULL) - { - return NULL; - } - - INIT(this, - .public = { - .signer = { - .get_signature = _get_signature, - .allocate_signature = _allocate_signature, - .verify_signature = _verify_signature, - .get_key_size = _get_key_size, - .get_block_size = _get_block_size, - .set_key = _set_key, - .destroy = _destroy, - }, - }, - .cmac = cmac, - .block_size = min(truncation, cmac->get_block_size(cmac)), - ); - - return &this->public; -} diff --git a/src/libstrongswan/plugins/constraints/Makefile.in b/src/libstrongswan/plugins/constraints/Makefile.in index 06b66db60..693d76334 100644 --- a/src/libstrongswan/plugins/constraints/Makefile.in +++ b/src/libstrongswan/plugins/constraints/Makefile.in @@ -49,6 +49,7 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/config/libtool.m4 \ am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; @@ -86,7 +87,7 @@ libstrongswan_constraints_la_LINK = $(LIBTOOL) --tag=CC \ @MONOLITHIC_FALSE@am_libstrongswan_constraints_la_rpath = -rpath \ @MONOLITHIC_FALSE@ $(plugindir) @MONOLITHIC_TRUE@am_libstrongswan_constraints_la_rpath = -DEFAULT_INCLUDES = -I.@am__isrc@ +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles am__mv = mv -f @@ -112,6 +113,7 @@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ +BFDLIB = @BFDLIB@ BTLIB = @BTLIB@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ @@ -206,11 +208,14 @@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ c_plugins = @c_plugins@ +charon_natt_port = @charon_natt_port@ +charon_plugins = @charon_plugins@ +charon_udp_port = @charon_udp_port@ clearsilver_LIBS = @clearsilver_LIBS@ datadir = @datadir@ datarootdir = @datarootdir@ dbusservicedir = @dbusservicedir@ -default_pkcs11 = @default_pkcs11@ +dev_headers = @dev_headers@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ @@ -227,11 +232,12 @@ imcvdir = @imcvdir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ +ipsec_script = @ipsec_script@ +ipsec_script_upper = @ipsec_script_upper@ ipsecdir = @ipsecdir@ ipsecgroup = @ipsecgroup@ ipseclibdir = @ipseclibdir@ ipsecuser = @ipsecuser@ -libcharon_plugins = @libcharon_plugins@ libdir = @libdir@ libexecdir = @libexecdir@ linux_headers = @linux_headers@ @@ -247,6 +253,7 @@ mkdir_p = @mkdir_p@ nm_CFLAGS = @nm_CFLAGS@ nm_LIBS = @nm_LIBS@ nm_ca_dir = @nm_ca_dir@ +nm_plugins = @nm_plugins@ oldincludedir = @oldincludedir@ openac_plugins = @openac_plugins@ p_plugins = @p_plugins@ @@ -256,7 +263,6 @@ pdfdir = @pdfdir@ piddir = @piddir@ pki_plugins = @pki_plugins@ plugindir = @plugindir@ -pluto_plugins = @pluto_plugins@ pool_plugins = @pool_plugins@ prefix = @prefix@ program_transform_name = @program_transform_name@ diff --git a/src/libstrongswan/plugins/ctr/Makefile.in b/src/libstrongswan/plugins/ctr/Makefile.in index 853625a19..adab5d7d5 100644 --- a/src/libstrongswan/plugins/ctr/Makefile.in +++ b/src/libstrongswan/plugins/ctr/Makefile.in @@ -49,6 +49,7 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/config/libtool.m4 \ am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; @@ -82,7 +83,7 @@ libstrongswan_ctr_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \ $(libstrongswan_ctr_la_LDFLAGS) $(LDFLAGS) -o $@ @MONOLITHIC_FALSE@am_libstrongswan_ctr_la_rpath = -rpath $(plugindir) @MONOLITHIC_TRUE@am_libstrongswan_ctr_la_rpath = -DEFAULT_INCLUDES = -I.@am__isrc@ +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles am__mv = mv -f @@ -108,6 +109,7 @@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ +BFDLIB = @BFDLIB@ BTLIB = @BTLIB@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ @@ -202,11 +204,14 @@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ c_plugins = @c_plugins@ +charon_natt_port = @charon_natt_port@ +charon_plugins = @charon_plugins@ +charon_udp_port = @charon_udp_port@ clearsilver_LIBS = @clearsilver_LIBS@ datadir = @datadir@ datarootdir = @datarootdir@ dbusservicedir = @dbusservicedir@ -default_pkcs11 = @default_pkcs11@ +dev_headers = @dev_headers@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ @@ -223,11 +228,12 @@ imcvdir = @imcvdir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ +ipsec_script = @ipsec_script@ +ipsec_script_upper = @ipsec_script_upper@ ipsecdir = @ipsecdir@ ipsecgroup = @ipsecgroup@ ipseclibdir = @ipseclibdir@ ipsecuser = @ipsecuser@ -libcharon_plugins = @libcharon_plugins@ libdir = @libdir@ libexecdir = @libexecdir@ linux_headers = @linux_headers@ @@ -243,6 +249,7 @@ mkdir_p = @mkdir_p@ nm_CFLAGS = @nm_CFLAGS@ nm_LIBS = @nm_LIBS@ nm_ca_dir = @nm_ca_dir@ +nm_plugins = @nm_plugins@ oldincludedir = @oldincludedir@ openac_plugins = @openac_plugins@ p_plugins = @p_plugins@ @@ -252,7 +259,6 @@ pdfdir = @pdfdir@ piddir = @piddir@ pki_plugins = @pki_plugins@ plugindir = @plugindir@ -pluto_plugins = @pluto_plugins@ pool_plugins = @pool_plugins@ prefix = @prefix@ program_transform_name = @program_transform_name@ diff --git a/src/libstrongswan/plugins/ctr/ctr_ipsec_crypter.c b/src/libstrongswan/plugins/ctr/ctr_ipsec_crypter.c index ddcae423b..59d201a6f 100644 --- a/src/libstrongswan/plugins/ctr/ctr_ipsec_crypter.c +++ b/src/libstrongswan/plugins/ctr/ctr_ipsec_crypter.c @@ -45,7 +45,7 @@ struct private_ctr_ipsec_crypter_t { /** * Do the CTR crypto operation */ -static void crypt_ctr(private_ctr_ipsec_crypter_t *this, +static bool crypt_ctr(private_ctr_ipsec_crypter_t *this, chunk_t in, chunk_t out) { size_t is, bs; @@ -63,8 +63,11 @@ static void crypt_ctr(private_ctr_ipsec_crypter_t *this, memset(iv, 0, is); memcpy(block, state.ptr, bs); - this->crypter->encrypt(this->crypter, - chunk_create(block, bs), chunk_create(iv, is), NULL); + if (!this->crypter->encrypt(this->crypter, chunk_create(block, bs), + chunk_create(iv, is), NULL)) + { + return FALSE; + } chunk_increment(state); if (in.ptr != out.ptr) @@ -75,9 +78,10 @@ static void crypt_ctr(private_ctr_ipsec_crypter_t *this, in = chunk_skip(in, bs); out = chunk_skip(out, bs); } + return TRUE; } -METHOD(crypter_t, crypt, void, +METHOD(crypter_t, crypt, bool, private_ctr_ipsec_crypter_t *this, chunk_t in, chunk_t iv, chunk_t *out) { memcpy(this->state.iv, iv.ptr, sizeof(this->state.iv)); @@ -85,12 +89,9 @@ METHOD(crypter_t, crypt, void, if (out) { *out = chunk_alloc(in.len); - crypt_ctr(this, in, *out); - } - else - { - crypt_ctr(this, in, in); + return crypt_ctr(this, in, *out); } + return crypt_ctr(this, in, in); } METHOD(crypter_t, get_block_size, size_t, @@ -112,13 +113,13 @@ METHOD(crypter_t, get_key_size, size_t, + sizeof(this->state.nonce); } -METHOD(crypter_t, set_key, void, +METHOD(crypter_t, set_key, bool, private_ctr_ipsec_crypter_t *this, chunk_t key) { memcpy(this->state.nonce, key.ptr + key.len - sizeof(this->state.nonce), sizeof(this->state.nonce)); key.len -= sizeof(this->state.nonce); - this->crypter->set_key(this->crypter, key); + return this->crypter->set_key(this->crypter, key); } METHOD(crypter_t, destroy, void, diff --git a/src/libstrongswan/plugins/curl/Makefile.in b/src/libstrongswan/plugins/curl/Makefile.in index 5b83c60f8..b6f38681f 100644 --- a/src/libstrongswan/plugins/curl/Makefile.in +++ b/src/libstrongswan/plugins/curl/Makefile.in @@ -49,6 +49,7 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/config/libtool.m4 \ am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; @@ -82,7 +83,7 @@ libstrongswan_curl_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \ $(libstrongswan_curl_la_LDFLAGS) $(LDFLAGS) -o $@ @MONOLITHIC_FALSE@am_libstrongswan_curl_la_rpath = -rpath $(plugindir) @MONOLITHIC_TRUE@am_libstrongswan_curl_la_rpath = -DEFAULT_INCLUDES = -I.@am__isrc@ +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles am__mv = mv -f @@ -108,6 +109,7 @@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ +BFDLIB = @BFDLIB@ BTLIB = @BTLIB@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ @@ -202,11 +204,14 @@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ c_plugins = @c_plugins@ +charon_natt_port = @charon_natt_port@ +charon_plugins = @charon_plugins@ +charon_udp_port = @charon_udp_port@ clearsilver_LIBS = @clearsilver_LIBS@ datadir = @datadir@ datarootdir = @datarootdir@ dbusservicedir = @dbusservicedir@ -default_pkcs11 = @default_pkcs11@ +dev_headers = @dev_headers@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ @@ -223,11 +228,12 @@ imcvdir = @imcvdir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ +ipsec_script = @ipsec_script@ +ipsec_script_upper = @ipsec_script_upper@ ipsecdir = @ipsecdir@ ipsecgroup = @ipsecgroup@ ipseclibdir = @ipseclibdir@ ipsecuser = @ipsecuser@ -libcharon_plugins = @libcharon_plugins@ libdir = @libdir@ libexecdir = @libexecdir@ linux_headers = @linux_headers@ @@ -243,6 +249,7 @@ mkdir_p = @mkdir_p@ nm_CFLAGS = @nm_CFLAGS@ nm_LIBS = @nm_LIBS@ nm_ca_dir = @nm_ca_dir@ +nm_plugins = @nm_plugins@ oldincludedir = @oldincludedir@ openac_plugins = @openac_plugins@ p_plugins = @p_plugins@ @@ -252,7 +259,6 @@ pdfdir = @pdfdir@ piddir = @piddir@ pki_plugins = @pki_plugins@ plugindir = @plugindir@ -pluto_plugins = @pluto_plugins@ pool_plugins = @pool_plugins@ prefix = @prefix@ program_transform_name = @program_transform_name@ diff --git a/src/libstrongswan/plugins/des/Makefile.in b/src/libstrongswan/plugins/des/Makefile.in index f4056951a..04d489824 100644 --- a/src/libstrongswan/plugins/des/Makefile.in +++ b/src/libstrongswan/plugins/des/Makefile.in @@ -49,6 +49,7 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/config/libtool.m4 \ am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; @@ -82,7 +83,7 @@ libstrongswan_des_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \ $(libstrongswan_des_la_LDFLAGS) $(LDFLAGS) -o $@ @MONOLITHIC_FALSE@am_libstrongswan_des_la_rpath = -rpath $(plugindir) @MONOLITHIC_TRUE@am_libstrongswan_des_la_rpath = -DEFAULT_INCLUDES = -I.@am__isrc@ +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles am__mv = mv -f @@ -108,6 +109,7 @@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ +BFDLIB = @BFDLIB@ BTLIB = @BTLIB@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ @@ -202,11 +204,14 @@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ c_plugins = @c_plugins@ +charon_natt_port = @charon_natt_port@ +charon_plugins = @charon_plugins@ +charon_udp_port = @charon_udp_port@ clearsilver_LIBS = @clearsilver_LIBS@ datadir = @datadir@ datarootdir = @datarootdir@ dbusservicedir = @dbusservicedir@ -default_pkcs11 = @default_pkcs11@ +dev_headers = @dev_headers@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ @@ -223,11 +228,12 @@ imcvdir = @imcvdir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ +ipsec_script = @ipsec_script@ +ipsec_script_upper = @ipsec_script_upper@ ipsecdir = @ipsecdir@ ipsecgroup = @ipsecgroup@ ipseclibdir = @ipseclibdir@ ipsecuser = @ipsecuser@ -libcharon_plugins = @libcharon_plugins@ libdir = @libdir@ libexecdir = @libexecdir@ linux_headers = @linux_headers@ @@ -243,6 +249,7 @@ mkdir_p = @mkdir_p@ nm_CFLAGS = @nm_CFLAGS@ nm_LIBS = @nm_LIBS@ nm_ca_dir = @nm_ca_dir@ +nm_plugins = @nm_plugins@ oldincludedir = @oldincludedir@ openac_plugins = @openac_plugins@ p_plugins = @p_plugins@ @@ -252,7 +259,6 @@ pdfdir = @pdfdir@ piddir = @piddir@ pki_plugins = @pki_plugins@ plugindir = @plugindir@ -pluto_plugins = @pluto_plugins@ pool_plugins = @pool_plugins@ prefix = @prefix@ program_transform_name = @program_transform_name@ diff --git a/src/libstrongswan/plugins/des/des_crypter.c b/src/libstrongswan/plugins/des/des_crypter.c index bc399ef8a..c81318b19 100644 --- a/src/libstrongswan/plugins/des/des_crypter.c +++ b/src/libstrongswan/plugins/des/des_crypter.c @@ -1416,7 +1416,7 @@ static void des_ede3_cbc_encrypt(des_cblock *input, des_cblock *output, long len tin[0]=tin[1]=0; } -METHOD(crypter_t, decrypt, void, +METHOD(crypter_t, decrypt, bool, private_des_crypter_t *this, chunk_t data, chunk_t iv, chunk_t *decrypted) { des_cblock ivb; @@ -1431,10 +1431,11 @@ METHOD(crypter_t, decrypt, void, memcpy(&ivb, iv.ptr, sizeof(des_cblock)); des_cbc_encrypt((des_cblock*)(data.ptr), (des_cblock*)out, data.len, this->ks, &ivb, DES_DECRYPT); + return TRUE; } -METHOD(crypter_t, encrypt, void, +METHOD(crypter_t, encrypt, bool, private_des_crypter_t *this, chunk_t data, chunk_t iv, chunk_t *encrypted) { des_cblock ivb; @@ -1449,9 +1450,10 @@ METHOD(crypter_t, encrypt, void, memcpy(&ivb, iv.ptr, sizeof(des_cblock)); des_cbc_encrypt((des_cblock*)(data.ptr), (des_cblock*)out, data.len, this->ks, &ivb, DES_ENCRYPT); + return TRUE; } -METHOD(crypter_t, decrypt_ecb, void, +METHOD(crypter_t, decrypt_ecb, bool, private_des_crypter_t *this, chunk_t data, chunk_t iv, chunk_t *decrypted) { u_int8_t *out; @@ -1464,9 +1466,10 @@ METHOD(crypter_t, decrypt_ecb, void, } des_ecb_encrypt((des_cblock*)(data.ptr), (des_cblock*)out, data.len, this->ks, DES_DECRYPT); + return TRUE; } -METHOD(crypter_t, encrypt_ecb, void, +METHOD(crypter_t, encrypt_ecb, bool, private_des_crypter_t *this, chunk_t data, chunk_t iv, chunk_t *encrypted) { u_int8_t *out; @@ -1479,9 +1482,10 @@ METHOD(crypter_t, encrypt_ecb, void, } des_ecb_encrypt((des_cblock*)(data.ptr), (des_cblock*)out, data.len, this->ks, DES_ENCRYPT); + return TRUE; } -METHOD(crypter_t, decrypt3, void, +METHOD(crypter_t, decrypt3, bool, private_des_crypter_t *this, chunk_t data, chunk_t iv, chunk_t *decrypted) { des_cblock ivb; @@ -1497,9 +1501,10 @@ METHOD(crypter_t, decrypt3, void, 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 TRUE; } -METHOD(crypter_t, encrypt3, void, +METHOD(crypter_t, encrypt3, bool, private_des_crypter_t *this, chunk_t data, chunk_t iv, chunk_t *encrypted) { des_cblock ivb; @@ -1515,6 +1520,7 @@ METHOD(crypter_t, encrypt3, void, 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 TRUE; } METHOD(crypter_t, get_block_size, size_t, @@ -1535,18 +1541,20 @@ METHOD(crypter_t, get_key_size, size_t, return this->key_size; } -METHOD(crypter_t, set_key, void, +METHOD(crypter_t, set_key, bool, private_des_crypter_t *this, chunk_t key) { des_set_key((des_cblock*)(key.ptr), &this->ks); + return TRUE; } -METHOD(crypter_t, set_key3, void, +METHOD(crypter_t, set_key3, bool, 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 TRUE; } METHOD(crypter_t, destroy, void, diff --git a/src/libstrongswan/plugins/dnskey/Makefile.in b/src/libstrongswan/plugins/dnskey/Makefile.in index dabddd6d0..2f86f7558 100644 --- a/src/libstrongswan/plugins/dnskey/Makefile.in +++ b/src/libstrongswan/plugins/dnskey/Makefile.in @@ -49,6 +49,7 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/config/libtool.m4 \ am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; @@ -85,7 +86,7 @@ libstrongswan_dnskey_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \ @MONOLITHIC_FALSE@am_libstrongswan_dnskey_la_rpath = -rpath \ @MONOLITHIC_FALSE@ $(plugindir) @MONOLITHIC_TRUE@am_libstrongswan_dnskey_la_rpath = -DEFAULT_INCLUDES = -I.@am__isrc@ +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles am__mv = mv -f @@ -111,6 +112,7 @@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ +BFDLIB = @BFDLIB@ BTLIB = @BTLIB@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ @@ -205,11 +207,14 @@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ c_plugins = @c_plugins@ +charon_natt_port = @charon_natt_port@ +charon_plugins = @charon_plugins@ +charon_udp_port = @charon_udp_port@ clearsilver_LIBS = @clearsilver_LIBS@ datadir = @datadir@ datarootdir = @datarootdir@ dbusservicedir = @dbusservicedir@ -default_pkcs11 = @default_pkcs11@ +dev_headers = @dev_headers@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ @@ -226,11 +231,12 @@ imcvdir = @imcvdir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ +ipsec_script = @ipsec_script@ +ipsec_script_upper = @ipsec_script_upper@ ipsecdir = @ipsecdir@ ipsecgroup = @ipsecgroup@ ipseclibdir = @ipseclibdir@ ipsecuser = @ipsecuser@ -libcharon_plugins = @libcharon_plugins@ libdir = @libdir@ libexecdir = @libexecdir@ linux_headers = @linux_headers@ @@ -246,6 +252,7 @@ mkdir_p = @mkdir_p@ nm_CFLAGS = @nm_CFLAGS@ nm_LIBS = @nm_LIBS@ nm_ca_dir = @nm_ca_dir@ +nm_plugins = @nm_plugins@ oldincludedir = @oldincludedir@ openac_plugins = @openac_plugins@ p_plugins = @p_plugins@ @@ -255,7 +262,6 @@ pdfdir = @pdfdir@ piddir = @piddir@ pki_plugins = @pki_plugins@ plugindir = @plugindir@ -pluto_plugins = @pluto_plugins@ pool_plugins = @pool_plugins@ prefix = @prefix@ program_transform_name = @program_transform_name@ diff --git a/src/libstrongswan/plugins/fips_prf/Makefile.in b/src/libstrongswan/plugins/fips_prf/Makefile.in index cbe9ef303..017f00e50 100644 --- a/src/libstrongswan/plugins/fips_prf/Makefile.in +++ b/src/libstrongswan/plugins/fips_prf/Makefile.in @@ -49,6 +49,7 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/config/libtool.m4 \ am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; @@ -85,7 +86,7 @@ libstrongswan_fips_prf_la_LINK = $(LIBTOOL) --tag=CC \ @MONOLITHIC_FALSE@am_libstrongswan_fips_prf_la_rpath = -rpath \ @MONOLITHIC_FALSE@ $(plugindir) @MONOLITHIC_TRUE@am_libstrongswan_fips_prf_la_rpath = -DEFAULT_INCLUDES = -I.@am__isrc@ +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles am__mv = mv -f @@ -111,6 +112,7 @@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ +BFDLIB = @BFDLIB@ BTLIB = @BTLIB@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ @@ -205,11 +207,14 @@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ c_plugins = @c_plugins@ +charon_natt_port = @charon_natt_port@ +charon_plugins = @charon_plugins@ +charon_udp_port = @charon_udp_port@ clearsilver_LIBS = @clearsilver_LIBS@ datadir = @datadir@ datarootdir = @datarootdir@ dbusservicedir = @dbusservicedir@ -default_pkcs11 = @default_pkcs11@ +dev_headers = @dev_headers@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ @@ -226,11 +231,12 @@ imcvdir = @imcvdir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ +ipsec_script = @ipsec_script@ +ipsec_script_upper = @ipsec_script_upper@ ipsecdir = @ipsecdir@ ipsecgroup = @ipsecgroup@ ipseclibdir = @ipseclibdir@ ipsecuser = @ipsecuser@ -libcharon_plugins = @libcharon_plugins@ libdir = @libdir@ libexecdir = @libexecdir@ linux_headers = @linux_headers@ @@ -246,6 +252,7 @@ mkdir_p = @mkdir_p@ nm_CFLAGS = @nm_CFLAGS@ nm_LIBS = @nm_LIBS@ nm_ca_dir = @nm_ca_dir@ +nm_plugins = @nm_plugins@ oldincludedir = @oldincludedir@ openac_plugins = @openac_plugins@ p_plugins = @p_plugins@ @@ -255,7 +262,6 @@ pdfdir = @pdfdir@ piddir = @piddir@ pki_plugins = @pki_plugins@ plugindir = @plugindir@ -pluto_plugins = @pluto_plugins@ pool_plugins = @pool_plugins@ prefix = @prefix@ program_transform_name = @program_transform_name@ diff --git a/src/libstrongswan/plugins/fips_prf/fips_prf.c b/src/libstrongswan/plugins/fips_prf/fips_prf.c index c0666367a..3fe204d35 100644 --- a/src/libstrongswan/plugins/fips_prf/fips_prf.c +++ b/src/libstrongswan/plugins/fips_prf/fips_prf.c @@ -48,7 +48,7 @@ struct private_fips_prf_t { /** * G function, either SHA1 or DES */ - void (*g)(private_fips_prf_t *this, chunk_t c, u_int8_t res[]); + bool (*g)(private_fips_prf_t *this, chunk_t c, u_int8_t res[]); }; /** @@ -106,7 +106,7 @@ static void chunk_mod(size_t length, chunk_t chunk, u_int8_t buffer[]) * 0xcb, 0x0f, 0x6c, 0x55, 0xba, 0xbb, 0x13, 0x78, * 0x8e, 0x20, 0xd7, 0x37, 0xa3, 0x27, 0x51, 0x16 */ -METHOD(prf_t, get_bytes, void, +METHOD(prf_t, get_bytes, bool, private_fips_prf_t *this, chunk_t seed, u_int8_t w[]) { int i; @@ -138,6 +138,8 @@ METHOD(prf_t, get_bytes, void, } /* 3.3 done already, mod q not used */ + + return TRUE; } METHOD(prf_t, get_block_size, size_t, @@ -145,11 +147,11 @@ METHOD(prf_t, get_block_size, size_t, { return 2 * this->b; } -METHOD(prf_t, allocate_bytes, void, +METHOD(prf_t, allocate_bytes, bool, private_fips_prf_t *this, chunk_t seed, chunk_t *chunk) { *chunk = chunk_alloc(get_block_size(this)); - get_bytes(this, seed, chunk->ptr); + return get_bytes(this, seed, chunk->ptr); } METHOD(prf_t, get_key_size, size_t, @@ -158,17 +160,18 @@ METHOD(prf_t, get_key_size, size_t, return this->b; } -METHOD(prf_t, set_key, void, +METHOD(prf_t, set_key, bool, private_fips_prf_t *this, chunk_t key) { /* save key as "key mod 2^b" */ chunk_mod(this->b, key, this->key); + return TRUE; } /** * Implementation of the G() function based on SHA1 */ -void g_sha1(private_fips_prf_t *this, chunk_t c, u_int8_t res[]) +static bool g_sha1(private_fips_prf_t *this, chunk_t c, u_int8_t res[]) { u_int8_t buf[64]; @@ -187,8 +190,12 @@ void g_sha1(private_fips_prf_t *this, chunk_t c, u_int8_t res[]) } /* 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); + if (!this->keyed_prf->set_key(this->keyed_prf, chunk_empty) || + !this->keyed_prf->get_bytes(this->keyed_prf, c, res)) + { + return FALSE; + } + return TRUE; } METHOD(prf_t, destroy, void, diff --git a/src/libstrongswan/plugins/gcm/Makefile.in b/src/libstrongswan/plugins/gcm/Makefile.in index 8285b5aeb..0c5eea0a7 100644 --- a/src/libstrongswan/plugins/gcm/Makefile.in +++ b/src/libstrongswan/plugins/gcm/Makefile.in @@ -49,6 +49,7 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/config/libtool.m4 \ am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; @@ -82,7 +83,7 @@ libstrongswan_gcm_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \ $(libstrongswan_gcm_la_LDFLAGS) $(LDFLAGS) -o $@ @MONOLITHIC_FALSE@am_libstrongswan_gcm_la_rpath = -rpath $(plugindir) @MONOLITHIC_TRUE@am_libstrongswan_gcm_la_rpath = -DEFAULT_INCLUDES = -I.@am__isrc@ +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles am__mv = mv -f @@ -108,6 +109,7 @@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ +BFDLIB = @BFDLIB@ BTLIB = @BTLIB@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ @@ -202,11 +204,14 @@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ c_plugins = @c_plugins@ +charon_natt_port = @charon_natt_port@ +charon_plugins = @charon_plugins@ +charon_udp_port = @charon_udp_port@ clearsilver_LIBS = @clearsilver_LIBS@ datadir = @datadir@ datarootdir = @datarootdir@ dbusservicedir = @dbusservicedir@ -default_pkcs11 = @default_pkcs11@ +dev_headers = @dev_headers@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ @@ -223,11 +228,12 @@ imcvdir = @imcvdir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ +ipsec_script = @ipsec_script@ +ipsec_script_upper = @ipsec_script_upper@ ipsecdir = @ipsecdir@ ipsecgroup = @ipsecgroup@ ipseclibdir = @ipseclibdir@ ipsecuser = @ipsecuser@ -libcharon_plugins = @libcharon_plugins@ libdir = @libdir@ libexecdir = @libexecdir@ linux_headers = @linux_headers@ @@ -243,6 +249,7 @@ mkdir_p = @mkdir_p@ nm_CFLAGS = @nm_CFLAGS@ nm_LIBS = @nm_LIBS@ nm_ca_dir = @nm_ca_dir@ +nm_plugins = @nm_plugins@ oldincludedir = @oldincludedir@ openac_plugins = @openac_plugins@ p_plugins = @p_plugins@ @@ -252,7 +259,6 @@ pdfdir = @pdfdir@ piddir = @piddir@ pki_plugins = @pki_plugins@ plugindir = @plugindir@ -pluto_plugins = @pluto_plugins@ pool_plugins = @pool_plugins@ prefix = @prefix@ program_transform_name = @program_transform_name@ diff --git a/src/libstrongswan/plugins/gcm/gcm_aead.c b/src/libstrongswan/plugins/gcm/gcm_aead.c index 0d7d91dbf..79ee65d98 100644 --- a/src/libstrongswan/plugins/gcm/gcm_aead.c +++ b/src/libstrongswan/plugins/gcm/gcm_aead.c @@ -149,7 +149,7 @@ static void ghash(private_gcm_aead_t *this, chunk_t x, char *res) /** * GCTR function, en-/decrypts x inline */ -static void gctr(private_gcm_aead_t *this, char *icb, chunk_t x) +static bool gctr(private_gcm_aead_t *this, char *icb, chunk_t x) { char cb[BLOCK_SIZE], iv[BLOCK_SIZE], tmp[BLOCK_SIZE]; @@ -159,12 +159,16 @@ static void gctr(private_gcm_aead_t *this, char *icb, chunk_t x) while (x.len) { memcpy(tmp, cb, BLOCK_SIZE); - this->crypter->encrypt(this->crypter, chunk_from_thing(tmp), - chunk_from_thing(iv), NULL); + if (!this->crypter->encrypt(this->crypter, chunk_from_thing(tmp), + chunk_from_thing(iv), NULL)) + { + return FALSE; + } memxor(x.ptr, tmp, min(BLOCK_SIZE, x.len)); chunk_increment(chunk_from_thing(cb)); x = chunk_skip(x, BLOCK_SIZE); } + return TRUE; } /** @@ -180,21 +184,21 @@ static void create_j(private_gcm_aead_t *this, char *iv, char *j) /** * Create GHASH subkey H */ -static void create_h(private_gcm_aead_t *this, char *h) +static bool create_h(private_gcm_aead_t *this, char *h) { char zero[BLOCK_SIZE]; memset(zero, 0, BLOCK_SIZE); memset(h, 0, BLOCK_SIZE); - this->crypter->encrypt(this->crypter, chunk_create(h, BLOCK_SIZE), - chunk_from_thing(zero), NULL); + return this->crypter->encrypt(this->crypter, chunk_create(h, BLOCK_SIZE), + chunk_from_thing(zero), NULL); } /** * Encrypt/decrypt */ -static void crypt(private_gcm_aead_t *this, char *j, chunk_t in, chunk_t out) +static bool crypt(private_gcm_aead_t *this, char *j, chunk_t in, chunk_t out) { char icb[BLOCK_SIZE]; @@ -206,13 +210,13 @@ static void crypt(private_gcm_aead_t *this, char *j, chunk_t in, chunk_t out) { memcpy(out.ptr, in.ptr, in.len); } - gctr(this, icb, out); + return gctr(this, icb, out); } /** * Create ICV */ -static void create_icv(private_gcm_aead_t *this, chunk_t assoc, chunk_t crypt, +static bool create_icv(private_gcm_aead_t *this, chunk_t assoc, chunk_t crypt, char *j, char *icv) { size_t assoc_pad, crypt_pad; @@ -249,9 +253,12 @@ static void create_icv(private_gcm_aead_t *this, chunk_t assoc, chunk_t crypt, ghash(this, chunk, s); free(chunk.ptr); - gctr(this, j, chunk_from_thing(s)); - + if (!gctr(this, j, chunk_from_thing(s))) + { + return FALSE; + } memcpy(icv, s, this->icv_size); + return TRUE; } /** @@ -262,12 +269,11 @@ static bool verify_icv(private_gcm_aead_t *this, chunk_t assoc, chunk_t crypt, { char tmp[this->icv_size]; - create_icv(this, assoc, crypt, j, tmp); - - return memeq(tmp, icv, this->icv_size); + return create_icv(this, assoc, crypt, j, tmp) && + memeq(tmp, icv, this->icv_size); } -METHOD(aead_t, encrypt, void, +METHOD(aead_t, encrypt, bool, private_gcm_aead_t *this, chunk_t plain, chunk_t assoc, chunk_t iv, chunk_t *encrypted) { @@ -278,16 +284,13 @@ METHOD(aead_t, encrypt, void, if (encrypted) { *encrypted = chunk_alloc(plain.len + this->icv_size); - crypt(this, j, plain, *encrypted); - create_icv(this, assoc, - chunk_create(encrypted->ptr, encrypted->len - this->icv_size), - j, encrypted->ptr + encrypted->len - this->icv_size); - } - else - { - crypt(this, j, plain, plain); - create_icv(this, assoc, plain, j, plain.ptr + plain.len); + return crypt(this, j, plain, *encrypted) && + create_icv(this, assoc, + chunk_create(encrypted->ptr, encrypted->len - this->icv_size), + j, encrypted->ptr + encrypted->len - this->icv_size); } + return crypt(this, j, plain, plain) && + create_icv(this, assoc, plain, j, plain.ptr + plain.len); } METHOD(aead_t, decrypt, bool, @@ -311,13 +314,9 @@ METHOD(aead_t, decrypt, bool, if (plain) { *plain = chunk_alloc(encrypted.len); - crypt(this, j, encrypted, *plain); + return crypt(this, j, encrypted, *plain); } - else - { - crypt(this, j, encrypted, encrypted); - } - return TRUE; + return crypt(this, j, encrypted, encrypted); } METHOD(aead_t, get_block_size, size_t, @@ -344,13 +343,13 @@ METHOD(aead_t, get_key_size, size_t, return this->crypter->get_key_size(this->crypter) + SALT_SIZE; } -METHOD(aead_t, set_key, void, +METHOD(aead_t, set_key, bool, private_gcm_aead_t *this, chunk_t key) { memcpy(this->salt, key.ptr + key.len - SALT_SIZE, SALT_SIZE); key.len -= SALT_SIZE; - this->crypter->set_key(this->crypter, key); - create_h(this, this->h); + return this->crypter->set_key(this->crypter, key) && + create_h(this, this->h); } METHOD(aead_t, destroy, void, diff --git a/src/libstrongswan/plugins/gcrypt/Makefile.in b/src/libstrongswan/plugins/gcrypt/Makefile.in index 4dc72fed0..72e525b16 100644 --- a/src/libstrongswan/plugins/gcrypt/Makefile.in +++ b/src/libstrongswan/plugins/gcrypt/Makefile.in @@ -49,6 +49,7 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/config/libtool.m4 \ am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; @@ -86,7 +87,7 @@ libstrongswan_gcrypt_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \ @MONOLITHIC_FALSE@am_libstrongswan_gcrypt_la_rpath = -rpath \ @MONOLITHIC_FALSE@ $(plugindir) @MONOLITHIC_TRUE@am_libstrongswan_gcrypt_la_rpath = -DEFAULT_INCLUDES = -I.@am__isrc@ +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles am__mv = mv -f @@ -112,6 +113,7 @@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ +BFDLIB = @BFDLIB@ BTLIB = @BTLIB@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ @@ -206,11 +208,14 @@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ c_plugins = @c_plugins@ +charon_natt_port = @charon_natt_port@ +charon_plugins = @charon_plugins@ +charon_udp_port = @charon_udp_port@ clearsilver_LIBS = @clearsilver_LIBS@ datadir = @datadir@ datarootdir = @datarootdir@ dbusservicedir = @dbusservicedir@ -default_pkcs11 = @default_pkcs11@ +dev_headers = @dev_headers@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ @@ -227,11 +232,12 @@ imcvdir = @imcvdir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ +ipsec_script = @ipsec_script@ +ipsec_script_upper = @ipsec_script_upper@ ipsecdir = @ipsecdir@ ipsecgroup = @ipsecgroup@ ipseclibdir = @ipseclibdir@ ipsecuser = @ipsecuser@ -libcharon_plugins = @libcharon_plugins@ libdir = @libdir@ libexecdir = @libexecdir@ linux_headers = @linux_headers@ @@ -247,6 +253,7 @@ mkdir_p = @mkdir_p@ nm_CFLAGS = @nm_CFLAGS@ nm_LIBS = @nm_LIBS@ nm_ca_dir = @nm_ca_dir@ +nm_plugins = @nm_plugins@ oldincludedir = @oldincludedir@ openac_plugins = @openac_plugins@ p_plugins = @p_plugins@ @@ -256,7 +263,6 @@ pdfdir = @pdfdir@ piddir = @piddir@ pki_plugins = @pki_plugins@ plugindir = @plugindir@ -pluto_plugins = @pluto_plugins@ pool_plugins = @pool_plugins@ prefix = @prefix@ program_transform_name = @program_transform_name@ diff --git a/src/libstrongswan/plugins/gcrypt/gcrypt_crypter.c b/src/libstrongswan/plugins/gcrypt/gcrypt_crypter.c index 599481911..0b5dc0365 100644 --- a/src/libstrongswan/plugins/gcrypt/gcrypt_crypter.c +++ b/src/libstrongswan/plugins/gcrypt/gcrypt_crypter.c @@ -59,50 +59,47 @@ struct private_gcrypt_crypter_t { /** * Set the IV for en/decryption */ -static void set_iv(private_gcrypt_crypter_t *this, chunk_t iv) +static bool set_iv(private_gcrypt_crypter_t *this, chunk_t iv) { if (this->ctr_mode) { memcpy(this->ctr.iv, iv.ptr, sizeof(this->ctr.iv)); this->ctr.counter = htonl(1); - gcry_cipher_setctr(this->h, &this->ctr, sizeof(this->ctr)); - } - else - { - gcry_cipher_setiv(this->h, iv.ptr, iv.len); + return gcry_cipher_setctr(this->h, &this->ctr, sizeof(this->ctr)) == 0; } + return gcry_cipher_setiv(this->h, iv.ptr, iv.len) == 0; } -METHOD(crypter_t, decrypt, void, +METHOD(crypter_t, decrypt, bool, private_gcrypt_crypter_t *this, chunk_t data, chunk_t iv, chunk_t *dst) { - set_iv(this, iv); - - if (dst) + if (!set_iv(this, iv)) { - *dst = chunk_alloc(data.len); - gcry_cipher_decrypt(this->h, dst->ptr, dst->len, data.ptr, data.len); + return FALSE; } - else + if (dst) { - gcry_cipher_decrypt(this->h, data.ptr, data.len, NULL, 0); + *dst = chunk_alloc(data.len); + return gcry_cipher_decrypt(this->h, dst->ptr, dst->len, + data.ptr, data.len) == 0; } + return gcry_cipher_decrypt(this->h, data.ptr, data.len, NULL, 0) == 0; } -METHOD(crypter_t, encrypt, void, +METHOD(crypter_t, encrypt, bool, private_gcrypt_crypter_t *this, chunk_t data, chunk_t iv, chunk_t *dst) { - set_iv(this, iv); - - if (dst) + if (!set_iv(this, iv)) { - *dst = chunk_alloc(data.len); - gcry_cipher_encrypt(this->h, dst->ptr, dst->len, data.ptr, data.len); + return FALSE; } - else + if (dst) { - gcry_cipher_encrypt(this->h, data.ptr, data.len, NULL, 0); + *dst = chunk_alloc(data.len); + return gcry_cipher_encrypt(this->h, dst->ptr, dst->len, + data.ptr, data.len) == 0; } + return gcry_cipher_encrypt(this->h, data.ptr, data.len, NULL, 0) == 0; } METHOD(crypter_t, get_block_size, size_t, @@ -144,7 +141,7 @@ METHOD(crypter_t, get_key_size, size_t, return len; } -METHOD(crypter_t, set_key, void, +METHOD(crypter_t, set_key, bool, private_gcrypt_crypter_t *this, chunk_t key) { if (this->ctr_mode) @@ -154,7 +151,7 @@ METHOD(crypter_t, set_key, void, sizeof(this->ctr.nonce)); key.len -= sizeof(this->ctr.nonce); } - gcry_cipher_setkey(this->h, key.ptr, key.len); + return gcry_cipher_setkey(this->h, key.ptr, key.len) == 0; } METHOD(crypter_t, destroy, void, diff --git a/src/libstrongswan/plugins/gcrypt/gcrypt_dh.c b/src/libstrongswan/plugins/gcrypt/gcrypt_dh.c index 6c4665da2..0efd3ba16 100644 --- a/src/libstrongswan/plugins/gcrypt/gcrypt_dh.c +++ b/src/libstrongswan/plugins/gcrypt/gcrypt_dh.c @@ -208,9 +208,8 @@ gcrypt_dh_t *create_generic(diffie_hellman_group_t group, size_t exp_len, } rng = lib->crypto->create_rng(lib->crypto, RNG_STRONG); - if (rng) + if (rng && rng->allocate_bytes(rng, exp_len, &random)) { /* prefer external randomizer */ - rng->allocate_bytes(rng, exp_len, &random); rng->destroy(rng); err = gcry_mpi_scan(&this->xa, GCRYMPI_FMT_USG, random.ptr, random.len, NULL); @@ -226,6 +225,7 @@ gcrypt_dh_t *create_generic(diffie_hellman_group_t group, size_t exp_len, } else { /* fallback to gcrypt internal randomizer, shouldn't ever happen */ + DESTROY_IF(rng); this->xa = gcry_mpi_new(exp_len * 8); gcry_mpi_randomize(this->xa, exp_len * 8, GCRY_STRONG_RANDOM); } diff --git a/src/libstrongswan/plugins/gcrypt/gcrypt_hasher.c b/src/libstrongswan/plugins/gcrypt/gcrypt_hasher.c index 96c87614f..3155a4aa0 100644 --- a/src/libstrongswan/plugins/gcrypt/gcrypt_hasher.c +++ b/src/libstrongswan/plugins/gcrypt/gcrypt_hasher.c @@ -43,13 +43,14 @@ METHOD(hasher_t, get_hash_size, size_t, return gcry_md_get_algo_dlen(gcry_md_get_algo(this->hd)); } -METHOD(hasher_t, reset, void, +METHOD(hasher_t, reset, bool, private_gcrypt_hasher_t *this) { gcry_md_reset(this->hd); + return TRUE; } -METHOD(hasher_t, get_hash, void, +METHOD(hasher_t, get_hash, bool, private_gcrypt_hasher_t *this, chunk_t chunk, u_int8_t *hash) { gcry_md_write(this->hd, chunk.ptr, chunk.len); @@ -58,20 +59,18 @@ METHOD(hasher_t, get_hash, void, memcpy(hash, gcry_md_read(this->hd, 0), get_hash_size(this)); gcry_md_reset(this->hd); } + return TRUE; } -METHOD(hasher_t, allocate_hash, void, +METHOD(hasher_t, allocate_hash, bool, private_gcrypt_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); + return get_hash(this, chunk, hash->ptr); } + return get_hash(this, chunk, NULL); } METHOD(hasher_t, destroy, void, diff --git a/src/libstrongswan/plugins/gcrypt/gcrypt_plugin.c b/src/libstrongswan/plugins/gcrypt/gcrypt_plugin.c index a48d4a133..5ebdcebce 100644 --- a/src/libstrongswan/plugins/gcrypt/gcrypt_plugin.c +++ b/src/libstrongswan/plugins/gcrypt/gcrypt_plugin.c @@ -132,9 +132,9 @@ METHOD(plugin_t, get_features, int, PLUGIN_PROVIDE(CRYPTER, ENCR_TWOFISH_CBC, 32), /* hashers */ PLUGIN_REGISTER(HASHER, gcrypt_hasher_create), + PLUGIN_PROVIDE(HASHER, HASH_SHA1), PLUGIN_PROVIDE(HASHER, HASH_MD4), PLUGIN_PROVIDE(HASHER, HASH_MD5), - PLUGIN_PROVIDE(HASHER, HASH_SHA1), PLUGIN_PROVIDE(HASHER, HASH_SHA224), PLUGIN_PROVIDE(HASHER, HASH_SHA256), PLUGIN_PROVIDE(HASHER, HASH_SHA384), diff --git a/src/libstrongswan/plugins/gcrypt/gcrypt_rng.c b/src/libstrongswan/plugins/gcrypt/gcrypt_rng.c index d29755de9..dc34a8d66 100644 --- a/src/libstrongswan/plugins/gcrypt/gcrypt_rng.c +++ b/src/libstrongswan/plugins/gcrypt/gcrypt_rng.c @@ -35,7 +35,7 @@ struct private_gcrypt_rng_t { rng_quality_t quality; }; -METHOD(rng_t, get_bytes, void, +METHOD(rng_t, get_bytes, bool, private_gcrypt_rng_t *this, size_t bytes, u_int8_t *buffer) { switch (this->quality) @@ -50,13 +50,15 @@ METHOD(rng_t, get_bytes, void, gcry_randomize(buffer, bytes, GCRY_VERY_STRONG_RANDOM); break; } + return TRUE; } -METHOD(rng_t, allocate_bytes, void, +METHOD(rng_t, allocate_bytes, bool, private_gcrypt_rng_t *this, size_t bytes, chunk_t *chunk) { *chunk = chunk_alloc(bytes); get_bytes(this, chunk->len, chunk->ptr); + return TRUE; } METHOD(rng_t, destroy, void, diff --git a/src/libstrongswan/plugins/gcrypt/gcrypt_rsa_private_key.c b/src/libstrongswan/plugins/gcrypt/gcrypt_rsa_private_key.c index eb38eea3b..9fdb2d45b 100644 --- a/src/libstrongswan/plugins/gcrypt/gcrypt_rsa_private_key.c +++ b/src/libstrongswan/plugins/gcrypt/gcrypt_rsa_private_key.c @@ -165,11 +165,11 @@ static bool sign_pkcs1(private_gcrypt_rsa_private_key_t *this, return FALSE; } hasher = lib->crypto->create_hasher(lib->crypto, hash_algorithm); - if (!hasher) + if (!hasher || !hasher->allocate_hash(hasher, data, &hash)) { + DESTROY_IF(hasher); return FALSE; } - hasher->allocate_hash(hasher, data, &hash); hasher->destroy(hasher); err = gcry_sexp_build(&in, NULL, "(data(flags pkcs1)(hash %s %b))", diff --git a/src/libstrongswan/plugins/gcrypt/gcrypt_rsa_public_key.c b/src/libstrongswan/plugins/gcrypt/gcrypt_rsa_public_key.c index f8645da97..c54f2c0cf 100644 --- a/src/libstrongswan/plugins/gcrypt/gcrypt_rsa_public_key.c +++ b/src/libstrongswan/plugins/gcrypt/gcrypt_rsa_public_key.c @@ -121,11 +121,11 @@ static bool verify_pkcs1(private_gcrypt_rsa_public_key_t *this, gcry_sexp_t in, sig; hasher = lib->crypto->create_hasher(lib->crypto, algorithm); - if (!hasher) + if (!hasher || !hasher->allocate_hash(hasher, data, &hash)) { + DESTROY_IF(hasher); return FALSE; } - hasher->allocate_hash(hasher, data, &hash); hasher->destroy(hasher); err = gcry_sexp_build(&in, NULL, "(data(flags pkcs1)(hash %s %b))", diff --git a/src/libstrongswan/plugins/gmp/Makefile.in b/src/libstrongswan/plugins/gmp/Makefile.in index 34a23312b..f1bb28c1f 100644 --- a/src/libstrongswan/plugins/gmp/Makefile.in +++ b/src/libstrongswan/plugins/gmp/Makefile.in @@ -49,6 +49,7 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/config/libtool.m4 \ am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; @@ -83,7 +84,7 @@ libstrongswan_gmp_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \ $(libstrongswan_gmp_la_LDFLAGS) $(LDFLAGS) -o $@ @MONOLITHIC_FALSE@am_libstrongswan_gmp_la_rpath = -rpath $(plugindir) @MONOLITHIC_TRUE@am_libstrongswan_gmp_la_rpath = -DEFAULT_INCLUDES = -I.@am__isrc@ +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles am__mv = mv -f @@ -109,6 +110,7 @@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ +BFDLIB = @BFDLIB@ BTLIB = @BTLIB@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ @@ -203,11 +205,14 @@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ c_plugins = @c_plugins@ +charon_natt_port = @charon_natt_port@ +charon_plugins = @charon_plugins@ +charon_udp_port = @charon_udp_port@ clearsilver_LIBS = @clearsilver_LIBS@ datadir = @datadir@ datarootdir = @datarootdir@ dbusservicedir = @dbusservicedir@ -default_pkcs11 = @default_pkcs11@ +dev_headers = @dev_headers@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ @@ -224,11 +229,12 @@ imcvdir = @imcvdir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ +ipsec_script = @ipsec_script@ +ipsec_script_upper = @ipsec_script_upper@ ipsecdir = @ipsecdir@ ipsecgroup = @ipsecgroup@ ipseclibdir = @ipseclibdir@ ipsecuser = @ipsecuser@ -libcharon_plugins = @libcharon_plugins@ libdir = @libdir@ libexecdir = @libexecdir@ linux_headers = @linux_headers@ @@ -244,6 +250,7 @@ mkdir_p = @mkdir_p@ nm_CFLAGS = @nm_CFLAGS@ nm_LIBS = @nm_LIBS@ nm_ca_dir = @nm_ca_dir@ +nm_plugins = @nm_plugins@ oldincludedir = @oldincludedir@ openac_plugins = @openac_plugins@ p_plugins = @p_plugins@ @@ -253,7 +260,6 @@ pdfdir = @pdfdir@ piddir = @piddir@ pki_plugins = @pki_plugins@ plugindir = @plugindir@ -pluto_plugins = @pluto_plugins@ pool_plugins = @pool_plugins@ prefix = @prefix@ program_transform_name = @program_transform_name@ diff --git a/src/libstrongswan/plugins/gmp/gmp_diffie_hellman.c b/src/libstrongswan/plugins/gmp/gmp_diffie_hellman.c index e99502b27..7d232e4f1 100644 --- a/src/libstrongswan/plugins/gmp/gmp_diffie_hellman.c +++ b/src/libstrongswan/plugins/gmp/gmp_diffie_hellman.c @@ -230,8 +230,13 @@ static gmp_diffie_hellman_t *create_generic(diffie_hellman_group_t group, destroy(this); return NULL; } - - rng->allocate_bytes(rng, exp_len, &random); + if (!rng->allocate_bytes(rng, exp_len, &random)) + { + DBG1(DBG_LIB, "failed to allocate DH secret"); + rng->destroy(rng); + destroy(this); + return NULL; + } rng->destroy(rng); if (exp_len == this->p_len) diff --git a/src/libstrongswan/plugins/gmp/gmp_rsa_private_key.c b/src/libstrongswan/plugins/gmp/gmp_rsa_private_key.c index 1b6c20817..590ab6cb4 100644 --- a/src/libstrongswan/plugins/gmp/gmp_rsa_private_key.c +++ b/src/libstrongswan/plugins/gmp/gmp_rsa_private_key.c @@ -149,7 +149,12 @@ static status_t compute_prime(private_gmp_rsa_private_key_t *this, mpz_init(*prime); do { - rng->allocate_bytes(rng, prime_size, &random_bytes); + if (!rng->allocate_bytes(rng, prime_size, &random_bytes)) + { + DBG1(DBG_LIB, "failed to allocate random prime"); + rng->destroy(rng); + return FAILED; + } /* make sure the two most significant bits are set */ random_bytes.ptr[0] = random_bytes.ptr[0] | 0xC0; @@ -230,11 +235,11 @@ static bool build_emsa_pkcs1_signature(private_gmp_rsa_private_key_t *this, } hasher = lib->crypto->create_hasher(lib->crypto, hash_algorithm); - if (hasher == NULL) + if (!hasher || !hasher->allocate_hash(hasher, data, &hash)) { + DESTROY_IF(hasher); return FALSE; } - hasher->allocate_hash(hasher, data, &hash); hasher->destroy(hasher); /* build DER-encoded digestInfo */ diff --git a/src/libstrongswan/plugins/gmp/gmp_rsa_public_key.c b/src/libstrongswan/plugins/gmp/gmp_rsa_public_key.c index 898892f5b..2d84f0025 100644 --- a/src/libstrongswan/plugins/gmp/gmp_rsa_public_key.c +++ b/src/libstrongswan/plugins/gmp/gmp_rsa_public_key.c @@ -252,7 +252,11 @@ static bool verify_emsa_pkcs1_signature(private_gmp_rsa_public_key_t *this, } /* build our own hash and compare */ - hasher->allocate_hash(hasher, data, &hash); + if (!hasher->allocate_hash(hasher, data, &hash)) + { + hasher->destroy(hasher); + goto end_parser; + } hasher->destroy(hasher); success = memeq(object.ptr, hash.ptr, hash.len); free(hash.ptr); @@ -314,7 +318,7 @@ METHOD(public_key_t, encrypt_, bool, { chunk_t em; u_char *pos; - int padding, i; + int padding; rng_t *rng; if (scheme != ENCRYPT_RSA_PKCS1) @@ -348,16 +352,12 @@ METHOD(public_key_t, encrypt_, bool, *pos++ = 0x02; /* fill with pseudo random octets */ - rng->get_bytes(rng, padding, pos); - - /* replace zero-valued random octets */ - for (i = 0; i < padding; i++) + if (!rng_get_bytes_not_zero(rng, padding, pos, TRUE)) { - while (*pos == 0) - { - rng->get_bytes(rng, 1, pos); - } - pos++; + DBG1(DBG_LIB, "failed to allocate padding"); + chunk_clear(&em); + rng->destroy(rng); + return FALSE; } rng->destroy(rng); diff --git a/src/libstrongswan/plugins/hmac/Makefile.am b/src/libstrongswan/plugins/hmac/Makefile.am index 77aa0ffd1..4faf321ef 100644 --- a/src/libstrongswan/plugins/hmac/Makefile.am +++ b/src/libstrongswan/plugins/hmac/Makefile.am @@ -10,7 +10,6 @@ plugin_LTLIBRARIES = libstrongswan-hmac.la endif 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 + hmac_plugin.h hmac_plugin.c hmac.h hmac.c libstrongswan_hmac_la_LDFLAGS = -module -avoid-version diff --git a/src/libstrongswan/plugins/hmac/Makefile.in b/src/libstrongswan/plugins/hmac/Makefile.in index 5242764d4..aed35cf16 100644 --- a/src/libstrongswan/plugins/hmac/Makefile.in +++ b/src/libstrongswan/plugins/hmac/Makefile.in @@ -49,6 +49,7 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/config/libtool.m4 \ am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; @@ -75,15 +76,14 @@ am__base_list = \ am__installdirs = "$(DESTDIR)$(plugindir)" LTLIBRARIES = $(noinst_LTLIBRARIES) $(plugin_LTLIBRARIES) libstrongswan_hmac_la_LIBADD = -am_libstrongswan_hmac_la_OBJECTS = hmac_plugin.lo hmac.lo hmac_prf.lo \ - hmac_signer.lo +am_libstrongswan_hmac_la_OBJECTS = hmac_plugin.lo hmac.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 $@ @MONOLITHIC_FALSE@am_libstrongswan_hmac_la_rpath = -rpath $(plugindir) @MONOLITHIC_TRUE@am_libstrongswan_hmac_la_rpath = -DEFAULT_INCLUDES = -I.@am__isrc@ +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles am__mv = mv -f @@ -109,6 +109,7 @@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ +BFDLIB = @BFDLIB@ BTLIB = @BTLIB@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ @@ -203,11 +204,14 @@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ c_plugins = @c_plugins@ +charon_natt_port = @charon_natt_port@ +charon_plugins = @charon_plugins@ +charon_udp_port = @charon_udp_port@ clearsilver_LIBS = @clearsilver_LIBS@ datadir = @datadir@ datarootdir = @datarootdir@ dbusservicedir = @dbusservicedir@ -default_pkcs11 = @default_pkcs11@ +dev_headers = @dev_headers@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ @@ -224,11 +228,12 @@ imcvdir = @imcvdir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ +ipsec_script = @ipsec_script@ +ipsec_script_upper = @ipsec_script_upper@ ipsecdir = @ipsecdir@ ipsecgroup = @ipsecgroup@ ipseclibdir = @ipseclibdir@ ipsecuser = @ipsecuser@ -libcharon_plugins = @libcharon_plugins@ libdir = @libdir@ libexecdir = @libexecdir@ linux_headers = @linux_headers@ @@ -244,6 +249,7 @@ mkdir_p = @mkdir_p@ nm_CFLAGS = @nm_CFLAGS@ nm_LIBS = @nm_LIBS@ nm_ca_dir = @nm_ca_dir@ +nm_plugins = @nm_plugins@ oldincludedir = @oldincludedir@ openac_plugins = @openac_plugins@ p_plugins = @p_plugins@ @@ -253,7 +259,6 @@ pdfdir = @pdfdir@ piddir = @piddir@ pki_plugins = @pki_plugins@ plugindir = @plugindir@ -pluto_plugins = @pluto_plugins@ pool_plugins = @pool_plugins@ prefix = @prefix@ program_transform_name = @program_transform_name@ @@ -286,8 +291,7 @@ AM_CFLAGS = -rdynamic @MONOLITHIC_TRUE@noinst_LTLIBRARIES = libstrongswan-hmac.la @MONOLITHIC_FALSE@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 + hmac_plugin.h hmac_plugin.c hmac.h hmac.c libstrongswan_hmac_la_LDFLAGS = -module -avoid-version all: all-am @@ -375,8 +379,6 @@ distclean-compile: @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 $@ $< diff --git a/src/libstrongswan/plugins/hmac/hmac.c b/src/libstrongswan/plugins/hmac/hmac.c index 91294305e..44cb46b4d 100644 --- a/src/libstrongswan/plugins/hmac/hmac.c +++ b/src/libstrongswan/plugins/hmac/hmac.c @@ -1,4 +1,5 @@ /* + * Copyright (C) 2012 Tobias Brunner * Copyright (C) 2005-2006 Martin Willi * Copyright (C) 2005 Jan Hutter * Hochschule fuer Technik Rapperswil @@ -14,23 +15,25 @@ * for more details. */ -#include <string.h> - #include "hmac.h" +#include <crypto/mac.h> +#include <crypto/prfs/mac_prf.h> +#include <crypto/signers/mac_signer.h> -typedef struct private_hmac_t private_hmac_t; +typedef struct private_mac_t private_mac_t; /** - * Private data of a hmac_t object. + * Private data of a mac_t object. * * The variable names are the same as in the RFC. */ -struct private_hmac_t { +struct private_mac_t { + /** - * Public hmac_t interface. + * Implements mac_t interface */ - hmac_t public; + mac_t public; /** * Block size, as in RFC. @@ -53,8 +56,8 @@ struct private_hmac_t { chunk_t ipaded_key; }; -METHOD(hmac_t, get_mac, void, - private_hmac_t *this, chunk_t data, u_int8_t *out) +METHOD(mac_t, get_mac, bool, + private_mac_t *this, chunk_t data, u_int8_t *out) { /* H(K XOR opad, H(K XOR ipad, text)) * @@ -69,51 +72,28 @@ METHOD(hmac_t, get_mac, void, if (out == NULL) { /* append data to inner */ - this->h->get_hash(this->h, data, NULL); + return this->h->get_hash(this->h, data, NULL); } - else - { - /* append and do outer hash */ - inner.ptr = buffer; - inner.len = this->h->get_hash_size(this->h); - - /* complete inner */ - this->h->get_hash(this->h, data, buffer); - /* do outer */ - this->h->get_hash(this->h, this->opaded_key, NULL); - this->h->get_hash(this->h, inner, out); + /* append and do outer hash */ + inner.ptr = buffer; + inner.len = this->h->get_hash_size(this->h); - /* reinit for next call */ - this->h->get_hash(this->h, this->ipaded_key, NULL); - } + /* complete inner, do outer and reinit for next call */ + return this->h->get_hash(this->h, data, buffer) && + this->h->get_hash(this->h, this->opaded_key, NULL) && + this->h->get_hash(this->h, inner, out) && + this->h->get_hash(this->h, this->ipaded_key, NULL); } -METHOD(hmac_t, allocate_mac, void, - private_hmac_t *this, chunk_t data, chunk_t *out) -{ - /* allocate space and use get_mac */ - if (out == NULL) - { - /* append mode */ - get_mac(this, data, NULL); - } - else - { - out->len = this->h->get_hash_size(this->h); - out->ptr = malloc(out->len); - get_mac(this, data, out->ptr); - } -} - -METHOD(hmac_t, get_block_size, size_t, - private_hmac_t *this) +METHOD(mac_t, get_mac_size, size_t, + private_mac_t *this) { return this->h->get_hash_size(this->h); } -METHOD(hmac_t, set_key, void, - private_hmac_t *this, chunk_t key) +METHOD(mac_t, set_key, bool, + private_mac_t *this, chunk_t key) { int i; u_int8_t buffer[this->b]; @@ -123,7 +103,10 @@ METHOD(hmac_t, set_key, void, if (key.len > this->b) { /* if key is too long, it will be hashed */ - this->h->get_hash(this->h, key, buffer); + if (!this->h->get_hash(this->h, key, buffer)) + { + return FALSE; + } } else { @@ -139,12 +122,12 @@ METHOD(hmac_t, set_key, void, } /* begin hashing of inner pad */ - this->h->reset(this->h); - this->h->get_hash(this->h, this->ipaded_key, NULL); + return this->h->reset(this->h) && + this->h->get_hash(this->h, this->ipaded_key, NULL); } -METHOD(hmac_t, destroy, void, - private_hmac_t *this) +METHOD(mac_t, destroy, void, + private_mac_t *this) { this->h->destroy(this->h); chunk_clear(&this->opaded_key); @@ -153,17 +136,16 @@ METHOD(hmac_t, destroy, void, } /* - * Described in header + * Creates an mac_t object */ -hmac_t *hmac_create(hash_algorithm_t hash_algorithm) +static mac_t *hmac_create(hash_algorithm_t hash_algorithm) { - private_hmac_t *this; + private_mac_t *this; INIT(this, .public = { .get_mac = _get_mac, - .allocate_mac = _allocate_mac, - .get_block_size = _get_block_size, + .get_mac_size = _get_mac_size, .set_key = _set_key, .destroy = _destroy, }, @@ -202,3 +184,34 @@ hmac_t *hmac_create(hash_algorithm_t hash_algorithm) return &this->public; } + +/* + * Described in header + */ +prf_t *hmac_prf_create(pseudo_random_function_t algo) +{ + mac_t *hmac; + + hmac = hmac_create(hasher_algorithm_from_prf(algo)); + if (hmac) + { + return mac_prf_create(hmac); + } + return NULL; +} + +/* + * Described in header + */ +signer_t *hmac_signer_create(integrity_algorithm_t algo) +{ + mac_t *hmac; + size_t trunc; + + hmac = hmac_create(hasher_algorithm_from_integrity(algo, &trunc)); + if (hmac) + { + return mac_signer_create(hmac, trunc); + } + return NULL; +} diff --git a/src/libstrongswan/plugins/hmac/hmac.h b/src/libstrongswan/plugins/hmac/hmac.h index 1ed041596..bf66dd4aa 100644 --- a/src/libstrongswan/plugins/hmac/hmac.h +++ b/src/libstrongswan/plugins/hmac/hmac.h @@ -1,6 +1,5 @@ /* - * Copyright (C) 2005-2008 Martin Willi - * Copyright (C) 2005 Jan Hutter + * Copyright (C) 2012 Tobias Brunner * Hochschule fuer Technik Rapperswil * * This program is free software; you can redistribute it and/or modify it @@ -15,79 +14,34 @@ */ /** - * @defgroup hmac hmac + * Implements the message authentication algorithm described in RFC2104. + * + * It uses a hash function, which must be implemented as a hasher_t class. + * + * @defgroup hmac_mac mac * @{ @ingroup hmac_p */ #ifndef HMAC_H_ #define HMAC_H_ -typedef struct hmac_t hmac_t; - -#include <crypto/hashers/hasher.h> +#include <crypto/prfs/prf.h> +#include <crypto/signers/signer.h> /** - * Message authentication using hash functions. + * Creates a new prf_t object based on an HMAC. * - * This class implements the message authentication algorithm - * described in RFC2104. It uses a hash function, which must - * be implemented as a hasher_t class. + * @param algo algorithm to implement + * @return prf_t object, NULL if not supported */ -struct hmac_t { - /** - * Generate message authentication code. - * - * If buffer is NULL, no result is given back. A next call will - * append the data to already supplied data. If buffer is not NULL, - * the mac of all apended data is calculated, returned and the - * state of the hmac_t is reseted. - * - * @param data chunk of data to authenticate - * @param buffer pointer where the generated bytes will be written - */ - void (*get_mac) (hmac_t *this, chunk_t data, u_int8_t *buffer); - - /** - * Generates message authentication code and allocate space for them. - * - * If chunk is NULL, no result is given back. A next call will - * append the data to already supplied. If chunk is not NULL, - * the mac of all apended data is calculated, returned and the - * state of the hmac_t reset; - * - * @param data chunk of data to authenticate - * @param chunk chunk which will hold generated bytes - */ - void (*allocate_mac) (hmac_t *this, chunk_t data, chunk_t *chunk); - - /** - * Get the block size of this hmac_t object. - * - * @return block size in bytes - */ - size_t (*get_block_size) (hmac_t *this); - - /** - * Set the key for this hmac_t object. - * - * Any key length is accepted. - * - * @param key key to set - */ - void (*set_key) (hmac_t *this, chunk_t key); - - /** - * Destroys a hmac_t object. - */ - void (*destroy) (hmac_t *this); -}; +prf_t *hmac_prf_create(pseudo_random_function_t algo); /** - * Creates a new hmac_t object. + * Creates a new signer_t object based on an HMAC. * - * @param hash_algorithm hash algorithm to use - * @return hmac_t object, NULL if not supported + * @param algo algorithm to implement + * @return signer_t, NULL if not supported */ -hmac_t *hmac_create(hash_algorithm_t hash_algorithm); +signer_t *hmac_signer_create(integrity_algorithm_t algo); #endif /** HMAC_H_ @}*/ diff --git a/src/libstrongswan/plugins/hmac/hmac_plugin.c b/src/libstrongswan/plugins/hmac/hmac_plugin.c index 7d9ff3c67..f9c0c484b 100644 --- a/src/libstrongswan/plugins/hmac/hmac_plugin.c +++ b/src/libstrongswan/plugins/hmac/hmac_plugin.c @@ -16,8 +16,7 @@ #include "hmac_plugin.h" #include <library.h> -#include "hmac_signer.h" -#include "hmac_prf.h" +#include "hmac.h" typedef struct private_hmac_plugin_t private_hmac_plugin_t; diff --git a/src/libstrongswan/plugins/hmac/hmac_prf.c b/src/libstrongswan/plugins/hmac/hmac_prf.c deleted file mode 100644 index ca10612f9..000000000 --- a/src/libstrongswan/plugins/hmac/hmac_prf.c +++ /dev/null @@ -1,126 +0,0 @@ -/* - * 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 "hmac_prf.h" - -#include "hmac.h" - - -typedef struct private_hmac_prf_t private_hmac_prf_t; - -/** - * Private data of a hma_prf_t object. - */ -struct private_hmac_prf_t { - /** - * Public hmac_prf_t interface. - */ - hmac_prf_t public; - - /** - * Hmac to use for generation. - */ - hmac_t *hmac; -}; - -METHOD(prf_t, get_bytes, void, - private_hmac_prf_t *this, chunk_t seed, u_int8_t *buffer) -{ - this->hmac->get_mac(this->hmac, seed, buffer); -} - -METHOD(prf_t, allocate_bytes, void, - private_hmac_prf_t *this, chunk_t seed, chunk_t *chunk) -{ - this->hmac->allocate_mac(this->hmac, seed, chunk); -} - -METHOD(prf_t, get_block_size, size_t, - private_hmac_prf_t *this) -{ - return this->hmac->get_block_size(this->hmac); -} - -METHOD(prf_t, get_key_size, size_t, - private_hmac_prf_t *this) -{ - /* for HMAC prfs, IKEv2 uses block size as key size */ - return this->hmac->get_block_size(this->hmac); -} - -METHOD(prf_t, set_key, void, - private_hmac_prf_t *this, chunk_t key) -{ - this->hmac->set_key(this->hmac, key); -} - -METHOD(prf_t, destroy, void, - private_hmac_prf_t *this) -{ - this->hmac->destroy(this->hmac); - free(this); -} - -/* - * Described in header. - */ -hmac_prf_t *hmac_prf_create(pseudo_random_function_t algo) -{ - private_hmac_prf_t *this; - hmac_t *hmac; - - switch (algo) - { - case PRF_HMAC_SHA1: - hmac = hmac_create(HASH_SHA1); - break; - case PRF_HMAC_MD5: - hmac = hmac_create(HASH_MD5); - break; - case PRF_HMAC_SHA2_256: - hmac = hmac_create(HASH_SHA256); - break; - case PRF_HMAC_SHA2_384: - hmac = hmac_create(HASH_SHA384); - break; - case PRF_HMAC_SHA2_512: - hmac = hmac_create(HASH_SHA512); - break; - default: - return NULL; - } - if (hmac == NULL) - { - return NULL; - } - - INIT(this, - .public = { - .prf = { - .get_bytes = _get_bytes, - .allocate_bytes = _allocate_bytes, - .get_block_size = _get_block_size, - .get_key_size = _get_key_size, - .set_key = _set_key, - .destroy = _destroy, - }, - }, - .hmac = hmac, - ); - - return &this->public; -} - diff --git a/src/libstrongswan/plugins/hmac/hmac_prf.h b/src/libstrongswan/plugins/hmac/hmac_prf.h deleted file mode 100644 index 29d7269ae..000000000 --- a/src/libstrongswan/plugins/hmac/hmac_prf.h +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright (C) 2008 Martin Willi - * Copyright (C) 2005 Jan Hutter - * Hochschule fuer Technik Rapperswil - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * for more details. - */ - -/** - * @defgroup hmac_prf hmac_prf - * @{ @ingroup hmac_p - */ - -#ifndef PRF_HMAC_H_ -#define PRF_HMAC_H_ - -typedef struct hmac_prf_t hmac_prf_t; - -#include <crypto/prfs/prf.h> - -/** - * Implementation of prf_t interface using the HMAC algorithm. - * - * This simply wraps a hmac_t in a prf_t. More a question of - * interface matching. - */ -struct hmac_prf_t { - - /** - * Implements prf_t interface. - */ - prf_t prf; -}; - -/** - * Creates a new hmac_prf_t object. - * - * @param algo algorithm to implement - * @return hmac_prf_t object, NULL if hash not supported - */ -hmac_prf_t *hmac_prf_create(pseudo_random_function_t algo); - -#endif /** PRF_HMAC_SHA1_H_ @}*/ diff --git a/src/libstrongswan/plugins/hmac/hmac_signer.c b/src/libstrongswan/plugins/hmac/hmac_signer.c deleted file mode 100644 index 511a3e3a5..000000000 --- a/src/libstrongswan/plugins/hmac/hmac_signer.c +++ /dev/null @@ -1,197 +0,0 @@ -/* - * 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. - */ - -#include <string.h> - -#include "hmac_signer.h" -#include "hmac.h" - -typedef struct private_hmac_signer_t private_hmac_signer_t; - -/** - * Private data structure with signing context. - */ -struct private_hmac_signer_t { - /** - * Public interface of hmac_signer_t. - */ - hmac_signer_t public; - - /** - * Assigned hmac function. - */ - hmac_t *hmac; - - /** - * Block size (truncation of HMAC Hash) - */ - size_t block_size; -}; - -METHOD(signer_t, get_signature, void, - private_hmac_signer_t *this, chunk_t data, u_int8_t *buffer) -{ - if (buffer == NULL) - { /* append mode */ - this->hmac->get_mac(this->hmac, data, NULL); - } - else - { - u_int8_t mac[this->hmac->get_block_size(this->hmac)]; - - this->hmac->get_mac(this->hmac, data, mac); - memcpy(buffer, mac, this->block_size); - } -} - -METHOD(signer_t, allocate_signature, void, - private_hmac_signer_t *this, chunk_t data, chunk_t *chunk) -{ - if (chunk == NULL) - { /* append mode */ - this->hmac->get_mac(this->hmac, data, NULL); - } - else - { - u_int8_t mac[this->hmac->get_block_size(this->hmac)]; - - this->hmac->get_mac(this->hmac, data, mac); - - chunk->ptr = malloc(this->block_size); - chunk->len = this->block_size; - - memcpy(chunk->ptr, mac, this->block_size); - } -} - -METHOD(signer_t, verify_signature, bool, - private_hmac_signer_t *this, chunk_t data, chunk_t signature) -{ - u_int8_t mac[this->hmac->get_block_size(this->hmac)]; - - this->hmac->get_mac(this->hmac, data, mac); - - if (signature.len != this->block_size) - { - return FALSE; - } - return memeq(signature.ptr, mac, this->block_size); -} - -METHOD(signer_t, get_key_size, size_t, - private_hmac_signer_t *this) -{ - return this->hmac->get_block_size(this->hmac); -} - -METHOD(signer_t, get_block_size, size_t, - private_hmac_signer_t *this) -{ - return this->block_size; -} - -METHOD(signer_t, set_key, void, - private_hmac_signer_t *this, chunk_t key) -{ - this->hmac->set_key(this->hmac, key); -} - -METHOD(signer_t, destroy, void, - private_hmac_signer_t *this) -{ - this->hmac->destroy(this->hmac); - free(this); -} - -/* - * Described in header - */ -hmac_signer_t *hmac_signer_create(integrity_algorithm_t algo) -{ - private_hmac_signer_t *this; - hmac_t *hmac; - size_t trunc; - - switch (algo) - { - case AUTH_HMAC_SHA1_96: - hmac = hmac_create(HASH_SHA1); - trunc = 12; - break; - case AUTH_HMAC_SHA1_128: - hmac = hmac_create(HASH_SHA1); - trunc = 16; - break; - case AUTH_HMAC_SHA1_160: - hmac = hmac_create(HASH_SHA1); - trunc = 20; - break; - case AUTH_HMAC_MD5_96: - hmac = hmac_create(HASH_MD5); - trunc = 12; - break; - case AUTH_HMAC_MD5_128: - hmac = hmac_create(HASH_MD5); - trunc = 16; - break; - case AUTH_HMAC_SHA2_256_128: - hmac = hmac_create(HASH_SHA256); - trunc = 16; - break; - case AUTH_HMAC_SHA2_384_192: - hmac = hmac_create(HASH_SHA384); - trunc = 24; - break; - case AUTH_HMAC_SHA2_512_256: - hmac = hmac_create(HASH_SHA512); - trunc = 32; - break; - case AUTH_HMAC_SHA2_256_256: - hmac = hmac_create(HASH_SHA256); - trunc = 32; - break; - case AUTH_HMAC_SHA2_384_384: - hmac = hmac_create(HASH_SHA384); - trunc = 48; - break; - default: - return NULL; - } - - if (hmac == NULL) - { - return NULL; - } - - INIT(this, - .public = { - .signer = { - .get_signature = _get_signature, - .allocate_signature = _allocate_signature, - .verify_signature = _verify_signature, - .get_key_size = _get_key_size, - .get_block_size = _get_block_size, - .set_key = _set_key, - .destroy = _destroy, - }, - }, - .block_size = min(trunc, hmac->get_block_size(hmac)), - .hmac = hmac, - ); - - return &this->public; -} - diff --git a/src/libstrongswan/plugins/hmac/hmac_signer.h b/src/libstrongswan/plugins/hmac/hmac_signer.h deleted file mode 100644 index 5e798683b..000000000 --- a/src/libstrongswan/plugins/hmac/hmac_signer.h +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright (C) 2005-2008 Martin Willi - * Copyright (C) 2005 Jan Hutter - * Hochschule fuer Technik Rapperswil - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * for more details. - */ - -/** - * @defgroup hmac_signer hmac_signer - * @{ @ingroup hmac_p - */ - -#ifndef HMAC_SIGNER_H_ -#define HMAC_SIGNER_H_ - -typedef struct hmac_signer_t hmac_signer_t; - -#include <crypto/signers/signer.h> - -/** - * Implementation of signer_t interface using HMAC. - * - * HMAC uses a standard hash function implemented in a hasher_t to build a MAC. - */ -struct hmac_signer_t { - - /** - * Implements signer_t interface. - */ - signer_t signer; -}; - -/** - * Creates a new hmac_signer_t. - * - * HMAC signatures are often truncated to shorten them to a more usable, but - * still secure enough length. - * Block size must be equal or smaller then the hash algorithms hash. - * - * @param algo algorithm to implement - * @return hmac_signer_t, NULL if not supported - */ -hmac_signer_t *hmac_signer_create(integrity_algorithm_t algo); - -#endif /** HMAC_SIGNER_H_ @}*/ diff --git a/src/libstrongswan/plugins/ldap/Makefile.in b/src/libstrongswan/plugins/ldap/Makefile.in index 851df5667..d11feddb1 100644 --- a/src/libstrongswan/plugins/ldap/Makefile.in +++ b/src/libstrongswan/plugins/ldap/Makefile.in @@ -49,6 +49,7 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/config/libtool.m4 \ am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; @@ -82,7 +83,7 @@ libstrongswan_ldap_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \ $(libstrongswan_ldap_la_LDFLAGS) $(LDFLAGS) -o $@ @MONOLITHIC_FALSE@am_libstrongswan_ldap_la_rpath = -rpath $(plugindir) @MONOLITHIC_TRUE@am_libstrongswan_ldap_la_rpath = -DEFAULT_INCLUDES = -I.@am__isrc@ +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles am__mv = mv -f @@ -108,6 +109,7 @@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ +BFDLIB = @BFDLIB@ BTLIB = @BTLIB@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ @@ -202,11 +204,14 @@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ c_plugins = @c_plugins@ +charon_natt_port = @charon_natt_port@ +charon_plugins = @charon_plugins@ +charon_udp_port = @charon_udp_port@ clearsilver_LIBS = @clearsilver_LIBS@ datadir = @datadir@ datarootdir = @datarootdir@ dbusservicedir = @dbusservicedir@ -default_pkcs11 = @default_pkcs11@ +dev_headers = @dev_headers@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ @@ -223,11 +228,12 @@ imcvdir = @imcvdir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ +ipsec_script = @ipsec_script@ +ipsec_script_upper = @ipsec_script_upper@ ipsecdir = @ipsecdir@ ipsecgroup = @ipsecgroup@ ipseclibdir = @ipseclibdir@ ipsecuser = @ipsecuser@ -libcharon_plugins = @libcharon_plugins@ libdir = @libdir@ libexecdir = @libexecdir@ linux_headers = @linux_headers@ @@ -243,6 +249,7 @@ mkdir_p = @mkdir_p@ nm_CFLAGS = @nm_CFLAGS@ nm_LIBS = @nm_LIBS@ nm_ca_dir = @nm_ca_dir@ +nm_plugins = @nm_plugins@ oldincludedir = @oldincludedir@ openac_plugins = @openac_plugins@ p_plugins = @p_plugins@ @@ -252,7 +259,6 @@ pdfdir = @pdfdir@ piddir = @piddir@ pki_plugins = @pki_plugins@ plugindir = @plugindir@ -pluto_plugins = @pluto_plugins@ pool_plugins = @pool_plugins@ prefix = @prefix@ program_transform_name = @program_transform_name@ diff --git a/src/libstrongswan/plugins/ldap/ldap_fetcher.c b/src/libstrongswan/plugins/ldap/ldap_fetcher.c index fc6114b0a..75f964853 100644 --- a/src/libstrongswan/plugins/ldap/ldap_fetcher.c +++ b/src/libstrongswan/plugins/ldap/ldap_fetcher.c @@ -176,13 +176,14 @@ METHOD(fetcher_t, set_option, bool, switch (option) { case FETCH_TIMEOUT: - { this->timeout = va_arg(args, u_int); - return TRUE; - } + break; default: + va_end(args); return FALSE; } + va_end(args); + return TRUE; } METHOD(fetcher_t, destroy, void, diff --git a/src/libstrongswan/plugins/md4/Makefile.in b/src/libstrongswan/plugins/md4/Makefile.in index f5b06a0df..14b6370f4 100644 --- a/src/libstrongswan/plugins/md4/Makefile.in +++ b/src/libstrongswan/plugins/md4/Makefile.in @@ -49,6 +49,7 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/config/libtool.m4 \ am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; @@ -82,7 +83,7 @@ libstrongswan_md4_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \ $(libstrongswan_md4_la_LDFLAGS) $(LDFLAGS) -o $@ @MONOLITHIC_FALSE@am_libstrongswan_md4_la_rpath = -rpath $(plugindir) @MONOLITHIC_TRUE@am_libstrongswan_md4_la_rpath = -DEFAULT_INCLUDES = -I.@am__isrc@ +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles am__mv = mv -f @@ -108,6 +109,7 @@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ +BFDLIB = @BFDLIB@ BTLIB = @BTLIB@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ @@ -202,11 +204,14 @@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ c_plugins = @c_plugins@ +charon_natt_port = @charon_natt_port@ +charon_plugins = @charon_plugins@ +charon_udp_port = @charon_udp_port@ clearsilver_LIBS = @clearsilver_LIBS@ datadir = @datadir@ datarootdir = @datarootdir@ dbusservicedir = @dbusservicedir@ -default_pkcs11 = @default_pkcs11@ +dev_headers = @dev_headers@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ @@ -223,11 +228,12 @@ imcvdir = @imcvdir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ +ipsec_script = @ipsec_script@ +ipsec_script_upper = @ipsec_script_upper@ ipsecdir = @ipsecdir@ ipsecgroup = @ipsecgroup@ ipseclibdir = @ipseclibdir@ ipsecuser = @ipsecuser@ -libcharon_plugins = @libcharon_plugins@ libdir = @libdir@ libexecdir = @libexecdir@ linux_headers = @linux_headers@ @@ -243,6 +249,7 @@ mkdir_p = @mkdir_p@ nm_CFLAGS = @nm_CFLAGS@ nm_LIBS = @nm_LIBS@ nm_ca_dir = @nm_ca_dir@ +nm_plugins = @nm_plugins@ oldincludedir = @oldincludedir@ openac_plugins = @openac_plugins@ p_plugins = @p_plugins@ @@ -252,7 +259,6 @@ pdfdir = @pdfdir@ piddir = @piddir@ pki_plugins = @pki_plugins@ plugindir = @plugindir@ -pluto_plugins = @pluto_plugins@ pool_plugins = @pool_plugins@ prefix = @prefix@ program_transform_name = @program_transform_name@ diff --git a/src/libstrongswan/plugins/md4/md4_hasher.c b/src/libstrongswan/plugins/md4/md4_hasher.c index 6a31017c2..06c9ec2f8 100644 --- a/src/libstrongswan/plugins/md4/md4_hasher.c +++ b/src/libstrongswan/plugins/md4/md4_hasher.c @@ -266,20 +266,32 @@ static void MD4Final (private_md4_hasher_t *this, u_int8_t digest[16]) } } +METHOD(hasher_t, reset, bool, + private_md4_hasher_t *this) +{ + this->state[0] = 0x67452301; + this->state[1] = 0xefcdab89; + this->state[2] = 0x98badcfe; + this->state[3] = 0x10325476; + this->count[0] = 0; + this->count[1] = 0; + return TRUE; +} -METHOD(hasher_t, get_hash, void, +METHOD(hasher_t, get_hash, bool, private_md4_hasher_t *this, chunk_t chunk, u_int8_t *buffer) { MD4Update(this, chunk.ptr, chunk.len); if (buffer != NULL) { MD4Final(this, buffer); - this->public.hasher_interface.reset(&(this->public.hasher_interface)); + reset(this); } + return TRUE; } -METHOD(hasher_t, allocate_hash, void, +METHOD(hasher_t, allocate_hash, bool, private_md4_hasher_t *this, chunk_t chunk, chunk_t *hash) { chunk_t allocated_hash; @@ -291,10 +303,11 @@ METHOD(hasher_t, allocate_hash, void, allocated_hash.len = HASH_SIZE_MD4; MD4Final(this, allocated_hash.ptr); - this->public.hasher_interface.reset(&(this->public.hasher_interface)); + reset(this); *hash = allocated_hash; } + return TRUE; } METHOD(hasher_t, get_hash_size, size_t, @@ -303,17 +316,6 @@ METHOD(hasher_t, get_hash_size, size_t, return HASH_SIZE_MD4; } -METHOD(hasher_t, reset, void, - private_md4_hasher_t *this) -{ - this->state[0] = 0x67452301; - this->state[1] = 0xefcdab89; - this->state[2] = 0x98badcfe; - this->state[3] = 0x10325476; - this->count[0] = 0; - this->count[1] = 0; -} - METHOD(hasher_t, destroy, void, private_md4_hasher_t *this) { diff --git a/src/libstrongswan/plugins/md5/Makefile.in b/src/libstrongswan/plugins/md5/Makefile.in index f7762c37e..ba228f8ea 100644 --- a/src/libstrongswan/plugins/md5/Makefile.in +++ b/src/libstrongswan/plugins/md5/Makefile.in @@ -49,6 +49,7 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/config/libtool.m4 \ am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; @@ -82,7 +83,7 @@ libstrongswan_md5_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \ $(libstrongswan_md5_la_LDFLAGS) $(LDFLAGS) -o $@ @MONOLITHIC_FALSE@am_libstrongswan_md5_la_rpath = -rpath $(plugindir) @MONOLITHIC_TRUE@am_libstrongswan_md5_la_rpath = -DEFAULT_INCLUDES = -I.@am__isrc@ +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles am__mv = mv -f @@ -108,6 +109,7 @@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ +BFDLIB = @BFDLIB@ BTLIB = @BTLIB@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ @@ -202,11 +204,14 @@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ c_plugins = @c_plugins@ +charon_natt_port = @charon_natt_port@ +charon_plugins = @charon_plugins@ +charon_udp_port = @charon_udp_port@ clearsilver_LIBS = @clearsilver_LIBS@ datadir = @datadir@ datarootdir = @datarootdir@ dbusservicedir = @dbusservicedir@ -default_pkcs11 = @default_pkcs11@ +dev_headers = @dev_headers@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ @@ -223,11 +228,12 @@ imcvdir = @imcvdir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ +ipsec_script = @ipsec_script@ +ipsec_script_upper = @ipsec_script_upper@ ipsecdir = @ipsecdir@ ipsecgroup = @ipsecgroup@ ipseclibdir = @ipseclibdir@ ipsecuser = @ipsecuser@ -libcharon_plugins = @libcharon_plugins@ libdir = @libdir@ libexecdir = @libexecdir@ linux_headers = @linux_headers@ @@ -243,6 +249,7 @@ mkdir_p = @mkdir_p@ nm_CFLAGS = @nm_CFLAGS@ nm_LIBS = @nm_LIBS@ nm_ca_dir = @nm_ca_dir@ +nm_plugins = @nm_plugins@ oldincludedir = @oldincludedir@ openac_plugins = @openac_plugins@ p_plugins = @p_plugins@ @@ -252,7 +259,6 @@ pdfdir = @pdfdir@ piddir = @piddir@ pki_plugins = @pki_plugins@ plugindir = @plugindir@ -pluto_plugins = @pluto_plugins@ pool_plugins = @pool_plugins@ prefix = @prefix@ program_transform_name = @program_transform_name@ diff --git a/src/libstrongswan/plugins/md5/md5_hasher.c b/src/libstrongswan/plugins/md5/md5_hasher.c index 45c2391ef..99b505e58 100644 --- a/src/libstrongswan/plugins/md5/md5_hasher.c +++ b/src/libstrongswan/plugins/md5/md5_hasher.c @@ -299,33 +299,42 @@ static void MD5Final (private_md5_hasher_t *this, u_int8_t digest[16]) } } -METHOD(hasher_t, get_hash, void, +METHOD(hasher_t, reset, bool, + private_md5_hasher_t *this) +{ + this->state[0] = 0x67452301; + this->state[1] = 0xefcdab89; + this->state[2] = 0x98badcfe; + this->state[3] = 0x10325476; + this->count[0] = 0; + this->count[1] = 0; + + return TRUE; +} + +METHOD(hasher_t, get_hash, bool, private_md5_hasher_t *this, chunk_t chunk, u_int8_t *buffer) { MD5Update(this, chunk.ptr, chunk.len); if (buffer != NULL) { MD5Final(this, buffer); - this->public.hasher_interface.reset(&(this->public.hasher_interface)); + reset(this); } + return TRUE; } -METHOD(hasher_t, allocate_hash, void, +METHOD(hasher_t, allocate_hash, bool, private_md5_hasher_t *this, chunk_t chunk, chunk_t *hash) { - chunk_t allocated_hash; - MD5Update(this, chunk.ptr, chunk.len); if (hash != NULL) { - allocated_hash.ptr = malloc(HASH_SIZE_MD5); - allocated_hash.len = HASH_SIZE_MD5; - - MD5Final(this, allocated_hash.ptr); - this->public.hasher_interface.reset(&(this->public.hasher_interface)); - - *hash = allocated_hash; + *hash = chunk_alloc(HASH_SIZE_MD5); + MD5Final(this, hash->ptr); + reset(this); } + return TRUE; } METHOD(hasher_t, get_hash_size, size_t, @@ -334,17 +343,6 @@ METHOD(hasher_t, get_hash_size, size_t, return HASH_SIZE_MD5; } -METHOD(hasher_t, reset, void, - private_md5_hasher_t *this) -{ - this->state[0] = 0x67452301; - this->state[1] = 0xefcdab89; - this->state[2] = 0x98badcfe; - this->state[3] = 0x10325476; - this->count[0] = 0; - this->count[1] = 0; -} - METHOD(hasher_t, destroy, void, private_md5_hasher_t *this) { diff --git a/src/libstrongswan/plugins/md5/md5_plugin.c b/src/libstrongswan/plugins/md5/md5_plugin.c index a3ad7b305..4a61af618 100644 --- a/src/libstrongswan/plugins/md5/md5_plugin.c +++ b/src/libstrongswan/plugins/md5/md5_plugin.c @@ -51,8 +51,6 @@ METHOD(plugin_t, get_features, int, METHOD(plugin_t, destroy, void, private_md5_plugin_t *this) { - lib->crypto->remove_hasher(lib->crypto, - (hasher_constructor_t)md5_hasher_create); free(this); } diff --git a/src/libstrongswan/plugins/mysql/Makefile.in b/src/libstrongswan/plugins/mysql/Makefile.in index 5025a0eb8..88dba0967 100644 --- a/src/libstrongswan/plugins/mysql/Makefile.in +++ b/src/libstrongswan/plugins/mysql/Makefile.in @@ -49,6 +49,7 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/config/libtool.m4 \ am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; @@ -84,7 +85,7 @@ libstrongswan_mysql_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \ @MONOLITHIC_FALSE@am_libstrongswan_mysql_la_rpath = -rpath \ @MONOLITHIC_FALSE@ $(plugindir) @MONOLITHIC_TRUE@am_libstrongswan_mysql_la_rpath = -DEFAULT_INCLUDES = -I.@am__isrc@ +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles am__mv = mv -f @@ -110,6 +111,7 @@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ +BFDLIB = @BFDLIB@ BTLIB = @BTLIB@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ @@ -204,11 +206,14 @@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ c_plugins = @c_plugins@ +charon_natt_port = @charon_natt_port@ +charon_plugins = @charon_plugins@ +charon_udp_port = @charon_udp_port@ clearsilver_LIBS = @clearsilver_LIBS@ datadir = @datadir@ datarootdir = @datarootdir@ dbusservicedir = @dbusservicedir@ -default_pkcs11 = @default_pkcs11@ +dev_headers = @dev_headers@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ @@ -225,11 +230,12 @@ imcvdir = @imcvdir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ +ipsec_script = @ipsec_script@ +ipsec_script_upper = @ipsec_script_upper@ ipsecdir = @ipsecdir@ ipsecgroup = @ipsecgroup@ ipseclibdir = @ipseclibdir@ ipsecuser = @ipsecuser@ -libcharon_plugins = @libcharon_plugins@ libdir = @libdir@ libexecdir = @libexecdir@ linux_headers = @linux_headers@ @@ -245,6 +251,7 @@ mkdir_p = @mkdir_p@ nm_CFLAGS = @nm_CFLAGS@ nm_LIBS = @nm_LIBS@ nm_ca_dir = @nm_ca_dir@ +nm_plugins = @nm_plugins@ oldincludedir = @oldincludedir@ openac_plugins = @openac_plugins@ p_plugins = @p_plugins@ @@ -254,7 +261,6 @@ pdfdir = @pdfdir@ piddir = @piddir@ pki_plugins = @pki_plugins@ plugindir = @plugindir@ -pluto_plugins = @pluto_plugins@ pool_plugins = @pool_plugins@ prefix = @prefix@ program_transform_name = @program_transform_name@ diff --git a/src/libstrongswan/plugins/mysql/mysql_database.c b/src/libstrongswan/plugins/mysql/mysql_database.c index 25ea42a4f..1a20a804a 100644 --- a/src/libstrongswan/plugins/mysql/mysql_database.c +++ b/src/libstrongswan/plugins/mysql/mysql_database.c @@ -472,6 +472,7 @@ static bool mysql_enumerator_enumerate(mysql_enumerator_t *this, ...) break; } } + va_end(args); return TRUE; } diff --git a/src/libstrongswan/plugins/nonce/Makefile.am b/src/libstrongswan/plugins/nonce/Makefile.am new file mode 100644 index 000000000..0a2ccfc08 --- /dev/null +++ b/src/libstrongswan/plugins/nonce/Makefile.am @@ -0,0 +1,16 @@ + +INCLUDES = -I$(top_srcdir)/src/libstrongswan + +AM_CFLAGS = -rdynamic + +if MONOLITHIC +noinst_LTLIBRARIES = libstrongswan-nonce.la +else +plugin_LTLIBRARIES = libstrongswan-nonce.la +endif + +libstrongswan_nonce_la_SOURCES = \ + nonce_plugin.h nonce_plugin.c \ + nonce_nonceg.c nonce_nonceg.h + +libstrongswan_nonce_la_LDFLAGS = -module -avoid-version diff --git a/src/libstrongswan/plugins/nonce/Makefile.in b/src/libstrongswan/plugins/nonce/Makefile.in new file mode 100644 index 000000000..7ce23b4d9 --- /dev/null +++ b/src/libstrongswan/plugins/nonce/Makefile.in @@ -0,0 +1,617 @@ +# Makefile.in generated by automake 1.11.1 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004, 2005, 2006, 2007, 2008, 2009 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@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@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/nonce +DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/m4/config/libtool.m4 \ + $(top_srcdir)/m4/config/ltoptions.m4 \ + $(top_srcdir)/m4/config/ltsugar.m4 \ + $(top_srcdir)/m4/config/ltversion.m4 \ + $(top_srcdir)/m4/config/lt~obsolete.m4 \ + $(top_srcdir)/m4/macros/with.m4 \ + $(top_srcdir)/m4/macros/enable-disable.m4 \ + $(top_srcdir)/m4/macros/add-plugin.m4 \ + $(top_srcdir)/configure.in +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_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 = f=`echo $$p | sed -e 's|^.*/||'`; +am__install_max = 40 +am__nobase_strip_setup = \ + srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` +am__nobase_strip = \ + for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" +am__nobase_list = $(am__nobase_strip_setup); \ + for p in $$list; do echo "$$p $$p"; done | \ + sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ + $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ + if (++n[$$2] == $(am__install_max)) \ + { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ + END { for (dir in files) print dir, files[dir] }' +am__base_list = \ + sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ + sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' +am__installdirs = "$(DESTDIR)$(plugindir)" +LTLIBRARIES = $(noinst_LTLIBRARIES) $(plugin_LTLIBRARIES) +libstrongswan_nonce_la_LIBADD = +am_libstrongswan_nonce_la_OBJECTS = nonce_plugin.lo nonce_nonceg.lo +libstrongswan_nonce_la_OBJECTS = $(am_libstrongswan_nonce_la_OBJECTS) +libstrongswan_nonce_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(libstrongswan_nonce_la_LDFLAGS) $(LDFLAGS) -o $@ +@MONOLITHIC_FALSE@am_libstrongswan_nonce_la_rpath = -rpath \ +@MONOLITHIC_FALSE@ $(plugindir) +@MONOLITHIC_TRUE@am_libstrongswan_nonce_la_rpath = +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) +depcomp = $(SHELL) $(top_srcdir)/depcomp +am__depfiles_maybe = depfiles +am__mv = mv -f +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_nonce_la_SOURCES) +DIST_SOURCES = $(libstrongswan_nonce_la_SOURCES) +ETAGS = etags +CTAGS = ctags +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +ALLOCA = @ALLOCA@ +AMTAR = @AMTAR@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +BFDLIB = @BFDLIB@ +BTLIB = @BTLIB@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DLLIB = @DLLIB@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +FGREP = @FGREP@ +GPERF = @GPERF@ +GREP = @GREP@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LEX = @LEX@ +LEXLIB = @LEXLIB@ +LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +MAKEINFO = @MAKEINFO@ +MKDIR_P = @MKDIR_P@ +MYSQLCFLAG = @MYSQLCFLAG@ +MYSQLCONFIG = @MYSQLCONFIG@ +MYSQLLIB = @MYSQLLIB@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PERL = @PERL@ +PKG_CONFIG = @PKG_CONFIG@ +PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ +PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ +PTHREADLIB = @PTHREADLIB@ +RANLIB = @RANLIB@ +RTLIB = @RTLIB@ +RUBY = @RUBY@ +RUBYINCLUDE = @RUBYINCLUDE@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +SOCKLIB = @SOCKLIB@ +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_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +attest_plugins = @attest_plugins@ +axis2c_CFLAGS = @axis2c_CFLAGS@ +axis2c_LIBS = @axis2c_LIBS@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +c_plugins = @c_plugins@ +charon_natt_port = @charon_natt_port@ +charon_plugins = @charon_plugins@ +charon_udp_port = @charon_udp_port@ +clearsilver_LIBS = @clearsilver_LIBS@ +datadir = @datadir@ +datarootdir = @datarootdir@ +dbusservicedir = @dbusservicedir@ +dev_headers = @dev_headers@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +gtk_CFLAGS = @gtk_CFLAGS@ +gtk_LIBS = @gtk_LIBS@ +h_plugins = @h_plugins@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +imcvdir = @imcvdir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +ipsec_script = @ipsec_script@ +ipsec_script_upper = @ipsec_script_upper@ +ipsecdir = @ipsecdir@ +ipsecgroup = @ipsecgroup@ +ipseclibdir = @ipseclibdir@ +ipsecuser = @ipsecuser@ +libdir = @libdir@ +libexecdir = @libexecdir@ +linux_headers = @linux_headers@ +localedir = @localedir@ +localstatedir = @localstatedir@ +lt_ECHO = @lt_ECHO@ +maemo_CFLAGS = @maemo_CFLAGS@ +maemo_LIBS = @maemo_LIBS@ +manager_plugins = @manager_plugins@ +mandir = @mandir@ +medsrv_plugins = @medsrv_plugins@ +mkdir_p = @mkdir_p@ +nm_CFLAGS = @nm_CFLAGS@ +nm_LIBS = @nm_LIBS@ +nm_ca_dir = @nm_ca_dir@ +nm_plugins = @nm_plugins@ +oldincludedir = @oldincludedir@ +openac_plugins = @openac_plugins@ +p_plugins = @p_plugins@ +pcsclite_CFLAGS = @pcsclite_CFLAGS@ +pcsclite_LIBS = @pcsclite_LIBS@ +pdfdir = @pdfdir@ +piddir = @piddir@ +pki_plugins = @pki_plugins@ +plugindir = @plugindir@ +pool_plugins = @pool_plugins@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +random_device = @random_device@ +resolv_conf = @resolv_conf@ +routing_table = @routing_table@ +routing_table_prio = @routing_table_prio@ +s_plugins = @s_plugins@ +sbindir = @sbindir@ +scepclient_plugins = @scepclient_plugins@ +scripts_plugins = @scripts_plugins@ +sharedstatedir = @sharedstatedir@ +soup_CFLAGS = @soup_CFLAGS@ +soup_LIBS = @soup_LIBS@ +srcdir = @srcdir@ +starter_plugins = @starter_plugins@ +strongswan_conf = @strongswan_conf@ +sysconfdir = @sysconfdir@ +systemdsystemunitdir = @systemdsystemunitdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +urandom_device = @urandom_device@ +xml_CFLAGS = @xml_CFLAGS@ +xml_LIBS = @xml_LIBS@ +INCLUDES = -I$(top_srcdir)/src/libstrongswan +AM_CFLAGS = -rdynamic +@MONOLITHIC_TRUE@noinst_LTLIBRARIES = libstrongswan-nonce.la +@MONOLITHIC_FALSE@plugin_LTLIBRARIES = libstrongswan-nonce.la +libstrongswan_nonce_la_SOURCES = \ + nonce_plugin.h nonce_plugin.c \ + nonce_nonceg.c nonce_nonceg.h + +libstrongswan_nonce_la_LDFLAGS = -module -avoid-version +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 ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/libstrongswan/plugins/nonce/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnu src/libstrongswan/plugins/nonce/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 +$(am__aclocal_m4_deps): + +clean-noinstLTLIBRARIES: + -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) + @list='$(noinst_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 +install-pluginLTLIBRARIES: $(plugin_LTLIBRARIES) + @$(NORMAL_INSTALL) + test -z "$(plugindir)" || $(MKDIR_P) "$(DESTDIR)$(plugindir)" + @list='$(plugin_LTLIBRARIES)'; test -n "$(plugindir)" || list=; \ + list2=; for p in $$list; do \ + if test -f $$p; then \ + list2="$$list2 $$p"; \ + else :; fi; \ + done; \ + test -z "$$list2" || { \ + echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(plugindir)'"; \ + $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(plugindir)"; \ + } + +uninstall-pluginLTLIBRARIES: + @$(NORMAL_UNINSTALL) + @list='$(plugin_LTLIBRARIES)'; test -n "$(plugindir)" || list=; \ + for p in $$list; do \ + $(am__strip_dir) \ + echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(plugindir)/$$f'"; \ + $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(plugindir)/$$f"; \ + 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-nonce.la: $(libstrongswan_nonce_la_OBJECTS) $(libstrongswan_nonce_la_DEPENDENCIES) + $(libstrongswan_nonce_la_LINK) $(am_libstrongswan_nonce_la_rpath) $(libstrongswan_nonce_la_OBJECTS) $(libstrongswan_nonce_la_LIBADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nonce_nonceg.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nonce_plugin.Plo@am__quote@ + +.c.o: +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ $(am__mv) $(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@ $(am__mv) $(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@ $(am__mv) $(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; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + mkid -fID $$unique +tags: TAGS + +TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + set x; \ + 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; }; }'`; \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: CTAGS +CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + 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)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__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 "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$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) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_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-noinstLTLIBRARIES \ + 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 + +html-am: + +info: info-am + +info-am: + +install-data-am: install-pluginLTLIBRARIES + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +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-noinstLTLIBRARIES 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/nonce/nonce_nonceg.c b/src/libstrongswan/plugins/nonce/nonce_nonceg.c new file mode 100644 index 000000000..0402e3574 --- /dev/null +++ b/src/libstrongswan/plugins/nonce/nonce_nonceg.c @@ -0,0 +1,84 @@ +/* + * Copyright (C) 2012 Adrian-Ken Rueegsegger + * Hochschule fuer Technik Rapperswil + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT 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 "nonce_nonceg.h" + +#include <debug.h> + +typedef struct private_nonce_nonceg_t private_nonce_nonceg_t; + +/** + * Private data of a nonce_nonceg_t object. + */ +struct private_nonce_nonceg_t { + + /** + * Public nonce_nonceg_t interface. + */ + nonce_nonceg_t public; + + /** + * Random number generator + */ + rng_t* rng; +}; + +METHOD(nonce_gen_t, get_nonce, bool, + private_nonce_nonceg_t *this, size_t size, u_int8_t *buffer) +{ + return this->rng->get_bytes(this->rng, size, buffer); +} + +METHOD(nonce_gen_t, allocate_nonce, bool, + private_nonce_nonceg_t *this, size_t size, chunk_t *chunk) +{ + return this->rng->allocate_bytes(this->rng, size, chunk); +} + +METHOD(nonce_gen_t, destroy, void, + private_nonce_nonceg_t *this) +{ + DESTROY_IF(this->rng); + free(this); +} + +/* + * Described in header. + */ +nonce_nonceg_t *nonce_nonceg_create() +{ + private_nonce_nonceg_t *this; + + INIT(this, + .public = { + .nonce_gen = { + .get_nonce = _get_nonce, + .allocate_nonce = _allocate_nonce, + .destroy = _destroy, + }, + }, + ); + + this->rng = lib->crypto->create_rng(lib->crypto, RNG_WEAK); + if (!this->rng) + { + DBG1(DBG_LIB, "no RNG found for quality %N", rng_quality_names, + RNG_WEAK); + destroy(this); + return NULL; + } + + return &this->public; +} diff --git a/src/libstrongswan/plugins/xcbc/xcbc_signer.h b/src/libstrongswan/plugins/nonce/nonce_nonceg.h index 56b55f223..2ae0c97de 100644 --- a/src/libstrongswan/plugins/xcbc/xcbc_signer.h +++ b/src/libstrongswan/plugins/nonce/nonce_nonceg.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2008 Martin Willi + * Copyright (C) 2012 Adrian-Ken Rueegsegger * Hochschule fuer Technik Rapperswil * * This program is free software; you can redistribute it and/or modify it @@ -14,34 +14,33 @@ */ /** - * @defgroup xcbc_signer xcbc_signer - * @{ @ingroup xcbc_p + * @defgroup nonce_nonceg nonce_nonceg + * @{ @ingroup nonce_p */ -#ifndef XCBC_SIGNER_H_ -#define XCBC_SIGNER_H_ +#ifndef NONCE_NONCEG_H_ +#define NONCE_NONCEG_H_ -typedef struct xcbc_signer_t xcbc_signer_t; +typedef struct nonce_nonceg_t nonce_nonceg_t; -#include <crypto/signers/signer.h> +#include <library.h> /** - * Implementation of signer_t based on CBC symmetric cypher. XCBC, RFC3566. + * nonce_gen_t implementation using an rng plugin */ -struct xcbc_signer_t { +struct nonce_nonceg_t { /** - * Implements signer_t interface. + * Implements nonce_gen_t. */ - signer_t signer; + nonce_gen_t nonce_gen; }; /** - * Creates a new xcbc_signer_t. + * Creates an nonce_nonceg_t instance. * - * @param algo algorithm to implement - * @return xcbc_signer_t, NULL if not supported + * @return created nonce_nonceg_t */ -xcbc_signer_t *xcbc_signer_create(integrity_algorithm_t algo); +nonce_nonceg_t *nonce_nonceg_create(); -#endif /** XCBC_SIGNER_H_ @}*/ +#endif /** NONCE_NONCEG_H_ @} */ diff --git a/src/libstrongswan/plugins/nonce/nonce_plugin.c b/src/libstrongswan/plugins/nonce/nonce_plugin.c new file mode 100644 index 000000000..90f2e8fac --- /dev/null +++ b/src/libstrongswan/plugins/nonce/nonce_plugin.c @@ -0,0 +1,76 @@ +/* + * Copyright (C) 2012 Adrian-Ken Rueegsegger + * Hochschule fuer Technik Rapperswil + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT 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 "nonce_plugin.h" + +#include <library.h> +#include "nonce_nonceg.h" + +typedef struct private_nonce_plugin_t private_nonce_plugin_t; + +/** + * private data of nonce_plugin + */ +struct private_nonce_plugin_t { + + /** + * public functions + */ + nonce_plugin_t public; +}; + +METHOD(plugin_t, get_name, char*, + private_nonce_plugin_t *this) +{ + return "nonce"; +} + +METHOD(plugin_t, get_features, int, + private_nonce_plugin_t *this, plugin_feature_t *features[]) +{ + static plugin_feature_t f[] = { + PLUGIN_REGISTER(NONCE_GEN, nonce_nonceg_create), + PLUGIN_PROVIDE(NONCE_GEN), + PLUGIN_DEPENDS(RNG, RNG_WEAK), + }; + *features = f; + return countof(f); +} + +METHOD(plugin_t, destroy, void, + private_nonce_plugin_t *this) +{ + free(this); +} + +/* + * see header file + */ +plugin_t *nonce_plugin_create() +{ + private_nonce_plugin_t *this; + + INIT(this, + .public = { + .plugin = { + .get_name = _get_name, + .get_features = _get_features, + .destroy = _destroy, + }, + }, + ); + + return &this->public.plugin; +} diff --git a/src/libstrongswan/plugins/nonce/nonce_plugin.h b/src/libstrongswan/plugins/nonce/nonce_plugin.h new file mode 100644 index 000000000..f4be1c3a8 --- /dev/null +++ b/src/libstrongswan/plugins/nonce/nonce_plugin.h @@ -0,0 +1,42 @@ +/* + * Copyright (C) 2012 Adrian-Ken Rueegsegger + * Hochschule fuer Technik Rapperswil + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT 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 nonce_p nonce + * @ingroup plugins + * + * @defgroup nonce_plugin nonce_plugin + * @{ @ingroup nonce_p + */ + +#ifndef NONCE_PLUGIN_H_ +#define NONCE_PLUGIN_H_ + +#include <plugins/plugin.h> + +typedef struct nonce_plugin_t nonce_plugin_t; + +/** + * Plugin implementing a nonce generator using an RNG. + */ +struct nonce_plugin_t { + + /** + * Implements plugin interface + */ + plugin_t plugin; +}; + +#endif /** NONCE_PLUGIN_H_ @}*/ diff --git a/src/libstrongswan/plugins/openssl/Makefile.am b/src/libstrongswan/plugins/openssl/Makefile.am index 5c845a19c..c59888663 100644 --- a/src/libstrongswan/plugins/openssl/Makefile.am +++ b/src/libstrongswan/plugins/openssl/Makefile.am @@ -22,7 +22,9 @@ libstrongswan_openssl_la_SOURCES = \ openssl_ec_private_key.c openssl_ec_private_key.h \ openssl_ec_public_key.c openssl_ec_public_key.h \ openssl_x509.c openssl_x509.h \ - openssl_crl.c openssl_crl.h + openssl_crl.c openssl_crl.h \ + openssl_rng.c openssl_rng.h \ + openssl_hmac.c openssl_hmac.h libstrongswan_openssl_la_LDFLAGS = -module -avoid-version libstrongswan_openssl_la_LIBADD = -lcrypto diff --git a/src/libstrongswan/plugins/openssl/Makefile.in b/src/libstrongswan/plugins/openssl/Makefile.in index 8994ff1b4..ada44ead3 100644 --- a/src/libstrongswan/plugins/openssl/Makefile.in +++ b/src/libstrongswan/plugins/openssl/Makefile.in @@ -49,6 +49,7 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/config/libtool.m4 \ am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; @@ -80,7 +81,8 @@ am_libstrongswan_openssl_la_OBJECTS = openssl_plugin.lo \ openssl_sha1_prf.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 openssl_x509.lo openssl_crl.lo + openssl_ec_public_key.lo openssl_x509.lo openssl_crl.lo \ + openssl_rng.lo openssl_hmac.lo libstrongswan_openssl_la_OBJECTS = \ $(am_libstrongswan_openssl_la_OBJECTS) libstrongswan_openssl_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \ @@ -89,7 +91,7 @@ libstrongswan_openssl_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \ @MONOLITHIC_FALSE@am_libstrongswan_openssl_la_rpath = -rpath \ @MONOLITHIC_FALSE@ $(plugindir) @MONOLITHIC_TRUE@am_libstrongswan_openssl_la_rpath = -DEFAULT_INCLUDES = -I.@am__isrc@ +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles am__mv = mv -f @@ -115,6 +117,7 @@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ +BFDLIB = @BFDLIB@ BTLIB = @BTLIB@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ @@ -209,11 +212,14 @@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ c_plugins = @c_plugins@ +charon_natt_port = @charon_natt_port@ +charon_plugins = @charon_plugins@ +charon_udp_port = @charon_udp_port@ clearsilver_LIBS = @clearsilver_LIBS@ datadir = @datadir@ datarootdir = @datarootdir@ dbusservicedir = @dbusservicedir@ -default_pkcs11 = @default_pkcs11@ +dev_headers = @dev_headers@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ @@ -230,11 +236,12 @@ imcvdir = @imcvdir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ +ipsec_script = @ipsec_script@ +ipsec_script_upper = @ipsec_script_upper@ ipsecdir = @ipsecdir@ ipsecgroup = @ipsecgroup@ ipseclibdir = @ipseclibdir@ ipsecuser = @ipsecuser@ -libcharon_plugins = @libcharon_plugins@ libdir = @libdir@ libexecdir = @libexecdir@ linux_headers = @linux_headers@ @@ -250,6 +257,7 @@ mkdir_p = @mkdir_p@ nm_CFLAGS = @nm_CFLAGS@ nm_LIBS = @nm_LIBS@ nm_ca_dir = @nm_ca_dir@ +nm_plugins = @nm_plugins@ oldincludedir = @oldincludedir@ openac_plugins = @openac_plugins@ p_plugins = @p_plugins@ @@ -259,7 +267,6 @@ pdfdir = @pdfdir@ piddir = @piddir@ pki_plugins = @pki_plugins@ plugindir = @plugindir@ -pluto_plugins = @pluto_plugins@ pool_plugins = @pool_plugins@ prefix = @prefix@ program_transform_name = @program_transform_name@ @@ -304,7 +311,9 @@ libstrongswan_openssl_la_SOURCES = \ openssl_ec_private_key.c openssl_ec_private_key.h \ openssl_ec_public_key.c openssl_ec_public_key.h \ openssl_x509.c openssl_x509.h \ - openssl_crl.c openssl_crl.h + openssl_crl.c openssl_crl.h \ + openssl_rng.c openssl_rng.h \ + openssl_hmac.c openssl_hmac.h libstrongswan_openssl_la_LDFLAGS = -module -avoid-version libstrongswan_openssl_la_LIBADD = -lcrypto @@ -398,7 +407,9 @@ distclean-compile: @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_hmac.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/openssl_plugin.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/openssl_rng.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_sha1_prf.Plo@am__quote@ diff --git a/src/libstrongswan/plugins/openssl/openssl_crl.c b/src/libstrongswan/plugins/openssl/openssl_crl.c index 9a9efb2b6..e529ff8a5 100644 --- a/src/libstrongswan/plugins/openssl/openssl_crl.c +++ b/src/libstrongswan/plugins/openssl/openssl_crl.c @@ -225,7 +225,8 @@ METHOD(certificate_t, has_subject_or_issuer, id_match_t, } METHOD(certificate_t, issued_by, bool, - private_openssl_crl_t *this, certificate_t *issuer) + private_openssl_crl_t *this, certificate_t *issuer, + signature_scheme_t *scheme) { chunk_t fingerprint, tbs; public_key_t *key; @@ -270,6 +271,10 @@ METHOD(certificate_t, issued_by, bool, openssl_asn1_str2chunk(this->crl->signature)); free(tbs.ptr); key->destroy(key); + if (valid && scheme) + { + *scheme = this->scheme; + } return valid; } diff --git a/src/libstrongswan/plugins/openssl/openssl_crypter.c b/src/libstrongswan/plugins/openssl/openssl_crypter.c index cd9a3bd4a..07b96b320 100644 --- a/src/libstrongswan/plugins/openssl/openssl_crypter.c +++ b/src/libstrongswan/plugins/openssl/openssl_crypter.c @@ -90,7 +90,7 @@ static char* lookup_algorithm(u_int16_t ikev2_algo, size_t *key_size) /** * Do the actual en/decryption in an EVP context */ -static void crypt(private_openssl_crypter_t *this, chunk_t data, chunk_t iv, +static bool crypt(private_openssl_crypter_t *this, chunk_t data, chunk_t iv, chunk_t *dst, int enc) { int len; @@ -104,25 +104,26 @@ static void crypt(private_openssl_crypter_t *this, chunk_t data, chunk_t iv, } EVP_CIPHER_CTX ctx; EVP_CIPHER_CTX_init(&ctx); - EVP_CipherInit_ex(&ctx, this->cipher, NULL, NULL, NULL, enc); - EVP_CIPHER_CTX_set_padding(&ctx, 0); /* disable padding */ - EVP_CIPHER_CTX_set_key_length(&ctx, this->key.len); - EVP_CipherInit_ex(&ctx, NULL, NULL, this->key.ptr, iv.ptr, enc); - EVP_CipherUpdate(&ctx, out, &len, data.ptr, data.len); - EVP_CipherFinal_ex(&ctx, out + len, &len); /* since padding is disabled this does nothing */ - EVP_CIPHER_CTX_cleanup(&ctx); + return EVP_CipherInit_ex(&ctx, this->cipher, NULL, NULL, NULL, enc) && + EVP_CIPHER_CTX_set_padding(&ctx, 0) /* disable padding */ && + EVP_CIPHER_CTX_set_key_length(&ctx, this->key.len) && + EVP_CipherInit_ex(&ctx, NULL, NULL, this->key.ptr, iv.ptr, enc) && + EVP_CipherUpdate(&ctx, out, &len, data.ptr, data.len) && + /* since padding is disabled this does nothing */ + EVP_CipherFinal_ex(&ctx, out + len, &len) && + EVP_CIPHER_CTX_cleanup(&ctx); } -METHOD(crypter_t, decrypt, void, +METHOD(crypter_t, decrypt, bool, private_openssl_crypter_t *this, chunk_t data, chunk_t iv, chunk_t *dst) { - crypt(this, data, iv, dst, 0); + return crypt(this, data, iv, dst, 0); } -METHOD(crypter_t, encrypt, void, +METHOD(crypter_t, encrypt, bool, private_openssl_crypter_t *this, chunk_t data, chunk_t iv, chunk_t *dst) { - crypt(this, data, iv, dst, 1); + return crypt(this, data, iv, dst, 1); } METHOD(crypter_t, get_block_size, size_t, @@ -143,10 +144,11 @@ METHOD(crypter_t, get_key_size, size_t, return this->key.len; } -METHOD(crypter_t, set_key, void, +METHOD(crypter_t, set_key, bool, private_openssl_crypter_t *this, chunk_t key) { memcpy(this->key.ptr, key.ptr, min(key.len, this->key.len)); + return TRUE; } METHOD(crypter_t, destroy, void, diff --git a/src/libstrongswan/plugins/openssl/openssl_ec_public_key.c b/src/libstrongswan/plugins/openssl/openssl_ec_public_key.c index 7461695ad..9cb68a3ab 100644 --- a/src/libstrongswan/plugins/openssl/openssl_ec_public_key.c +++ b/src/libstrongswan/plugins/openssl/openssl_ec_public_key.c @@ -221,13 +221,13 @@ bool openssl_ec_fingerprint(EC_KEY *ec, cred_encoding_type_t type, chunk_t *fp) return FALSE; } hasher = lib->crypto->create_hasher(lib->crypto, HASH_SHA1); - if (!hasher) + if (!hasher || !hasher->allocate_hash(hasher, key, fp)) { DBG1(DBG_LIB, "SHA1 hash algorithm not supported, fingerprinting failed"); + DESTROY_IF(hasher); free(key.ptr); return FALSE; } - hasher->allocate_hash(hasher, key, fp); hasher->destroy(hasher); free(key.ptr); lib->encoding->cache(lib->encoding, type, ec, *fp); diff --git a/src/libstrongswan/plugins/openssl/openssl_hasher.c b/src/libstrongswan/plugins/openssl/openssl_hasher.c index d81f4b21e..50b14698b 100644 --- a/src/libstrongswan/plugins/openssl/openssl_hasher.c +++ b/src/libstrongswan/plugins/openssl/openssl_hasher.c @@ -40,91 +40,45 @@ struct private_openssl_hasher_t { 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_SHA224, "sha224"}, - {HASH_SHA256, "sha256"}, - {HASH_SHA384, "sha384"}, - {HASH_SHA512, "sha512"}, - {HASH_MD4, "md4"}, - {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; -} - METHOD(hasher_t, get_hash_size, size_t, private_openssl_hasher_t *this) { return this->hasher->md_size; } -METHOD(hasher_t, reset, void, +METHOD(hasher_t, reset, bool, private_openssl_hasher_t *this) { - EVP_DigestInit_ex(this->ctx, this->hasher, NULL); + return EVP_DigestInit_ex(this->ctx, this->hasher, NULL) == 1; } -METHOD(hasher_t, get_hash, void, +METHOD(hasher_t, get_hash, bool, private_openssl_hasher_t *this, chunk_t chunk, u_int8_t *hash) { - EVP_DigestUpdate(this->ctx, chunk.ptr, chunk.len); + if (EVP_DigestUpdate(this->ctx, chunk.ptr, chunk.len) != 1) + { + return FALSE; + } if (hash) { - EVP_DigestFinal_ex(this->ctx, hash, NULL); - reset(this); + if (EVP_DigestFinal_ex(this->ctx, hash, NULL) != 1) + { + return FALSE; + } + return reset(this); } + return TRUE; } -METHOD(hasher_t, allocate_hash, void, +METHOD(hasher_t, allocate_hash, bool, 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); + return get_hash(this, chunk, hash->ptr); } + return get_hash(this, chunk, NULL); } METHOD(hasher_t, destroy, void, @@ -140,11 +94,11 @@ METHOD(hasher_t, destroy, void, openssl_hasher_t *openssl_hasher_create(hash_algorithm_t algo) { private_openssl_hasher_t *this; + char* name; - char* name = lookup_algorithm(integrity_algs, algo); + name = enum_to_name(hash_algorithm_short_names, algo); if (!name) { - /* algo unavailable */ return NULL; } @@ -171,7 +125,11 @@ openssl_hasher_t *openssl_hasher_create(hash_algorithm_t algo) this->ctx = EVP_MD_CTX_create(); /* initialization */ - reset(this); + if (!reset(this)) + { + destroy(this); + return NULL; + } return &this->public; } diff --git a/src/libstrongswan/plugins/openssl/openssl_hmac.c b/src/libstrongswan/plugins/openssl/openssl_hmac.c new file mode 100644 index 000000000..5d05425d3 --- /dev/null +++ b/src/libstrongswan/plugins/openssl/openssl_hmac.c @@ -0,0 +1,191 @@ +/* + * Copyright (C) 2012 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. + */ + +/* + * Copyright (C) 2012 Aleksandr Grinberg + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include <openssl/evp.h> +#include <openssl/hmac.h> + +#include "openssl_hmac.h" + +#include <crypto/mac.h> +#include <crypto/prfs/mac_prf.h> +#include <crypto/signers/mac_signer.h> + +typedef struct private_mac_t private_mac_t; + +/** + * Private data of a mac_t object. + */ +struct private_mac_t { + + /** + * Public interface + */ + mac_t public; + + /** + * Hasher to use + */ + const EVP_MD *hasher; + + /** + * Current HMAC context + */ + HMAC_CTX hmac; +}; + +METHOD(mac_t, set_key, bool, + private_mac_t *this, chunk_t key) +{ +#if OPENSSL_VERSION_NUMBER >= 0x10000000L + return HMAC_Init_ex(&this->hmac, key.ptr, key.len, this->hasher, NULL); +#else /* OPENSSL_VERSION_NUMBER < 1.0 */ + HMAC_Init_ex(&this->hmac, key.ptr, key.len, this->hasher, NULL); + return TRUE; +#endif +} + +METHOD(mac_t, get_mac, bool, + private_mac_t *this, chunk_t data, u_int8_t *out) +{ +#if OPENSSL_VERSION_NUMBER >= 0x10000000L + if (!HMAC_Update(&this->hmac, data.ptr, data.len)) + { + return FALSE; + } + if (out == NULL) + { + return TRUE; + } + if (!HMAC_Final(&this->hmac, out, NULL)) + { + return FALSE; + } +#else /* OPENSSL_VERSION_NUMBER < 1.0 */ + HMAC_Update(&this->hmac, data.ptr, data.len); + if (out == NULL) + { + return TRUE; + } + HMAC_Final(&this->hmac, out, NULL); +#endif + return set_key(this, chunk_empty); +} + +METHOD(mac_t, get_mac_size, size_t, + private_mac_t *this) +{ + return EVP_MD_size(this->hasher); +} + +METHOD(mac_t, destroy, void, + private_mac_t *this) +{ + HMAC_CTX_cleanup(&this->hmac); + free(this); +} + +/* + * Create an OpenSSL-backed implementation of the mac_t interface + */ +static mac_t *hmac_create(hash_algorithm_t algo) +{ + private_mac_t *this; + char *name; + + name = enum_to_name(hash_algorithm_short_names, algo); + if (!name) + { + return NULL; + } + + INIT(this, + .public = { + .get_mac = _get_mac, + .get_mac_size = _get_mac_size, + .set_key = _set_key, + .destroy = _destroy, + }, + .hasher = EVP_get_digestbyname(name), + ); + + if (!this->hasher) + { + free(this); + return NULL; + } + + HMAC_CTX_init(&this->hmac); + if (!set_key(this, chunk_empty)) + { + destroy(this); + return NULL; + } + + return &this->public; +} + +/* + * Described in header + */ +prf_t *openssl_hmac_prf_create(pseudo_random_function_t algo) +{ + mac_t *hmac; + + hmac = hmac_create(hasher_algorithm_from_prf(algo)); + if (hmac) + { + return mac_prf_create(hmac); + } + return NULL; +} + +/* + * Described in header + */ +signer_t *openssl_hmac_signer_create(integrity_algorithm_t algo) +{ + mac_t *hmac; + size_t trunc; + + hmac = hmac_create(hasher_algorithm_from_integrity(algo, &trunc)); + if (hmac) + { + return mac_signer_create(hmac, trunc); + } + return NULL; +} + diff --git a/src/libstrongswan/plugins/cmac/cmac_prf.h b/src/libstrongswan/plugins/openssl/openssl_hmac.h index a53cc5947..95ab6bfc3 100644 --- a/src/libstrongswan/plugins/cmac/cmac_prf.h +++ b/src/libstrongswan/plugins/openssl/openssl_hmac.h @@ -14,37 +14,32 @@ */ /** - * @defgroup cmac_prf cmac_prf - * @{ @ingroup cmac_p + * Implements HMAC based PRF and signer using OpenSSL's HMAC functions. + * + * @defgroup openssl_hmac openssl_hmac + * @{ @ingroup openssl_p */ -#ifndef PRF_CMAC_H_ -#define PRF_CMAC_H_ - -typedef struct cmac_prf_t cmac_prf_t; +#ifndef OPENSSL_HMAC_H_ +#define OPENSSL_HMAC_H_ #include <crypto/prfs/prf.h> +#include <crypto/signers/signer.h> /** - * Implementation of prf_t on CBC block cipher using CMAC, RFC 4493 / RFC 4615. + * Creates a new prf_t object based on an HMAC. * - * This simply wraps a cmac_t in a prf_t. More a question of - * interface matching. + * @param algo algorithm to implement + * @return prf_t object, NULL if not supported */ -struct cmac_prf_t { - - /** - * Implements prf_t interface. - */ - prf_t prf; -}; +prf_t *openssl_hmac_prf_create(pseudo_random_function_t algo); /** - * Creates a new cmac_prf_t object. + * Creates a new signer_t object based on an HMAC. * * @param algo algorithm to implement - * @return cmac_prf_t object, NULL if hash not supported + * @return signer_t, NULL if not supported */ -cmac_prf_t *cmac_prf_create(pseudo_random_function_t algo); +signer_t *openssl_hmac_signer_create(integrity_algorithm_t algo); -#endif /** PRF_CMAC_H_ @}*/ +#endif /** OPENSSL_HMAC_H_ @}*/ diff --git a/src/libstrongswan/plugins/openssl/openssl_plugin.c b/src/libstrongswan/plugins/openssl/openssl_plugin.c index c93ceacc9..b69de981e 100644 --- a/src/libstrongswan/plugins/openssl/openssl_plugin.c +++ b/src/libstrongswan/plugins/openssl/openssl_plugin.c @@ -40,6 +40,8 @@ #include "openssl_ec_public_key.h" #include "openssl_x509.h" #include "openssl_crl.h" +#include "openssl_rng.h" +#include "openssl_hmac.h" typedef struct private_openssl_plugin_t private_openssl_plugin_t; @@ -127,7 +129,9 @@ static void destroy_function(struct CRYPTO_dynlock_value *lock, */ static unsigned long id_function(void) { - return (unsigned long)thread_current_id(); + /* ensure the thread ID is never zero, otherwise OpenSSL might try to + * acquire locks recursively */ + return 1 + (unsigned long)thread_current_id(); } /** @@ -170,7 +174,11 @@ static bool seed_rng() return FALSE; } } - rng->get_bytes(rng, sizeof(buf), buf); + if (!rng->get_bytes(rng, sizeof(buf), buf)) + { + rng->destroy(rng); + return FALSE; + } RAND_seed(buf, sizeof(buf)); } DESTROY_IF(rng); @@ -260,6 +268,41 @@ METHOD(plugin_t, get_features, int, PLUGIN_REGISTER(PRF, openssl_sha1_prf_create), PLUGIN_PROVIDE(PRF, PRF_KEYED_SHA1), #endif +#ifndef OPENSSL_NO_HMAC + PLUGIN_REGISTER(PRF, openssl_hmac_prf_create), +#ifndef OPENSSL_NO_MD5 + PLUGIN_PROVIDE(PRF, PRF_HMAC_MD5), +#endif +#ifndef OPENSSL_NO_SHA1 + PLUGIN_PROVIDE(PRF, PRF_HMAC_SHA1), +#endif +#ifndef OPENSSL_NO_SHA256 + PLUGIN_PROVIDE(PRF, PRF_HMAC_SHA2_256), +#endif +#ifndef OPENSSL_NO_SHA512 + PLUGIN_PROVIDE(PRF, PRF_HMAC_SHA2_384), + PLUGIN_PROVIDE(PRF, PRF_HMAC_SHA2_512), +#endif + PLUGIN_REGISTER(SIGNER, openssl_hmac_signer_create), +#ifndef OPENSSL_NO_MD5 + PLUGIN_PROVIDE(SIGNER, AUTH_HMAC_MD5_96), + PLUGIN_PROVIDE(SIGNER, AUTH_HMAC_MD5_128), +#endif +#ifndef OPENSSL_NO_SHA1 + PLUGIN_PROVIDE(SIGNER, AUTH_HMAC_SHA1_96), + PLUGIN_PROVIDE(SIGNER, AUTH_HMAC_SHA1_128), + PLUGIN_PROVIDE(SIGNER, AUTH_HMAC_SHA1_160), +#endif +#ifndef OPENSSL_NO_SHA256 + PLUGIN_PROVIDE(SIGNER, AUTH_HMAC_SHA2_256_128), + PLUGIN_PROVIDE(SIGNER, AUTH_HMAC_SHA2_256_256), +#endif +#ifndef OPENSSL_NO_SHA512 + PLUGIN_PROVIDE(SIGNER, AUTH_HMAC_SHA2_384_192), + PLUGIN_PROVIDE(SIGNER, AUTH_HMAC_SHA2_384_384), + PLUGIN_PROVIDE(SIGNER, AUTH_HMAC_SHA2_512_256), +#endif +#endif /* OPENSSL_NO_HMAC */ #ifndef OPENSSL_NO_DH /* MODP DH groups */ PLUGIN_REGISTER(DH, openssl_diffie_hellman_create), @@ -284,7 +327,7 @@ METHOD(plugin_t, get_features, int, PLUGIN_PROVIDE(PRIVKEY, KEY_ANY), PLUGIN_REGISTER(PRIVKEY_GEN, openssl_rsa_private_key_gen, FALSE), PLUGIN_PROVIDE(PRIVKEY_GEN, KEY_RSA), - PLUGIN_REGISTER(PUBKEY, openssl_rsa_public_key_load, FALSE), + PLUGIN_REGISTER(PUBKEY, openssl_rsa_public_key_load, TRUE), PLUGIN_PROVIDE(PUBKEY, KEY_RSA), PLUGIN_REGISTER(PUBKEY, openssl_rsa_public_key_load, TRUE), PLUGIN_PROVIDE(PUBKEY, KEY_ANY), @@ -317,6 +360,9 @@ METHOD(plugin_t, get_features, int, /* certificate/CRL loading */ PLUGIN_REGISTER(CERT_DECODE, openssl_x509_load, TRUE), PLUGIN_PROVIDE(CERT_DECODE, CERT_X509), + PLUGIN_SDEPEND(PUBKEY, KEY_RSA), + PLUGIN_SDEPEND(PUBKEY, KEY_ECDSA), + PLUGIN_SDEPEND(PUBKEY, KEY_DSA), PLUGIN_REGISTER(CERT_DECODE, openssl_crl_load, TRUE), PLUGIN_PROVIDE(CERT_DECODE, CERT_X509_CRL), #ifndef OPENSSL_NO_ECDH @@ -360,6 +406,9 @@ METHOD(plugin_t, get_features, int, PLUGIN_PROVIDE(PUBKEY_VERIFY, SIGN_ECDSA_521), #endif #endif /* OPENSSL_NO_ECDSA */ + PLUGIN_REGISTER(RNG, openssl_rng_create), + PLUGIN_PROVIDE(RNG, RNG_STRONG), + PLUGIN_PROVIDE(RNG, RNG_WEAK), }; *features = f; return countof(f); diff --git a/src/libstrongswan/plugins/openssl/openssl_rng.c b/src/libstrongswan/plugins/openssl/openssl_rng.c new file mode 100644 index 000000000..c83244f60 --- /dev/null +++ b/src/libstrongswan/plugins/openssl/openssl_rng.c @@ -0,0 +1,100 @@ +/* + * Copyright (C) 2012 Aleksandr Grinberg + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include <debug.h> +#include <openssl/rand.h> +#include <openssl/err.h> + +#include "openssl_rng.h" + +typedef struct private_openssl_rng_t private_openssl_rng_t; + +/** + * Private data of openssl_rng_t + */ +struct private_openssl_rng_t { + + /** + * Public part of this class. + */ + openssl_rng_t public; + + /** + * Quality of randomness + */ + rng_quality_t quality; +}; + +METHOD(rng_t, get_bytes, bool, + private_openssl_rng_t *this, size_t bytes, u_int8_t *buffer) +{ + u_int32_t ret; + + if (this->quality == RNG_STRONG) + { + ret = RAND_bytes((char*)buffer, bytes); + } + else + { + ret = RAND_pseudo_bytes((char*)buffer, bytes); + } + return ret != 0; +} + +METHOD(rng_t, allocate_bytes, bool, + private_openssl_rng_t *this, size_t bytes, chunk_t *chunk) +{ + *chunk = chunk_alloc(bytes); + if (!get_bytes(this, chunk->len, chunk->ptr)) + { + chunk_free(chunk); + return FALSE; + } + return TRUE; +} + +METHOD(rng_t, destroy, void, + private_openssl_rng_t *this) +{ + free(this); +} + +/* + * Described in header. + */ +openssl_rng_t *openssl_rng_create(rng_quality_t quality) +{ + private_openssl_rng_t *this; + + INIT(this, + .public = { + .rng = { + .get_bytes = _get_bytes, + .allocate_bytes = _allocate_bytes, + .destroy = _destroy, + }, + }, + .quality = quality, + ); + + return &this->public; +} diff --git a/src/libstrongswan/plugins/openssl/openssl_rng.h b/src/libstrongswan/plugins/openssl/openssl_rng.h new file mode 100644 index 000000000..a4596563a --- /dev/null +++ b/src/libstrongswan/plugins/openssl/openssl_rng.h @@ -0,0 +1,54 @@ +/* + * Copyright (C) 2012 Aleksandr Grinberg + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +/** + * @defgroup openssl_rng openssl_rng + * @{ @ingroup openssl_p + */ + +#ifndef OPENSSL_RNG_H_ +#define OPENSSL_RNG_H_ + +#include <library.h> + +typedef struct openssl_rng_t openssl_rng_t; + +/** + * Implementation of random number using OpenSSL. + */ +struct openssl_rng_t { + + /** + * Implements rng_t interface. + */ + rng_t rng; +}; + +/** + * Constructor to create openssl_rng_t. + * + * @param quality quality of randomness + * @return openssl_rng_t + */ +openssl_rng_t *openssl_rng_create(rng_quality_t quality); + +#endif /** OPENSSL_RNG_H_ @}*/ diff --git a/src/libstrongswan/plugins/openssl/openssl_rsa_private_key.c b/src/libstrongswan/plugins/openssl/openssl_rsa_private_key.c index d1afd94cc..98cd700bf 100644 --- a/src/libstrongswan/plugins/openssl/openssl_rsa_private_key.c +++ b/src/libstrongswan/plugins/openssl/openssl_rsa_private_key.c @@ -475,7 +475,8 @@ static bool login(ENGINE *engine, chunk_t keyid) { found = TRUE; key = shared->get_key(shared); - if (snprintf(pin, sizeof(pin), "%.*s", key.len, key.ptr) >= sizeof(pin)) + if (snprintf(pin, sizeof(pin), + "%.*s", (int)key.len, key.ptr) >= sizeof(pin)) { continue; } diff --git a/src/libstrongswan/plugins/openssl/openssl_rsa_public_key.c b/src/libstrongswan/plugins/openssl/openssl_rsa_public_key.c index a24bae5d6..5872a8159 100644 --- a/src/libstrongswan/plugins/openssl/openssl_rsa_public_key.c +++ b/src/libstrongswan/plugins/openssl/openssl_rsa_public_key.c @@ -217,13 +217,13 @@ bool openssl_rsa_fingerprint(RSA *rsa, cred_encoding_type_t type, chunk_t *fp) return FALSE; } hasher = lib->crypto->create_hasher(lib->crypto, HASH_SHA1); - if (!hasher) + if (!hasher || !hasher->allocate_hash(hasher, key, fp)) { DBG1(DBG_LIB, "SHA1 hash algorithm not supported, fingerprinting failed"); + DESTROY_IF(hasher); free(key.ptr); return FALSE; } - hasher->allocate_hash(hasher, key, fp); free(key.ptr); hasher->destroy(hasher); lib->encoding->cache(lib->encoding, type, rsa, *fp); diff --git a/src/libstrongswan/plugins/openssl/openssl_sha1_prf.c b/src/libstrongswan/plugins/openssl/openssl_sha1_prf.c index 20f2fa984..8501e2cd4 100644 --- a/src/libstrongswan/plugins/openssl/openssl_sha1_prf.c +++ b/src/libstrongswan/plugins/openssl/openssl_sha1_prf.c @@ -35,7 +35,7 @@ struct private_openssl_sha1_prf_t { SHA_CTX ctx; }; -METHOD(prf_t, get_bytes, void, +METHOD(prf_t, get_bytes, bool, private_openssl_sha1_prf_t *this, chunk_t seed, u_int8_t *bytes) { SHA1_Update(&this->ctx, seed.ptr, seed.len); @@ -50,6 +50,8 @@ METHOD(prf_t, get_bytes, void, hash[3] = htonl(this->ctx.h3); hash[4] = htonl(this->ctx.h4); } + + return TRUE; } METHOD(prf_t, get_block_size, size_t, @@ -58,18 +60,15 @@ METHOD(prf_t, get_block_size, size_t, return HASH_SIZE_SHA1; } -METHOD(prf_t, allocate_bytes, void, +METHOD(prf_t, allocate_bytes, bool, private_openssl_sha1_prf_t *this, chunk_t seed, chunk_t *chunk) { if (chunk) { *chunk = chunk_alloc(HASH_SIZE_SHA1); - get_bytes(this, seed, chunk->ptr); - } - else - { - get_bytes(this, seed, NULL); + return get_bytes(this, seed, chunk->ptr); } + return get_bytes(this, seed, NULL); } METHOD(prf_t, get_key_size, size_t, @@ -78,11 +77,15 @@ METHOD(prf_t, get_key_size, size_t, return HASH_SIZE_SHA1; } -METHOD(prf_t, set_key, void, +METHOD(prf_t, set_key, bool, private_openssl_sha1_prf_t *this, chunk_t key) { SHA1_Init(&this->ctx); + if (key.len % 4) + { + return FALSE; + } if (key.len >= 4) { this->ctx.h0 ^= untoh32(key.ptr); @@ -103,6 +106,7 @@ METHOD(prf_t, set_key, void, { this->ctx.h4 ^= untoh32(key.ptr + 16); } + return TRUE; } METHOD(prf_t, destroy, void, diff --git a/src/libstrongswan/plugins/openssl/openssl_x509.c b/src/libstrongswan/plugins/openssl/openssl_x509.c index 5caf5182c..e85c5cc90 100644 --- a/src/libstrongswan/plugins/openssl/openssl_x509.c +++ b/src/libstrongswan/plugins/openssl/openssl_x509.c @@ -350,7 +350,8 @@ METHOD(certificate_t, has_issuer, id_match_t, } METHOD(certificate_t, issued_by, bool, - private_openssl_x509_t *this, certificate_t *issuer) + private_openssl_x509_t *this, certificate_t *issuer, + signature_scheme_t *scheme) { public_key_t *key; bool valid; @@ -393,6 +394,10 @@ METHOD(certificate_t, issued_by, bool, openssl_asn1_str2chunk(this->x509->signature)); free(tbs.ptr); key->destroy(key); + if (valid && scheme) + { + *scheme = this->scheme; + } return valid; } @@ -968,14 +973,14 @@ static bool parse_certificate(private_openssl_x509_t *this) parse_extKeyUsage(this); hasher = lib->crypto->create_hasher(lib->crypto, HASH_SHA1); - if (!hasher) + if (!hasher || !hasher->allocate_hash(hasher, this->encoding, &this->hash)) { + DESTROY_IF(hasher); return FALSE; } - hasher->allocate_hash(hasher, this->encoding, &this->hash); hasher->destroy(hasher); - if (issued_by(this, &this->public.x509.interface)) + if (issued_by(this, &this->public.x509.interface, NULL)) { this->flags |= X509_SELF_SIGNED; } diff --git a/src/libstrongswan/plugins/padlock/Makefile.in b/src/libstrongswan/plugins/padlock/Makefile.in index 6ff607456..5a559eadf 100644 --- a/src/libstrongswan/plugins/padlock/Makefile.in +++ b/src/libstrongswan/plugins/padlock/Makefile.in @@ -49,6 +49,7 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/config/libtool.m4 \ am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; @@ -85,7 +86,7 @@ libstrongswan_padlock_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \ @MONOLITHIC_FALSE@am_libstrongswan_padlock_la_rpath = -rpath \ @MONOLITHIC_FALSE@ $(plugindir) @MONOLITHIC_TRUE@am_libstrongswan_padlock_la_rpath = -DEFAULT_INCLUDES = -I.@am__isrc@ +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles am__mv = mv -f @@ -111,6 +112,7 @@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ +BFDLIB = @BFDLIB@ BTLIB = @BTLIB@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ @@ -205,11 +207,14 @@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ c_plugins = @c_plugins@ +charon_natt_port = @charon_natt_port@ +charon_plugins = @charon_plugins@ +charon_udp_port = @charon_udp_port@ clearsilver_LIBS = @clearsilver_LIBS@ datadir = @datadir@ datarootdir = @datarootdir@ dbusservicedir = @dbusservicedir@ -default_pkcs11 = @default_pkcs11@ +dev_headers = @dev_headers@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ @@ -226,11 +231,12 @@ imcvdir = @imcvdir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ +ipsec_script = @ipsec_script@ +ipsec_script_upper = @ipsec_script_upper@ ipsecdir = @ipsecdir@ ipsecgroup = @ipsecgroup@ ipseclibdir = @ipseclibdir@ ipsecuser = @ipsecuser@ -libcharon_plugins = @libcharon_plugins@ libdir = @libdir@ libexecdir = @libexecdir@ linux_headers = @linux_headers@ @@ -246,6 +252,7 @@ mkdir_p = @mkdir_p@ nm_CFLAGS = @nm_CFLAGS@ nm_LIBS = @nm_LIBS@ nm_ca_dir = @nm_ca_dir@ +nm_plugins = @nm_plugins@ oldincludedir = @oldincludedir@ openac_plugins = @openac_plugins@ p_plugins = @p_plugins@ @@ -255,7 +262,6 @@ pdfdir = @pdfdir@ piddir = @piddir@ pki_plugins = @pki_plugins@ plugindir = @plugindir@ -pluto_plugins = @pluto_plugins@ pool_plugins = @pool_plugins@ prefix = @prefix@ program_transform_name = @program_transform_name@ diff --git a/src/libstrongswan/plugins/padlock/padlock_aes_crypter.c b/src/libstrongswan/plugins/padlock/padlock_aes_crypter.c index 119de86aa..b5060de0a 100644 --- a/src/libstrongswan/plugins/padlock/padlock_aes_crypter.c +++ b/src/libstrongswan/plugins/padlock/padlock_aes_crypter.c @@ -109,16 +109,18 @@ static void crypt(private_padlock_aes_crypter_t *this, char *iv, memwipe(key_aligned, sizeof(key_aligned)); } -METHOD(crypter_t, decrypt, void, +METHOD(crypter_t, decrypt, bool, private_padlock_aes_crypter_t *this, chunk_t data, chunk_t iv, chunk_t *dst) { crypt(this, iv.ptr, data, dst, TRUE); + return TRUE; } -METHOD(crypter_t, encrypt, void, +METHOD(crypter_t, encrypt, bool, private_padlock_aes_crypter_t *this, chunk_t data, chunk_t iv, chunk_t *dst) { crypt(this, iv.ptr, data, dst, FALSE); + return TRUE; } METHOD(crypter_t, get_block_size, size_t, @@ -139,10 +141,11 @@ METHOD(crypter_t, get_key_size, size_t, return this->key.len; } -METHOD(crypter_t, set_key, void, +METHOD(crypter_t, set_key, bool, private_padlock_aes_crypter_t *this, chunk_t key) { memcpy(this->key.ptr, key.ptr, min(key.len, this->key.len)); + return TRUE; } METHOD(crypter_t, destroy, void, diff --git a/src/libstrongswan/plugins/padlock/padlock_rng.c b/src/libstrongswan/plugins/padlock/padlock_rng.c index 3d805df9d..517914ab5 100644 --- a/src/libstrongswan/plugins/padlock/padlock_rng.c +++ b/src/libstrongswan/plugins/padlock/padlock_rng.c @@ -69,7 +69,7 @@ static void rng(char *buf, int len, int quality) } } -METHOD(rng_t, allocate_bytes, void, +METHOD(rng_t, allocate_bytes, bool, private_padlock_rng_t *this, size_t bytes, chunk_t *chunk) { chunk->len = bytes; @@ -77,9 +77,10 @@ METHOD(rng_t, allocate_bytes, void, chunk->ptr = malloc(bytes + 7); rng(chunk->ptr, chunk->len, this->quality); + return TRUE; } -METHOD(rng_t, get_bytes, void, +METHOD(rng_t, get_bytes, bool, private_padlock_rng_t *this, size_t bytes, u_int8_t *buffer) { chunk_t chunk; @@ -88,6 +89,7 @@ METHOD(rng_t, get_bytes, void, allocate_bytes(this, bytes, &chunk); memcpy(buffer, chunk.ptr, bytes); chunk_clear(&chunk); + return TRUE; } METHOD(rng_t, destroy, void, diff --git a/src/libstrongswan/plugins/padlock/padlock_sha1_hasher.c b/src/libstrongswan/plugins/padlock/padlock_sha1_hasher.c index 66a077353..4489b902a 100644 --- a/src/libstrongswan/plugins/padlock/padlock_sha1_hasher.c +++ b/src/libstrongswan/plugins/padlock/padlock_sha1_hasher.c @@ -83,13 +83,14 @@ static void append_data(private_padlock_sha1_hasher_t *this, chunk_t data) this->data.len += data.len; } -METHOD(hasher_t, reset, void, +METHOD(hasher_t, reset, bool, private_padlock_sha1_hasher_t *this) { chunk_free(&this->data); + return TRUE; } -METHOD(hasher_t, get_hash, void, +METHOD(hasher_t, get_hash, bool, private_padlock_sha1_hasher_t *this, chunk_t chunk, u_int8_t *hash) { if (hash) @@ -109,20 +110,18 @@ METHOD(hasher_t, get_hash, void, { append_data(this, chunk); } + return TRUE; } -METHOD(hasher_t, allocate_hash, void, +METHOD(hasher_t, allocate_hash, bool, 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); + return get_hash(this, chunk, hash->ptr); } + return get_hash(this, chunk, NULL); } METHOD(hasher_t, get_hash_size, size_t, diff --git a/src/libstrongswan/plugins/pem/Makefile.in b/src/libstrongswan/plugins/pem/Makefile.in index 98c196ef4..7988d1e74 100644 --- a/src/libstrongswan/plugins/pem/Makefile.in +++ b/src/libstrongswan/plugins/pem/Makefile.in @@ -49,6 +49,7 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/config/libtool.m4 \ am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; @@ -83,7 +84,7 @@ libstrongswan_pem_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \ $(libstrongswan_pem_la_LDFLAGS) $(LDFLAGS) -o $@ @MONOLITHIC_FALSE@am_libstrongswan_pem_la_rpath = -rpath $(plugindir) @MONOLITHIC_TRUE@am_libstrongswan_pem_la_rpath = -DEFAULT_INCLUDES = -I.@am__isrc@ +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles am__mv = mv -f @@ -109,6 +110,7 @@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ +BFDLIB = @BFDLIB@ BTLIB = @BTLIB@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ @@ -203,11 +205,14 @@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ c_plugins = @c_plugins@ +charon_natt_port = @charon_natt_port@ +charon_plugins = @charon_plugins@ +charon_udp_port = @charon_udp_port@ clearsilver_LIBS = @clearsilver_LIBS@ datadir = @datadir@ datarootdir = @datarootdir@ dbusservicedir = @dbusservicedir@ -default_pkcs11 = @default_pkcs11@ +dev_headers = @dev_headers@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ @@ -224,11 +229,12 @@ imcvdir = @imcvdir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ +ipsec_script = @ipsec_script@ +ipsec_script_upper = @ipsec_script_upper@ ipsecdir = @ipsecdir@ ipsecgroup = @ipsecgroup@ ipseclibdir = @ipseclibdir@ ipsecuser = @ipsecuser@ -libcharon_plugins = @libcharon_plugins@ libdir = @libdir@ libexecdir = @libexecdir@ linux_headers = @linux_headers@ @@ -244,6 +250,7 @@ mkdir_p = @mkdir_p@ nm_CFLAGS = @nm_CFLAGS@ nm_LIBS = @nm_LIBS@ nm_ca_dir = @nm_ca_dir@ +nm_plugins = @nm_plugins@ oldincludedir = @oldincludedir@ openac_plugins = @openac_plugins@ p_plugins = @p_plugins@ @@ -253,7 +260,6 @@ pdfdir = @pdfdir@ piddir = @piddir@ pki_plugins = @pki_plugins@ plugindir = @plugindir@ -pluto_plugins = @pluto_plugins@ pool_plugins = @pool_plugins@ prefix = @prefix@ program_transform_name = @program_transform_name@ diff --git a/src/libstrongswan/plugins/pem/pem_builder.c b/src/libstrongswan/plugins/pem/pem_builder.c index c5d96be47..9b9777031 100644 --- a/src/libstrongswan/plugins/pem/pem_builder.c +++ b/src/libstrongswan/plugins/pem/pem_builder.c @@ -104,15 +104,21 @@ static status_t pem_decrypt(chunk_t *blob, encryption_algorithm_t alg, } hash.len = hasher->get_hash_size(hasher); hash.ptr = alloca(hash.len); - hasher->get_hash(hasher, passphrase, NULL); - hasher->get_hash(hasher, salt, hash.ptr); + if (!hasher->get_hash(hasher, passphrase, NULL) || + !hasher->get_hash(hasher, salt, hash.ptr)) + { + return FAILED; + } memcpy(key.ptr, hash.ptr, hash.len); if (key.len > hash.len) { - hasher->get_hash(hasher, hash, NULL); - hasher->get_hash(hasher, passphrase, NULL); - hasher->get_hash(hasher, salt, hash.ptr); + if (!hasher->get_hash(hasher, hash, NULL) || + !hasher->get_hash(hasher, passphrase, NULL) || + !hasher->get_hash(hasher, salt, hash.ptr)) + { + return FAILED; + } memcpy(key.ptr + hash.len, hash.ptr, key.len - hash.len); } hasher->destroy(hasher); @@ -125,7 +131,6 @@ static status_t pem_decrypt(chunk_t *blob, encryption_algorithm_t alg, encryption_algorithm_names, alg); return NOT_SUPPORTED; } - crypter->set_key(crypter, key); if (iv.len != crypter->get_iv_size(crypter) || blob->len % crypter->get_block_size(crypter)) @@ -134,7 +139,12 @@ static status_t pem_decrypt(chunk_t *blob, encryption_algorithm_t alg, DBG1(DBG_ASN, " data size is not multiple of block size"); return PARSE_ERROR; } - crypter->decrypt(crypter, *blob, iv, &decrypted); + if (!crypter->set_key(crypter, key) || + !crypter->decrypt(crypter, *blob, iv, &decrypted)) + { + crypter->destroy(crypter); + return FAILED; + } crypter->destroy(crypter); memcpy(blob->ptr, decrypted.ptr, blob->len); chunk_free(&decrypted); @@ -275,7 +285,7 @@ static status_t pem_to_bin(chunk_t *blob, bool *pgp) else { DBG1(DBG_ASN, " encryption algorithm '%.*s'" - " not supported", dek.len, dek.ptr); + " not supported", (int)dek.len, dek.ptr); return NOT_SUPPORTED; } eat_whitespace(&value); diff --git a/src/libstrongswan/plugins/pem/pem_plugin.c b/src/libstrongswan/plugins/pem/pem_plugin.c index fca717a10..d74ab9ee3 100644 --- a/src/libstrongswan/plugins/pem/pem_plugin.c +++ b/src/libstrongswan/plugins/pem/pem_plugin.c @@ -46,46 +46,64 @@ METHOD(plugin_t, get_features, int, /* private key PEM decoding */ PLUGIN_REGISTER(PRIVKEY, pem_private_key_load, FALSE), PLUGIN_PROVIDE(PRIVKEY, KEY_ANY), - PLUGIN_DEPENDS(HASHER, HASH_MD5), + PLUGIN_DEPENDS(PRIVKEY, KEY_ANY), + PLUGIN_SDEPEND(HASHER, HASH_MD5), PLUGIN_REGISTER(PRIVKEY, pem_private_key_load, FALSE), PLUGIN_PROVIDE(PRIVKEY, KEY_RSA), - PLUGIN_DEPENDS(HASHER, HASH_MD5), + PLUGIN_DEPENDS(PRIVKEY, KEY_RSA), + PLUGIN_SDEPEND(HASHER, HASH_MD5), PLUGIN_REGISTER(PRIVKEY, pem_private_key_load, FALSE), PLUGIN_PROVIDE(PRIVKEY, KEY_ECDSA), - PLUGIN_DEPENDS(HASHER, HASH_MD5), + PLUGIN_DEPENDS(PRIVKEY, KEY_ECDSA), + PLUGIN_SDEPEND(HASHER, HASH_MD5), PLUGIN_REGISTER(PRIVKEY, pem_private_key_load, FALSE), PLUGIN_PROVIDE(PRIVKEY, KEY_DSA), - PLUGIN_DEPENDS(HASHER, HASH_MD5), + PLUGIN_DEPENDS(PRIVKEY, KEY_DSA), + PLUGIN_SDEPEND(HASHER, HASH_MD5), /* public key PEM decoding */ PLUGIN_REGISTER(PUBKEY, pem_public_key_load, FALSE), PLUGIN_PROVIDE(PUBKEY, KEY_ANY), + PLUGIN_DEPENDS(PUBKEY, KEY_ANY), PLUGIN_REGISTER(PUBKEY, pem_public_key_load, FALSE), PLUGIN_PROVIDE(PUBKEY, KEY_RSA), + PLUGIN_DEPENDS(PUBKEY, KEY_RSA), PLUGIN_REGISTER(PUBKEY, pem_public_key_load, FALSE), PLUGIN_PROVIDE(PUBKEY, KEY_ECDSA), + PLUGIN_DEPENDS(PUBKEY, KEY_ECDSA), PLUGIN_REGISTER(PUBKEY, pem_public_key_load, FALSE), PLUGIN_PROVIDE(PUBKEY, KEY_DSA), + PLUGIN_DEPENDS(PUBKEY, KEY_DSA), /* certificate PEM decoding */ PLUGIN_REGISTER(CERT_DECODE, pem_certificate_load, FALSE), PLUGIN_PROVIDE(CERT_DECODE, CERT_ANY), + PLUGIN_SDEPEND(CERT_DECODE, CERT_X509), + PLUGIN_SDEPEND(CERT_DECODE, CERT_GPG), PLUGIN_REGISTER(CERT_DECODE, pem_certificate_load, FALSE), PLUGIN_PROVIDE(CERT_DECODE, CERT_X509), + PLUGIN_DEPENDS(CERT_DECODE, CERT_X509), PLUGIN_REGISTER(CERT_DECODE, pem_certificate_load, FALSE), PLUGIN_PROVIDE(CERT_DECODE, CERT_X509_CRL), + PLUGIN_DEPENDS(CERT_DECODE, CERT_X509_CRL), PLUGIN_REGISTER(CERT_DECODE, pem_certificate_load, FALSE), PLUGIN_PROVIDE(CERT_DECODE, CERT_X509_OCSP_REQUEST), + PLUGIN_DEPENDS(CERT_DECODE, CERT_X509_OCSP_REQUEST), PLUGIN_REGISTER(CERT_DECODE, pem_certificate_load, FALSE), PLUGIN_PROVIDE(CERT_DECODE, CERT_X509_OCSP_RESPONSE), + PLUGIN_DEPENDS(CERT_DECODE, CERT_X509_OCSP_RESPONSE), PLUGIN_REGISTER(CERT_DECODE, pem_certificate_load, FALSE), PLUGIN_PROVIDE(CERT_DECODE, CERT_X509_AC), + PLUGIN_DEPENDS(CERT_DECODE, CERT_X509_AC), PLUGIN_REGISTER(CERT_DECODE, pem_certificate_load, FALSE), PLUGIN_PROVIDE(CERT_DECODE, CERT_PKCS10_REQUEST), + PLUGIN_DEPENDS(CERT_DECODE, CERT_PKCS10_REQUEST), PLUGIN_REGISTER(CERT_DECODE, pem_certificate_load, FALSE), PLUGIN_PROVIDE(CERT_DECODE, CERT_TRUSTED_PUBKEY), + PLUGIN_DEPENDS(CERT_DECODE, CERT_TRUSTED_PUBKEY), PLUGIN_REGISTER(CERT_DECODE, pem_certificate_load, FALSE), PLUGIN_PROVIDE(CERT_DECODE, CERT_GPG), + PLUGIN_DEPENDS(CERT_DECODE, CERT_GPG), /* pluto specific certificate formats */ PLUGIN_REGISTER(CERT_DECODE, pem_certificate_load, FALSE), diff --git a/src/libstrongswan/plugins/pgp/Makefile.in b/src/libstrongswan/plugins/pgp/Makefile.in index 946424eee..65acdc196 100644 --- a/src/libstrongswan/plugins/pgp/Makefile.in +++ b/src/libstrongswan/plugins/pgp/Makefile.in @@ -49,6 +49,7 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/config/libtool.m4 \ am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; @@ -83,7 +84,7 @@ libstrongswan_pgp_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \ $(libstrongswan_pgp_la_LDFLAGS) $(LDFLAGS) -o $@ @MONOLITHIC_FALSE@am_libstrongswan_pgp_la_rpath = -rpath $(plugindir) @MONOLITHIC_TRUE@am_libstrongswan_pgp_la_rpath = -DEFAULT_INCLUDES = -I.@am__isrc@ +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles am__mv = mv -f @@ -109,6 +110,7 @@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ +BFDLIB = @BFDLIB@ BTLIB = @BTLIB@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ @@ -203,11 +205,14 @@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ c_plugins = @c_plugins@ +charon_natt_port = @charon_natt_port@ +charon_plugins = @charon_plugins@ +charon_udp_port = @charon_udp_port@ clearsilver_LIBS = @clearsilver_LIBS@ datadir = @datadir@ datarootdir = @datarootdir@ dbusservicedir = @dbusservicedir@ -default_pkcs11 = @default_pkcs11@ +dev_headers = @dev_headers@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ @@ -224,11 +229,12 @@ imcvdir = @imcvdir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ +ipsec_script = @ipsec_script@ +ipsec_script_upper = @ipsec_script_upper@ ipsecdir = @ipsecdir@ ipsecgroup = @ipsecgroup@ ipseclibdir = @ipseclibdir@ ipsecuser = @ipsecuser@ -libcharon_plugins = @libcharon_plugins@ libdir = @libdir@ libexecdir = @libexecdir@ linux_headers = @linux_headers@ @@ -244,6 +250,7 @@ mkdir_p = @mkdir_p@ nm_CFLAGS = @nm_CFLAGS@ nm_LIBS = @nm_LIBS@ nm_ca_dir = @nm_ca_dir@ +nm_plugins = @nm_plugins@ oldincludedir = @oldincludedir@ openac_plugins = @openac_plugins@ p_plugins = @p_plugins@ @@ -253,7 +260,6 @@ pdfdir = @pdfdir@ piddir = @piddir@ pki_plugins = @pki_plugins@ plugindir = @plugindir@ -pluto_plugins = @pluto_plugins@ pool_plugins = @pool_plugins@ prefix = @prefix@ program_transform_name = @program_transform_name@ diff --git a/src/libstrongswan/plugins/pgp/pgp_cert.c b/src/libstrongswan/plugins/pgp/pgp_cert.c index 70a236855..a99bed2f6 100644 --- a/src/libstrongswan/plugins/pgp/pgp_cert.c +++ b/src/libstrongswan/plugins/pgp/pgp_cert.c @@ -114,7 +114,7 @@ METHOD(certificate_t, has_issuer, id_match_t, } METHOD(certificate_t, issued_by,bool, - private_pgp_cert_t *this, certificate_t *issuer) + private_pgp_cert_t *this, certificate_t *issuer, signature_scheme_t *scheme) { /* TODO: check signature blobs for a valid signature */ return FALSE; @@ -321,8 +321,12 @@ static bool parse_public_key(private_pgp_cert_t *this, chunk_t packet) DBG1(DBG_ASN, "no SHA-1 hasher available"); return FALSE; } - hasher->allocate_hash(hasher, pubkey_packet_header, NULL); - hasher->allocate_hash(hasher, pubkey_packet, &this->fingerprint); + if (!hasher->allocate_hash(hasher, pubkey_packet_header, NULL) || + !hasher->allocate_hash(hasher, pubkey_packet, &this->fingerprint)) + { + hasher->destroy(hasher); + return FALSE; + } hasher->destroy(hasher); DBG2(DBG_ASN, "L2 - v4 fingerprint %#B", &this->fingerprint); } diff --git a/src/libstrongswan/plugins/pgp/pgp_encoder.c b/src/libstrongswan/plugins/pgp/pgp_encoder.c index 9043cdb9f..d16d1d71b 100644 --- a/src/libstrongswan/plugins/pgp/pgp_encoder.c +++ b/src/libstrongswan/plugins/pgp/pgp_encoder.c @@ -44,8 +44,12 @@ static bool build_v3_fingerprint(chunk_t *encoding, va_list args) { e = chunk_skip(e, 1); } - hasher->allocate_hash(hasher, n, NULL); - hasher->allocate_hash(hasher, e, encoding); + if (!hasher->allocate_hash(hasher, n, NULL) || + !hasher->allocate_hash(hasher, e, encoding)) + { + hasher->destroy(hasher); + return FALSE; + } hasher->destroy(hasher); return TRUE; } diff --git a/src/libstrongswan/plugins/pkcs1/Makefile.in b/src/libstrongswan/plugins/pkcs1/Makefile.in index f9322a62d..85246f3de 100644 --- a/src/libstrongswan/plugins/pkcs1/Makefile.in +++ b/src/libstrongswan/plugins/pkcs1/Makefile.in @@ -49,6 +49,7 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/config/libtool.m4 \ am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; @@ -84,7 +85,7 @@ libstrongswan_pkcs1_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \ @MONOLITHIC_FALSE@am_libstrongswan_pkcs1_la_rpath = -rpath \ @MONOLITHIC_FALSE@ $(plugindir) @MONOLITHIC_TRUE@am_libstrongswan_pkcs1_la_rpath = -DEFAULT_INCLUDES = -I.@am__isrc@ +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles am__mv = mv -f @@ -110,6 +111,7 @@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ +BFDLIB = @BFDLIB@ BTLIB = @BTLIB@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ @@ -204,11 +206,14 @@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ c_plugins = @c_plugins@ +charon_natt_port = @charon_natt_port@ +charon_plugins = @charon_plugins@ +charon_udp_port = @charon_udp_port@ clearsilver_LIBS = @clearsilver_LIBS@ datadir = @datadir@ datarootdir = @datarootdir@ dbusservicedir = @dbusservicedir@ -default_pkcs11 = @default_pkcs11@ +dev_headers = @dev_headers@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ @@ -225,11 +230,12 @@ imcvdir = @imcvdir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ +ipsec_script = @ipsec_script@ +ipsec_script_upper = @ipsec_script_upper@ ipsecdir = @ipsecdir@ ipsecgroup = @ipsecgroup@ ipseclibdir = @ipseclibdir@ ipsecuser = @ipsecuser@ -libcharon_plugins = @libcharon_plugins@ libdir = @libdir@ libexecdir = @libexecdir@ linux_headers = @linux_headers@ @@ -245,6 +251,7 @@ mkdir_p = @mkdir_p@ nm_CFLAGS = @nm_CFLAGS@ nm_LIBS = @nm_LIBS@ nm_ca_dir = @nm_ca_dir@ +nm_plugins = @nm_plugins@ oldincludedir = @oldincludedir@ openac_plugins = @openac_plugins@ p_plugins = @p_plugins@ @@ -254,7 +261,6 @@ pdfdir = @pdfdir@ piddir = @piddir@ pki_plugins = @pki_plugins@ plugindir = @plugindir@ -pluto_plugins = @pluto_plugins@ pool_plugins = @pool_plugins@ prefix = @prefix@ program_transform_name = @program_transform_name@ diff --git a/src/libstrongswan/plugins/pkcs1/pkcs1_encoder.c b/src/libstrongswan/plugins/pkcs1/pkcs1_encoder.c index 6957b2ad1..9122e8d8e 100644 --- a/src/libstrongswan/plugins/pkcs1/pkcs1_encoder.c +++ b/src/libstrongswan/plugins/pkcs1/pkcs1_encoder.c @@ -94,14 +94,14 @@ static bool hash_pubkey(chunk_t pubkey, chunk_t *hash) hasher_t *hasher; hasher = lib->crypto->create_hasher(lib->crypto, HASH_SHA1); - if (hasher == NULL) + if (!hasher || !hasher->allocate_hash(hasher, pubkey, hash)) { + DESTROY_IF(hasher); chunk_free(&pubkey); DBG1(DBG_LIB, "SHA1 hash algorithm not supported, " "fingerprinting failed"); return FALSE; } - hasher->allocate_hash(hasher, pubkey, hash); hasher->destroy(hasher); chunk_free(&pubkey); return TRUE; diff --git a/src/libstrongswan/plugins/pkcs11/Makefile.in b/src/libstrongswan/plugins/pkcs11/Makefile.in index 2ead77f5a..dc0ab1e82 100644 --- a/src/libstrongswan/plugins/pkcs11/Makefile.in +++ b/src/libstrongswan/plugins/pkcs11/Makefile.in @@ -49,6 +49,7 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/config/libtool.m4 \ am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; @@ -87,7 +88,7 @@ libstrongswan_pkcs11_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \ @MONOLITHIC_FALSE@am_libstrongswan_pkcs11_la_rpath = -rpath \ @MONOLITHIC_FALSE@ $(plugindir) @MONOLITHIC_TRUE@am_libstrongswan_pkcs11_la_rpath = -DEFAULT_INCLUDES = -I.@am__isrc@ +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles am__mv = mv -f @@ -113,6 +114,7 @@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ +BFDLIB = @BFDLIB@ BTLIB = @BTLIB@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ @@ -207,11 +209,14 @@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ c_plugins = @c_plugins@ +charon_natt_port = @charon_natt_port@ +charon_plugins = @charon_plugins@ +charon_udp_port = @charon_udp_port@ clearsilver_LIBS = @clearsilver_LIBS@ datadir = @datadir@ datarootdir = @datarootdir@ dbusservicedir = @dbusservicedir@ -default_pkcs11 = @default_pkcs11@ +dev_headers = @dev_headers@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ @@ -228,11 +233,12 @@ imcvdir = @imcvdir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ +ipsec_script = @ipsec_script@ +ipsec_script_upper = @ipsec_script_upper@ ipsecdir = @ipsecdir@ ipsecgroup = @ipsecgroup@ ipseclibdir = @ipseclibdir@ ipsecuser = @ipsecuser@ -libcharon_plugins = @libcharon_plugins@ libdir = @libdir@ libexecdir = @libexecdir@ linux_headers = @linux_headers@ @@ -248,6 +254,7 @@ mkdir_p = @mkdir_p@ nm_CFLAGS = @nm_CFLAGS@ nm_LIBS = @nm_LIBS@ nm_ca_dir = @nm_ca_dir@ +nm_plugins = @nm_plugins@ oldincludedir = @oldincludedir@ openac_plugins = @openac_plugins@ p_plugins = @p_plugins@ @@ -257,7 +264,6 @@ pdfdir = @pdfdir@ piddir = @piddir@ pki_plugins = @pki_plugins@ plugindir = @plugindir@ -pluto_plugins = @pluto_plugins@ pool_plugins = @pool_plugins@ prefix = @prefix@ program_transform_name = @program_transform_name@ diff --git a/src/libstrongswan/plugins/pkcs11/pkcs11_creds.c b/src/libstrongswan/plugins/pkcs11/pkcs11_creds.c index a81ec1147..7536ce1d3 100644 --- a/src/libstrongswan/plugins/pkcs11/pkcs11_creds.c +++ b/src/libstrongswan/plugins/pkcs11/pkcs11_creds.c @@ -109,7 +109,8 @@ static void find_certificates(private_pkcs11_creds_t *this, if (cert) { DBG1(DBG_CFG, " loaded %strusted cert '%.*s'", - entry->trusted ? "" : "un", entry->label.len, entry->label.ptr); + entry->trusted ? "" : "un", (int)entry->label.len, + entry->label.ptr); /* trusted certificates are also returned as untrusted */ this->untrusted->insert_last(this->untrusted, cert); if (entry->trusted) @@ -120,7 +121,7 @@ static void find_certificates(private_pkcs11_creds_t *this, else { DBG1(DBG_CFG, " loading cert '%.*s' failed", - entry->label.len, entry->label.ptr); + (int)entry->label.len, entry->label.ptr); } free(entry->value.ptr); free(entry->label.ptr); diff --git a/src/libstrongswan/plugins/pkcs11/pkcs11_hasher.c b/src/libstrongswan/plugins/pkcs11/pkcs11_hasher.c index 069fa98b6..53a2bfca7 100644 --- a/src/libstrongswan/plugins/pkcs11/pkcs11_hasher.c +++ b/src/libstrongswan/plugins/pkcs11/pkcs11_hasher.c @@ -84,7 +84,7 @@ METHOD(hasher_t, get_hash_size, size_t, /** * Save the Operation state to host memory */ -static void save_state(private_pkcs11_hasher_t *this) +static bool save_state(private_pkcs11_hasher_t *this) { CK_RV rv; @@ -110,20 +110,20 @@ static void save_state(private_pkcs11_hasher_t *this) continue; case CKR_OK: this->have_state = TRUE; - return; + return TRUE; default: break; } break; } DBG1(DBG_CFG, "C_GetOperationState() failed: %N", ck_rv_names, rv); - abort(); + return FALSE; } /** * Load the Operation state from host memory */ -static void load_state(private_pkcs11_hasher_t *this) +static bool load_state(private_pkcs11_hasher_t *this) { CK_RV rv; @@ -132,18 +132,20 @@ static void load_state(private_pkcs11_hasher_t *this) if (rv != CKR_OK) { DBG1(DBG_CFG, "C_SetOperationState() failed: %N", ck_rv_names, rv); - abort(); + return FALSE; } this->have_state = FALSE; + return TRUE; } -METHOD(hasher_t, reset, void, +METHOD(hasher_t, reset, bool, private_pkcs11_hasher_t *this) { this->have_state = FALSE; + return TRUE; } -METHOD(hasher_t, get_hash, void, +METHOD(hasher_t, get_hash, bool, private_pkcs11_hasher_t *this, chunk_t chunk, u_int8_t *hash) { CK_RV rv; @@ -152,7 +154,11 @@ METHOD(hasher_t, get_hash, void, this->mutex->lock(this->mutex); if (this->have_state) { - load_state(this); + if (!load_state(this)) + { + this->mutex->unlock(this->mutex); + return FALSE; + } } else { @@ -160,7 +166,8 @@ METHOD(hasher_t, get_hash, void, if (rv != CKR_OK) { DBG1(DBG_CFG, "C_DigestInit() failed: %N", ck_rv_names, rv); - abort(); + this->mutex->unlock(this->mutex); + return FALSE; } } if (chunk.len) @@ -169,7 +176,8 @@ METHOD(hasher_t, get_hash, void, if (rv != CKR_OK) { DBG1(DBG_CFG, "C_DigestUpdate() failed: %N", ck_rv_names, rv); - abort(); + this->mutex->unlock(this->mutex); + return FALSE; } } if (hash) @@ -180,28 +188,31 @@ METHOD(hasher_t, get_hash, void, if (rv != CKR_OK) { DBG1(DBG_CFG, "C_DigestFinal() failed: %N", ck_rv_names, rv); - abort(); + this->mutex->unlock(this->mutex); + return FALSE; } } else { - save_state(this); + if (!save_state(this)) + { + this->mutex->unlock(this->mutex); + return FALSE; + } } this->mutex->unlock(this->mutex); + return TRUE; } -METHOD(hasher_t, allocate_hash, void, +METHOD(hasher_t, allocate_hash, bool, private_pkcs11_hasher_t *this, chunk_t chunk, chunk_t *hash) { if (hash) { *hash = chunk_alloc(this->size); - get_hash(this, chunk, hash->ptr); - } - else - { - get_hash(this, chunk, NULL); + return get_hash(this, chunk, hash->ptr); } + return get_hash(this, chunk, NULL); } METHOD(hasher_t, destroy, void, diff --git a/src/libstrongswan/plugins/pkcs11/pkcs11_manager.c b/src/libstrongswan/plugins/pkcs11/pkcs11_manager.c index 5b321b26e..83c383671 100644 --- a/src/libstrongswan/plugins/pkcs11/pkcs11_manager.c +++ b/src/libstrongswan/plugins/pkcs11/pkcs11_manager.c @@ -61,8 +61,6 @@ typedef struct { char *path; /* loaded library */ pkcs11_library_t *lib; - /* event dispatcher job */ - callback_job_t *job; } lib_entry_t; /** @@ -70,10 +68,6 @@ typedef struct { */ static void lib_entry_destroy(lib_entry_t *entry) { - if (entry->job) - { - entry->job->cancel(entry->job); - } entry->lib->destroy(entry->lib); free(entry); } @@ -202,14 +196,6 @@ static job_requeue_t dispatch_slot_events(lib_entry_t *entry) } /** - * End dispatching, unset job - */ -static void end_dispatch(lib_entry_t *entry) -{ - entry->job = NULL; -} - -/** * Get the slot list of a library */ static CK_SLOT_ID_PTR get_slot_list(pkcs11_library_t *p11, CK_ULONG *out) @@ -384,9 +370,9 @@ pkcs11_manager_t *pkcs11_manager_create(pkcs11_manager_token_event_t cb, while (enumerator->enumerate(enumerator, &entry)) { query_slots(entry); - entry->job = callback_job_create_with_prio((void*)dispatch_slot_events, - entry, (void*)end_dispatch, NULL, JOB_PRIO_CRITICAL); - lib->processor->queue_job(lib->processor, (job_t*)entry->job); + lib->processor->queue_job(lib->processor, + (job_t*)callback_job_create_with_prio((void*)dispatch_slot_events, + entry, NULL, (void*)return_false, JOB_PRIO_CRITICAL)); } enumerator->destroy(enumerator); diff --git a/src/libstrongswan/plugins/pkcs11/pkcs11_private_key.c b/src/libstrongswan/plugins/pkcs11/pkcs11_private_key.c index b616abc38..f7f7d3f79 100644 --- a/src/libstrongswan/plugins/pkcs11/pkcs11_private_key.c +++ b/src/libstrongswan/plugins/pkcs11/pkcs11_private_key.c @@ -266,13 +266,15 @@ METHOD(private_key_t, sign, bool, } if (hash_alg != HASH_UNKNOWN) { - hasher_t *hasher = lib->crypto->create_hasher(lib->crypto, hash_alg); - if (!hasher) + hasher_t *hasher; + + hasher = lib->crypto->create_hasher(lib->crypto, hash_alg); + if (!hasher || !hasher->allocate_hash(hasher, data, &hash)) { + DESTROY_IF(hasher); this->lib->f->C_CloseSession(session); return FALSE; } - hasher->allocate_hash(hasher, data, &hash); hasher->destroy(hasher); data = hash; } diff --git a/src/libstrongswan/plugins/pkcs11/pkcs11_public_key.c b/src/libstrongswan/plugins/pkcs11/pkcs11_public_key.c index d4ec9235d..f0d7093db 100644 --- a/src/libstrongswan/plugins/pkcs11/pkcs11_public_key.c +++ b/src/libstrongswan/plugins/pkcs11/pkcs11_public_key.c @@ -235,13 +235,15 @@ METHOD(public_key_t, verify, bool, } if (hash_alg != HASH_UNKNOWN) { - hasher_t *hasher = lib->crypto->create_hasher(lib->crypto, hash_alg); - if (!hasher) + hasher_t *hasher; + + hasher = lib->crypto->create_hasher(lib->crypto, hash_alg); + if (!hasher || !hasher->allocate_hash(hasher, data, &hash)) { + DESTROY_IF(hasher); this->lib->f->C_CloseSession(session); return FALSE; } - hasher->allocate_hash(hasher, data, &hash); hasher->destroy(hasher); data = hash; } @@ -374,12 +376,12 @@ static bool fingerprint_ecdsa(private_pkcs11_public_key_t *this, return FALSE; } hasher = lib->crypto->create_hasher(lib->crypto, HASH_SHA1); - if (!hasher) + if (!hasher || !hasher->allocate_hash(hasher, asn1, fp)) { + DESTROY_IF(hasher); chunk_clear(&asn1); return FALSE; } - hasher->allocate_hash(hasher, asn1, fp); hasher->destroy(hasher); chunk_clear(&asn1); lib->encoding->cache(lib->encoding, type, this, *fp); diff --git a/src/libstrongswan/plugins/pkcs11/pkcs11_rng.c b/src/libstrongswan/plugins/pkcs11/pkcs11_rng.c index 45cf0b7c2..20e4b6f76 100644 --- a/src/libstrongswan/plugins/pkcs11/pkcs11_rng.c +++ b/src/libstrongswan/plugins/pkcs11/pkcs11_rng.c @@ -43,7 +43,7 @@ struct private_pkcs11_rng_t { }; -METHOD(rng_t, get_bytes, void, +METHOD(rng_t, get_bytes, bool, private_pkcs11_rng_t *this, size_t bytes, u_int8_t *buffer) { CK_RV rv; @@ -51,15 +51,21 @@ METHOD(rng_t, get_bytes, void, if (rv != CKR_OK) { DBG1(DBG_CFG, "C_GenerateRandom() failed: %N", ck_rv_names, rv); - abort(); + return FALSE; } + return TRUE; } -METHOD(rng_t, allocate_bytes, void, +METHOD(rng_t, allocate_bytes, bool, private_pkcs11_rng_t *this, size_t bytes, chunk_t *chunk) { *chunk = chunk_alloc(bytes); - get_bytes(this, chunk->len, chunk->ptr); + if (!get_bytes(this, chunk->len, chunk->ptr)) + { + chunk_clear(chunk); + return FALSE; + } + return TRUE; } METHOD(rng_t, destroy, void, diff --git a/src/libstrongswan/plugins/pkcs8/Makefile.in b/src/libstrongswan/plugins/pkcs8/Makefile.in index 2b9c6cf95..60d7ae643 100644 --- a/src/libstrongswan/plugins/pkcs8/Makefile.in +++ b/src/libstrongswan/plugins/pkcs8/Makefile.in @@ -49,6 +49,7 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/config/libtool.m4 \ am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; @@ -83,7 +84,7 @@ libstrongswan_pkcs8_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \ @MONOLITHIC_FALSE@am_libstrongswan_pkcs8_la_rpath = -rpath \ @MONOLITHIC_FALSE@ $(plugindir) @MONOLITHIC_TRUE@am_libstrongswan_pkcs8_la_rpath = -DEFAULT_INCLUDES = -I.@am__isrc@ +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles am__mv = mv -f @@ -109,6 +110,7 @@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ +BFDLIB = @BFDLIB@ BTLIB = @BTLIB@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ @@ -203,11 +205,14 @@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ c_plugins = @c_plugins@ +charon_natt_port = @charon_natt_port@ +charon_plugins = @charon_plugins@ +charon_udp_port = @charon_udp_port@ clearsilver_LIBS = @clearsilver_LIBS@ datadir = @datadir@ datarootdir = @datarootdir@ dbusservicedir = @dbusservicedir@ -default_pkcs11 = @default_pkcs11@ +dev_headers = @dev_headers@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ @@ -224,11 +229,12 @@ imcvdir = @imcvdir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ +ipsec_script = @ipsec_script@ +ipsec_script_upper = @ipsec_script_upper@ ipsecdir = @ipsecdir@ ipsecgroup = @ipsecgroup@ ipseclibdir = @ipseclibdir@ ipsecuser = @ipsecuser@ -libcharon_plugins = @libcharon_plugins@ libdir = @libdir@ libexecdir = @libexecdir@ linux_headers = @linux_headers@ @@ -244,6 +250,7 @@ mkdir_p = @mkdir_p@ nm_CFLAGS = @nm_CFLAGS@ nm_LIBS = @nm_LIBS@ nm_ca_dir = @nm_ca_dir@ +nm_plugins = @nm_plugins@ oldincludedir = @oldincludedir@ openac_plugins = @openac_plugins@ p_plugins = @p_plugins@ @@ -253,7 +260,6 @@ pdfdir = @pdfdir@ piddir = @piddir@ pki_plugins = @pki_plugins@ plugindir = @plugindir@ -pluto_plugins = @pluto_plugins@ pool_plugins = @pool_plugins@ prefix = @prefix@ program_transform_name = @program_transform_name@ diff --git a/src/libstrongswan/plugins/pkcs8/pkcs8_builder.c b/src/libstrongswan/plugins/pkcs8/pkcs8_builder.c index 346240ae1..a501423b1 100644 --- a/src/libstrongswan/plugins/pkcs8/pkcs8_builder.c +++ b/src/libstrongswan/plugins/pkcs8/pkcs8_builder.c @@ -126,7 +126,7 @@ static bool verify_padding(chunk_t *blob) /** * Prototype for key derivation functions. */ -typedef void (*kdf_t)(void *generator, chunk_t password, chunk_t salt, +typedef bool (*kdf_t)(void *generator, chunk_t password, chunk_t salt, u_int64_t iterations, chunk_t key); /** @@ -164,10 +164,15 @@ static private_key_t *decrypt_private_key(chunk_t blob, { chunk_t decrypted; - kdf(generator, shared->get_key(shared), salt, iterations, keymat); - - crypter->set_key(crypter, key); - crypter->decrypt(crypter, blob, iv, &decrypted); + if (!kdf(generator, shared->get_key(shared), salt, iterations, keymat)) + { + continue; + } + if (!crypter->set_key(crypter, key) || + !crypter->decrypt(crypter, blob, iv, &decrypted)) + { + continue; + } if (verify_padding(&decrypted)) { private_key = parse_private_key(decrypted); @@ -188,34 +193,44 @@ static private_key_t *decrypt_private_key(chunk_t blob, /** * Function F of PBKDF2 */ -static void pbkdf2_f(chunk_t block, prf_t *prf, chunk_t seed, +static bool pbkdf2_f(chunk_t block, prf_t *prf, chunk_t seed, u_int64_t iterations) { chunk_t u; u_int64_t i; u = chunk_alloca(prf->get_block_size(prf)); - prf->get_bytes(prf, seed, u.ptr); + if (!prf->get_bytes(prf, seed, u.ptr)) + { + return FALSE; + } memcpy(block.ptr, u.ptr, block.len); for (i = 1; i < iterations; i++) { - prf->get_bytes(prf, u, u.ptr); + if (!prf->get_bytes(prf, u, u.ptr)) + { + return FALSE; + } memxor(block.ptr, u.ptr, block.len); } + return TRUE; } /** * PBKDF2 key derivation function */ -static void pbkdf2(prf_t *prf, chunk_t password, chunk_t salt, +static bool pbkdf2(prf_t *prf, chunk_t password, chunk_t salt, u_int64_t iterations, chunk_t key) { chunk_t keymat, block, seed; size_t blocks; u_int32_t i = 0, *ni; - prf->set_key(prf, password); + if (!prf->set_key(prf, password)) + { + return FALSE; + } block.len = prf->get_block_size(prf); blocks = (key.len - 1) / block.len + 1; @@ -228,10 +243,15 @@ static void pbkdf2(prf_t *prf, chunk_t password, chunk_t salt, { *ni = htonl(i + 1); block.ptr = keymat.ptr + (i * block.len); - pbkdf2_f(block, prf, seed, iterations); + if (!pbkdf2_f(block, prf, seed, iterations)) + { + return FALSE; + } } memcpy(key.ptr, keymat.ptr, key.len); + + return TRUE; } /** @@ -266,22 +286,30 @@ static private_key_t *decrypt_private_key_pbes2(chunk_t blob, /** * PBKDF1 key derivation function */ -static void pbkdf1(hasher_t *hasher, chunk_t password, chunk_t salt, +static bool pbkdf1(hasher_t *hasher, chunk_t password, chunk_t salt, u_int64_t iterations, chunk_t key) { chunk_t hash; u_int64_t i; hash = chunk_alloca(hasher->get_hash_size(hasher)); - hasher->get_hash(hasher, password, NULL); - hasher->get_hash(hasher, salt, hash.ptr); + if (!hasher->get_hash(hasher, password, NULL) || + !hasher->get_hash(hasher, salt, hash.ptr)) + { + return FALSE; + } for (i = 1; i < iterations; i++) { - hasher->get_hash(hasher, hash, hash.ptr); + if (!hasher->get_hash(hasher, hash, hash.ptr)) + { + return FALSE; + } } memcpy(key.ptr, hash.ptr, key.len); + + return TRUE; } /** @@ -535,7 +563,7 @@ static const asn1Object_t encryptedPKIObjects[] = { static private_key_t *parse_encrypted_private_key(chunk_t blob) { asn1_parser_t *parser; - chunk_t object, params, salt, iv; + chunk_t object, params, salt = chunk_empty, iv = chunk_empty; u_int64_t iterations = 0; int objectID; encryption_algorithm_t encr = ENCR_UNDEFINED; diff --git a/src/libstrongswan/plugins/plugin_feature.c b/src/libstrongswan/plugins/plugin_feature.c index 2a97205bb..6e043878c 100644 --- a/src/libstrongswan/plugins/plugin_feature.c +++ b/src/libstrongswan/plugins/plugin_feature.c @@ -1,4 +1,7 @@ /* + * Copyright (C) 2012 Tobias Brunner + * Hochschule fuer Technik Rapperswil + * * Copyright (C) 2011 Martin Willi * Copyright (C) 2011 revosec AG * @@ -29,6 +32,7 @@ ENUM(plugin_feature_names, FEATURE_NONE, FEATURE_CUSTOM, "PRF", "DH", "RNG", + "NONCE_GEN", "PRIVKEY", "PRIVKEY_GEN", "PRIVKEY_SIGN", @@ -40,6 +44,8 @@ ENUM(plugin_feature_names, FEATURE_NONE, FEATURE_CUSTOM, "CERT_ENCODE", "EAP_SERVER", "EAP_CLIENT", + "XAUTH_SERVER", + "XAUTH_CLIENT", "DATABASE", "FETCHER", "CUSTOM", @@ -48,6 +54,56 @@ ENUM(plugin_feature_names, FEATURE_NONE, FEATURE_CUSTOM, /** * See header. */ +u_int32_t plugin_feature_hash(plugin_feature_t *feature) +{ + chunk_t data; + + switch (feature->type) + { + case FEATURE_NONE: + case FEATURE_RNG: + case FEATURE_NONCE_GEN: + case FEATURE_DATABASE: + case FEATURE_FETCHER: + /* put these special cases in their (type-specific) buckets */ + data = chunk_empty; + break; + case FEATURE_CRYPTER: + case FEATURE_AEAD: + case FEATURE_SIGNER: + case FEATURE_HASHER: + case FEATURE_PRF: + case FEATURE_DH: + case FEATURE_PRIVKEY: + case FEATURE_PRIVKEY_GEN: + case FEATURE_PUBKEY: + case FEATURE_PRIVKEY_SIGN: + case FEATURE_PUBKEY_VERIFY: + case FEATURE_PRIVKEY_DECRYPT: + case FEATURE_PUBKEY_ENCRYPT: + case FEATURE_CERT_DECODE: + case FEATURE_CERT_ENCODE: + case FEATURE_EAP_SERVER: + case FEATURE_EAP_PEER: + data = chunk_from_thing(feature->arg); + break; + case FEATURE_CUSTOM: + data = chunk_create(feature->arg.custom, + strlen(feature->arg.custom)); + break; + case FEATURE_XAUTH_SERVER: + case FEATURE_XAUTH_PEER: + data = chunk_create(feature->arg.xauth, + strlen(feature->arg.xauth)); + break; + } + return chunk_hash_inc(chunk_from_thing(feature->type), + chunk_hash(data)); +} + +/** + * See header. + */ bool plugin_feature_matches(plugin_feature_t *a, plugin_feature_t *b) { if (a->type == b->type) @@ -72,6 +128,8 @@ bool plugin_feature_matches(plugin_feature_t *a, plugin_feature_t *b) return a->arg.dh_group == b->arg.dh_group; case FEATURE_RNG: return a->arg.rng_quality <= b->arg.rng_quality; + case FEATURE_NONCE_GEN: + return TRUE; case FEATURE_PRIVKEY: case FEATURE_PRIVKEY_GEN: case FEATURE_PUBKEY: @@ -96,6 +154,9 @@ bool plugin_feature_matches(plugin_feature_t *a, plugin_feature_t *b) streq(a->arg.fetcher, b->arg.fetcher); case FEATURE_CUSTOM: return streq(a->arg.custom, b->arg.custom); + case FEATURE_XAUTH_SERVER: + case FEATURE_XAUTH_PEER: + return streq(a->arg.xauth, b->arg.xauth); } } return FALSE; @@ -167,6 +228,12 @@ char* plugin_feature_get_string(plugin_feature_t *feature) return str; } break; + case FEATURE_NONCE_GEN: + if (asprintf(&str, "%N", plugin_feature_names, feature->type) > 0) + { + return str; + } + break; case FEATURE_PRIVKEY: case FEATURE_PRIVKEY_GEN: case FEATURE_PUBKEY: @@ -229,6 +296,14 @@ char* plugin_feature_get_string(plugin_feature_t *feature) return str; } break; + case FEATURE_XAUTH_SERVER: + case FEATURE_XAUTH_PEER: + if (asprintf(&str, "%N:%s", plugin_feature_names, feature->type, + feature->arg.xauth) > 0) + { + return str; + } + break; } if (!str) { @@ -251,7 +326,8 @@ bool plugin_feature_load(plugin_t *plugin, plugin_feature_t *feature, } if (reg->kind == FEATURE_CALLBACK) { - if (reg->arg.cb.f(plugin, feature, TRUE, reg->arg.cb.data)) + if (!reg->arg.cb.f || + reg->arg.cb.f(plugin, feature, TRUE, reg->arg.cb.data)) { return TRUE; } @@ -288,6 +364,10 @@ bool plugin_feature_load(plugin_t *plugin, plugin_feature_t *feature, lib->crypto->add_rng(lib->crypto, feature->arg.rng_quality, name, reg->arg.reg.f); break; + case FEATURE_NONCE_GEN: + lib->crypto->add_nonce_gen(lib->crypto, + name, reg->arg.reg.f); + break; case FEATURE_PRIVKEY: case FEATURE_PRIVKEY_GEN: lib->creds->add_builder(lib->creds, CRED_PRIVATE_KEY, @@ -330,7 +410,8 @@ bool plugin_feature_unload(plugin_t *plugin, plugin_feature_t *feature, } if (reg->kind == FEATURE_CALLBACK) { - if (reg->arg.cb.f(plugin, feature, FALSE, reg->arg.cb.data)) + if (!reg->arg.cb.f || + reg->arg.cb.f(plugin, feature, FALSE, reg->arg.cb.data)) { return TRUE; } @@ -359,6 +440,9 @@ bool plugin_feature_unload(plugin_t *plugin, plugin_feature_t *feature, case FEATURE_RNG: lib->crypto->remove_rng(lib->crypto, reg->arg.reg.f); break; + case FEATURE_NONCE_GEN: + lib->crypto->remove_nonce_gen(lib->crypto, reg->arg.reg.f); + break; case FEATURE_PRIVKEY: case FEATURE_PRIVKEY_GEN: lib->creds->remove_builder(lib->creds, reg->arg.reg.f); diff --git a/src/libstrongswan/plugins/plugin_feature.h b/src/libstrongswan/plugins/plugin_feature.h index b1500feba..90f8a948a 100644 --- a/src/libstrongswan/plugins/plugin_feature.h +++ b/src/libstrongswan/plugins/plugin_feature.h @@ -1,4 +1,7 @@ /* + * Copyright (C) 2012 Tobias Brunner + * Hochschule fuer Technik Rapperswil + * * Copyright (C) 2011 Martin Willi * Copyright (C) 2011 revosec AG * @@ -48,17 +51,19 @@ typedef bool (*plugin_feature_callback_t)(plugin_t *plugin, * features provided by the plugin, hard (DEPENDS) or soft (SDEPEND) dependency * specified is related to the previously defined PROVIDE feature. * If a plugin feature requires to hook in functionality into the library - * or a daemon, it can use REGISTER or CALLBACK entries. Each PROVIDED feature + * or a daemon, it can use REGISTER or CALLBACK entries. Each PROVIDE feature * uses the REGISTER/CALLBACK entry defined previously. The REGISTER entry * defines a common feature registration function directly passed to the * associated manager or factory (crypto/credential factory etc.). A callback * function is more generic allows the loader to invoke a callback to do - * the registration. + * the registration. PROVIDE features that do not use a registration or callback + * function must be listed before any REGISTER/CALLBACK entry, or use the NOOP + * helper macro. * - * To conviently create feature lists, use the four macros PLUGIN_REGISTER, - * PLUGIN_CALLBACK, PLUGIN_PROVIDE, PLUGIN_DEPENDS and PLUGIN_SDEPEND. Use - * identation to show how the registration functions and dependencies are - * related to a provided feature, such as: + * To conveniently create feature lists, use the macros PLUGIN_REGISTER, + * PLUGIN_CALLBACK, PLUGIN_NOOP, PLUGIN_PROVIDE, PLUGIN_DEPENDS and + * PLUGIN_SDEPEND. Use indentation to show how the registration functions + * and dependencies are related to a provided feature, such as: * * @verbatim // two features, one with two dependencies, both use a callback to register @@ -72,7 +77,8 @@ typedef bool (*plugin_feature_callback_t)(plugin_t *plugin, PLUGIN_PROVIDE(...), PLUGIN_DEPENDS(...), // feature that does not use a registration function - PLUGIN_PROVIDE(...), + PLUGIN_NOOP, + PLUGIN_PROVIDE(...), @endverbatim */ struct plugin_feature_t { @@ -107,6 +113,8 @@ struct plugin_feature_t { FEATURE_DH, /** rng_t */ FEATURE_RNG, + /** nonce_gen_t */ + FEATURE_NONCE_GEN, /** generic private key support */ FEATURE_PRIVKEY, /** generating new private keys */ @@ -129,6 +137,10 @@ struct plugin_feature_t { FEATURE_EAP_SERVER, /** EAP peer implementation */ FEATURE_EAP_PEER, + /** XAuth server implementation */ + FEATURE_XAUTH_SERVER, + /** XAuth peer implementation */ + FEATURE_XAUTH_PEER, /** database_t */ FEATURE_DATABASE, /** fetcher_t */ @@ -182,6 +194,8 @@ struct plugin_feature_t { char *fetcher; /** FEATURE_CUSTOM */ char *custom; + /** FEATURE_XAUTH_SERVER/CLIENT */ + char *xauth; /** FEATURE_REGISTER */ struct { @@ -221,6 +235,11 @@ struct plugin_feature_t { #define PLUGIN_CALLBACK(cb, data) _PLUGIN_FEATURE_CALLBACK(cb, data) /** + * The upcoming features use neither a callback nor a register function. + */ +#define PLUGIN_NOOP _PLUGIN_FEATURE_CALLBACK(NULL, NULL) + +/** * Define a feature the plugin provides. * * @param type feature type to provide @@ -252,6 +271,7 @@ struct plugin_feature_t { #define _PLUGIN_FEATURE_PRF(kind, alg) __PLUGIN_FEATURE(kind, PRF, .prf = alg) #define _PLUGIN_FEATURE_DH(kind, group) __PLUGIN_FEATURE(kind, DH, .dh_group = group) #define _PLUGIN_FEATURE_RNG(kind, quality) __PLUGIN_FEATURE(kind, RNG, .rng_quality = quality) +#define _PLUGIN_FEATURE_NONCE_GEN(kind, ...) __PLUGIN_FEATURE(kind, NONCE_GEN, .custom = NULL) #define _PLUGIN_FEATURE_PRIVKEY(kind, type) __PLUGIN_FEATURE(kind, PRIVKEY, .privkey = type) #define _PLUGIN_FEATURE_PRIVKEY_GEN(kind, type) __PLUGIN_FEATURE(kind, PRIVKEY_GEN, .privkey_gen = type) #define _PLUGIN_FEATURE_PRIVKEY_SIGN(kind, scheme) __PLUGIN_FEATURE(kind, PRIVKEY_SIGN, .privkey_sign = scheme) @@ -266,6 +286,8 @@ struct plugin_feature_t { #define _PLUGIN_FEATURE_DATABASE(kind, type) __PLUGIN_FEATURE(kind, DATABASE, .database = type) #define _PLUGIN_FEATURE_FETCHER(kind, type) __PLUGIN_FEATURE(kind, FETCHER, .fetcher = type) #define _PLUGIN_FEATURE_CUSTOM(kind, name) __PLUGIN_FEATURE(kind, CUSTOM, .custom = name) +#define _PLUGIN_FEATURE_XAUTH_SERVER(kind, name) __PLUGIN_FEATURE(kind, XAUTH_SERVER, .xauth = name) +#define _PLUGIN_FEATURE_XAUTH_PEER(kind, name) __PLUGIN_FEATURE(kind, XAUTH_PEER, .xauth = name) #define __PLUGIN_FEATURE_REGISTER(type, _f) (plugin_feature_t){ FEATURE_REGISTER, FEATURE_##type, .arg.reg.f = _f } #define __PLUGIN_FEATURE_REGISTER_BUILDER(type, _f, _final) (plugin_feature_t){ FEATURE_REGISTER, FEATURE_##type, .arg.reg = {.f = _f, .final = _final, }} @@ -276,6 +298,7 @@ struct plugin_feature_t { #define _PLUGIN_FEATURE_REGISTER_PRF(type, f) __PLUGIN_FEATURE_REGISTER(type, f) #define _PLUGIN_FEATURE_REGISTER_DH(type, f) __PLUGIN_FEATURE_REGISTER(type, f) #define _PLUGIN_FEATURE_REGISTER_RNG(type, f) __PLUGIN_FEATURE_REGISTER(type, f) +#define _PLUGIN_FEATURE_REGISTER_NONCE_GEN(type, f) __PLUGIN_FEATURE_REGISTER(type, f) #define _PLUGIN_FEATURE_REGISTER_PRIVKEY(type, f, final) __PLUGIN_FEATURE_REGISTER_BUILDER(type, f, final) #define _PLUGIN_FEATURE_REGISTER_PRIVKEY_GEN(type, f, final)__PLUGIN_FEATURE_REGISTER_BUILDER(type, f, final) #define _PLUGIN_FEATURE_REGISTER_PUBKEY(type, f, final) __PLUGIN_FEATURE_REGISTER_BUILDER(type, f, final) @@ -292,6 +315,18 @@ struct plugin_feature_t { extern enum_name_t *plugin_feature_names; /** + * Calculates a hash value for the given feature. + * + * Since this is intended to be used with the plugin_features_matches function + * the hash is not really unique for all types of features (e.g. RNGs are all + * mapped to the same value because they are loosely matched by said function). + * + * @param feature feature to hash + * @return hash value of the feature + */ +u_int32_t plugin_feature_hash(plugin_feature_t *feature); + +/** * Check if feature a matches to feature b. * * @param a feature to check diff --git a/src/libstrongswan/plugins/plugin_loader.c b/src/libstrongswan/plugins/plugin_loader.c index f97cbb31f..95a0bfc02 100644 --- a/src/libstrongswan/plugins/plugin_loader.c +++ b/src/libstrongswan/plugins/plugin_loader.c @@ -25,6 +25,7 @@ #include <debug.h> #include <library.h> #include <integrity_checker.h> +#include <utils/hashtable.h> #include <utils/linked_list.h> #include <plugins/plugin.h> @@ -47,6 +48,11 @@ struct private_plugin_loader_t { linked_list_t *plugins; /** + * Hashtable for loaded features, as plugin_feature_t + */ + hashtable_t *loaded_features; + + /** * List of names of loaded plugins */ char *loaded_plugins; @@ -63,6 +69,11 @@ struct plugin_entry_t { plugin_t *plugin; /** + * TRUE, if the plugin is marked as critical + */ + bool critical; + + /** * dlopen handle, if in separate lib */ void *handle; @@ -94,12 +105,93 @@ static void plugin_entry_destroy(plugin_entry_t *entry) } /** + * Wrapper for static plugin features + */ +typedef struct { + + /** + * Implements plugin_t interface + */ + plugin_t public; + + /** + * Name of the module registering these features + */ + char *name; + + /** + * Static plugin features + */ + plugin_feature_t *features; + + /** + * Number of plugin features + */ + int count; + +} static_features_t; + +METHOD(plugin_t, get_static_name, char*, + static_features_t *this) +{ + return this->name; +} + +METHOD(plugin_t, get_static_features, int, + static_features_t *this, plugin_feature_t *features[]) +{ + *features = this->features; + return this->count; +} + +METHOD(plugin_t, static_destroy, void, + static_features_t *this) +{ + free(this->features); + free(this->name); + free(this); +} + +/** + * Create a wrapper around static plugin features. + */ +static plugin_t *static_features_create(const char *name, + plugin_feature_t features[], int count) +{ + static_features_t *this; + + INIT(this, + .public = { + .get_name = _get_static_name, + .get_features = _get_static_features, + .destroy = _static_destroy, + }, + .name = strdup(name), + .features = calloc(count, sizeof(plugin_feature_t)), + .count = count, + ); + + memcpy(this->features, features, sizeof(plugin_feature_t) * count); + + return &this->public; +} + +/** + * Compare function for hashtable of loaded features. + */ +static bool plugin_feature_equals(plugin_feature_t *a, plugin_feature_t *b) +{ + return a == b; +} + +/** * create a plugin * returns: NOT_FOUND, if the constructor was not found * FAILED, if the plugin could not be constructed */ static status_t create_plugin(private_plugin_loader_t *this, void *handle, - char *name, bool integrity, plugin_entry_t **entry) + char *name, bool integrity, bool critical, + plugin_entry_t **entry) { char create[128]; plugin_t *plugin; @@ -135,6 +227,7 @@ static status_t create_plugin(private_plugin_loader_t *this, void *handle, } INIT(*entry, .plugin = plugin, + .critical = critical, .loaded = linked_list_create(), .failed = linked_list_create(), ); @@ -145,19 +238,23 @@ static status_t create_plugin(private_plugin_loader_t *this, void *handle, /** * load a single plugin */ -static bool load_plugin(private_plugin_loader_t *this, char *name, char *file) +static bool load_plugin(private_plugin_loader_t *this, char *name, char *file, + bool critical) { plugin_entry_t *entry; void *handle; - switch (create_plugin(this, RTLD_DEFAULT, name, FALSE, &entry)) + switch (create_plugin(this, RTLD_DEFAULT, name, FALSE, critical, &entry)) { case SUCCESS: this->plugins->insert_last(this->plugins, entry); return TRUE; case NOT_FOUND: - /* try to load the plugin from a file */ - break; + if (file) + { /* try to load the plugin from a file */ + break; + } + /* fall-through */ default: return FALSE; } @@ -176,7 +273,7 @@ static bool load_plugin(private_plugin_loader_t *this, char *name, char *file) DBG1(DBG_LIB, "plugin '%s' failed to load: %s", name, dlerror()); return FALSE; } - if (create_plugin(this, handle, name, TRUE, &entry) != SUCCESS) + if (create_plugin(this, handle, name, TRUE, critical, &entry) != SUCCESS) { dlclose(handle); return FALSE; @@ -294,32 +391,15 @@ static bool dependencies_satisfied(private_plugin_loader_t *this, /* first entry is provided feature, followed by dependencies */ for (i = 1; i < count; i++) { - enumerator_t *entries, *loaded; - plugin_feature_t *feature; - plugin_entry_t *current; - bool found = FALSE; + plugin_feature_t *found; if (features[i].kind != FEATURE_DEPENDS && features[i].kind != FEATURE_SDEPEND) { /* end of dependencies */ break; } - entries = this->plugins->create_enumerator(this->plugins); - while (entries->enumerate(entries, ¤t)) - { - loaded = current->loaded->create_enumerator(current->loaded); - while (loaded->enumerate(loaded, &feature)) - { - if (plugin_feature_matches(&features[i], feature)) - { - found = TRUE; - break; - } - } - loaded->destroy(loaded); - } - entries->destroy(entries); - + found = this->loaded_features->get_match(this->loaded_features, + &features[i], (hashtable_equals_t)plugin_feature_matches); if (!found && (features[i].kind != FEATURE_SDEPEND || soft)) { if (report) @@ -361,7 +441,8 @@ static bool dependency_required(private_plugin_loader_t *this, count = entry->plugin->get_features(entry->plugin, &features); for (i = 0; i < count; i++) { - if (feature_loaded(this, entry, &features[i])) + if (&features[i] != dep && + feature_loaded(this, entry, &features[i])) { while (++i < count && (features[i].kind == FEATURE_DEPENDS || features[i].kind == FEATURE_SDEPEND)) @@ -410,6 +491,8 @@ static int load_features(private_plugin_loader_t *this, bool soft, bool report) { if (plugin_feature_load(entry->plugin, feature, reg)) { + this->loaded_features->put(this->loaded_features, + feature, feature); entry->loaded->insert_last(entry->loaded, feature); loaded++; } @@ -428,6 +511,10 @@ static int load_features(private_plugin_loader_t *this, bool soft, bool report) } feature++; } + if (loaded && !report) + { /* got new feature, restart from beginning of list */ + break; + } } enumerator->destroy(enumerator); return loaded; @@ -451,6 +538,8 @@ static int unload_features(private_plugin_loader_t *this, plugin_entry_t *entry) !dependency_required(this, feature) && plugin_feature_unload(entry->plugin, feature, reg)) { + this->loaded_features->remove(this->loaded_features, + feature); entry->loaded->remove(entry->loaded, feature, NULL); unloaded++; } @@ -468,6 +557,55 @@ static int unload_features(private_plugin_loader_t *this, plugin_entry_t *entry) } /** + * Check that we have all features loaded for critical plugins + */ +static bool missing_critical_features(private_plugin_loader_t *this) +{ + enumerator_t *enumerator; + plugin_entry_t *entry; + bool critical_failed = FALSE; + + enumerator = this->plugins->create_enumerator(this->plugins); + while (enumerator->enumerate(enumerator, &entry)) + { + if (!entry->plugin->get_features) + { /* feature interface not supported */ + continue; + } + if (entry->critical) + { + plugin_feature_t *feature; + char *name, *provide; + int count, i, failed = 0; + + name = entry->plugin->get_name(entry->plugin); + count = entry->plugin->get_features(entry->plugin, &feature); + for (i = 0; i < count; i++, feature++) + { + if (feature->kind == FEATURE_PROVIDE && + !feature_loaded(this, entry, feature)) + { + provide = plugin_feature_get_string(feature); + DBG2(DBG_LIB, " failed to load %s in critical plugin '%s'", + provide, name); + free(provide); + failed++; + } + } + if (failed) + { + DBG1(DBG_LIB, "failed to load %d feature%s in critical plugin " + "'%s'", failed, failed > 1 ? "s" : "", name); + critical_failed = TRUE; + } + } + } + enumerator->destroy(enumerator); + + return critical_failed; +} + +/** * Remove plugins that we were not able to load any features from. */ static void purge_plugins(private_plugin_loader_t *this) @@ -491,6 +629,24 @@ static void purge_plugins(private_plugin_loader_t *this) enumerator->destroy(enumerator); } +METHOD(plugin_loader_t, add_static_features, void, + private_plugin_loader_t *this, const char *name, + plugin_feature_t features[], int count, bool critical) +{ + plugin_entry_t *entry; + plugin_t *plugin; + + plugin = static_features_create(name, features, count); + + INIT(entry, + .plugin = plugin, + .critical = critical, + .loaded = linked_list_create(), + .failed = linked_list_create(), + ); + this->plugins->insert_last(this->plugins, entry); +} + METHOD(plugin_loader_t, load_plugins, bool, private_plugin_loader_t *this, char *path, char *list) { @@ -498,16 +654,18 @@ METHOD(plugin_loader_t, load_plugins, bool, char *token; bool critical_failed = FALSE; +#ifdef PLUGINDIR if (path == NULL) { path = PLUGINDIR; } +#endif /* PLUGINDIR */ enumerator = enumerator_create_token(list, " ", " "); while (!critical_failed && enumerator->enumerate(enumerator, &token)) { bool critical = FALSE; - char file[PATH_MAX]; + char buf[PATH_MAX], *file = NULL; int len; token = strdup(token); @@ -522,12 +680,16 @@ METHOD(plugin_loader_t, load_plugins, bool, free(token); continue; } - if (snprintf(file, sizeof(file), "%s/libstrongswan-%s.so", - path, token) >= sizeof(file)) + if (path) { - return FALSE; + if (snprintf(buf, sizeof(buf), "%s/libstrongswan-%s.so", + path, token) >= sizeof(buf)) + { + return FALSE; + } + file = buf; } - if (!load_plugin(this, token, file) && critical) + if (!load_plugin(this, token, file, critical) && critical) { critical_failed = TRUE; DBG1(DBG_LIB, "loading critical plugin '%s' failed", token); @@ -550,6 +712,8 @@ METHOD(plugin_loader_t, load_plugins, bool, } /* report missing dependencies */ load_features(this, FALSE, TRUE); + /* check for unloaded features provided by critical plugins */ + critical_failed = missing_critical_features(this); /* unload plugins that we were not able to load any features for */ purge_plugins(this); } @@ -660,6 +824,7 @@ METHOD(plugin_loader_t, destroy, void, private_plugin_loader_t *this) { unload(this); + this->loaded_features->destroy(this->loaded_features); this->plugins->destroy(this->plugins); free(this->loaded_plugins); free(this); @@ -674,6 +839,7 @@ plugin_loader_t *plugin_loader_create() INIT(this, .public = { + .add_static_features = _add_static_features, .load = _load_plugins, .reload = _reload, .unload = _unload, @@ -682,6 +848,9 @@ plugin_loader_t *plugin_loader_create() .destroy = _destroy, }, .plugins = linked_list_create(), + .loaded_features = hashtable_create( + (hashtable_hash_t)plugin_feature_hash, + (hashtable_equals_t)plugin_feature_equals, 64), ); return &this->public; diff --git a/src/libstrongswan/plugins/plugin_loader.h b/src/libstrongswan/plugins/plugin_loader.h index 7fd07044d..94181dbb6 100644 --- a/src/libstrongswan/plugins/plugin_loader.h +++ b/src/libstrongswan/plugins/plugin_loader.h @@ -26,12 +26,36 @@ typedef struct plugin_loader_t plugin_loader_t; #include <utils/enumerator.h> +/* to avoid circular references we can't include plugin_feature.h */ +struct plugin_feature_t; + /** * The plugin_loader loads plugins from a directory and initializes them */ struct plugin_loader_t { /** + * Add static plugin features, not loaded via plugins. + * + * Similar to features provided by plugins they are evaluated during load(), + * and unloaded when unload() is called. + * + * If critical is TRUE load() will fail if any of the added features could + * not be loaded. + * + * @note The name should be unique otherwise a plugin with the same name is + * not loaded. + * + * @param name name of the component adding the features + * @param features array of plugin features + * @param count number of features in the array + * @param critical TRUE if the features are critical + */ + void (*add_static_features) (plugin_loader_t *this, const char *name, + struct plugin_feature_t *features, int count, + bool critical); + + /** * Load a list of plugins from a directory. * * Each plugin in list may have a ending exclamation mark (!) to mark it diff --git a/src/libstrongswan/plugins/pubkey/Makefile.in b/src/libstrongswan/plugins/pubkey/Makefile.in index 0de048791..6680873c2 100644 --- a/src/libstrongswan/plugins/pubkey/Makefile.in +++ b/src/libstrongswan/plugins/pubkey/Makefile.in @@ -49,6 +49,7 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/config/libtool.m4 \ am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; @@ -84,7 +85,7 @@ libstrongswan_pubkey_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \ @MONOLITHIC_FALSE@am_libstrongswan_pubkey_la_rpath = -rpath \ @MONOLITHIC_FALSE@ $(plugindir) @MONOLITHIC_TRUE@am_libstrongswan_pubkey_la_rpath = -DEFAULT_INCLUDES = -I.@am__isrc@ +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles am__mv = mv -f @@ -110,6 +111,7 @@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ +BFDLIB = @BFDLIB@ BTLIB = @BTLIB@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ @@ -204,11 +206,14 @@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ c_plugins = @c_plugins@ +charon_natt_port = @charon_natt_port@ +charon_plugins = @charon_plugins@ +charon_udp_port = @charon_udp_port@ clearsilver_LIBS = @clearsilver_LIBS@ datadir = @datadir@ datarootdir = @datarootdir@ dbusservicedir = @dbusservicedir@ -default_pkcs11 = @default_pkcs11@ +dev_headers = @dev_headers@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ @@ -225,11 +230,12 @@ imcvdir = @imcvdir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ +ipsec_script = @ipsec_script@ +ipsec_script_upper = @ipsec_script_upper@ ipsecdir = @ipsecdir@ ipsecgroup = @ipsecgroup@ ipseclibdir = @ipseclibdir@ ipsecuser = @ipsecuser@ -libcharon_plugins = @libcharon_plugins@ libdir = @libdir@ libexecdir = @libexecdir@ linux_headers = @linux_headers@ @@ -245,6 +251,7 @@ mkdir_p = @mkdir_p@ nm_CFLAGS = @nm_CFLAGS@ nm_LIBS = @nm_LIBS@ nm_ca_dir = @nm_ca_dir@ +nm_plugins = @nm_plugins@ oldincludedir = @oldincludedir@ openac_plugins = @openac_plugins@ p_plugins = @p_plugins@ @@ -254,7 +261,6 @@ pdfdir = @pdfdir@ piddir = @piddir@ pki_plugins = @pki_plugins@ plugindir = @plugindir@ -pluto_plugins = @pluto_plugins@ pool_plugins = @pool_plugins@ prefix = @prefix@ program_transform_name = @program_transform_name@ diff --git a/src/libstrongswan/plugins/pubkey/pubkey_cert.c b/src/libstrongswan/plugins/pubkey/pubkey_cert.c index 67240fe0c..0304ccb36 100644 --- a/src/libstrongswan/plugins/pubkey/pubkey_cert.c +++ b/src/libstrongswan/plugins/pubkey/pubkey_cert.c @@ -126,8 +126,13 @@ METHOD(certificate_t, equals, bool, } METHOD(certificate_t, issued_by, bool, - private_pubkey_cert_t *this, certificate_t *issuer) + private_pubkey_cert_t *this, certificate_t *issuer, + signature_scheme_t *scheme) { + if (scheme) + { + *scheme = SIGN_UNKNOWN; + } return equals(this, issuer); } diff --git a/src/libstrongswan/plugins/pubkey/pubkey_plugin.c b/src/libstrongswan/plugins/pubkey/pubkey_plugin.c index 92bfc2e63..a898bbfcc 100644 --- a/src/libstrongswan/plugins/pubkey/pubkey_plugin.c +++ b/src/libstrongswan/plugins/pubkey/pubkey_plugin.c @@ -43,6 +43,11 @@ METHOD(plugin_t, get_features, int, static plugin_feature_t f[] = { PLUGIN_REGISTER(CERT_ENCODE, pubkey_cert_wrap, FALSE), PLUGIN_PROVIDE(CERT_ENCODE, CERT_TRUSTED_PUBKEY), + PLUGIN_REGISTER(CERT_DECODE, pubkey_cert_wrap, TRUE), + PLUGIN_PROVIDE(CERT_DECODE, CERT_TRUSTED_PUBKEY), + PLUGIN_SDEPEND(PUBKEY, KEY_RSA), + PLUGIN_SDEPEND(PUBKEY, KEY_ECDSA), + PLUGIN_SDEPEND(PUBKEY, KEY_DSA), }; *features = f; return countof(f); diff --git a/src/libstrongswan/plugins/random/Makefile.in b/src/libstrongswan/plugins/random/Makefile.in index 9b549b071..a393e8049 100644 --- a/src/libstrongswan/plugins/random/Makefile.in +++ b/src/libstrongswan/plugins/random/Makefile.in @@ -49,6 +49,7 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/config/libtool.m4 \ am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; @@ -84,7 +85,7 @@ libstrongswan_random_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \ @MONOLITHIC_FALSE@am_libstrongswan_random_la_rpath = -rpath \ @MONOLITHIC_FALSE@ $(plugindir) @MONOLITHIC_TRUE@am_libstrongswan_random_la_rpath = -DEFAULT_INCLUDES = -I.@am__isrc@ +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles am__mv = mv -f @@ -110,6 +111,7 @@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ +BFDLIB = @BFDLIB@ BTLIB = @BTLIB@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ @@ -204,11 +206,14 @@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ c_plugins = @c_plugins@ +charon_natt_port = @charon_natt_port@ +charon_plugins = @charon_plugins@ +charon_udp_port = @charon_udp_port@ clearsilver_LIBS = @clearsilver_LIBS@ datadir = @datadir@ datarootdir = @datarootdir@ dbusservicedir = @dbusservicedir@ -default_pkcs11 = @default_pkcs11@ +dev_headers = @dev_headers@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ @@ -225,11 +230,12 @@ imcvdir = @imcvdir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ +ipsec_script = @ipsec_script@ +ipsec_script_upper = @ipsec_script_upper@ ipsecdir = @ipsecdir@ ipsecgroup = @ipsecgroup@ ipseclibdir = @ipseclibdir@ ipsecuser = @ipsecuser@ -libcharon_plugins = @libcharon_plugins@ libdir = @libdir@ libexecdir = @libexecdir@ linux_headers = @linux_headers@ @@ -245,6 +251,7 @@ mkdir_p = @mkdir_p@ nm_CFLAGS = @nm_CFLAGS@ nm_LIBS = @nm_LIBS@ nm_ca_dir = @nm_ca_dir@ +nm_plugins = @nm_plugins@ oldincludedir = @oldincludedir@ openac_plugins = @openac_plugins@ p_plugins = @p_plugins@ @@ -254,7 +261,6 @@ pdfdir = @pdfdir@ piddir = @piddir@ pki_plugins = @pki_plugins@ plugindir = @plugindir@ -pluto_plugins = @pluto_plugins@ pool_plugins = @pool_plugins@ prefix = @prefix@ program_transform_name = @program_transform_name@ diff --git a/src/libstrongswan/plugins/random/random_plugin.c b/src/libstrongswan/plugins/random/random_plugin.c index 7f81e2622..cef20047a 100644 --- a/src/libstrongswan/plugins/random/random_plugin.c +++ b/src/libstrongswan/plugins/random/random_plugin.c @@ -15,9 +15,24 @@ #include "random_plugin.h" +#include <unistd.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <errno.h> + #include <library.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_plugin_t private_random_plugin_t; /** @@ -31,6 +46,41 @@ struct private_random_plugin_t { random_plugin_t public; }; +/** /dev/random file descriptor */ +static int dev_random = -1; +/** /dev/urandom file descriptor */ +static int dev_urandom = -1; + +/** + * See header. + */ +int random_plugin_get_dev_random() +{ + return dev_random; +} + +/** + * See header. + */ +int random_plugin_get_dev_urandom() +{ + return dev_urandom; +} + +/** + * Open a random device file + */ +static bool open_dev(char *file, int *fd) +{ + *fd = open(file, O_RDONLY); + if (*fd == -1) + { + DBG1(DBG_LIB, "opening \"%s\" failed: %s", file, strerror(errno)); + return FALSE; + } + return TRUE; +} + METHOD(plugin_t, get_name, char*, private_random_plugin_t *this) { @@ -52,6 +102,14 @@ METHOD(plugin_t, get_features, int, METHOD(plugin_t, destroy, void, private_random_plugin_t *this) { + if (dev_random != -1) + { + close(dev_random); + } + if (dev_urandom != -1) + { + close(dev_urandom); + } free(this); } @@ -61,6 +119,7 @@ METHOD(plugin_t, destroy, void, plugin_t *random_plugin_create() { private_random_plugin_t *this; + char *urandom_file, *random_file; INIT(this, .public = { @@ -72,6 +131,17 @@ plugin_t *random_plugin_create() }, ); + urandom_file = lib->settings->get_str(lib->settings, + "libstrongswan.plugins.random.urandom", DEV_URANDOM); + random_file = lib->settings->get_str(lib->settings, + "libstrongswan.plugins.random.random", DEV_RANDOM); + if (!open_dev(urandom_file, &dev_urandom) || + !open_dev(random_file, &dev_random)) + { + destroy(this); + return NULL; + } + return &this->public.plugin; } diff --git a/src/libstrongswan/plugins/random/random_plugin.h b/src/libstrongswan/plugins/random/random_plugin.h index 7e22c3e5f..c34fa8196 100644 --- a/src/libstrongswan/plugins/random/random_plugin.h +++ b/src/libstrongswan/plugins/random/random_plugin.h @@ -39,4 +39,14 @@ struct random_plugin_t { plugin_t plugin; }; +/** + * Get the /dev/random file descriptor + */ +int random_plugin_get_dev_random(); + +/** + * Get the /dev/urandom file descriptor + */ +int random_plugin_get_dev_urandom(); + #endif /** RANDOM_PLUGIN_H_ @}*/ diff --git a/src/libstrongswan/plugins/random/random_rng.c b/src/libstrongswan/plugins/random/random_rng.c index 1d99a63d5..52cfc080e 100644 --- a/src/libstrongswan/plugins/random/random_rng.c +++ b/src/libstrongswan/plugins/random/random_rng.c @@ -15,22 +15,12 @@ */ #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 +#include "random_plugin.h" typedef struct private_random_rng_t private_random_rng_t; @@ -47,15 +37,10 @@ struct private_random_rng_t { /** * random device, depends on quality */ - int dev; - - /** - * file we read random bytes from - */ - char *file; + int fd; }; -METHOD(rng_t, get_bytes, void, +METHOD(rng_t, get_bytes, bool, private_random_rng_t *this, size_t bytes, u_int8_t *buffer) { size_t done; @@ -65,30 +50,29 @@ METHOD(rng_t, get_bytes, void, while (done < bytes) { - got = read(this->dev, buffer + done, bytes - done); + got = read(this->fd, buffer + done, bytes - done); if (got <= 0) { - DBG1(DBG_LIB, "reading from \"%s\" failed: %s, retrying...", - this->file, strerror(errno)); - close(this->dev); + DBG1(DBG_LIB, "reading from random FD %d failed: %s, retrying...", + this->fd, strerror(errno)); sleep(1); - this->dev = open(this->file, 0); } done += got; } + return TRUE; } -METHOD(rng_t, allocate_bytes, void, +METHOD(rng_t, allocate_bytes, bool, private_random_rng_t *this, size_t bytes, chunk_t *chunk) { *chunk = chunk_alloc(bytes); get_bytes(this, chunk->len, chunk->ptr); + return TRUE; } METHOD(rng_t, destroy, void, private_random_rng_t *this) { - close(this->dev); free(this); } @@ -109,22 +93,18 @@ random_rng_t *random_rng_create(rng_quality_t quality) }, ); - if (quality == RNG_TRUE) + switch (quality) { - this->file = DEV_RANDOM; - } - else - { - this->file = DEV_URANDOM; + case RNG_TRUE: + this->fd = random_plugin_get_dev_random(); + break; + case RNG_STRONG: + case RNG_WEAK: + default: + this->fd = random_plugin_get_dev_urandom(); + break; } - this->dev = open(this->file, 0); - if (this->dev < 0) - { - DBG1(DBG_LIB, "opening \"%s\" failed: %s", this->file, strerror(errno)); - free(this); - return NULL; - } return &this->public; } diff --git a/src/libstrongswan/plugins/revocation/Makefile.in b/src/libstrongswan/plugins/revocation/Makefile.in index a78762c82..e2cbbbbe0 100644 --- a/src/libstrongswan/plugins/revocation/Makefile.in +++ b/src/libstrongswan/plugins/revocation/Makefile.in @@ -49,6 +49,7 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/config/libtool.m4 \ am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; @@ -86,7 +87,7 @@ libstrongswan_revocation_la_LINK = $(LIBTOOL) --tag=CC \ @MONOLITHIC_FALSE@am_libstrongswan_revocation_la_rpath = -rpath \ @MONOLITHIC_FALSE@ $(plugindir) @MONOLITHIC_TRUE@am_libstrongswan_revocation_la_rpath = -DEFAULT_INCLUDES = -I.@am__isrc@ +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles am__mv = mv -f @@ -112,6 +113,7 @@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ +BFDLIB = @BFDLIB@ BTLIB = @BTLIB@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ @@ -206,11 +208,14 @@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ c_plugins = @c_plugins@ +charon_natt_port = @charon_natt_port@ +charon_plugins = @charon_plugins@ +charon_udp_port = @charon_udp_port@ clearsilver_LIBS = @clearsilver_LIBS@ datadir = @datadir@ datarootdir = @datarootdir@ dbusservicedir = @dbusservicedir@ -default_pkcs11 = @default_pkcs11@ +dev_headers = @dev_headers@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ @@ -227,11 +232,12 @@ imcvdir = @imcvdir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ +ipsec_script = @ipsec_script@ +ipsec_script_upper = @ipsec_script_upper@ ipsecdir = @ipsecdir@ ipsecgroup = @ipsecgroup@ ipseclibdir = @ipseclibdir@ ipsecuser = @ipsecuser@ -libcharon_plugins = @libcharon_plugins@ libdir = @libdir@ libexecdir = @libexecdir@ linux_headers = @linux_headers@ @@ -247,6 +253,7 @@ mkdir_p = @mkdir_p@ nm_CFLAGS = @nm_CFLAGS@ nm_LIBS = @nm_LIBS@ nm_ca_dir = @nm_ca_dir@ +nm_plugins = @nm_plugins@ oldincludedir = @oldincludedir@ openac_plugins = @openac_plugins@ p_plugins = @p_plugins@ @@ -256,7 +263,6 @@ pdfdir = @pdfdir@ piddir = @piddir@ pki_plugins = @pki_plugins@ plugindir = @plugindir@ -pluto_plugins = @pluto_plugins@ pool_plugins = @pool_plugins@ prefix = @prefix@ program_transform_name = @program_transform_name@ diff --git a/src/libstrongswan/plugins/revocation/revocation_validator.c b/src/libstrongswan/plugins/revocation/revocation_validator.c index 34f347d1a..dc8e454e7 100644 --- a/src/libstrongswan/plugins/revocation/revocation_validator.c +++ b/src/libstrongswan/plugins/revocation/revocation_validator.c @@ -103,7 +103,7 @@ static bool verify_ocsp(ocsp_response_t *response, auth_cfg_t *auth) bool verified = FALSE; wrapper = ocsp_response_wrapper_create((ocsp_response_t*)response); - lib->credmgr->add_local_set(lib->credmgr, &wrapper->set); + lib->credmgr->add_local_set(lib->credmgr, &wrapper->set, FALSE); subject = &response->certificate; responder = subject->get_issuer(subject); @@ -111,7 +111,7 @@ static bool verify_ocsp(ocsp_response_t *response, auth_cfg_t *auth) KEY_ANY, responder, FALSE); while (enumerator->enumerate(enumerator, &issuer, ¤t)) { - if (lib->credmgr->issued_by(lib->credmgr, subject, issuer)) + if (lib->credmgr->issued_by(lib->credmgr, subject, issuer, NULL)) { DBG1(DBG_CFG, " ocsp response correctly signed by \"%Y\"", issuer->get_subject(issuer)); @@ -341,7 +341,7 @@ static bool verify_crl(certificate_t *crl, auth_cfg_t *auth) KEY_ANY, crl->get_issuer(crl), FALSE); while (enumerator->enumerate(enumerator, &issuer, ¤t)) { - if (lib->credmgr->issued_by(lib->credmgr, crl, issuer)) + if (lib->credmgr->issued_by(lib->credmgr, crl, issuer, NULL)) { DBG1(DBG_CFG, " crl correctly signed by \"%Y\"", issuer->get_subject(issuer)); diff --git a/src/libstrongswan/plugins/sha1/Makefile.in b/src/libstrongswan/plugins/sha1/Makefile.in index f59c7516d..5188c3fbf 100644 --- a/src/libstrongswan/plugins/sha1/Makefile.in +++ b/src/libstrongswan/plugins/sha1/Makefile.in @@ -49,6 +49,7 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/config/libtool.m4 \ am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; @@ -83,7 +84,7 @@ libstrongswan_sha1_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \ $(libstrongswan_sha1_la_LDFLAGS) $(LDFLAGS) -o $@ @MONOLITHIC_FALSE@am_libstrongswan_sha1_la_rpath = -rpath $(plugindir) @MONOLITHIC_TRUE@am_libstrongswan_sha1_la_rpath = -DEFAULT_INCLUDES = -I.@am__isrc@ +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles am__mv = mv -f @@ -109,6 +110,7 @@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ +BFDLIB = @BFDLIB@ BTLIB = @BTLIB@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ @@ -203,11 +205,14 @@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ c_plugins = @c_plugins@ +charon_natt_port = @charon_natt_port@ +charon_plugins = @charon_plugins@ +charon_udp_port = @charon_udp_port@ clearsilver_LIBS = @clearsilver_LIBS@ datadir = @datadir@ datarootdir = @datarootdir@ dbusservicedir = @dbusservicedir@ -default_pkcs11 = @default_pkcs11@ +dev_headers = @dev_headers@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ @@ -224,11 +229,12 @@ imcvdir = @imcvdir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ +ipsec_script = @ipsec_script@ +ipsec_script_upper = @ipsec_script_upper@ ipsecdir = @ipsecdir@ ipsecgroup = @ipsecgroup@ ipseclibdir = @ipseclibdir@ ipsecuser = @ipsecuser@ -libcharon_plugins = @libcharon_plugins@ libdir = @libdir@ libexecdir = @libexecdir@ linux_headers = @linux_headers@ @@ -244,6 +250,7 @@ mkdir_p = @mkdir_p@ nm_CFLAGS = @nm_CFLAGS@ nm_LIBS = @nm_LIBS@ nm_ca_dir = @nm_ca_dir@ +nm_plugins = @nm_plugins@ oldincludedir = @oldincludedir@ openac_plugins = @openac_plugins@ p_plugins = @p_plugins@ @@ -253,7 +260,6 @@ pdfdir = @pdfdir@ piddir = @piddir@ pki_plugins = @pki_plugins@ plugindir = @plugindir@ -pluto_plugins = @pluto_plugins@ pool_plugins = @pool_plugins@ prefix = @prefix@ program_transform_name = @program_transform_name@ diff --git a/src/libstrongswan/plugins/sha1/sha1_hasher.c b/src/libstrongswan/plugins/sha1/sha1_hasher.c index 4d69ad5a4..b0efbae7d 100644 --- a/src/libstrongswan/plugins/sha1/sha1_hasher.c +++ b/src/libstrongswan/plugins/sha1/sha1_hasher.c @@ -175,7 +175,7 @@ static void SHA1Final(private_sha1_hasher_t *this, u_int8_t *digest) } } -METHOD(hasher_t, reset, void, +METHOD(hasher_t, reset, bool, private_sha1_hasher_t *this) { this->state[0] = 0x67452301; @@ -185,9 +185,11 @@ METHOD(hasher_t, reset, void, this->state[4] = 0xC3D2E1F0; this->count[0] = 0; this->count[1] = 0; + + return TRUE; } -METHOD(hasher_t, get_hash, void, +METHOD(hasher_t, get_hash, bool, private_sha1_hasher_t *this, chunk_t chunk, u_int8_t *buffer) { SHA1Update(this, chunk.ptr, chunk.len); @@ -196,9 +198,10 @@ METHOD(hasher_t, get_hash, void, SHA1Final(this, buffer); reset(this); } + return TRUE; } -METHOD(hasher_t, allocate_hash, void, +METHOD(hasher_t, allocate_hash, bool, private_sha1_hasher_t *this, chunk_t chunk, chunk_t *hash) { SHA1Update(this, chunk.ptr, chunk.len); @@ -210,6 +213,7 @@ METHOD(hasher_t, allocate_hash, void, SHA1Final(this, hash->ptr); reset(this); } + return TRUE; } METHOD(hasher_t, get_hash_size, size_t, diff --git a/src/libstrongswan/plugins/sha1/sha1_prf.c b/src/libstrongswan/plugins/sha1/sha1_prf.c index 11f588c9d..cdc494b34 100644 --- a/src/libstrongswan/plugins/sha1/sha1_prf.c +++ b/src/libstrongswan/plugins/sha1/sha1_prf.c @@ -59,7 +59,7 @@ struct private_sha1_prf_t { */ extern void SHA1Update(private_sha1_hasher_t* this, u_int8_t *data, u_int32_t len); -METHOD(prf_t, get_bytes, void, +METHOD(prf_t, get_bytes, bool, private_sha1_prf_t *this, chunk_t seed, u_int8_t *bytes) { u_int32_t *hash = (u_int32_t*)bytes; @@ -71,6 +71,8 @@ METHOD(prf_t, get_bytes, void, hash[2] = htonl(this->hasher->state[2]); hash[3] = htonl(this->hasher->state[3]); hash[4] = htonl(this->hasher->state[4]); + + return TRUE; } METHOD(prf_t, get_block_size, size_t, @@ -79,11 +81,11 @@ METHOD(prf_t, get_block_size, size_t, return HASH_SIZE_SHA1; } -METHOD(prf_t, allocate_bytes, void, +METHOD(prf_t, allocate_bytes, bool, private_sha1_prf_t *this, chunk_t seed, chunk_t *chunk) { *chunk = chunk_alloc(HASH_SIZE_SHA1); - get_bytes(this, seed, chunk->ptr); + return get_bytes(this, seed, chunk->ptr); } METHOD(prf_t, get_key_size, size_t, @@ -92,18 +94,23 @@ METHOD(prf_t, get_key_size, size_t, return sizeof(this->hasher->state); } -METHOD(prf_t, set_key, void, +METHOD(prf_t, set_key, bool, private_sha1_prf_t *this, chunk_t key) { int i, rounds; u_int32_t *iv = (u_int32_t*)key.ptr; - this->hasher->public.hasher_interface.reset(&this->hasher->public.hasher_interface); + if (!this->hasher->public.hasher_interface.reset( + &this->hasher->public.hasher_interface)) + { + return FALSE; + } 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]); } + return TRUE; } METHOD(prf_t, destroy, void, diff --git a/src/libstrongswan/plugins/sha2/Makefile.in b/src/libstrongswan/plugins/sha2/Makefile.in index c99f30e43..adf7d10b4 100644 --- a/src/libstrongswan/plugins/sha2/Makefile.in +++ b/src/libstrongswan/plugins/sha2/Makefile.in @@ -49,6 +49,7 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/config/libtool.m4 \ am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; @@ -82,7 +83,7 @@ libstrongswan_sha2_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \ $(libstrongswan_sha2_la_LDFLAGS) $(LDFLAGS) -o $@ @MONOLITHIC_FALSE@am_libstrongswan_sha2_la_rpath = -rpath $(plugindir) @MONOLITHIC_TRUE@am_libstrongswan_sha2_la_rpath = -DEFAULT_INCLUDES = -I.@am__isrc@ +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles am__mv = mv -f @@ -108,6 +109,7 @@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ +BFDLIB = @BFDLIB@ BTLIB = @BTLIB@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ @@ -202,11 +204,14 @@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ c_plugins = @c_plugins@ +charon_natt_port = @charon_natt_port@ +charon_plugins = @charon_plugins@ +charon_udp_port = @charon_udp_port@ clearsilver_LIBS = @clearsilver_LIBS@ datadir = @datadir@ datarootdir = @datarootdir@ dbusservicedir = @dbusservicedir@ -default_pkcs11 = @default_pkcs11@ +dev_headers = @dev_headers@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ @@ -223,11 +228,12 @@ imcvdir = @imcvdir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ +ipsec_script = @ipsec_script@ +ipsec_script_upper = @ipsec_script_upper@ ipsecdir = @ipsecdir@ ipsecgroup = @ipsecgroup@ ipseclibdir = @ipseclibdir@ ipsecuser = @ipsecuser@ -libcharon_plugins = @libcharon_plugins@ libdir = @libdir@ libexecdir = @libexecdir@ linux_headers = @linux_headers@ @@ -243,6 +249,7 @@ mkdir_p = @mkdir_p@ nm_CFLAGS = @nm_CFLAGS@ nm_LIBS = @nm_LIBS@ nm_ca_dir = @nm_ca_dir@ +nm_plugins = @nm_plugins@ oldincludedir = @oldincludedir@ openac_plugins = @openac_plugins@ p_plugins = @p_plugins@ @@ -252,7 +259,6 @@ pdfdir = @pdfdir@ piddir = @piddir@ pki_plugins = @pki_plugins@ plugindir = @plugindir@ -pluto_plugins = @pluto_plugins@ pool_plugins = @pool_plugins@ prefix = @prefix@ program_transform_name = @program_transform_name@ diff --git a/src/libstrongswan/plugins/sha2/sha2_hasher.c b/src/libstrongswan/plugins/sha2/sha2_hasher.c index 60fe4bd20..1c6dd2533 100644 --- a/src/libstrongswan/plugins/sha2/sha2_hasher.c +++ b/src/libstrongswan/plugins/sha2/sha2_hasher.c @@ -426,41 +426,49 @@ static void sha512_final(private_sha512_hasher_t *ctx) } while(++j < 8); } -METHOD(hasher_t, reset224, void, +METHOD(hasher_t, reset224, bool, private_sha256_hasher_t *this) { memcpy(&this->sha_H[0], &sha224_hashInit[0], sizeof(this->sha_H)); this->sha_blocks = 0; this->sha_bufCnt = 0; + + return TRUE; } -METHOD(hasher_t, reset256, void, +METHOD(hasher_t, reset256, bool, private_sha256_hasher_t *this) { memcpy(&this->sha_H[0], &sha256_hashInit[0], sizeof(this->sha_H)); this->sha_blocks = 0; this->sha_bufCnt = 0; + + return TRUE; } -METHOD(hasher_t, reset384, void, +METHOD(hasher_t, reset384, bool, private_sha512_hasher_t *this) { memcpy(&this->sha_H[0], &sha384_hashInit[0], sizeof(this->sha_H)); this->sha_blocks = 0; this->sha_blocksMSB = 0; this->sha_bufCnt = 0; + + return TRUE; } -METHOD(hasher_t, reset512, void, +METHOD(hasher_t, reset512, bool, private_sha512_hasher_t *this) { memcpy(&this->sha_H[0], &sha512_hashInit[0], sizeof(this->sha_H)); this->sha_blocks = 0; this->sha_blocksMSB = 0; this->sha_bufCnt = 0; + + return TRUE; } -METHOD(hasher_t, get_hash224, void, +METHOD(hasher_t, get_hash224, bool, private_sha256_hasher_t *this, chunk_t chunk, u_int8_t *buffer) { sha256_write(this, chunk.ptr, chunk.len); @@ -470,9 +478,10 @@ METHOD(hasher_t, get_hash224, void, memcpy(buffer, this->sha_out, HASH_SIZE_SHA224); reset224(this); } + return TRUE; } -METHOD(hasher_t, get_hash256, void, +METHOD(hasher_t, get_hash256, bool, private_sha256_hasher_t *this, chunk_t chunk, u_int8_t *buffer) { sha256_write(this, chunk.ptr, chunk.len); @@ -482,9 +491,10 @@ METHOD(hasher_t, get_hash256, void, memcpy(buffer, this->sha_out, HASH_SIZE_SHA256); reset256(this); } + return TRUE; } -METHOD(hasher_t, get_hash384, void, +METHOD(hasher_t, get_hash384, bool, private_sha512_hasher_t *this, chunk_t chunk, u_int8_t *buffer) { sha512_write(this, chunk.ptr, chunk.len); @@ -494,9 +504,10 @@ METHOD(hasher_t, get_hash384, void, memcpy(buffer, this->sha_out, HASH_SIZE_SHA384); reset384(this); } + return TRUE; } -METHOD(hasher_t, get_hash512, void, +METHOD(hasher_t, get_hash512, bool, private_sha512_hasher_t *this, chunk_t chunk, u_int8_t *buffer) { sha512_write(this, chunk.ptr, chunk.len); @@ -506,9 +517,10 @@ METHOD(hasher_t, get_hash512, void, memcpy(buffer, this->sha_out, HASH_SIZE_SHA512); reset512(this); } + return TRUE; } -METHOD(hasher_t, allocate_hash224, void, +METHOD(hasher_t, allocate_hash224, bool, private_sha256_hasher_t *this, chunk_t chunk, chunk_t *hash) { chunk_t allocated_hash; @@ -522,9 +534,10 @@ METHOD(hasher_t, allocate_hash224, void, reset224(this); *hash = allocated_hash; } + return TRUE; } -METHOD(hasher_t, allocate_hash256, void, +METHOD(hasher_t, allocate_hash256, bool, private_sha256_hasher_t *this, chunk_t chunk, chunk_t *hash) { chunk_t allocated_hash; @@ -538,9 +551,10 @@ METHOD(hasher_t, allocate_hash256, void, reset256(this); *hash = allocated_hash; } + return TRUE; } -METHOD(hasher_t, allocate_hash384, void, +METHOD(hasher_t, allocate_hash384, bool, private_sha512_hasher_t *this, chunk_t chunk, chunk_t *hash) { chunk_t allocated_hash; @@ -554,9 +568,10 @@ METHOD(hasher_t, allocate_hash384, void, reset384(this); *hash = allocated_hash; } + return TRUE; } -METHOD(hasher_t, allocate_hash512, void, +METHOD(hasher_t, allocate_hash512, bool, private_sha512_hasher_t *this, chunk_t chunk, chunk_t *hash) { chunk_t allocated_hash; @@ -570,6 +585,7 @@ METHOD(hasher_t, allocate_hash512, void, reset512(this); *hash = allocated_hash; } + return TRUE; } METHOD(hasher_t, get_hash_size224, size_t, diff --git a/src/libstrongswan/plugins/soup/Makefile.in b/src/libstrongswan/plugins/soup/Makefile.in index ce4b07769..5ab3f94aa 100644 --- a/src/libstrongswan/plugins/soup/Makefile.in +++ b/src/libstrongswan/plugins/soup/Makefile.in @@ -49,6 +49,7 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/config/libtool.m4 \ am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; @@ -83,7 +84,7 @@ libstrongswan_soup_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \ $(libstrongswan_soup_la_LDFLAGS) $(LDFLAGS) -o $@ @MONOLITHIC_FALSE@am_libstrongswan_soup_la_rpath = -rpath $(plugindir) @MONOLITHIC_TRUE@am_libstrongswan_soup_la_rpath = -DEFAULT_INCLUDES = -I.@am__isrc@ +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles am__mv = mv -f @@ -109,6 +110,7 @@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ +BFDLIB = @BFDLIB@ BTLIB = @BTLIB@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ @@ -203,11 +205,14 @@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ c_plugins = @c_plugins@ +charon_natt_port = @charon_natt_port@ +charon_plugins = @charon_plugins@ +charon_udp_port = @charon_udp_port@ clearsilver_LIBS = @clearsilver_LIBS@ datadir = @datadir@ datarootdir = @datarootdir@ dbusservicedir = @dbusservicedir@ -default_pkcs11 = @default_pkcs11@ +dev_headers = @dev_headers@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ @@ -224,11 +229,12 @@ imcvdir = @imcvdir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ +ipsec_script = @ipsec_script@ +ipsec_script_upper = @ipsec_script_upper@ ipsecdir = @ipsecdir@ ipsecgroup = @ipsecgroup@ ipseclibdir = @ipseclibdir@ ipsecuser = @ipsecuser@ -libcharon_plugins = @libcharon_plugins@ libdir = @libdir@ libexecdir = @libexecdir@ linux_headers = @linux_headers@ @@ -244,6 +250,7 @@ mkdir_p = @mkdir_p@ nm_CFLAGS = @nm_CFLAGS@ nm_LIBS = @nm_LIBS@ nm_ca_dir = @nm_ca_dir@ +nm_plugins = @nm_plugins@ oldincludedir = @oldincludedir@ openac_plugins = @openac_plugins@ p_plugins = @p_plugins@ @@ -253,7 +260,6 @@ pdfdir = @pdfdir@ piddir = @piddir@ pki_plugins = @pki_plugins@ plugindir = @plugindir@ -pluto_plugins = @pluto_plugins@ pool_plugins = @pool_plugins@ prefix = @prefix@ program_transform_name = @program_transform_name@ diff --git a/src/libstrongswan/plugins/sqlite/Makefile.in b/src/libstrongswan/plugins/sqlite/Makefile.in index 391827724..f13540edb 100644 --- a/src/libstrongswan/plugins/sqlite/Makefile.in +++ b/src/libstrongswan/plugins/sqlite/Makefile.in @@ -49,6 +49,7 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/config/libtool.m4 \ am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; @@ -85,7 +86,7 @@ libstrongswan_sqlite_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \ @MONOLITHIC_FALSE@am_libstrongswan_sqlite_la_rpath = -rpath \ @MONOLITHIC_FALSE@ $(plugindir) @MONOLITHIC_TRUE@am_libstrongswan_sqlite_la_rpath = -DEFAULT_INCLUDES = -I.@am__isrc@ +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles am__mv = mv -f @@ -111,6 +112,7 @@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ +BFDLIB = @BFDLIB@ BTLIB = @BTLIB@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ @@ -205,11 +207,14 @@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ c_plugins = @c_plugins@ +charon_natt_port = @charon_natt_port@ +charon_plugins = @charon_plugins@ +charon_udp_port = @charon_udp_port@ clearsilver_LIBS = @clearsilver_LIBS@ datadir = @datadir@ datarootdir = @datarootdir@ dbusservicedir = @dbusservicedir@ -default_pkcs11 = @default_pkcs11@ +dev_headers = @dev_headers@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ @@ -226,11 +231,12 @@ imcvdir = @imcvdir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ +ipsec_script = @ipsec_script@ +ipsec_script_upper = @ipsec_script_upper@ ipsecdir = @ipsecdir@ ipsecgroup = @ipsecgroup@ ipseclibdir = @ipseclibdir@ ipsecuser = @ipsecuser@ -libcharon_plugins = @libcharon_plugins@ libdir = @libdir@ libexecdir = @libexecdir@ linux_headers = @linux_headers@ @@ -246,6 +252,7 @@ mkdir_p = @mkdir_p@ nm_CFLAGS = @nm_CFLAGS@ nm_LIBS = @nm_LIBS@ nm_ca_dir = @nm_ca_dir@ +nm_plugins = @nm_plugins@ oldincludedir = @oldincludedir@ openac_plugins = @openac_plugins@ p_plugins = @p_plugins@ @@ -255,7 +262,6 @@ pdfdir = @pdfdir@ piddir = @piddir@ pki_plugins = @pki_plugins@ plugindir = @plugindir@ -pluto_plugins = @pluto_plugins@ pool_plugins = @pool_plugins@ prefix = @prefix@ program_transform_name = @program_transform_name@ diff --git a/src/libstrongswan/plugins/sqlite/sqlite_database.c b/src/libstrongswan/plugins/sqlite/sqlite_database.c index f9e06199e..0fb3c7fff 100644 --- a/src/libstrongswan/plugins/sqlite/sqlite_database.c +++ b/src/libstrongswan/plugins/sqlite/sqlite_database.c @@ -206,6 +206,7 @@ static bool sqlite_enumerator_enumerate(sqlite_enumerator_t *this, ...) } default: DBG1(DBG_LIB, "invalid result type supplied"); + va_end(args); return FALSE; } } diff --git a/src/libstrongswan/plugins/test_vectors/Makefile.in b/src/libstrongswan/plugins/test_vectors/Makefile.in index 7e0271b13..f717ad6d9 100644 --- a/src/libstrongswan/plugins/test_vectors/Makefile.in +++ b/src/libstrongswan/plugins/test_vectors/Makefile.in @@ -49,6 +49,7 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/config/libtool.m4 \ am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; @@ -91,7 +92,7 @@ libstrongswan_test_vectors_la_LINK = $(LIBTOOL) --tag=CC \ @MONOLITHIC_FALSE@am_libstrongswan_test_vectors_la_rpath = -rpath \ @MONOLITHIC_FALSE@ $(plugindir) @MONOLITHIC_TRUE@am_libstrongswan_test_vectors_la_rpath = -DEFAULT_INCLUDES = -I.@am__isrc@ +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles am__mv = mv -f @@ -117,6 +118,7 @@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ +BFDLIB = @BFDLIB@ BTLIB = @BTLIB@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ @@ -211,11 +213,14 @@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ c_plugins = @c_plugins@ +charon_natt_port = @charon_natt_port@ +charon_plugins = @charon_plugins@ +charon_udp_port = @charon_udp_port@ clearsilver_LIBS = @clearsilver_LIBS@ datadir = @datadir@ datarootdir = @datarootdir@ dbusservicedir = @dbusservicedir@ -default_pkcs11 = @default_pkcs11@ +dev_headers = @dev_headers@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ @@ -232,11 +237,12 @@ imcvdir = @imcvdir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ +ipsec_script = @ipsec_script@ +ipsec_script_upper = @ipsec_script_upper@ ipsecdir = @ipsecdir@ ipsecgroup = @ipsecgroup@ ipseclibdir = @ipseclibdir@ ipsecuser = @ipsecuser@ -libcharon_plugins = @libcharon_plugins@ libdir = @libdir@ libexecdir = @libexecdir@ linux_headers = @linux_headers@ @@ -252,6 +258,7 @@ mkdir_p = @mkdir_p@ nm_CFLAGS = @nm_CFLAGS@ nm_LIBS = @nm_LIBS@ nm_ca_dir = @nm_ca_dir@ +nm_plugins = @nm_plugins@ oldincludedir = @oldincludedir@ openac_plugins = @openac_plugins@ p_plugins = @p_plugins@ @@ -261,7 +268,6 @@ pdfdir = @pdfdir@ piddir = @piddir@ pki_plugins = @pki_plugins@ plugindir = @plugindir@ -pluto_plugins = @pluto_plugins@ pool_plugins = @pool_plugins@ prefix = @prefix@ program_transform_name = @program_transform_name@ diff --git a/src/libstrongswan/plugins/test_vectors/test_vectors.h b/src/libstrongswan/plugins/test_vectors/test_vectors.h index 40fb51da6..a00469779 100644 --- a/src/libstrongswan/plugins/test_vectors/test_vectors.h +++ b/src/libstrongswan/plugins/test_vectors/test_vectors.h @@ -140,6 +140,7 @@ TEST_VECTOR_HASHER(md5_7) TEST_VECTOR_HASHER(sha1_1) TEST_VECTOR_HASHER(sha1_2) TEST_VECTOR_HASHER(sha1_3) +TEST_VECTOR_HASHER(sha1_4) TEST_VECTOR_HASHER(sha224_1) TEST_VECTOR_HASHER(sha224_2) TEST_VECTOR_HASHER(sha224_3) diff --git a/src/libstrongswan/plugins/test_vectors/test_vectors/sha1.c b/src/libstrongswan/plugins/test_vectors/test_vectors/sha1.c index 51f22716e..669adf8c6 100644 --- a/src/libstrongswan/plugins/test_vectors/test_vectors/sha1.c +++ b/src/libstrongswan/plugins/test_vectors/test_vectors/sha1.c @@ -49,3 +49,9 @@ hasher_test_vector_t sha1_3 = { "\x2b\xad\x27\xb3" }; +hasher_test_vector_t sha1_4 = { + .alg = HASH_SHA1, .len = 62, + .data = "12345678901234567890123456789012345678901234567890123456789012", + .hash = "\xd8\xd0\x73\xb3\x83\x15\x66\x17\xc5\xca\xdf\x17\xf6\x15\x96\xa3" + "\x84\x0a\xfd\x8b" +}; diff --git a/src/libstrongswan/plugins/x509/Makefile.in b/src/libstrongswan/plugins/x509/Makefile.in index 8c05cb22d..6d9f88647 100644 --- a/src/libstrongswan/plugins/x509/Makefile.in +++ b/src/libstrongswan/plugins/x509/Makefile.in @@ -49,6 +49,7 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/config/libtool.m4 \ am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; @@ -84,7 +85,7 @@ libstrongswan_x509_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \ $(libstrongswan_x509_la_LDFLAGS) $(LDFLAGS) -o $@ @MONOLITHIC_FALSE@am_libstrongswan_x509_la_rpath = -rpath $(plugindir) @MONOLITHIC_TRUE@am_libstrongswan_x509_la_rpath = -DEFAULT_INCLUDES = -I.@am__isrc@ +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles am__mv = mv -f @@ -110,6 +111,7 @@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ +BFDLIB = @BFDLIB@ BTLIB = @BTLIB@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ @@ -204,11 +206,14 @@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ c_plugins = @c_plugins@ +charon_natt_port = @charon_natt_port@ +charon_plugins = @charon_plugins@ +charon_udp_port = @charon_udp_port@ clearsilver_LIBS = @clearsilver_LIBS@ datadir = @datadir@ datarootdir = @datarootdir@ dbusservicedir = @dbusservicedir@ -default_pkcs11 = @default_pkcs11@ +dev_headers = @dev_headers@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ @@ -225,11 +230,12 @@ imcvdir = @imcvdir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ +ipsec_script = @ipsec_script@ +ipsec_script_upper = @ipsec_script_upper@ ipsecdir = @ipsecdir@ ipsecgroup = @ipsecgroup@ ipseclibdir = @ipseclibdir@ ipsecuser = @ipsecuser@ -libcharon_plugins = @libcharon_plugins@ libdir = @libdir@ libexecdir = @libexecdir@ linux_headers = @linux_headers@ @@ -245,6 +251,7 @@ mkdir_p = @mkdir_p@ nm_CFLAGS = @nm_CFLAGS@ nm_LIBS = @nm_LIBS@ nm_ca_dir = @nm_ca_dir@ +nm_plugins = @nm_plugins@ oldincludedir = @oldincludedir@ openac_plugins = @openac_plugins@ p_plugins = @p_plugins@ @@ -254,7 +261,6 @@ pdfdir = @pdfdir@ piddir = @piddir@ pki_plugins = @pki_plugins@ plugindir = @plugindir@ -pluto_plugins = @pluto_plugins@ pool_plugins = @pool_plugins@ prefix = @prefix@ program_transform_name = @program_transform_name@ diff --git a/src/libstrongswan/plugins/x509/x509_ac.c b/src/libstrongswan/plugins/x509/x509_ac.c index a2cb589e0..d6ca8c4fa 100644 --- a/src/libstrongswan/plugins/x509/x509_ac.c +++ b/src/libstrongswan/plugins/x509/x509_ac.c @@ -701,7 +701,7 @@ METHOD(certificate_t, has_issuer, id_match_t, } METHOD(certificate_t, issued_by, bool, - private_x509_ac_t *this, certificate_t *issuer) + private_x509_ac_t *this, certificate_t *issuer, signature_scheme_t *schemep) { public_key_t *key; signature_scheme_t scheme; @@ -750,6 +750,10 @@ METHOD(certificate_t, issued_by, bool, } valid = key->verify(key, scheme, this->certificateInfo, this->signature); key->destroy(key); + if (valid && schemep) + { + *schemep = scheme; + } return valid; } diff --git a/src/libstrongswan/plugins/x509/x509_cert.c b/src/libstrongswan/plugins/x509/x509_cert.c index 4859f4310..2269eb453 100644 --- a/src/libstrongswan/plugins/x509/x509_cert.c +++ b/src/libstrongswan/plugins/x509/x509_cert.c @@ -752,6 +752,9 @@ static void parse_extendedKeyUsage(chunk_t blob, int level0, case OID_CLIENT_AUTH: this->flags |= X509_CLIENT_AUTH; break; + case OID_IKE_INTERMEDIATE: + this->flags |= X509_IKE_INTERMEDIATE; + break; case OID_OCSP_SIGNING: this->flags |= X509_OCSP_SIGNER; break; @@ -1105,19 +1108,19 @@ static void parse_policyConstraints(chunk_t blob, int level0, * ASN.1 definition of ipAddrBlocks according to RFC 3779 */ static const asn1Object_t ipAddrBlocksObjects[] = { - { 0, "ipAddrBlocks", ASN1_SEQUENCE, ASN1_LOOP }, /* 0 */ + { 0, "ipAddrBlocks", ASN1_SEQUENCE, ASN1_LOOP }, /* 0 */ { 1, "ipAddressFamily", ASN1_SEQUENCE, ASN1_NONE }, /* 1 */ - { 2, "addressFamily", ASN1_OCTET_STRING, ASN1_BODY }, /* 2 */ - { 2, "inherit", ASN1_NULL, ASN1_OPT|ASN1_NONE }, /* 3 */ - { 2, "end choice", ASN1_EOC, ASN1_END }, /* 4 */ - { 2, "addressesOrRanges", ASN1_SEQUENCE, ASN1_OPT|ASN1_LOOP }, /* 5 */ - { 3, "addressPrefix", ASN1_BIT_STRING, ASN1_OPT|ASN1_BODY }, /* 6 */ - { 3, "end choice", ASN1_EOC, ASN1_END }, /* 7 */ - { 3, "addressRange", ASN1_SEQUENCE, ASN1_OPT|ASN1_NONE }, /* 8 */ - { 4, "min", ASN1_BIT_STRING, ASN1_BODY }, /* 9 */ - { 4, "max", ASN1_BIT_STRING, ASN1_BODY }, /* 10 */ - { 3, "end choice", ASN1_EOC, ASN1_END }, /* 11 */ - { 2, "end opt/loop", ASN1_EOC, ASN1_END }, /* 12 */ + { 2, "addressFamily", ASN1_OCTET_STRING, ASN1_BODY }, /* 2 */ + { 2, "inherit", ASN1_NULL, ASN1_OPT|ASN1_NONE }, /* 3 */ + { 2, "end choice", ASN1_EOC, ASN1_END }, /* 4 */ + { 2, "addressesOrRanges", ASN1_SEQUENCE, ASN1_OPT|ASN1_LOOP }, /* 5 */ + { 3, "addressPrefix", ASN1_BIT_STRING, ASN1_OPT|ASN1_BODY }, /* 6 */ + { 3, "end choice", ASN1_EOC, ASN1_END }, /* 7 */ + { 3, "addressRange", ASN1_SEQUENCE, ASN1_OPT|ASN1_NONE }, /* 8 */ + { 4, "min", ASN1_BIT_STRING, ASN1_BODY }, /* 9 */ + { 4, "max", ASN1_BIT_STRING, ASN1_BODY }, /* 10 */ + { 3, "end choice", ASN1_EOC, ASN1_END }, /* 11 */ + { 2, "end opt/loop", ASN1_EOC, ASN1_END }, /* 12 */ { 0, "end loop", ASN1_EOC, ASN1_END }, /* 13 */ { 0, "exit", ASN1_EOC, ASN1_EXIT } }; @@ -1480,18 +1483,20 @@ end: /* check if the certificate is self-signed */ if (this->public.interface.interface.issued_by( &this->public.interface.interface, - &this->public.interface.interface)) + &this->public.interface.interface, + NULL)) { this->flags |= X509_SELF_SIGNED; } /* create certificate hash */ hasher = lib->crypto->create_hasher(lib->crypto, HASH_SHA1); - if (hasher == NULL) + if (!hasher || + !hasher->allocate_hash(hasher, this->encoding, &this->encoding_hash)) { + DESTROY_IF(hasher); DBG1(DBG_ASN, " unable to create hash of certificate, SHA1 not supported"); return FALSE; } - hasher->allocate_hash(hasher, this->encoding, &this->encoding_hash); hasher->destroy(hasher); } return success; @@ -1565,7 +1570,8 @@ METHOD(certificate_t, has_issuer, id_match_t, } METHOD(certificate_t, issued_by, bool, - private_x509_cert_t *this, certificate_t *issuer) + private_x509_cert_t *this, certificate_t *issuer, + signature_scheme_t *schemep) { public_key_t *key; signature_scheme_t scheme; @@ -1609,6 +1615,10 @@ METHOD(certificate_t, issued_by, bool, } valid = key->verify(key, scheme, this->tbsCertificate, this->signature); key->destroy(key); + if (valid && schemep) + { + *schemep = scheme; + } return valid; } @@ -1994,6 +2004,7 @@ static bool generate(private_x509_cert_t *cert, certificate_t *sign_cert, chunk_t subjectKeyIdentifier = chunk_empty, authKeyIdentifier = chunk_empty; chunk_t crlDistributionPoints = chunk_empty, authorityInfoAccess = chunk_empty; chunk_t policyConstraints = chunk_empty, inhibitAnyPolicy = chunk_empty; + chunk_t ikeIntermediate = chunk_empty; identification_t *issuer, *subject; chunk_t key_info; signature_scheme_t scheme; @@ -2107,7 +2118,7 @@ static bool generate(private_x509_cert_t *cert, certificate_t *sign_cert, asn1_wrap(ASN1_BIT_STRING, "c", keyUsageBits))); } - /* add serverAuth extendedKeyUsage flag */ + /* add extendedKeyUsage flags */ if (cert->flags & X509_SERVER_AUTH) { serverAuth = asn1_build_known_oid(OID_SERVER_AUTH); @@ -2116,20 +2127,24 @@ static bool generate(private_x509_cert_t *cert, certificate_t *sign_cert, { clientAuth = asn1_build_known_oid(OID_CLIENT_AUTH); } - - /* add ocspSigning extendedKeyUsage flag */ + if (cert->flags & X509_IKE_INTERMEDIATE) + { + ikeIntermediate = asn1_build_known_oid(OID_IKE_INTERMEDIATE); + } if (cert->flags & X509_OCSP_SIGNER) { ocspSigning = asn1_build_known_oid(OID_OCSP_SIGNING); } - if (serverAuth.ptr || clientAuth.ptr || ocspSigning.ptr) + if (serverAuth.ptr || clientAuth.ptr || ikeIntermediate.ptr || + ocspSigning.ptr) { extendedKeyUsage = asn1_wrap(ASN1_SEQUENCE, "mm", asn1_build_known_oid(OID_EXTENDED_KEY_USAGE), asn1_wrap(ASN1_OCTET_STRING, "m", - asn1_wrap(ASN1_SEQUENCE, "mmm", - serverAuth, clientAuth, ocspSigning))); + asn1_wrap(ASN1_SEQUENCE, "mmmm", + serverAuth, clientAuth, ikeIntermediate, + ocspSigning))); } /* add subjectKeyIdentifier to CA and OCSP signer certificates */ @@ -2330,11 +2345,12 @@ static bool generate(private_x509_cert_t *cert, certificate_t *sign_cert, asn1_bitstring("c", cert->signature)); hasher = lib->crypto->create_hasher(lib->crypto, HASH_SHA1); - if (!hasher) + if (!hasher || + !hasher->allocate_hash(hasher, cert->encoding, &cert->encoding_hash)) { + DESTROY_IF(hasher); return FALSE; } - hasher->allocate_hash(hasher, cert->encoding, &cert->encoding_hash); hasher->destroy(hasher); return TRUE; } diff --git a/src/libstrongswan/plugins/x509/x509_crl.c b/src/libstrongswan/plugins/x509/x509_crl.c index 7bcca16a3..47621103e 100644 --- a/src/libstrongswan/plugins/x509/x509_crl.c +++ b/src/libstrongswan/plugins/x509/x509_crl.c @@ -221,7 +221,7 @@ static bool parse(private_x509_crl_t *this) { asn1_parser_t *parser; chunk_t object; - chunk_t extnID; + chunk_t extnID = chunk_empty; chunk_t userCertificate = chunk_empty; int objectID; int sig_alg = OID_UNKNOWN; @@ -442,7 +442,7 @@ METHOD(certificate_t, has_issuer, id_match_t, } METHOD(certificate_t, issued_by, bool, - private_x509_crl_t *this, certificate_t *issuer) + private_x509_crl_t *this, certificate_t *issuer, signature_scheme_t *schemep) { public_key_t *key; signature_scheme_t scheme; @@ -490,6 +490,10 @@ METHOD(certificate_t, issued_by, bool, } valid = key->verify(key, scheme, this->tbsCertList, this->signature); key->destroy(key); + if (valid && schemep) + { + *schemep = scheme; + } return valid; } diff --git a/src/libstrongswan/plugins/x509/x509_ocsp_request.c b/src/libstrongswan/plugins/x509/x509_ocsp_request.c index 33d0aa792..bbd1c5905 100644 --- a/src/libstrongswan/plugins/x509/x509_ocsp_request.c +++ b/src/libstrongswan/plugins/x509/x509_ocsp_request.c @@ -159,22 +159,24 @@ static chunk_t build_requestList(private_x509_ocsp_request_t *this) enumerator_t *enumerator; 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)) + if (hasher->allocate_hash(hasher, issuer->get_encoding(issuer), + &issuerNameHash)) { - chunk_t request, serialNumber; - - serialNumber = x509->get_serial(x509); - request = build_Request(this, issuerNameHash, issuerKeyHash, - serialNumber); - list = chunk_cat("mm", list, request); + 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); } - enumerator->destroy(enumerator); - chunk_free(&issuerNameHash); + hasher->destroy(hasher); } } else @@ -199,15 +201,15 @@ 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) + if (!rng || !rng->allocate_bytes(rng, NONCE_LEN, &this->nonce)) { - 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(DBG_LIB, "creating OCSP request nonce failed, no RNG found"); + DESTROY_IF(rng); + return chunk_empty; } - DBG1(DBG_LIB, "creating OCSP request nonce failed, no RNG found"); - return chunk_empty; + rng->destroy(rng); + return asn1_wrap(ASN1_SEQUENCE, "cm", ASN1_nonce_oid, + asn1_simple_object(ASN1_OCTET_STRING, this->nonce)); } /** @@ -364,7 +366,8 @@ METHOD(certificate_t, has_issuer, id_match_t, } METHOD(certificate_t, issued_by, bool, - private_x509_ocsp_request_t *this, certificate_t *issuer) + private_x509_ocsp_request_t *this, certificate_t *issuer, + signature_scheme_t *scheme) { DBG1(DBG_LIB, "OCSP request validation not implemented!"); return FALSE; diff --git a/src/libstrongswan/plugins/x509/x509_ocsp_response.c b/src/libstrongswan/plugins/x509/x509_ocsp_response.c index 7dfef3993..27497e0e3 100644 --- a/src/libstrongswan/plugins/x509/x509_ocsp_response.c +++ b/src/libstrongswan/plugins/x509/x509_ocsp_response.c @@ -201,19 +201,22 @@ METHOD(ocsp_response_t, get_status, cert_validation_t, /* check issuerNameHash, if available */ else if (response->issuerNameHash.ptr) { + id = issuercert->get_subject(issuercert); hasher = lib->crypto->create_hasher(lib->crypto, hasher_algorithm_from_oid(response->hashAlgorithm)); - if (!hasher) + if (!hasher || + !hasher->allocate_hash(hasher, id->get_encoding(id), &hash)) { + DESTROY_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)) { + free(hash.ptr); continue; } + free(hash.ptr); } else { @@ -670,7 +673,8 @@ METHOD(certificate_t, has_issuer, id_match_t, } METHOD(certificate_t, issued_by, bool, - private_x509_ocsp_response_t *this, certificate_t *issuer) + private_x509_ocsp_response_t *this, certificate_t *issuer, + signature_scheme_t *schemep) { public_key_t *key; signature_scheme_t scheme; @@ -722,6 +726,10 @@ METHOD(certificate_t, issued_by, bool, } valid = key->verify(key, scheme, this->tbsResponseData, this->signature); key->destroy(key); + if (valid && schemep) + { + *schemep = scheme; + } return valid; } diff --git a/src/libstrongswan/plugins/x509/x509_pkcs10.c b/src/libstrongswan/plugins/x509/x509_pkcs10.c index ca08db2c6..9fa91fed2 100644 --- a/src/libstrongswan/plugins/x509/x509_pkcs10.c +++ b/src/libstrongswan/plugins/x509/x509_pkcs10.c @@ -123,10 +123,12 @@ METHOD(certificate_t, has_subject, id_match_t, } METHOD(certificate_t, issued_by, bool, - private_x509_pkcs10_t *this, certificate_t *issuer) + private_x509_pkcs10_t *this, certificate_t *issuer, + signature_scheme_t *schemep) { public_key_t *key; signature_scheme_t scheme; + bool valid; if (&this->public.interface.interface != issuer) { @@ -150,8 +152,13 @@ METHOD(certificate_t, issued_by, bool, { return FALSE; } - return key->verify(key, scheme, this->certificationRequestInfo, - this->signature); + valid = key->verify(key, scheme, this->certificationRequestInfo, + this->signature); + if (valid && schemep) + { + *schemep = scheme; + } + return valid; } METHOD(certificate_t, get_public_key, public_key_t*, @@ -327,7 +334,7 @@ static bool parse_challengePassword(private_x509_pkcs10_t *this, chunk_t blob, i return FALSE; } DBG2(DBG_ASN, "L%d - challengePassword:", level); - DBG4(DBG_ASN, " '%.*s'", blob.len, blob.ptr); + DBG4(DBG_ASN, " '%.*s'", (int)blob.len, blob.ptr); return TRUE; } @@ -441,7 +448,7 @@ end: if (success) { /* check if the certificate request is self-signed */ - if (issued_by(this, &this->public.interface.interface)) + if (issued_by(this, &this->public.interface.interface, NULL)) { this->self_signed = TRUE; } diff --git a/src/libstrongswan/plugins/x509/x509_plugin.c b/src/libstrongswan/plugins/x509/x509_plugin.c index ed6fbfd91..15fea7ee0 100644 --- a/src/libstrongswan/plugins/x509/x509_plugin.c +++ b/src/libstrongswan/plugins/x509/x509_plugin.c @@ -52,6 +52,9 @@ METHOD(plugin_t, get_features, int, PLUGIN_REGISTER(CERT_DECODE, x509_cert_load, TRUE), PLUGIN_PROVIDE(CERT_DECODE, CERT_X509), PLUGIN_DEPENDS(HASHER, HASH_SHA1), + PLUGIN_SDEPEND(PUBKEY, KEY_RSA), + PLUGIN_SDEPEND(PUBKEY, KEY_ECDSA), + PLUGIN_SDEPEND(PUBKEY, KEY_DSA), PLUGIN_REGISTER(CERT_ENCODE, x509_ac_gen, FALSE), PLUGIN_PROVIDE(CERT_ENCODE, CERT_X509_AC), diff --git a/src/libstrongswan/plugins/xcbc/Makefile.am b/src/libstrongswan/plugins/xcbc/Makefile.am index 7de306832..28e99f650 100644 --- a/src/libstrongswan/plugins/xcbc/Makefile.am +++ b/src/libstrongswan/plugins/xcbc/Makefile.am @@ -10,7 +10,6 @@ plugin_LTLIBRARIES = libstrongswan-xcbc.la endif 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 + xcbc_plugin.h xcbc_plugin.c xcbc.h xcbc.c libstrongswan_xcbc_la_LDFLAGS = -module -avoid-version diff --git a/src/libstrongswan/plugins/xcbc/Makefile.in b/src/libstrongswan/plugins/xcbc/Makefile.in index ae23ce730..b4d0a2160 100644 --- a/src/libstrongswan/plugins/xcbc/Makefile.in +++ b/src/libstrongswan/plugins/xcbc/Makefile.in @@ -49,6 +49,7 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/config/libtool.m4 \ am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; @@ -75,15 +76,14 @@ am__base_list = \ am__installdirs = "$(DESTDIR)$(plugindir)" LTLIBRARIES = $(noinst_LTLIBRARIES) $(plugin_LTLIBRARIES) libstrongswan_xcbc_la_LIBADD = -am_libstrongswan_xcbc_la_OBJECTS = xcbc_plugin.lo xcbc.lo xcbc_prf.lo \ - xcbc_signer.lo +am_libstrongswan_xcbc_la_OBJECTS = xcbc_plugin.lo xcbc.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 $@ @MONOLITHIC_FALSE@am_libstrongswan_xcbc_la_rpath = -rpath $(plugindir) @MONOLITHIC_TRUE@am_libstrongswan_xcbc_la_rpath = -DEFAULT_INCLUDES = -I.@am__isrc@ +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles am__mv = mv -f @@ -109,6 +109,7 @@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ +BFDLIB = @BFDLIB@ BTLIB = @BTLIB@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ @@ -203,11 +204,14 @@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ c_plugins = @c_plugins@ +charon_natt_port = @charon_natt_port@ +charon_plugins = @charon_plugins@ +charon_udp_port = @charon_udp_port@ clearsilver_LIBS = @clearsilver_LIBS@ datadir = @datadir@ datarootdir = @datarootdir@ dbusservicedir = @dbusservicedir@ -default_pkcs11 = @default_pkcs11@ +dev_headers = @dev_headers@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ @@ -224,11 +228,12 @@ imcvdir = @imcvdir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ +ipsec_script = @ipsec_script@ +ipsec_script_upper = @ipsec_script_upper@ ipsecdir = @ipsecdir@ ipsecgroup = @ipsecgroup@ ipseclibdir = @ipseclibdir@ ipsecuser = @ipsecuser@ -libcharon_plugins = @libcharon_plugins@ libdir = @libdir@ libexecdir = @libexecdir@ linux_headers = @linux_headers@ @@ -244,6 +249,7 @@ mkdir_p = @mkdir_p@ nm_CFLAGS = @nm_CFLAGS@ nm_LIBS = @nm_LIBS@ nm_ca_dir = @nm_ca_dir@ +nm_plugins = @nm_plugins@ oldincludedir = @oldincludedir@ openac_plugins = @openac_plugins@ p_plugins = @p_plugins@ @@ -253,7 +259,6 @@ pdfdir = @pdfdir@ piddir = @piddir@ pki_plugins = @pki_plugins@ plugindir = @plugindir@ -pluto_plugins = @pluto_plugins@ pool_plugins = @pool_plugins@ prefix = @prefix@ program_transform_name = @program_transform_name@ @@ -286,8 +291,7 @@ AM_CFLAGS = -rdynamic @MONOLITHIC_TRUE@noinst_LTLIBRARIES = libstrongswan-xcbc.la @MONOLITHIC_FALSE@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 + xcbc_plugin.h xcbc_plugin.c xcbc.h xcbc.c libstrongswan_xcbc_la_LDFLAGS = -module -avoid-version all: all-am @@ -375,8 +379,6 @@ distclean-compile: @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 $@ $< diff --git a/src/libstrongswan/plugins/xcbc/xcbc.c b/src/libstrongswan/plugins/xcbc/xcbc.c index 53629abe5..1bb7e640a 100644 --- a/src/libstrongswan/plugins/xcbc/xcbc.c +++ b/src/libstrongswan/plugins/xcbc/xcbc.c @@ -1,4 +1,5 @@ /* + * Copyright (C) 2012 Tobias Brunner * Copyright (C) 2008 Martin Willi * Hochschule fuer Technik Rapperswil * @@ -18,20 +19,23 @@ #include "xcbc.h" #include <debug.h> +#include <crypto/mac.h> +#include <crypto/prfs/mac_prf.h> +#include <crypto/signers/mac_signer.h> -typedef struct private_xcbc_t private_xcbc_t; +typedef struct private_mac_t private_mac_t; /** - * Private data of a xcbc_t object. + * Private data of a mac_t object. * * The variable names are the same as in the RFC. */ -struct private_xcbc_t { +struct private_mac_t { /** - * Public xcbc_t interface. + * Public mac_t interface. */ - xcbc_t public; + mac_t public; /** * Block size, in bytes @@ -77,7 +81,7 @@ struct private_xcbc_t { /** * xcbc supplied data, but do not run final operation */ -static void update(private_xcbc_t *this, chunk_t data) +static bool update(private_mac_t *this, chunk_t data) { chunk_t iv; @@ -90,7 +94,7 @@ static void update(private_xcbc_t *this, chunk_t data) { /* no complete block, just copy into remaining */ memcpy(this->remaining + this->remaining_bytes, data.ptr, data.len); this->remaining_bytes += data.len; - return; + return TRUE; } iv = chunk_alloca(this->b); @@ -106,7 +110,10 @@ static void update(private_xcbc_t *this, chunk_t data) 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); + if (!this->k1->encrypt(this->k1, chunk_create(this->e, this->b), iv, NULL)) + { + return FALSE; + } /* process blocks M[2] ... M[n-1] */ while (data.len > this->b) @@ -114,18 +121,24 @@ static void update(private_xcbc_t *this, chunk_t data) 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); + if (!this->k1->encrypt(this->k1, chunk_create(this->e, this->b), + iv, NULL)) + { + return FALSE; + } } /* store remaining bytes of block M[n] */ memcpy(this->remaining, data.ptr, data.len); this->remaining_bytes = data.len; + + return TRUE; } /** * run last round, data is in this->e */ -static void final(private_xcbc_t *this, u_int8_t *out) +static bool final(private_mac_t *this, u_int8_t *out) { chunk_t iv; @@ -141,7 +154,6 @@ static void final(private_xcbc_t *this, u_int8_t *out) */ 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 { @@ -164,7 +176,10 @@ static void final(private_xcbc_t *this, u_int8_t *out) */ 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); + } + if (!this->k1->encrypt(this->k1, chunk_create(this->e, this->b), iv, NULL)) + { + return FALSE; } memcpy(out, this->e, this->b); @@ -173,28 +188,34 @@ static void final(private_xcbc_t *this, u_int8_t *out) memset(this->e, 0, this->b); this->remaining_bytes = 0; this->zero = TRUE; + + return TRUE; } -METHOD(xcbc_t, get_mac, void, - private_xcbc_t *this, chunk_t data, u_int8_t *out) +METHOD(mac_t, get_mac, bool, + private_mac_t *this, chunk_t data, u_int8_t *out) { /* update E, do not process last block */ - update(this, data); + if (!update(this, data)) + { + return FALSE; + } if (out) { /* if not in append mode, process last block and output result */ - final(this, out); + return final(this, out); } + return TRUE; } -METHOD(xcbc_t, get_block_size, size_t, - private_xcbc_t *this) +METHOD(mac_t, get_mac_size, size_t, + private_mac_t *this) { return this->b; } -METHOD(xcbc_t, set_key, void, - private_xcbc_t *this, chunk_t key) +METHOD(mac_t, set_key, bool, + private_mac_t *this, chunk_t key) { chunk_t iv, k1, lengthened; @@ -213,8 +234,11 @@ METHOD(xcbc_t, set_key, void, { /* 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); + if (!set_key(this, lengthened) || + !get_mac(this, key, lengthened.ptr)) + { + return FALSE; + } } k1 = chunk_alloca(this->b); @@ -228,20 +252,26 @@ METHOD(xcbc_t, set_key, void, * K2 = 0x02020202020202020202020202020202 encrypted with Key K * K3 = 0x03030303030303030303030303030303 encrypted with Key K */ - this->k1->set_key(this->k1, lengthened); + + memset(k1.ptr, 0x01, this->b); 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); + if (!this->k1->set_key(this->k1, lengthened) || + !this->k1->encrypt(this->k1, chunk_create(this->k2, this->b), iv, NULL) || + !this->k1->encrypt(this->k1, chunk_create(this->k3, this->b), iv, NULL) || + !this->k1->encrypt(this->k1, k1, iv, NULL) || + !this->k1->set_key(this->k1, k1)) + { + memwipe(k1.ptr, k1.len); + return FALSE; + } memwipe(k1.ptr, k1.len); + return TRUE; } -METHOD(xcbc_t, destroy, void, - private_xcbc_t *this) +METHOD(mac_t, destroy, void, + private_mac_t *this) { this->k1->destroy(this->k1); memwipe(this->k2, this->b); @@ -256,9 +286,9 @@ METHOD(xcbc_t, destroy, void, /* * Described in header */ -xcbc_t *xcbc_create(encryption_algorithm_t algo, size_t key_size) +static mac_t *xcbc_create(encryption_algorithm_t algo, size_t key_size) { - private_xcbc_t *this; + private_mac_t *this; crypter_t *crypter; u_int8_t b; @@ -278,7 +308,7 @@ xcbc_t *xcbc_create(encryption_algorithm_t algo, size_t key_size) INIT(this, .public = { .get_mac = _get_mac, - .get_block_size = _get_block_size, + .get_mac_size = _get_mac_size, .set_key = _set_key, .destroy = _destroy, }, @@ -295,3 +325,55 @@ xcbc_t *xcbc_create(encryption_algorithm_t algo, size_t key_size) return &this->public; } +/* + * Described in header. + */ +prf_t *xcbc_prf_create(pseudo_random_function_t algo) +{ + mac_t *xcbc; + + switch (algo) + { + case PRF_AES128_XCBC: + xcbc = xcbc_create(ENCR_AES_CBC, 16); + break; + case PRF_CAMELLIA128_XCBC: + xcbc = xcbc_create(ENCR_CAMELLIA_CBC, 16); + break; + default: + return NULL; + } + if (xcbc) + { + return mac_prf_create(xcbc); + } + return NULL; +} + +/* + * Described in header + */ +signer_t *xcbc_signer_create(integrity_algorithm_t algo) +{ + size_t trunc; + mac_t *xcbc; + + switch (algo) + { + case AUTH_AES_XCBC_96: + xcbc = xcbc_create(ENCR_AES_CBC, 16); + trunc = 12; + break; + case AUTH_CAMELLIA_XCBC_96: + xcbc = xcbc_create(ENCR_CAMELLIA_CBC, 16); + trunc = 12; + break; + default: + return NULL; + } + if (xcbc) + { + return mac_signer_create(xcbc, trunc); + } + return NULL; +} diff --git a/src/libstrongswan/plugins/xcbc/xcbc.h b/src/libstrongswan/plugins/xcbc/xcbc.h index 5d5eb04fb..a36069a17 100644 --- a/src/libstrongswan/plugins/xcbc/xcbc.h +++ b/src/libstrongswan/plugins/xcbc/xcbc.h @@ -14,6 +14,11 @@ */ /** + * Message authentication using CBC crypter. + * + * This class implements the message authentication algorithm + * described in RFC3566. + * * @defgroup xcbc xcbc * @{ @ingroup xcbc_p */ @@ -21,58 +26,23 @@ #ifndef XCBC_H_ #define XCBC_H_ -typedef struct xcbc_t xcbc_t; - -#include <crypto/hashers/hasher.h> +#include <crypto/prfs/prf.h> +#include <crypto/signers/signer.h> /** - * Message authentication using CBC crypter. + * Creates a new prf_t object based on a XCBC MAC. * - * This class implements the message authentication algorithm - * described in RFC3566. + * @param algo algorithm to implement + * @return prf_t object, NULL if not supported */ -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); -}; +prf_t *xcbc_prf_create(pseudo_random_function_t algo); /** - * Creates a new xcbc_t object. + * Creates a new signer_t object based on a XCBC MAC. * - * @param algo underlying crypto algorithm - * @param key_size key size to use, if required for algorithm - * @return xcbc_t object, NULL if not supported + * @param algo algorithm to implement + * @return signer_t, NULL if not supported */ -xcbc_t *xcbc_create(encryption_algorithm_t algo, size_t key_size); +signer_t *xcbc_signer_create(integrity_algorithm_t algo); #endif /** XCBC_H_ @}*/ diff --git a/src/libstrongswan/plugins/xcbc/xcbc_plugin.c b/src/libstrongswan/plugins/xcbc/xcbc_plugin.c index 3c3b9d12a..4706a9574 100644 --- a/src/libstrongswan/plugins/xcbc/xcbc_plugin.c +++ b/src/libstrongswan/plugins/xcbc/xcbc_plugin.c @@ -16,8 +16,7 @@ #include "xcbc_plugin.h" #include <library.h> -#include "xcbc_signer.h" -#include "xcbc_prf.h" +#include "xcbc.h" typedef struct private_xcbc_plugin_t private_xcbc_plugin_t; diff --git a/src/libstrongswan/plugins/xcbc/xcbc_prf.c b/src/libstrongswan/plugins/xcbc/xcbc_prf.c deleted file mode 100644 index ac9e1fda0..000000000 --- a/src/libstrongswan/plugins/xcbc/xcbc_prf.c +++ /dev/null @@ -1,124 +0,0 @@ -/* - * 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 "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; -}; - -METHOD(prf_t, get_bytes, void, - private_xcbc_prf_t *this, chunk_t seed, u_int8_t *buffer) -{ - this->xcbc->get_mac(this->xcbc, seed, buffer); -} - -METHOD(prf_t, allocate_bytes, void, - 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); - } -} - -METHOD(prf_t, get_block_size, size_t, - private_xcbc_prf_t *this) -{ - return this->xcbc->get_block_size(this->xcbc); -} - -METHOD(prf_t, get_key_size, size_t, - private_xcbc_prf_t *this) -{ - /* in xcbc, block and key size are always equal */ - return this->xcbc->get_block_size(this->xcbc); -} - -METHOD(prf_t, set_key, void, - private_xcbc_prf_t *this, chunk_t key) -{ - this->xcbc->set_key(this->xcbc, key); -} - -METHOD(prf_t, destroy, void, - 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; - case PRF_CAMELLIA128_XCBC: - xcbc = xcbc_create(ENCR_CAMELLIA_CBC, 16); - break; - default: - return NULL; - } - if (!xcbc) - { - return NULL; - } - - INIT(this, - .public = { - .prf = { - .get_bytes = _get_bytes, - .allocate_bytes = _allocate_bytes, - .get_block_size = _get_block_size, - .get_key_size = _get_key_size, - .set_key = _set_key, - .destroy = _destroy, - }, - }, - .xcbc = xcbc, - ); - - return &this->public; -} - diff --git a/src/libstrongswan/plugins/xcbc/xcbc_signer.c b/src/libstrongswan/plugins/xcbc/xcbc_signer.c deleted file mode 100644 index ece592323..000000000 --- a/src/libstrongswan/plugins/xcbc/xcbc_signer.c +++ /dev/null @@ -1,164 +0,0 @@ -/* - * 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 <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; -}; - -METHOD(signer_t, get_signature, void, - 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); - } -} - -METHOD(signer_t, allocate_signature, void, - 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); - } -} - -METHOD(signer_t, verify_signature, bool, - 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); -} - -METHOD(signer_t, get_key_size, size_t, - private_xcbc_signer_t *this) -{ - return this->xcbc->get_block_size(this->xcbc); -} - -METHOD(signer_t, get_block_size, size_t, - private_xcbc_signer_t *this) -{ - return this->block_size; -} - -METHOD(signer_t, set_key, void, - private_xcbc_signer_t *this, chunk_t key) -{ - this->xcbc->set_key(this->xcbc, key); -} - -METHOD(signer_t, destroy, void, - private_xcbc_signer_t *this) -{ - this->xcbc->destroy(this->xcbc); - free(this); -} - -/* - * 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; - case AUTH_CAMELLIA_XCBC_96: - xcbc = xcbc_create(ENCR_CAMELLIA_CBC, 16); - trunc = 12; - break; - default: - return NULL; - } - if (xcbc == NULL) - { - return NULL; - } - - INIT(this, - .public = { - .signer = { - .get_signature = _get_signature, - .allocate_signature = _allocate_signature, - .verify_signature = _verify_signature, - .get_key_size = _get_key_size, - .get_block_size = _get_block_size, - .set_key = _set_key, - .destroy = _destroy, - }, - }, - .xcbc = xcbc, - .block_size = min(trunc, xcbc->get_block_size(xcbc)), - ); - - return &this->public; -} - diff --git a/src/libstrongswan/printf_hook.c b/src/libstrongswan/printf_hook.c index c3b5191fd..6e51aa4c3 100644 --- a/src/libstrongswan/printf_hook.c +++ b/src/libstrongswan/printf_hook.c @@ -86,21 +86,18 @@ static printf_hook_handler_t *printf_hooks[NUM_HANDLERS]; static int custom_print(FILE *stream, const struct printf_info *info, const void *const *args) { - int written; - char buf[PRINTF_BUF_LEN]; printf_hook_spec_t spec; printf_hook_handler_t *handler = printf_hooks[SPEC_TO_INDEX(info->spec)]; + printf_hook_data_t data = { + .stream = stream, + }; spec.hash = info->alt; + spec.plus = info->showsign; spec.minus = info->left; spec.width = info->width; - written = handler->hook(buf, sizeof(buf), &spec, args); - if (written > 0) - { - ignore_result(fwrite(buf, 1, written, stream)); - } - return written; + return handler->hook(&data, &spec, args); } /** @@ -145,11 +142,14 @@ static int custom_arginfo(const struct printf_info *info, size_t n, int *argtype */ static int custom_fmt_cb(Vstr_base *base, size_t pos, Vstr_fmt_spec *fmt_spec) { - int i, written; - char buf[PRINTF_BUF_LEN]; + int i; const void *args[ARGS_MAX]; printf_hook_spec_t spec; printf_hook_handler_t *handler = printf_hooks[SPEC_TO_INDEX(fmt_spec->name[0])]; + printf_hook_data_t data = { + .base = base, + .pos = pos, + }; for (i = 0; i < handler->numargs; i++) { @@ -165,14 +165,11 @@ static int custom_fmt_cb(Vstr_base *base, size_t pos, Vstr_fmt_spec *fmt_spec) } spec.hash = fmt_spec->fmt_hash; + spec.plus = fmt_spec->fmt_plus; spec.minus = fmt_spec->fmt_minus; spec.width = fmt_spec->fmt_field_width; - written = handler->hook(buf, sizeof(buf), &spec, args); - if (written > 0) - { - vstr_add_buf(base, pos, buf, written); - } + handler->hook(&data, &spec, args); return 1; } @@ -241,6 +238,21 @@ static inline Vstr_conf *get_vstr_conf() } /** + * Described in header + */ +size_t vstr_print_in_hook(struct Vstr_base *base, size_t pos, const char *fmt, + ...) +{ + va_list args; + int written; + + va_start(args, fmt); + written = vstr_add_vfmt(base, pos, fmt, args); + va_end(args); + return written; +} + +/** * Wrapper functions for printf and alike */ int vstr_wrapper_printf(const char *format, ...) diff --git a/src/libstrongswan/printf_hook.h b/src/libstrongswan/printf_hook.h index 11fd66ce9..7d3f23bce 100644 --- a/src/libstrongswan/printf_hook.h +++ b/src/libstrongswan/printf_hook.h @@ -24,9 +24,17 @@ typedef struct printf_hook_t printf_hook_t; typedef struct printf_hook_spec_t printf_hook_spec_t; +typedef struct printf_hook_data_t printf_hook_data_t; typedef enum printf_hook_argtype_t printf_hook_argtype_t; #if !defined(USE_VSTR) && \ + !defined(HAVE_PRINTF_FUNCTION) && \ + !defined(HAVE_PRINTF_SPECIFIER) +/* assume newer glibc register_printf_specifier if none given */ +#define HAVE_PRINTF_SPECIFIER +#endif + +#if !defined(USE_VSTR) && \ (defined(HAVE_PRINTF_FUNCTION) || defined(HAVE_PRINTF_SPECIFIER)) #include <stdio.h> @@ -38,6 +46,29 @@ enum printf_hook_argtype_t { PRINTF_HOOK_ARGTYPE_POINTER = PA_POINTER, }; +/** + * Data to pass to a printf hook. + */ +struct printf_hook_data_t { + + /** + * Output FILE stream + */ + FILE *stream;; +}; + +/** + * Helper macro to be used in printf hook callbacks. + */ +#define print_in_hook(data, fmt, ...) ({\ + ssize_t _written = fprintf(data->stream, fmt, ##__VA_ARGS__);\ + if (_written < 0)\ + {\ + _written = 0;\ + }\ + _written;\ +}) + #else #include <vstr.h> @@ -66,6 +97,37 @@ int vstr_wrapper_vsprintf(char *str, const char *format, va_list ap); int vstr_wrapper_vsnprintf(char *str, size_t size, const char *format, va_list ap); int vstr_wrapper_vasprintf(char **str, const char *format, va_list ap); +#ifdef printf +#undef printf +#endif +#ifdef fprintf +#undef fprintf +#endif +#ifdef sprintf +#undef sprintf +#endif +#ifdef snprintf +#undef snprintf +#endif +#ifdef asprintf +#undef asprintf +#endif +#ifdef vprintf +#undef vprintf +#endif +#ifdef vfprintf +#undef vfprintf +#endif +#ifdef vsprintf +#undef vsprintf +#endif +#ifdef vsnprintf +#undef vsnprintf +#endif +#ifdef vasprintf +#undef vasprintf +#endif + #define printf vstr_wrapper_printf #define fprintf vstr_wrapper_fprintf #define sprintf vstr_wrapper_sprintf @@ -78,36 +140,59 @@ int vstr_wrapper_vasprintf(char **str, const char *format, va_list ap); #define vsnprintf vstr_wrapper_vsnprintf #define vasprintf vstr_wrapper_vasprintf -#endif +/** + * Data to pass to a printf hook. + */ +struct printf_hook_data_t { + + /** + * Base to append printf to + */ + Vstr_base *base; + + /** + * Position in base to write to + */ + size_t pos; +}; /** - * Callback function type for printf hooks. + * Wrapper around vstr_add_vfmt(), avoids having to link all users of + * print_in_hook() against libvstr. * - * @param dst destination buffer - * @param len length of the buffer - * @param spec format specifier - * @param args arguments array + * @param base Vstr_string to add string to + * @param pos position to write to + * @param fmt format string + * @param ... arguments * @return number of characters written */ -typedef int (*printf_hook_function_t)(char *dst, size_t len, - printf_hook_spec_t *spec, - const void *const *args); +size_t vstr_print_in_hook(struct Vstr_base *base, size_t pos, const char *fmt, + ...); /** * Helper macro to be used in printf hook callbacks. - * buf and buflen get modified. */ -#define print_in_hook(buf, buflen, fmt, ...) ({\ - int _written = snprintf(buf, buflen, fmt, ##__VA_ARGS__);\ - if (_written < 0 || _written >= buflen)\ - {\ - _written = buflen - 1;\ - }\ - buf += _written;\ - buflen -= _written;\ +#define print_in_hook(data, fmt, ...) ({\ + size_t _written; \ + _written = vstr_print_in_hook(data->base, data->pos, fmt, ##__VA_ARGS__);\ + data->pos += _written;\ _written;\ }) +#endif + +/** + * Callback function type for printf hooks. + * + * @param data hook data, to pass to print_in_hook() + * @param spec format specifier + * @param args arguments array + * @return number of characters written + */ +typedef int (*printf_hook_function_t)(printf_hook_data_t *data, + printf_hook_spec_t *spec, + const void *const *args); + /** * Properties of the format specifier */ @@ -123,6 +208,11 @@ struct printf_hook_spec_t { int minus; /** + * TRUE if a '+' was used in the format specifier + */ + int plus; + + /** * The width as given in the format specifier. */ int width; diff --git a/src/libstrongswan/processing/jobs/callback_job.c b/src/libstrongswan/processing/jobs/callback_job.c index 13f22e69c..a5ddc8ff6 100644 --- a/src/libstrongswan/processing/jobs/callback_job.c +++ b/src/libstrongswan/processing/jobs/callback_job.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2009 Tobias Brunner + * Copyright (C) 2009-2012 Tobias Brunner * Copyright (C) 2007-2011 Martin Willi * Copyright (C) 2011 revosec AG * Hochschule fuer Technik Rapperswil @@ -17,10 +17,9 @@ #include "callback_job.h" -#include <semaphore.h> - #include <threading/thread.h> #include <threading/condvar.h> +#include <threading/semaphore.h> #include <threading/mutex.h> #include <utils/linked_list.h> @@ -52,42 +51,9 @@ struct private_callback_job_t { callback_job_cleanup_t cleanup; /** - * thread of the job, if running - */ - thread_t *thread; - - /** - * mutex to access jobs interna - */ - mutex_t *mutex; - - /** - * list of associated child jobs - */ - linked_list_t *children; - - /** - * parent of this job, or NULL + * cancel function */ - private_callback_job_t *parent; - - /** - * TRUE if the job got cancelled - */ - bool cancelled; - - /** - * condvar to synchronize the cancellation/destruction of the job - */ - condvar_t *destroyable; - - /** - * semaphore to synchronize the termination of the assigned thread. - * - * separately allocated during cancellation, so that we can wait on it - * without risking that it gets freed too early during destruction. - */ - sem_t *terminated; + callback_job_cancel_t cancel; /** * Priority of this job @@ -95,141 +61,26 @@ struct private_callback_job_t { job_priority_t prio; }; -/** - * unregister a child from its parent, if any. - * note: this->mutex has to be locked - */ -static void unregister(private_callback_job_t *this) -{ - if (this->parent) - { - this->parent->mutex->lock(this->parent->mutex); - if (this->parent->cancelled && !this->cancelled) - { - /* if the parent has been cancelled but we have not yet, we do not - * unregister until we got cancelled by the parent. */ - this->parent->mutex->unlock(this->parent->mutex); - this->destroyable->wait(this->destroyable, this->mutex); - this->parent->mutex->lock(this->parent->mutex); - } - this->parent->children->remove(this->parent->children, this, NULL); - this->parent->mutex->unlock(this->parent->mutex); - this->parent = NULL; - } -} - METHOD(job_t, destroy, void, private_callback_job_t *this) { - this->mutex->lock(this->mutex); - unregister(this); if (this->cleanup) { this->cleanup(this->data); } - if (this->terminated) - { - sem_post(this->terminated); - } - this->children->destroy(this->children); - this->destroyable->destroy(this->destroyable); - this->mutex->unlock(this->mutex); - this->mutex->destroy(this->mutex); free(this); } -METHOD(callback_job_t, cancel, void, +METHOD(job_t, execute, job_requeue_t, private_callback_job_t *this) { - callback_job_t *child; - sem_t *terminated = NULL; - - this->mutex->lock(this->mutex); - this->cancelled = TRUE; - /* terminate children */ - while (this->children->get_first(this->children, (void**)&child) == SUCCESS) - { - this->mutex->unlock(this->mutex); - child->cancel(child); - this->mutex->lock(this->mutex); - } - if (this->thread) - { - /* terminate the thread, if there is currently one executing the job. - * we wait for its termination using a semaphore */ - this->thread->cancel(this->thread); - terminated = this->terminated = malloc_thing(sem_t); - sem_init(terminated, 0, 0); - } - else - { - /* if the job is currently queued, it gets terminated later. - * we can't wait, because it might not get executed at all. - * we also unregister the queued job manually from its parent (the - * others get unregistered during destruction) */ - unregister(this); - } - this->destroyable->signal(this->destroyable); - this->mutex->unlock(this->mutex); - - if (terminated) - { - sem_wait(terminated); - sem_destroy(terminated); - free(terminated); - } + return this->callback(this->data); } -METHOD(job_t, execute, void, +METHOD(job_t, cancel, bool, private_callback_job_t *this) { - bool cleanup = FALSE, requeue = FALSE; - - thread_cleanup_push((thread_cleanup_t)destroy, this); - - this->mutex->lock(this->mutex); - this->thread = thread_current(); - this->mutex->unlock(this->mutex); - - while (TRUE) - { - this->mutex->lock(this->mutex); - if (this->cancelled) - { - this->mutex->unlock(this->mutex); - cleanup = TRUE; - break; - } - this->mutex->unlock(this->mutex); - switch (this->callback(this->data)) - { - case JOB_REQUEUE_DIRECT: - continue; - case JOB_REQUEUE_FAIR: - { - requeue = TRUE; - break; - } - case JOB_REQUEUE_NONE: - default: - { - cleanup = TRUE; - break; - } - } - break; - } - this->mutex->lock(this->mutex); - this->thread = NULL; - this->mutex->unlock(this->mutex); - /* manually create a cancellation point to avoid that a cancelled thread - * goes back into the thread pool */ - thread_cancellation_point(); - if (requeue) - { - lib->processor->queue_job(lib->processor, &this->public.job); - } - thread_cleanup_pop(cleanup); + return this->cancel(this->data); } METHOD(job_t, get_priority, job_priority_t, @@ -242,8 +93,8 @@ METHOD(job_t, get_priority, job_priority_t, * Described in header. */ callback_job_t *callback_job_create_with_prio(callback_job_cb_t cb, void *data, - callback_job_cleanup_t cleanup, callback_job_t *parent, - job_priority_t prio) + callback_job_cleanup_t cleanup, callback_job_cancel_t cancel, + job_priority_t prio) { private_callback_job_t *this; @@ -254,24 +105,17 @@ callback_job_t *callback_job_create_with_prio(callback_job_cb_t cb, void *data, .get_priority = _get_priority, .destroy = _destroy, }, - .cancel = _cancel, }, - .mutex = mutex_create(MUTEX_TYPE_DEFAULT), .callback = cb, .data = data, .cleanup = cleanup, - .children = linked_list_create(), - .parent = (private_callback_job_t*)parent, - .destroyable = condvar_create(CONDVAR_TYPE_DEFAULT), + .cancel = cancel, .prio = prio, ); - /* register us at parent */ - if (parent) + if (cancel) { - this->parent->mutex->lock(this->parent->mutex); - this->parent->children->insert_last(this->parent->children, this); - this->parent->mutex->unlock(this->parent->mutex); + this->public.job.cancel = _cancel; } return &this->public; @@ -282,8 +126,8 @@ callback_job_t *callback_job_create_with_prio(callback_job_cb_t cb, void *data, */ callback_job_t *callback_job_create(callback_job_cb_t cb, void *data, callback_job_cleanup_t cleanup, - callback_job_t *parent) + callback_job_cancel_t cancel) { - return callback_job_create_with_prio(cb, data, cleanup, parent, + return callback_job_create_with_prio(cb, data, cleanup, cancel, JOB_PRIO_MEDIUM); } diff --git a/src/libstrongswan/processing/jobs/callback_job.h b/src/libstrongswan/processing/jobs/callback_job.h index 3e92b01c0..6f2e39eb8 100644 --- a/src/libstrongswan/processing/jobs/callback_job.h +++ b/src/libstrongswan/processing/jobs/callback_job.h @@ -1,4 +1,5 @@ /* + * Copyright (C) 2012 Tobias Brunner * Copyright (C) 2007-2011 Martin Willi * Copyright (C) 2011 revosec AG * Hochschule fuer Technik Rapperswil @@ -27,33 +28,6 @@ typedef struct callback_job_t callback_job_t; #include <library.h> #include <processing/jobs/job.h> - -typedef enum job_requeue_t job_requeue_t; - -/** - * Job requeueing policy. - * - * The job requeueing policy defines how a job is handled when the callback - * function returns. - */ -enum job_requeue_t { - - /** - * Do not requeue job, destroy it - */ - JOB_REQUEUE_NONE, - - /** - * Reque the job fairly, meaning it has to requeue as any other job - */ - JOB_REQUEUE_FAIR, - - /** - * Reexecute the job directly, without the need of requeueing it - */ - JOB_REQUEUE_DIRECT, -}; - /** * The callback function to use for the callback job. * @@ -73,11 +47,22 @@ typedef job_requeue_t (*callback_job_cb_t)(void *data); * to supply to the constructor. * * @param data param supplied to job - * @return requeing policy how to requeue the job */ typedef void (*callback_job_cleanup_t)(void *data); /** + * Cancellation function to use for the callback job. + * + * Optional function to be called when a job has to be canceled. + * + * See job_t.cancel() for details on the return value. + * + * @param data param supplied to job + * @return TRUE if canceled, FALSE to explicitly cancel the thread + */ +typedef bool (*callback_job_cancel_t)(void *data); + +/** * Class representing an callback Job. * * This is a special job which allows a simple callback function to @@ -91,14 +76,6 @@ struct callback_job_t { */ job_t job; - /** - * Cancel the job's thread and wait for its termination. - * - * This only works reliably for jobs that always use JOB_REQUEUE_FAIR or - * JOB_REQUEUE_DIRECT, otherwise the job may already be destroyed when - * cancel is called. - */ - void (*cancel)(callback_job_t *this); }; /** @@ -106,19 +83,20 @@ struct callback_job_t { * * The cleanup function is called when the job gets destroyed to destroy * the associated data. - * If parent is not NULL, the specified job gets an association. Whenever - * the parent gets cancelled (or runs out), all of its children are cancelled, - * too. + * + * The cancel function is optional and should only be provided if the callback + * function calls potentially blocking functions and/or always returns + * JOB_REQUEUE_DIRECT. * * @param cb callback to call from the processor * @param data user data to supply to callback * @param cleanup destructor for data on destruction, or NULL - * @param parent parent of this job + * @param cancel function to cancel the job, or NULL * @return callback_job_t object */ callback_job_t *callback_job_create(callback_job_cb_t cb, void *data, callback_job_cleanup_t cleanup, - callback_job_t *parent); + callback_job_cancel_t cancel); /** * Creates a callback job, with priority. @@ -128,12 +106,12 @@ callback_job_t *callback_job_create(callback_job_cb_t cb, void *data, * @param cb callback to call from the processor * @param data user data to supply to callback * @param cleanup destructor for data on destruction, or NULL - * @param parent parent of this job + * @param cancel function to cancel the job, or NULL * @param prio job priority * @return callback_job_t object */ callback_job_t *callback_job_create_with_prio(callback_job_cb_t cb, void *data, - callback_job_cleanup_t cleanup, callback_job_t *parent, - job_priority_t prio); + callback_job_cleanup_t cleanup, callback_job_cancel_t cancel, + job_priority_t prio); #endif /** CALLBACK_JOB_H_ @}*/ diff --git a/src/libstrongswan/processing/jobs/job.h b/src/libstrongswan/processing/jobs/job.h index d25cee03e..64454718a 100644 --- a/src/libstrongswan/processing/jobs/job.h +++ b/src/libstrongswan/processing/jobs/job.h @@ -1,4 +1,5 @@ /* + * Copyright (C) 2012 Tobias Brunner * Copyright (C) 2005-2006 Martin Willi * Copyright (C) 2005 Jan Hutter * Hochschule fuer Technik Rapperswil @@ -24,6 +25,9 @@ typedef struct job_t job_t; typedef enum job_priority_t job_priority_t; +typedef enum job_status_t job_status_t; +typedef enum job_requeue_type_t job_requeue_type_t; +typedef struct job_requeue_t job_requeue_t; #include <library.h> @@ -48,18 +52,107 @@ enum job_priority_t { extern enum_name_t *job_priority_names; /** + * Job status + */ +enum job_status_t { + /** The job is queued and has not yet been executed */ + JOB_STATUS_QUEUED = 0, + /** During execution */ + JOB_STATUS_EXECUTING, + /** If the job got canceled */ + JOB_STATUS_CANCELED, + /** The job was executed successfully */ + JOB_STATUS_DONE, +}; + +/** + * How a job is handled after is has been executed. + */ +enum job_requeue_type_t { + /** Do not requeue job, destroy it */ + JOB_REQUEUE_TYPE_NONE = 0, + /** Requeue the job fairly, i.e. it is inserted at the end of the queue */ + JOB_REQUEUE_TYPE_FAIR, + /** Reexecute the job directly, without the need of requeueing it */ + JOB_REQUEUE_TYPE_DIRECT, + /** Rescheduled the job via scheduler_t */ + JOB_REQUEUE_TYPE_SCHEDULE, +}; + +/** + * Job requeueing policy. + * + * The job requeueing policy defines how a job is handled after it has been + * executed. + */ +struct job_requeue_t { + /** How to handle the job after executing it */ + job_requeue_type_t type; + /** How to reschedule the job, if so */ + enum { + JOB_SCHEDULE, + JOB_SCHEDULE_MS, + JOB_SCHEDULE_TV, + } schedule; + /** Time to reschedule the job */ + union { + u_int32_t rel; + timeval_t abs; + } time; +}; + +/** + * Helper macros to easily define requeueing policies. + */ +#define __JOB_REQUEUE(t) (job_requeue_t){ .type = t } +#define JOB_REQUEUE_NONE __JOB_REQUEUE(JOB_REQUEUE_TYPE_NONE) +#define JOB_REQUEUE_FAIR __JOB_REQUEUE(JOB_REQUEUE_TYPE_FAIR) +#define JOB_REQUEUE_DIRECT __JOB_REQUEUE(JOB_REQUEUE_TYPE_DIRECT) +#define __JOB_RESCHEDULE(t, ...) (job_requeue_t){ .type = JOB_REQUEUE_TYPE_SCHEDULE, .schedule = t, { __VA_ARGS__ } } +#define JOB_RESCHEDULE(s) __JOB_RESCHEDULE(JOB_SCHEDULE, .rel = s) +#define JOB_RESCHEDULE_MS(ms) __JOB_RESCHEDULE(JOB_SCHEDULE_MS, .rel = ms) +#define JOB_RESCHEDULE_TV(tv) __JOB_RESCHEDULE(JOB_SCHEDULE_TV, .abs = tv) + +/** * Job interface as it is stored in the job queue. */ struct job_t { /** + * Status of this job, is modified exclusively by the processor/scheduler + */ + job_status_t status; + + /** * Execute a job. * * The processing facility executes a job using this method. Jobs are - * one-shot, they destroy themself after execution, so don't use a job - * once it has been executed. + * one-shot, they are destroyed after execution (depending on the return + * value here), so don't use a job once it has been queued. + * + * @return policy how to requeue the job + */ + job_requeue_t (*execute) (job_t *this); + + /** + * Cancel a job. + * + * Implementing this method is optional. It allows potentially blocking + * jobs to be canceled during shutdown. + * + * If no special action is to be taken simply return FALSE then the thread + * executing the job will be canceled. If TRUE is returned the job is + * expected to return from execute() itself (i.e. the thread won't be + * canceled explicitly and can still be joined later). + * Jobs that return FALSE have to make sure they provide the appropriate + * cancellation points. + * + * @note Regular jobs that do not block MUST NOT implement this method. + * @note This method could be called even before execute() has been called. + * + * @return FALSE to cancel the thread, TRUE if canceled otherwise */ - void (*execute) (job_t *this); + bool (*cancel)(job_t *this); /** * Get the priority of a job. @@ -71,10 +164,12 @@ struct job_t { /** * Destroy a job. * - * Is only called whenever a job was not executed (e.g. due daemon shutdown). - * After execution, jobs destroy themself. + * Is called after a job is executed or got canceled. It is also called + * for queued jobs that were never executed. + * + * Use the status of a job to decide what to do during destruction. */ - void (*destroy) (job_t *this); + void (*destroy)(job_t *this); }; #endif /** JOB_H_ @}*/ diff --git a/src/libstrongswan/processing/processor.c b/src/libstrongswan/processing/processor.c index 222f1a535..5b7fd467c 100644 --- a/src/libstrongswan/processing/processor.c +++ b/src/libstrongswan/processing/processor.c @@ -1,7 +1,7 @@ /* * Copyright (C) 2005-2011 Martin Willi * Copyright (C) 2011 revosec AG - * Copyright (C) 2008-2011 Tobias Brunner + * Copyright (C) 2008-2012 Tobias Brunner * Copyright (C) 2005 Jan Hutter * Hochschule fuer Technik Rapperswil * @@ -58,7 +58,7 @@ struct private_processor_t { /** * All threads managed in the pool (including threads that have been - * cancelled, this allows to join them during destruction) + * canceled, this allows to join them later), as worker_thread_t */ linked_list_t *threads; @@ -73,11 +73,6 @@ struct private_processor_t { int prio_threads[JOB_PRIO_MAX]; /** - * Priority of the job executed by a thread - */ - thread_value_t *priority; - - /** * access to job lists is locked through this mutex */ mutex_t *mutex; @@ -93,39 +88,71 @@ struct private_processor_t { condvar_t *thread_terminated; }; -static void process_jobs(private_processor_t *this); +/** + * Worker thread + */ +typedef struct { + + /** + * Reference to the processor + */ + private_processor_t *processor; + + /** + * The actual thread + */ + thread_t *thread; + + /** + * Job currently being executed by this worker thread + */ + job_t *job; + + /** + * Priority of the current job + */ + job_priority_t priority; + +} worker_thread_t; + +static void process_jobs(worker_thread_t *worker); /** * restart a terminated thread */ -static void restart(private_processor_t *this) +static void restart(worker_thread_t *worker) { - thread_t *thread; + private_processor_t *this = worker->processor; DBG2(DBG_JOB, "terminated worker thread %.2u", thread_current_id()); - /* respawn thread if required */ this->mutex->lock(this->mutex); - if (this->desired_threads < this->total_threads || - (thread = thread_create((thread_main_t)process_jobs, this)) == NULL) - { - this->total_threads--; - this->thread_terminated->signal(this->thread_terminated); - } - else + /* cleanup worker thread */ + this->working_threads[worker->priority]--; + worker->job->status = JOB_STATUS_CANCELED; + worker->job->destroy(worker->job); + worker->job = NULL; + + /* respawn thread if required */ + if (this->desired_threads >= this->total_threads) { - this->threads->insert_last(this->threads, thread); + worker_thread_t *new_worker; + + INIT(new_worker, + .processor = this, + ); + new_worker->thread = thread_create((thread_main_t)process_jobs, + new_worker); + if (new_worker->thread) + { + this->threads->insert_last(this->threads, new_worker); + this->mutex->unlock(this->mutex); + return; + } + free(new_worker); } - this->mutex->unlock(this->mutex); -} - -/** - * Decrement working thread count of a priority class - */ -static void decrement_working_threads(private_processor_t *this) -{ - this->mutex->lock(this->mutex); - this->working_threads[(intptr_t)this->priority->get(this->priority)]--; + this->total_threads--; + this->thread_terminated->signal(this->thread_terminated); this->mutex->unlock(this->mutex); } @@ -147,9 +174,11 @@ static u_int get_idle_threads_nolock(private_processor_t *this) /** * Process queued jobs, called by the worker threads */ -static void process_jobs(private_processor_t *this) +static void process_jobs(worker_thread_t *worker) { - /* worker threads are not cancellable by default */ + private_processor_t *this = worker->processor; + + /* worker threads are not cancelable by default */ thread_cancelability(FALSE); DBG2(DBG_JOB, "started worker thread %.2u", thread_current_id()); @@ -157,7 +186,6 @@ static void process_jobs(private_processor_t *this) this->mutex->lock(this->mutex); while (this->desired_threads >= this->total_threads) { - job_t *job = NULL; int i, reserved = 0, idle; idle = get_idle_threads_nolock(this); @@ -176,27 +204,80 @@ static void process_jobs(private_processor_t *this) reserved += this->prio_threads[i] - this->working_threads[i]; } if (this->jobs[i]->remove_first(this->jobs[i], - (void**)&job) == SUCCESS) + (void**)&worker->job) == SUCCESS) { + job_requeue_t requeue; + this->working_threads[i]++; + worker->job->status = JOB_STATUS_EXECUTING; + worker->priority = i; this->mutex->unlock(this->mutex); - this->priority->set(this->priority, (void*)(intptr_t)i); - /* terminated threads are restarted to get a constant pool */ - thread_cleanup_push((thread_cleanup_t)restart, this); - thread_cleanup_push((thread_cleanup_t)decrement_working_threads, - this); - job->execute(job); - thread_cleanup_pop(FALSE); + /* canceled threads are restarted to get a constant pool */ + thread_cleanup_push((thread_cleanup_t)restart, worker); + while (TRUE) + { + requeue = worker->job->execute(worker->job); + if (requeue.type != JOB_REQUEUE_TYPE_DIRECT) + { + break; + } + else if (!worker->job->cancel) + { /* only allow cancelable jobs to requeue directly */ + requeue.type = JOB_REQUEUE_TYPE_FAIR; + break; + } + } thread_cleanup_pop(FALSE); this->mutex->lock(this->mutex); this->working_threads[i]--; + if (worker->job->status == JOB_STATUS_CANCELED) + { /* job was canceled via a custom cancel() method or did not + * use JOB_REQUEUE_TYPE_DIRECT */ + worker->job->destroy(worker->job); + break; + } + switch (requeue.type) + { + case JOB_REQUEUE_TYPE_NONE: + worker->job->status = JOB_STATUS_DONE; + worker->job->destroy(worker->job); + break; + case JOB_REQUEUE_TYPE_FAIR: + worker->job->status = JOB_STATUS_QUEUED; + this->jobs[i]->insert_last(this->jobs[i], + worker->job); + this->job_added->signal(this->job_added); + break; + case JOB_REQUEUE_TYPE_SCHEDULE: + /* scheduler_t does not hold its lock when queeuing jobs + * so this should be safe without unlocking our mutex */ + switch (requeue.schedule) + { + case JOB_SCHEDULE: + lib->scheduler->schedule_job(lib->scheduler, + worker->job, requeue.time.rel); + break; + case JOB_SCHEDULE_MS: + lib->scheduler->schedule_job_ms(lib->scheduler, + worker->job, requeue.time.rel); + break; + case JOB_SCHEDULE_TV: + lib->scheduler->schedule_job_tv(lib->scheduler, + worker->job, requeue.time.abs); + break; + } + break; + default: + break; + } break; } } - if (!job) + if (!worker->job) { this->job_added->wait(this->job_added, this->mutex); } + worker->job = NULL; } this->total_threads--; this->thread_terminated->signal(this->thread_terminated); @@ -266,6 +347,8 @@ METHOD(processor_t, queue_job, void, job_priority_t prio; prio = sane_prio(job->get_priority(job)); + job->status = JOB_STATUS_QUEUED; + this->mutex->lock(this->mutex); this->jobs[prio]->insert_last(this->jobs[prio], job); this->job_added->signal(this->job_added); @@ -278,19 +361,26 @@ METHOD(processor_t, set_threads, void, this->mutex->lock(this->mutex); if (count > this->total_threads) { /* increase thread count */ + worker_thread_t *worker; int i; - thread_t *current; this->desired_threads = count; DBG1(DBG_JOB, "spawning %d worker threads", count - this->total_threads); for (i = this->total_threads; i < count; i++) { - current = thread_create((thread_main_t)process_jobs, this); - if (current) + INIT(worker, + .processor = this, + ); + worker->thread = thread_create((thread_main_t)process_jobs, worker); + if (worker->thread) { - this->threads->insert_last(this->threads, current); + this->threads->insert_last(this->threads, worker); this->total_threads++; } + else + { + free(worker); + } } } else if (count < this->total_threads) @@ -301,26 +391,49 @@ METHOD(processor_t, set_threads, void, this->mutex->unlock(this->mutex); } -METHOD(processor_t, destroy, void, +METHOD(processor_t, cancel, void, private_processor_t *this) { - thread_t *current; - int i; + enumerator_t *enumerator; + worker_thread_t *worker; - set_threads(this, 0); this->mutex->lock(this->mutex); + this->desired_threads = 0; + /* cancel potentially blocking jobs */ + enumerator = this->threads->create_enumerator(this->threads); + while (enumerator->enumerate(enumerator, (void**)&worker)) + { + if (worker->job && worker->job->cancel) + { + worker->job->status = JOB_STATUS_CANCELED; + if (!worker->job->cancel(worker->job)) + { /* job requests to be canceled explicitly, otherwise we assume + * the thread terminates itself and can be joined */ + worker->thread->cancel(worker->thread); + } + } + } + enumerator->destroy(enumerator); while (this->total_threads > 0) { this->job_added->broadcast(this->job_added); this->thread_terminated->wait(this->thread_terminated, this->mutex); } while (this->threads->remove_first(this->threads, - (void**)¤t) == SUCCESS) + (void**)&worker) == SUCCESS) { - current->join(current); + worker->thread->join(worker->thread); + free(worker); } this->mutex->unlock(this->mutex); - this->priority->destroy(this->priority); +} + +METHOD(processor_t, destroy, void, + private_processor_t *this) +{ + int i; + + cancel(this); this->thread_terminated->destroy(this->thread_terminated); this->job_added->destroy(this->job_added); this->mutex->destroy(this->mutex); @@ -348,10 +461,10 @@ processor_t *processor_create() .get_job_load = _get_job_load, .queue_job = _queue_job, .set_threads = _set_threads, + .cancel = _cancel, .destroy = _destroy, }, .threads = linked_list_create(), - .priority = thread_value_create(NULL), .mutex = mutex_create(MUTEX_TYPE_DEFAULT), .job_added = condvar_create(CONDVAR_TYPE_DEFAULT), .thread_terminated = condvar_create(CONDVAR_TYPE_DEFAULT), diff --git a/src/libstrongswan/processing/processor.h b/src/libstrongswan/processing/processor.h index 5db42c04c..94860f5d3 100644 --- a/src/libstrongswan/processing/processor.h +++ b/src/libstrongswan/processing/processor.h @@ -1,4 +1,5 @@ /* + * Copyright (C) 2012 Tobias Brunner * Copyright (C) 2005-2007 Martin Willi * Copyright (C) 2005 Jan Hutter * Hochschule fuer Technik Rapperswil @@ -51,7 +52,7 @@ struct processor_t { /** * Get the number of threads currently working, per priority class. * - * @param prioritiy to check + * @param priority to check * @return number of threads in priority working */ u_int (*get_working_threads)(processor_t *this, job_priority_t prio); @@ -78,14 +79,21 @@ struct processor_t { * * If the number of threads is smaller than number of currently running * threads, thread count is decreased. Use 0 to disable the processor. - * This call blocks if it decreases thread count until threads have - * terminated, so make sure there are not too many blocking jobs. + * + * This call does not block and wait for threads to terminate if the number + * of threads is reduced. Instead use cancel() for that during shutdown. * * @param count number of threads to allocate */ void (*set_threads)(processor_t *this, u_int count); /** + * Sets the number of threads to 0 and cancels all blocking jobs, then waits + * for all threads to be terminated. + */ + void (*cancel)(processor_t *this); + + /** * Destroy a processor object. */ void (*destroy) (processor_t *processor); diff --git a/src/libstrongswan/processing/scheduler.c b/src/libstrongswan/processing/scheduler.c index f3cc1164a..c97dbc4be 100644 --- a/src/libstrongswan/processing/scheduler.c +++ b/src/libstrongswan/processing/scheduler.c @@ -68,11 +68,6 @@ struct private_scheduler_t { scheduler_t public; /** - * Job which queues scheduled jobs to the processor. - */ - callback_job_t *job; - - /** * The heap in which the events are stored. */ event_t **heap; @@ -250,6 +245,7 @@ METHOD(scheduler_t, schedule_job_tv, void, event = malloc_thing(event_t); event->job = job; + event->job->status = JOB_STATUS_QUEUED; event->time = tv; this->mutex->lock(this->mutex); @@ -308,7 +304,6 @@ METHOD(scheduler_t, destroy, void, private_scheduler_t *this) { event_t *event; - this->job->cancel(this->job); this->condvar->destroy(this->condvar); this->mutex->destroy(this->mutex); while ((event = remove_event(this)) != NULL) @@ -325,6 +320,7 @@ METHOD(scheduler_t, destroy, void, scheduler_t * scheduler_create() { private_scheduler_t *this; + callback_job_t *job; INIT(this, .public = { @@ -341,9 +337,9 @@ scheduler_t * scheduler_create() this->heap = (event_t**)calloc(this->heap_size + 1, sizeof(event_t*)); - this->job = callback_job_create_with_prio((callback_job_cb_t)schedule, - this, NULL, NULL, JOB_PRIO_CRITICAL); - lib->processor->queue_job(lib->processor, (job_t*)this->job); + job = callback_job_create_with_prio((callback_job_cb_t)schedule, this, + NULL, return_false, JOB_PRIO_CRITICAL); + lib->processor->queue_job(lib->processor, (job_t*)job); return &this->public; } diff --git a/src/libstrongswan/selectors/traffic_selector.c b/src/libstrongswan/selectors/traffic_selector.c index b1bcf1b2d..b19b962e6 100644 --- a/src/libstrongswan/selectors/traffic_selector.c +++ b/src/libstrongswan/selectors/traffic_selector.c @@ -179,8 +179,8 @@ static private_traffic_selector_t *traffic_selector_create(u_int8_t protocol, ts /** * Described in header. */ -int traffic_selector_printf_hook(char *dst, size_t len, printf_hook_spec_t *spec, - const void *const *args) +int traffic_selector_printf_hook(printf_hook_data_t *data, + printf_hook_spec_t *spec, const void *const *args) { private_traffic_selector_t *this = *((private_traffic_selector_t**)(args[0])); linked_list_t *list = *((linked_list_t**)(args[0])); @@ -195,7 +195,7 @@ int traffic_selector_printf_hook(char *dst, size_t len, printf_hook_spec_t *spec if (this == NULL) { - return print_in_hook(dst, len, "(null)"); + return print_in_hook(data, "(null)"); } if (spec->hash) @@ -204,7 +204,7 @@ int traffic_selector_printf_hook(char *dst, size_t len, printf_hook_spec_t *spec while (enumerator->enumerate(enumerator, (void**)&this)) { /* call recursivly */ - written += print_in_hook(dst, len, "%R ", this); + written += print_in_hook(data, "%R ", this); } enumerator->destroy(enumerator); return written; @@ -216,7 +216,7 @@ int traffic_selector_printf_hook(char *dst, size_t len, printf_hook_spec_t *spec memeq(this->from, from, this->type == TS_IPV4_ADDR_RANGE ? 4 : 16) && memeq(this->to, to, this->type == TS_IPV4_ADDR_RANGE ? 4 : 16)) { - written += print_in_hook(dst, len, "dynamic"); + written += print_in_hook(data, "dynamic"); } else { @@ -238,11 +238,11 @@ int traffic_selector_printf_hook(char *dst, size_t len, printf_hook_spec_t *spec { inet_ntop(AF_INET6, &this->to6, to_str, sizeof(to_str)); } - written += print_in_hook(dst, len, "%s..%s", from_str, to_str); + written += print_in_hook(data, "%s..%s", from_str, to_str); } else { - written += print_in_hook(dst, len, "%s/%d", from_str, this->netbits); + written += print_in_hook(data, "%s/%d", from_str, this->netbits); } } @@ -255,7 +255,7 @@ int traffic_selector_printf_hook(char *dst, size_t len, printf_hook_spec_t *spec return written; } - written += print_in_hook(dst, len, "["); + written += print_in_hook(data, "["); /* build protocol string */ if (has_proto) @@ -264,18 +264,18 @@ int traffic_selector_printf_hook(char *dst, size_t len, printf_hook_spec_t *spec if (proto) { - written += print_in_hook(dst, len, "%s", proto->p_name); + written += print_in_hook(data, "%s", proto->p_name); serv_proto = proto->p_name; } else { - written += print_in_hook(dst, len, "%d", this->protocol); + written += print_in_hook(data, "%d", this->protocol); } } if (has_proto && has_ports) { - written += print_in_hook(dst, len, "/"); + written += print_in_hook(data, "/"); } /* build port string */ @@ -287,20 +287,20 @@ int traffic_selector_printf_hook(char *dst, size_t len, printf_hook_spec_t *spec if (serv) { - written += print_in_hook(dst, len, "%s", serv->s_name); + written += print_in_hook(data, "%s", serv->s_name); } else { - written += print_in_hook(dst, len, "%d", this->from_port); + written += print_in_hook(data, "%d", this->from_port); } } else { - written += print_in_hook(dst, len, "%d-%d", this->from_port, this->to_port); + written += print_in_hook(data, "%d-%d", this->from_port, this->to_port); } } - written += print_in_hook(dst, len, "]"); + written += print_in_hook(data, "]"); return written; } @@ -310,6 +310,10 @@ int traffic_selector_printf_hook(char *dst, size_t len, printf_hook_spec_t *spec */ static traffic_selector_t *get_subset(private_traffic_selector_t *this, private_traffic_selector_t *other) { + if (this->dynamic || other->dynamic) + { /* no set_address() applied, TS has no subset */ + return NULL; + } if (this->type == other->type && (this->protocol == other->protocol || this->protocol == 0 || other->protocol == 0)) { @@ -367,7 +371,6 @@ static traffic_selector_t *get_subset(private_traffic_selector_t *this, private_ /* we have a match in protocol, port, and address: return it... */ new_ts = traffic_selector_create(protocol, this->type, from_port, to_port); - new_ts->dynamic = this->dynamic || other->dynamic; memcpy(new_ts->from, from, size); memcpy(new_ts->to, to, size); calc_netbits(new_ts); @@ -510,7 +513,7 @@ METHOD(traffic_selector_t, is_dynamic, bool, METHOD(traffic_selector_t, set_address, void, private_traffic_selector_t *this, host_t *host) { - if (this->dynamic) + if (is_host(this, NULL)) { this->type = host->get_family(host) == AF_INET ? TS_IPV4_ADDR_RANGE : TS_IPV6_ADDR_RANGE; @@ -528,6 +531,7 @@ METHOD(traffic_selector_t, set_address, void, memcpy(this->to, from.ptr, from.len); this->netbits = from.len * 8; } + this->dynamic = FALSE; } } @@ -571,7 +575,7 @@ METHOD(traffic_selector_t, includes, bool, return FALSE; } -METHOD(traffic_selector_t, to_subnet, void, +METHOD(traffic_selector_t, to_subnet, bool, private_traffic_selector_t *this, host_t **net, u_int8_t *mask) { /* there is no way to do this cleanly, as the address range may @@ -597,7 +601,7 @@ METHOD(traffic_selector_t, to_subnet, void, break; default: /* unreachable */ - return; + return FALSE; } net_chunk.ptr = malloc(net_chunk.len); @@ -616,6 +620,8 @@ METHOD(traffic_selector_t, to_subnet, void, *net = host_create_from_chunk(family, net_chunk, port); chunk_free(&net_chunk); + + return this->netbits != NON_SUBNET_ADDRESS_RANGE; } METHOD(traffic_selector_t, clone_, traffic_selector_t*, @@ -735,66 +741,36 @@ traffic_selector_t *traffic_selector_create_from_rfc3779_format(ts_type_t type, traffic_selector_t *traffic_selector_create_from_subnet(host_t *net, u_int8_t netbits, u_int8_t protocol, u_int16_t port) { - private_traffic_selector_t *this = traffic_selector_create(protocol, 0, 0, 65535); + private_traffic_selector_t *this; + chunk_t from; + + this = traffic_selector_create(protocol, 0, 0, 65535); switch (net->get_family(net)) { case AF_INET: - { - chunk_t from; - this->type = TS_IPV4_ADDR_RANGE; - from = net->get_address(net); - memcpy(this->from, from.ptr, from.len); - if (this->from4[0] == 0) - { - /* use /0 for 0.0.0.0 */ - this->to4[0] = ~0; - this->netbits = 0; - } - else - { - calc_range(this, netbits); - } break; - } case AF_INET6: - { - chunk_t from; - this->type = TS_IPV6_ADDR_RANGE; - from = net->get_address(net); - memcpy(this->from, from.ptr, from.len); - if (this->from6[0] == 0 && this->from6[1] == 0 && - this->from6[2] == 0 && this->from6[3] == 0) - { - /* use /0 for ::0 */ - this->to6[0] = ~0; - this->to6[1] = ~0; - this->to6[2] = ~0; - this->to6[3] = ~0; - this->netbits = 0; - } - else - { - calc_range(this, netbits); - } break; - } default: - { net->destroy(net); free(this); return NULL; - } } + from = net->get_address(net); + memcpy(this->from, from.ptr, from.len); + netbits = min(netbits, this->type == TS_IPV4_ADDR_RANGE ? 32 : 128); + calc_range(this, netbits); if (port) { this->from_port = port; this->to_port = port; } net->destroy(net); - return (&this->public); + + return &this->public; } /* diff --git a/src/libstrongswan/selectors/traffic_selector.h b/src/libstrongswan/selectors/traffic_selector.h index 257da3f24..7a81521e9 100644 --- a/src/libstrongswan/selectors/traffic_selector.h +++ b/src/libstrongswan/selectors/traffic_selector.h @@ -203,8 +203,9 @@ struct traffic_selector_t { * * @param net converted subnet (has to be freed) * @param mask converted net mask + * @return TRUE if traffic selector matches exactly to the subnet */ - void (*to_subnet) (traffic_selector_t *this, host_t **net, u_int8_t *mask); + bool (*to_subnet) (traffic_selector_t *this, host_t **net, u_int8_t *mask); /** * Destroys the ts object @@ -309,7 +310,7 @@ traffic_selector_t *traffic_selector_create_dynamic(u_int8_t protocol, * With the #-specifier, arguments are: * linked_list_t *list containing traffic_selector_t* */ -int traffic_selector_printf_hook(char *dst, size_t len, printf_hook_spec_t *spec, - const void *const *args); +int traffic_selector_printf_hook(printf_hook_data_t *data, + printf_hook_spec_t *spec, const void *const *args); #endif /** TRAFFIC_SELECTOR_H_ @}*/ diff --git a/src/libstrongswan/settings.c b/src/libstrongswan/settings.c index b26fbebb4..8977cd9ed 100644 --- a/src/libstrongswan/settings.c +++ b/src/libstrongswan/settings.c @@ -1117,14 +1117,21 @@ static bool load_files_internal(private_settings_t *this, section_t *parent, char *pattern, bool merge) { char *text; - linked_list_t *contents = linked_list_create(); - section_t *section = section_create(NULL); + linked_list_t *contents; + section_t *section; if (pattern == NULL) { +#ifdef STRONGSWAN_CONF pattern = STRONGSWAN_CONF; +#else + return FALSE; +#endif } + contents = linked_list_create(); + section = section_create(NULL); + if (!parse_files(contents, NULL, 0, pattern, section)) { contents->destroy_function(contents, (void*)free); diff --git a/src/libstrongswan/settings.h b/src/libstrongswan/settings.h index a864779f1..c8b50d008 100644 --- a/src/libstrongswan/settings.h +++ b/src/libstrongswan/settings.h @@ -189,7 +189,7 @@ struct settings_t { * @param key key including sections, printf style format * @param def value returned if key not found * @param ... argument list for key - * @return value of the key + * @return value of the key (in seconds) */ u_int32_t (*get_time)(settings_t *this, char *key, u_int32_t def, ...); diff --git a/src/libstrongswan/threading/mutex.c b/src/libstrongswan/threading/mutex.c index 3bdb3bf29..2ef918a28 100644 --- a/src/libstrongswan/threading/mutex.c +++ b/src/libstrongswan/threading/mutex.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2008-2009 Tobias Brunner + * Copyright (C) 2008-2012 Tobias Brunner * Copyright (C) 2008 Martin Willi * Hochschule fuer Technik Rapperswil * @@ -73,9 +73,9 @@ struct private_r_mutex_t { pthread_t thread; /** - * times we have locked the lock, stored per thread + * times the current thread locked the mutex */ - pthread_key_t times; + u_int times; }; /** @@ -127,35 +127,24 @@ METHOD(mutex_t, lock_r, void, { pthread_t self = pthread_self(); - if (this->thread == self) + if (pthread_equal(this->thread, self)) { - uintptr_t times; - - /* times++ */ - times = (uintptr_t)pthread_getspecific(this->times); - pthread_setspecific(this->times, (void*)times + 1); + this->times++; } else { lock(&this->generic); this->thread = self; - /* times = 1 */ - pthread_setspecific(this->times, (void*)1); + this->times = 1; } } METHOD(mutex_t, unlock_r, void, private_r_mutex_t *this) { - uintptr_t times; - - /* times-- */ - times = (uintptr_t)pthread_getspecific(this->times); - pthread_setspecific(this->times, (void*)--times); - - if (times == 0) + if (--this->times == 0) { - this->thread = 0; + memset(&this->thread, 0, sizeof(this->thread)); unlock(&this->generic); } } @@ -173,7 +162,6 @@ METHOD(mutex_t, mutex_destroy_r, void, { profiler_cleanup(&this->generic.profile); pthread_mutex_destroy(&this->generic.mutex); - pthread_key_delete(this->times); free(this); } @@ -200,7 +188,6 @@ mutex_t *mutex_create(mutex_type_t type) ); pthread_mutex_init(&this->generic.mutex, NULL); - pthread_key_create(&this->times, NULL); profiler_init(&this->generic.profile); return &this->generic.public; @@ -233,11 +220,15 @@ METHOD(condvar_t, wait_, void, if (mutex->recursive) { private_r_mutex_t* recursive = (private_r_mutex_t*)mutex; + u_int times; + /* keep track of the number of times this thread locked the mutex */ + times = recursive->times; /* mutex owner gets cleared during condvar wait */ - recursive->thread = 0; + memset(&recursive->thread, 0, sizeof(recursive->thread)); pthread_cond_wait(&this->condvar, &mutex->mutex); recursive->thread = pthread_self(); + recursive->times = times; } else { @@ -262,11 +253,14 @@ METHOD(condvar_t, timed_wait_abs, bool, if (mutex->recursive) { private_r_mutex_t* recursive = (private_r_mutex_t*)mutex; + u_int times; - recursive->thread = 0; + times = recursive->times; + memset(&recursive->thread, 0, sizeof(recursive->thread)); timed_out = pthread_cond_timedwait(&this->condvar, &mutex->mutex, &ts) == ETIMEDOUT; recursive->thread = pthread_self(); + recursive->times = times; } else { diff --git a/src/libstrongswan/threading/rwlock.c b/src/libstrongswan/threading/rwlock.c index 15dc0b334..7097a8e8c 100644 --- a/src/libstrongswan/threading/rwlock.c +++ b/src/libstrongswan/threading/rwlock.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2008-2009 Tobias Brunner + * Copyright (C) 2008-2012 Tobias Brunner * Copyright (C) 2008 Martin Willi * Hochschule fuer Technik Rapperswil * @@ -21,11 +21,14 @@ #include <debug.h> #include "rwlock.h" +#include "rwlock_condvar.h" +#include "thread.h" #include "condvar.h" #include "mutex.h" #include "lock_profiler.h" typedef struct private_rwlock_t private_rwlock_t; +typedef struct private_rwlock_condvar_t private_rwlock_condvar_t; /** * private data of rwlock @@ -72,9 +75,9 @@ struct private_rwlock_t { u_int reader_count; /** - * current writer thread, if any + * TRUE, if a writer is holding the lock currently */ - pthread_t writer; + bool writer; #endif /* HAVE_PTHREAD_RWLOCK_INIT */ @@ -84,6 +87,27 @@ struct private_rwlock_t { lock_profile_t profile; }; +/** + * private data of condvar + */ +struct private_rwlock_condvar_t { + + /** + * public interface + */ + rwlock_condvar_t public; + + /** + * mutex used to implement rwlock condvar + */ + mutex_t *mutex; + + /** + * regular condvar to implement rwlock condvar + */ + condvar_t *condvar; +}; + #ifdef HAVE_PTHREAD_RWLOCK_INIT @@ -175,37 +199,81 @@ rwlock_t *rwlock_create(rwlock_type_t type) /** * This implementation of the rwlock_t interface uses mutex_t and condvar_t - * primitives, if the pthread_rwlock_* group of functions is not available. + * primitives, if the pthread_rwlock_* group of functions is not available or + * don't allow recursive locking for readers. * * The following constraints are enforced: * - Multiple readers can hold the lock at the same time. * - Only a single writer can hold the lock at any given time. * - A writer must block until all readers have released the lock before * obtaining the lock exclusively. - * - Readers that arrive while a writer is waiting to acquire the lock will - * block until after the writer has obtained and released the lock. + * - Readers that don't hold any read lock and arrive while a writer is + * waiting to acquire the lock will block until after the writer has + * obtained and released the lock. * These constraints allow for read sharing, prevent write sharing, prevent - * read-write sharing and prevent starvation of writers by a steady stream - * of incoming readers. Reader starvation is not prevented (this could happen - * if there are more writers than readers). + * read-write sharing and (largely) prevent starvation of writers by a steady + * stream of incoming readers. Reader starvation is not prevented (this could + * happen if there are more writers than readers). * - * The implementation does not support recursive locking and readers must not - * acquire the lock exclusively at the same time and vice-versa (this is not - * checked or enforced so behave yourself to prevent deadlocks). + * The implementation supports recursive locking of the read lock but not of + * the write lock. Readers must not acquire the lock exclusively at the same + * time and vice-versa (this is not checked or enforced so behave yourself to + * prevent deadlocks). + * + * Since writers are preferred a thread currently holding the read lock that + * tries to acquire the read lock recursively while a writer is waiting would + * result in a deadlock. In order to avoid having to use a thread-specific + * value for each rwlock_t (or a list of threads) to keep track if a thread + * already acquired the read lock we use a single thread-specific value for all + * rwlock_t objects that keeps track of how many read locks a thread currently + * holds. Preferring readers that already hold ANY read locks prevents this + * deadlock while it still largely avoids writer starvation (for locks that can + * only be acquired while holding another read lock this will obviously not + * work). */ +/** + * Keep track of how many read locks a thread holds. + */ +static pthread_key_t is_reader; + +/** + * Only initialize the read lock counter once. + */ +static pthread_once_t is_reader_initialized = PTHREAD_ONCE_INIT; + +/** + * Initialize the read lock counter. + */ +static void initialize_is_reader() +{ + pthread_key_create(&is_reader, NULL); +} + METHOD(rwlock_t, read_lock, void, private_rwlock_t *this) { + uintptr_t reading; + + reading = (uintptr_t)pthread_getspecific(is_reader); profiler_start(&this->profile); this->mutex->lock(this->mutex); - while (this->writer || this->waiting_writers) + if (!this->writer && reading > 0) { - this->readers->wait(this->readers, this->mutex); + /* directly allow threads that hold ANY read locks, to avoid a deadlock + * caused by preferring writers in the loop below */ + } + else + { + while (this->writer || this->waiting_writers) + { + this->readers->wait(this->readers, this->mutex); + } } this->reader_count++; profiler_end(&this->profile); this->mutex->unlock(this->mutex); + pthread_setspecific(is_reader, (void*)(reading + 1)); } METHOD(rwlock_t, write_lock, void, @@ -219,7 +287,7 @@ METHOD(rwlock_t, write_lock, void, this->writers->wait(this->writers, this->mutex); } this->waiting_writers--; - this->writer = pthread_self(); + this->writer = TRUE; profiler_end(&this->profile); this->mutex->unlock(this->mutex); } @@ -231,8 +299,7 @@ METHOD(rwlock_t, try_write_lock, bool, this->mutex->lock(this->mutex); if (!this->writer && !this->reader_count) { - res = TRUE; - this->writer = pthread_self(); + res = this->writer = TRUE; } this->mutex->unlock(this->mutex); return res; @@ -242,9 +309,20 @@ METHOD(rwlock_t, unlock, void, private_rwlock_t *this) { this->mutex->lock(this->mutex); - if (this->writer == pthread_self()) + if (this->writer) + { + this->writer = FALSE; + } + else + { + uintptr_t reading; + + this->reader_count--; + reading = (uintptr_t)pthread_getspecific(is_reader); + pthread_setspecific(is_reader, (void*)(reading - 1)); + } + if (!this->reader_count) { - this->writer = 0; if (this->waiting_writers) { this->writers->signal(this->writers); @@ -254,14 +332,6 @@ METHOD(rwlock_t, unlock, void, this->readers->broadcast(this->readers); } } - else - { - this->reader_count--; - if (!this->reader_count) - { - this->writers->signal(this->writers); - } - } this->mutex->unlock(this->mutex); } @@ -280,6 +350,8 @@ METHOD(rwlock_t, destroy, void, */ rwlock_t *rwlock_create(rwlock_type_t type) { + pthread_once(&is_reader_initialized, initialize_is_reader); + switch (type) { case RWLOCK_TYPE_DEFAULT: @@ -309,3 +381,110 @@ rwlock_t *rwlock_create(rwlock_type_t type) #endif /* HAVE_PTHREAD_RWLOCK_INIT */ + +METHOD(rwlock_condvar_t, wait_, void, + private_rwlock_condvar_t *this, rwlock_t *lock) +{ + /* at this point we have the write lock locked, to make signals more + * predictable we try to prevent other threads from signaling by acquiring + * the mutex while we still hold the write lock (this assumes they will + * hold the write lock themselves when signaling, which is not mandatory) */ + this->mutex->lock(this->mutex); + /* unlock the rwlock and wait for a signal */ + lock->unlock(lock); + /* if the calling thread enabled thread cancelability we want to replicate + * the behavior of the regular condvar, i.e. the lock will be held again + * before executing cleanup functions registered by the calling thread */ + thread_cleanup_push((thread_cleanup_t)lock->write_lock, lock); + thread_cleanup_push((thread_cleanup_t)this->mutex->unlock, this->mutex); + this->condvar->wait(this->condvar, this->mutex); + /* we release the mutex to allow other threads into the condvar (might even + * be required so we can acquire the lock again below) */ + thread_cleanup_pop(TRUE); + /* finally we reacquire the lock we held previously */ + thread_cleanup_pop(TRUE); +} + +METHOD(rwlock_condvar_t, timed_wait_abs, bool, + private_rwlock_condvar_t *this, rwlock_t *lock, timeval_t time) +{ + bool timed_out; + + /* see wait() above for details on what is going on here */ + this->mutex->lock(this->mutex); + lock->unlock(lock); + thread_cleanup_push((thread_cleanup_t)lock->write_lock, lock); + thread_cleanup_push((thread_cleanup_t)this->mutex->unlock, this->mutex); + timed_out = this->condvar->timed_wait_abs(this->condvar, this->mutex, time); + thread_cleanup_pop(TRUE); + thread_cleanup_pop(!timed_out); + return timed_out; +} + +METHOD(rwlock_condvar_t, timed_wait, bool, + private_rwlock_condvar_t *this, rwlock_t *lock, u_int timeout) +{ + timeval_t tv; + u_int s, ms; + + time_monotonic(&tv); + + s = timeout / 1000; + ms = timeout % 1000; + + tv.tv_sec += s; + tv.tv_usec += ms * 1000; + + if (tv.tv_usec > 1000000 /* 1s */) + { + tv.tv_usec -= 1000000; + tv.tv_sec++; + } + return timed_wait_abs(this, lock, tv); +} + +METHOD(rwlock_condvar_t, signal_, void, + private_rwlock_condvar_t *this) +{ + this->mutex->lock(this->mutex); + this->condvar->signal(this->condvar); + this->mutex->unlock(this->mutex); +} + +METHOD(rwlock_condvar_t, broadcast, void, + private_rwlock_condvar_t *this) +{ + this->mutex->lock(this->mutex); + this->condvar->broadcast(this->condvar); + this->mutex->unlock(this->mutex); +} + +METHOD(rwlock_condvar_t, condvar_destroy, void, + private_rwlock_condvar_t *this) +{ + this->condvar->destroy(this->condvar); + this->mutex->destroy(this->mutex); + free(this); +} + +/* + * see header file + */ +rwlock_condvar_t *rwlock_condvar_create() +{ + private_rwlock_condvar_t *this; + + INIT(this, + .public = { + .wait = _wait_, + .timed_wait = _timed_wait, + .timed_wait_abs = _timed_wait_abs, + .signal = _signal_, + .broadcast = _broadcast, + .destroy = _condvar_destroy, + }, + .mutex = mutex_create(MUTEX_TYPE_DEFAULT), + .condvar = condvar_create(CONDVAR_TYPE_DEFAULT), + ); + return &this->public; +} diff --git a/src/libstrongswan/threading/rwlock_condvar.h b/src/libstrongswan/threading/rwlock_condvar.h new file mode 100644 index 000000000..2b40c3fc6 --- /dev/null +++ b/src/libstrongswan/threading/rwlock_condvar.h @@ -0,0 +1,90 @@ +/* + * Copyright (C) 2012 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. + */ + +/** + * @defgroup rwlock_condvar rwlock_condvar + * @{ @ingroup threading + */ + +#ifndef RWLOCK_CONDVAR_H_ +#define RWLOCK_CONDVAR_H_ + +typedef struct rwlock_condvar_t rwlock_condvar_t; + +#include "rwlock.h" + +/** + * A special condvar implementation that can be used in conjunction + * with rwlock_t (the write lock to be precise). + * + * @note The implementation does not verify that the current thread actually + * holds the write lock and not the read lock, so watch out. + */ +struct rwlock_condvar_t { + + /** + * Wait on a condvar until it gets signalized. + * + * @param lock lock to release while waiting (write lock) + */ + void (*wait)(rwlock_condvar_t *this, rwlock_t *lock); + + /** + * Wait on a condvar until it gets signalized, or times out. + * + * @param lock lock to release while waiting (write lock) + * @param timeout timeout im ms + * @return TRUE if timed out, FALSE otherwise + */ + bool (*timed_wait)(rwlock_condvar_t *this, rwlock_t *lock, u_int timeout); + + /** + * Wait on a condvar until it gets signalized, or times out. + * + * The passed timeval should be calculated based on the time_monotonic() + * function. + * + * @param lock lock to release while waiting (write lock) + * @param tv absolute time until timeout + * @return TRUE if timed out, FALSE otherwise + */ + bool (*timed_wait_abs)(rwlock_condvar_t *this, rwlock_t *lock, + timeval_t tv); + + /** + * Wake up a single thread in a condvar. + */ + void (*signal)(rwlock_condvar_t *this); + + /** + * Wake up all threads in a condvar. + */ + void (*broadcast)(rwlock_condvar_t *this); + + /** + * Destroy a condvar and free its resources. + */ + void (*destroy)(rwlock_condvar_t *this); +}; + +/** + * Create a condvar instance. + * + * @return condvar instance + */ +rwlock_condvar_t *rwlock_condvar_create(); + +#endif /** RWLOCK_CONDVAR_H_ @} */ + diff --git a/src/libstrongswan/threading/semaphore.c b/src/libstrongswan/threading/semaphore.c new file mode 100644 index 000000000..b785ff944 --- /dev/null +++ b/src/libstrongswan/threading/semaphore.c @@ -0,0 +1,179 @@ +/* + * Copyright (C) 2011 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. + */ + +#include <library.h> + +#if defined(HAVE_CLOCK_GETTIME) && \ + (defined(HAVE_CONDATTR_CLOCK_MONOTONIC) || \ + defined(HAVE_PTHREAD_COND_TIMEDWAIT_MONOTONIC)) +/* if we use MONOTONIC times, we can't use POSIX_SEMAPHORES since they use + * times based on CLOCK_REALTIME */ +#undef HAVE_SEM_TIMEDWAIT +#endif /* HAVE_CLOCK_GETTIME && ... */ + +#ifdef HAVE_SEM_TIMEDWAIT +#include <semaphore.h> +#else /* !HAVE_SEM_TIMEDWAIT */ +#include <threading/condvar.h> +#endif /* HAVE_SEM_TIMEDWAIT */ + +#include "semaphore.h" + +typedef struct private_semaphore_t private_semaphore_t; + +/** + * private data of a semaphore + */ +struct private_semaphore_t { + /** + * public interface + */ + semaphore_t public; + +#ifdef HAVE_SEM_TIMEDWAIT + /** + * wrapped POSIX semaphore object + */ + sem_t sem; +#else /* !HAVE_SEM_TIMEDWAIT */ + + /** + * Mutex to lock count variable + */ + mutex_t *mutex; + + /** + * Condvar to signal count increase + */ + condvar_t *cond; + + /** + * Semaphore count value + */ + u_int count; +#endif /* HAVE_SEM_TIMEDWAIT */ +}; + +METHOD(semaphore_t, wait_, void, + private_semaphore_t *this) +{ +#ifdef HAVE_SEM_TIMEDWAIT + sem_wait(&this->sem); +#else /* !HAVE_SEM_TIMEDWAIT */ + this->mutex->lock(this->mutex); + while (this->count == 0) + { + this->cond->wait(this->cond, this->mutex); + } + this->count--; + this->mutex->unlock(this->mutex); +#endif /* HAVE_SEM_TIMEDWAIT */ +} + +METHOD(semaphore_t, timed_wait_abs, bool, + private_semaphore_t *this, timeval_t tv) +{ +#ifdef HAVE_SEM_TIMEDWAIT + timespec_t ts; + + ts.tv_sec = tv.tv_sec; + ts.tv_nsec = tv.tv_usec * 1000; + + /* there are errors other than ETIMEDOUT possible, but we consider them + * all as timeout */ + return sem_timedwait(&this->sem, &ts) == -1; +#else /* !HAVE_SEM_TIMEDWAIT */ + this->mutex->lock(this->mutex); + while (this->count == 0) + { + if (this->cond->timed_wait_abs(this->cond, this->mutex, tv)) + { + this->mutex->unlock(this->mutex); + return TRUE; + } + } + this->count--; + this->mutex->unlock(this->mutex); + return FALSE; +#endif /* HAVE_SEM_TIMEDWAIT */ +} + +METHOD(semaphore_t, timed_wait, bool, + private_semaphore_t *this, u_int timeout) +{ + timeval_t tv, add; + + add.tv_sec = timeout / 1000; + add.tv_usec = (timeout % 1000) * 1000; + + time_monotonic(&tv); + timeradd(&tv, &add, &tv); + + return timed_wait_abs(this, tv); +} + +METHOD(semaphore_t, post, void, + private_semaphore_t *this) +{ +#ifdef HAVE_SEM_TIMEDWAIT + sem_post(&this->sem); +#else /* !HAVE_SEM_TIMEDWAIT */ + this->mutex->lock(this->mutex); + this->count++; + this->mutex->unlock(this->mutex); + this->cond->signal(this->cond); +#endif /* HAVE_SEM_TIMEDWAIT */ +} + +METHOD(semaphore_t, destroy, void, + private_semaphore_t *this) +{ +#ifdef HAVE_SEM_TIMEDWAIT + sem_destroy(&this->sem); +#else /* !HAVE_SEM_TIMEDWAIT */ + this->cond->destroy(this->cond); + this->mutex->destroy(this->mutex); +#endif /* HAVE_SEM_TIMEDWAIT */ + free(this); +} + +/* + * Described in header + */ +semaphore_t *semaphore_create(u_int value) +{ + private_semaphore_t *this; + + INIT(this, + .public = { + .wait = _wait_, + .timed_wait = _timed_wait, + .timed_wait_abs = _timed_wait_abs, + .post = _post, + .destroy = _destroy, + }, + ); + +#ifdef HAVE_SEM_TIMEDWAIT + sem_init(&this->sem, 0, value); +#else /* !HAVE_SEM_TIMEDWAIT */ + this->mutex = mutex_create(MUTEX_TYPE_DEFAULT); + this->cond = condvar_create(CONDVAR_TYPE_DEFAULT); + this->count = value; +#endif /* HAVE_SEM_TIMEDWAIT */ + + return &this->public; +} + diff --git a/src/libstrongswan/threading/semaphore.h b/src/libstrongswan/threading/semaphore.h new file mode 100644 index 000000000..cdb0a6f19 --- /dev/null +++ b/src/libstrongswan/threading/semaphore.h @@ -0,0 +1,85 @@ +/* + * Copyright (C) 2011 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. + */ + +/** + * @defgroup semaphore semaphore + * @{ @ingroup threading + */ + +#ifndef THREADING_SEMAPHORE_H_ +#define THREADING_SEMAPHORE_H_ + +typedef struct semaphore_t semaphore_t; + +/** + * A semaphore is basically an integer whose value is never allowed to be + * lower than 0. Two operations can be performed on it: increment the + * value by one, and decrement the value by one. If the value is currently + * zero, then the decrement operation will blcok until the value becomes + * greater than zero. + */ +struct semaphore_t { + + /** + * Decrease the value by one, if it is greater than zero. Otherwise the + * current thread is blocked and it waits until the value increases. + */ + void (*wait)(semaphore_t *this); + + /** + * Decrease the value by one, if it is greater than zero. Otherwise the + * current thread is blocked and it waits until the value increases, or the + * call times out. + * + * @param timeout timeout im ms + * @return TRUE if timed out, FALSE otherwise + */ + bool (*timed_wait)(semaphore_t *this, u_int timeout); + + /** + * Decrease the value by one, if it is greater than zero. Otherwise the + * current thread is blocked and it waits until the value increases, or the + * call times out. + * + * The passed timeval should be calculated based on the time_monotonic() + * function. + * + * @param tv absolute time until timeout + * @return TRUE if timed out, FALSE otherwise + */ + bool (*timed_wait_abs)(semaphore_t *this, timeval_t tv); + + /** + * Increase the value by one. If the value becomes greater than zero, then + * another thread waiting will be woken up. + */ + void (*post)(semaphore_t *this); + + /** + * Destroy a semaphore and free its resources. + */ + void (*destroy)(semaphore_t *this); +}; + +/** + * Create a semaphore instance. + * + * @param value initial value (typically 0) + * @return semaphore instance + */ +semaphore_t *semaphore_create(u_int value); + +#endif /** THREADING_SEMAPHORE_H_ @} */ + diff --git a/src/libstrongswan/threading/spinlock.c b/src/libstrongswan/threading/spinlock.c new file mode 100644 index 000000000..812cf696b --- /dev/null +++ b/src/libstrongswan/threading/spinlock.c @@ -0,0 +1,136 @@ +/* + * Copyright (C) 2012 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. + */ + +#include <unistd.h> /* for _POSIX_SPIN_LOCKS */ +#include <pthread.h> + +#include <library.h> +#include <debug.h> + +#include "spinlock.h" +#include "mutex.h" +#include "lock_profiler.h" + +#if defined(_POSIX_SPIN_LOCKS) && _POSIX_SPIN_LOCKS == -1 +#undef _POSIX_SPIN_LOCKS +#endif + +typedef struct private_spinlock_t private_spinlock_t; + +/** + * private data + */ +struct private_spinlock_t { + + /** + * public functions + */ + spinlock_t public; + +#ifdef _POSIX_SPIN_LOCKS + + /** + * wrapped pthread spin lock + */ + pthread_spinlock_t spinlock; + + /** + * profiling info, if enabled (the mutex below does profile itself) + */ + lock_profile_t profile; + +#else /* _POSIX_SPIN_LOCKS */ + + /** + * use a mutex if spin locks are not available + */ + mutex_t *mutex; + +#endif /* _POSIX_SPIN_LOCKS */ +}; + +METHOD(spinlock_t, lock, void, + private_spinlock_t *this) +{ +#ifdef _POSIX_SPIN_LOCKS + int err; + + profiler_start(&this->profile); + err = pthread_spin_lock(&this->spinlock); + if (err) + { + DBG1(DBG_LIB, "!!! SPIN LOCK LOCK ERROR: %s !!!", strerror(err)); + } + profiler_end(&this->profile); +#else + this->mutex->lock(this->mutex); +#endif +} + +METHOD(spinlock_t, unlock, void, + private_spinlock_t *this) +{ +#ifdef _POSIX_SPIN_LOCKS + int err; + + err = pthread_spin_unlock(&this->spinlock); + if (err) + { + DBG1(DBG_LIB, "!!! SPIN LOCK UNLOCK ERROR: %s !!!", strerror(err)); + } +#else + this->mutex->unlock(this->mutex); +#endif +} + +METHOD(spinlock_t, destroy, void, + private_spinlock_t *this) +{ +#ifdef _POSIX_SPIN_LOCKS + profiler_cleanup(&this->profile); + pthread_spin_destroy(&this->spinlock); +#else + this->mutex->destroy(this->mutex); +#endif + free(this); +} + +/* + * Described in header + */ +spinlock_t *spinlock_create() +{ + private_spinlock_t *this; + + INIT(this, + .public = { + .lock = _lock, + .unlock = _unlock, + .destroy = _destroy, + }, + ); + +#ifdef _POSIX_SPIN_LOCKS + pthread_spin_init(&this->spinlock, PTHREAD_PROCESS_PRIVATE); + profiler_init(&this->profile); +#else + #warning Using mutexes as spin lock alternatives + this->mutex = mutex_create(MUTEX_TYPE_DEFAULT); +#endif + + return &this->public; +} + + diff --git a/src/libstrongswan/threading/spinlock.h b/src/libstrongswan/threading/spinlock.h new file mode 100644 index 000000000..883980cc2 --- /dev/null +++ b/src/libstrongswan/threading/spinlock.h @@ -0,0 +1,58 @@ +/* + * Copyright (C) 2012 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. + */ + +/** + * @defgroup spinlock spinlock + * @{ @ingroup threading + */ + +#ifndef THREADING_SPINLOCK_H_ +#define THREADING_SPINLOCK_H_ + +typedef struct spinlock_t spinlock_t; + +/** + * Spin lock wrapper implements a lock with low overhead when the lock is held + * only for a short time (waiting wastes processor cycles, though). + * + * If native spin locks are not available regular mutexes are used as fallback. + */ +struct spinlock_t { + + /** + * Acquire the lock. + */ + void (*lock)(spinlock_t *this); + + /** + * Release the lock. + */ + void (*unlock)(spinlock_t *this); + + /** + * Destroy the instance. + */ + void (*destroy)(spinlock_t *this); +}; + +/** + * Create a spin lock instance. + * + * @return unlocked instance + */ +spinlock_t *spinlock_create(); + +#endif /** THREADING_SPINLOCK_H_ @} */ + diff --git a/src/libstrongswan/threading/thread.c b/src/libstrongswan/threading/thread.c index 49a1b8430..9ef514ebc 100644 --- a/src/libstrongswan/threading/thread.c +++ b/src/libstrongswan/threading/thread.c @@ -114,7 +114,7 @@ typedef struct { /** * Next thread ID. */ -static u_int next_id = 1; +static u_int next_id; /** * Mutex to safely access the next thread ID. @@ -452,6 +452,7 @@ void threads_init() dummy1 = thread_value_create(NULL); + next_id = 1; main_thread->id = 0; main_thread->thread_id = pthread_self(); current_thread = thread_value_create(NULL); @@ -482,4 +483,3 @@ void threads_deinit() current_thread->destroy(current_thread); id_mutex->destroy(id_mutex); } - diff --git a/src/libstrongswan/threading/thread_value.c b/src/libstrongswan/threading/thread_value.c index 3fa70acb2..190b7434f 100644 --- a/src/libstrongswan/threading/thread_value.c +++ b/src/libstrongswan/threading/thread_value.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2009 Tobias Brunner + * Copyright (C) 2009-2012 Tobias Brunner * Hochschule fuer Technik Rapperswil * * This program is free software; you can redistribute it and/or modify it @@ -33,6 +33,11 @@ struct private_thread_value_t { */ pthread_key_t key; + /** + * Destructor to cleanup the value of the thread destroying this object + */ + thread_cleanup_t destructor; + }; METHOD(thread_value_t, set, void, @@ -50,11 +55,22 @@ METHOD(thread_value_t, get, void*, METHOD(thread_value_t, destroy, void, private_thread_value_t *this) { + void *val; + + /* the destructor is not called automatically for the thread calling + * pthread_key_delete() */ + if (this->destructor) + { + val = pthread_getspecific(this->key); + if (val) + { + this->destructor(val); + } + } pthread_key_delete(this->key); free(this); } - /** * Described in header. */ @@ -68,6 +84,7 @@ thread_value_t *thread_value_create(thread_cleanup_t destructor) .get = _get, .destroy = _destroy, }, + .destructor = destructor, ); pthread_key_create(&this->key, destructor); diff --git a/src/libstrongswan/utils.c b/src/libstrongswan/utils.c index f76245a19..d43a4bc2f 100644 --- a/src/libstrongswan/utils.c +++ b/src/libstrongswan/utils.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2008-2011 Tobias Brunner + * Copyright (C) 2008-2012 Tobias Brunner * Copyright (C) 2005-2008 Martin Willi * Hochschule fuer Technik Rapperswil * @@ -25,6 +25,7 @@ #include <limits.h> #include <dirent.h> #include <time.h> +#include <pthread.h> #include "enum.h" #include "debug.h" @@ -194,6 +195,85 @@ bool mkdir_p(const char *path, mode_t mode) return TRUE; } + +/** + * The size of the thread-specific error buffer + */ +#define STRERROR_BUF_LEN 256 + +/** + * Key to store thread-specific error buffer + */ +static pthread_key_t strerror_buf_key; + +/** + * Only initialize the key above once + */ +static pthread_once_t strerror_buf_key_once = PTHREAD_ONCE_INIT; + +/** + * Create the key used for the thread-specific error buffer + */ +static void create_strerror_buf_key() +{ + pthread_key_create(&strerror_buf_key, free); +} + +/** + * Retrieve the error buffer assigned to the current thread (or create it) + */ +static inline char *get_strerror_buf() +{ + char *buf; + + pthread_once(&strerror_buf_key_once, create_strerror_buf_key); + buf = pthread_getspecific(strerror_buf_key); + if (!buf) + { + buf = malloc(STRERROR_BUF_LEN); + pthread_setspecific(strerror_buf_key, buf); + } + return buf; +} + +#ifdef HAVE_STRERROR_R +/* + * Described in header. + */ +const char *safe_strerror(int errnum) +{ + char *buf = get_strerror_buf(), *msg; + +#ifdef STRERROR_R_CHAR_P + /* char* version which may or may not return the original buffer */ + msg = strerror_r(errnum, buf, STRERROR_BUF_LEN); +#else + /* int version returns 0 on success */ + msg = strerror_r(errnum, buf, STRERROR_BUF_LEN) ? "Unknown error" : buf; +#endif + return msg; +} +#else /* HAVE_STRERROR_R */ +/* we actually wan't to call strerror(3) below */ +#undef strerror +/* + * Described in header. + */ +const char *safe_strerror(int errnum) +{ + static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; + char *buf = get_strerror_buf(); + + /* use a mutex to ensure calling strerror(3) is thread-safe */ + pthread_mutex_lock(&mutex); + strncpy(buf, strerror(errnum), STRERROR_BUF_LEN); + pthread_mutex_unlock(&mutex); + buf[STRERROR_BUF_LEN - 1] = '\0'; + return buf; +} +#endif /* HAVE_STRERROR_R */ + + #ifndef HAVE_CLOSEFROM /** * Described in header. @@ -315,7 +395,6 @@ void nop() } #ifndef HAVE_GCC_ATOMIC_OPERATIONS -#include <pthread.h> /** * We use a single mutex for all refcount variables. @@ -371,7 +450,7 @@ _cas_impl(ptr, void*) /** * Described in header. */ -int time_printf_hook(char *dst, size_t len, printf_hook_spec_t *spec, +int time_printf_hook(printf_hook_data_t *data, printf_hook_spec_t *spec, const void *const *args) { static const char* months[] = { @@ -384,7 +463,7 @@ int time_printf_hook(char *dst, size_t len, printf_hook_spec_t *spec, if (time == UNDEFINED_TIME) { - return print_in_hook(dst, len, "--- -- --:--:--%s----", + return print_in_hook(data, "--- -- --:--:--%s----", utc ? " UTC " : " "); } if (utc) @@ -395,7 +474,7 @@ int time_printf_hook(char *dst, size_t len, printf_hook_spec_t *spec, { localtime_r(time, &t); } - return print_in_hook(dst, len, "%s %02d %02d:%02d:%02d%s%04d", + return print_in_hook(data, "%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); } @@ -403,7 +482,7 @@ int time_printf_hook(char *dst, size_t len, printf_hook_spec_t *spec, /** * Described in header. */ -int time_delta_printf_hook(char *dst, size_t len, printf_hook_spec_t *spec, +int time_delta_printf_hook(printf_hook_data_t *data, printf_hook_spec_t *spec, const void *const *args) { char* unit = "second"; @@ -426,7 +505,7 @@ int time_delta_printf_hook(char *dst, size_t len, printf_hook_spec_t *spec, delta /= 60; unit = "minute"; } - return print_in_hook(dst, len, "%" PRIu64 " %s%s", delta, unit, + return print_in_hook(data, "%" PRIu64 " %s%s", delta, unit, (delta == 1) ? "" : "s"); } @@ -440,7 +519,7 @@ static char hexdig_upper[] = "0123456789ABCDEF"; /** * Described in header. */ -int mem_printf_hook(char *dst, size_t dstlen, +int mem_printf_hook(printf_hook_data_t *data, printf_hook_spec_t *spec, const void *const *args) { char *bytes = *((void**)(args[0])); @@ -455,7 +534,7 @@ int mem_printf_hook(char *dst, size_t dstlen, int i = 0; int written = 0; - written += print_in_hook(dst, dstlen, "=> %u bytes @ %p", len, bytes); + written += print_in_hook(data, "=> %u bytes @ %p", len, bytes); while (bytes_pos < bytes_roof) { @@ -476,7 +555,7 @@ int mem_printf_hook(char *dst, size_t dstlen, *buffer_pos++ = '\0'; ascii_buffer[i] = '\0'; - written += print_in_hook(dst, dstlen, "\n%4d: %s %s", + written += print_in_hook(data, "\n%4d: %s %s", line_start, buffer, ascii_buffer); buffer_pos = buffer; diff --git a/src/libstrongswan/utils.h b/src/libstrongswan/utils.h index cedfe8fd1..f47c65ac1 100644 --- a/src/libstrongswan/utils.h +++ b/src/libstrongswan/utils.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2008-2011 Tobias Brunner + * Copyright (C) 2008-2012 Tobias Brunner * Copyright (C) 2008 Martin Willi * Hochschule fuer Technik Rapperswil * @@ -52,9 +52,33 @@ #define BUF_LEN 512 /** - * Macro compares two strings for equality + * General purpose boolean type. */ -#define streq(x,y) (strcmp(x, y) == 0) +#ifdef HAVE_STDBOOL_H +# include <stdbool.h> +#else +# ifndef HAVE__BOOL +# define _Bool signed char +# endif /* HAVE__BOOL */ +# define bool _Bool +# define false 0 +# define true 1 +# define __bool_true_false_are_defined 1 +#endif /* HAVE_STDBOOL_H */ +#ifndef FALSE +# define FALSE false +#endif /* FALSE */ +#ifndef TRUE +# define TRUE true +#endif /* TRUE */ + +/** + * Helper function that compares two strings for equality + */ +static inline bool streq(const char *x, const char *y) +{ + return strcmp(x, y) == 0; +} /** * Macro compares two strings for equality, length limited @@ -62,9 +86,12 @@ #define strneq(x,y,len) (strncmp(x, y, len) == 0) /** - * Macro compares two strings for equality ignoring case + * Helper function that compares two strings for equality ignoring case */ -#define strcaseeq(x,y) (strcasecmp(x, y) == 0) +static inline bool strcaseeq(const char *x, const char *y) +{ + return strcasecmp(x, y) == 0; +} /** * Macro compares two strings for equality ignoring case, length limited @@ -74,7 +101,10 @@ /** * NULL-safe strdup variant */ -#define strdupnull(x) ({ char *_x = x; _x ? strdup(_x) : NULL; }) +static inline char *strdupnull(const char *s) +{ + return s ? strdup(s) : NULL; +} /** * Macro compares two binary blobs for equality @@ -121,9 +151,8 @@ /** * Object allocation/initialization macro, using designated initializer. */ -#define INIT(this, ...) ({ (this) = malloc(sizeof(*(this))); \ - *(this) = (typeof(*(this))){ __VA_ARGS__ }; \ - (this); }) +#define INIT(this, ...) { (this) = malloc(sizeof(*(this))); \ + *(this) = (typeof(*(this))){ __VA_ARGS__ }; } /** * Method declaration/definition macro, providing private and public interface. @@ -136,7 +165,7 @@ #define METHOD(iface, name, ret, this, ...) \ static ret name(union {iface *_public; this;} \ __attribute__((transparent_union)), ##__VA_ARGS__); \ - static const typeof(name) *_##name = (const typeof(name)*)name; \ + static typeof(name) *_##name = (typeof(name)*)name; \ static ret name(this, ##__VA_ARGS__) /** @@ -145,7 +174,7 @@ #define METHOD2(iface1, iface2, name, ret, this, ...) \ static ret name(union {iface1 *_public1; iface2 *_public2; this;} \ __attribute__((transparent_union)), ##__VA_ARGS__); \ - static const typeof(name) *_##name = (const typeof(name)*)name; \ + static typeof(name) *_##name = (typeof(name)*)name; \ static ret name(this, ##__VA_ARGS__) /** @@ -201,27 +230,6 @@ #define TIME_32_BIT_SIGNED_MAX 0x7fffffff /** - * General purpose boolean type. - */ -#ifdef HAVE_STDBOOL_H -# include <stdbool.h> -#else -# ifndef HAVE__BOOL -# define _Bool signed char -# endif /* HAVE__BOOL */ -# define bool _Bool -# define false 0 -# define true 1 -# define __bool_true_false_are_defined 1 -#endif /* HAVE_STDBOOL_H */ -#ifndef FALSE -# define FALSE false -#endif /* FALSE */ -#ifndef TRUE -# define TRUE true -#endif /* TRUE */ - -/** * define some missing fixed width int types on OpenSolaris. * TODO: since the uintXX_t types are defined by the C99 standard we should * probably use those anyway @@ -408,6 +416,23 @@ char *translate(char *str, const char *from, const char *to); */ bool mkdir_p(const char *path, mode_t mode); +/** + * Thread-safe wrapper around strerror and strerror_r. + * + * This is required because the first is not thread-safe (on some platforms) + * and the second uses two different signatures (POSIX/GNU) and is impractical + * to use anyway. + * + * @param errnum error code (i.e. errno) + * @return error message + */ +const char *safe_strerror(int errnum); + +/** + * Replace usages of strerror(3) with thread-safe variant. + */ +#define strerror(errnum) safe_strerror(errnum) + #ifndef HAVE_CLOSEFROM /** * Close open file descriptors greater than or equal to lowfd. @@ -491,6 +516,11 @@ static inline void htoun32(void *network, u_int32_t host) static inline void htoun64(void *network, u_int64_t host) { char *unaligned = (char*)network; + +#ifdef be64toh + host = htobe64(host); + memcpy((char*)unaligned, &host, sizeof(host)); +#else u_int32_t high_part, low_part; high_part = host >> 32; @@ -501,6 +531,7 @@ static inline void htoun64(void *network, u_int64_t host) memcpy(unaligned, &high_part, sizeof(high_part)); unaligned += sizeof(high_part); memcpy(unaligned, &low_part, sizeof(low_part)); +#endif } /** @@ -542,6 +573,13 @@ static inline u_int32_t untoh32(void *network) static inline u_int64_t untoh64(void *network) { char *unaligned = (char*)network; + +#ifdef be64toh + u_int64_t tmp; + + memcpy(&tmp, unaligned, sizeof(tmp)); + return be64toh(tmp); +#else u_int32_t high_part, low_part; memcpy(&high_part, unaligned, sizeof(high_part)); @@ -552,6 +590,7 @@ static inline u_int64_t untoh64(void *network) low_part = ntohl(low_part); return (((u_int64_t)high_part) << 32) + low_part; +#endif } /** @@ -612,7 +651,6 @@ bool cas_bool(bool *ptr, bool oldval, bool newval); */ bool cas_ptr(void **ptr, void *oldval, void *newval); - #endif /* HAVE_GCC_ATOMIC_OPERATIONS */ /** @@ -621,7 +659,7 @@ bool cas_ptr(void **ptr, void *oldval, void *newval); * Arguments are: * time_t* time, bool utc */ -int time_printf_hook(char *dst, size_t len, printf_hook_spec_t *spec, +int time_printf_hook(printf_hook_data_t *data, printf_hook_spec_t *spec, const void *const *args); /** @@ -630,7 +668,7 @@ int time_printf_hook(char *dst, size_t len, printf_hook_spec_t *spec, * Arguments are: * time_t* begin, time_t* end */ -int time_delta_printf_hook(char *dst, size_t len, printf_hook_spec_t *spec, +int time_delta_printf_hook(printf_hook_data_t *data, printf_hook_spec_t *spec, const void *const *args); /** @@ -639,7 +677,7 @@ int time_delta_printf_hook(char *dst, size_t len, printf_hook_spec_t *spec, * Arguments are: * u_char *ptr, u_int len */ -int mem_printf_hook(char *dst, size_t len, printf_hook_spec_t *spec, +int mem_printf_hook(printf_hook_data_t *data, printf_hook_spec_t *spec, const void *const *args); #endif /** UTILS_H_ @}*/ diff --git a/src/libstrongswan/utils/backtrace.c b/src/libstrongswan/utils/backtrace.c index cb83d9830..b6015fb35 100644 --- a/src/libstrongswan/utils/backtrace.c +++ b/src/libstrongswan/utils/backtrace.c @@ -50,6 +50,284 @@ struct private_backtrace_t { void *frames[]; }; +#ifdef HAVE_DLADDR +#ifdef HAVE_BFD_H + +#include <bfd.h> +#include <utils/hashtable.h> +#include <threading/mutex.h> + +/** + * Hashtable-cached bfd handle + */ +typedef struct { + /** binary file name on disk */ + char *filename; + /** bfd handle */ + bfd *abfd; + /** loaded symbols */ + asymbol **syms; +} bfd_entry_t; + +/** + * Destroy a bfd_entry + */ +static void bfd_entry_destroy(bfd_entry_t *this) +{ + free(this->filename); + free(this->syms); + bfd_close(this->abfd); + free(this); +} + +/** + * Data to pass to find_addr() + */ +typedef struct { + /** used bfd entry */ + bfd_entry_t *entry; + /** backtrace address */ + bfd_vma vma; + /** stream to log to */ + FILE *file; + /** TRUE if complete */ + bool found; +} bfd_find_data_t; + +/** + * bfd entry cache + */ +static hashtable_t *bfds; + +static mutex_t *bfd_mutex; + +/** + * Hashtable hash function + */ +static u_int bfd_hash(char *key) +{ + return chunk_hash(chunk_create(key, strlen(key))); +} + +/** + * Hashtable equals function + */ +static bool bfd_equals(char *a, char *b) +{ + return streq(a, b); +} + +/** + * See header. + */ +void backtrace_init() +{ + bfd_init(); + bfds = hashtable_create((hashtable_hash_t)bfd_hash, + (hashtable_equals_t)bfd_equals, 8); + bfd_mutex = mutex_create(MUTEX_TYPE_DEFAULT); +} + +/** + * See header. + */ +void backtrace_deinit() +{ + enumerator_t *enumerator; + bfd_entry_t *entry; + char *key; + + enumerator = bfds->create_enumerator(bfds); + while (enumerator->enumerate(enumerator, &key, &entry)) + { + bfds->remove_at(bfds, enumerator); + bfd_entry_destroy(entry); + } + enumerator->destroy(enumerator); + + bfds->destroy(bfds); + bfd_mutex->destroy(bfd_mutex); +} + +/** + * Find and print information to an address + */ +static void find_addr(bfd *abfd, asection *section, bfd_find_data_t *data) +{ + bfd_size_type size; + bfd_vma vma; + const char *source; + const char *function; + u_int line; + + if (!data->found || (bfd_get_section_flags(abfd, section) & SEC_ALLOC) != 0) + { + vma = bfd_get_section_vma(abfd, section); + if (data->vma >= vma) + { + size = bfd_get_section_size(section); + if (data->vma < vma + size) + { + data->found = bfd_find_nearest_line(abfd, section, + data->entry->syms, data->vma - vma, + &source, &function, &line); + if (data->found) + { + if (source || function) + { + fprintf(data->file, " -> "); + if (function) + { + fprintf(data->file, "\e[34m%s() ", function); + } + if (source) + { + fprintf(data->file, "\e[32m@ %s:%d", source, line); + } + fprintf(data->file, "\e[0m\n"); + } + } + } + } + } +} + +/** + * Find a cached bfd entry, create'n'cache if not found + */ +static bfd_entry_t *get_bfd_entry(char *filename) +{ + bool dynamic = FALSE, ok = FALSE; + bfd_entry_t *entry; + long size; + + /* check cache */ + entry = bfds->get(bfds, filename); + if (entry) + { + return entry; + } + + INIT(entry, + .abfd = bfd_openr(filename, NULL), + ); + + if (!entry->abfd) + { + free(entry); + return NULL; + } +#ifdef BFD_DECOMPRESS + entry->abfd->flags |= BFD_DECOMPRESS; +#endif + if (bfd_check_format(entry->abfd, bfd_archive) == 0 && + bfd_check_format_matches(entry->abfd, bfd_object, NULL)) + { + if (bfd_get_file_flags(entry->abfd) & HAS_SYMS) + { + size = bfd_get_symtab_upper_bound(entry->abfd); + if (size == 0) + { + size = bfd_get_dynamic_symtab_upper_bound(entry->abfd); + } + if (size >= 0) + { + entry->syms = malloc(size); + if (dynamic) + { + ok = bfd_canonicalize_dynamic_symtab(entry->abfd, + entry->syms) >= 0; + } + else + { + ok = bfd_canonicalize_symtab(entry->abfd, + entry->syms) >= 0; + } + } + } + } + if (ok) + { + entry->filename = strdup(filename); + bfds->put(bfds, entry->filename, entry); + return entry; + } + bfd_entry_destroy(entry); + return NULL; +} + +/** + * Print the source file with line number to file, libbfd variant + */ +static void print_sourceline(FILE *file, char *filename, void *ptr) +{ + bfd_entry_t *entry; + bfd_find_data_t data = { + .file = file, + .vma = (uintptr_t)ptr, + }; + bool old = FALSE; + + bfd_mutex->lock(bfd_mutex); + if (lib->leak_detective) + { + old = lib->leak_detective->set_state(lib->leak_detective, FALSE); + } + entry = get_bfd_entry(filename); + if (entry) + { + data.entry = entry; + bfd_map_over_sections(entry->abfd, (void*)find_addr, &data); + } + if (lib->leak_detective) + { + lib->leak_detective->set_state(lib->leak_detective, old); + } + bfd_mutex->unlock(bfd_mutex); +} + +#else /* !HAVE_BFD_H */ + +void backtrace_init() {} +void backtrace_deinit() {} + +/** + * Print the source file with line number to file, slow addr2line variant + */ +static void print_sourceline(FILE *file, char *filename, void *ptr) +{ + char cmd[1024]; + FILE *output; + int c; + + snprintf(cmd, sizeof(cmd), "addr2line -e %s %p", filename, ptr); + output = popen(cmd, "r"); + if (output) + { + fprintf(file, " -> \e[32m"); + while (TRUE) + { + c = getc(output); + if (c == '\n' || c == EOF) + { + break; + } + fputc(c, file); + } + pclose(output); + fprintf(file, "\e[0m\n"); + } +} + +#endif /* HAVE_BFD_H */ + +#else /* !HAVE_DLADDR */ + +void backtrace_init() {} +void backtrace_deinit() {} + +#endif /* HAVE_DLADDR */ + METHOD(backtrace_t, log_, void, private_backtrace_t *this, FILE *file, bool detailed) { @@ -67,9 +345,6 @@ METHOD(backtrace_t, log_, void, if (dladdr(this->frames[i], &info)) { - char cmd[1024]; - FILE *output; - int c; void *ptr = this->frames[i]; if (strstr(info.dli_fname, ".so")) @@ -89,37 +364,14 @@ METHOD(backtrace_t, log_, void, } if (detailed) { - fprintf(file, " -> \e[32m"); - snprintf(cmd, sizeof(cmd), "addr2line -e %s %p", - info.dli_fname, ptr); - output = popen(cmd, "r"); - if (output) - { - while (TRUE) - { - c = getc(output); - if (c == '\n' || c == EOF) - { - break; - } - fputc(c, file); - } - pclose(output); - } - else - { - #endif /* HAVE_DLADDR */ - fprintf(file, " %s\n", strings[i]); - #ifdef HAVE_DLADDR - } - fprintf(file, "\n\e[0m"); + print_sourceline(file, (char*)info.dli_fname, ptr); } } else +#endif /* HAVE_DLADDR */ { fprintf(file, " %s\n", strings[i]); } -#endif /* HAVE_DLADDR */ } free (strings); #else /* !HAVE_BACKTRACE */ @@ -248,3 +500,20 @@ backtrace_t *backtrace_create(int skip) return &this->public; } +/** + * See header + */ +void backtrace_dump(char *label, FILE *file, bool detailed) +{ + backtrace_t *backtrace; + + backtrace = backtrace_create(2); + + if (label) + { + fprintf(file, "Debug backtrace: %s\n", label); + } + backtrace->log(backtrace, file, detailed); + backtrace->destroy(backtrace); +} + diff --git a/src/libstrongswan/utils/backtrace.h b/src/libstrongswan/utils/backtrace.h index 9d59d2503..aeeba4dd6 100644 --- a/src/libstrongswan/utils/backtrace.h +++ b/src/libstrongswan/utils/backtrace.h @@ -77,4 +77,23 @@ struct backtrace_t { */ backtrace_t *backtrace_create(int skip); +/** + * Create a backtrace, dump it and clean it up. + * + * @param label description to print for this backtrace, or NULL + * @param file FILE to log backtrace to + * @param detailed TRUE to resolve line/file using addr2line (slow) + */ +void backtrace_dump(char *label, FILE *file, bool detailed); + +/** + * Initialize backtracing framework. + */ +void backtrace_init(); + +/** + * Deinitialize backtracing framework. + */ +void backtrace_deinit(); + #endif /** BACKTRACE_H_ @}*/ diff --git a/src/libstrongswan/utils/blocking_queue.c b/src/libstrongswan/utils/blocking_queue.c new file mode 100644 index 000000000..c70184198 --- /dev/null +++ b/src/libstrongswan/utils/blocking_queue.c @@ -0,0 +1,129 @@ +/* + * Copyright (C) 2012 Tobias Brunner + * Copyright (C) 2012 Giuliano Grassi + * Copyright (C) 2012 Ralf Sager + * Hochschule fuer Technik Rapperswil + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT 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 "blocking_queue.h" + +#include <threading/mutex.h> +#include <threading/thread.h> +#include <threading/condvar.h> +#include <utils/linked_list.h> + +typedef struct private_blocking_queue_t private_blocking_queue_t; + +/** + * Private data of a blocking_queue_t object. + */ +struct private_blocking_queue_t { + + /** + * Public part + */ + blocking_queue_t public; + + /** + * Linked list containing all items in the queue + */ + linked_list_t *list; + + /** + * Mutex used to synchronize access to the queue + */ + mutex_t *mutex; + + /** + * Condvar used to wait for items + */ + condvar_t *condvar; + +}; + +METHOD(blocking_queue_t, enqueue, void, + private_blocking_queue_t *this, void *item) +{ + this->mutex->lock(this->mutex); + this->list->insert_first(this->list, item); + this->condvar->signal(this->condvar); + this->mutex->unlock(this->mutex); +} + +METHOD(blocking_queue_t, dequeue, void*, + private_blocking_queue_t *this) +{ + bool oldstate; + void *item; + + + this->mutex->lock(this->mutex); + thread_cleanup_push((thread_cleanup_t)this->mutex->unlock, this->mutex); + /* ensure that a canceled thread does not dequeue any items */ + thread_cancellation_point(); + while (this->list->remove_last(this->list, &item) != SUCCESS) + { + oldstate = thread_cancelability(TRUE); + this->condvar->wait(this->condvar, this->mutex); + thread_cancelability(oldstate); + } + thread_cleanup_pop(TRUE); + return item; +} + +METHOD(blocking_queue_t, destroy, void, + private_blocking_queue_t *this) +{ + this->list->destroy(this->list); + this->condvar->destroy(this->condvar); + this->mutex->destroy(this->mutex); + free(this); +} + +METHOD(blocking_queue_t, destroy_offset, void, + private_blocking_queue_t *this, size_t offset) +{ + this->list->invoke_offset(this->list, offset); + destroy(this); +} + +METHOD(blocking_queue_t, destroy_function, void, + private_blocking_queue_t *this, void (*fn)(void*)) +{ + this->list->invoke_function(this->list, (linked_list_invoke_t)fn); + destroy(this); +} + +/* + * Described in header. + */ +blocking_queue_t *blocking_queue_create() +{ + private_blocking_queue_t *this; + + INIT(this, + .public = { + .enqueue = _enqueue, + .dequeue = _dequeue, + .destroy = _destroy, + .destroy_offset = _destroy_offset, + .destroy_function = _destroy_function, + }, + .list = linked_list_create(), + .mutex = mutex_create(MUTEX_TYPE_DEFAULT), + .condvar = condvar_create(CONDVAR_TYPE_DEFAULT), + ); + + return &this->public; +} + diff --git a/src/libstrongswan/utils/blocking_queue.h b/src/libstrongswan/utils/blocking_queue.h new file mode 100644 index 000000000..cf2712cf4 --- /dev/null +++ b/src/libstrongswan/utils/blocking_queue.h @@ -0,0 +1,97 @@ +/* + * Copyright (C) 2012 Tobias Brunner + * Copyright (C) 2012 Giuliano Grassi + * Copyright (C) 2012 Ralf Sager + * Hochschule fuer Technik Rapperswil + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT 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 blocking_queue blocking_queue + * @{ @ingroup utils + */ + +#ifndef BLOCKING_QUEUE_H_ +#define BLOCKING_QUEUE_H_ + +typedef struct blocking_queue_t blocking_queue_t; + +#include <library.h> + +/** + * Class implementing a synchronized blocking queue based on linked_list_t + */ +struct blocking_queue_t { + + /** + * Inserts a new item at the tail of the queue + * + * @param item item to insert in queue + */ + void (*enqueue)(blocking_queue_t *this, void *item); + + /** + * Removes the first item in the queue and returns its value. + * If the queue is empty, this call blocks until a new item is inserted. + * + * @note This is a thread cancellation point + * + * @return removed item + */ + void *(*dequeue)(blocking_queue_t *this); + + /** + * Destroys a blocking_queue_t object. + * + * @note No thread must wait in dequeue() when this function is called + */ + void (*destroy)(blocking_queue_t *this); + + /** + * Destroys a queue and its objects using the given destructor. + * + * If a queue 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.: queue->destroy_offset(queue, offsetof(object_t, destroy)); + * + * @note No thread must wait in dequeue() when this function is called + * + * @param offset offset of the objects destructor + */ + void (*destroy_offset)(blocking_queue_t *this, size_t offset); + + /** + * Destroys a queue and its objects using a cleanup function. + * + * If a queue 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.: queue->destroy_function(queue, free); + * + * @note No thread must wait in dequeue() when this function is called + * + * @param function function to call on each object + */ + void (*destroy_function)(blocking_queue_t *this, void (*)(void*)); + +}; + +/** + * Creates an empty queue object. + * + * @return blocking_queue_t object. + */ +blocking_queue_t *blocking_queue_create(); + +#endif /** BLOCKING_QUEUE_H_ @}*/ + diff --git a/src/libstrongswan/utils/capabilities.c b/src/libstrongswan/utils/capabilities.c new file mode 100644 index 000000000..34128d010 --- /dev/null +++ b/src/libstrongswan/utils/capabilities.c @@ -0,0 +1,291 @@ +/* + * Copyright (C) 2012 Tobias Brunner + * Hochschule fuer Technik Rapperswil + * Copyright (C) 2012 Martin Willi + * Copyright (C) 2012 revosec AG + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT 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 "capabilities.h" + +#include <errno.h> +#include <string.h> +#include <sys/types.h> +#include <pwd.h> +#include <grp.h> +#include <unistd.h> +#ifdef HAVE_PRCTL +# include <sys/prctl.h> +#endif /* HAVE_PRCTL */ + +#include <debug.h> + +#if !defined(HAVE_GETPWNAM_R) || !defined(HAVE_GETGRNAM_R) +# include <threading/mutex.h> +# define EMULATE_R_FUNCS +#endif + +typedef struct private_capabilities_t private_capabilities_t; + +/** + * Private data of an capabilities_t object. + */ +struct private_capabilities_t { + + /** + * Public capabilities_t interface. + */ + capabilities_t public; + + /** + * user ID to switch during rights dropping + */ + uid_t uid; + + /** + * group ID to switch during rights dropping + */ + gid_t gid; + + /** + * capabilities to keep + */ +#ifdef CAPABILITIES_LIBCAP + cap_t caps; +#endif /* CAPABILITIES_LIBCAP */ +#ifdef CAPABILITIES_NATIVE + struct __user_cap_data_struct caps[2]; +#endif /* CAPABILITIES_NATIVE */ + +#ifdef EMULATE_R_FUNCS + /** + * mutex to emulate get(pw|gr)nam_r functions + */ + mutex_t *mutex; +#endif +}; + +METHOD(capabilities_t, keep, void, + private_capabilities_t *this, u_int cap) +{ +#ifdef CAPABILITIES_LIBCAP + cap_set_flag(this->caps, CAP_EFFECTIVE, 1, &cap, CAP_SET); + cap_set_flag(this->caps, CAP_INHERITABLE, 1, &cap, CAP_SET); + cap_set_flag(this->caps, CAP_PERMITTED, 1, &cap, CAP_SET); +#endif /* CAPABILITIES_LIBCAP */ +#ifdef CAPABILITIES_NATIVE + int i = 0; + + if (cap >= 32) + { + i++; + cap -= 32; + } + this->caps[i].effective |= 1 << cap; + this->caps[i].permitted |= 1 << cap; + this->caps[i].inheritable |= 1 << cap; +#endif /* CAPABILITIES_NATIVE */ +} + +METHOD(capabilities_t, get_uid, uid_t, + private_capabilities_t *this) +{ + return this->uid; +} + +METHOD(capabilities_t, get_gid, gid_t, + private_capabilities_t *this) +{ + return this->gid; +} + +METHOD(capabilities_t, set_uid, void, + private_capabilities_t *this, uid_t uid) +{ + this->uid = uid; +} + +METHOD(capabilities_t, set_gid, void, + private_capabilities_t *this, gid_t gid) +{ + this->gid = gid; +} + +METHOD(capabilities_t, resolve_uid, bool, + private_capabilities_t *this, char *username) +{ + struct passwd *pwp; + int err; + +#ifdef HAVE_GETPWNAM_R + struct passwd passwd; + char buf[1024]; + + err = getpwnam_r(username, &passwd, buf, sizeof(buf), &pwp); + if (pwp) + { + this->uid = pwp->pw_uid; + } +#else /* HAVE GETPWNAM_R */ + this->mutex->lock(this->mutex); + pwp = getpwnam(username); + if (pwp) + { + this->uid = pwp->pw_uid; + } + err = errno; + this->mutex->unlock(this->mutex); +#endif /* HAVE GETPWNAM_R */ + if (pwp) + { + return TRUE; + } + DBG1(DBG_LIB, "resolving user '%s' failed: %s", username, + err ? strerror(err) : "user not found"); + return FALSE; +} + +METHOD(capabilities_t, resolve_gid, bool, + private_capabilities_t *this, char *groupname) +{ + struct group *grp; + int err; + +#ifdef HAVE_GETGRNAM_R + struct group group; + char buf[1024]; + + err = getgrnam_r(groupname, &group, buf, sizeof(buf), &grp); + if (grp) + { + this->gid = grp->gr_gid; + } +#else /* HAVE_GETGRNAM_R */ + this->mutex->lock(this->mutex); + grp = getgrnam(groupname); + if (grp) + { + this->gid = grp->gr_gid; + } + err = errno; + this->mutex->unlock(this->mutex); +#endif /* HAVE_GETGRNAM_R */ + if (grp) + { + return TRUE; + } + DBG1(DBG_LIB, "resolving user '%s' failed: %s", groupname, + err ? strerror(err) : "group not found"); + return FALSE; +} + +METHOD(capabilities_t, drop, bool, + private_capabilities_t *this) +{ +#ifdef HAVE_PRCTL + prctl(PR_SET_KEEPCAPS, 1, 0, 0, 0); +#endif + + if (this->gid && setgid(this->gid) != 0) + { + DBG1(DBG_LIB, "change to unprivileged group %u failed: %s", + this->gid, strerror(errno)); + return FALSE; + } + if (this->uid && setuid(this->uid) != 0) + { + DBG1(DBG_LIB, "change to unprivileged user %u failed: %s", + this->uid, strerror(errno)); + return FALSE; + } + +#ifdef CAPABILITIES_LIBCAP + if (cap_set_proc(this->caps) != 0) + { + DBG1(DBG_LIB, "dropping capabilities failed: %s", strerror(errno)); + return FALSE; + } +#endif /* CAPABILITIES_LIBCAP */ +#ifdef CAPABILITIES_NATIVE + struct __user_cap_header_struct header = { +#if defined(_LINUX_CAPABILITY_VERSION_3) + .version = _LINUX_CAPABILITY_VERSION_3, +#elif defined(_LINUX_CAPABILITY_VERSION_2) + .version = _LINUX_CAPABILITY_VERSION_2, +#elif defined(_LINUX_CAPABILITY_VERSION_1) + .version = _LINUX_CAPABILITY_VERSION_1, +#else + .version = _LINUX_CAPABILITY_VERSION, +#endif + }; + if (capset(&header, this->caps) != 0) + { + DBG1(DBG_LIB, "dropping capabilities failed: %s", strerror(errno)); + return FALSE; + } +#endif /* CAPABILITIES_NATIVE */ +#ifdef CAPABILITIES + DBG1(DBG_LIB, "dropped capabilities, running as uid %u, gid %u", + this->uid, this->gid); +#endif /* CAPABILITIES */ + return TRUE; +} + +METHOD(capabilities_t, destroy, void, + private_capabilities_t *this) +{ +#ifdef EMULATE_R_FUNCS + this->mutex->destroy(this->mutex); +#endif /* EMULATE_R_FUNCS */ +#ifdef CAPABILITIES_LIBCAP + cap_free(this->caps); +#endif /* CAPABILITIES_LIBCAP */ + free(this); +} + +/** + * See header + */ +capabilities_t *capabilities_create() +{ + private_capabilities_t *this; + + INIT(this, + .public = { + .keep = _keep, + .get_uid = _get_uid, + .get_gid = _get_gid, + .set_uid = _set_uid, + .set_gid = _set_gid, + .resolve_uid = _resolve_uid, + .resolve_gid = _resolve_gid, + .drop = _drop, + .destroy = _destroy, + }, + ); + +#ifdef CAPABILITIES +#ifdef CAPABILITIES_LIBCAP + this->caps = cap_init(); +#endif /* CAPABILITIES_LIBCAP */ + if (lib->leak_detective) + { + keep(this, CAP_SYS_NICE); + } +#endif /* CAPABILITIES */ + +#ifdef EMULATE_R_FUNCS + this->mutex = mutex_create(MUTEX_TYPE_DEFAULT); +#endif /* EMULATE_R_FUNCS */ + + return &this->public; +} diff --git a/src/libstrongswan/utils/capabilities.h b/src/libstrongswan/utils/capabilities.h new file mode 100644 index 000000000..cd23cbf10 --- /dev/null +++ b/src/libstrongswan/utils/capabilities.h @@ -0,0 +1,107 @@ +/* + * Copyright (C) 2012 Martin Willi + * Copyright (C) 2012 revosec AG + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT 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 capabilities capabilities + * @{ @ingroup utils + */ + +#ifndef CAPABILITIES_H_ +#define CAPABILITIES_H_ + +#include <library.h> +#ifdef HAVE_SYS_CAPABILITY_H +# include <sys/capability.h> +#elif defined(CAPABILITIES_NATIVE) +# include <linux/capability.h> +#endif + +typedef struct capabilities_t capabilities_t; + +/** + * POSIX capability dropping abstraction layer. + */ +struct capabilities_t { + + /** + * Register a capability to keep while calling drop(). + * + * @param cap capability to keep + */ + void (*keep)(capabilities_t *this, u_int cap); + + /** + * Get the user ID set through set_uid/resolve_uid. + * + * @return currently set user ID + */ + uid_t (*get_uid)(capabilities_t *this); + + /** + * Get the group ID set through set_gid/resolve_gid. + * + * @return currently set group ID + */ + gid_t (*get_gid)(capabilities_t *this); + + /** + * Set the numerical user ID to use during rights dropping. + * + * @param uid user ID to use + */ + void (*set_uid)(capabilities_t *this, uid_t uid); + + /** + * Set the numerical group ID to use during rights dropping. + * + * @param gid group ID to use + */ + void (*set_gid)(capabilities_t *this, gid_t gid); + + /** + * Resolve a username and set the user ID accordingly. + * + * @param username username get the uid for + * @return TRUE if username resolved and uid set + */ + bool (*resolve_uid)(capabilities_t *this, char *username); + + /** + * Resolve a groupname and set the group ID accordingly. + * + * @param groupname groupname to get the gid for + * @return TRUE if groupname resolved and gid set + */ + bool (*resolve_gid)(capabilities_t *this, char *groupname); + + /** + * Drop all capabilities not previously passed to keep(), switch to UID/GID. + * + * @return TRUE if capability drop successful + */ + bool (*drop)(capabilities_t *this); + + /** + * Destroy a capabilities_t. + */ + void (*destroy)(capabilities_t *this); +}; + +/** + * Create a capabilities instance. + */ +capabilities_t *capabilities_create(); + +#endif /** CAPABILITIES_H_ @}*/ diff --git a/src/libstrongswan/utils/enumerator.c b/src/libstrongswan/utils/enumerator.c index fb461b448..53c94f9dd 100644 --- a/src/libstrongswan/utils/enumerator.c +++ b/src/libstrongswan/utils/enumerator.c @@ -121,7 +121,7 @@ static bool enumerate_dir_enum(dir_enum_t *this, char **relative, /** * See header */ -enumerator_t* enumerator_create_directory(char *path) +enumerator_t* enumerator_create_directory(const char *path) { int len; dir_enum_t *this = malloc_thing(dir_enum_t); @@ -168,9 +168,9 @@ typedef struct { /** current position */ char *pos; /** separater chars */ - char *sep; + const char *sep; /** trim chars */ - char *trim; + const char *trim; } token_enum_t; /** @@ -187,7 +187,8 @@ static void destroy_token_enum(token_enum_t *this) */ static bool enumerate_token_enum(token_enum_t *this, char **token) { - char *pos = NULL, *tmp, *sep, *trim; + const char *sep, *trim; + char *pos = NULL, *tmp; bool last = FALSE; /* trim leading characters/separators */ @@ -303,7 +304,8 @@ static bool enumerate_token_enum(token_enum_t *this, char **token) /** * See header */ -enumerator_t* enumerator_create_token(char *string, char *sep, char *trim) +enumerator_t* enumerator_create_token(const char *string, const char *sep, + const char *trim) { token_enum_t *enumerator = malloc_thing(token_enum_t); diff --git a/src/libstrongswan/utils/enumerator.h b/src/libstrongswan/utils/enumerator.h index 12b5712ae..8c3d70173 100644 --- a/src/libstrongswan/utils/enumerator.h +++ b/src/libstrongswan/utils/enumerator.h @@ -93,7 +93,7 @@ enumerator_t *enumerator_create_single(void *item, void (*cleanup)(void *item)); * @param path path of the directory * @return the directory enumerator, NULL on failure */ -enumerator_t* enumerator_create_directory(char *path); +enumerator_t* enumerator_create_directory(const char *path); /** * Create an enumerator over tokens of a string. @@ -106,7 +106,8 @@ enumerator_t* enumerator_create_directory(char *path); * @param trim characters to trim from tokens * @return enumerator over char* tokens */ -enumerator_t* enumerator_create_token(char *string, char *sep, char *trim); +enumerator_t* enumerator_create_token(const char *string, const char *sep, + const char *trim); /** * Creates an enumerator which enumerates over enumerated enumerators :-). diff --git a/src/libstrongswan/utils/hashtable.c b/src/libstrongswan/utils/hashtable.c index 33f645170..d181d8ec8 100644 --- a/src/libstrongswan/utils/hashtable.c +++ b/src/libstrongswan/utils/hashtable.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2008-2011 Tobias Brunner + * Copyright (C) 2008-2012 Tobias Brunner * Hochschule fuer Technik Rapperswil * * This program is free software; you can redistribute it and/or modify it @@ -251,16 +251,21 @@ METHOD(hashtable_t, put, void*, return old_value; } -METHOD(hashtable_t, get, void*, - private_hashtable_t *this, void *key) +static void *get_internal(private_hashtable_t *this, void *key, + hashtable_equals_t equals) { void *value = NULL; pair_t *pair; + if (!this->count) + { /* no need to calculate the hash */ + return NULL; + } + pair = this->table[this->hash(key) & this->mask]; while (pair) { - if (this->equals(key, pair->key)) + if (equals(key, pair->key)) { value = pair->value; break; @@ -270,6 +275,18 @@ METHOD(hashtable_t, get, void*, return value; } +METHOD(hashtable_t, get, void*, + private_hashtable_t *this, void *key) +{ + return get_internal(this, key, this->equals); +} + +METHOD(hashtable_t, get_match, void*, + private_hashtable_t *this, void *key, hashtable_equals_t match) +{ + return get_internal(this, key, match); +} + METHOD(hashtable_t, remove_, void*, private_hashtable_t *this, void *key) { @@ -409,6 +426,7 @@ hashtable_t *hashtable_create(hashtable_hash_t hash, hashtable_equals_t equals, .public = { .put = _put, .get = _get, + .get_match = _get_match, .remove = _remove_, .remove_at = (void*)_remove_at, .get_count = _get_count, diff --git a/src/libstrongswan/utils/hashtable.h b/src/libstrongswan/utils/hashtable.h index 27aca9b68..0a21ca373 100644 --- a/src/libstrongswan/utils/hashtable.h +++ b/src/libstrongswan/utils/hashtable.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2008-2010 Tobias Brunner + * Copyright (C) 2008-2012 Tobias Brunner * Hochschule fuer Technik Rapperswil * * This program is free software; you can redistribute it and/or modify it @@ -78,6 +78,22 @@ struct hashtable_t { void *(*get) (hashtable_t *this, void *key); /** + * Returns the value with a matching key, if the hash table contains such an + * entry, otherwise NULL is returned. + * + * Compared to get() the given match function is used to compare the keys + * for equality. The hash function does have to be deviced properly in + * order to make this work if the match function compares keys differently + * than the equals function provided to the constructor. This basically + * allows to enumerate all entries with the same hash value. + * + * @param key the key to match against + * @param match match function to be used when comparing keys + * @return the value, NULL if not found + */ + void *(*get_match) (hashtable_t *this, void *key, hashtable_equals_t match); + + /** * Removes the value with the given key from the hash table and returns the * removed value (or NULL if no such value existed). * diff --git a/src/libstrongswan/utils/host.c b/src/libstrongswan/utils/host.c index d3020a5d0..e17b6ad02 100644 --- a/src/libstrongswan/utils/host.c +++ b/src/libstrongswan/utils/host.c @@ -74,20 +74,16 @@ METHOD(host_t, get_sockaddr_len, socklen_t*, METHOD(host_t, is_anyaddr, bool, private_host_t *this) { + static const u_int8_t zeroes[IPV6_LEN]; + switch (this->address.sa_family) { case AF_INET: { - u_int8_t zeroes[IPV4_LEN]; - - memset(zeroes, 0, IPV4_LEN); return memeq(zeroes, &(this->address4.sin_addr.s_addr), IPV4_LEN); } case AF_INET6: { - u_int8_t zeroes[IPV6_LEN]; - - memset(zeroes, 0, IPV6_LEN); return memeq(zeroes, &(this->address6.sin6_addr.s6_addr), IPV6_LEN); } default: @@ -100,7 +96,7 @@ METHOD(host_t, is_anyaddr, bool, /** * Described in header. */ -int host_printf_hook(char *dst, size_t dstlen, printf_hook_spec_t *spec, +int host_printf_hook(printf_hook_data_t *data, printf_hook_spec_t *spec, const void *const *args) { private_host_t *this = *((private_host_t**)(args[0])); @@ -110,7 +106,7 @@ int host_printf_hook(char *dst, size_t dstlen, printf_hook_spec_t *spec, { snprintf(buffer, sizeof(buffer), "(null)"); } - else if (is_anyaddr(this)) + else if (is_anyaddr(this) && !spec->plus) { snprintf(buffer, sizeof(buffer), "%%any%s", this->address.sa_family == AF_INET6 ? "6" : ""); @@ -152,9 +148,9 @@ int host_printf_hook(char *dst, size_t dstlen, printf_hook_spec_t *spec, } if (spec->minus) { - return print_in_hook(dst, dstlen, "%-*s", spec->width, buffer); + return print_in_hook(data, "%-*s", spec->width, buffer); } - return print_in_hook(dst, dstlen, "%*s", spec->width, buffer); + return print_in_hook(data, "%*s", spec->width, buffer); } METHOD(host_t, get_address, chunk_t, @@ -430,13 +426,15 @@ host_t *host_create_from_sockaddr(sockaddr_t *sockaddr) { case AF_INET: { - memcpy(&this->address4, sockaddr, sizeof(struct sockaddr_in)); + memcpy(&this->address4, (struct sockaddr_in*)sockaddr, + sizeof(struct sockaddr_in)); this->socklen = sizeof(struct sockaddr_in); return &this->public; } case AF_INET6: { - memcpy(&this->address6, sockaddr, sizeof(struct sockaddr_in6)); + memcpy(&this->address6, (struct sockaddr_in6*)sockaddr, + sizeof(struct sockaddr_in6)); this->socklen = sizeof(struct sockaddr_in6); return &this->public; } diff --git a/src/libstrongswan/utils/host.h b/src/libstrongswan/utils/host.h index 0a1be6e47..a8b010544 100644 --- a/src/libstrongswan/utils/host.h +++ b/src/libstrongswan/utils/host.h @@ -155,7 +155,7 @@ struct host_t { * * @param string string of an address, such as "152.96.193.130" * @param port port number - * @return host_t, NULL if string not an address. + * @return host_t, NULL if string not an address. */ host_t *host_create_from_string(char *string, u_int16_t port); @@ -165,7 +165,7 @@ host_t *host_create_from_string(char *string, u_int16_t port); * @param string hostname to resolve * @param family family to prefer, 0 for first match * @param port port number - * @return host_t, NULL lookup failed + * @return host_t, NULL lookup failed */ host_t *host_create_from_dns(char *string, int family, u_int16_t port); @@ -174,10 +174,10 @@ host_t *host_create_from_dns(char *string, int family, u_int16_t port); * * If family is AF_UNSPEC, it is guessed using address.len. * - * @param family Address family, such as AF_INET or AF_INET6 + * @param family Address family, such as AF_INET or AF_INET6 * @param address address as chunk_t in network order * @param port port number - * @return host_t, NULL if family not supported/chunk invalid + * @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); @@ -185,7 +185,7 @@ host_t *host_create_from_chunk(int family, chunk_t address, u_int16_t port); * Constructor to create a host_t object from a sockaddr struct * * @param sockaddr sockaddr struct which contains family, address and port - * @return host_t, NULL if family not supported + * @return host_t, NULL if family not supported */ host_t *host_create_from_sockaddr(sockaddr_t *sockaddr); @@ -202,7 +202,7 @@ host_t *host_create_from_subnet(char *string, int *bits); * Create a host without an address, a "any" host. * * @param family family of the any host - * @return host_t, NULL if family not supported + * @return host_t, NULL if family not supported */ host_t *host_create_any(int family); @@ -212,8 +212,9 @@ host_t *host_create_any(int family); * Arguments are: * host_t *host * Use #-modifier to include port number + * Use +-modifier to force numeric representation (instead of e.g. %any) */ -int host_printf_hook(char *dst, size_t len, printf_hook_spec_t *spec, +int host_printf_hook(printf_hook_data_t *data, printf_hook_spec_t *spec, const void *const *args); #endif /** HOST_H_ @}*/ diff --git a/src/libstrongswan/utils/identification.c b/src/libstrongswan/utils/identification.c index 9f0007f78..2669c2da6 100644 --- a/src/libstrongswan/utils/identification.c +++ b/src/libstrongswan/utils/identification.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2009 Tobias Brunner + * Copyright (C) 2009-2012 Tobias Brunner * Copyright (C) 2005-2009 Martin Willi * Copyright (C) 2005 Jan Hutter * Hochschule fuer Technik Rapperswil @@ -310,7 +310,7 @@ static void dntoa(chunk_t dn, char *buf, size_t len) len -= written; chunk_printable(data, &printable, '?'); - written = snprintf(buf, len, "%.*s", printable.len, printable.ptr); + written = snprintf(buf, len, "%.*s", (int)printable.len, printable.ptr); chunk_free(&printable); if (written < 0 || written >= len) { @@ -414,14 +414,22 @@ static status_t atodn(char *src, chunk_t *dn) } break; case SEARCH_NAME: - if (*src != ' ' && *src != '=') + if (*src == ' ' || *src == '=') + { + break; + } + else if (*src != ',' && *src != '/') { name.ptr = src; name.len = 1; whitespace = 0; state = READ_NAME; + break; } - break; + name = chunk_empty; + whitespace = 0; + state = READ_NAME; + /* fall-through */ case READ_NAME: if (*src != ',' && *src != '/' && *src != '\0') { @@ -748,8 +756,8 @@ METHOD(identification_t, matches_dn, id_match_t, /** * Described in header. */ -int identification_printf_hook(char *dst, size_t len, printf_hook_spec_t *spec, - const void *const *args) +int identification_printf_hook(printf_hook_data_t *data, + printf_hook_spec_t *spec, const void *const *args) { private_identification_t *this = *((private_identification_t**)(args[0])); chunk_t proper; @@ -757,7 +765,7 @@ int identification_printf_hook(char *dst, size_t len, printf_hook_spec_t *spec, if (this == NULL) { - return print_in_hook(dst, len, "%*s", spec->width, "(null)"); + return print_in_hook(data, "%*s", spec->width, "(null)"); } switch (this->type) @@ -783,7 +791,7 @@ int identification_printf_hook(char *dst, size_t len, printf_hook_spec_t *spec, case ID_RFC822_ADDR: case ID_DER_ASN1_GN_URI: chunk_printable(this->encoded, &proper, '?'); - snprintf(buf, sizeof(buf), "%.*s", proper.len, proper.ptr); + snprintf(buf, sizeof(buf), "%.*s", (int)proper.len, proper.ptr); chunk_free(&proper); break; case ID_DER_ASN1_DN: @@ -796,8 +804,8 @@ int identification_printf_hook(char *dst, size_t len, printf_hook_spec_t *spec, if (chunk_printable(this->encoded, NULL, '?') && this->encoded.len != HASH_SIZE_SHA1) { /* fully printable, use ascii version */ - snprintf(buf, sizeof(buf), "%.*s", - this->encoded.len, this->encoded.ptr); + snprintf(buf, sizeof(buf), "%.*s", (int)this->encoded.len, + this->encoded.ptr); } else { /* not printable, hex dump */ @@ -813,9 +821,9 @@ int identification_printf_hook(char *dst, size_t len, printf_hook_spec_t *spec, } if (spec->minus) { - return print_in_hook(dst, len, "%-*s", spec->width, buf); + return print_in_hook(data, "%-*s", spec->width, buf); } - return print_in_hook(dst, len, "%*s", spec->width, buf); + return print_in_hook(data, "%*s", spec->width, buf); } METHOD(identification_t, clone_, identification_t*, @@ -1016,7 +1024,7 @@ identification_t * identification_create_from_data(chunk_t data) char buf[data.len + 1]; /* use string constructor */ - snprintf(buf, sizeof(buf), "%.*s", data.len, data.ptr); + snprintf(buf, sizeof(buf), "%.*s", (int)data.len, data.ptr); return identification_create_from_string(buf); } diff --git a/src/libstrongswan/utils/identification.h b/src/libstrongswan/utils/identification.h index 3978b23f3..024fcea4b 100644 --- a/src/libstrongswan/utils/identification.h +++ b/src/libstrongswan/utils/identification.h @@ -342,7 +342,7 @@ identification_t * identification_create_from_sockaddr(sockaddr_t *sockaddr); * Arguments are: * identification_t *identification */ -int identification_printf_hook(char *dst, size_t len, printf_hook_spec_t *spec, - const void *const *args); +int identification_printf_hook(printf_hook_data_t *data, + printf_hook_spec_t *spec, const void *const *args); #endif /** IDENTIFICATION_H_ @}*/ diff --git a/src/libstrongswan/utils/leak_detective.c b/src/libstrongswan/utils/leak_detective.c index 0a8789335..cface0538 100644 --- a/src/libstrongswan/utils/leak_detective.c +++ b/src/libstrongswan/utils/leak_detective.c @@ -188,6 +188,7 @@ static void uninstall_hooks() char *whitelist[] = { /* backtraces, including own */ "backtrace_create", + "safe_strerror", /* pthread stuff */ "pthread_create", "pthread_setspecific", @@ -224,6 +225,7 @@ char *whitelist[] = { "getpwent_r", "setpwent", "endpwent", + "getspnam_r", /* ignore dlopen, as we do not dlclose to get proper leak reports */ "dlopen", "dlerror", @@ -396,6 +398,35 @@ METHOD(leak_detective_t, report, void, } } +METHOD(leak_detective_t, set_state, bool, + private_leak_detective_t *this, bool enable) +{ + static struct sched_param oldparams; + static int oldpolicy; + struct sched_param params; + pthread_t thread_id; + + if (enable == installed) + { + return installed; + } + thread_id = pthread_self(); + if (enable) + { + install_hooks(); + pthread_setschedparam(thread_id, oldpolicy, &oldparams); + } + else + { + pthread_getschedparam(thread_id, &oldpolicy, &oldparams); + params.__sched_priority = sched_get_priority_max(SCHED_FIFO); + pthread_setschedparam(thread_id, SCHED_FIFO, ¶ms); + uninstall_hooks(); + } + installed = enable; + return !installed; +} + METHOD(leak_detective_t, usage, void, private_leak_detective_t *this, FILE *out) { @@ -444,7 +475,7 @@ void *malloc_hook(size_t bytes, const void *caller) hdr->magic = MEMORY_HEADER_MAGIC; hdr->bytes = bytes; - hdr->backtrace = backtrace_create(3); + hdr->backtrace = backtrace_create(2); tail->magic = MEMORY_TAIL_MAGIC; install_hooks(); @@ -513,7 +544,7 @@ void free_hook(void *ptr, const void *caller) /* memory was not allocated by our hooks */ fprintf(stderr, "freeing invalid memory (%p)", ptr); } - backtrace = backtrace_create(3); + backtrace = backtrace_create(2); backtrace->log(backtrace, stderr, TRUE); backtrace->destroy(backtrace); } @@ -569,15 +600,17 @@ void *realloc_hook(void *old, size_t bytes, const void *caller) if (hdr->magic != MEMORY_HEADER_MAGIC || tail->magic != MEMORY_TAIL_MAGIC) { - fprintf(stderr, "reallocating invalid memory (%p): " - "header magic 0x%x, tail magic 0x%x:\n", - old, hdr->magic, tail->magic); - backtrace = backtrace_create(3); + fprintf(stderr, "reallocating invalid memory (%p):\n" + "header magic 0x%x:\n", old, hdr->magic); + backtrace = backtrace_create(2); backtrace->log(backtrace, stderr, TRUE); backtrace->destroy(backtrace); } - /* clear tail magic, allocate, set tail magic */ - memset(&tail->magic, MEMORY_ALLOC_PATTERN, sizeof(tail->magic)); + else + { + /* 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; @@ -585,7 +618,7 @@ void *realloc_hook(void *old, size_t bytes, const void *caller) /* update statistics */ hdr->bytes = bytes; hdr->backtrace->destroy(hdr->backtrace); - hdr->backtrace = backtrace_create(3); + hdr->backtrace = backtrace_create(2); /* update header of linked list neighbours */ if (hdr->next) @@ -619,6 +652,7 @@ leak_detective_t *leak_detective_create() .public = { .report = _report, .usage = _usage, + .set_state = _set_state, .destroy = _destroy, }, ); diff --git a/src/libstrongswan/utils/leak_detective.h b/src/libstrongswan/utils/leak_detective.h index 8c80d2532..55d7e44d9 100644 --- a/src/libstrongswan/utils/leak_detective.h +++ b/src/libstrongswan/utils/leak_detective.h @@ -50,6 +50,14 @@ struct leak_detective_t { void (*usage)(leak_detective_t *this, FILE *out); /** + * Enable/disable leak detective hooks. + * + * @param TRUE to enable, FALSE to disable + * @return state active before calling set_state + */ + bool (*set_state)(leak_detective_t *this, bool enabled); + + /** * Destroy a leak_detective instance. */ void (*destroy)(leak_detective_t *this); diff --git a/src/libstrongswan/utils/linked_list.c b/src/libstrongswan/utils/linked_list.c index 59d416f2f..1ff80999b 100644 --- a/src/libstrongswan/utils/linked_list.c +++ b/src/libstrongswan/utils/linked_list.c @@ -16,6 +16,7 @@ */ #include <stdlib.h> +#include <stdarg.h> #include "linked_list.h" @@ -572,3 +573,43 @@ linked_list_t *linked_list_create() return &this->public; } + +/* + * See header. + */ +linked_list_t *linked_list_create_from_enumerator(enumerator_t *enumerator) +{ + linked_list_t *list; + void *item; + + list = linked_list_create(); + + while (enumerator->enumerate(enumerator, &item)) + { + list->insert_last(list, item); + } + enumerator->destroy(enumerator); + + return list; +} + +/* + * See header. + */ +linked_list_t *linked_list_create_with_items(void *item, ...) +{ + linked_list_t *list; + va_list args; + + list = linked_list_create(); + + va_start(args, item); + while (item) + { + list->insert_last(list, item); + item = va_arg(args, void*); + } + va_end(args); + + return list; +} diff --git a/src/libstrongswan/utils/linked_list.h b/src/libstrongswan/utils/linked_list.h index 293ca8661..1b5518480 100644 --- a/src/libstrongswan/utils/linked_list.h +++ b/src/libstrongswan/utils/linked_list.h @@ -299,4 +299,21 @@ struct linked_list_t { */ linked_list_t *linked_list_create(void); +/** + * Creates a linked list from an enumerator. + * + * @param enumerator enumerator over void*, gets destroyed + * @return linked_list_t object, containing enumerated values + */ +linked_list_t *linked_list_create_from_enumerator(enumerator_t *enumerator); + +/** + * Creates a linked list from a NULL terminated vararg list of items. + * + * @param first first item + * @param ... subsequent items, terminated by NULL + * @return linked_list_t object, containing passed items + */ +linked_list_t *linked_list_create_with_items(void *first, ...); + #endif /** LINKED_LIST_H_ @}*/ diff --git a/src/libstrongswan/utils/packet.c b/src/libstrongswan/utils/packet.c new file mode 100644 index 000000000..a2c329d60 --- /dev/null +++ b/src/libstrongswan/utils/packet.c @@ -0,0 +1,163 @@ +/* + * Copyright (C) 2012 Tobias Brunner + * Copyright (C) 2005-2006 Martin Willi + * Copyright (C) 2005 Jan Hutter + * Hochschule fuer Technik Rapperswil + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT 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 "packet.h" + +typedef struct private_packet_t private_packet_t; + +/** + * Private data of an packet_t object. + */ +struct private_packet_t { + + /** + * Public part of a packet_t object. + */ + packet_t public; + + /** + * source address + */ + host_t *source; + + /** + * destination address + */ + host_t *destination; + + /** + * message data + */ + chunk_t data; + + /** + * actual chunk returned from get_data, adjusted when skip_bytes is called + */ + chunk_t adjusted_data; +}; + +METHOD(packet_t, set_source, void, + private_packet_t *this, host_t *source) +{ + DESTROY_IF(this->source); + this->source = source; +} + +METHOD(packet_t, set_destination, void, + private_packet_t *this, host_t *destination) +{ + DESTROY_IF(this->destination); + this->destination = destination; +} + +METHOD(packet_t, get_source, host_t*, + private_packet_t *this) +{ + return this->source; +} + +METHOD(packet_t, get_destination, host_t*, + private_packet_t *this) +{ + return this->destination; +} + +METHOD(packet_t, get_data, chunk_t, + private_packet_t *this) +{ + return this->adjusted_data; +} + +METHOD(packet_t, set_data, void, + private_packet_t *this, chunk_t data) +{ + free(this->data.ptr); + this->adjusted_data = this->data = data; +} + +METHOD(packet_t, skip_bytes, void, + private_packet_t *this, size_t bytes) +{ + this->adjusted_data = chunk_skip(this->adjusted_data, bytes); +} + +METHOD(packet_t, destroy, void, + private_packet_t *this) +{ + DESTROY_IF(this->source); + DESTROY_IF(this->destination); + free(this->data.ptr); + free(this); +} + +METHOD(packet_t, clone_, packet_t*, + private_packet_t *this) +{ + packet_t *other; + + other = packet_create(); + if (this->destination) + { + other->set_destination(other, + this->destination->clone(this->destination)); + } + if (this->source) + { + other->set_source(other, this->source->clone(this->source)); + } + if (this->data.ptr) + { + other->set_data(other, chunk_clone(this->adjusted_data)); + } + return other; +} + +/** + * Described in header. + */ +packet_t *packet_create_from_data(host_t *src, host_t *dst, chunk_t data) +{ + private_packet_t *this; + + INIT(this, + .public = { + .set_data = _set_data, + .get_data = _get_data, + .set_source = _set_source, + .get_source = _get_source, + .set_destination = _set_destination, + .get_destination = _get_destination, + .skip_bytes = _skip_bytes, + .clone = _clone_, + .destroy = _destroy, + }, + .source = src, + .destination = dst, + .adjusted_data = data, + .data = data, + ); + + return &this->public; +} + +/* + * Described in header. + */ +packet_t *packet_create() +{ + return packet_create_from_data(NULL, NULL, chunk_empty); +} diff --git a/src/libstrongswan/utils/packet.h b/src/libstrongswan/utils/packet.h new file mode 100644 index 000000000..5c4440115 --- /dev/null +++ b/src/libstrongswan/utils/packet.h @@ -0,0 +1,121 @@ +/* + * Copyright (C) 2012 Tobias Brunner + * Copyright (C) 2005-2006 Martin Willi + * Copyright (C) 2005 Jan Hutter + * Hochschule fuer Technik Rapperswil + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT 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 packet packet + * @{ @ingroup utils + */ + +#ifndef PACKET_H_ +#define PACKET_H_ + +typedef struct packet_t packet_t; + +#include <library.h> +#include <utils/host.h> + +/** + * Abstraction of an IP/UDP-Packet, contains data, sender and receiver. + */ +struct packet_t { + + /** + * Set the source address. + * + * @param source address to set as source (gets owned) + */ + void (*set_source)(packet_t *packet, host_t *source); + + /** + * Set the destination address. + * + * @param source address to set as destination (gets owned) + */ + void (*set_destination)(packet_t *packet, host_t *destination); + + /** + * Get the source address. + * + * @return source address (internal data) + */ + host_t *(*get_source)(packet_t *packet); + + /** + * Get the destination address. + * + * @return destination address (internal data) + */ + host_t *(*get_destination)(packet_t *packet); + + /** + * Get the data from the packet. + * + * @return chunk containing the data (internal data) + */ + chunk_t (*get_data)(packet_t *packet); + + /** + * Set the data in the packet. + * + * @param data chunk with data to set (gets owned) + */ + void (*set_data)(packet_t *packet, chunk_t data); + + /** + * Increase the offset where the actual packet data starts. + * + * The total offset applies to future calls of get_data() and clone(). + * + * @note The offset is reset to 0 when set_data() is called. + * + * @param bytes the number of additional bytes to skip + */ + void (*skip_bytes)(packet_t *packet, size_t bytes); + + /** + * Clones a packet_t object. + * + * @note Data is cloned without skipped bytes. + * + * @param clone clone of the packet + */ + packet_t* (*clone)(packet_t *packet); + + /** + * Destroy the packet, freeing contained data. + */ + void (*destroy)(packet_t *packet); +}; + +/** + * Create an empty packet + * + * @return packet_t object + */ +packet_t *packet_create(); + +/** + * Create a packet from the supplied data + * + * @param src source address (gets owned) + * @param dst destination address (gets owned) + * @param data packet data (gets owned) + * @return packet_t object + */ +packet_t *packet_create_from_data(host_t *src, host_t *dst, chunk_t data); + +#endif /** PACKET_H_ @}*/ diff --git a/src/libstrongswan/utils/tun_device.c b/src/libstrongswan/utils/tun_device.c new file mode 100644 index 000000000..36f3359c0 --- /dev/null +++ b/src/libstrongswan/utils/tun_device.c @@ -0,0 +1,461 @@ +/* + * Copyright (C) 2012 Tobias Brunner + * Copyright (C) 2012 Giuliano Grassi + * Copyright (C) 2012 Ralf Sager + * Hochschule fuer Technik Rapperswil + * Copyright (C) 2012 Martin Willi + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT 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 <errno.h> +#include <fcntl.h> +#include <netinet/in.h> +#include <string.h> +#include <sys/ioctl.h> +#include <sys/types.h> +#include <sys/socket.h> +#include <sys/stat.h> +#include <unistd.h> +#include <net/if.h> + +#ifdef __APPLE__ +#include <net/if_utun.h> +#include <netinet/in_var.h> +#include <sys/kern_control.h> +#elif defined(__linux__) +#include <linux/if_tun.h> +#else +#include <net/if_tun.h> +#endif + +#include "tun_device.h" + +#include <library.h> +#include <debug.h> +#include <threading/thread.h> + +#define TUN_DEFAULT_MTU 1500 + +typedef struct private_tun_device_t private_tun_device_t; + +struct private_tun_device_t { + + /** + * Public interface + */ + tun_device_t public; + + /** + * The TUN device's file descriptor + */ + int tunfd; + + /** + * Name of the TUN device + */ + char if_name[IFNAMSIZ]; + + /** + * Socket used for ioctl() to set interface addr, ... + */ + int sock; + + /** + * The current MTU + */ + int mtu; +}; + +/** + * Set the sockaddr_t from the given netmask + */ +static void set_netmask(struct ifreq *ifr, int family, u_int8_t netmask) +{ + int len, bytes, bits; + char *target; + + switch (family) + { + case AF_INET: + { + struct sockaddr_in *addr = (struct sockaddr_in*)&ifr->ifr_addr; + addr->sin_family = AF_INET; + target = (char*)&addr->sin_addr; + len = 4; + break; + } + case AF_INET6: + { + struct sockaddr_in6 *addr = (struct sockaddr_in6*)&ifr->ifr_addr; + addr->sin6_family = AF_INET6; + target = (char*)&addr->sin6_addr; + len = 16; + break; + } + default: + return; + } + + bytes = (netmask + 7) / 8; + bits = (bytes * 8) - netmask; + + memset(target, 0xff, bytes); + memset(target + bytes, 0x00, len - bytes); + target[bytes - 1] = bits ? (u_int8_t)(0xff << bits) : 0xff; +} + +METHOD(tun_device_t, set_address, bool, + private_tun_device_t *this, host_t *addr, u_int8_t netmask) +{ + struct ifreq ifr; + int family; + + family = addr->get_family(addr); + if ((netmask > 32 && family == AF_INET) || netmask > 128) + { + DBG1(DBG_LIB, "failed to set address on %s: invalid netmask", + this->if_name); + return FALSE; + } + + memset(&ifr, 0, sizeof(ifr)); + strncpy(ifr.ifr_name, this->if_name, IFNAMSIZ); + memcpy(&ifr.ifr_addr, addr->get_sockaddr(addr), sizeof(sockaddr_t)); + + if (ioctl(this->sock, SIOCSIFADDR, &ifr) < 0) + { + DBG1(DBG_LIB, "failed to set address on %s: %s", + this->if_name, strerror(errno)); + return FALSE; + } +#ifdef __APPLE__ + if (ioctl(this->sock, SIOCSIFDSTADDR, &ifr) < 0) + { + DBG1(DBG_LIB, "failed to set dest address on %s: %s", + this->if_name, strerror(errno)); + return FALSE; + } +#endif /* __APPLE__ */ + + set_netmask(&ifr, family, netmask); + + if (ioctl(this->sock, SIOCSIFNETMASK, &ifr) < 0) + { + DBG1(DBG_LIB, "failed to set netmask on %s: %s", + this->if_name, strerror(errno)); + return FALSE; + } + return TRUE; +} + +METHOD(tun_device_t, up, bool, + private_tun_device_t *this) +{ + struct ifreq ifr; + + memset(&ifr, 0, sizeof(ifr)); + strncpy(ifr.ifr_name, this->if_name, IFNAMSIZ); + + if (ioctl(this->sock, SIOCGIFFLAGS, &ifr) < 0) + { + DBG1(DBG_LIB, "failed to get interface flags for %s: %s", this->if_name, + strerror(errno)); + return FALSE; + } + + ifr.ifr_flags |= IFF_RUNNING | IFF_UP; + + if (ioctl(this->sock, SIOCSIFFLAGS, &ifr) < 0) + { + DBG1(DBG_LIB, "failed to set interface flags on %s: %s", this->if_name, + strerror(errno)); + return FALSE; + } + return TRUE; +} + +METHOD(tun_device_t, set_mtu, bool, + private_tun_device_t *this, int mtu) +{ + struct ifreq ifr; + + memset(&ifr, 0, sizeof(ifr)); + strncpy(ifr.ifr_name, this->if_name, IFNAMSIZ); + ifr.ifr_mtu = mtu; + + if (ioctl(this->sock, SIOCSIFMTU, &ifr) < 0) + { + DBG1(DBG_LIB, "failed to set MTU on %s: %s", this->if_name, + strerror(errno)); + return FALSE; + } + this->mtu = mtu; + return TRUE; +} + +METHOD(tun_device_t, get_mtu, int, + private_tun_device_t *this) +{ + struct ifreq ifr; + + if (this->mtu > 0) + { + return this->mtu; + } + + memset(&ifr, 0, sizeof(ifr)); + strncpy(ifr.ifr_name, this->if_name, IFNAMSIZ); + this->mtu = TUN_DEFAULT_MTU; + + if (ioctl(this->sock, SIOCGIFMTU, &ifr) == 0) + { + this->mtu = ifr.ifr_mtu; + } + return this->mtu; +} + +METHOD(tun_device_t, get_name, char*, + private_tun_device_t *this) +{ + return this->if_name; +} + +METHOD(tun_device_t, write_packet, bool, + private_tun_device_t *this, chunk_t packet) +{ + ssize_t s; + + s = write(this->tunfd, packet.ptr, packet.len); + if (s < 0) + { + DBG1(DBG_LIB, "failed to write packet to TUN device %s: %s", + this->if_name, strerror(errno)); + return FALSE; + } + else if (s != packet.len) + { + return FALSE; + } + return TRUE; +} + +METHOD(tun_device_t, read_packet, bool, + private_tun_device_t *this, chunk_t *packet) +{ + ssize_t len; + fd_set set; + bool old; + + FD_ZERO(&set); + FD_SET(this->tunfd, &set); + + old = thread_cancelability(TRUE); + len = select(this->tunfd + 1, &set, NULL, NULL, NULL); + thread_cancelability(old); + + if (len < 0) + { + DBG1(DBG_LIB, "select on TUN device %s failed: %s", this->if_name, + strerror(errno)); + return FALSE; + } + /* FIXME: this is quite expensive for lots of small packets, copy from + * local buffer instead? */ + *packet = chunk_alloc(get_mtu(this)); + len = read(this->tunfd, packet->ptr, packet->len); + if (len < 0) + { + DBG1(DBG_LIB, "reading from TUN device %s failed: %s", this->if_name, + strerror(errno)); + chunk_free(packet); + return FALSE; + } + packet->len = len; + return TRUE; +} + +METHOD(tun_device_t, destroy, void, + private_tun_device_t *this) +{ + if (this->tunfd > 0) + { + close(this->tunfd); +#ifdef __FreeBSD__ + /* tun(4) says the following: "These network interfaces persist until + * the if_tun.ko module is unloaded, or until removed with the + * ifconfig(8) command." So simply closing the FD is not enough. */ + struct ifreq ifr; + + memset(&ifr, 0, sizeof(ifr)); + strncpy(ifr.ifr_name, this->if_name, IFNAMSIZ); + if (ioctl(this->sock, SIOCIFDESTROY, &ifr) < 0) + { + DBG1(DBG_LIB, "failed to destroy %s: %s", this->if_name, + strerror(errno)); + } +#endif /* __FreeBSD__ */ + } + if (this->sock > 0) + { + close(this->sock); + } + free(this); +} + +/** + * Initialize the tun device + */ +static bool init_tun(private_tun_device_t *this, const char *name_tmpl) +{ +#ifdef __APPLE__ + + struct ctl_info info; + struct sockaddr_ctl addr; + socklen_t size = IFNAMSIZ; + + memset(&info, 0, sizeof(info)); + memset(&addr, 0, sizeof(addr)); + + this->tunfd = socket(PF_SYSTEM, SOCK_DGRAM, SYSPROTO_CONTROL); + if (this->tunfd < 0) + { + DBG1(DBG_LIB, "failed to open tundevice PF_SYSTEM socket: %s", + strerror(errno)); + return FALSE; + } + + /* get a control identifier for the utun kernel extension */ + strncpy(info.ctl_name, UTUN_CONTROL_NAME, strlen(UTUN_CONTROL_NAME)); + if (ioctl(this->tunfd, CTLIOCGINFO, &info) < 0) + { + DBG1(DBG_LIB, "failed to ioctl tundevice: %s", strerror(errno)); + close(this->tunfd); + return FALSE; + } + + addr.sc_id = info.ctl_id; + addr.sc_len = sizeof(addr); + addr.sc_family = AF_SYSTEM; + addr.ss_sysaddr = AF_SYS_CONTROL; + /* allocate identifier dynamically */ + addr.sc_unit = 0; + + if (connect(this->tunfd, (struct sockaddr*)&addr, sizeof(addr)) < 0) + { + DBG1(DBG_LIB, "failed to connect tundevice: %s", strerror(errno)); + close(this->tunfd); + return FALSE; + } + if (getsockopt(this->tunfd, SYSPROTO_CONTROL, UTUN_OPT_IFNAME, + this->if_name, &size) < 0) + { + DBG1(DBG_LIB, "getting tundevice name failed: %s", strerror(errno)); + close(this->tunfd); + return FALSE; + } + return TRUE; + +#elif defined(IFF_TUN) + + struct ifreq ifr; + + strncpy(this->if_name, name_tmpl ?: "tun%d", IFNAMSIZ); + this->if_name[IFNAMSIZ-1] = '\0'; + + this->tunfd = open("/dev/net/tun", O_RDWR); + if (this->tunfd < 0) + { + DBG1(DBG_LIB, "failed to open /dev/net/tun: %s", strerror(errno)); + return FALSE; + } + + memset(&ifr, 0, sizeof(ifr)); + + /* TUN device, no packet info */ + ifr.ifr_flags = IFF_TUN | IFF_NO_PI; + + strncpy(ifr.ifr_name, this->if_name, IFNAMSIZ); + if (ioctl(this->tunfd, TUNSETIFF, (void*)&ifr) < 0) + { + DBG1(DBG_LIB, "failed to configure TUN device: %s", strerror(errno)); + close(this->tunfd); + return FALSE; + } + strncpy(this->if_name, ifr.ifr_name, IFNAMSIZ); + return TRUE; + +#else /* !IFF_TUN */ + + /* this works on FreeBSD and might also work on Linux with older TUN + * driver versions (no IFF_TUN) */ + char devname[IFNAMSIZ]; + int i; + + if (name_tmpl) + { + DBG1(DBG_LIB, "arbitrary naming of TUN devices is not supported"); + } + + for (i = 0; i < 256; i++) + { + snprintf(devname, IFNAMSIZ, "/dev/tun%d", i); + this->tunfd = open(devname, O_RDWR); + if (this->tunfd > 0) + { /* for ioctl(2) calls only the interface name is used */ + snprintf(this->if_name, IFNAMSIZ, "tun%d", i); + break; + } + DBG1(DBG_LIB, "failed to open %s: %s", this->if_name, strerror(errno)); + } + return this->tunfd > 0; + +#endif /* !__APPLE__ */ +} + +/* + * Described in header + */ +tun_device_t *tun_device_create(const char *name_tmpl) +{ + private_tun_device_t *this; + + INIT(this, + .public = { + .read_packet = _read_packet, + .write_packet = _write_packet, + .get_mtu = _get_mtu, + .set_mtu = _set_mtu, + .get_name = _get_name, + .set_address = _set_address, + .up = _up, + .destroy = _destroy, + }, + .tunfd = -1, + .sock = -1, + ); + + if (!init_tun(this, name_tmpl)) + { + free(this); + return NULL; + } + DBG1(DBG_LIB, "created TUN device: %s", this->if_name); + + this->sock = socket(AF_INET, SOCK_DGRAM, 0); + if (this->sock < 0) + { + DBG1(DBG_LIB, "failed to open socket to configure TUN device"); + destroy(this); + return NULL; + } + return &this->public; +} diff --git a/src/libstrongswan/utils/tun_device.h b/src/libstrongswan/utils/tun_device.h new file mode 100644 index 000000000..71af0386b --- /dev/null +++ b/src/libstrongswan/utils/tun_device.h @@ -0,0 +1,112 @@ +/* + * Copyright (C) 2012 Tobias Brunner + * Copyright (C) 2012 Giuliano Grassi + * Copyright (C) 2012 Ralf Sager + * Hochschule fuer Technik Rapperswil + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT 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 tun_device tun_device + * @{ @ingroup utils + */ + +#ifndef TUN_DEVICE_H_ +#define TUN_DEVICE_H_ + +#include <library.h> +#include <utils/host.h> + +typedef struct tun_device_t tun_device_t; + +/** + * Class to create TUN devices + * + * Creating such a device requires the CAP_NET_ADMIN capability. + * + * @note The implementation is currently very Linux specific + */ +struct tun_device_t { + + /** + * Read a packet from the TUN device + * + * @note This call blocks until a packet is available. It is a thread + * cancellation point. + * + * @param packet the packet read from the device + * @return TRUE if successful + */ + bool (*read_packet)(tun_device_t *this, chunk_t *packet); + + /** + * Write a packet to the TUN device + * + * @param packet the packet to write to the TUN device + * @return TRUE if successful + */ + bool (*write_packet)(tun_device_t *this, chunk_t packet); + + /** + * Set the IP address of the device + * + * @param addr the desired interface address + * @param netmask the netmask to use + * @return TRUE if operation successful + */ + bool (*set_address)(tun_device_t *this, host_t *addr, u_int8_t netmask); + + /** + * Bring the TUN device up + * + * @return TRUE if operation successful + */ + bool (*up)(tun_device_t *this); + + /** + * Set the MTU for this TUN device + * + * @param mtu new MTU + * @return TRUE if operation successful + */ + bool (*set_mtu)(tun_device_t *this, int mtu); + + /** + * Get the current MTU for this TUN device + * + * @return current MTU + */ + int (*get_mtu)(tun_device_t *this); + + /** + * Get the interface name of this device + * + * @return interface name + */ + char *(*get_name)(tun_device_t *this); + + /** + * Destroy a tun_device_t + */ + void (*destroy)(tun_device_t *this); + +}; + +/** + * Create a TUN device using the given name template. + * + * @param name_tmpl name template, defaults to "tun%d" if not given + * @return TUN device + */ +tun_device_t *tun_device_create(const char *name_tmpl); + +#endif /** TUN_DEVICE_H_ @}*/ |