[Pkg-swan-devel] [strongswan] 07/14: New upstream version 5.6.0

Yves-Alexis Perez corsac at moszumanska.debian.org
Sun Sep 3 13:23:48 UTC 2017


This is an automated email from the git hooks/post-receive script.

corsac pushed a commit to branch master
in repository strongswan.

commit 11d6b62db969bdd808d0f56706cb18f113927a31
Author: Yves-Alexis Perez <corsac at corsac.net>
Date:   Fri Sep 1 17:21:25 2017 +0200

    New upstream version 5.6.0
---
 Android.common.mk                                  |    2 +-
 Makefile.in                                        |    8 +-
 NEWS                                               |   44 +-
 conf/Makefile.am                                   |    9 +-
 conf/Makefile.in                                   |   17 +-
 conf/format-options.py                             |   42 +-
 conf/options/charon.conf                           |    2 +-
 conf/options/charon.opt                            |    2 +-
 conf/options/imcv.conf                             |   17 +
 conf/options/imcv.opt                              |    9 +
 conf/options/sw-collector.conf                     |   31 +
 conf/options/sw-collector.opt                      |   31 +
 conf/options/swanctl.conf                          |    3 +
 conf/options/swanctl.opt                           |    5 +-
 conf/plugins/curl.conf                             |   12 +
 conf/plugins/curl.opt                              |    3 +
 conf/plugins/eap-aka-3ggp2.opt                     |    1 -
 .../{eap-aka-3ggp2.conf => eap-aka-3gpp.conf}      |    4 +-
 conf/plugins/eap-aka-3gpp.opt                      |    3 +
 .../{eap-aka-3ggp2.conf => eap-aka-3gpp2.conf}     |    4 +-
 conf/plugins/eap-aka-3gpp2.opt                     |    4 +
 conf/plugins/imc-swid.opt                          |    7 +-
 .../plugins/{eap-aka-3ggp2.conf => imc-swima.conf} |    4 +-
 conf/plugins/imc-swima.opt                         |   21 +
 .../plugins/{eap-aka-3ggp2.conf => imv-swima.conf} |    4 +-
 conf/plugins/imv-swima.opt                         |    5 +
 conf/strongswan.conf.5.main                        |  101 +-
 config.h.in                                        |    9 +
 configure                                          |  459 ++++++--
 configure.ac                                       |   77 +-
 fuzz/Makefile.in                                   |    8 +-
 init/Makefile.in                                   |    8 +-
 init/systemd-swanctl/Makefile.in                   |    8 +-
 init/systemd/Makefile.in                           |    8 +-
 man/Makefile.in                                    |    8 +-
 man/ipsec.conf.5.in                                |    5 +-
 scripts/Makefile.in                                |    8 +-
 src/Makefile.am                                    |    4 +
 src/Makefile.in                                    |   17 +-
 src/_copyright/Makefile.in                         |    8 +-
 src/_updown/Makefile.in                            |    8 +-
 src/aikgen/Makefile.in                             |    8 +-
 src/charon-cmd/Makefile.in                         |    8 +-
 src/charon-nm/Makefile.in                          |    8 +-
 src/charon-svc/Makefile.in                         |    8 +-
 src/charon-systemd/Makefile.in                     |    8 +-
 src/charon-tkm/Makefile.in                         |    8 +-
 src/charon-tkm/src/ees/ees_callbacks.c             |    1 +
 src/charon-tkm/src/tkm/tkm_kernel_ipsec.c          |   71 +-
 src/charon-tkm/src/tkm/tkm_kernel_sad.c            |   86 +-
 src/charon-tkm/src/tkm/tkm_kernel_sad.h            |   18 +-
 src/charon-tkm/tests/kernel_sad_tests.c            |   38 +-
 src/charon/Makefile.in                             |    8 +-
 src/checksum/Makefile.am                           |    8 +
 src/checksum/Makefile.in                           |   13 +-
 src/conftest/Makefile.in                           |    8 +-
 src/dumm/Makefile.am                               |    9 +-
 src/dumm/Makefile.in                               |   64 +-
 src/dumm/ext/dumm.c                                |    2 +
 src/dumm/irdumm.c                                  |    2 +
 src/include/Makefile.in                            |    8 +-
 src/ipsec/Makefile.in                              |    8 +-
 src/ipsec/_ipsec.8                                 |    2 +-
 src/ipsec/_ipsec.in                                |    2 +-
 src/libcharon/Android.mk                           |    2 +
 src/libcharon/Makefile.am                          |    7 +
 src/libcharon/Makefile.in                          |  234 ++--
 src/libcharon/bus/bus.c                            |    5 +-
 src/libcharon/config/peer_cfg.c                    |   30 +-
 src/libcharon/encoding/generator.c                 |    2 +-
 src/libcharon/encoding/message.h                   |    8 +-
 src/libcharon/encoding/payloads/encodings.h        |    2 +-
 .../encoding/payloads/proposal_substructure.c      |    2 +-
 src/libcharon/kernel/kernel_interface.h            |    2 +
 src/libcharon/plugins/addrblock/Makefile.in        |    8 +-
 src/libcharon/plugins/android_dns/Makefile.in      |    8 +-
 src/libcharon/plugins/android_log/Makefile.in      |    8 +-
 src/libcharon/plugins/attr/Makefile.in             |    8 +-
 src/libcharon/plugins/attr_sql/Makefile.in         |    8 +-
 src/libcharon/plugins/bypass_lan/Makefile.in       |    8 +-
 src/libcharon/plugins/certexpire/Makefile.in       |    8 +-
 src/libcharon/plugins/connmark/Makefile.in         |    8 +-
 src/libcharon/plugins/coupling/Makefile.in         |    8 +-
 src/libcharon/plugins/dhcp/Makefile.in             |    8 +-
 src/libcharon/plugins/dnscert/Makefile.in          |    8 +-
 src/libcharon/plugins/duplicheck/Makefile.in       |    8 +-
 src/libcharon/plugins/eap_aka/Makefile.in          |    8 +-
 src/libcharon/plugins/eap_aka_3gpp/Makefile.am     |   22 +
 .../{eap_sim_file => eap_aka_3gpp}/Makefile.in     |   71 +-
 .../plugins/eap_aka_3gpp/eap_aka_3gpp_card.c       |  208 ++++
 .../plugins/eap_aka_3gpp/eap_aka_3gpp_card.h       |   75 ++
 .../plugins/eap_aka_3gpp/eap_aka_3gpp_functions.c  |  364 +++++++
 .../plugins/eap_aka_3gpp/eap_aka_3gpp_functions.h  |  172 +++
 .../plugins/eap_aka_3gpp/eap_aka_3gpp_plugin.c     |  164 +++
 .../plugins/eap_aka_3gpp/eap_aka_3gpp_plugin.h     |   89 ++
 .../plugins/eap_aka_3gpp/eap_aka_3gpp_provider.c   |  205 ++++
 .../plugins/eap_aka_3gpp/eap_aka_3gpp_provider.h   |   74 ++
 src/libcharon/plugins/eap_aka_3gpp2/Makefile.in    |    8 +-
 src/libcharon/plugins/eap_dynamic/Makefile.in      |    8 +-
 src/libcharon/plugins/eap_gtc/Makefile.in          |    8 +-
 src/libcharon/plugins/eap_identity/Makefile.in     |    8 +-
 src/libcharon/plugins/eap_md5/Makefile.in          |    8 +-
 src/libcharon/plugins/eap_mschapv2/Makefile.in     |    8 +-
 src/libcharon/plugins/eap_peap/Makefile.in         |    8 +-
 src/libcharon/plugins/eap_radius/Makefile.in       |    8 +-
 .../plugins/eap_radius/eap_radius_accounting.c     |    2 +-
 src/libcharon/plugins/eap_sim/Makefile.in          |    8 +-
 src/libcharon/plugins/eap_sim_file/Makefile.in     |    8 +-
 src/libcharon/plugins/eap_sim_pcsc/Makefile.in     |    8 +-
 .../plugins/eap_simaka_pseudonym/Makefile.in       |    8 +-
 .../plugins/eap_simaka_reauth/Makefile.in          |    8 +-
 src/libcharon/plugins/eap_simaka_sql/Makefile.in   |    8 +-
 src/libcharon/plugins/eap_tls/Makefile.in          |    8 +-
 src/libcharon/plugins/eap_tnc/Makefile.in          |    8 +-
 src/libcharon/plugins/eap_ttls/Makefile.in         |    8 +-
 src/libcharon/plugins/error_notify/Makefile.in     |    8 +-
 .../plugins/error_notify/error_notify_socket.c     |    3 +-
 src/libcharon/plugins/ext_auth/Makefile.in         |    8 +-
 src/libcharon/plugins/farp/Makefile.in             |    8 +-
 src/libcharon/plugins/farp/farp_listener.c         |    1 +
 src/libcharon/plugins/forecast/Makefile.in         |    8 +-
 src/libcharon/plugins/ha/Makefile.in               |    8 +-
 src/libcharon/plugins/ipseckey/Makefile.in         |    8 +-
 src/libcharon/plugins/kernel_iph/Makefile.in       |    8 +-
 src/libcharon/plugins/kernel_libipsec/Makefile.in  |    8 +-
 src/libcharon/plugins/kernel_netlink/Makefile.in   |    8 +-
 .../plugins/kernel_netlink/kernel_netlink_ipsec.c  |   14 +-
 .../plugins/kernel_netlink/kernel_netlink_shared.c |   14 +-
 src/libcharon/plugins/kernel_pfkey/Makefile.in     |    8 +-
 src/libcharon/plugins/kernel_pfroute/Makefile.in   |    8 +-
 .../plugins/kernel_pfroute/kernel_pfroute_net.c    |    4 +-
 src/libcharon/plugins/kernel_wfp/Makefile.in       |    8 +-
 src/libcharon/plugins/led/Makefile.in              |    8 +-
 src/libcharon/plugins/load_tester/Makefile.in      |    8 +-
 src/libcharon/plugins/lookip/Makefile.in           |    8 +-
 src/libcharon/plugins/medcli/Makefile.in           |    8 +-
 src/libcharon/plugins/medsrv/Makefile.in           |    8 +-
 src/libcharon/plugins/osx_attr/Makefile.in         |    8 +-
 src/libcharon/plugins/p_cscf/Makefile.in           |    8 +-
 src/libcharon/plugins/radattr/Makefile.in          |    8 +-
 src/libcharon/plugins/resolve/Makefile.in          |    8 +-
 src/libcharon/plugins/smp/Makefile.in              |    8 +-
 src/libcharon/plugins/socket_default/Makefile.in   |    8 +-
 src/libcharon/plugins/socket_dynamic/Makefile.in   |    8 +-
 src/libcharon/plugins/socket_win/Makefile.in       |    8 +-
 src/libcharon/plugins/sql/Makefile.in              |    8 +-
 src/libcharon/plugins/sql/sql_config.c             |   93 +-
 src/libcharon/plugins/sql/sql_cred.c               |   10 +-
 src/libcharon/plugins/stroke/Makefile.in           |    8 +-
 src/libcharon/plugins/stroke/stroke_config.c       |   27 +-
 src/libcharon/plugins/systime_fix/Makefile.in      |    8 +-
 src/libcharon/plugins/tnc_ifmap/Makefile.in        |    8 +-
 src/libcharon/plugins/tnc_pdp/Makefile.in          |    8 +-
 src/libcharon/plugins/uci/Makefile.in              |    8 +-
 src/libcharon/plugins/unity/Makefile.in            |    8 +-
 src/libcharon/plugins/updown/Makefile.in           |    8 +-
 src/libcharon/plugins/vici/Makefile.in             |    8 +-
 src/libcharon/plugins/vici/perl/Makefile.in        |    8 +-
 src/libcharon/plugins/vici/python/Makefile.in      |    8 +-
 src/libcharon/plugins/vici/ruby/Makefile.in        |   10 +-
 src/libcharon/plugins/vici/ruby/lib/vici.rb        |    2 +-
 src/libcharon/plugins/whitelist/Makefile.in        |    8 +-
 src/libcharon/plugins/xauth_eap/Makefile.in        |    8 +-
 src/libcharon/plugins/xauth_generic/Makefile.in    |    8 +-
 src/libcharon/plugins/xauth_noauth/Makefile.in     |    8 +-
 src/libcharon/plugins/xauth_pam/Makefile.in        |    8 +-
 src/libcharon/sa/child_sa.c                        |  143 ++-
 src/libcharon/sa/child_sa.h                        |   34 +-
 src/libcharon/sa/ikev1/task_manager_v1.c           |    6 +-
 src/libcharon/sa/ikev1/tasks/quick_mode.c          |    7 +-
 src/libcharon/sa/ikev2/keymat_v2.c                 |    7 +-
 src/libcharon/sa/ikev2/tasks/child_create.c        |   81 +-
 src/libcharon/sa/ikev2/tasks/child_delete.c        |    1 -
 src/libcharon/sa/ikev2/tasks/child_rekey.c         |   62 +-
 src/libcharon/sa/trap_manager.c                    |   59 +-
 src/libcharon/tests/Makefile.in                    |    8 +-
 src/libcharon/tests/suites/test_child_rekey.c      |   82 +-
 src/libcharon/tests/utils/exchange_test_asserts.h  |   12 +-
 src/libcharon/tests/utils/sa_asserts.h             |    3 +-
 src/libfast/Makefile.in                            |    8 +-
 src/libimcv/Android.mk                             |   11 +
 src/libimcv/Makefile.am                            |   41 +-
 src/libimcv/Makefile.in                            |  361 ++++++-
 src/libimcv/ietf/ietf_attr.c                       |   37 +-
 src/libimcv/ietf/ietf_attr.h                       |   18 +-
 src/libimcv/ietf/ietf_attr_pa_tnc_error.c          |   22 +-
 src/libimcv/ietf/ietf_attr_pa_tnc_error.h          |   21 +-
 .../swima/ietf_swima_attr_req.c}                   |  171 ++-
 src/libimcv/ietf/swima/ietf_swima_attr_req.h       |   96 ++
 src/libimcv/ietf/swima/ietf_swima_attr_sw_ev.c     |  482 +++++++++
 src/libimcv/ietf/swima/ietf_swima_attr_sw_ev.h     |  111 ++
 src/libimcv/ietf/swima/ietf_swima_attr_sw_inv.c    |  438 ++++++++
 src/libimcv/ietf/swima/ietf_swima_attr_sw_inv.h    |  112 ++
 src/libimcv/imcv.h                                 |    3 +
 src/libimcv/imcv_tests.h                           |    4 +-
 src/libimcv/imv/data.sql                           |  118 ++-
 src/libimcv/imv/imv_policy_manager.c               |   25 +
 src/libimcv/imv/tables.sql                         |   57 +-
 src/libimcv/pa_tnc/pa_tnc_msg.c                    |    5 +-
 src/libimcv/plugins/imc_attestation/Makefile.in    |    8 +-
 src/libimcv/plugins/imc_hcd/Makefile.in            |    8 +-
 src/libimcv/plugins/imc_os/Makefile.in             |    8 +-
 src/libimcv/plugins/imc_scanner/Makefile.in        |    8 +-
 src/libimcv/plugins/imc_swid/Makefile.am           |   17 +-
 src/libimcv/plugins/imc_swid/Makefile.in           |   86 +-
 src/libimcv/plugins/imc_swid/imc_swid.c            |   13 +-
 .../strongswan.org__strongSwan-5-6-0.swidtag       |   11 +
 ...ag.in => strongswan.org__strongSwan.swidtag.in} |    9 +-
 src/libimcv/plugins/imc_swima/Makefile.am          |   33 +
 .../plugins/{imc_swid => imc_swima}/Makefile.in    |  127 +--
 .../{imc_swid/imc_swid.c => imc_swima/imc_swima.c} |  225 ++--
 src/libimcv/plugins/imc_swima/imc_swima_state.c    |  176 +++
 src/libimcv/plugins/imc_swima/imc_swima_state.h    |   51 +
 .../strongswan.org__strongSwan-5-6-0.swidtag       |   11 +
 .../strongswan.org__strongSwan.swidtag.in}         |    9 +-
 src/libimcv/plugins/imc_test/Makefile.in           |    8 +-
 src/libimcv/plugins/imv_attestation/Makefile.in    |    8 +-
 src/libimcv/plugins/imv_attestation/attest_db.c    |  239 +++--
 src/libimcv/plugins/imv_attestation/attest_usage.c |    7 +-
 src/libimcv/plugins/imv_hcd/Makefile.in            |    8 +-
 src/libimcv/plugins/imv_os/Makefile.in             |    8 +-
 src/libimcv/plugins/imv_scanner/Makefile.in        |    8 +-
 src/libimcv/plugins/imv_swid/Makefile.am           |    3 +-
 src/libimcv/plugins/imv_swid/Makefile.in           |   14 +-
 src/libimcv/plugins/imv_swid/imv_swid_agent.c      |   14 +-
 src/libimcv/plugins/imv_swid/imv_swid_rest.c       |  124 ---
 src/libimcv/plugins/imv_swid/imv_swid_state.c      |   14 +-
 .../plugins/{imv_swid => imv_swima}/Makefile.am    |   13 +-
 .../plugins/{imv_swid => imv_swima}/Makefile.in    |   54 +-
 .../imv_swima/imv_swima.c}                         |   11 +-
 .../imv_swima_agent.c}                             |  429 +++++---
 .../imv_swima/imv_swima_agent.h}                   |   23 +-
 .../imv_swima_state.c}                             |  222 ++--
 src/libimcv/plugins/imv_swima/imv_swima_state.h    |  153 +++
 src/libimcv/plugins/imv_test/Makefile.in           |    8 +-
 src/libimcv/pts/components/ita/ita_comp_ima.c      |    9 +-
 src/libimcv/pts/pts_database.c                     |   27 +-
 src/libimcv/rest/rest.c                            |  167 +++
 .../imv_swid/imv_swid_rest.h => rest/rest.h}       |   43 +-
 src/libimcv/suites/test_imcv_swima.c               | 1117 ++++++++++++++++++++
 src/libimcv/swid/swid_inventory.c                  |  302 ++----
 src/libimcv/swid/swid_inventory.h                  |    5 +-
 src/libimcv/swid_gen/swid_gen.c                    |  291 +++++
 src/libimcv/swid_gen/swid_gen.h                    |   69 ++
 src/libimcv/swid_gen/swid_gen_info.c               |  174 +++
 src/libimcv/swid_gen/swid_gen_info.h               |   69 ++
 src/libimcv/swima/swima_collector.c                |  592 +++++++++++
 src/libimcv/swima/swima_collector.h                |   68 ++
 .../{imcv_tests.h => swima/swima_data_model.c}     |   15 +-
 .../{imcv_tests.h => swima/swima_data_model.h}     |   25 +-
 src/libimcv/swima/swima_error.c                    |   77 ++
 src/libimcv/swima/swima_error.h                    |   43 +
 src/libimcv/swima/swima_event.c                    |  124 +++
 src/libimcv/swima/swima_event.h                    |   87 ++
 src/libimcv/swima/swima_events.c                   |  155 +++
 src/libimcv/swima/swima_events.h                   |  106 ++
 src/libimcv/swima/swima_inventory.c                |  140 +++
 src/libimcv/swima/swima_inventory.h                |   99 ++
 src/libimcv/swima/swima_record.c                   |  174 +++
 src/libimcv/swima/swima_record.h                   |  115 ++
 src/libimcv/tcg/swid/tcg_swid_attr_req.c           |    4 +-
 src/libimcv/tcg/swid/tcg_swid_attr_req.h           |    6 +-
 src/libipsec/Makefile.in                           |    8 +-
 src/libipsec/tests/Makefile.in                     |    8 +-
 src/libpttls/Makefile.in                           |    8 +-
 src/libradius/Makefile.in                          |    8 +-
 src/libsimaka/Makefile.in                          |    8 +-
 src/libstrongswan/Android.mk                       |    4 +-
 src/libstrongswan/Makefile.in                      |    8 +-
 src/libstrongswan/credentials/auth_cfg.c           |    2 +-
 src/libstrongswan/credentials/credential_manager.c |    2 +
 src/libstrongswan/crypto/crypto_tester.h           |    2 +-
 src/libstrongswan/crypto/prf_plus.c                |    4 +-
 src/libstrongswan/ipsec/ipsec_types.c              |   15 +-
 src/libstrongswan/ipsec/ipsec_types.h              |    4 +-
 src/libstrongswan/math/libnttfft/Makefile.in       |    8 +-
 src/libstrongswan/math/libnttfft/tests/Makefile.in |    8 +-
 src/libstrongswan/plugins/acert/Makefile.in        |    8 +-
 src/libstrongswan/plugins/aes/Makefile.in          |    8 +-
 src/libstrongswan/plugins/aesni/Makefile.in        |    8 +-
 src/libstrongswan/plugins/af_alg/Makefile.in       |    8 +-
 src/libstrongswan/plugins/agent/Makefile.in        |    8 +-
 src/libstrongswan/plugins/bliss/Makefile.am        |    3 +-
 src/libstrongswan/plugins/bliss/Makefile.in        |   11 +-
 src/libstrongswan/plugins/bliss/tests/Makefile.in  |    8 +-
 src/libstrongswan/plugins/blowfish/Makefile.in     |    8 +-
 src/libstrongswan/plugins/ccm/Makefile.in          |    8 +-
 src/libstrongswan/plugins/chapoly/Makefile.in      |    8 +-
 src/libstrongswan/plugins/cmac/Makefile.in         |    8 +-
 src/libstrongswan/plugins/constraints/Makefile.in  |    8 +-
 src/libstrongswan/plugins/ctr/Makefile.in          |    8 +-
 src/libstrongswan/plugins/curl/Makefile.in         |    8 +-
 src/libstrongswan/plugins/curl/curl_fetcher.c      |   23 +-
 src/libstrongswan/plugins/curve25519/Makefile.in   |    8 +-
 src/libstrongswan/plugins/des/Makefile.in          |    8 +-
 src/libstrongswan/plugins/dnskey/Makefile.in       |    8 +-
 src/libstrongswan/plugins/files/Makefile.in        |    8 +-
 src/libstrongswan/plugins/fips_prf/Makefile.in     |    8 +-
 src/libstrongswan/plugins/gcm/Makefile.in          |    8 +-
 src/libstrongswan/plugins/gcrypt/Makefile.in       |    8 +-
 src/libstrongswan/plugins/gmp/Makefile.in          |    8 +-
 src/libstrongswan/plugins/gmp/gmp_rsa_public_key.c |   12 +-
 src/libstrongswan/plugins/hmac/Makefile.in         |    8 +-
 src/libstrongswan/plugins/keychain/Makefile.in     |    8 +-
 src/libstrongswan/plugins/ldap/Makefile.in         |    8 +-
 src/libstrongswan/plugins/md4/Makefile.in          |    8 +-
 src/libstrongswan/plugins/md5/Makefile.in          |    8 +-
 src/libstrongswan/plugins/mgf1/Makefile.in         |    8 +-
 src/libstrongswan/plugins/mysql/Makefile.in        |    8 +-
 src/libstrongswan/plugins/newhope/Makefile.am      |    3 +-
 src/libstrongswan/plugins/newhope/Makefile.in      |   11 +-
 .../plugins/newhope/tests/Makefile.in              |    8 +-
 src/libstrongswan/plugins/nonce/Makefile.in        |    8 +-
 src/libstrongswan/plugins/ntru/Makefile.am         |    3 +-
 src/libstrongswan/plugins/ntru/Makefile.in         |   11 +-
 src/libstrongswan/plugins/openssl/Makefile.in      |    8 +-
 src/libstrongswan/plugins/openssl/openssl_x509.c   |   14 +-
 src/libstrongswan/plugins/padlock/Makefile.in      |    8 +-
 src/libstrongswan/plugins/pem/Makefile.in          |    8 +-
 src/libstrongswan/plugins/pgp/Makefile.in          |    8 +-
 src/libstrongswan/plugins/pkcs1/Makefile.in        |    8 +-
 src/libstrongswan/plugins/pkcs11/Makefile.in       |    8 +-
 src/libstrongswan/plugins/pkcs12/Makefile.in       |    8 +-
 src/libstrongswan/plugins/pkcs7/Makefile.in        |    8 +-
 src/libstrongswan/plugins/pkcs8/Makefile.in        |    8 +-
 src/libstrongswan/plugins/pubkey/Makefile.in       |    8 +-
 src/libstrongswan/plugins/random/Makefile.in       |    8 +-
 src/libstrongswan/plugins/rc2/Makefile.in          |    8 +-
 src/libstrongswan/plugins/rdrand/Makefile.in       |    8 +-
 src/libstrongswan/plugins/revocation/Makefile.in   |    8 +-
 src/libstrongswan/plugins/sha1/Makefile.in         |    8 +-
 src/libstrongswan/plugins/sha2/Makefile.in         |    8 +-
 src/libstrongswan/plugins/sha2/sha2_hasher.c       |   82 +-
 src/libstrongswan/plugins/sha3/Makefile.in         |    8 +-
 src/libstrongswan/plugins/soup/Makefile.in         |    8 +-
 src/libstrongswan/plugins/sqlite/Makefile.in       |    8 +-
 src/libstrongswan/plugins/sshkey/Makefile.in       |    8 +-
 src/libstrongswan/plugins/test_vectors/Makefile.in |    8 +-
 src/libstrongswan/plugins/unbound/Makefile.in      |    8 +-
 src/libstrongswan/plugins/winhttp/Makefile.in      |    8 +-
 src/libstrongswan/plugins/x509/Makefile.in         |    8 +-
 src/libstrongswan/plugins/x509/x509_ocsp_request.c |    3 +-
 src/libstrongswan/plugins/xcbc/Makefile.in         |    8 +-
 src/libstrongswan/tests/Makefile.in                |    8 +-
 src/libstrongswan/tests/suites/test_settings.c     |    8 +-
 src/libstrongswan/tests/test_suite.c               |    2 +-
 src/libstrongswan/tests/tests.h                    |    2 +-
 src/libstrongswan/utils/utils/memory.c             |    2 +-
 src/libstrongswan/utils/utils/memory.h             |    2 +-
 src/libtls/Makefile.in                             |    8 +-
 src/libtls/tests/Makefile.in                       |    8 +-
 src/libtls/tls.h                                   |    2 +-
 src/libtls/tls_aead.h                              |    2 +-
 src/libtnccs/Android.mk                            |    2 +-
 src/libtnccs/Makefile.in                           |    8 +-
 src/libtnccs/plugins/tnc_imc/Makefile.in           |    8 +-
 src/libtnccs/plugins/tnc_imv/Makefile.in           |    8 +-
 src/libtnccs/plugins/tnc_tnccs/Makefile.in         |    8 +-
 src/libtnccs/plugins/tnccs_11/Makefile.in          |    8 +-
 src/libtnccs/plugins/tnccs_20/Makefile.in          |    8 +-
 src/libtnccs/plugins/tnccs_dynamic/Makefile.in     |    8 +-
 src/libtncif/Makefile.in                           |    8 +-
 src/libtncif/tncif_pa_subtypes.c                   |   10 +-
 src/libtncif/tncif_pa_subtypes.h                   |    3 +-
 src/libtpmtss/Makefile.in                          |    8 +-
 src/libtpmtss/plugins/tpm/Makefile.in              |    8 +-
 src/libtpmtss/tpm_tss_tss2.c                       |   94 +-
 src/manager/Makefile.in                            |    8 +-
 src/medsrv/Makefile.in                             |    8 +-
 src/pki/Makefile.in                                |    8 +-
 src/pki/man/Makefile.in                            |    8 +-
 src/pki/man/pki---print.1.in                       |    6 +-
 src/pool/Makefile.in                               |    8 +-
 src/pt-tls-client/Makefile.am                      |    6 +-
 src/pt-tls-client/Makefile.in                      |  161 ++-
 src/pt-tls-client/pt-tls-client.1.in               |  130 +++
 src/pt-tls-client/pt-tls-client.c                  |   40 +-
 src/scepclient/Makefile.in                         |    8 +-
 src/starter/Makefile.in                            |    8 +-
 src/starter/tests/Makefile.in                      |    8 +-
 src/stroke/Makefile.in                             |    8 +-
 src/sw-collector/Makefile.am                       |   32 +
 src/{charon-cmd => sw-collector}/Makefile.in       |  168 +--
 src/sw-collector/sw-collector.8.in                 |  124 +++
 src/sw-collector/sw-collector.c                    |  652 ++++++++++++
 src/sw-collector/sw_collector_db.c                 |  427 ++++++++
 src/sw-collector/sw_collector_db.h                 |  155 +++
 src/sw-collector/sw_collector_dpkg.c               |  152 +++
 src/sw-collector/sw_collector_dpkg.h               |   53 +
 src/sw-collector/sw_collector_history.c            |  519 +++++++++
 src/sw-collector/sw_collector_history.h            |   91 ++
 src/sw-collector/sw_collector_rest_api.c           |  200 ++++
 src/sw-collector/sw_collector_rest_api.h           |   57 +
 src/sw-collector/sw_collector_tables.sql           |   31 +
 src/swanctl/Makefile.am                            |    1 +
 src/swanctl/Makefile.in                            |    9 +-
 src/swanctl/command.c                              |    4 +
 src/swanctl/swanctl.conf                           |    6 +
 src/swanctl/swanctl.conf.5.main                    |   29 +-
 src/swanctl/swanctl.opt                            |   16 +-
 testing/Makefile.in                                |    8 +-
 testing/do-tests                                   |   94 +-
 testing/hosts/alice/etc/strongswan.conf            |    6 +-
 testing/hosts/bob/etc/strongswan.conf              |    6 +-
 testing/hosts/carol/etc/strongswan.conf            |    6 +-
 testing/hosts/dave/etc/strongswan.conf             |    6 +-
 testing/hosts/default/usr/local/bin/init_collector |    4 +
 testing/hosts/moon/etc/strongswan.conf             |    6 +-
 testing/hosts/sun/etc/strongswan.conf              |    6 +-
 testing/hosts/venus/etc/strongswan.conf            |    6 +-
 testing/scripts/build-guestimages                  |    2 +-
 testing/scripts/build-strongswan                   |    1 +
 testing/scripts/recipes/013_strongswan.mk          |    2 +
 testing/testing.conf                               |    2 +-
 testing/tests/ikev2/net2net-rekey/description.txt  |   10 +
 testing/tests/ikev2/net2net-rekey/evaltest.dat     |   14 +
 .../ikev2/net2net-rekey/hosts/moon/etc/ipsec.conf  |   24 +
 .../net2net-rekey/hosts/moon/etc/strongswan.conf   |    7 +
 .../net2net-rekey/hosts/sun}/etc/ipsec.conf        |   17 +-
 .../net2net-rekey/hosts/sun/etc/strongswan.conf    |    5 +
 testing/tests/ikev2/net2net-rekey/posttest.dat     |    5 +
 testing/tests/ikev2/net2net-rekey/pretest.dat      |    7 +
 testing/tests/ikev2/net2net-rekey/test.conf        |   21 +
 .../rw-suite-b-192/hosts/dave/etc/ipsec.conf       |    2 +-
 testing/tests/pfkey/net2net-rekey/description.txt  |   10 +
 testing/tests/pfkey/net2net-rekey/evaltest.dat     |   16 +
 .../pfkey/net2net-rekey/hosts/moon/etc/ipsec.conf  |   24 +
 .../net2net-rekey/hosts/moon/etc/strongswan.conf   |    7 +
 .../net2net-rekey/hosts/sun}/etc/ipsec.conf        |   17 +-
 .../net2net-rekey/hosts/sun/etc/strongswan.conf    |    5 +
 testing/tests/pfkey/net2net-rekey/posttest.dat     |    5 +
 testing/tests/pfkey/net2net-rekey/pretest.dat      |    7 +
 testing/tests/pfkey/net2net-rekey/test.conf        |   21 +
 testing/tests/tkm/xfrmproxy-expire/evaltest.dat    |   12 +-
 .../hosts/moon/etc/strongswan.conf                 |    2 +
 .../xfrmproxy-expire/hosts/moon/etc/tkm/tkm.conf   |    2 +-
 testing/tests/tkm/xfrmproxy-rekey/description.txt  |    6 +
 .../evaltest.dat                                   |   13 +-
 .../hosts/moon/etc/strongswan.conf                 |    2 +
 .../xfrmproxy-rekey/hosts/moon/etc/tkm/moonKey.der |  Bin 0 -> 1191 bytes
 .../hosts/moon/etc/tkm/strongswanCert.der          |  Bin 0 -> 956 bytes
 .../hosts/moon/etc/tkm/tkm.conf                    |    2 +-
 .../tkm/xfrmproxy-rekey/hosts/sun/etc/ipsec.conf   |   22 +
 .../xfrmproxy-rekey/hosts/sun/etc/strongswan.conf  |    5 +
 testing/tests/tkm/xfrmproxy-rekey/posttest.dat     |    5 +
 testing/tests/tkm/xfrmproxy-rekey/pretest.dat      |   12 +
 testing/tests/tkm/xfrmproxy-rekey/test.conf        |   21 +
 .../tests/tnc/tnccs-20-ev-pt-tls/description.txt   |    9 +
 .../evaltest.dat                                   |   17 +-
 .../etc/apache2/sites-available/000-default.conf   |   31 +
 .../alice/etc/apache2/sites-available/default      |    1 +
 .../hosts/alice/etc/iptables.rules                 |   28 +
 .../hosts/alice/etc/pts/data1.sql                  |   61 ++
 .../hosts/alice/etc/strongTNC/settings.ini         |   19 +
 .../hosts/alice/etc/strongswan.conf                |   49 +
 .../hosts/alice/etc/swanctl/rsa/aaaKey.pem         |   27 +
 .../hosts/alice/etc/swanctl/swanctl.conf           |    7 +
 .../hosts/alice/etc/swanctl/x509/aaaCert.pem       |   25 +
 .../tnccs-20-ev-pt-tls/hosts/alice/etc/tnc_config  |    4 +
 .../tnccs-20-ev-pt-tls/hosts/carol/etc/ipsec.sql   |    4 +
 .../hosts/carol/etc/iptables.rules                 |   20 +
 .../tnccs-20-ev-pt-tls/hosts/carol/etc/pts/options |    6 +
 .../hosts/carol/etc/strongswan.conf                |   25 +
 .../hosts/carol/etc/swanctl/swanctl.conf           |    1 +
 .../tnccs-20-ev-pt-tls/hosts/carol/etc/tnc_config  |    4 +
 .../tnccs-20-ev-pt-tls/hosts/dave/etc/ipsec.sql    |    4 +
 .../hosts/dave/etc/iptables.rules                  |   20 +
 .../tnccs-20-ev-pt-tls/hosts/dave/etc/pts/options  |    7 +
 .../hosts/dave/etc/strongswan.conf                 |   20 +
 .../hosts/dave/etc/swanctl/swanctl.conf            |    1 +
 .../tnccs-20-ev-pt-tls/hosts/dave/etc/tnc_config   |    4 +
 .../hosts/moon/etc/strongswan.conf                 |    7 +-
 .../hosts/moon/etc/swanctl/swanctl.conf            |    1 +
 testing/tests/tnc/tnccs-20-ev-pt-tls/posttest.dat  |   10 +
 .../pretest.dat                                    |    5 +-
 testing/tests/tnc/tnccs-20-ev-pt-tls/test.conf     |   29 +
 .../tests/tnc/tnccs-20-mutual-pt-tls/pretest.dat   |    2 +-
 .../tests/tnc/tnccs-20-nea-pt-tls/description.txt  |    9 +
 .../evaltest.dat                                   |   16 +-
 .../etc/apache2/sites-available/000-default.conf   |   31 +
 .../alice/etc/apache2/sites-available/default      |    1 +
 .../hosts/alice/etc/iptables.rules                 |   28 +
 .../hosts/alice/etc/pts/data1.sql                  |   61 ++
 .../hosts/alice/etc/strongTNC/settings.ini         |   19 +
 .../hosts/alice/etc/strongswan.conf                |   49 +
 .../hosts/alice/etc/swanctl/rsa/aaaKey.pem         |   27 +
 .../hosts/alice/etc/swanctl/swanctl.conf           |    7 +
 .../hosts/alice/etc/swanctl/x509/aaaCert.pem       |   25 +
 .../tnccs-20-nea-pt-tls/hosts/alice/etc/tnc_config |    4 +
 .../tnccs-20-nea-pt-tls/hosts/carol/etc/ipsec.sql  |    4 +
 .../hosts/carol/etc/iptables.rules                 |   20 +
 .../hosts/carol/etc/pts/options                    |    6 +
 .../hosts/carol/etc/strongswan.conf                |   18 +
 .../hosts/carol/etc/swanctl/swanctl.conf           |    1 +
 .../tnccs-20-nea-pt-tls/hosts/carol/etc/tnc_config |    4 +
 .../tnccs-20-nea-pt-tls/hosts/dave/etc/ipsec.sql   |    4 +
 .../hosts/dave/etc/iptables.rules                  |   20 +
 .../tnccs-20-nea-pt-tls/hosts/dave/etc/pts/options |    7 +
 .../hosts/dave/etc/strongswan.conf                 |   27 +
 .../hosts/dave/etc/swanctl/swanctl.conf            |    1 +
 .../tnccs-20-nea-pt-tls/hosts/dave/etc/tnc_config  |    4 +
 .../hosts/moon/etc/strongswan.conf                 |    7 +-
 .../hosts/moon/etc/swanctl/swanctl.conf            |    1 +
 testing/tests/tnc/tnccs-20-nea-pt-tls/posttest.dat |   10 +
 .../pretest.dat                                    |    4 +-
 testing/tests/tnc/tnccs-20-nea-pt-tls/test.conf    |   29 +
 testing/tests/tnc/tnccs-20-pdp-pt-tls/evaltest.dat |    2 +-
 testing/tests/tnc/tnccs-20-pdp-pt-tls/pretest.dat  |    4 +-
 508 files changed, 15540 insertions(+), 2757 deletions(-)

diff --git a/Android.common.mk b/Android.common.mk
index 1302123..1243e26 100644
--- a/Android.common.mk
+++ b/Android.common.mk
@@ -26,5 +26,5 @@ add_plugin_subdirs = $(if $(call plugin_enabled,$(1)), \
               )
 
 # strongSwan version, replaced by top Makefile
-strongswan_VERSION := "5.5.3"
+strongswan_VERSION := "5.6.0"
 
diff --git a/Makefile.in b/Makefile.in
index 07528a7..b08cb7b 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -342,8 +342,6 @@ RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
 RUBYGEMDIR = @RUBYGEMDIR@
-RUBYINCLUDE = @RUBYINCLUDE@
-RUBYLIB = @RUBYLIB@
 SED = @SED@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
@@ -444,6 +442,8 @@ random_device = @random_device@
 resolv_conf = @resolv_conf@
 routing_table = @routing_table@
 routing_table_prio = @routing_table_prio@
+ruby_CFLAGS = @ruby_CFLAGS@
+ruby_LIBS = @ruby_LIBS@
 runstatedir = @runstatedir@
 s_plugins = @s_plugins@
 sbindir = @sbindir@
@@ -472,6 +472,10 @@ top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
 tss2_CFLAGS = @tss2_CFLAGS@
 tss2_LIBS = @tss2_LIBS@
+tss2_socket_CFLAGS = @tss2_socket_CFLAGS@
+tss2_socket_LIBS = @tss2_socket_LIBS@
+tss2_tabrmd_CFLAGS = @tss2_tabrmd_CFLAGS@
+tss2_tabrmd_LIBS = @tss2_tabrmd_LIBS@
 urandom_device = @urandom_device@
 xml_CFLAGS = @xml_CFLAGS@
 xml_LIBS = @xml_LIBS@
diff --git a/NEWS b/NEWS
index 98aefe7..8e82607 100644
--- a/NEWS
+++ b/NEWS
@@ -1,3 +1,45 @@
+strongswan-5.6.0
+----------------
+
+- Fixed a DoS vulnerability in the gmp plugin that was caused by insufficient
+  input validation when verifying RSA signatures, which requires decryption
+  with the operation m^e mod n, where m is the signature, and e and n are the
+  exponent and modulus of the public key.  The value m is an integer between
+  0 and n-1, however, the gmp plugin did not verify this.  So if m equals n the
+  calculation results in 0, in which case mpz_export() returns NULL.  This
+  result wasn't handled properly causing a null-pointer dereference.
+  This vulnerability has been registered as CVE-2017-11185.
+
+- New SWIMA IMC/IMV pair implements the "draft-ietf-sacm-nea-swima-patnc"
+  Internet Draft and has been demonstrated at the IETF 99 Prague Hackathon.
+
+- The IMV database template has been adapted to achieve full compliance
+  with the ISO 19770-2:2015 SWID tag standard.
+
+- The sw-collector tool extracts software events from apt history logs
+  and stores them in an SQLite database to be used by the SWIMA IMC.
+  The tool can also generate SWID tags both for installed and removed
+  package versions.
+
+- The pt-tls-client can attach and use TPM 2.0 protected private keys
+  via the --keyid parameter.
+
+- libtpmtss supports Intel's TSS2 Architecture Broker and Resource
+  Manager interface (tcti-tabrmd).
+
+- The new eap-aka-3gpp plugin implements the 3GPP MILENAGE algorithms
+  in software.  K (optionally concatenated with OPc) may be configured as
+  binary EAP secret.
+
+- CHILD_SA rekeying was fixed in charon-tkm and was slightly changed: The
+  switch to the new outbound IPsec SA now happens via SPI on the outbound
+  policy on Linux, and in case of lost rekey collisions no outbound SA/policy
+  is temporarily installed for the redundant CHILD_SA.
+
+- The new %unique-dir value for mark* settings allocates separate unique marks
+  for each CHILD_SA direction (in/out).
+
+
 strongswan-5.5.3
 ----------------
 
@@ -894,7 +936,7 @@ strongswan-5.0.0
   keying protocols. The feature-set of IKEv1 in charon is almost on par with
   pluto, but currently does not support AH or bundled AH+ESP SAs. Beside
   RSA/ECDSA, PSK and XAuth, charon also supports the Hybrid authentication
-  mode. Informations for interoperability and migration is available at
+  mode. Information for interoperability and migration is available at
   http://wiki.strongswan.org/projects/strongswan/wiki/CharonPlutoIKEv1.
 
 - Charon's bus_t has been refactored so that loggers and other listeners are
diff --git a/conf/Makefile.am b/conf/Makefile.am
index eb5c9c2..87319db 100644
--- a/conf/Makefile.am
+++ b/conf/Makefile.am
@@ -24,7 +24,8 @@ options = \
 	options/scepclient.opt \
 	options/starter.opt \
 	options/swanctl.opt \
-	options/tnc.opt
+	options/tnc.opt \
+	options/sw-collector.opt
 
 plugins = \
 	plugins/addrblock.opt \
@@ -35,11 +36,13 @@ plugins = \
 	plugins/bypass-lan.opt \
 	plugins/certexpire.opt \
 	plugins/coupling.opt \
+	plugins/curl.opt \
 	plugins/dhcp.opt \
 	plugins/dnscert.opt \
 	plugins/duplicheck.opt \
 	plugins/eap-aka.opt \
-	plugins/eap-aka-3ggp2.opt \
+	plugins/eap-aka-3gpp.opt \
+	plugins/eap-aka-3gpp2.opt \
 	plugins/eap-dynamic.opt \
 	plugins/eap-gtc.opt \
 	plugins/eap-peap.opt \
@@ -59,11 +62,13 @@ plugins = \
 	plugins/imc-os.opt \
 	plugins/imc-scanner.opt \
 	plugins/imc-swid.opt \
+	plugins/imc-swima.opt \
 	plugins/imc-test.opt \
 	plugins/imv-attestation.opt \
 	plugins/imv-os.opt \
 	plugins/imv-scanner.opt \
 	plugins/imv-swid.opt \
+	plugins/imv-swima.opt \
 	plugins/imv-test.opt \
 	plugins/ipseckey.opt \
 	plugins/led.opt \
diff --git a/conf/Makefile.in b/conf/Makefile.in
index 9a85514..b403c72 100644
--- a/conf/Makefile.in
+++ b/conf/Makefile.in
@@ -265,8 +265,6 @@ RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
 RUBYGEMDIR = @RUBYGEMDIR@
-RUBYINCLUDE = @RUBYINCLUDE@
-RUBYLIB = @RUBYLIB@
 SED = @SED@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
@@ -367,6 +365,8 @@ random_device = @random_device@
 resolv_conf = @resolv_conf@
 routing_table = @routing_table@
 routing_table_prio = @routing_table_prio@
+ruby_CFLAGS = @ruby_CFLAGS@
+ruby_LIBS = @ruby_LIBS@
 runstatedir = @runstatedir@
 s_plugins = @s_plugins@
 sbindir = @sbindir@
@@ -395,6 +395,10 @@ top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
 tss2_CFLAGS = @tss2_CFLAGS@
 tss2_LIBS = @tss2_LIBS@
+tss2_socket_CFLAGS = @tss2_socket_CFLAGS@
+tss2_socket_LIBS = @tss2_socket_LIBS@
+tss2_tabrmd_CFLAGS = @tss2_tabrmd_CFLAGS@
+tss2_tabrmd_LIBS = @tss2_tabrmd_LIBS@
 urandom_device = @urandom_device@
 xml_CFLAGS = @xml_CFLAGS@
 xml_LIBS = @xml_LIBS@
@@ -424,7 +428,8 @@ options = \
 	options/scepclient.opt \
 	options/starter.opt \
 	options/swanctl.opt \
-	options/tnc.opt
+	options/tnc.opt \
+	options/sw-collector.opt
 
 plugins = \
 	plugins/addrblock.opt \
@@ -435,11 +440,13 @@ plugins = \
 	plugins/bypass-lan.opt \
 	plugins/certexpire.opt \
 	plugins/coupling.opt \
+	plugins/curl.opt \
 	plugins/dhcp.opt \
 	plugins/dnscert.opt \
 	plugins/duplicheck.opt \
 	plugins/eap-aka.opt \
-	plugins/eap-aka-3ggp2.opt \
+	plugins/eap-aka-3gpp.opt \
+	plugins/eap-aka-3gpp2.opt \
 	plugins/eap-dynamic.opt \
 	plugins/eap-gtc.opt \
 	plugins/eap-peap.opt \
@@ -459,11 +466,13 @@ plugins = \
 	plugins/imc-os.opt \
 	plugins/imc-scanner.opt \
 	plugins/imc-swid.opt \
+	plugins/imc-swima.opt \
 	plugins/imc-test.opt \
 	plugins/imv-attestation.opt \
 	plugins/imv-os.opt \
 	plugins/imv-scanner.opt \
 	plugins/imv-swid.opt \
+	plugins/imv-swima.opt \
 	plugins/imv-test.opt \
 	plugins/ipseckey.opt \
 	plugins/led.opt \
diff --git a/conf/format-options.py b/conf/format-options.py
index 3073943..592bf67 100755
--- a/conf/format-options.py
+++ b/conf/format-options.py
@@ -1,7 +1,7 @@
 #!/usr/bin/env python
 #
-# Copyright (C) 2014-2015 Tobias Brunner
-# Hochschule fuer Technik Rapperswil
+# Copyright (C) 2014-2017 Tobias Brunner
+# HSR Hochschule fuer Technik Rapperswil
 #
 # This program is free software; you can redistribute it and/or modify it
 # under the terms of the GNU General Public License as published by the
@@ -49,6 +49,12 @@ full.section.name {[#]}
 If a # is added between the curly braces the section header will be commented
 out in the configuration file snippet, which is useful for example sections.
 
+To add include statements to generated config files (ignored when generating
+man pages) the following format can be used:
+
+full.section.name.include files/to/include
+	Description of this include statement
+
 Dots in section/option names may be escaped with a backslash.  For instance,
 with the following section description
 
@@ -62,17 +68,18 @@ import sys
 import re
 from textwrap import TextWrapper
 from optparse import OptionParser
-from operator import attrgetter
+from functools import cmp_to_key
 
 class ConfigOption:
 	"""Representing a configuration option or described section in strongswan.conf"""
-	def __init__(self, path, default = None, section = False, commented = False):
+	def __init__(self, path, default = None, section = False, commented = False, include = False):
 		self.path = path
 		self.name = path[-1]
 		self.fullname = '.'.join(path)
 		self.default = default
 		self.section = section
 		self.commented = commented
+		self.include = include
 		self.desc = []
 		self.options = []
 
@@ -99,6 +106,13 @@ class ConfigOption:
 		self.commented = other.commented
 		self.desc = other.desc
 
+	@staticmethod
+	def cmp(a, b):
+		# order options before sections and includes last
+		if a.include or b.include:
+			return a.include - b.include
+		return a.section - b.section
+
 class Parser:
 	"""Parses one or more files of configuration options"""
 	def __init__(self, sort = True):
@@ -135,6 +149,14 @@ class Parser:
 			self.__current = ConfigOption(path, section = True,
 										  commented = m.group('comment'))
 			return
+		# include definition
+		m = re.match(r'^(?P<name>\S+\.include|include)\s+(?P<pattern>\S+)\s*$', line)
+		if m:
+			if self.__current:
+				self.__add_option(self.__current)
+			path = self.__split_name(m.group('name'))
+			self.__current = ConfigOption(path, m.group('pattern'), include = True)
+			return
 		# paragraph separator
 		m = re.match(r'^\s*$', line)
 		if m and self.__current:
@@ -195,7 +217,7 @@ class TagReplacer:
 		return re.compile(r'''
 			(^|\s|(?P<brack>[(\[])) # prefix with optional opening bracket
 			(?P<tag>''' + tag + r''') # start tag
-			(?P<text>\w|\S.*?\S) # text
+			(?P<text>\S|\S.*?\S) # text
 			''' + tag + r''' # end tag
 			(?P<punct>([.,!:)\]]|\(\d+\))*) # punctuation
 			(?=$|\s) # suffix (don't consume it so that subsequent tags can match)
@@ -248,7 +270,9 @@ class ConfFormatter:
 		"""Print a single option with description and default value"""
 		comment = "# " if commented or opt.commented else ""
 		self.__print_description(opt, indent)
-		if opt.default:
+		if opt.include:
+			print('{0}{1} {2}'.format(self.__indent * indent, opt.name, opt.default))
+		elif opt.default:
 			print('{0}{1}{2} = {3}'.format(self.__indent * indent, comment, opt.name, opt.default))
 		else:
 			print('{0}{1}{2} ='.format(self.__indent * indent, comment, opt.name))
@@ -261,7 +285,7 @@ class ConfFormatter:
 		self.__print_description(section, indent)
 		print('{0}{1}{2} {{'.format(self.__indent * indent, comment, section.name))
 		print('')
-		for o in sorted(section.options, key=attrgetter('section')):
+		for o in sorted(section.options, key=cmp_to_key(ConfigOption.cmp)):
 			if o.section:
 				self.__print_section(o, indent + 1, commented)
 			else:
@@ -273,7 +297,7 @@ class ConfFormatter:
 		"""Print a list of options"""
 		if not options:
 			return
-		for option in sorted(options, key=attrgetter('section')):
+		for option in sorted(options, key=cmp_to_key(ConfigOption.cmp)):
 			if option.section:
 				self.__print_section(option, 0, False)
 			else:
@@ -297,6 +321,8 @@ class ManFormatter:
 		"""Print a single option"""
 		if option.section and not len(option.desc):
 			return
+		if option.include:
+			return
 		if option.section:
 			print('.TP\n.B {0}\n.br'.format(option.fullname))
 		else:
diff --git a/conf/options/charon.conf b/conf/options/charon.conf
index 7ccb749..f0d084b 100644
--- a/conf/options/charon.conf
+++ b/conf/options/charon.conf
@@ -168,7 +168,7 @@ charon {
     # will be allocated.
     # port_nat_t = 4500
 
-    # Wether to prefer updating SAs to the path with the best route.
+    # Whether to prefer updating SAs to the path with the best route.
     # prefer_best_path = no
 
     # Prefer locally configured proposals for IKE/IPsec over supplied ones as
diff --git a/conf/options/charon.opt b/conf/options/charon.opt
index 3593c6a..900b9b4 100644
--- a/conf/options/charon.opt
+++ b/conf/options/charon.opt
@@ -271,7 +271,7 @@ charon.port_nat_t = 4500
 	port will be allocated.
 
 charon.prefer_best_path = no
-	Wether to prefer updating SAs to the path with the best route.
+	Whether to prefer updating SAs to the path with the best route.
 
 	By default, charon keeps SAs on the routing path with addresses it
 	previously used if that path is still usable. By setting this option to
diff --git a/conf/options/imcv.conf b/conf/options/imcv.conf
index bc1f183..ede2d9d 100644
--- a/conf/options/imcv.conf
+++ b/conf/options/imcv.conf
@@ -42,5 +42,22 @@ libimcv {
     # Disable output to stderr with a stand-alone libimcv library.
     # stderr_quiet = no
 
+    swid_gen {
+
+        # SWID generator command to be executed.
+        # command = /usr/local/bin/swid_generator
+
+        tag_creator {
+
+            # Name of the tagCreator entity.
+            # name = strongSwan Project
+
+            # regid of the tagCreator entity.
+            # regid = strongswan.org
+
+        }
+
+    }
+
 }
 
diff --git a/conf/options/imcv.opt b/conf/options/imcv.opt
index 33ab74b..177781f 100644
--- a/conf/options/imcv.opt
+++ b/conf/options/imcv.opt
@@ -21,6 +21,15 @@ charon.imcv.os_info.default_password_enabled = no
 charon.imcv.policy_script = ipsec _imv_policy
 	Script called for each TNC connection to generate IMV policies.
 
+libimcv.swid_gen.command = /usr/local/bin/swid_generator
+	SWID generator command to be executed.
+
+libimcv.swid_gen.tag_creator.name = strongSwan Project
+	Name of the tagCreator entity.
+
+libimcv.swid_gen.tag_creator.regid = strongswan.org
+	regid of the tagCreator entity.
+
 libimcv.debug_level = 1
 	Debug level for a stand-alone _libimcv_ library.
 
diff --git a/conf/options/sw-collector.conf b/conf/options/sw-collector.conf
new file mode 100644
index 0000000..6f588b4
--- /dev/null
+++ b/conf/options/sw-collector.conf
@@ -0,0 +1,31 @@
+# Options for the sw-collector tool.
+sw-collector {
+
+    # URI to software collector database containing event timestamps, software
+    # creation and deletion events and collected software identifiers.
+    # database =
+
+    # Path pointing to file created when the Linux OS was installed.
+    # first_file = /var/log/bootstrap.log
+
+    # Time in UTC when the Linux OS was installed.
+    # first_time = 0000-00-00T00:00:00Z
+
+    # Path pointing to apt history.log file.
+    # history =
+
+    # Plugins to load in sw-collector tool.
+    # load =
+
+    rest_api {
+
+        # Timeout of REST API HTTP POST transaction.
+        # timeout = 120
+
+        # HTTP URI of the central collector's REST API.
+        # uri =
+
+    }
+
+}
+
diff --git a/conf/options/sw-collector.opt b/conf/options/sw-collector.opt
new file mode 100644
index 0000000..976f4f4
--- /dev/null
+++ b/conf/options/sw-collector.opt
@@ -0,0 +1,31 @@
+sw-collector {}
+	Options for the sw-collector tool.
+
+	Options for the sw-collector tool.
+
+sw-collector.database =
+	URI to software collector database containing event timestamps, software
+	creation and deletion events and collected software identifiers.
+
+	URI to software collector database containing event timestamps,	software
+	creation and deletion events and collected software identifiers.
+	If it contains a password, make sure to adjust the permissions of the config
+	file accordingly.
+
+sw-collector.first_file = /var/log/bootstrap.log
+	Path pointing to file created when the Linux OS was installed.
+
+sw-collector.first_time = 0000-00-00T00:00:00Z
+	Time in UTC when the Linux OS was installed.
+
+sw-collector.history =
+	Path pointing to apt history.log file.
+
+sw-collector.rest_api.uri =
+	HTTP URI of the central collector's REST API.
+
+sw-collector.rest_api.timeout = 120
+	Timeout of REST API HTTP POST transaction.
+
+sw-collector.load =
+	Plugins to load in sw-collector tool.
diff --git a/conf/options/swanctl.conf b/conf/options/swanctl.conf
index cb18239..18cea48 100644
--- a/conf/options/swanctl.conf
+++ b/conf/options/swanctl.conf
@@ -3,5 +3,8 @@ swanctl {
     # Plugins to load in swanctl.
     # load =
 
+    # VICI socket to connect to by default.
+    # socket = unix://${piddir}/charon.vici
+
 }
 
diff --git a/conf/options/swanctl.opt b/conf/options/swanctl.opt
index f78b4bc..f2a8a0f 100644
--- a/conf/options/swanctl.opt
+++ b/conf/options/swanctl.opt
@@ -1,2 +1,5 @@
 swanctl.load =
-	Plugins to load in swanctl.
\ No newline at end of file
+	Plugins to load in swanctl.
+
+swanctl.socket = unix://${piddir}/charon.vici
+	VICI socket to connect to by default.
diff --git a/conf/plugins/curl.conf b/conf/plugins/curl.conf
new file mode 100644
index 0000000..9ba0420
--- /dev/null
+++ b/conf/plugins/curl.conf
@@ -0,0 +1,12 @@
+curl {
+
+    # Whether to load the plugin. Can also be an integer to increase the
+    # priority of this plugin.
+    load = yes
+
+    # Maximum number of redirects followed by the plugin, set to 0 to disable
+    # following redirects, set to -1 for no limit.
+    # redir = -1
+
+}
+
diff --git a/conf/plugins/curl.opt b/conf/plugins/curl.opt
new file mode 100644
index 0000000..90efa12
--- /dev/null
+++ b/conf/plugins/curl.opt
@@ -0,0 +1,3 @@
+charon.plugins.curl.redir = -1
+	Maximum number of redirects followed by the plugin, set to 0 to disable
+	following redirects, set to -1 for no limit.
diff --git a/conf/plugins/eap-aka-3ggp2.opt b/conf/plugins/eap-aka-3ggp2.opt
deleted file mode 100644
index 9e2a42b..0000000
--- a/conf/plugins/eap-aka-3ggp2.opt
+++ /dev/null
@@ -1 +0,0 @@
-charon.plugins.eap-aka-3ggp2.seq_check =
diff --git a/conf/plugins/eap-aka-3ggp2.conf b/conf/plugins/eap-aka-3gpp.conf
similarity index 54%
copy from conf/plugins/eap-aka-3ggp2.conf
copy to conf/plugins/eap-aka-3gpp.conf
index c52c996..4164535 100644
--- a/conf/plugins/eap-aka-3ggp2.conf
+++ b/conf/plugins/eap-aka-3gpp.conf
@@ -1,9 +1,11 @@
-eap-aka-3ggp2 {
+eap-aka-3gpp {
 
     # Whether to load the plugin. Can also be an integer to increase the
     # priority of this plugin.
     load = yes
 
+    # Enable to activate sequence check of the AKA SQN values in order to
+    # trigger resync cycles.
     # seq_check =
 
 }
diff --git a/conf/plugins/eap-aka-3gpp.opt b/conf/plugins/eap-aka-3gpp.opt
new file mode 100644
index 0000000..1bc733a
--- /dev/null
+++ b/conf/plugins/eap-aka-3gpp.opt
@@ -0,0 +1,3 @@
+charon.plugins.eap-aka-3gpp.seq_check =
+	Enable to activate sequence check of the AKA SQN values	in order to trigger
+	resync cycles.
diff --git a/conf/plugins/eap-aka-3ggp2.conf b/conf/plugins/eap-aka-3gpp2.conf
similarity index 54%
copy from conf/plugins/eap-aka-3ggp2.conf
copy to conf/plugins/eap-aka-3gpp2.conf
index c52c996..3f329ae 100644
--- a/conf/plugins/eap-aka-3ggp2.conf
+++ b/conf/plugins/eap-aka-3gpp2.conf
@@ -1,9 +1,11 @@
-eap-aka-3ggp2 {
+eap-aka-3gpp2 {
 
     # Whether to load the plugin. Can also be an integer to increase the
     # priority of this plugin.
     load = yes
 
+    # Enable to activate sequence check of the AKA SQN values in order to
+    # trigger resync cycles.
     # seq_check =
 
 }
diff --git a/conf/plugins/eap-aka-3gpp2.opt b/conf/plugins/eap-aka-3gpp2.opt
new file mode 100644
index 0000000..679c386
--- /dev/null
+++ b/conf/plugins/eap-aka-3gpp2.opt
@@ -0,0 +1,4 @@
+charon.plugins.eap-aka-3gpp2.seq_check =
+	Enable to activate sequence check of the AKA SQN values in order to trigger
+	resync cycles.
+
diff --git a/conf/plugins/imc-swid.opt b/conf/plugins/imc-swid.opt
index 74490c1..e622aa6 100644
--- a/conf/plugins/imc-swid.opt
+++ b/conf/plugins/imc-swid.opt
@@ -1,11 +1,8 @@
 libimcv.plugins.imc-swid.swid_directory = ${prefix}/share
 	Directory where SWID tags are located.
 
-libimcv.plugins.imc-swid.swid_generator = /usr/local/bin/swid_generator
-	SWID generator command to be executed.
-
-libimcv.plugins.imc-swid.swid_pretty = FALSE
+libimcv.plugins.imc-swid.swid_pretty = no
 	Generate XML-encoded SWID tags with pretty indentation.
 
-libimcv.plugins.imc-swid.swid_full = FALSE
+libimcv.plugins.imc-swid.swid_full = no
 	Include file information in the XML-encoded SWID tags.
diff --git a/conf/plugins/eap-aka-3ggp2.conf b/conf/plugins/imc-swima.conf
similarity index 77%
copy from conf/plugins/eap-aka-3ggp2.conf
copy to conf/plugins/imc-swima.conf
index c52c996..0d1e88a 100644
--- a/conf/plugins/eap-aka-3ggp2.conf
+++ b/conf/plugins/imc-swima.conf
@@ -1,10 +1,8 @@
-eap-aka-3ggp2 {
+imc-swima {
 
     # Whether to load the plugin. Can also be an integer to increase the
     # priority of this plugin.
     load = yes
 
-    # seq_check =
-
 }
 
diff --git a/conf/plugins/imc-swima.opt b/conf/plugins/imc-swima.opt
new file mode 100644
index 0000000..099a3c8
--- /dev/null
+++ b/conf/plugins/imc-swima.opt
@@ -0,0 +1,21 @@
+libimcv.plugins.imc-swima.eid_epoch = 0x11223344
+	Set 32 bit epoch value for event IDs manually if software collector database
+	is not available.
+
+libimcv.plugins.imc-swima.swid_database =
+	URI to software collector database containing event timestamps,	software
+	creation and deletion events and collected software identifiers.
+
+	URI to software collector database containing event timestamps,	software
+	creation and deletion events and collected software identifiers.
+	If it contains a password, make sure to adjust the permissions of the config
+	file accordingly.
+
+libimcv.plugins.imc-swima.swid_directory = ${prefix}/share
+	Directory where SWID tags are located.
+
+libimcv.plugins.imc-swima.swid_pretty = no
+	Generate XML-encoded SWID tags with pretty indentation.
+
+libimcv.plugins.imc-swima.swid_full = no
+	Include file information in the XML-encoded SWID tags.
diff --git a/conf/plugins/eap-aka-3ggp2.conf b/conf/plugins/imv-swima.conf
similarity index 77%
rename from conf/plugins/eap-aka-3ggp2.conf
rename to conf/plugins/imv-swima.conf
index c52c996..cde4e1a 100644
--- a/conf/plugins/eap-aka-3ggp2.conf
+++ b/conf/plugins/imv-swima.conf
@@ -1,10 +1,8 @@
-eap-aka-3ggp2 {
+imv-swima {
 
     # Whether to load the plugin. Can also be an integer to increase the
     # priority of this plugin.
     load = yes
 
-    # seq_check =
-
 }
 
diff --git a/conf/plugins/imv-swima.opt b/conf/plugins/imv-swima.opt
new file mode 100644
index 0000000..a9ba96c
--- /dev/null
+++ b/conf/plugins/imv-swima.opt
@@ -0,0 +1,5 @@
+libimcv.plugins.imv-swima.rest_api.uri =
+	HTTP URI of the SWID REST API.
+
+libimcv.plugins.imv-swima.rest_api.timeout = 120
+	Timeout of SWID REST API HTTP POST transaction.
diff --git a/conf/strongswan.conf.5.main b/conf/strongswan.conf.5.main
index 4df7ce4..4f38c9b 100644
--- a/conf/strongswan.conf.5.main
+++ b/conf/strongswan.conf.5.main
@@ -519,6 +519,11 @@ Hashing algorithm to fingerprint coupled certificates.
 Maximum number of coupling entries to create.
 
 .TP
+.BR charon.plugins.curl.redir " [-1]"
+Maximum number of redirects followed by the plugin, set to 0 to disable
+following redirects, set to \-1 for no limit.
+
+.TP
 .BR charon.plugins.dhcp.force_server_address " [no]"
 Always use the configured server address. This might be helpful if the DHCP
 server runs on the same host as strongSwan, and the DHCP daemon does not listen
@@ -556,7 +561,15 @@ Socket provided by the duplicheck plugin.
 .TP
 .BR charon.plugins.eap-aka.request_identity " [yes]"
 .TP
-.BR charon.plugins.eap-aka-3ggp2.seq_check " []"
+.BR charon.plugins.eap-aka-3gpp.seq_check " []"
+Enable to activate sequence check of the AKA SQN values in order to trigger
+resync cycles.
+
+.TP
+.BR charon.plugins.eap-aka-3gpp2.seq_check " []"
+Enable to activate sequence check of the AKA SQN values in order to trigger
+resync cycles.
+
 .TP
 .BR charon.plugins.eap-dynamic.prefer_user " [no]"
 If enabled the EAP methods proposed in an EAP\-Nak message sent by the peer are
@@ -2115,15 +2128,34 @@ Send open listening ports without being prompted.
 Directory where SWID tags are located.
 
 .TP
-.BR libimcv.plugins.imc-swid.swid_full " [FALSE]"
+.BR libimcv.plugins.imc-swid.swid_full " [no]"
 Include file information in the XML\-encoded SWID tags.
 
 .TP
-.BR libimcv.plugins.imc-swid.swid_generator " [/usr/local/bin/swid_generator]"
-SWID generator command to be executed.
+.BR libimcv.plugins.imc-swid.swid_pretty " [no]"
+Generate XML\-encoded SWID tags with pretty indentation.
 
 .TP
-.BR libimcv.plugins.imc-swid.swid_pretty " [FALSE]"
+.BR libimcv.plugins.imc-swima.eid_epoch " [0x11223344]"
+Set 32 bit epoch value for event IDs manually if software collector database is
+not available.
+
+.TP
+.BR libimcv.plugins.imc-swima.swid_database " []"
+URI to software collector database containing event timestamps, software
+creation and deletion events and collected software identifiers. If it contains
+a password, make sure to adjust the permissions of the config file accordingly.
+
+.TP
+.BR libimcv.plugins.imc-swima.swid_directory " [${prefix}/share]"
+Directory where SWID tags are located.
+
+.TP
+.BR libimcv.plugins.imc-swima.swid_full " [no]"
+Include file information in the XML\-encoded SWID tags.
+
+.TP
+.BR libimcv.plugins.imc-swima.swid_pretty " [no]"
 Generate XML\-encoded SWID tags with pretty indentation.
 
 .TP
@@ -2183,6 +2215,14 @@ Timeout of SWID REST API HTTP POST transaction.
 HTTP URI of the SWID REST API.
 
 .TP
+.BR libimcv.plugins.imv-swima.rest_api.timeout " [120]"
+Timeout of SWID REST API HTTP POST transaction.
+
+.TP
+.BR libimcv.plugins.imv-swima.rest_api.uri " []"
+HTTP URI of the SWID REST API.
+
+.TP
 .BR libimcv.plugins.imv-test.rounds " [0]"
 Number of IMC\-IMV retry rounds.
 
@@ -2193,6 +2233,18 @@ Disable output to stderr with a stand\-alone
 library.
 
 .TP
+.BR libimcv.swid_gen.command " [/usr/local/bin/swid_generator]"
+SWID generator command to be executed.
+
+.TP
+.BR libimcv.swid_gen.tag_creator.name " [strongSwan Project]"
+Name of the tagCreator entity.
+
+.TP
+.BR libimcv.swid_gen.tag_creator.regid " [strongswan.org]"
+regid of the tagCreator entity.
+
+.TP
 .BR manager.database " []"
 Credential database URI for manager. If it contains a password, make sure to
 adjust the permissions of the config file accordingly.
@@ -2291,6 +2343,45 @@ Location of the ipsec.conf file
 Disable charon plugin load option warning.
 
 .TP
+.B sw-collector
+.br
+Options for the sw\-collector tool.
+
+.TP
+.BR sw-collector.database " []"
+URI to software collector database containing event timestamps, software
+creation and deletion events and collected software identifiers. If it contains
+a password, make sure to adjust the permissions of the config file accordingly.
+
+.TP
+.BR sw-collector.first_file " [/var/log/bootstrap.log]"
+Path pointing to file created when the Linux OS was installed.
+
+.TP
+.BR sw-collector.first_time " [0000-00-00T00:00:00Z]"
+Time in UTC when the Linux OS was installed.
+
+.TP
+.BR sw-collector.history " []"
+Path pointing to apt history.log file.
+
+.TP
+.BR sw-collector.load " []"
+Plugins to load in sw\-collector tool.
+
+.TP
+.BR sw-collector.rest_api.timeout " [120]"
+Timeout of REST API HTTP POST transaction.
+
+.TP
+.BR sw-collector.rest_api.uri " []"
+HTTP URI of the central collector's REST API.
+
+.TP
 .BR swanctl.load " []"
 Plugins to load in swanctl.
 
+.TP
+.BR swanctl.socket " [unix://${piddir}/charon.vici]"
+VICI socket to connect to by default.
+
diff --git a/config.h.in b/config.h.in
index 49aa093..06d3999 100644
--- a/config.h.in
+++ b/config.h.in
@@ -322,6 +322,12 @@
 /* Define to 1 if strerror_r returns char *. */
 #undef STRERROR_R_CHAR_P
 
+/* use TCTI Sockets */
+#undef TSS2_TCTI_SOCKET
+
+/* use TCTI Access Broker and Resource Mamager */
+#undef TSS2_TCTI_TABRMD
+
 /* use TrouSerS library libtspi */
 #undef TSS_TROUSERS
 
@@ -340,6 +346,9 @@
 /* support for IKEv2 protocol */
 #undef USE_IKEV2
 
+/* build code for JSON */
+#undef USE_JSON
+
 /* use thread ID for thread identification, if available */
 #undef USE_THREAD_IDS
 
diff --git a/configure b/configure
index 21db534..287d2b6 100755
--- a/configure
+++ b/configure
@@ -1,6 +1,6 @@
 #! /bin/sh
 # Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.69 for strongSwan 5.5.3.
+# Generated by GNU Autoconf 2.69 for strongSwan 5.6.0.
 #
 #
 # Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc.
@@ -587,8 +587,8 @@ MAKEFLAGS=
 # Identity of this package.
 PACKAGE_NAME='strongSwan'
 PACKAGE_TARNAME='strongswan'
-PACKAGE_VERSION='5.5.3'
-PACKAGE_STRING='strongSwan 5.5.3'
+PACKAGE_VERSION='5.6.0'
+PACKAGE_STRING='strongSwan 5.6.0'
 PACKAGE_BUGREPORT=''
 PACKAGE_URL=''
 
@@ -769,6 +769,10 @@ USE_IMV_HCD_FALSE
 USE_IMV_HCD_TRUE
 USE_IMC_HCD_FALSE
 USE_IMC_HCD_TRUE
+USE_IMV_SWIMA_FALSE
+USE_IMV_SWIMA_TRUE
+USE_IMC_SWIMA_FALSE
+USE_IMC_SWIMA_TRUE
 USE_IMV_SWID_FALSE
 USE_IMV_SWID_TRUE
 USE_IMC_SWID_FALSE
@@ -829,6 +833,8 @@ USE_EAP_MSCHAPV2_FALSE
 USE_EAP_MSCHAPV2_TRUE
 USE_EAP_AKA_3GPP2_FALSE
 USE_EAP_AKA_3GPP2_TRUE
+USE_EAP_AKA_3GPP_FALSE
+USE_EAP_AKA_3GPP_TRUE
 USE_EAP_AKA_FALSE
 USE_EAP_AKA_TRUE
 USE_EAP_GTC_FALSE
@@ -1078,8 +1084,8 @@ MYSQLCFLAG
 MYSQLCONFIG
 MYSQLLIB
 clearsilver_LIBS
-RUBYLIB
-RUBYINCLUDE
+ruby_LIBS
+ruby_CFLAGS
 RUBY
 gtk_LIBS
 gtk_CFLAGS
@@ -1087,6 +1093,10 @@ json_LIBS
 json_CFLAGS
 tss2_LIBS
 tss2_CFLAGS
+tss2_socket_LIBS
+tss2_socket_CFLAGS
+tss2_tabrmd_LIBS
+tss2_tabrmd_CFLAGS
 systemd_journal_LIBS
 systemd_journal_CFLAGS
 systemd_daemon_LIBS
@@ -1099,7 +1109,6 @@ soup_LIBS
 soup_CFLAGS
 USE_X86X64_FALSE
 USE_X86X64_TRUE
-PLUGIN_CFLAGS
 USE_WINDOWS_FALSE
 USE_WINDOWS_TRUE
 OPENSSL_LIB
@@ -1175,6 +1184,7 @@ CPPFLAGS
 LDFLAGS
 CFLAGS
 CC
+PLUGIN_CFLAGS
 ipsec_script_upper
 charon_natt_port
 charon_udp_port
@@ -1364,6 +1374,7 @@ enable_eap_sim
 enable_eap_sim_file
 enable_eap_sim_pcsc
 enable_eap_aka
+enable_eap_aka_3gpp
 enable_eap_aka_3gpp2
 enable_eap_simaka_sql
 enable_eap_simaka_pseudonym
@@ -1421,6 +1432,8 @@ enable_imc_attestation
 enable_imv_attestation
 enable_imc_swid
 enable_imv_swid
+enable_imc_swima
+enable_imv_swima
 enable_imc_hcd
 enable_imv_hcd
 enable_tnc_ifmap
@@ -1524,12 +1537,16 @@ systemd_daemon_CFLAGS
 systemd_daemon_LIBS
 systemd_journal_CFLAGS
 systemd_journal_LIBS
-tss2_CFLAGS
-tss2_LIBS
+tss2_tabrmd_CFLAGS
+tss2_tabrmd_LIBS
+tss2_socket_CFLAGS
+tss2_socket_LIBS
 json_CFLAGS
 json_LIBS
 gtk_CFLAGS
 gtk_LIBS
+ruby_CFLAGS
+ruby_LIBS
 pcsclite_CFLAGS
 pcsclite_LIBS
 nm_CFLAGS
@@ -2086,7 +2103,7 @@ if test "$ac_init_help" = "long"; then
   # Omit some internal or obsolete options to make the list less imposing.
   # This message is too long to be a string in the A/UX 3.1 sh.
   cat <<_ACEOF
-\`configure' configures strongSwan 5.5.3 to adapt to many kinds of systems.
+\`configure' configures strongSwan 5.6.0 to adapt to many kinds of systems.
 
 Usage: $0 [OPTION]... [VAR=VALUE]...
 
@@ -2157,7 +2174,7 @@ fi
 
 if test -n "$ac_init_help"; then
   case $ac_init_help in
-     short | recursive ) echo "Configuration of strongSwan 5.5.3:";;
+     short | recursive ) echo "Configuration of strongSwan 5.6.0:";;
    esac
   cat <<\_ACEOF
 
@@ -2238,6 +2255,8 @@ Optional Features:
   --enable-eap-sim-pcsc   enable EAP-SIM backend based on a smartcard reader.
                           Requires libpcsclite.
   --enable-eap-aka        enable EAP AKA authentication module.
+  --enable-eap-aka-3gpp   enable EAP AKA backend implementing 3GPP MILENAGE
+                          algorithms in software.
   --enable-eap-aka-3gpp2  enable EAP AKA backend implementing 3GPP2 algorithms
                           in software. Requires libgmp.
   --enable-eap-simaka-sql enable EAP-SIM/AKA backend based on a
@@ -2313,6 +2332,8 @@ Optional Features:
                           enable IMV attestation module.
   --enable-imc-swid       enable IMC swid module.
   --enable-imv-swid       enable IMV swid module.
+  --enable-imc-swima      enable IMC swima module.
+  --enable-imv-swima      enable IMV swima module.
   --enable-imc-hcd        enable IMC hcd module.
   --enable-imv-hcd        enable IMV hcd module.
   --enable-tnc-ifmap      enable TNC IF-MAP module. Requires libxml
@@ -2540,12 +2561,20 @@ Some influential environment variables:
               C compiler flags for systemd_journal, overriding pkg-config
   systemd_journal_LIBS
               linker flags for systemd_journal, overriding pkg-config
-  tss2_CFLAGS C compiler flags for tss2, overriding pkg-config
-  tss2_LIBS   linker flags for tss2, overriding pkg-config
+  tss2_tabrmd_CFLAGS
+              C compiler flags for tss2_tabrmd, overriding pkg-config
+  tss2_tabrmd_LIBS
+              linker flags for tss2_tabrmd, overriding pkg-config
+  tss2_socket_CFLAGS
+              C compiler flags for tss2_socket, overriding pkg-config
+  tss2_socket_LIBS
+              linker flags for tss2_socket, overriding pkg-config
   json_CFLAGS C compiler flags for json, overriding pkg-config
   json_LIBS   linker flags for json, overriding pkg-config
   gtk_CFLAGS  C compiler flags for gtk, overriding pkg-config
   gtk_LIBS    linker flags for gtk, overriding pkg-config
+  ruby_CFLAGS C compiler flags for ruby, overriding pkg-config
+  ruby_LIBS   linker flags for ruby, overriding pkg-config
   pcsclite_CFLAGS
               C compiler flags for pcsclite, overriding pkg-config
   pcsclite_LIBS
@@ -2623,7 +2652,7 @@ fi
 test -n "$ac_init_help" && exit $ac_status
 if $ac_init_version; then
   cat <<\_ACEOF
-strongSwan configure 5.5.3
+strongSwan configure 5.6.0
 generated by GNU Autoconf 2.69
 
 Copyright (C) 2012 Free Software Foundation, Inc.
@@ -3145,7 +3174,7 @@ cat >config.log <<_ACEOF
 This file contains any messages produced by compilers while
 running configure, to aid debugging if configure makes a mistake.
 
-It was created by strongSwan $as_me 5.5.3, which was
+It was created by strongSwan $as_me 5.6.0, which was
 generated by GNU Autoconf 2.69.  Invocation command line was
 
   $ $0 $@
@@ -4008,7 +4037,7 @@ fi
 
 # Define the identity of the package.
  PACKAGE='strongswan'
- VERSION='5.5.3'
+ VERSION='5.6.0'
 
 
 cat >>confdefs.h <<_ACEOF
@@ -5842,6 +5871,22 @@ fi
 
 	disabled_by_default=${disabled_by_default}" eap_aka"
 
+# Check whether --enable-eap-aka-3gpp was given.
+if test "${enable_eap_aka_3gpp+set}" = set; then :
+  enableval=$enable_eap_aka_3gpp; eap_aka_3gpp_given=true
+		if test x$enableval = xyes; then
+			eap_aka_3gpp=true
+		 else
+			eap_aka_3gpp=false
+		fi
+else
+  eap_aka_3gpp=false
+		eap_aka_3gpp_given=false
+
+fi
+
+	disabled_by_default=${disabled_by_default}" eap_aka_3gpp"
+
 # Check whether --enable-eap-aka-3gpp2 was given.
 if test "${enable_eap_aka_3gpp2+set}" = set; then :
   enableval=$enable_eap_aka_3gpp2; eap_aka_3gpp2_given=true
@@ -6758,6 +6803,38 @@ fi
 
 	disabled_by_default=${disabled_by_default}" imv_swid"
 
+# Check whether --enable-imc-swima was given.
+if test "${enable_imc_swima+set}" = set; then :
+  enableval=$enable_imc_swima; imc_swima_given=true
+		if test x$enableval = xyes; then
+			imc_swima=true
+		 else
+			imc_swima=false
+		fi
+else
+  imc_swima=false
+		imc_swima_given=false
+
+fi
+
+	disabled_by_default=${disabled_by_default}" imc_swima"
+
+# Check whether --enable-imv-swima was given.
+if test "${enable_imv_swima+set}" = set; then :
+  enableval=$enable_imv_swima; imv_swima_given=true
+		if test x$enableval = xyes; then
+			imv_swima=true
+		 else
+			imv_swima=false
+		fi
+else
+  imv_swima=false
+		imv_swima_given=false
+
+fi
+
+	disabled_by_default=${disabled_by_default}" imv_swima"
+
 # Check whether --enable-imc-hcd was given.
 if test "${enable_imc_hcd+set}" = set; then :
   enableval=$enable_imc_hcd; imc_hcd_given=true
@@ -7867,6 +7944,7 @@ fi
 if test -z "$CFLAGS"; then
 	CFLAGS="-g -O2 -Wall -Wno-format -Wno-format-security -Wno-pointer-sign"
 fi
+
 ac_ext=c
 ac_cpp='$CPP $CPPFLAGS'
 ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
@@ -18041,7 +18119,7 @@ if test x$eap_tls = xtrue -o x$eap_ttls = xtrue -o x$eap_peap = xtrue -o x$tnc_t
 	tls=true;
 fi
 
-if test x$imc_test = xtrue -o x$imv_test = xtrue -o x$imc_scanner = xtrue -o x$imv_scanner = xtrue -o x$imc_os = xtrue -o x$imv_os = xtrue -o x$imc_attestation = xtrue -o x$imv_attestation = xtrue -o x$imc_swid = xtrue -o x$imv_swid = xtrue -o x$imc_hcd = xtrue -o x$imv_hcd = xtrue; then
+if test x$imc_test = xtrue -o x$imv_test = xtrue -o x$imc_scanner = xtrue -o x$imv_scanner = xtrue -o x$imc_os = xtrue -o x$imv_os = xtrue -o x$imc_attestation = xtrue -o x$imv_attestation = xtrue -o x$imc_swid = xtrue -o x$imv_swid = xtrue -o x$imc_swima = xtrue -o x$imv_swima = xtrue -o x$imc_hcd = xtrue -o x$imv_hcd = xtrue; then
 	imcv=true;
 fi
 
@@ -19688,8 +19766,7 @@ else
 $as_echo "no" >&6; }
 		# GCC, but not MinGW requires -rdynamic for plugins
 		if test x$windows != xtrue; then
-			PLUGIN_CFLAGS=-rdynamic
-
+			PLUGIN_CFLAGS="$PLUGIN_CFLAGS -rdynamic"
 		fi
 
 
@@ -20853,11 +20930,84 @@ fi
 if test x$tss_tss2 = xtrue; then
 
 pkg_failed=no
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for tss2" >&5
-$as_echo_n "checking for tss2... " >&6; }
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for tss2_tabrmd" >&5
+$as_echo_n "checking for tss2_tabrmd... " >&6; }
+
+if test -n "$tss2_tabrmd_CFLAGS"; then
+    pkg_cv_tss2_tabrmd_CFLAGS="$tss2_tabrmd_CFLAGS"
+ elif test -n "$PKG_CONFIG"; then
+    if test -n "$PKG_CONFIG" && \
+    { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"tcti-tabrmd\""; } >&5
+  ($PKG_CONFIG --exists --print-errors "tcti-tabrmd") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; then
+  pkg_cv_tss2_tabrmd_CFLAGS=`$PKG_CONFIG --cflags "tcti-tabrmd" 2>/dev/null`
+		      test "x$?" != "x0" && pkg_failed=yes
+else
+  pkg_failed=yes
+fi
+ else
+    pkg_failed=untried
+fi
+if test -n "$tss2_tabrmd_LIBS"; then
+    pkg_cv_tss2_tabrmd_LIBS="$tss2_tabrmd_LIBS"
+ elif test -n "$PKG_CONFIG"; then
+    if test -n "$PKG_CONFIG" && \
+    { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"tcti-tabrmd\""; } >&5
+  ($PKG_CONFIG --exists --print-errors "tcti-tabrmd") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; then
+  pkg_cv_tss2_tabrmd_LIBS=`$PKG_CONFIG --libs "tcti-tabrmd" 2>/dev/null`
+		      test "x$?" != "x0" && pkg_failed=yes
+else
+  pkg_failed=yes
+fi
+ else
+    pkg_failed=untried
+fi
+
+
+
+if test $pkg_failed = yes; then
+   	{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then
+        _pkg_short_errors_supported=yes
+else
+        _pkg_short_errors_supported=no
+fi
+        if test $_pkg_short_errors_supported = yes; then
+	        tss2_tabrmd_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "tcti-tabrmd" 2>&1`
+        else
+	        tss2_tabrmd_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "tcti-tabrmd" 2>&1`
+        fi
+	# Put the nasty error message in config.log where it belongs
+	echo "$tss2_tabrmd_PKG_ERRORS" >&5
+
+	tss2_tabrmd=false
+elif test $pkg_failed = untried; then
+     	{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+	tss2_tabrmd=false
+else
+	tss2_tabrmd_CFLAGS=$pkg_cv_tss2_tabrmd_CFLAGS
+	tss2_tabrmd_LIBS=$pkg_cv_tss2_tabrmd_LIBS
+        { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+	tss2_tabrmd=true;
+$as_echo "#define TSS2_TCTI_TABRMD /**/" >>confdefs.h
+
+fi
+
+pkg_failed=no
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for tss2_socket" >&5
+$as_echo_n "checking for tss2_socket... " >&6; }
 
-if test -n "$tss2_CFLAGS"; then
-    pkg_cv_tss2_CFLAGS="$tss2_CFLAGS"
+if test -n "$tss2_socket_CFLAGS"; then
+    pkg_cv_tss2_socket_CFLAGS="$tss2_socket_CFLAGS"
  elif test -n "$PKG_CONFIG"; then
     if test -n "$PKG_CONFIG" && \
     { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"tcti-socket\""; } >&5
@@ -20865,7 +21015,7 @@ if test -n "$tss2_CFLAGS"; then
   ac_status=$?
   $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
   test $ac_status = 0; }; then
-  pkg_cv_tss2_CFLAGS=`$PKG_CONFIG --cflags "tcti-socket" 2>/dev/null`
+  pkg_cv_tss2_socket_CFLAGS=`$PKG_CONFIG --cflags "tcti-socket" 2>/dev/null`
 		      test "x$?" != "x0" && pkg_failed=yes
 else
   pkg_failed=yes
@@ -20873,8 +21023,8 @@ fi
  else
     pkg_failed=untried
 fi
-if test -n "$tss2_LIBS"; then
-    pkg_cv_tss2_LIBS="$tss2_LIBS"
+if test -n "$tss2_socket_LIBS"; then
+    pkg_cv_tss2_socket_LIBS="$tss2_socket_LIBS"
  elif test -n "$PKG_CONFIG"; then
     if test -n "$PKG_CONFIG" && \
     { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"tcti-socket\""; } >&5
@@ -20882,7 +21032,7 @@ if test -n "$tss2_LIBS"; then
   ac_status=$?
   $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
   test $ac_status = 0; }; then
-  pkg_cv_tss2_LIBS=`$PKG_CONFIG --libs "tcti-socket" 2>/dev/null`
+  pkg_cv_tss2_socket_LIBS=`$PKG_CONFIG --libs "tcti-socket" 2>/dev/null`
 		      test "x$?" != "x0" && pkg_failed=yes
 else
   pkg_failed=yes
@@ -20903,52 +21053,44 @@ else
         _pkg_short_errors_supported=no
 fi
         if test $_pkg_short_errors_supported = yes; then
-	        tss2_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "tcti-socket" 2>&1`
+	        tss2_socket_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "tcti-socket" 2>&1`
         else
-	        tss2_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "tcti-socket" 2>&1`
+	        tss2_socket_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "tcti-socket" 2>&1`
         fi
 	# Put the nasty error message in config.log where it belongs
-	echo "$tss2_PKG_ERRORS" >&5
-
-	as_fn_error $? "Package requirements (tcti-socket) were not met:
+	echo "$tss2_socket_PKG_ERRORS" >&5
 
-$tss2_PKG_ERRORS
-
-Consider adjusting the PKG_CONFIG_PATH environment variable if you
-installed software in a non-standard prefix.
-
-Alternatively, you may set the environment variables tss2_CFLAGS
-and tss2_LIBS to avoid the need to call pkg-config.
-See the pkg-config man page for more details." "$LINENO" 5
+	tss2_socket=false
 elif test $pkg_failed = untried; then
      	{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
 $as_echo "no" >&6; }
-	{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
-$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
-as_fn_error $? "The pkg-config script could not be found or is too old.  Make sure it
-is in your PATH or set the PKG_CONFIG environment variable to the full
-path to pkg-config.
-
-Alternatively, you may set the environment variables tss2_CFLAGS
-and tss2_LIBS to avoid the need to call pkg-config.
-See the pkg-config man page for more details.
-
-To get pkg-config, see <http://pkg-config.freedesktop.org/>.
-See \`config.log' for more details" "$LINENO" 5; }
+	tss2_socket=false
 else
-	tss2_CFLAGS=$pkg_cv_tss2_CFLAGS
-	tss2_LIBS=$pkg_cv_tss2_LIBS
+	tss2_socket_CFLAGS=$pkg_cv_tss2_socket_CFLAGS
+	tss2_socket_LIBS=$pkg_cv_tss2_socket_LIBS
         { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
 $as_echo "yes" >&6; }
+	tss2_socket=true;
+$as_echo "#define TSS2_TCTI_SOCKET /**/" >>confdefs.h
+
+fi
+	if test x$tss2_tabrmd = xtrue -o x$tss2_socket = xtrue; then
 
 $as_echo "#define TSS_TSS2 /**/" >>confdefs.h
 
-fi
+		tss2_CFLAGS="$tss2_tabrmd_CFLAGS $tss2_socket_CFLAGS"
 
+		tss2_LIBS="$tss2_tabrmd_LIBS $tss2_socket_LIBS"
 
+	else
+		{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "no TSS2 TCTI library detected
+See \`config.log' for more details" "$LINENO" 5; }
+	fi
 fi
 
-if test x$imv_swid = xtrue; then
+if test x$imc_swima = xtrue -o $imv_swima = xtrue -o x$imv_swid = xtrue; then
 
 pkg_failed=no
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for json" >&5
@@ -21340,64 +21482,99 @@ fi
   test -n "$RUBY" && break
 done
 
-	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for Ruby header files" >&5
-$as_echo_n "checking for Ruby header files... " >&6; }
-	if test -n "$RUBY"; then
-		RUBYINCLUDE=
-		RUBYDIR=`($RUBY -r rbconfig -e 'print RbConfig::CONFIG["rubyhdrdir"] || ""') 2>/dev/null`
-		if test -n "$RUBYDIR" -a -r "$RUBYDIR/ruby.h"; then
-			RUBYARCH=`($RUBY -r rbconfig -e 'print RbConfig::CONFIG["arch"] || ""') 2>/dev/null`
-			if test -n "$RUBYARCH"; then
-				{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $RUBYDIR" >&5
-$as_echo "$RUBYDIR" >&6; }
-				RUBYINCLUDE="-I$RUBYDIR -I$RUBYDIR/$RUBYARCH"
-			fi
-		else
-			RUBYDIR=`($RUBY -r rbconfig -e 'print RbConfig::CONFIG["archdir"] || ""') 2>/dev/null`
-			if test -n "$RUBYDIR" -a -r "$RUBYDIR/ruby.h"; then
-				{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $RUBYDIR" >&5
-$as_echo "$RUBYDIR" >&6; }
-				RUBYINCLUDE="-I$RUBYDIR"
-			fi
-		fi
-		if test -z "$RUBYINCLUDE"; then
-			as_fn_error $? "ruby.h not found" "$LINENO" 5
-		fi
 
-	else
-		as_fn_error $? "don't know how to run ruby" "$LINENO" 5
-	fi
-	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for libruby" >&5
-$as_echo_n "checking for libruby... " >&6; }
-	saved_LIBS=$LIBS
-	LIBS=`($RUBY -r rbconfig -e 'print RbConfig::CONFIG["LIBRUBYARG_SHARED"] || ""') 2>/dev/null`
-	cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
+pkg_failed=no
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for ruby" >&5
+$as_echo_n "checking for ruby... " >&6; }
 
-/* Override any GCC internal prototype to avoid an error.
-   Use char because int might match the return type of a GCC
-   builtin and then its argument prototype would still apply.  */
-#ifdef __cplusplus
-extern "C"
-#endif
-char ruby_init ();
-int
-main ()
-{
-return ruby_init ();
-  ;
-  return 0;
-}
-_ACEOF
-if ac_fn_c_try_link "$LINENO"; then :
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LIBS" >&5
-$as_echo "$LIBS" >&6; }; RUBYLIB=$LIBS
+if test -n "$ruby_CFLAGS"; then
+    pkg_cv_ruby_CFLAGS="$ruby_CFLAGS"
+ elif test -n "$PKG_CONFIG"; then
+    if test -n "$PKG_CONFIG" && \
+    { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"ruby\""; } >&5
+  ($PKG_CONFIG --exists --print-errors "ruby") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; then
+  pkg_cv_ruby_CFLAGS=`$PKG_CONFIG --cflags "ruby" 2>/dev/null`
+		      test "x$?" != "x0" && pkg_failed=yes
 else
-  as_fn_error $? "not found" "$LINENO" 5
+  pkg_failed=yes
 fi
-rm -f core conftest.err conftest.$ac_objext \
-    conftest$ac_exeext conftest.$ac_ext
+ else
+    pkg_failed=untried
+fi
+if test -n "$ruby_LIBS"; then
+    pkg_cv_ruby_LIBS="$ruby_LIBS"
+ elif test -n "$PKG_CONFIG"; then
+    if test -n "$PKG_CONFIG" && \
+    { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"ruby\""; } >&5
+  ($PKG_CONFIG --exists --print-errors "ruby") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; then
+  pkg_cv_ruby_LIBS=`$PKG_CONFIG --libs "ruby" 2>/dev/null`
+		      test "x$?" != "x0" && pkg_failed=yes
+else
+  pkg_failed=yes
+fi
+ else
+    pkg_failed=untried
+fi
+
 
+
+if test $pkg_failed = yes; then
+   	{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then
+        _pkg_short_errors_supported=yes
+else
+        _pkg_short_errors_supported=no
+fi
+        if test $_pkg_short_errors_supported = yes; then
+	        ruby_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "ruby" 2>&1`
+        else
+	        ruby_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "ruby" 2>&1`
+        fi
+	# Put the nasty error message in config.log where it belongs
+	echo "$ruby_PKG_ERRORS" >&5
+
+	as_fn_error $? "Package requirements (ruby) were not met:
+
+$ruby_PKG_ERRORS
+
+Consider adjusting the PKG_CONFIG_PATH environment variable if you
+installed software in a non-standard prefix.
+
+Alternatively, you may set the environment variables ruby_CFLAGS
+and ruby_LIBS to avoid the need to call pkg-config.
+See the pkg-config man page for more details." "$LINENO" 5
+elif test $pkg_failed = untried; then
+     	{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+	{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "The pkg-config script could not be found or is too old.  Make sure it
+is in your PATH or set the PKG_CONFIG environment variable to the full
+path to pkg-config.
+
+Alternatively, you may set the environment variables ruby_CFLAGS
+and ruby_LIBS to avoid the need to call pkg-config.
+See the pkg-config man page for more details.
+
+To get pkg-config, see <http://pkg-config.freedesktop.org/>.
+See \`config.log' for more details" "$LINENO" 5; }
+else
+	ruby_CFLAGS=$pkg_cv_ruby_CFLAGS
+	ruby_LIBS=$pkg_cv_ruby_LIBS
+        { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+fi
+	saved_LIBS=$LIBS
+	LIBS=$ruby_LIBS
 	for ac_func in rb_errinfo
 do :
   ac_fn_c_check_func "$LINENO" "rb_errinfo" "ac_cv_func_rb_errinfo"
@@ -22859,6 +23036,7 @@ fi
 	COVERAGE_LDFLAGS="-fprofile-arcs"
 
 
+	PLUGIN_CFLAGS="$PLUGIN_CFLAGS $COVERAGE_CFLAGS"
 
 	{ $as_echo "$as_me:${as_lineno-$LINENO}: coverage enabled, adding \"-g -O0\" to CFLAGS" >&5
 $as_echo "$as_me: coverage enabled, adding \"-g -O0\" to CFLAGS" >&6;}
@@ -23353,6 +23531,7 @@ if test x$acert = xtrue; then
 if test x$pubkey = xtrue; then
 		s_plugins=${s_plugins}" pubkey"
 		charon_plugins=${charon_plugins}" pubkey"
+		pki_plugins=${pki_plugins}" pubkey"
 		cmd_plugins=${cmd_plugins}" pubkey"
 		aikgen_plugins=${aikgen_plugins}" pubkey"
 
@@ -23888,6 +24067,12 @@ if test x$eap_aka = xtrue; then
 
 	fi
 
+if test x$eap_aka_3gpp = xtrue; then
+		c_plugins=${c_plugins}" eap-aka-3gpp"
+		charon_plugins=${charon_plugins}" eap-aka-3gpp"
+
+	fi
+
 if test x$eap_aka_3gpp2 = xtrue; then
 		c_plugins=${c_plugins}" eap-aka-3gpp2"
 		charon_plugins=${charon_plugins}" eap-aka-3gpp2"
@@ -25008,6 +25193,14 @@ else
   USE_EAP_AKA_FALSE=
 fi
 
+ if test x$eap_aka_3gpp = xtrue; then
+  USE_EAP_AKA_3GPP_TRUE=
+  USE_EAP_AKA_3GPP_FALSE='#'
+else
+  USE_EAP_AKA_3GPP_TRUE='#'
+  USE_EAP_AKA_3GPP_FALSE=
+fi
+
  if test x$eap_aka_3gpp2 = xtrue; then
   USE_EAP_AKA_3GPP2_TRUE=
   USE_EAP_AKA_3GPP2_FALSE='#'
@@ -25248,6 +25441,22 @@ else
   USE_IMV_SWID_FALSE=
 fi
 
+ if test x$imc_swima = xtrue; then
+  USE_IMC_SWIMA_TRUE=
+  USE_IMC_SWIMA_FALSE='#'
+else
+  USE_IMC_SWIMA_TRUE='#'
+  USE_IMC_SWIMA_FALSE=
+fi
+
+ if test x$imv_swima = xtrue; then
+  USE_IMV_SWIMA_TRUE=
+  USE_IMV_SWIMA_FALSE='#'
+else
+  USE_IMV_SWIMA_TRUE='#'
+  USE_IMV_SWIMA_FALSE=
+fi
+
  if test x$imc_hcd = xtrue; then
   USE_IMC_HCD_TRUE=
   USE_IMC_HCD_FALSE='#'
@@ -25840,6 +26049,11 @@ if test x$fuzzing = xtrue; then
 $as_echo "#define USE_FUZZING /**/" >>confdefs.h
 
 fi
+if test x$imc_swima = xtrue -o x$imv_swima = xtrue -o x$imv_swid = xtrue ; then
+
+$as_echo "#define USE_JSON /**/" >>confdefs.h
+
+fi
 
 # ====================================================
 #  options for enabled modules (see conf/Makefile.am)
@@ -25886,6 +26100,9 @@ fi
 if test -z "$USE_SWANCTL_TRUE"; then :
   strongswan_options=${strongswan_options}" swanctl"
 fi
+if test -z "$USE_SYSTEMD_TRUE"; then :
+  strongswan_options=${strongswan_options}" charon-systemd"
+fi
 
 
 
@@ -25893,14 +26110,14 @@ fi
 #  build Makefiles
 # =================
 
-ac_config_files="$ac_config_files Makefile conf/Makefile fuzz/Makefile man/Makefile init/Makefile init/systemd/Makefile init/systemd-swanctl/Makefile src/Makefile src/include/Makefile src/libstrongswan/Makefile src/libstrongswan/math/libnttfft/Makefile src/libstrongswan/math/libnttfft/tests/Makefile src/libstrongswan/plugins/aes/Makefile src/libstrongswan/plugins/cmac/Makefile src/libstrongswan/plugins/des/Makefile src/libstrongswan/plugins/blowfish/Makefile src/libstrongswan/plugins/rc2 [...]
+ac_config_files="$ac_config_files Makefile conf/Makefile fuzz/Makefile man/Makefile init/Makefile init/systemd/Makefile init/systemd-swanctl/Makefile src/Makefile src/include/Makefile src/libstrongswan/Makefile src/libstrongswan/math/libnttfft/Makefile src/libstrongswan/math/libnttfft/tests/Makefile src/libstrongswan/plugins/aes/Makefile src/libstrongswan/plugins/cmac/Makefile src/libstrongswan/plugins/des/Makefile src/libstrongswan/plugins/blowfish/Makefile src/libstrongswan/plugins/rc2 [...]
 
 
 # =================
 #  build man pages
 # =================
 
-ac_config_files="$ac_config_files conf/strongswan.conf.5.head conf/strongswan.conf.5.tail man/ipsec.conf.5 man/ipsec.secrets.5 src/charon-cmd/charon-cmd.8 src/pki/man/pki.1 src/pki/man/pki---acert.1 src/pki/man/pki---dn.1 src/pki/man/pki---gen.1 src/pki/man/pki---issue.1 src/pki/man/pki---keyid.1 src/pki/man/pki---pkcs12.1 src/pki/man/pki---pkcs7.1 src/pki/man/pki---print.1 src/pki/man/pki---pub.1 src/pki/man/pki---req.1 src/pki/man/pki---self.1 src/pki/man/pki---signcrl.1 src/pki/man/pk [...]
+ac_config_files="$ac_config_files conf/strongswan.conf.5.head conf/strongswan.conf.5.tail man/ipsec.conf.5 man/ipsec.secrets.5 src/charon-cmd/charon-cmd.8 src/pki/man/pki.1 src/pki/man/pki---acert.1 src/pki/man/pki---dn.1 src/pki/man/pki---gen.1 src/pki/man/pki---issue.1 src/pki/man/pki---keyid.1 src/pki/man/pki---pkcs12.1 src/pki/man/pki---pkcs7.1 src/pki/man/pki---print.1 src/pki/man/pki---pub.1 src/pki/man/pki---req.1 src/pki/man/pki---self.1 src/pki/man/pki---signcrl.1 src/pki/man/pk [...]
 
 
 cat >confcache <<\_ACEOF
@@ -26465,6 +26682,10 @@ if test -z "${USE_EAP_AKA_TRUE}" && test -z "${USE_EAP_AKA_FALSE}"; then
   as_fn_error $? "conditional \"USE_EAP_AKA\" was never defined.
 Usually this means the macro was only invoked conditionally." "$LINENO" 5
 fi
+if test -z "${USE_EAP_AKA_3GPP_TRUE}" && test -z "${USE_EAP_AKA_3GPP_FALSE}"; then
+  as_fn_error $? "conditional \"USE_EAP_AKA_3GPP\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
 if test -z "${USE_EAP_AKA_3GPP2_TRUE}" && test -z "${USE_EAP_AKA_3GPP2_FALSE}"; then
   as_fn_error $? "conditional \"USE_EAP_AKA_3GPP2\" was never defined.
 Usually this means the macro was only invoked conditionally." "$LINENO" 5
@@ -26585,6 +26806,14 @@ if test -z "${USE_IMV_SWID_TRUE}" && test -z "${USE_IMV_SWID_FALSE}"; then
   as_fn_error $? "conditional \"USE_IMV_SWID\" was never defined.
 Usually this means the macro was only invoked conditionally." "$LINENO" 5
 fi
+if test -z "${USE_IMC_SWIMA_TRUE}" && test -z "${USE_IMC_SWIMA_FALSE}"; then
+  as_fn_error $? "conditional \"USE_IMC_SWIMA\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${USE_IMV_SWIMA_TRUE}" && test -z "${USE_IMV_SWIMA_FALSE}"; then
+  as_fn_error $? "conditional \"USE_IMV_SWIMA\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
 if test -z "${USE_IMC_HCD_TRUE}" && test -z "${USE_IMC_HCD_FALSE}"; then
   as_fn_error $? "conditional \"USE_IMC_HCD\" was never defined.
 Usually this means the macro was only invoked conditionally." "$LINENO" 5
@@ -27254,7 +27483,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
 # report actual input values of CONFIG_FILES etc. instead of their
 # values after options handling.
 ac_log="
-This file was extended by strongSwan $as_me 5.5.3, which was
+This file was extended by strongSwan $as_me 5.6.0, which was
 generated by GNU Autoconf 2.69.  Invocation command line was
 
   CONFIG_FILES    = $CONFIG_FILES
@@ -27320,7 +27549,7 @@ _ACEOF
 cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
 ac_cs_version="\\
-strongSwan config.status 5.5.3
+strongSwan config.status 5.6.0
 configured by $0, generated by GNU Autoconf 2.69,
   with options \\"\$ac_cs_config\\"
 
@@ -27832,6 +28061,8 @@ do
     "src/libimcv/plugins/imv_attestation/Makefile") CONFIG_FILES="$CONFIG_FILES src/libimcv/plugins/imv_attestation/Makefile" ;;
     "src/libimcv/plugins/imc_swid/Makefile") CONFIG_FILES="$CONFIG_FILES src/libimcv/plugins/imc_swid/Makefile" ;;
     "src/libimcv/plugins/imv_swid/Makefile") CONFIG_FILES="$CONFIG_FILES src/libimcv/plugins/imv_swid/Makefile" ;;
+    "src/libimcv/plugins/imc_swima/Makefile") CONFIG_FILES="$CONFIG_FILES src/libimcv/plugins/imc_swima/Makefile" ;;
+    "src/libimcv/plugins/imv_swima/Makefile") CONFIG_FILES="$CONFIG_FILES src/libimcv/plugins/imv_swima/Makefile" ;;
     "src/libimcv/plugins/imc_hcd/Makefile") CONFIG_FILES="$CONFIG_FILES src/libimcv/plugins/imc_hcd/Makefile" ;;
     "src/libimcv/plugins/imv_hcd/Makefile") CONFIG_FILES="$CONFIG_FILES src/libimcv/plugins/imv_hcd/Makefile" ;;
     "src/charon/Makefile") CONFIG_FILES="$CONFIG_FILES src/charon/Makefile" ;;
@@ -27842,6 +28073,7 @@ do
     "src/charon-systemd/Makefile") CONFIG_FILES="$CONFIG_FILES src/charon-systemd/Makefile" ;;
     "src/libcharon/Makefile") CONFIG_FILES="$CONFIG_FILES src/libcharon/Makefile" ;;
     "src/libcharon/plugins/eap_aka/Makefile") CONFIG_FILES="$CONFIG_FILES src/libcharon/plugins/eap_aka/Makefile" ;;
+    "src/libcharon/plugins/eap_aka_3gpp/Makefile") CONFIG_FILES="$CONFIG_FILES src/libcharon/plugins/eap_aka_3gpp/Makefile" ;;
     "src/libcharon/plugins/eap_aka_3gpp2/Makefile") CONFIG_FILES="$CONFIG_FILES src/libcharon/plugins/eap_aka_3gpp2/Makefile" ;;
     "src/libcharon/plugins/eap_dynamic/Makefile") CONFIG_FILES="$CONFIG_FILES src/libcharon/plugins/eap_dynamic/Makefile" ;;
     "src/libcharon/plugins/eap_identity/Makefile") CONFIG_FILES="$CONFIG_FILES src/libcharon/plugins/eap_identity/Makefile" ;;
@@ -27935,6 +28167,7 @@ do
     "src/checksum/Makefile") CONFIG_FILES="$CONFIG_FILES src/checksum/Makefile" ;;
     "src/conftest/Makefile") CONFIG_FILES="$CONFIG_FILES src/conftest/Makefile" ;;
     "src/pt-tls-client/Makefile") CONFIG_FILES="$CONFIG_FILES src/pt-tls-client/Makefile" ;;
+    "src/sw-collector/Makefile") CONFIG_FILES="$CONFIG_FILES src/sw-collector/Makefile" ;;
     "src/swanctl/Makefile") CONFIG_FILES="$CONFIG_FILES src/swanctl/Makefile" ;;
     "scripts/Makefile") CONFIG_FILES="$CONFIG_FILES scripts/Makefile" ;;
     "testing/Makefile") CONFIG_FILES="$CONFIG_FILES testing/Makefile" ;;
@@ -27960,6 +28193,8 @@ do
     "src/swanctl/swanctl.8") CONFIG_FILES="$CONFIG_FILES src/swanctl/swanctl.8" ;;
     "src/swanctl/swanctl.conf.5.head") CONFIG_FILES="$CONFIG_FILES src/swanctl/swanctl.conf.5.head" ;;
     "src/swanctl/swanctl.conf.5.tail") CONFIG_FILES="$CONFIG_FILES src/swanctl/swanctl.conf.5.tail" ;;
+    "src/pt-tls-client/pt-tls-client.1") CONFIG_FILES="$CONFIG_FILES src/pt-tls-client/pt-tls-client.1" ;;
+    "src/sw-collector/sw-collector.8") CONFIG_FILES="$CONFIG_FILES src/sw-collector/sw-collector.8" ;;
 
   *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;;
   esac
diff --git a/configure.ac b/configure.ac
index 1ca254e..45277d9 100644
--- a/configure.ac
+++ b/configure.ac
@@ -19,7 +19,7 @@
 #  initialize & set some vars
 # ============================
 
-AC_INIT([strongSwan],[5.5.3])
+AC_INIT([strongSwan],[5.6.0])
 AM_INIT_AUTOMAKE(m4_esyscmd([
 	echo tar-ustar
 	echo subdir-objects
@@ -185,6 +185,7 @@ ARG_ENABL_SET([eap-sim],        [enable SIM authentication module for EAP.])
 ARG_ENABL_SET([eap-sim-file],   [enable EAP-SIM backend based on a triplet file.])
 ARG_ENABL_SET([eap-sim-pcsc],   [enable EAP-SIM backend based on a smartcard reader. Requires libpcsclite.])
 ARG_ENABL_SET([eap-aka],        [enable EAP AKA authentication module.])
+ARG_ENABL_SET([eap-aka-3gpp],   [enable EAP AKA backend implementing 3GPP MILENAGE algorithms in software.])
 ARG_ENABL_SET([eap-aka-3gpp2],  [enable EAP AKA backend implementing 3GPP2 algorithms in software. Requires libgmp.])
 ARG_ENABL_SET([eap-simaka-sql], [enable EAP-SIM/AKA backend based on a triplet/quintuplet SQL database.])
 ARG_ENABL_SET([eap-simaka-pseudonym], [enable EAP-SIM/AKA pseudonym storage plugin.])
@@ -246,6 +247,8 @@ ARG_ENABL_SET([imc-attestation],[enable IMC attestation module.])
 ARG_ENABL_SET([imv-attestation],[enable IMV attestation module.])
 ARG_ENABL_SET([imc-swid],       [enable IMC swid module.])
 ARG_ENABL_SET([imv-swid],       [enable IMV swid module.])
+ARG_ENABL_SET([imc-swima],      [enable IMC swima module.])
+ARG_ENABL_SET([imv-swima],      [enable IMV swima module.])
 ARG_ENABL_SET([imc-hcd],        [enable IMC hcd module.])
 ARG_ENABL_SET([imv-hcd],        [enable IMV hcd module.])
 ARG_ENABL_SET([tnc-ifmap],      [enable TNC IF-MAP module. Requires libxml])
@@ -350,6 +353,7 @@ fi
 if test -z "$CFLAGS"; then
 	CFLAGS="-g -O2 -Wall -Wno-format -Wno-format-security -Wno-pointer-sign"
 fi
+AC_SUBST(PLUGIN_CFLAGS)
 AC_PROG_CC
 AM_PROG_CC_C_O
 
@@ -420,7 +424,7 @@ if test x$eap_tls = xtrue -o x$eap_ttls = xtrue -o x$eap_peap = xtrue -o x$tnc_t
 	tls=true;
 fi
 
-if test x$imc_test = xtrue -o x$imv_test = xtrue -o x$imc_scanner = xtrue -o x$imv_scanner = xtrue -o x$imc_os = xtrue -o x$imv_os = xtrue -o x$imc_attestation = xtrue -o x$imv_attestation = xtrue -o x$imc_swid = xtrue -o x$imv_swid = xtrue -o x$imc_hcd = xtrue -o x$imv_hcd = xtrue; then
+if test x$imc_test = xtrue -o x$imv_test = xtrue -o x$imc_scanner = xtrue -o x$imv_scanner = xtrue -o x$imc_os = xtrue -o x$imv_os = xtrue -o x$imc_attestation = xtrue -o x$imv_attestation = xtrue -o x$imc_swid = xtrue -o x$imv_swid = xtrue -o x$imc_swima = xtrue -o x$imv_swima = xtrue -o x$imc_hcd = xtrue -o x$imv_hcd = xtrue; then
 	imcv=true;
 fi
 
@@ -877,7 +881,7 @@ AC_COMPILE_IFELSE(
 		AC_MSG_RESULT([no])
 		# GCC, but not MinGW requires -rdynamic for plugins
 		if test x$windows != xtrue; then
-			AC_SUBST(PLUGIN_CFLAGS, [-rdynamic])
+			PLUGIN_CFLAGS="$PLUGIN_CFLAGS -rdynamic"
 		fi
 	]
 )
@@ -994,12 +998,22 @@ if test x$tss_trousers = xtrue; then
 fi
 
 if test x$tss_tss2 = xtrue; then
-	PKG_CHECK_MODULES(tss2, [tcti-socket], [AC_DEFINE([TSS_TSS2], [], [use TSS 2.0 libraries])])
-	AC_SUBST(tss2_CFLAGS)
-	AC_SUBST(tss2_LIBS)
+	PKG_CHECK_MODULES(tss2_tabrmd, [tcti-tabrmd],
+		[tss2_tabrmd=true; AC_DEFINE([TSS2_TCTI_TABRMD], [], [use TCTI Access Broker and Resource Mamager])],
+		[tss2_tabrmd=false])
+	PKG_CHECK_MODULES(tss2_socket, [tcti-socket],
+		[tss2_socket=true; AC_DEFINE([TSS2_TCTI_SOCKET], [], [use TCTI Sockets])],
+		[tss2_socket=false])
+	if test x$tss2_tabrmd = xtrue -o x$tss2_socket = xtrue; then
+		AC_DEFINE([TSS_TSS2], [], [use TSS 2.0 libraries])
+		AC_SUBST(tss2_CFLAGS, "$tss2_tabrmd_CFLAGS $tss2_socket_CFLAGS")
+		AC_SUBST(tss2_LIBS, "$tss2_tabrmd_LIBS $tss2_socket_LIBS")
+	else
+		AC_MSG_FAILURE([no TSS2 TCTI library detected])
+	fi
 fi
 
-if test x$imv_swid = xtrue; then
+if test x$imc_swima = xtrue -o $imv_swima = xtrue -o x$imv_swid = xtrue; then
 	PKG_CHECK_MODULES(json, [json-c], [],
 		[PKG_CHECK_MODULES(json, [json])])
 	AC_SUBST(json_CFLAGS)
@@ -1011,37 +1025,9 @@ if test x$dumm = xtrue; then
 	AC_SUBST(gtk_CFLAGS)
 	AC_SUBST(gtk_LIBS)
 	AC_CHECK_PROGS(RUBY, ruby)
-	AC_MSG_CHECKING([for Ruby header files])
-	if test -n "$RUBY"; then
-		RUBYINCLUDE=
-		RUBYDIR=`($RUBY -r rbconfig -e 'print RbConfig::CONFIG[["rubyhdrdir"]] || ""') 2>/dev/null`
-		if test -n "$RUBYDIR" -a -r "$RUBYDIR/ruby.h"; then
-			RUBYARCH=`($RUBY -r rbconfig -e 'print RbConfig::CONFIG[["arch"]] || ""') 2>/dev/null`
-			if test -n "$RUBYARCH"; then
-				AC_MSG_RESULT([$RUBYDIR])
-				RUBYINCLUDE="-I$RUBYDIR -I$RUBYDIR/$RUBYARCH"
-			fi
-		else
-			RUBYDIR=`($RUBY -r rbconfig -e 'print RbConfig::CONFIG[["archdir"]] || ""') 2>/dev/null`
-			if test -n "$RUBYDIR" -a -r "$RUBYDIR/ruby.h"; then
-				AC_MSG_RESULT([$RUBYDIR])
-				RUBYINCLUDE="-I$RUBYDIR"
-			fi
-		fi
-		if test -z "$RUBYINCLUDE"; then
-			AC_MSG_ERROR([ruby.h not found])
-		fi
-		AC_SUBST(RUBYINCLUDE)
-	else
-		AC_MSG_ERROR([don't know how to run ruby])
-	fi
-	AC_MSG_CHECKING([for libruby])
+	PKG_CHECK_MODULES(ruby, [ruby])
 	saved_LIBS=$LIBS
-	LIBS=`($RUBY -r rbconfig -e 'print RbConfig::CONFIG[["LIBRUBYARG_SHARED"]] || ""') 2>/dev/null`
-	AC_TRY_LINK_FUNC(ruby_init,
-		[AC_MSG_RESULT([$LIBS]); RUBYLIB=$LIBS],
-		[AC_MSG_ERROR([not found])])
-	AC_SUBST(RUBYLIB)
+	LIBS=$ruby_LIBS
 	AC_CHECK_FUNCS(rb_errinfo)
 	LIBS=$saved_LIBS
 fi
@@ -1261,6 +1247,7 @@ if test x$coverage = xtrue; then
 	COVERAGE_LDFLAGS="-fprofile-arcs"
 	AC_SUBST(COVERAGE_CFLAGS)
 	AC_SUBST(COVERAGE_LDFLAGS)
+	PLUGIN_CFLAGS="$PLUGIN_CFLAGS $COVERAGE_CFLAGS"
 
 	AC_MSG_NOTICE([coverage enabled, adding "-g -O0" to CFLAGS])
 	CFLAGS="${CFLAGS} -g -O0"
@@ -1362,7 +1349,7 @@ ADD_PLUGIN([x509],                 [s charon scepclient pki scripts attest nm cm
 ADD_PLUGIN([revocation],           [s charon pki nm cmd])
 ADD_PLUGIN([constraints],          [s charon nm cmd])
 ADD_PLUGIN([acert],                [s charon])
-ADD_PLUGIN([pubkey],               [s charon cmd aikgen])
+ADD_PLUGIN([pubkey],               [s charon pki cmd aikgen])
 ADD_PLUGIN([pkcs1],                [s charon scepclient pki scripts manager medsrv attest nm cmd aikgen fuzz])
 ADD_PLUGIN([pkcs7],                [s charon scepclient pki scripts nm cmd])
 ADD_PLUGIN([pkcs8],                [s charon scepclient pki scripts manager medsrv attest nm cmd])
@@ -1425,6 +1412,7 @@ ADD_PLUGIN([eap-sim],              [c charon])
 ADD_PLUGIN([eap-sim-file],         [c charon])
 ADD_PLUGIN([eap-sim-pcsc],         [c charon])
 ADD_PLUGIN([eap-aka],              [c charon])
+ADD_PLUGIN([eap-aka-3gpp],         [c charon])
 ADD_PLUGIN([eap-aka-3gpp2],        [c charon])
 ADD_PLUGIN([eap-simaka-sql],       [c charon])
 ADD_PLUGIN([eap-simaka-pseudonym], [c charon])
@@ -1600,6 +1588,7 @@ AM_CONDITIONAL(USE_EAP_IDENTITY, test x$eap_identity = xtrue)
 AM_CONDITIONAL(USE_EAP_MD5, test x$eap_md5 = xtrue)
 AM_CONDITIONAL(USE_EAP_GTC, test x$eap_gtc = xtrue)
 AM_CONDITIONAL(USE_EAP_AKA, test x$eap_aka = xtrue)
+AM_CONDITIONAL(USE_EAP_AKA_3GPP, test x$eap_aka_3gpp = xtrue)
 AM_CONDITIONAL(USE_EAP_AKA_3GPP2, test x$eap_aka_3gpp2 = xtrue)
 AM_CONDITIONAL(USE_EAP_MSCHAPV2, test x$eap_mschapv2 = xtrue)
 AM_CONDITIONAL(USE_EAP_TLS, test x$eap_tls = xtrue)
@@ -1630,6 +1619,8 @@ AM_CONDITIONAL(USE_IMC_ATTESTATION, test x$imc_attestation = xtrue)
 AM_CONDITIONAL(USE_IMV_ATTESTATION, test x$imv_attestation = xtrue)
 AM_CONDITIONAL(USE_IMC_SWID, test x$imc_swid = xtrue)
 AM_CONDITIONAL(USE_IMV_SWID, test x$imv_swid = xtrue)
+AM_CONDITIONAL(USE_IMC_SWIMA, test x$imc_swima = xtrue)
+AM_CONDITIONAL(USE_IMV_SWIMA, test x$imv_swima = xtrue)
 AM_CONDITIONAL(USE_IMC_HCD, test x$imc_hcd = xtrue)
 AM_CONDITIONAL(USE_IMV_HCD, test x$imv_hcd = xtrue)
 AM_CONDITIONAL(USE_SOCKET_DEFAULT, test x$socket_default = xtrue)
@@ -1730,6 +1721,9 @@ fi
 if test x$fuzzing = xtrue; then
 	AC_DEFINE([USE_FUZZING], [], [build code for fuzzing])
 fi
+if test x$imc_swima = xtrue -o x$imv_swima = xtrue -o x$imv_swid = xtrue ; then
+	AC_DEFINE([USE_JSON], [], [build code for JSON])
+fi
 
 # ====================================================
 #  options for enabled modules (see conf/Makefile.am)
@@ -1750,6 +1744,7 @@ AM_COND_IF([USE_MEDSRV], [strongswan_options=${strongswan_options}" medsrv"])
 AM_COND_IF([USE_SCEPCLIENT], [strongswan_options=${strongswan_options}" scepclient"])
 AM_COND_IF([USE_PKI], [strongswan_options=${strongswan_options}" pki"])
 AM_COND_IF([USE_SWANCTL], [strongswan_options=${strongswan_options}" swanctl"])
+AM_COND_IF([USE_SYSTEMD], [strongswan_options=${strongswan_options}" charon-systemd"])
 
 AC_SUBST(strongswan_options)
 
@@ -1855,6 +1850,8 @@ AC_CONFIG_FILES([
 	src/libimcv/plugins/imv_attestation/Makefile
 	src/libimcv/plugins/imc_swid/Makefile
 	src/libimcv/plugins/imv_swid/Makefile
+	src/libimcv/plugins/imc_swima/Makefile
+	src/libimcv/plugins/imv_swima/Makefile
 	src/libimcv/plugins/imc_hcd/Makefile
 	src/libimcv/plugins/imv_hcd/Makefile
 	src/charon/Makefile
@@ -1865,6 +1862,7 @@ AC_CONFIG_FILES([
 	src/charon-systemd/Makefile
 	src/libcharon/Makefile
 	src/libcharon/plugins/eap_aka/Makefile
+	src/libcharon/plugins/eap_aka_3gpp/Makefile
 	src/libcharon/plugins/eap_aka_3gpp2/Makefile
 	src/libcharon/plugins/eap_dynamic/Makefile
 	src/libcharon/plugins/eap_identity/Makefile
@@ -1958,6 +1956,7 @@ AC_CONFIG_FILES([
 	src/checksum/Makefile
 	src/conftest/Makefile
 	src/pt-tls-client/Makefile
+	src/sw-collector/Makefile
 	src/swanctl/Makefile
 	scripts/Makefile
 	testing/Makefile
@@ -1990,6 +1989,8 @@ AC_CONFIG_FILES([
 	src/swanctl/swanctl.8
 	src/swanctl/swanctl.conf.5.head
 	src/swanctl/swanctl.conf.5.tail
+	src/pt-tls-client/pt-tls-client.1
+	src/sw-collector/sw-collector.8
 ])
 
 AC_OUTPUT
diff --git a/fuzz/Makefile.in b/fuzz/Makefile.in
index ea2365f..8306f44 100644
--- a/fuzz/Makefile.in
+++ b/fuzz/Makefile.in
@@ -235,8 +235,6 @@ RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
 RUBYGEMDIR = @RUBYGEMDIR@
-RUBYINCLUDE = @RUBYINCLUDE@
-RUBYLIB = @RUBYLIB@
 SED = @SED@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
@@ -337,6 +335,8 @@ random_device = @random_device@
 resolv_conf = @resolv_conf@
 routing_table = @routing_table@
 routing_table_prio = @routing_table_prio@
+ruby_CFLAGS = @ruby_CFLAGS@
+ruby_LIBS = @ruby_LIBS@
 runstatedir = @runstatedir@
 s_plugins = @s_plugins@
 sbindir = @sbindir@
@@ -365,6 +365,10 @@ top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
 tss2_CFLAGS = @tss2_CFLAGS@
 tss2_LIBS = @tss2_LIBS@
+tss2_socket_CFLAGS = @tss2_socket_CFLAGS@
+tss2_socket_LIBS = @tss2_socket_LIBS@
+tss2_tabrmd_CFLAGS = @tss2_tabrmd_CFLAGS@
+tss2_tabrmd_LIBS = @tss2_tabrmd_LIBS@
 urandom_device = @urandom_device@
 xml_CFLAGS = @xml_CFLAGS@
 xml_LIBS = @xml_LIBS@
diff --git a/init/Makefile.in b/init/Makefile.in
index 118b62e..a0b2b9b 100644
--- a/init/Makefile.in
+++ b/init/Makefile.in
@@ -289,8 +289,6 @@ RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
 RUBYGEMDIR = @RUBYGEMDIR@
-RUBYINCLUDE = @RUBYINCLUDE@
-RUBYLIB = @RUBYLIB@
 SED = @SED@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
@@ -391,6 +389,8 @@ random_device = @random_device@
 resolv_conf = @resolv_conf@
 routing_table = @routing_table@
 routing_table_prio = @routing_table_prio@
+ruby_CFLAGS = @ruby_CFLAGS@
+ruby_LIBS = @ruby_LIBS@
 runstatedir = @runstatedir@
 s_plugins = @s_plugins@
 sbindir = @sbindir@
@@ -419,6 +419,10 @@ top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
 tss2_CFLAGS = @tss2_CFLAGS@
 tss2_LIBS = @tss2_LIBS@
+tss2_socket_CFLAGS = @tss2_socket_CFLAGS@
+tss2_socket_LIBS = @tss2_socket_LIBS@
+tss2_tabrmd_CFLAGS = @tss2_tabrmd_CFLAGS@
+tss2_tabrmd_LIBS = @tss2_tabrmd_LIBS@
 urandom_device = @urandom_device@
 xml_CFLAGS = @xml_CFLAGS@
 xml_LIBS = @xml_LIBS@
diff --git a/init/systemd-swanctl/Makefile.in b/init/systemd-swanctl/Makefile.in
index 432e87c..b68958d 100644
--- a/init/systemd-swanctl/Makefile.in
+++ b/init/systemd-swanctl/Makefile.in
@@ -257,8 +257,6 @@ RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
 RUBYGEMDIR = @RUBYGEMDIR@
-RUBYINCLUDE = @RUBYINCLUDE@
-RUBYLIB = @RUBYLIB@
 SED = @SED@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
@@ -359,6 +357,8 @@ random_device = @random_device@
 resolv_conf = @resolv_conf@
 routing_table = @routing_table@
 routing_table_prio = @routing_table_prio@
+ruby_CFLAGS = @ruby_CFLAGS@
+ruby_LIBS = @ruby_LIBS@
 runstatedir = @runstatedir@
 s_plugins = @s_plugins@
 sbindir = @sbindir@
@@ -387,6 +387,10 @@ top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
 tss2_CFLAGS = @tss2_CFLAGS@
 tss2_LIBS = @tss2_LIBS@
+tss2_socket_CFLAGS = @tss2_socket_CFLAGS@
+tss2_socket_LIBS = @tss2_socket_LIBS@
+tss2_tabrmd_CFLAGS = @tss2_tabrmd_CFLAGS@
+tss2_tabrmd_LIBS = @tss2_tabrmd_LIBS@
 urandom_device = @urandom_device@
 xml_CFLAGS = @xml_CFLAGS@
 xml_LIBS = @xml_LIBS@
diff --git a/init/systemd/Makefile.in b/init/systemd/Makefile.in
index a551f8f..3e20f5c 100644
--- a/init/systemd/Makefile.in
+++ b/init/systemd/Makefile.in
@@ -257,8 +257,6 @@ RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
 RUBYGEMDIR = @RUBYGEMDIR@
-RUBYINCLUDE = @RUBYINCLUDE@
-RUBYLIB = @RUBYLIB@
 SED = @SED@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
@@ -359,6 +357,8 @@ random_device = @random_device@
 resolv_conf = @resolv_conf@
 routing_table = @routing_table@
 routing_table_prio = @routing_table_prio@
+ruby_CFLAGS = @ruby_CFLAGS@
+ruby_LIBS = @ruby_LIBS@
 runstatedir = @runstatedir@
 s_plugins = @s_plugins@
 sbindir = @sbindir@
@@ -387,6 +387,10 @@ top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
 tss2_CFLAGS = @tss2_CFLAGS@
 tss2_LIBS = @tss2_LIBS@
+tss2_socket_CFLAGS = @tss2_socket_CFLAGS@
+tss2_socket_LIBS = @tss2_socket_LIBS@
+tss2_tabrmd_CFLAGS = @tss2_tabrmd_CFLAGS@
+tss2_tabrmd_LIBS = @tss2_tabrmd_LIBS@
 urandom_device = @urandom_device@
 xml_CFLAGS = @xml_CFLAGS@
 xml_LIBS = @xml_LIBS@
diff --git a/man/Makefile.in b/man/Makefile.in
index 22b23c0..795505a 100644
--- a/man/Makefile.in
+++ b/man/Makefile.in
@@ -263,8 +263,6 @@ RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
 RUBYGEMDIR = @RUBYGEMDIR@
-RUBYINCLUDE = @RUBYINCLUDE@
-RUBYLIB = @RUBYLIB@
 SED = @SED@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
@@ -365,6 +363,8 @@ random_device = @random_device@
 resolv_conf = @resolv_conf@
 routing_table = @routing_table@
 routing_table_prio = @routing_table_prio@
+ruby_CFLAGS = @ruby_CFLAGS@
+ruby_LIBS = @ruby_LIBS@
 runstatedir = @runstatedir@
 s_plugins = @s_plugins@
 sbindir = @sbindir@
@@ -393,6 +393,10 @@ top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
 tss2_CFLAGS = @tss2_CFLAGS@
 tss2_LIBS = @tss2_LIBS@
+tss2_socket_CFLAGS = @tss2_socket_CFLAGS@
+tss2_socket_LIBS = @tss2_socket_LIBS@
+tss2_tabrmd_CFLAGS = @tss2_tabrmd_CFLAGS@
+tss2_tabrmd_LIBS = @tss2_tabrmd_LIBS@
 urandom_device = @urandom_device@
 xml_CFLAGS = @xml_CFLAGS@
 xml_LIBS = @xml_LIBS@
diff --git a/man/ipsec.conf.5.in b/man/ipsec.conf.5.in
index fef44ae..69aeba8 100644
--- a/man/ipsec.conf.5.in
+++ b/man/ipsec.conf.5.in
@@ -1037,7 +1037,10 @@ mask of
 .B 0xffffffff
 is assumed. The special value
 .B %unique
-assigns a unique value to each newly created IPsec SA.
+assigns a unique value to each newly created IPsec SA. To additionally
+make the mark unique for each IPsec SA direction (in/out) the special value
+.B %unique-dir
+may be used.
 .TP
 .BR mark_in " = <value>[/<mask>]"
 sets an XFRM mark in the inbound IPsec SA and
diff --git a/scripts/Makefile.in b/scripts/Makefile.in
index 2dcbe4d..1f1c37b 100644
--- a/scripts/Makefile.in
+++ b/scripts/Makefile.in
@@ -371,8 +371,6 @@ RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
 RUBYGEMDIR = @RUBYGEMDIR@
-RUBYINCLUDE = @RUBYINCLUDE@
-RUBYLIB = @RUBYLIB@
 SED = @SED@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
@@ -473,6 +471,8 @@ random_device = @random_device@
 resolv_conf = @resolv_conf@
 routing_table = @routing_table@
 routing_table_prio = @routing_table_prio@
+ruby_CFLAGS = @ruby_CFLAGS@
+ruby_LIBS = @ruby_LIBS@
 runstatedir = @runstatedir@
 s_plugins = @s_plugins@
 sbindir = @sbindir@
@@ -501,6 +501,10 @@ top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
 tss2_CFLAGS = @tss2_CFLAGS@
 tss2_LIBS = @tss2_LIBS@
+tss2_socket_CFLAGS = @tss2_socket_CFLAGS@
+tss2_socket_LIBS = @tss2_socket_LIBS@
+tss2_tabrmd_CFLAGS = @tss2_tabrmd_CFLAGS@
+tss2_tabrmd_LIBS = @tss2_tabrmd_LIBS@
 urandom_device = @urandom_device@
 xml_CFLAGS = @xml_CFLAGS@
 xml_LIBS = @xml_LIBS@
diff --git a/src/Makefile.am b/src/Makefile.am
index df171b2..1bdb833 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -128,6 +128,10 @@ if USE_LIBPTTLS
   SUBDIRS += pt-tls-client
 endif
 
+if USE_IMC_SWIMA
+  SUBDIRS += sw-collector
+endif
+
 if USE_INTEGRITY_TEST
   SUBDIRS += checksum
 endif
diff --git a/src/Makefile.in b/src/Makefile.in
index 17c4a9a..84d2ad9 100644
--- a/src/Makefile.in
+++ b/src/Makefile.in
@@ -119,8 +119,9 @@ host_triplet = @host@
 @USE_CMD_TRUE at am__append_30 = charon-cmd
 @USE_SVC_TRUE at am__append_31 = charon-svc
 @USE_LIBPTTLS_TRUE at am__append_32 = pt-tls-client
- at USE_INTEGRITY_TEST_TRUE@am__append_33 = checksum
- at USE_AIKGEN_TRUE@am__append_34 = aikgen
+ at USE_IMC_SWIMA_TRUE@am__append_33 = sw-collector
+ at USE_INTEGRITY_TEST_TRUE@am__append_34 = checksum
+ at USE_AIKGEN_TRUE@am__append_35 = aikgen
 subdir = src
 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
 am__aclocal_m4_deps = $(top_srcdir)/m4/config/libtool.m4 \
@@ -199,7 +200,7 @@ DIST_SUBDIRS = . include libstrongswan libipsec libsimaka libtls \
 	libcharon starter ipsec _copyright charon charon-systemd \
 	charon-nm stroke _updown scepclient pki swanctl conftest dumm \
 	libfast manager medsrv pool charon-tkm charon-cmd charon-svc \
-	pt-tls-client checksum aikgen
+	pt-tls-client sw-collector checksum aikgen
 am__DIST_COMMON = $(srcdir)/Makefile.in
 DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
 am__relativize = \
@@ -326,8 +327,6 @@ RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
 RUBYGEMDIR = @RUBYGEMDIR@
-RUBYINCLUDE = @RUBYINCLUDE@
-RUBYLIB = @RUBYLIB@
 SED = @SED@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
@@ -428,6 +427,8 @@ random_device = @random_device@
 resolv_conf = @resolv_conf@
 routing_table = @routing_table@
 routing_table_prio = @routing_table_prio@
+ruby_CFLAGS = @ruby_CFLAGS@
+ruby_LIBS = @ruby_LIBS@
 runstatedir = @runstatedir@
 s_plugins = @s_plugins@
 sbindir = @sbindir@
@@ -456,6 +457,10 @@ top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
 tss2_CFLAGS = @tss2_CFLAGS@
 tss2_LIBS = @tss2_LIBS@
+tss2_socket_CFLAGS = @tss2_socket_CFLAGS@
+tss2_socket_LIBS = @tss2_socket_LIBS@
+tss2_tabrmd_CFLAGS = @tss2_tabrmd_CFLAGS@
+tss2_tabrmd_LIBS = @tss2_tabrmd_LIBS@
 urandom_device = @urandom_device@
 xml_CFLAGS = @xml_CFLAGS@
 xml_LIBS = @xml_LIBS@
@@ -470,7 +475,7 @@ SUBDIRS = . include $(am__append_1) $(am__append_2) $(am__append_3) \
 	$(am__append_25) $(am__append_26) $(am__append_27) \
 	$(am__append_28) $(am__append_29) $(am__append_30) \
 	$(am__append_31) $(am__append_32) $(am__append_33) \
-	$(am__append_34)
+	$(am__append_34) $(am__append_35)
 all: all-recursive
 
 .SUFFIXES:
diff --git a/src/_copyright/Makefile.in b/src/_copyright/Makefile.in
index 0bea80a..5ba747a 100644
--- a/src/_copyright/Makefile.in
+++ b/src/_copyright/Makefile.in
@@ -279,8 +279,6 @@ RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
 RUBYGEMDIR = @RUBYGEMDIR@
-RUBYINCLUDE = @RUBYINCLUDE@
-RUBYLIB = @RUBYLIB@
 SED = @SED@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
@@ -381,6 +379,8 @@ random_device = @random_device@
 resolv_conf = @resolv_conf@
 routing_table = @routing_table@
 routing_table_prio = @routing_table_prio@
+ruby_CFLAGS = @ruby_CFLAGS@
+ruby_LIBS = @ruby_LIBS@
 runstatedir = @runstatedir@
 s_plugins = @s_plugins@
 sbindir = @sbindir@
@@ -409,6 +409,10 @@ top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
 tss2_CFLAGS = @tss2_CFLAGS@
 tss2_LIBS = @tss2_LIBS@
+tss2_socket_CFLAGS = @tss2_socket_CFLAGS@
+tss2_socket_LIBS = @tss2_socket_LIBS@
+tss2_tabrmd_CFLAGS = @tss2_tabrmd_CFLAGS@
+tss2_tabrmd_LIBS = @tss2_tabrmd_LIBS@
 urandom_device = @urandom_device@
 xml_CFLAGS = @xml_CFLAGS@
 xml_LIBS = @xml_LIBS@
diff --git a/src/_updown/Makefile.in b/src/_updown/Makefile.in
index ba891c1..c51d65d 100644
--- a/src/_updown/Makefile.in
+++ b/src/_updown/Makefile.in
@@ -257,8 +257,6 @@ RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
 RUBYGEMDIR = @RUBYGEMDIR@
-RUBYINCLUDE = @RUBYINCLUDE@
-RUBYLIB = @RUBYLIB@
 SED = @SED@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
@@ -359,6 +357,8 @@ random_device = @random_device@
 resolv_conf = @resolv_conf@
 routing_table = @routing_table@
 routing_table_prio = @routing_table_prio@
+ruby_CFLAGS = @ruby_CFLAGS@
+ruby_LIBS = @ruby_LIBS@
 runstatedir = @runstatedir@
 s_plugins = @s_plugins@
 sbindir = @sbindir@
@@ -387,6 +387,10 @@ top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
 tss2_CFLAGS = @tss2_CFLAGS@
 tss2_LIBS = @tss2_LIBS@
+tss2_socket_CFLAGS = @tss2_socket_CFLAGS@
+tss2_socket_LIBS = @tss2_socket_LIBS@
+tss2_tabrmd_CFLAGS = @tss2_tabrmd_CFLAGS@
+tss2_tabrmd_LIBS = @tss2_tabrmd_LIBS@
 urandom_device = @urandom_device@
 xml_CFLAGS = @xml_CFLAGS@
 xml_LIBS = @xml_LIBS@
diff --git a/src/aikgen/Makefile.in b/src/aikgen/Makefile.in
index 7096dd6..61fcaf8 100644
--- a/src/aikgen/Makefile.in
+++ b/src/aikgen/Makefile.in
@@ -280,8 +280,6 @@ RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
 RUBYGEMDIR = @RUBYGEMDIR@
-RUBYINCLUDE = @RUBYINCLUDE@
-RUBYLIB = @RUBYLIB@
 SED = @SED@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
@@ -382,6 +380,8 @@ random_device = @random_device@
 resolv_conf = @resolv_conf@
 routing_table = @routing_table@
 routing_table_prio = @routing_table_prio@
+ruby_CFLAGS = @ruby_CFLAGS@
+ruby_LIBS = @ruby_LIBS@
 runstatedir = @runstatedir@
 s_plugins = @s_plugins@
 sbindir = @sbindir@
@@ -410,6 +410,10 @@ top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
 tss2_CFLAGS = @tss2_CFLAGS@
 tss2_LIBS = @tss2_LIBS@
+tss2_socket_CFLAGS = @tss2_socket_CFLAGS@
+tss2_socket_LIBS = @tss2_socket_LIBS@
+tss2_tabrmd_CFLAGS = @tss2_tabrmd_CFLAGS@
+tss2_tabrmd_LIBS = @tss2_tabrmd_LIBS@
 urandom_device = @urandom_device@
 xml_CFLAGS = @xml_CFLAGS@
 xml_LIBS = @xml_LIBS@
diff --git a/src/charon-cmd/Makefile.in b/src/charon-cmd/Makefile.in
index e4d057f..ea492f9 100644
--- a/src/charon-cmd/Makefile.in
+++ b/src/charon-cmd/Makefile.in
@@ -317,8 +317,6 @@ RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
 RUBYGEMDIR = @RUBYGEMDIR@
-RUBYINCLUDE = @RUBYINCLUDE@
-RUBYLIB = @RUBYLIB@
 SED = @SED@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
@@ -419,6 +417,8 @@ random_device = @random_device@
 resolv_conf = @resolv_conf@
 routing_table = @routing_table@
 routing_table_prio = @routing_table_prio@
+ruby_CFLAGS = @ruby_CFLAGS@
+ruby_LIBS = @ruby_LIBS@
 runstatedir = @runstatedir@
 s_plugins = @s_plugins@
 sbindir = @sbindir@
@@ -447,6 +447,10 @@ top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
 tss2_CFLAGS = @tss2_CFLAGS@
 tss2_LIBS = @tss2_LIBS@
+tss2_socket_CFLAGS = @tss2_socket_CFLAGS@
+tss2_socket_LIBS = @tss2_socket_LIBS@
+tss2_tabrmd_CFLAGS = @tss2_tabrmd_CFLAGS@
+tss2_tabrmd_LIBS = @tss2_tabrmd_LIBS@
 urandom_device = @urandom_device@
 xml_CFLAGS = @xml_CFLAGS@
 xml_LIBS = @xml_LIBS@
diff --git a/src/charon-nm/Makefile.in b/src/charon-nm/Makefile.in
index 3efcb8f..6733a33 100644
--- a/src/charon-nm/Makefile.in
+++ b/src/charon-nm/Makefile.in
@@ -316,8 +316,6 @@ RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
 RUBYGEMDIR = @RUBYGEMDIR@
-RUBYINCLUDE = @RUBYINCLUDE@
-RUBYLIB = @RUBYLIB@
 SED = @SED@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
@@ -418,6 +416,8 @@ random_device = @random_device@
 resolv_conf = @resolv_conf@
 routing_table = @routing_table@
 routing_table_prio = @routing_table_prio@
+ruby_CFLAGS = @ruby_CFLAGS@
+ruby_LIBS = @ruby_LIBS@
 runstatedir = @runstatedir@
 s_plugins = @s_plugins@
 sbindir = @sbindir@
@@ -446,6 +446,10 @@ top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
 tss2_CFLAGS = @tss2_CFLAGS@
 tss2_LIBS = @tss2_LIBS@
+tss2_socket_CFLAGS = @tss2_socket_CFLAGS@
+tss2_socket_LIBS = @tss2_socket_LIBS@
+tss2_tabrmd_CFLAGS = @tss2_tabrmd_CFLAGS@
+tss2_tabrmd_LIBS = @tss2_tabrmd_LIBS@
 urandom_device = @urandom_device@
 xml_CFLAGS = @xml_CFLAGS@
 xml_LIBS = @xml_LIBS@
diff --git a/src/charon-svc/Makefile.in b/src/charon-svc/Makefile.in
index 9c08e8a..263c6a3 100644
--- a/src/charon-svc/Makefile.in
+++ b/src/charon-svc/Makefile.in
@@ -280,8 +280,6 @@ RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
 RUBYGEMDIR = @RUBYGEMDIR@
-RUBYINCLUDE = @RUBYINCLUDE@
-RUBYLIB = @RUBYLIB@
 SED = @SED@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
@@ -382,6 +380,8 @@ random_device = @random_device@
 resolv_conf = @resolv_conf@
 routing_table = @routing_table@
 routing_table_prio = @routing_table_prio@
+ruby_CFLAGS = @ruby_CFLAGS@
+ruby_LIBS = @ruby_LIBS@
 runstatedir = @runstatedir@
 s_plugins = @s_plugins@
 sbindir = @sbindir@
@@ -410,6 +410,10 @@ top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
 tss2_CFLAGS = @tss2_CFLAGS@
 tss2_LIBS = @tss2_LIBS@
+tss2_socket_CFLAGS = @tss2_socket_CFLAGS@
+tss2_socket_LIBS = @tss2_socket_LIBS@
+tss2_tabrmd_CFLAGS = @tss2_tabrmd_CFLAGS@
+tss2_tabrmd_LIBS = @tss2_tabrmd_LIBS@
 urandom_device = @urandom_device@
 xml_CFLAGS = @xml_CFLAGS@
 xml_LIBS = @xml_LIBS@
diff --git a/src/charon-systemd/Makefile.in b/src/charon-systemd/Makefile.in
index 9377539..9697c42 100644
--- a/src/charon-systemd/Makefile.in
+++ b/src/charon-systemd/Makefile.in
@@ -284,8 +284,6 @@ RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
 RUBYGEMDIR = @RUBYGEMDIR@
-RUBYINCLUDE = @RUBYINCLUDE@
-RUBYLIB = @RUBYLIB@
 SED = @SED@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
@@ -386,6 +384,8 @@ random_device = @random_device@
 resolv_conf = @resolv_conf@
 routing_table = @routing_table@
 routing_table_prio = @routing_table_prio@
+ruby_CFLAGS = @ruby_CFLAGS@
+ruby_LIBS = @ruby_LIBS@
 runstatedir = @runstatedir@
 s_plugins = @s_plugins@
 sbindir = @sbindir@
@@ -414,6 +414,10 @@ top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
 tss2_CFLAGS = @tss2_CFLAGS@
 tss2_LIBS = @tss2_LIBS@
+tss2_socket_CFLAGS = @tss2_socket_CFLAGS@
+tss2_socket_LIBS = @tss2_socket_LIBS@
+tss2_tabrmd_CFLAGS = @tss2_tabrmd_CFLAGS@
+tss2_tabrmd_LIBS = @tss2_tabrmd_LIBS@
 urandom_device = @urandom_device@
 xml_CFLAGS = @xml_CFLAGS@
 xml_LIBS = @xml_LIBS@
diff --git a/src/charon-tkm/Makefile.in b/src/charon-tkm/Makefile.in
index 9987b44..258f33b 100644
--- a/src/charon-tkm/Makefile.in
+++ b/src/charon-tkm/Makefile.in
@@ -227,8 +227,6 @@ RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
 RUBYGEMDIR = @RUBYGEMDIR@
-RUBYINCLUDE = @RUBYINCLUDE@
-RUBYLIB = @RUBYLIB@
 SED = @SED@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
@@ -329,6 +327,8 @@ random_device = @random_device@
 resolv_conf = @resolv_conf@
 routing_table = @routing_table@
 routing_table_prio = @routing_table_prio@
+ruby_CFLAGS = @ruby_CFLAGS@
+ruby_LIBS = @ruby_LIBS@
 runstatedir = @runstatedir@
 s_plugins = @s_plugins@
 sbindir = @sbindir@
@@ -357,6 +357,10 @@ top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
 tss2_CFLAGS = @tss2_CFLAGS@
 tss2_LIBS = @tss2_LIBS@
+tss2_socket_CFLAGS = @tss2_socket_CFLAGS@
+tss2_socket_LIBS = @tss2_socket_LIBS@
+tss2_tabrmd_CFLAGS = @tss2_tabrmd_CFLAGS@
+tss2_tabrmd_LIBS = @tss2_tabrmd_LIBS@
 urandom_device = @urandom_device@
 xml_CFLAGS = @xml_CFLAGS@
 xml_LIBS = @xml_LIBS@
diff --git a/src/charon-tkm/src/ees/ees_callbacks.c b/src/charon-tkm/src/ees/ees_callbacks.c
index f4107d9..a36629b 100644
--- a/src/charon-tkm/src/ees/ees_callbacks.c
+++ b/src/charon-tkm/src/ees/ees_callbacks.c
@@ -47,4 +47,5 @@ void charon_esa_expire(result_type *res, const sp_id_type sp_id,
 	DBG1(DBG_KNL, "ees: expire received for reqid %u, spi %x, dst %H", sp_id,
 		 ntohl(spi_rem), dst);
 	charon->kernel->expire(charon->kernel, protocol, spi_rem, dst, hard != 0);
+	dst->destroy(dst);
 }
diff --git a/src/charon-tkm/src/tkm/tkm_kernel_ipsec.c b/src/charon-tkm/src/tkm/tkm_kernel_ipsec.c
index c9be898..5decde9 100644
--- a/src/charon-tkm/src/tkm/tkm_kernel_ipsec.c
+++ b/src/charon-tkm/src/tkm/tkm_kernel_ipsec.c
@@ -1,7 +1,8 @@
 /*
+ * Copyright (C) 2017 Tobias Brunner
  * Copyright (C) 2012-2014 Reto Buerki
  * Copyright (C) 2012 Adrian-Ken Rueegsegger
- * Hochschule fuer Technik Rapperswil
+ * HSR Hochschule fuer Technik Rapperswil
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the
@@ -52,6 +53,12 @@ struct private_tkm_kernel_ipsec_t {
 
 };
 
+METHOD(kernel_ipsec_t, get_features, kernel_feature_t,
+	private_tkm_kernel_ipsec_t *this)
+{
+	return KERNEL_POLICY_SPI;
+}
+
 METHOD(kernel_ipsec_t, get_spi, status_t,
 	private_tkm_kernel_ipsec_t *this, host_t *src, host_t *dst,
 	uint8_t protocol, uint32_t *spi)
@@ -176,15 +183,6 @@ METHOD(kernel_ipsec_t, add_sa, status_t,
 		tkm->chunk_map->remove(tkm->chunk_map, nonce_loc);
 		tkm->idmgr->release_id(tkm->idmgr, TKM_CTX_NONCE, nonce_loc_id);
 	}
-	if (ike_esa_select(esa_id) != TKM_OK)
-	{
-		DBG1(DBG_KNL, "error selecting new child SA (%llu)", esa_id);
-		if (ike_esa_reset(esa_id) != TKM_OK)
-		{
-			DBG1(DBG_KNL, "child SA (%llu) deletion failed", esa_id);
-		}
-		goto failure;
-	}
 
 	DBG1(DBG_KNL, "added child SA (esa: %llu, isa: %llu, esp_spi_loc: %x, "
 		 "esp_spi_rem: %x, role: %s)", esa_id, esa.isa_id, ntohl(spi_loc),
@@ -215,23 +213,12 @@ METHOD(kernel_ipsec_t, del_sa, status_t,
 	private_tkm_kernel_ipsec_t *this, kernel_ipsec_sa_id_t *id,
 	kernel_ipsec_del_sa_t *data)
 {
-	esa_id_type esa_id, other_esa_id;
+	esa_id_type esa_id;
 
 	esa_id = tkm->sad->get_esa_id(tkm->sad, id->src, id->dst,
-								  id->spi, id->proto);
+								  id->spi, id->proto, TRUE);
 	if (esa_id)
 	{
-		other_esa_id = tkm->sad->get_other_esa_id(tkm->sad, esa_id);
-		if (other_esa_id)
-		{
-			DBG1(DBG_KNL, "selecting child SA (esa: %llu)", other_esa_id);
-			if (ike_esa_select(other_esa_id) != TKM_OK)
-			{
-				DBG1(DBG_KNL, "error selecting other child SA (esa: %llu)",
-						other_esa_id);
-			}
-		}
-
 		DBG1(DBG_KNL, "deleting child SA (esa: %llu, spi: %x)", esa_id,
 			 ntohl(id->spi));
 		if (ike_esa_reset(esa_id) != TKM_OK)
@@ -263,6 +250,43 @@ METHOD(kernel_ipsec_t, add_policy, status_t,
 	private_tkm_kernel_ipsec_t *this, kernel_ipsec_policy_id_t *id,
 	kernel_ipsec_manage_policy_t *data)
 {
+	esa_id_type esa_id;
+	uint32_t spi;
+	uint8_t proto;
+
+	if (id->dir == POLICY_OUT && data->type == POLICY_IPSEC &&
+		data->prio == POLICY_PRIORITY_DEFAULT)
+	{
+		if (data->sa->esp.use)
+		{
+			spi = data->sa->esp.spi;
+			proto = IPPROTO_ESP;
+		}
+		else if (data->sa->ah.use)
+		{
+			spi = data->sa->ah.spi;
+			proto = IPPROTO_AH;
+		}
+		else
+		{
+			return FAILED;
+		}
+		esa_id = tkm->sad->get_esa_id(tkm->sad, data->src, data->dst,
+									  spi, proto, FALSE);
+		if (!esa_id)
+		{
+			DBG1(DBG_KNL, "unable to find esa ID for policy (spi: %x)",
+				 ntohl(spi));
+			return FAILED;
+		}
+		DBG1(DBG_KNL, "selecting child SA (esa: %llu, spi: %x)", esa_id,
+			 ntohl(spi));
+		if (ike_esa_select(esa_id) != TKM_OK)
+		{
+			DBG1(DBG_KNL, "error selecting new child SA (%llu)", esa_id);
+			return FAILED;
+		}
+	}
 	return SUCCESS;
 }
 
@@ -358,6 +382,7 @@ tkm_kernel_ipsec_t *tkm_kernel_ipsec_create()
 	INIT(this,
 		.public = {
 			.interface = {
+				.get_features = _get_features,
 				.get_spi = _get_spi,
 				.get_cpi = _get_cpi,
 				.add_sa  = _add_sa,
diff --git a/src/charon-tkm/src/tkm/tkm_kernel_sad.c b/src/charon-tkm/src/tkm/tkm_kernel_sad.c
index 97226f1..acc3ff1 100644
--- a/src/charon-tkm/src/tkm/tkm_kernel_sad.c
+++ b/src/charon-tkm/src/tkm/tkm_kernel_sad.c
@@ -107,16 +107,23 @@ CALLBACK(sad_entry_match, bool,
 	const host_t *src, *dst;
 	const uint32_t *spi;
 	const uint8_t *proto;
+	const bool *local;
 
-	VA_ARGS_VGET(args, src, dst, spi, proto);
+	VA_ARGS_VGET(args, src, dst, spi, proto, local);
 
-	if (entry->src == NULL || entry->dst == NULL)
+	if (entry->src == NULL || entry->dst == NULL || entry->proto != *proto)
 	{
 		return FALSE;
 	}
-	return src->ip_equals(entry->src, (host_t *)src) &&
-		   dst->ip_equals(entry->dst, (host_t *)dst) &&
-		   entry->spi_rem == *spi && entry->proto == *proto;
+	if (*local)
+	{
+		return entry->src->ip_equals(entry->src, (host_t *)dst) &&
+			   entry->dst->ip_equals(entry->dst, (host_t *)src) &&
+			   entry->spi_loc == *spi;
+	}
+	return entry->src->ip_equals(entry->src, (host_t *)src) &&
+		   entry->dst->ip_equals(entry->dst, (host_t *)dst) &&
+		   entry->spi_rem == *spi;
 }
 
 CALLBACK(sad_entry_match_dst, bool,
@@ -131,26 +138,6 @@ CALLBACK(sad_entry_match_dst, bool,
 		   entry->proto   == *proto;
 }
 
-CALLBACK(sad_entry_match_esa_id, bool,
-	sad_entry_t * const entry, va_list args)
-{
-	const esa_id_type *esa_id;
-
-	VA_ARGS_VGET(args, esa_id);
-	return entry->esa_id == *esa_id;
-}
-
-CALLBACK(sad_entry_match_other_esa, bool,
-	sad_entry_t * const entry, va_list args)
-{
-	const esa_id_type *esa_id;
-	const uint32_t *reqid;
-
-	VA_ARGS_VGET(args, esa_id, reqid);
-	return entry->reqid  == *reqid &&
-		   entry->esa_id != *esa_id;
-}
-
 CALLBACK(sad_entry_equal, bool,
 	sad_entry_t * const left, va_list args)
 {
@@ -213,7 +200,8 @@ METHOD(tkm_kernel_sad_t, insert, bool,
 
 METHOD(tkm_kernel_sad_t, get_esa_id, esa_id_type,
 	private_tkm_kernel_sad_t * const this, const host_t * const src,
-	const host_t * const dst, const uint32_t spi, const uint8_t proto)
+	const host_t * const dst, const uint32_t spi, const uint8_t proto,
+	const bool local)
 {
 	esa_id_type id = 0;
 	sad_entry_t *entry = NULL;
@@ -221,51 +209,18 @@ METHOD(tkm_kernel_sad_t, get_esa_id, esa_id_type,
 	this->mutex->lock(this->mutex);
 	const bool res = this->data->find_first(this->data, sad_entry_match,
 											(void**)&entry, src, dst, &spi,
-											&proto);
+											&proto, &local);
 	if (res && entry)
 	{
 		id = entry->esa_id;
 		DBG3(DBG_KNL, "returning ESA id %llu of SAD entry (src: %H, dst: %H, "
-			 "spi: %x, proto: %u)", id, src, dst, ntohl(spi), proto);
-	}
-	else
-	{
-		DBG3(DBG_KNL, "no SAD entry found for src %H, dst %H, spi %x, proto %u",
-			 src, dst, ntohl(spi), proto);
-	}
-	this->mutex->unlock(this->mutex);
-	return id;
-}
-
-METHOD(tkm_kernel_sad_t, get_other_esa_id, esa_id_type,
-	private_tkm_kernel_sad_t * const this, const esa_id_type esa_id)
-{
-	esa_id_type id = 0;
-	sad_entry_t *entry = NULL;
-	uint32_t reqid;
-	bool res;
-
-	this->mutex->lock(this->mutex);
-	res = this->data->find_first(this->data, sad_entry_match_esa_id,
-								 (void**)&entry, &esa_id);
-	if (res && entry)
-	{
-		reqid = entry->reqid;
+			 "%sbound spi: %x, proto: %u)", id, src, dst, local ? "in" : "out",
+			 ntohl(spi), proto);
 	}
 	else
 	{
-		DBG3(DBG_KNL, "no SAD entry found for ESA id %llu", esa_id);
-		this->mutex->unlock(this->mutex);
-		return id;
-	}
-
-	res = this->data->find_first(this->data, sad_entry_match_other_esa,
-								 (void**)&entry, &esa_id, &reqid);
-	if (res && entry)
-	{
-		id = entry->esa_id;
-		DBG3(DBG_KNL, "returning ESA id %llu of other SAD entry with reqid %u",
-			 id, reqid);
+		DBG3(DBG_KNL, "no SAD entry found for src %H, dst %H, %sbound spi %x, "
+			 "proto %u", src, dst, local ? "in" : "out", ntohl(spi), proto);
 	}
 	this->mutex->unlock(this->mutex);
 	return id;
@@ -283,7 +238,7 @@ METHOD(tkm_kernel_sad_t, get_dst_host, host_t *,
 											(void**)&entry, &reqid, &spi, &proto);
 	if (res && entry)
 	{
-		dst = entry->dst;
+		dst = entry->dst->clone(entry->dst);
 		DBG3(DBG_KNL, "returning destination host %H of SAD entry (reqid: %u,"
 			 " spi: %x, proto: %u)", dst, reqid, ntohl(spi), proto);
 	}
@@ -350,7 +305,6 @@ tkm_kernel_sad_t *tkm_kernel_sad_create()
 		.public = {
 			.insert = _insert,
 			.get_esa_id = _get_esa_id,
-			.get_other_esa_id = _get_other_esa_id,
 			.get_dst_host = _get_dst_host,
 			.remove = __remove,
 			.destroy = _destroy,
diff --git a/src/charon-tkm/src/tkm/tkm_kernel_sad.h b/src/charon-tkm/src/tkm/tkm_kernel_sad.h
index ba64621..3d9f5f3 100644
--- a/src/charon-tkm/src/tkm/tkm_kernel_sad.h
+++ b/src/charon-tkm/src/tkm/tkm_kernel_sad.h
@@ -55,23 +55,14 @@ struct tkm_kernel_sad_t {
 	 *
 	 * @param src			source address of CHILD SA
 	 * @param dst			destination address of CHILD SA
-	 * @param spi			Remote SPI of CHILD SA
+	 * @param spi			SPI of CHILD SA
 	 * @param proto			protocol of CHILD SA (ESP/AH)
+	 * @param local			whether the SPI is local or remote
 	 * @return				ESA id of entry if found, 0 otherwise
 	 */
 	esa_id_type (*get_esa_id)(tkm_kernel_sad_t * const this,
 				 const host_t * const src, const host_t * const dst,
-				 const uint32_t spi, const uint8_t proto);
-
-	/**
-	 * Get ESA id for entry associated with same security policy as the
-	 * specified ESA.
-	 *
-	 * @param esa_id		id of ESA identifying the security policy
-	 * @return				ESA id of entry if found, 0 otherwise
-	 */
-	esa_id_type (*get_other_esa_id)(tkm_kernel_sad_t * const this,
-									const esa_id_type esa_id);
+				 const uint32_t spi, const uint8_t proto, const bool local);
 
 	/**
 	 * Get destination host for entry with given parameters.
@@ -79,7 +70,8 @@ struct tkm_kernel_sad_t {
 	 * @param reqid			reqid of CHILD SA
 	 * @param spi			Remote SPI of CHILD SA
 	 * @param proto			protocol of CHILD SA (ESP/AH)
-	 * @return				destination host of entry if found, NULL otherwise
+	 * @return				destination host of entry if found (cloned),
+	 *						NULL otherwise
 	 */
 	host_t * (*get_dst_host)(tkm_kernel_sad_t * const this,
 			  const uint32_t reqid, const uint32_t spi, const uint8_t proto);
diff --git a/src/charon-tkm/tests/kernel_sad_tests.c b/src/charon-tkm/tests/kernel_sad_tests.c
index 2a033d2..39d8a79 100644
--- a/src/charon-tkm/tests/kernel_sad_tests.c
+++ b/src/charon-tkm/tests/kernel_sad_tests.c
@@ -63,50 +63,32 @@ START_TEST(test_get_esa_id)
 	tkm_kernel_sad_t *sad = tkm_kernel_sad_create();
 	fail_unless(sad->insert(sad, 23, 54, addr, addr, 27, 42, 50),
 				"Error inserting SAD entry");
-	fail_unless(sad->get_esa_id(sad, addr, addr, 42, 50) == 23,
+	fail_unless(sad->get_esa_id(sad, addr, addr, 42, 50, FALSE) == 23,
 				"Error getting esa id");
 	sad->destroy(sad);
 	addr->destroy(addr);
 }
 END_TEST
 
-START_TEST(test_get_esa_id_nonexistent)
-{
-	host_t *addr = host_create_from_string("127.0.0.1", 1024);
-	tkm_kernel_sad_t *sad = tkm_kernel_sad_create();
-	fail_unless(sad->get_esa_id(sad, addr, addr, 42, 50) == 0,
-				"Got esa id for nonexistent SAD entry");
-	sad->destroy(sad);
-	addr->destroy(addr);
-}
-END_TEST
-
-START_TEST(test_get_other_esa_id)
+START_TEST(test_get_esa_id_local)
 {
 	host_t *addr = host_create_from_string("127.0.0.1", 1024);
 	tkm_kernel_sad_t *sad = tkm_kernel_sad_create();
 	fail_unless(sad->insert(sad, 23, 54, addr, addr, 27, 42, 50),
 				"Error inserting SAD entry");
-	fail_unless(sad->insert(sad, 24, 54, addr, addr, 27, 42, 50),
-				"Error inserting SAD entry");
-	fail_unless(sad->get_other_esa_id(sad, 23) == 24,
-				"Error getting other esa id");
+	fail_unless(sad->get_esa_id(sad, addr, addr, 27, 50, TRUE) == 23,
+				"Error getting esa id");
 	sad->destroy(sad);
 	addr->destroy(addr);
 }
 END_TEST
 
-START_TEST(test_get_other_esa_id_nonexistent)
+START_TEST(test_get_esa_id_nonexistent)
 {
 	host_t *addr = host_create_from_string("127.0.0.1", 1024);
 	tkm_kernel_sad_t *sad = tkm_kernel_sad_create();
-	fail_unless(sad->get_other_esa_id(sad, 1) == 0,
-				"Got other esa id for nonexistent SAD entry");
-	fail_unless(sad->insert(sad, 23, 54, addr, addr, 27, 42, 50),
-				"Error inserting SAD entry");
-	fail_unless(sad->get_other_esa_id(sad, 23) == 0,
-				"Got own esa id");
-
+	fail_unless(sad->get_esa_id(sad, addr, addr, 42, 50, FALSE) == 0,
+				"Got esa id for nonexistent SAD entry");
 	sad->destroy(sad);
 	addr->destroy(addr);
 }
@@ -179,14 +161,10 @@ Suite *make_kernel_sad_tests()
 
 	tc = tcase_create("get_esa_id");
 	tcase_add_test(tc, test_get_esa_id);
+	tcase_add_test(tc, test_get_esa_id_local);
 	tcase_add_test(tc, test_get_esa_id_nonexistent);
 	suite_add_tcase(s, tc);
 
-	tc = tcase_create("get_other_esa_id");
-	tcase_add_test(tc, test_get_other_esa_id);
-	tcase_add_test(tc, test_get_other_esa_id_nonexistent);
-	suite_add_tcase(s, tc);
-
 	tc = tcase_create("get_dst_host");
 	tcase_add_test(tc, test_get_dst_host);
 	tcase_add_test(tc, test_get_dst_host_nonexistent);
diff --git a/src/charon/Makefile.in b/src/charon/Makefile.in
index d4cec54..9c5283c 100644
--- a/src/charon/Makefile.in
+++ b/src/charon/Makefile.in
@@ -283,8 +283,6 @@ RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
 RUBYGEMDIR = @RUBYGEMDIR@
-RUBYINCLUDE = @RUBYINCLUDE@
-RUBYLIB = @RUBYLIB@
 SED = @SED@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
@@ -385,6 +383,8 @@ random_device = @random_device@
 resolv_conf = @resolv_conf@
 routing_table = @routing_table@
 routing_table_prio = @routing_table_prio@
+ruby_CFLAGS = @ruby_CFLAGS@
+ruby_LIBS = @ruby_LIBS@
 runstatedir = @runstatedir@
 s_plugins = @s_plugins@
 sbindir = @sbindir@
@@ -413,6 +413,10 @@ top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
 tss2_CFLAGS = @tss2_CFLAGS@
 tss2_LIBS = @tss2_LIBS@
+tss2_socket_CFLAGS = @tss2_socket_CFLAGS@
+tss2_socket_LIBS = @tss2_socket_LIBS@
+tss2_tabrmd_CFLAGS = @tss2_tabrmd_CFLAGS@
+tss2_tabrmd_LIBS = @tss2_tabrmd_LIBS@
 urandom_device = @urandom_device@
 xml_CFLAGS = @xml_CFLAGS@
 xml_LIBS = @xml_LIBS@
diff --git a/src/checksum/Makefile.am b/src/checksum/Makefile.am
index 5db5b79..1856e2a 100644
--- a/src/checksum/Makefile.am
+++ b/src/checksum/Makefile.am
@@ -122,6 +122,14 @@ if USE_IMV_ATTESTATION
   exes += $(DESTDIR)$(ipsecdir)/attest
 endif
 
+if USE_LIBPTTLS
+  exes += $(DESTDIR)$(bindir)/pt-tls-client
+endif
+
+if USE_IMC_SWIMA
+  exes += $(DESTDIR)$(sbindir)/sw-collector
+endif
+
 checksum.c : checksum_builder $(deps) $(exes)
 		./checksum_builder $(libs) $(exes) > checksum.c
 
diff --git a/src/checksum/Makefile.in b/src/checksum/Makefile.in
index e4e3a16..87e78a9 100644
--- a/src/checksum/Makefile.in
+++ b/src/checksum/Makefile.in
@@ -121,6 +121,8 @@ EXTRA_PROGRAMS = checksum_builder$(EXEEXT)
 @USE_SWANCTL_TRUE at am__append_30 = $(DESTDIR)$(sbindir)/swanctl
 @USE_ATTR_SQL_TRUE at am__append_31 = $(DESTDIR)$(ipsecdir)/pool
 @USE_IMV_ATTESTATION_TRUE at am__append_32 = $(DESTDIR)$(ipsecdir)/attest
+ at USE_LIBPTTLS_TRUE@am__append_33 = $(DESTDIR)$(bindir)/pt-tls-client
+ at USE_IMC_SWIMA_TRUE@am__append_34 = $(DESTDIR)$(sbindir)/sw-collector
 subdir = src/checksum
 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
 am__aclocal_m4_deps = $(top_srcdir)/m4/config/libtool.m4 \
@@ -352,8 +354,6 @@ RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
 RUBYGEMDIR = @RUBYGEMDIR@
-RUBYINCLUDE = @RUBYINCLUDE@
-RUBYLIB = @RUBYLIB@
 SED = @SED@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
@@ -454,6 +454,8 @@ random_device = @random_device@
 resolv_conf = @resolv_conf@
 routing_table = @routing_table@
 routing_table_prio = @routing_table_prio@
+ruby_CFLAGS = @ruby_CFLAGS@
+ruby_LIBS = @ruby_LIBS@
 runstatedir = @runstatedir@
 s_plugins = @s_plugins@
 sbindir = @sbindir@
@@ -482,6 +484,10 @@ top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
 tss2_CFLAGS = @tss2_CFLAGS@
 tss2_LIBS = @tss2_LIBS@
+tss2_socket_CFLAGS = @tss2_socket_CFLAGS@
+tss2_socket_LIBS = @tss2_socket_LIBS@
+tss2_tabrmd_CFLAGS = @tss2_tabrmd_CFLAGS@
+tss2_tabrmd_LIBS = @tss2_tabrmd_LIBS@
 urandom_device = @urandom_device@
 xml_CFLAGS = @xml_CFLAGS@
 xml_LIBS = @xml_LIBS@
@@ -521,7 +527,8 @@ libs = $(DESTDIR)$(ipseclibdir)/libstrongswan.so $(am__append_3) \
 	$(am__append_19) $(am__append_21) $(am__append_23)
 exes = $(am__append_24) $(am__append_26) $(am__append_27) \
 	$(am__append_28) $(am__append_29) $(am__append_30) \
-	$(am__append_31) $(am__append_32)
+	$(am__append_31) $(am__append_32) $(am__append_33) \
+	$(am__append_34)
 all: all-am
 
 .SUFFIXES:
diff --git a/src/conftest/Makefile.in b/src/conftest/Makefile.in
index c7d4c6b..4f33d98 100644
--- a/src/conftest/Makefile.in
+++ b/src/conftest/Makefile.in
@@ -297,8 +297,6 @@ RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
 RUBYGEMDIR = @RUBYGEMDIR@
-RUBYINCLUDE = @RUBYINCLUDE@
-RUBYLIB = @RUBYLIB@
 SED = @SED@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
@@ -399,6 +397,8 @@ random_device = @random_device@
 resolv_conf = @resolv_conf@
 routing_table = @routing_table@
 routing_table_prio = @routing_table_prio@
+ruby_CFLAGS = @ruby_CFLAGS@
+ruby_LIBS = @ruby_LIBS@
 runstatedir = @runstatedir@
 s_plugins = @s_plugins@
 sbindir = @sbindir@
@@ -427,6 +427,10 @@ top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
 tss2_CFLAGS = @tss2_CFLAGS@
 tss2_LIBS = @tss2_LIBS@
+tss2_socket_CFLAGS = @tss2_socket_CFLAGS@
+tss2_socket_LIBS = @tss2_socket_LIBS@
+tss2_tabrmd_CFLAGS = @tss2_tabrmd_CFLAGS@
+tss2_tabrmd_LIBS = @tss2_tabrmd_LIBS@
 urandom_device = @urandom_device@
 xml_CFLAGS = @xml_CFLAGS@
 xml_LIBS = @xml_LIBS@
diff --git a/src/dumm/Makefile.am b/src/dumm/Makefile.am
index 1c6a68f..0d1cfb7 100644
--- a/src/dumm/Makefile.am
+++ b/src/dumm/Makefile.am
@@ -11,15 +11,14 @@ irdumm_SOURCES = irdumm.c
 
 libdumm_la_LIBADD = -lbridge -lfuse -lutil $(top_builddir)/src/libstrongswan/libstrongswan.la
 dumm_LDADD = libdumm.la ${gtk_LIBS} $(top_builddir)/src/libstrongswan/libstrongswan.la
-irdumm_LDADD = libdumm.la ${RUBYLIB} $(top_builddir)/src/libstrongswan/libstrongswan.la
+irdumm_LDADD = libdumm.la ${ruby_LIBS} $(top_builddir)/src/libstrongswan/libstrongswan.la
 
 AM_CPPFLAGS = \
 	-D_FILE_OFFSET_BITS=64 \
-	-I$(top_srcdir)/src/libstrongswan \
-	${RUBYINCLUDE}
+	-I$(top_srcdir)/src/libstrongswan
 
-AM_CFLAGS = \
-	${gtk_CFLAGS}
+dumm_CFLAGS = ${gtk_CFLAGS}
+irdumm_CFLAGS = ${ruby_CFLAGS}
 
 all-local: ext
 
diff --git a/src/dumm/Makefile.in b/src/dumm/Makefile.in
index 276ca2e..6c7cc41 100644
--- a/src/dumm/Makefile.in
+++ b/src/dumm/Makefile.in
@@ -148,15 +148,21 @@ am__v_lt_ = $(am__v_lt_ at AM_DEFAULT_V@)
 am__v_lt_0 = --silent
 am__v_lt_1 = 
 PROGRAMS = $(ipsec_PROGRAMS)
-am_dumm_OBJECTS = main.$(OBJEXT)
+am_dumm_OBJECTS = dumm-main.$(OBJEXT)
 dumm_OBJECTS = $(am_dumm_OBJECTS)
 am__DEPENDENCIES_1 =
 dumm_DEPENDENCIES = libdumm.la $(am__DEPENDENCIES_1) \
 	$(top_builddir)/src/libstrongswan/libstrongswan.la
-am_irdumm_OBJECTS = irdumm.$(OBJEXT)
+dumm_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+	$(LIBTOOLFLAGS) --mode=link $(CCLD) $(dumm_CFLAGS) $(CFLAGS) \
+	$(AM_LDFLAGS) $(LDFLAGS) -o $@
+am_irdumm_OBJECTS = irdumm-irdumm.$(OBJEXT)
 irdumm_OBJECTS = $(am_irdumm_OBJECTS)
 irdumm_DEPENDENCIES = libdumm.la $(am__DEPENDENCIES_1) \
 	$(top_builddir)/src/libstrongswan/libstrongswan.la
+irdumm_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+	$(LIBTOOLFLAGS) --mode=link $(CCLD) $(irdumm_CFLAGS) $(CFLAGS) \
+	$(AM_LDFLAGS) $(LDFLAGS) -o $@
 AM_V_P = $(am__v_P_ at AM_V@)
 am__v_P_ = $(am__v_P_ at AM_DEFAULT_V@)
 am__v_P_0 = false
@@ -318,8 +324,6 @@ RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
 RUBYGEMDIR = @RUBYGEMDIR@
-RUBYINCLUDE = @RUBYINCLUDE@
-RUBYLIB = @RUBYLIB@
 SED = @SED@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
@@ -420,6 +424,8 @@ random_device = @random_device@
 resolv_conf = @resolv_conf@
 routing_table = @routing_table@
 routing_table_prio = @routing_table_prio@
+ruby_CFLAGS = @ruby_CFLAGS@
+ruby_LIBS = @ruby_LIBS@
 runstatedir = @runstatedir@
 s_plugins = @s_plugins@
 sbindir = @sbindir@
@@ -448,6 +454,10 @@ top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
 tss2_CFLAGS = @tss2_CFLAGS@
 tss2_LIBS = @tss2_LIBS@
+tss2_socket_CFLAGS = @tss2_socket_CFLAGS@
+tss2_socket_LIBS = @tss2_socket_LIBS@
+tss2_tabrmd_CFLAGS = @tss2_tabrmd_CFLAGS@
+tss2_tabrmd_LIBS = @tss2_tabrmd_LIBS@
 urandom_device = @urandom_device@
 xml_CFLAGS = @xml_CFLAGS@
 xml_LIBS = @xml_LIBS@
@@ -462,15 +472,13 @@ dumm_SOURCES = main.c
 irdumm_SOURCES = irdumm.c
 libdumm_la_LIBADD = -lbridge -lfuse -lutil $(top_builddir)/src/libstrongswan/libstrongswan.la
 dumm_LDADD = libdumm.la ${gtk_LIBS} $(top_builddir)/src/libstrongswan/libstrongswan.la
-irdumm_LDADD = libdumm.la ${RUBYLIB} $(top_builddir)/src/libstrongswan/libstrongswan.la
+irdumm_LDADD = libdumm.la ${ruby_LIBS} $(top_builddir)/src/libstrongswan/libstrongswan.la
 AM_CPPFLAGS = \
 	-D_FILE_OFFSET_BITS=64 \
-	-I$(top_srcdir)/src/libstrongswan \
-	${RUBYINCLUDE}
-
-AM_CFLAGS = \
-	${gtk_CFLAGS}
+	-I$(top_srcdir)/src/libstrongswan
 
+dumm_CFLAGS = ${gtk_CFLAGS}
+irdumm_CFLAGS = ${ruby_CFLAGS}
 all: all-am
 
 .SUFFIXES:
@@ -594,11 +602,11 @@ clean-ipsecPROGRAMS:
 
 dumm$(EXEEXT): $(dumm_OBJECTS) $(dumm_DEPENDENCIES) $(EXTRA_dumm_DEPENDENCIES) 
 	@rm -f dumm$(EXEEXT)
-	$(AM_V_CCLD)$(LINK) $(dumm_OBJECTS) $(dumm_LDADD) $(LIBS)
+	$(AM_V_CCLD)$(dumm_LINK) $(dumm_OBJECTS) $(dumm_LDADD) $(LIBS)
 
 irdumm$(EXEEXT): $(irdumm_OBJECTS) $(irdumm_DEPENDENCIES) $(EXTRA_irdumm_DEPENDENCIES) 
 	@rm -f irdumm$(EXEEXT)
-	$(AM_V_CCLD)$(LINK) $(irdumm_OBJECTS) $(irdumm_LDADD) $(LIBS)
+	$(AM_V_CCLD)$(irdumm_LINK) $(irdumm_OBJECTS) $(irdumm_LDADD) $(LIBS)
 
 mostlyclean-compile:
 	-rm -f *.$(OBJEXT)
@@ -608,11 +616,11 @@ distclean-compile:
 
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/bridge.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/cowfs.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/dumm-main.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/dumm.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/guest.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/iface.Plo at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/irdumm.Po at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/main.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/irdumm-irdumm.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/mconsole.Plo at am__quote@
 
 .c.o:
@@ -639,6 +647,34 @@ distclean-compile:
 @AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
 @am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(LTCOMPILE) -c -o $@ $<
 
+dumm-main.o: main.c
+ at am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(dumm_CFLAGS) $(CFLAGS) -MT dumm-main.o -MD -MP -MF $(DEPDIR)/dumm-main.Tpo -c -o dumm-main.o `test -f 'main.c' || echo '$(srcdir)/'`main.c
+ at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/dumm-main.Tpo $(DEPDIR)/dumm-main.Po
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='main.c' object='dumm-main.o' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(dumm_CFLAGS) $(CFLAGS) -c -o dumm-main.o `test -f 'main.c' || echo '$(srcdir)/'`main.c
+
+dumm-main.obj: main.c
+ at am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(dumm_CFLAGS) $(CFLAGS) -MT dumm-main.obj -MD -MP -MF $(DEPDIR)/dumm-main.Tpo -c -o dumm-main.obj `if test -f 'main.c'; then $(CYGPATH_W) 'main.c'; else $(CYGPATH_W) '$(srcdir)/main.c'; fi`
+ at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/dumm-main.Tpo $(DEPDIR)/dumm-main.Po
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='main.c' object='dumm-main.obj' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(dumm_CFLAGS) $(CFLAGS) -c -o dumm-main.obj `if test -f 'main.c'; then $(CYGPATH_W) 'main.c'; else $(CYGPATH_W) '$(srcdir)/main.c'; fi`
+
+irdumm-irdumm.o: irdumm.c
+ at am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(irdumm_CFLAGS) $(CFLAGS) -MT irdumm-irdumm.o -MD -MP -MF $(DEPDIR)/irdumm-irdumm.Tpo -c -o irdumm-irdumm.o `test -f 'irdumm.c' || echo '$(srcdir)/'`irdumm.c
+ at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/irdumm-irdumm.Tpo $(DEPDIR)/irdumm-irdumm.Po
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='irdumm.c' object='irdumm-irdumm.o' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(irdumm_CFLAGS) $(CFLAGS) -c -o irdumm-irdumm.o `test -f 'irdumm.c' || echo '$(srcdir)/'`irdumm.c
+
+irdumm-irdumm.obj: irdumm.c
+ at am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(irdumm_CFLAGS) $(CFLAGS) -MT irdumm-irdumm.obj -MD -MP -MF $(DEPDIR)/irdumm-irdumm.Tpo -c -o irdumm-irdumm.obj `if test -f 'irdumm.c'; then $(CYGPATH_W) 'irdumm.c'; else $(CYGPATH_W) '$(srcdir)/irdumm.c'; fi`
+ at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/irdumm-irdumm.Tpo $(DEPDIR)/irdumm-irdumm.Po
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='irdumm.c' object='irdumm-irdumm.obj' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(irdumm_CFLAGS) $(CFLAGS) -c -o irdumm-irdumm.obj `if test -f 'irdumm.c'; then $(CYGPATH_W) 'irdumm.c'; else $(CYGPATH_W) '$(srcdir)/irdumm.c'; fi`
+
 mostlyclean-libtool:
 	-rm -f *.lo
 
diff --git a/src/dumm/ext/dumm.c b/src/dumm/ext/dumm.c
index df7ec47..b898a25 100644
--- a/src/dumm/ext/dumm.c
+++ b/src/dumm/ext/dumm.c
@@ -30,6 +30,8 @@
 #undef PACKAGE_STRING
 #undef PACKAGE_BUGREPORT
 #undef PACKAGE_URL
+#undef HAVE_DLADDR
+#undef HAVE_QSORT_R
 /* avoid redefintiion of snprintf etc. */
 #define RUBY_DONT_SUBST
 /* undef our _GNU_SOURCE, as it gets redefined by <ruby.h> */
diff --git a/src/dumm/irdumm.c b/src/dumm/irdumm.c
index d309737..1a4235c 100644
--- a/src/dumm/irdumm.c
+++ b/src/dumm/irdumm.c
@@ -19,6 +19,8 @@
 #undef PACKAGE_STRING
 #undef PACKAGE_BUGREPORT
 #undef PACKAGE_URL
+#undef HAVE_DLADDR
+#undef HAVE_QSORT_R
 #include <ruby.h>
 
 #ifdef HAVE_RB_ERRINFO
diff --git a/src/include/Makefile.in b/src/include/Makefile.in
index 569574f..dde85cb 100644
--- a/src/include/Makefile.in
+++ b/src/include/Makefile.in
@@ -227,8 +227,6 @@ RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
 RUBYGEMDIR = @RUBYGEMDIR@
-RUBYINCLUDE = @RUBYINCLUDE@
-RUBYLIB = @RUBYLIB@
 SED = @SED@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
@@ -329,6 +327,8 @@ random_device = @random_device@
 resolv_conf = @resolv_conf@
 routing_table = @routing_table@
 routing_table_prio = @routing_table_prio@
+ruby_CFLAGS = @ruby_CFLAGS@
+ruby_LIBS = @ruby_LIBS@
 runstatedir = @runstatedir@
 s_plugins = @s_plugins@
 sbindir = @sbindir@
@@ -357,6 +357,10 @@ top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
 tss2_CFLAGS = @tss2_CFLAGS@
 tss2_LIBS = @tss2_LIBS@
+tss2_socket_CFLAGS = @tss2_socket_CFLAGS@
+tss2_socket_LIBS = @tss2_socket_LIBS@
+tss2_tabrmd_CFLAGS = @tss2_tabrmd_CFLAGS@
+tss2_tabrmd_LIBS = @tss2_tabrmd_LIBS@
 urandom_device = @urandom_device@
 xml_CFLAGS = @xml_CFLAGS@
 xml_LIBS = @xml_LIBS@
diff --git a/src/ipsec/Makefile.in b/src/ipsec/Makefile.in
index 1a92242..494dc45 100644
--- a/src/ipsec/Makefile.in
+++ b/src/ipsec/Makefile.in
@@ -260,8 +260,6 @@ RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
 RUBYGEMDIR = @RUBYGEMDIR@
-RUBYINCLUDE = @RUBYINCLUDE@
-RUBYLIB = @RUBYLIB@
 SED = @SED@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
@@ -362,6 +360,8 @@ random_device = @random_device@
 resolv_conf = @resolv_conf@
 routing_table = @routing_table@
 routing_table_prio = @routing_table_prio@
+ruby_CFLAGS = @ruby_CFLAGS@
+ruby_LIBS = @ruby_LIBS@
 runstatedir = @runstatedir@
 s_plugins = @s_plugins@
 sbindir = @sbindir@
@@ -390,6 +390,10 @@ top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
 tss2_CFLAGS = @tss2_CFLAGS@
 tss2_LIBS = @tss2_LIBS@
+tss2_socket_CFLAGS = @tss2_socket_CFLAGS@
+tss2_socket_LIBS = @tss2_socket_LIBS@
+tss2_tabrmd_CFLAGS = @tss2_tabrmd_CFLAGS@
+tss2_tabrmd_LIBS = @tss2_tabrmd_LIBS@
 urandom_device = @urandom_device@
 xml_CFLAGS = @xml_CFLAGS@
 xml_LIBS = @xml_LIBS@
diff --git a/src/ipsec/_ipsec.8 b/src/ipsec/_ipsec.8
index 3f4316d..b23b042 100644
--- a/src/ipsec/_ipsec.8
+++ b/src/ipsec/_ipsec.8
@@ -1,4 +1,4 @@
-.TH IPSEC 8 "2013-10-29" "5.5.3dr2" "strongSwan"
+.TH IPSEC 8 "2013-10-29" "5.6.0dr1" "strongSwan"
 .
 .SH NAME
 .
diff --git a/src/ipsec/_ipsec.in b/src/ipsec/_ipsec.in
index ea399b8..65fadf2 100644
--- a/src/ipsec/_ipsec.in
+++ b/src/ipsec/_ipsec.in
@@ -73,7 +73,7 @@ case "$1" in
 	echo "	rereadocspcerts|rereadacerts|rereadcrls|rereadall"
 	echo "	purgecerts|purgecrls|purgeike|purgeocsp"
 	echo "	scepclient|pki"
-	echo "	starter|stroke"
+	echo "	stroke"
 	echo "	version"
 	echo
 	echo "Refer to the $IPSEC_SCRIPT(8) man page for details."
diff --git a/src/libcharon/Android.mk b/src/libcharon/Android.mk
index 1a8e068..f381860 100644
--- a/src/libcharon/Android.mk
+++ b/src/libcharon/Android.mk
@@ -163,6 +163,8 @@ LOCAL_SRC_FILES += $(call add_plugin, p-cscf)
 
 LOCAL_SRC_FILES += $(call add_plugin, eap-aka)
 
+LOCAL_SRC_FILES += $(call add_plugin, eap-aka-3gpp)
+
 LOCAL_SRC_FILES += $(call add_plugin, eap-aka-3gpp2)
 ifneq ($(call plugin_enabled, eap-aka-3gpp2),)
 LOCAL_C_INCLUDES += $(libgmp_PATH)
diff --git a/src/libcharon/Makefile.am b/src/libcharon/Makefile.am
index 3fcaedc..ed2236e 100644
--- a/src/libcharon/Makefile.am
+++ b/src/libcharon/Makefile.am
@@ -370,6 +370,13 @@ if MONOLITHIC
 endif
 endif
 
+if USE_EAP_AKA_3GPP
+  SUBDIRS += plugins/eap_aka_3gpp
+if MONOLITHIC
+  libcharon_la_LIBADD += plugins/eap_aka_3gpp/libstrongswan-eap-aka-3gpp.la
+endif
+endif
+
 if USE_EAP_AKA_3GPP2
   SUBDIRS += plugins/eap_aka_3gpp2
 if MONOLITHIC
diff --git a/src/libcharon/Makefile.in b/src/libcharon/Makefile.in
index ef9ffd3..fc66358 100644
--- a/src/libcharon/Makefile.in
+++ b/src/libcharon/Makefile.in
@@ -201,100 +201,102 @@ host_triplet = @host@
 @MONOLITHIC_TRUE@@USE_EAP_SIMAKA_REAUTH_TRUE at am__append_51 = plugins/eap_simaka_reauth/libstrongswan-eap-simaka-reauth.la
 @USE_EAP_AKA_TRUE at am__append_52 = plugins/eap_aka
 @MONOLITHIC_TRUE@@USE_EAP_AKA_TRUE at am__append_53 = plugins/eap_aka/libstrongswan-eap-aka.la
- at USE_EAP_AKA_3GPP2_TRUE@am__append_54 = plugins/eap_aka_3gpp2
- at MONOLITHIC_TRUE@@USE_EAP_AKA_3GPP2_TRUE at am__append_55 = plugins/eap_aka_3gpp2/libstrongswan-eap-aka-3gpp2.la
- at MONOLITHIC_TRUE@@USE_SIMAKA_TRUE at am__append_56 = $(top_builddir)/src/libsimaka/libsimaka.la
- at USE_EAP_MD5_TRUE@am__append_57 = plugins/eap_md5
- at MONOLITHIC_TRUE@@USE_EAP_MD5_TRUE at am__append_58 = plugins/eap_md5/libstrongswan-eap-md5.la
- at USE_EAP_GTC_TRUE@am__append_59 = plugins/eap_gtc
- at MONOLITHIC_TRUE@@USE_EAP_GTC_TRUE at am__append_60 = plugins/eap_gtc/libstrongswan-eap-gtc.la
- at USE_EAP_MSCHAPV2_TRUE@am__append_61 = plugins/eap_mschapv2
- at MONOLITHIC_TRUE@@USE_EAP_MSCHAPV2_TRUE at am__append_62 = plugins/eap_mschapv2/libstrongswan-eap-mschapv2.la
- at USE_EAP_DYNAMIC_TRUE@am__append_63 = plugins/eap_dynamic
- at MONOLITHIC_TRUE@@USE_EAP_DYNAMIC_TRUE at am__append_64 = plugins/eap_dynamic/libstrongswan-eap-dynamic.la
- at USE_EAP_RADIUS_TRUE@am__append_65 = plugins/eap_radius
- at MONOLITHIC_TRUE@@USE_EAP_RADIUS_TRUE at am__append_66 = plugins/eap_radius/libstrongswan-eap-radius.la
- at USE_EAP_TLS_TRUE@am__append_67 = plugins/eap_tls
- at MONOLITHIC_TRUE@@USE_EAP_TLS_TRUE at am__append_68 = plugins/eap_tls/libstrongswan-eap-tls.la
- at USE_EAP_TTLS_TRUE@am__append_69 = plugins/eap_ttls
- at MONOLITHIC_TRUE@@USE_EAP_TTLS_TRUE at am__append_70 = plugins/eap_ttls/libstrongswan-eap-ttls.la
- at USE_EAP_PEAP_TRUE@am__append_71 = plugins/eap_peap
- at MONOLITHIC_TRUE@@USE_EAP_PEAP_TRUE at am__append_72 = plugins/eap_peap/libstrongswan-eap-peap.la
- at USE_EAP_TNC_TRUE@am__append_73 = plugins/eap_tnc
- at MONOLITHIC_TRUE@@USE_EAP_TNC_TRUE at am__append_74 = plugins/eap_tnc/libstrongswan-eap-tnc.la
- at MONOLITHIC_TRUE@@USE_TLS_TRUE at am__append_75 = $(top_builddir)/src/libtls/libtls.la
- at MONOLITHIC_TRUE@@USE_RADIUS_TRUE at am__append_76 = $(top_builddir)/src/libradius/libradius.la
- at USE_TNC_IFMAP_TRUE@am__append_77 = plugins/tnc_ifmap
- at MONOLITHIC_TRUE@@USE_TNC_IFMAP_TRUE at am__append_78 = plugins/tnc_ifmap/libstrongswan-tnc-ifmap.la
- at USE_TNC_PDP_TRUE@am__append_79 = plugins/tnc_pdp
- at MONOLITHIC_TRUE@@USE_TNC_PDP_TRUE at am__append_80 = plugins/tnc_pdp/libstrongswan-tnc-pdp.la
- at MONOLITHIC_TRUE@@USE_LIBTNCCS_TRUE at am__append_81 = $(top_builddir)/src/libtnccs/libtnccs.la
- at USE_MEDSRV_TRUE@am__append_82 = plugins/medsrv
- at MONOLITHIC_TRUE@@USE_MEDSRV_TRUE at am__append_83 = plugins/medsrv/libstrongswan-medsrv.la
- at USE_MEDCLI_TRUE@am__append_84 = plugins/medcli
- at MONOLITHIC_TRUE@@USE_MEDCLI_TRUE at am__append_85 = plugins/medcli/libstrongswan-medcli.la
- at USE_DHCP_TRUE@am__append_86 = plugins/dhcp
- at MONOLITHIC_TRUE@@USE_DHCP_TRUE at am__append_87 = plugins/dhcp/libstrongswan-dhcp.la
- at USE_OSX_ATTR_TRUE@am__append_88 = plugins/osx_attr
- at MONOLITHIC_TRUE@@USE_OSX_ATTR_TRUE at am__append_89 = plugins/osx_attr/libstrongswan-osx-attr.la
- at USE_P_CSCF_TRUE@am__append_90 = plugins/p_cscf
- at MONOLITHIC_TRUE@@USE_P_CSCF_TRUE at am__append_91 = plugins/p_cscf/libstrongswan-p-cscf.la
- at USE_ANDROID_DNS_TRUE@am__append_92 = plugins/android_dns
- at MONOLITHIC_TRUE@@USE_ANDROID_DNS_TRUE at am__append_93 = plugins/android_dns/libstrongswan-android-dns.la
- at USE_ANDROID_LOG_TRUE@am__append_94 = plugins/android_log
- at MONOLITHIC_TRUE@@USE_ANDROID_LOG_TRUE at am__append_95 = plugins/android_log/libstrongswan-android-log.la
- at USE_HA_TRUE@am__append_96 = plugins/ha
- at MONOLITHIC_TRUE@@USE_HA_TRUE at am__append_97 = plugins/ha/libstrongswan-ha.la
- at USE_KERNEL_PFKEY_TRUE@am__append_98 = plugins/kernel_pfkey
- at MONOLITHIC_TRUE@@USE_KERNEL_PFKEY_TRUE at am__append_99 = plugins/kernel_pfkey/libstrongswan-kernel-pfkey.la
- at USE_KERNEL_PFROUTE_TRUE@am__append_100 = plugins/kernel_pfroute
- at MONOLITHIC_TRUE@@USE_KERNEL_PFROUTE_TRUE at am__append_101 = plugins/kernel_pfroute/libstrongswan-kernel-pfroute.la
- at USE_KERNEL_NETLINK_TRUE@am__append_102 = plugins/kernel_netlink
- at MONOLITHIC_TRUE@@USE_KERNEL_NETLINK_TRUE at am__append_103 = plugins/kernel_netlink/libstrongswan-kernel-netlink.la
- at USE_KERNEL_LIBIPSEC_TRUE@am__append_104 = plugins/kernel_libipsec
- at MONOLITHIC_TRUE@@USE_KERNEL_LIBIPSEC_TRUE at am__append_105 = plugins/kernel_libipsec/libstrongswan-kernel-libipsec.la
- at USE_KERNEL_WFP_TRUE@am__append_106 = plugins/kernel_wfp
- at MONOLITHIC_TRUE@@USE_KERNEL_WFP_TRUE at am__append_107 = plugins/kernel_wfp/libstrongswan-kernel-wfp.la
- at USE_KERNEL_IPH_TRUE@am__append_108 = plugins/kernel_iph
- at MONOLITHIC_TRUE@@USE_KERNEL_IPH_TRUE at am__append_109 = plugins/kernel_iph/libstrongswan-kernel-iph.la
- at USE_WHITELIST_TRUE@am__append_110 = plugins/whitelist
- at MONOLITHIC_TRUE@@USE_WHITELIST_TRUE at am__append_111 = plugins/whitelist/libstrongswan-whitelist.la
- at USE_LOOKIP_TRUE@am__append_112 = plugins/lookip
- at MONOLITHIC_TRUE@@USE_LOOKIP_TRUE at am__append_113 = plugins/lookip/libstrongswan-lookip.la
- at USE_ERROR_NOTIFY_TRUE@am__append_114 = plugins/error_notify
- at MONOLITHIC_TRUE@@USE_ERROR_NOTIFY_TRUE at am__append_115 = plugins/error_notify/libstrongswan-error-notify.la
- at USE_CERTEXPIRE_TRUE@am__append_116 = plugins/certexpire
- at MONOLITHIC_TRUE@@USE_CERTEXPIRE_TRUE at am__append_117 = plugins/certexpire/libstrongswan-certexpire.la
- at USE_SYSTIME_FIX_TRUE@am__append_118 = plugins/systime_fix
- at MONOLITHIC_TRUE@@USE_SYSTIME_FIX_TRUE at am__append_119 = plugins/systime_fix/libstrongswan-systime-fix.la
- at USE_LED_TRUE@am__append_120 = plugins/led
- at MONOLITHIC_TRUE@@USE_LED_TRUE at am__append_121 = plugins/led/libstrongswan-led.la
- at USE_DUPLICHECK_TRUE@am__append_122 = plugins/duplicheck
- at MONOLITHIC_TRUE@@USE_DUPLICHECK_TRUE at am__append_123 = plugins/duplicheck/libstrongswan-duplicheck.la
- at USE_COUPLING_TRUE@am__append_124 = plugins/coupling
- at MONOLITHIC_TRUE@@USE_COUPLING_TRUE at am__append_125 = plugins/coupling/libstrongswan-coupling.la
- at USE_RADATTR_TRUE@am__append_126 = plugins/radattr
- at MONOLITHIC_TRUE@@USE_RADATTR_TRUE at am__append_127 = plugins/radattr/libstrongswan-radattr.la
- at USE_UCI_TRUE@am__append_128 = plugins/uci
- at MONOLITHIC_TRUE@@USE_UCI_TRUE at am__append_129 = plugins/uci/libstrongswan-uci.la
- at USE_ADDRBLOCK_TRUE@am__append_130 = plugins/addrblock
- at MONOLITHIC_TRUE@@USE_ADDRBLOCK_TRUE at am__append_131 = plugins/addrblock/libstrongswan-addrblock.la
- at USE_UNITY_TRUE@am__append_132 = plugins/unity
- at MONOLITHIC_TRUE@@USE_UNITY_TRUE at am__append_133 = plugins/unity/libstrongswan-unity.la
- at USE_XAUTH_GENERIC_TRUE@am__append_134 = plugins/xauth_generic
- at MONOLITHIC_TRUE@@USE_XAUTH_GENERIC_TRUE at am__append_135 = plugins/xauth_generic/libstrongswan-xauth-generic.la
- at USE_XAUTH_EAP_TRUE@am__append_136 = plugins/xauth_eap
- at MONOLITHIC_TRUE@@USE_XAUTH_EAP_TRUE at am__append_137 = plugins/xauth_eap/libstrongswan-xauth-eap.la
- at USE_XAUTH_PAM_TRUE@am__append_138 = plugins/xauth_pam
- at MONOLITHIC_TRUE@@USE_XAUTH_PAM_TRUE at am__append_139 = plugins/xauth_pam/libstrongswan-xauth-pam.la
- at USE_XAUTH_NOAUTH_TRUE@am__append_140 = plugins/xauth_noauth
- at MONOLITHIC_TRUE@@USE_XAUTH_NOAUTH_TRUE at am__append_141 = plugins/xauth_noauth/libstrongswan-xauth-noauth.la
- at USE_RESOLVE_TRUE@am__append_142 = plugins/resolve
- at MONOLITHIC_TRUE@@USE_RESOLVE_TRUE at am__append_143 = plugins/resolve/libstrongswan-resolve.la
- at USE_ATTR_TRUE@am__append_144 = plugins/attr
- at MONOLITHIC_TRUE@@USE_ATTR_TRUE at am__append_145 = plugins/attr/libstrongswan-attr.la
- at USE_ATTR_SQL_TRUE@am__append_146 = plugins/attr_sql
- at MONOLITHIC_TRUE@@USE_ATTR_SQL_TRUE at am__append_147 = plugins/attr_sql/libstrongswan-attr-sql.la
+ at USE_EAP_AKA_3GPP_TRUE@am__append_54 = plugins/eap_aka_3gpp
+ at MONOLITHIC_TRUE@@USE_EAP_AKA_3GPP_TRUE at am__append_55 = plugins/eap_aka_3gpp/libstrongswan-eap-aka-3gpp.la
+ at USE_EAP_AKA_3GPP2_TRUE@am__append_56 = plugins/eap_aka_3gpp2
+ at MONOLITHIC_TRUE@@USE_EAP_AKA_3GPP2_TRUE at am__append_57 = plugins/eap_aka_3gpp2/libstrongswan-eap-aka-3gpp2.la
+ at MONOLITHIC_TRUE@@USE_SIMAKA_TRUE at am__append_58 = $(top_builddir)/src/libsimaka/libsimaka.la
+ at USE_EAP_MD5_TRUE@am__append_59 = plugins/eap_md5
+ at MONOLITHIC_TRUE@@USE_EAP_MD5_TRUE at am__append_60 = plugins/eap_md5/libstrongswan-eap-md5.la
+ at USE_EAP_GTC_TRUE@am__append_61 = plugins/eap_gtc
+ at MONOLITHIC_TRUE@@USE_EAP_GTC_TRUE at am__append_62 = plugins/eap_gtc/libstrongswan-eap-gtc.la
+ at USE_EAP_MSCHAPV2_TRUE@am__append_63 = plugins/eap_mschapv2
+ at MONOLITHIC_TRUE@@USE_EAP_MSCHAPV2_TRUE at am__append_64 = plugins/eap_mschapv2/libstrongswan-eap-mschapv2.la
+ at USE_EAP_DYNAMIC_TRUE@am__append_65 = plugins/eap_dynamic
+ at MONOLITHIC_TRUE@@USE_EAP_DYNAMIC_TRUE at am__append_66 = plugins/eap_dynamic/libstrongswan-eap-dynamic.la
+ at USE_EAP_RADIUS_TRUE@am__append_67 = plugins/eap_radius
+ at MONOLITHIC_TRUE@@USE_EAP_RADIUS_TRUE at am__append_68 = plugins/eap_radius/libstrongswan-eap-radius.la
+ at USE_EAP_TLS_TRUE@am__append_69 = plugins/eap_tls
+ at MONOLITHIC_TRUE@@USE_EAP_TLS_TRUE at am__append_70 = plugins/eap_tls/libstrongswan-eap-tls.la
+ at USE_EAP_TTLS_TRUE@am__append_71 = plugins/eap_ttls
+ at MONOLITHIC_TRUE@@USE_EAP_TTLS_TRUE at am__append_72 = plugins/eap_ttls/libstrongswan-eap-ttls.la
+ at USE_EAP_PEAP_TRUE@am__append_73 = plugins/eap_peap
+ at MONOLITHIC_TRUE@@USE_EAP_PEAP_TRUE at am__append_74 = plugins/eap_peap/libstrongswan-eap-peap.la
+ at USE_EAP_TNC_TRUE@am__append_75 = plugins/eap_tnc
+ at MONOLITHIC_TRUE@@USE_EAP_TNC_TRUE at am__append_76 = plugins/eap_tnc/libstrongswan-eap-tnc.la
+ at MONOLITHIC_TRUE@@USE_TLS_TRUE at am__append_77 = $(top_builddir)/src/libtls/libtls.la
+ at MONOLITHIC_TRUE@@USE_RADIUS_TRUE at am__append_78 = $(top_builddir)/src/libradius/libradius.la
+ at USE_TNC_IFMAP_TRUE@am__append_79 = plugins/tnc_ifmap
+ at MONOLITHIC_TRUE@@USE_TNC_IFMAP_TRUE at am__append_80 = plugins/tnc_ifmap/libstrongswan-tnc-ifmap.la
+ at USE_TNC_PDP_TRUE@am__append_81 = plugins/tnc_pdp
+ at MONOLITHIC_TRUE@@USE_TNC_PDP_TRUE at am__append_82 = plugins/tnc_pdp/libstrongswan-tnc-pdp.la
+ at MONOLITHIC_TRUE@@USE_LIBTNCCS_TRUE at am__append_83 = $(top_builddir)/src/libtnccs/libtnccs.la
+ at USE_MEDSRV_TRUE@am__append_84 = plugins/medsrv
+ at MONOLITHIC_TRUE@@USE_MEDSRV_TRUE at am__append_85 = plugins/medsrv/libstrongswan-medsrv.la
+ at USE_MEDCLI_TRUE@am__append_86 = plugins/medcli
+ at MONOLITHIC_TRUE@@USE_MEDCLI_TRUE at am__append_87 = plugins/medcli/libstrongswan-medcli.la
+ at USE_DHCP_TRUE@am__append_88 = plugins/dhcp
+ at MONOLITHIC_TRUE@@USE_DHCP_TRUE at am__append_89 = plugins/dhcp/libstrongswan-dhcp.la
+ at USE_OSX_ATTR_TRUE@am__append_90 = plugins/osx_attr
+ at MONOLITHIC_TRUE@@USE_OSX_ATTR_TRUE at am__append_91 = plugins/osx_attr/libstrongswan-osx-attr.la
+ at USE_P_CSCF_TRUE@am__append_92 = plugins/p_cscf
+ at MONOLITHIC_TRUE@@USE_P_CSCF_TRUE at am__append_93 = plugins/p_cscf/libstrongswan-p-cscf.la
+ at USE_ANDROID_DNS_TRUE@am__append_94 = plugins/android_dns
+ at MONOLITHIC_TRUE@@USE_ANDROID_DNS_TRUE at am__append_95 = plugins/android_dns/libstrongswan-android-dns.la
+ at USE_ANDROID_LOG_TRUE@am__append_96 = plugins/android_log
+ at MONOLITHIC_TRUE@@USE_ANDROID_LOG_TRUE at am__append_97 = plugins/android_log/libstrongswan-android-log.la
+ at USE_HA_TRUE@am__append_98 = plugins/ha
+ at MONOLITHIC_TRUE@@USE_HA_TRUE at am__append_99 = plugins/ha/libstrongswan-ha.la
+ at USE_KERNEL_PFKEY_TRUE@am__append_100 = plugins/kernel_pfkey
+ at MONOLITHIC_TRUE@@USE_KERNEL_PFKEY_TRUE at am__append_101 = plugins/kernel_pfkey/libstrongswan-kernel-pfkey.la
+ at USE_KERNEL_PFROUTE_TRUE@am__append_102 = plugins/kernel_pfroute
+ at MONOLITHIC_TRUE@@USE_KERNEL_PFROUTE_TRUE at am__append_103 = plugins/kernel_pfroute/libstrongswan-kernel-pfroute.la
+ at USE_KERNEL_NETLINK_TRUE@am__append_104 = plugins/kernel_netlink
+ at MONOLITHIC_TRUE@@USE_KERNEL_NETLINK_TRUE at am__append_105 = plugins/kernel_netlink/libstrongswan-kernel-netlink.la
+ at USE_KERNEL_LIBIPSEC_TRUE@am__append_106 = plugins/kernel_libipsec
+ at MONOLITHIC_TRUE@@USE_KERNEL_LIBIPSEC_TRUE at am__append_107 = plugins/kernel_libipsec/libstrongswan-kernel-libipsec.la
+ at USE_KERNEL_WFP_TRUE@am__append_108 = plugins/kernel_wfp
+ at MONOLITHIC_TRUE@@USE_KERNEL_WFP_TRUE at am__append_109 = plugins/kernel_wfp/libstrongswan-kernel-wfp.la
+ at USE_KERNEL_IPH_TRUE@am__append_110 = plugins/kernel_iph
+ at MONOLITHIC_TRUE@@USE_KERNEL_IPH_TRUE at am__append_111 = plugins/kernel_iph/libstrongswan-kernel-iph.la
+ at USE_WHITELIST_TRUE@am__append_112 = plugins/whitelist
+ at MONOLITHIC_TRUE@@USE_WHITELIST_TRUE at am__append_113 = plugins/whitelist/libstrongswan-whitelist.la
+ at USE_LOOKIP_TRUE@am__append_114 = plugins/lookip
+ at MONOLITHIC_TRUE@@USE_LOOKIP_TRUE at am__append_115 = plugins/lookip/libstrongswan-lookip.la
+ at USE_ERROR_NOTIFY_TRUE@am__append_116 = plugins/error_notify
+ at MONOLITHIC_TRUE@@USE_ERROR_NOTIFY_TRUE at am__append_117 = plugins/error_notify/libstrongswan-error-notify.la
+ at USE_CERTEXPIRE_TRUE@am__append_118 = plugins/certexpire
+ at MONOLITHIC_TRUE@@USE_CERTEXPIRE_TRUE at am__append_119 = plugins/certexpire/libstrongswan-certexpire.la
+ at USE_SYSTIME_FIX_TRUE@am__append_120 = plugins/systime_fix
+ at MONOLITHIC_TRUE@@USE_SYSTIME_FIX_TRUE at am__append_121 = plugins/systime_fix/libstrongswan-systime-fix.la
+ at USE_LED_TRUE@am__append_122 = plugins/led
+ at MONOLITHIC_TRUE@@USE_LED_TRUE at am__append_123 = plugins/led/libstrongswan-led.la
+ at USE_DUPLICHECK_TRUE@am__append_124 = plugins/duplicheck
+ at MONOLITHIC_TRUE@@USE_DUPLICHECK_TRUE at am__append_125 = plugins/duplicheck/libstrongswan-duplicheck.la
+ at USE_COUPLING_TRUE@am__append_126 = plugins/coupling
+ at MONOLITHIC_TRUE@@USE_COUPLING_TRUE at am__append_127 = plugins/coupling/libstrongswan-coupling.la
+ at USE_RADATTR_TRUE@am__append_128 = plugins/radattr
+ at MONOLITHIC_TRUE@@USE_RADATTR_TRUE at am__append_129 = plugins/radattr/libstrongswan-radattr.la
+ at USE_UCI_TRUE@am__append_130 = plugins/uci
+ at MONOLITHIC_TRUE@@USE_UCI_TRUE at am__append_131 = plugins/uci/libstrongswan-uci.la
+ at USE_ADDRBLOCK_TRUE@am__append_132 = plugins/addrblock
+ at MONOLITHIC_TRUE@@USE_ADDRBLOCK_TRUE at am__append_133 = plugins/addrblock/libstrongswan-addrblock.la
+ at USE_UNITY_TRUE@am__append_134 = plugins/unity
+ at MONOLITHIC_TRUE@@USE_UNITY_TRUE at am__append_135 = plugins/unity/libstrongswan-unity.la
+ at USE_XAUTH_GENERIC_TRUE@am__append_136 = plugins/xauth_generic
+ at MONOLITHIC_TRUE@@USE_XAUTH_GENERIC_TRUE at am__append_137 = plugins/xauth_generic/libstrongswan-xauth-generic.la
+ at USE_XAUTH_EAP_TRUE@am__append_138 = plugins/xauth_eap
+ at MONOLITHIC_TRUE@@USE_XAUTH_EAP_TRUE at am__append_139 = plugins/xauth_eap/libstrongswan-xauth-eap.la
+ at USE_XAUTH_PAM_TRUE@am__append_140 = plugins/xauth_pam
+ at MONOLITHIC_TRUE@@USE_XAUTH_PAM_TRUE at am__append_141 = plugins/xauth_pam/libstrongswan-xauth-pam.la
+ at USE_XAUTH_NOAUTH_TRUE@am__append_142 = plugins/xauth_noauth
+ at MONOLITHIC_TRUE@@USE_XAUTH_NOAUTH_TRUE at am__append_143 = plugins/xauth_noauth/libstrongswan-xauth-noauth.la
+ at USE_RESOLVE_TRUE@am__append_144 = plugins/resolve
+ at MONOLITHIC_TRUE@@USE_RESOLVE_TRUE at am__append_145 = plugins/resolve/libstrongswan-resolve.la
+ at USE_ATTR_TRUE@am__append_146 = plugins/attr
+ at MONOLITHIC_TRUE@@USE_ATTR_TRUE at am__append_147 = plugins/attr/libstrongswan-attr.la
+ at USE_ATTR_SQL_TRUE@am__append_148 = plugins/attr_sql
+ at MONOLITHIC_TRUE@@USE_ATTR_SQL_TRUE at am__append_149 = plugins/attr_sql/libstrongswan-attr-sql.la
 subdir = src/libcharon
 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
 am__aclocal_m4_deps = $(top_srcdir)/m4/config/libtool.m4 \
@@ -356,12 +358,12 @@ libcharon_la_DEPENDENCIES =  \
 	$(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_56) \
+	$(am__append_53) $(am__append_55) $(am__append_57) \
 	$(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_75) $(am__append_76) $(am__append_78) \
-	$(am__append_80) $(am__append_81) $(am__append_83) \
+	$(am__append_76) $(am__append_77) $(am__append_78) \
+	$(am__append_80) $(am__append_82) $(am__append_83) \
 	$(am__append_85) $(am__append_87) $(am__append_89) \
 	$(am__append_91) $(am__append_93) $(am__append_95) \
 	$(am__append_97) $(am__append_99) $(am__append_101) \
@@ -372,7 +374,7 @@ libcharon_la_DEPENDENCIES =  \
 	$(am__append_127) $(am__append_129) $(am__append_131) \
 	$(am__append_133) $(am__append_135) $(am__append_137) \
 	$(am__append_139) $(am__append_141) $(am__append_143) \
-	$(am__append_145) $(am__append_147)
+	$(am__append_145) $(am__append_147) $(am__append_149)
 am__libcharon_la_SOURCES_DIST = attributes/attributes.c \
 	attributes/attributes.h attributes/attribute_provider.h \
 	attributes/attribute_handler.h attributes/attribute_manager.c \
@@ -747,7 +749,7 @@ DIST_SUBDIRS = . plugins/load_tester plugins/socket_default \
 	plugins/ext_auth plugins/eap_identity plugins/eap_sim \
 	plugins/eap_sim_file plugins/eap_sim_pcsc \
 	plugins/eap_simaka_sql plugins/eap_simaka_pseudonym \
-	plugins/eap_simaka_reauth plugins/eap_aka \
+	plugins/eap_simaka_reauth plugins/eap_aka plugins/eap_aka_3gpp \
 	plugins/eap_aka_3gpp2 plugins/eap_md5 plugins/eap_gtc \
 	plugins/eap_mschapv2 plugins/eap_dynamic plugins/eap_radius \
 	plugins/eap_tls plugins/eap_ttls plugins/eap_peap \
@@ -889,8 +891,6 @@ RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
 RUBYGEMDIR = @RUBYGEMDIR@
-RUBYINCLUDE = @RUBYINCLUDE@
-RUBYLIB = @RUBYLIB@
 SED = @SED@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
@@ -991,6 +991,8 @@ random_device = @random_device@
 resolv_conf = @resolv_conf@
 routing_table = @routing_table@
 routing_table_prio = @routing_table_prio@
+ruby_CFLAGS = @ruby_CFLAGS@
+ruby_LIBS = @ruby_LIBS@
 runstatedir = @runstatedir@
 s_plugins = @s_plugins@
 sbindir = @sbindir@
@@ -1019,6 +1021,10 @@ top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
 tss2_CFLAGS = @tss2_CFLAGS@
 tss2_LIBS = @tss2_LIBS@
+tss2_socket_CFLAGS = @tss2_socket_CFLAGS@
+tss2_socket_LIBS = @tss2_socket_LIBS@
+tss2_tabrmd_CFLAGS = @tss2_tabrmd_CFLAGS@
+tss2_tabrmd_LIBS = @tss2_tabrmd_LIBS@
 urandom_device = @urandom_device@
 xml_CFLAGS = @xml_CFLAGS@
 xml_LIBS = @xml_LIBS@
@@ -1151,12 +1157,12 @@ libcharon_la_LIBADD =  \
 	$(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_56) $(am__append_58) \
+	$(am__append_55) $(am__append_57) $(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_75) \
-	$(am__append_76) $(am__append_78) $(am__append_80) \
-	$(am__append_81) $(am__append_83) $(am__append_85) \
+	$(am__append_72) $(am__append_74) $(am__append_76) \
+	$(am__append_77) $(am__append_78) $(am__append_80) \
+	$(am__append_82) $(am__append_83) $(am__append_85) \
 	$(am__append_87) $(am__append_89) $(am__append_91) \
 	$(am__append_93) $(am__append_95) $(am__append_97) \
 	$(am__append_99) $(am__append_101) $(am__append_103) \
@@ -1167,7 +1173,7 @@ libcharon_la_LIBADD =  \
 	$(am__append_129) $(am__append_131) $(am__append_133) \
 	$(am__append_135) $(am__append_137) $(am__append_139) \
 	$(am__append_141) $(am__append_143) $(am__append_145) \
-	$(am__append_147)
+	$(am__append_147) $(am__append_149)
 EXTRA_DIST = Android.mk
 @STATIC_PLUGIN_CONSTRUCTORS_TRUE at BUILT_SOURCES = $(srcdir)/plugin_constructors.c
 @STATIC_PLUGIN_CONSTRUCTORS_TRUE at CLEANFILES = $(srcdir)/plugin_constructors.c
@@ -1183,13 +1189,13 @@ EXTRA_DIST = Android.mk
 @MONOLITHIC_FALSE@	$(am__append_42) $(am__append_44) \
 @MONOLITHIC_FALSE@	$(am__append_46) $(am__append_48) \
 @MONOLITHIC_FALSE@	$(am__append_50) $(am__append_52) \
- at MONOLITHIC_FALSE@	$(am__append_54) $(am__append_57) \
+ at MONOLITHIC_FALSE@	$(am__append_54) $(am__append_56) \
 @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) \
- at MONOLITHIC_FALSE@	$(am__append_77) $(am__append_79) \
- at MONOLITHIC_FALSE@	$(am__append_82) $(am__append_84) \
+ at MONOLITHIC_FALSE@	$(am__append_75) $(am__append_79) \
+ at MONOLITHIC_FALSE@	$(am__append_81) $(am__append_84) \
 @MONOLITHIC_FALSE@	$(am__append_86) $(am__append_88) \
 @MONOLITHIC_FALSE@	$(am__append_90) $(am__append_92) \
 @MONOLITHIC_FALSE@	$(am__append_94) $(am__append_96) \
@@ -1205,7 +1211,7 @@ EXTRA_DIST = Android.mk
 @MONOLITHIC_FALSE@	$(am__append_134) $(am__append_136) \
 @MONOLITHIC_FALSE@	$(am__append_138) $(am__append_140) \
 @MONOLITHIC_FALSE@	$(am__append_142) $(am__append_144) \
- at MONOLITHIC_FALSE@	$(am__append_146) tests
+ at MONOLITHIC_FALSE@	$(am__append_146) $(am__append_148) tests
 
 # build optional plugins
 ########################
@@ -1221,13 +1227,13 @@ EXTRA_DIST = Android.mk
 @MONOLITHIC_TRUE@	$(am__append_42) $(am__append_44) \
 @MONOLITHIC_TRUE@	$(am__append_46) $(am__append_48) \
 @MONOLITHIC_TRUE@	$(am__append_50) $(am__append_52) \
- at MONOLITHIC_TRUE@	$(am__append_54) $(am__append_57) \
+ at MONOLITHIC_TRUE@	$(am__append_54) $(am__append_56) \
 @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) \
- at MONOLITHIC_TRUE@	$(am__append_77) $(am__append_79) \
- at MONOLITHIC_TRUE@	$(am__append_82) $(am__append_84) \
+ at MONOLITHIC_TRUE@	$(am__append_75) $(am__append_79) \
+ at MONOLITHIC_TRUE@	$(am__append_81) $(am__append_84) \
 @MONOLITHIC_TRUE@	$(am__append_86) $(am__append_88) \
 @MONOLITHIC_TRUE@	$(am__append_90) $(am__append_92) \
 @MONOLITHIC_TRUE@	$(am__append_94) $(am__append_96) \
@@ -1243,7 +1249,7 @@ EXTRA_DIST = Android.mk
 @MONOLITHIC_TRUE@	$(am__append_134) $(am__append_136) \
 @MONOLITHIC_TRUE@	$(am__append_138) $(am__append_140) \
 @MONOLITHIC_TRUE@	$(am__append_142) $(am__append_144) \
- at MONOLITHIC_TRUE@	$(am__append_146) . tests
+ at MONOLITHIC_TRUE@	$(am__append_146) $(am__append_148) . tests
 all: $(BUILT_SOURCES)
 	$(MAKE) $(AM_MAKEFLAGS) all-recursive
 
diff --git a/src/libcharon/bus/bus.c b/src/libcharon/bus/bus.c
index 77a9101..19943d0 100644
--- a/src/libcharon/bus/bus.c
+++ b/src/libcharon/bus/bus.c
@@ -827,7 +827,10 @@ METHOD(bus_t, ike_updown, void,
 		enumerator = ike_sa->create_child_sa_enumerator(ike_sa);
 		while (enumerator->enumerate(enumerator, (void**)&child_sa))
 		{
-			child_updown(this, child_sa, FALSE);
+			if (child_sa->get_state(child_sa) != CHILD_REKEYED)
+			{
+				child_updown(this, child_sa, FALSE);
+			}
 		}
 		enumerator->destroy(enumerator);
 	}
diff --git a/src/libcharon/config/peer_cfg.c b/src/libcharon/config/peer_cfg.c
index fcdd6fd..29f0678 100644
--- a/src/libcharon/config/peer_cfg.c
+++ b/src/libcharon/config/peer_cfg.c
@@ -21,7 +21,7 @@
 
 #include <daemon.h>
 
-#include <threading/mutex.h>
+#include <threading/rwlock.h>
 #include <collections/linked_list.h>
 #include <utils/identification.h>
 
@@ -71,9 +71,9 @@ struct private_peer_cfg_t {
 	linked_list_t *child_cfgs;
 
 	/**
-	 * mutex to lock access to list of child_cfgs
+	 * lock to access list of child_cfgs
 	 */
-	mutex_t *mutex;
+	rwlock_t *lock;
 
 	/**
 	 * should we send a certificate
@@ -195,9 +195,9 @@ METHOD(peer_cfg_t, get_ike_cfg, ike_cfg_t*,
 METHOD(peer_cfg_t, add_child_cfg, void,
 	private_peer_cfg_t *this, child_cfg_t *child_cfg)
 {
-	this->mutex->lock(this->mutex);
+	this->lock->write_lock(this->lock);
 	this->child_cfgs->insert_last(this->child_cfgs, child_cfg);
-	this->mutex->unlock(this->mutex);
+	this->lock->unlock(this->lock);
 }
 
 typedef struct {
@@ -266,13 +266,13 @@ METHOD(peer_cfg_t, replace_child_cfgs, enumerator_t*,
 
 	removed = linked_list_create();
 
-	other->mutex->lock(other->mutex);
+	other->lock->read_lock(other->lock);
 	added = linked_list_create_from_enumerator(
 					other->child_cfgs->create_enumerator(other->child_cfgs));
 	added->invoke_offset(added, offsetof(child_cfg_t, get_ref));
-	other->mutex->unlock(other->mutex);
+	other->lock->unlock(other->lock);
 
-	this->mutex->lock(this->mutex);
+	this->lock->write_lock(this->lock);
 	others = added->create_enumerator(added);
 	mine = this->child_cfgs->create_enumerator(this->child_cfgs);
 	while (mine->enumerate(mine, &my_cfg))
@@ -302,7 +302,7 @@ METHOD(peer_cfg_t, replace_child_cfgs, enumerator_t*,
 	}
 	others->destroy(others);
 	mine->destroy(mine);
-	this->mutex->unlock(this->mutex);
+	this->lock->unlock(this->lock);
 
 	INIT(enumerator,
 		.public = {
@@ -322,7 +322,7 @@ METHOD(peer_cfg_t, replace_child_cfgs, enumerator_t*,
 typedef struct {
 	enumerator_t public;
 	enumerator_t *wrapped;
-	mutex_t *mutex;
+	rwlock_t *lock;
 } child_cfg_enumerator_t;
 
 METHOD(peer_cfg_t, remove_child_cfg, void,
@@ -334,7 +334,7 @@ METHOD(peer_cfg_t, remove_child_cfg, void,
 METHOD(enumerator_t, child_cfg_enumerator_destroy, void,
 	child_cfg_enumerator_t *this)
 {
-	this->mutex->unlock(this->mutex);
+	this->lock->unlock(this->lock);
 	this->wrapped->destroy(this->wrapped);
 	free(this);
 }
@@ -359,11 +359,11 @@ METHOD(peer_cfg_t, create_child_cfg_enumerator, enumerator_t*,
 			.venumerate = _child_cfg_enumerate,
 			.destroy = _child_cfg_enumerator_destroy,
 		},
-		.mutex = this->mutex,
+		.lock = this->lock,
 		.wrapped = this->child_cfgs->create_enumerator(this->child_cfgs),
 	);
 
-	this->mutex->lock(this->mutex);
+	this->lock->read_lock(this->lock);
 	return &enumerator->public;
 }
 
@@ -724,7 +724,7 @@ METHOD(peer_cfg_t, destroy, void,
 		DESTROY_IF(this->peer_id);
 		free(this->mediated_by);
 #endif /* ME */
-		this->mutex->destroy(this->mutex);
+		this->lock->destroy(this->lock);
 		free(this->name);
 		free(this);
 	}
@@ -790,7 +790,7 @@ peer_cfg_t *peer_cfg_create(char *name, ike_cfg_t *ike_cfg,
 		.name = strdup(name),
 		.ike_cfg = ike_cfg,
 		.child_cfgs = linked_list_create(),
-		.mutex = mutex_create(MUTEX_TYPE_DEFAULT),
+		.lock = rwlock_create(RWLOCK_TYPE_DEFAULT),
 		.cert_policy = data->cert_policy,
 		.unique = data->unique,
 		.keyingtries = data->keyingtries,
diff --git a/src/libcharon/encoding/generator.c b/src/libcharon/encoding/generator.c
index 41aacd4..dee1a3f 100644
--- a/src/libcharon/encoding/generator.c
+++ b/src/libcharon/encoding/generator.c
@@ -86,7 +86,7 @@ struct private_generator_t {
 	uint8_t current_bit;
 
 	/**
-	 * Associated data struct to read informations from.
+	 * Associated data struct to read information from.
 	 */
 	void *data_struct;
 
diff --git a/src/libcharon/encoding/message.h b/src/libcharon/encoding/message.h
index 8c43729..732fd9b 100644
--- a/src/libcharon/encoding/message.h
+++ b/src/libcharon/encoding/message.h
@@ -312,7 +312,7 @@ struct message_t {
 	status_t (*add_fragment)(message_t *this, message_t *fragment);
 
 	/**
-	 * Gets the source host informations.
+	 * Gets the source host information.
 	 *
 	 * @warning Returned host_t object is not getting cloned,
 	 * do not destroy nor modify.
@@ -322,7 +322,7 @@ struct message_t {
 	host_t * (*get_source) (message_t *this);
 
 	/**
-	 * Sets the source host informations.
+	 * Sets the source host information.
 	 *
 	 * @warning host_t object is not getting cloned and gets destroyed by
 	 *			message_t.destroy or next call of message_t.set_source.
@@ -332,7 +332,7 @@ struct message_t {
 	void (*set_source) (message_t *this, host_t *host);
 
 	/**
-	 * Gets the destination host informations.
+	 * Gets the destination host information.
 	 *
 	 * @warning Returned host_t object is not getting cloned,
 	 * do not destroy nor modify.
@@ -342,7 +342,7 @@ struct message_t {
 	host_t * (*get_destination) (message_t *this);
 
 	/**
-	 * Sets the destination host informations.
+	 * Sets the destination host information.
 	 *
 	 * @warning host_t object is not getting cloned and gets destroyed by
 	 *			message_t.destroy or next call of message_t.set_destination.
diff --git a/src/libcharon/encoding/payloads/encodings.h b/src/libcharon/encoding/payloads/encodings.h
index 442bf74..9ff2375 100644
--- a/src/libcharon/encoding/payloads/encodings.h
+++ b/src/libcharon/encoding/payloads/encodings.h
@@ -37,7 +37,7 @@ typedef struct encoding_rule_t encoding_rule_t;
  * Header is parsed like a payload and gets its one payload_id
  * from PRIVATE USE space. Also the substructures
  * of specific payload types get their own payload_id
- * from PRIVATE_USE space. See IKEv2-Draft for more informations.
+ * from PRIVATE_USE space. See IKEv2-Draft for more information.
  */
 enum encoding_type_t {
 
diff --git a/src/libcharon/encoding/payloads/proposal_substructure.c b/src/libcharon/encoding/payloads/proposal_substructure.c
index 55641e1..c3f0639 100644
--- a/src/libcharon/encoding/payloads/proposal_substructure.c
+++ b/src/libcharon/encoding/payloads/proposal_substructure.c
@@ -1360,10 +1360,10 @@ static void set_from_proposal_v1(private_proposal_substructure_t *this,
 	enumerator = proposal->create_enumerator(proposal, INTEGRITY_ALGORITHM);
 	if (enumerator->enumerate(enumerator, &alg, &key_size))
 	{
+		transid = get_ikev1_transid_from_alg(INTEGRITY_ALGORITHM, alg);
 		alg = get_ikev1_auth_from_alg(alg);
 		if (alg)
 		{
-			transid = get_ikev1_transid_from_alg(INTEGRITY_ALGORITHM, alg);
 			if (!transform && transid)
 			{
 				transform = transform_substructure_create_type(
diff --git a/src/libcharon/kernel/kernel_interface.h b/src/libcharon/kernel/kernel_interface.h
index d601ebd..f4f55ad 100644
--- a/src/libcharon/kernel/kernel_interface.h
+++ b/src/libcharon/kernel/kernel_interface.h
@@ -77,6 +77,8 @@ enum kernel_feature_t {
 	KERNEL_REQUIRE_UDP_ENCAPSULATION = (1<<2),
 	/** IPsec backend does not require a policy reinstall on SA updates */
 	KERNEL_NO_POLICY_UPDATES = (1<<3),
+	/** IPsec backend supports installing SPIs on policies */
+	KERNEL_POLICY_SPI = (1<<4),
 };
 
 /**
diff --git a/src/libcharon/plugins/addrblock/Makefile.in b/src/libcharon/plugins/addrblock/Makefile.in
index 60fd19b..5a76c81 100644
--- a/src/libcharon/plugins/addrblock/Makefile.in
+++ b/src/libcharon/plugins/addrblock/Makefile.in
@@ -313,8 +313,6 @@ RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
 RUBYGEMDIR = @RUBYGEMDIR@
-RUBYINCLUDE = @RUBYINCLUDE@
-RUBYLIB = @RUBYLIB@
 SED = @SED@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
@@ -415,6 +413,8 @@ random_device = @random_device@
 resolv_conf = @resolv_conf@
 routing_table = @routing_table@
 routing_table_prio = @routing_table_prio@
+ruby_CFLAGS = @ruby_CFLAGS@
+ruby_LIBS = @ruby_LIBS@
 runstatedir = @runstatedir@
 s_plugins = @s_plugins@
 sbindir = @sbindir@
@@ -443,6 +443,10 @@ top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
 tss2_CFLAGS = @tss2_CFLAGS@
 tss2_LIBS = @tss2_LIBS@
+tss2_socket_CFLAGS = @tss2_socket_CFLAGS@
+tss2_socket_LIBS = @tss2_socket_LIBS@
+tss2_tabrmd_CFLAGS = @tss2_tabrmd_CFLAGS@
+tss2_tabrmd_LIBS = @tss2_tabrmd_LIBS@
 urandom_device = @urandom_device@
 xml_CFLAGS = @xml_CFLAGS@
 xml_LIBS = @xml_LIBS@
diff --git a/src/libcharon/plugins/android_dns/Makefile.in b/src/libcharon/plugins/android_dns/Makefile.in
index 0533d81..8f5ae6a 100644
--- a/src/libcharon/plugins/android_dns/Makefile.in
+++ b/src/libcharon/plugins/android_dns/Makefile.in
@@ -313,8 +313,6 @@ RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
 RUBYGEMDIR = @RUBYGEMDIR@
-RUBYINCLUDE = @RUBYINCLUDE@
-RUBYLIB = @RUBYLIB@
 SED = @SED@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
@@ -415,6 +413,8 @@ random_device = @random_device@
 resolv_conf = @resolv_conf@
 routing_table = @routing_table@
 routing_table_prio = @routing_table_prio@
+ruby_CFLAGS = @ruby_CFLAGS@
+ruby_LIBS = @ruby_LIBS@
 runstatedir = @runstatedir@
 s_plugins = @s_plugins@
 sbindir = @sbindir@
@@ -443,6 +443,10 @@ top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
 tss2_CFLAGS = @tss2_CFLAGS@
 tss2_LIBS = @tss2_LIBS@
+tss2_socket_CFLAGS = @tss2_socket_CFLAGS@
+tss2_socket_LIBS = @tss2_socket_LIBS@
+tss2_tabrmd_CFLAGS = @tss2_tabrmd_CFLAGS@
+tss2_tabrmd_LIBS = @tss2_tabrmd_LIBS@
 urandom_device = @urandom_device@
 xml_CFLAGS = @xml_CFLAGS@
 xml_LIBS = @xml_LIBS@
diff --git a/src/libcharon/plugins/android_log/Makefile.in b/src/libcharon/plugins/android_log/Makefile.in
index bc402ef..682fa15 100644
--- a/src/libcharon/plugins/android_log/Makefile.in
+++ b/src/libcharon/plugins/android_log/Makefile.in
@@ -313,8 +313,6 @@ RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
 RUBYGEMDIR = @RUBYGEMDIR@
-RUBYINCLUDE = @RUBYINCLUDE@
-RUBYLIB = @RUBYLIB@
 SED = @SED@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
@@ -415,6 +413,8 @@ random_device = @random_device@
 resolv_conf = @resolv_conf@
 routing_table = @routing_table@
 routing_table_prio = @routing_table_prio@
+ruby_CFLAGS = @ruby_CFLAGS@
+ruby_LIBS = @ruby_LIBS@
 runstatedir = @runstatedir@
 s_plugins = @s_plugins@
 sbindir = @sbindir@
@@ -443,6 +443,10 @@ top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
 tss2_CFLAGS = @tss2_CFLAGS@
 tss2_LIBS = @tss2_LIBS@
+tss2_socket_CFLAGS = @tss2_socket_CFLAGS@
+tss2_socket_LIBS = @tss2_socket_LIBS@
+tss2_tabrmd_CFLAGS = @tss2_tabrmd_CFLAGS@
+tss2_tabrmd_LIBS = @tss2_tabrmd_LIBS@
 urandom_device = @urandom_device@
 xml_CFLAGS = @xml_CFLAGS@
 xml_LIBS = @xml_LIBS@
diff --git a/src/libcharon/plugins/attr/Makefile.in b/src/libcharon/plugins/attr/Makefile.in
index 9fe4d94..6157045 100644
--- a/src/libcharon/plugins/attr/Makefile.in
+++ b/src/libcharon/plugins/attr/Makefile.in
@@ -310,8 +310,6 @@ RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
 RUBYGEMDIR = @RUBYGEMDIR@
-RUBYINCLUDE = @RUBYINCLUDE@
-RUBYLIB = @RUBYLIB@
 SED = @SED@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
@@ -412,6 +410,8 @@ random_device = @random_device@
 resolv_conf = @resolv_conf@
 routing_table = @routing_table@
 routing_table_prio = @routing_table_prio@
+ruby_CFLAGS = @ruby_CFLAGS@
+ruby_LIBS = @ruby_LIBS@
 runstatedir = @runstatedir@
 s_plugins = @s_plugins@
 sbindir = @sbindir@
@@ -440,6 +440,10 @@ top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
 tss2_CFLAGS = @tss2_CFLAGS@
 tss2_LIBS = @tss2_LIBS@
+tss2_socket_CFLAGS = @tss2_socket_CFLAGS@
+tss2_socket_LIBS = @tss2_socket_LIBS@
+tss2_tabrmd_CFLAGS = @tss2_tabrmd_CFLAGS@
+tss2_tabrmd_LIBS = @tss2_tabrmd_LIBS@
 urandom_device = @urandom_device@
 xml_CFLAGS = @xml_CFLAGS@
 xml_LIBS = @xml_LIBS@
diff --git a/src/libcharon/plugins/attr_sql/Makefile.in b/src/libcharon/plugins/attr_sql/Makefile.in
index b3ddf69..14a144c 100644
--- a/src/libcharon/plugins/attr_sql/Makefile.in
+++ b/src/libcharon/plugins/attr_sql/Makefile.in
@@ -313,8 +313,6 @@ RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
 RUBYGEMDIR = @RUBYGEMDIR@
-RUBYINCLUDE = @RUBYINCLUDE@
-RUBYLIB = @RUBYLIB@
 SED = @SED@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
@@ -415,6 +413,8 @@ random_device = @random_device@
 resolv_conf = @resolv_conf@
 routing_table = @routing_table@
 routing_table_prio = @routing_table_prio@
+ruby_CFLAGS = @ruby_CFLAGS@
+ruby_LIBS = @ruby_LIBS@
 runstatedir = @runstatedir@
 s_plugins = @s_plugins@
 sbindir = @sbindir@
@@ -443,6 +443,10 @@ top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
 tss2_CFLAGS = @tss2_CFLAGS@
 tss2_LIBS = @tss2_LIBS@
+tss2_socket_CFLAGS = @tss2_socket_CFLAGS@
+tss2_socket_LIBS = @tss2_socket_LIBS@
+tss2_tabrmd_CFLAGS = @tss2_tabrmd_CFLAGS@
+tss2_tabrmd_LIBS = @tss2_tabrmd_LIBS@
 urandom_device = @urandom_device@
 xml_CFLAGS = @xml_CFLAGS@
 xml_LIBS = @xml_LIBS@
diff --git a/src/libcharon/plugins/bypass_lan/Makefile.in b/src/libcharon/plugins/bypass_lan/Makefile.in
index 6c07948..1c1a452 100644
--- a/src/libcharon/plugins/bypass_lan/Makefile.in
+++ b/src/libcharon/plugins/bypass_lan/Makefile.in
@@ -313,8 +313,6 @@ RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
 RUBYGEMDIR = @RUBYGEMDIR@
-RUBYINCLUDE = @RUBYINCLUDE@
-RUBYLIB = @RUBYLIB@
 SED = @SED@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
@@ -415,6 +413,8 @@ random_device = @random_device@
 resolv_conf = @resolv_conf@
 routing_table = @routing_table@
 routing_table_prio = @routing_table_prio@
+ruby_CFLAGS = @ruby_CFLAGS@
+ruby_LIBS = @ruby_LIBS@
 runstatedir = @runstatedir@
 s_plugins = @s_plugins@
 sbindir = @sbindir@
@@ -443,6 +443,10 @@ top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
 tss2_CFLAGS = @tss2_CFLAGS@
 tss2_LIBS = @tss2_LIBS@
+tss2_socket_CFLAGS = @tss2_socket_CFLAGS@
+tss2_socket_LIBS = @tss2_socket_LIBS@
+tss2_tabrmd_CFLAGS = @tss2_tabrmd_CFLAGS@
+tss2_tabrmd_LIBS = @tss2_tabrmd_LIBS@
 urandom_device = @urandom_device@
 xml_CFLAGS = @xml_CFLAGS@
 xml_LIBS = @xml_LIBS@
diff --git a/src/libcharon/plugins/certexpire/Makefile.in b/src/libcharon/plugins/certexpire/Makefile.in
index acbd7a8..0ae0d28 100644
--- a/src/libcharon/plugins/certexpire/Makefile.in
+++ b/src/libcharon/plugins/certexpire/Makefile.in
@@ -313,8 +313,6 @@ RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
 RUBYGEMDIR = @RUBYGEMDIR@
-RUBYINCLUDE = @RUBYINCLUDE@
-RUBYLIB = @RUBYLIB@
 SED = @SED@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
@@ -415,6 +413,8 @@ random_device = @random_device@
 resolv_conf = @resolv_conf@
 routing_table = @routing_table@
 routing_table_prio = @routing_table_prio@
+ruby_CFLAGS = @ruby_CFLAGS@
+ruby_LIBS = @ruby_LIBS@
 runstatedir = @runstatedir@
 s_plugins = @s_plugins@
 sbindir = @sbindir@
@@ -443,6 +443,10 @@ top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
 tss2_CFLAGS = @tss2_CFLAGS@
 tss2_LIBS = @tss2_LIBS@
+tss2_socket_CFLAGS = @tss2_socket_CFLAGS@
+tss2_socket_LIBS = @tss2_socket_LIBS@
+tss2_tabrmd_CFLAGS = @tss2_tabrmd_CFLAGS@
+tss2_tabrmd_LIBS = @tss2_tabrmd_LIBS@
 urandom_device = @urandom_device@
 xml_CFLAGS = @xml_CFLAGS@
 xml_LIBS = @xml_LIBS@
diff --git a/src/libcharon/plugins/connmark/Makefile.in b/src/libcharon/plugins/connmark/Makefile.in
index 55bc25a..fb432cd 100644
--- a/src/libcharon/plugins/connmark/Makefile.in
+++ b/src/libcharon/plugins/connmark/Makefile.in
@@ -314,8 +314,6 @@ RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
 RUBYGEMDIR = @RUBYGEMDIR@
-RUBYINCLUDE = @RUBYINCLUDE@
-RUBYLIB = @RUBYLIB@
 SED = @SED@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
@@ -416,6 +414,8 @@ random_device = @random_device@
 resolv_conf = @resolv_conf@
 routing_table = @routing_table@
 routing_table_prio = @routing_table_prio@
+ruby_CFLAGS = @ruby_CFLAGS@
+ruby_LIBS = @ruby_LIBS@
 runstatedir = @runstatedir@
 s_plugins = @s_plugins@
 sbindir = @sbindir@
@@ -444,6 +444,10 @@ top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
 tss2_CFLAGS = @tss2_CFLAGS@
 tss2_LIBS = @tss2_LIBS@
+tss2_socket_CFLAGS = @tss2_socket_CFLAGS@
+tss2_socket_LIBS = @tss2_socket_LIBS@
+tss2_tabrmd_CFLAGS = @tss2_tabrmd_CFLAGS@
+tss2_tabrmd_LIBS = @tss2_tabrmd_LIBS@
 urandom_device = @urandom_device@
 xml_CFLAGS = @xml_CFLAGS@
 xml_LIBS = @xml_LIBS@
diff --git a/src/libcharon/plugins/coupling/Makefile.in b/src/libcharon/plugins/coupling/Makefile.in
index 6d6fe25..06f2592 100644
--- a/src/libcharon/plugins/coupling/Makefile.in
+++ b/src/libcharon/plugins/coupling/Makefile.in
@@ -313,8 +313,6 @@ RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
 RUBYGEMDIR = @RUBYGEMDIR@
-RUBYINCLUDE = @RUBYINCLUDE@
-RUBYLIB = @RUBYLIB@
 SED = @SED@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
@@ -415,6 +413,8 @@ random_device = @random_device@
 resolv_conf = @resolv_conf@
 routing_table = @routing_table@
 routing_table_prio = @routing_table_prio@
+ruby_CFLAGS = @ruby_CFLAGS@
+ruby_LIBS = @ruby_LIBS@
 runstatedir = @runstatedir@
 s_plugins = @s_plugins@
 sbindir = @sbindir@
@@ -443,6 +443,10 @@ top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
 tss2_CFLAGS = @tss2_CFLAGS@
 tss2_LIBS = @tss2_LIBS@
+tss2_socket_CFLAGS = @tss2_socket_CFLAGS@
+tss2_socket_LIBS = @tss2_socket_LIBS@
+tss2_tabrmd_CFLAGS = @tss2_tabrmd_CFLAGS@
+tss2_tabrmd_LIBS = @tss2_tabrmd_LIBS@
 urandom_device = @urandom_device@
 xml_CFLAGS = @xml_CFLAGS@
 xml_LIBS = @xml_LIBS@
diff --git a/src/libcharon/plugins/dhcp/Makefile.in b/src/libcharon/plugins/dhcp/Makefile.in
index d3f4ec8..aaca1ec 100644
--- a/src/libcharon/plugins/dhcp/Makefile.in
+++ b/src/libcharon/plugins/dhcp/Makefile.in
@@ -311,8 +311,6 @@ RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
 RUBYGEMDIR = @RUBYGEMDIR@
-RUBYINCLUDE = @RUBYINCLUDE@
-RUBYLIB = @RUBYLIB@
 SED = @SED@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
@@ -413,6 +411,8 @@ random_device = @random_device@
 resolv_conf = @resolv_conf@
 routing_table = @routing_table@
 routing_table_prio = @routing_table_prio@
+ruby_CFLAGS = @ruby_CFLAGS@
+ruby_LIBS = @ruby_LIBS@
 runstatedir = @runstatedir@
 s_plugins = @s_plugins@
 sbindir = @sbindir@
@@ -441,6 +441,10 @@ top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
 tss2_CFLAGS = @tss2_CFLAGS@
 tss2_LIBS = @tss2_LIBS@
+tss2_socket_CFLAGS = @tss2_socket_CFLAGS@
+tss2_socket_LIBS = @tss2_socket_LIBS@
+tss2_tabrmd_CFLAGS = @tss2_tabrmd_CFLAGS@
+tss2_tabrmd_LIBS = @tss2_tabrmd_LIBS@
 urandom_device = @urandom_device@
 xml_CFLAGS = @xml_CFLAGS@
 xml_LIBS = @xml_LIBS@
diff --git a/src/libcharon/plugins/dnscert/Makefile.in b/src/libcharon/plugins/dnscert/Makefile.in
index 3687f0c..0febca9 100644
--- a/src/libcharon/plugins/dnscert/Makefile.in
+++ b/src/libcharon/plugins/dnscert/Makefile.in
@@ -313,8 +313,6 @@ RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
 RUBYGEMDIR = @RUBYGEMDIR@
-RUBYINCLUDE = @RUBYINCLUDE@
-RUBYLIB = @RUBYLIB@
 SED = @SED@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
@@ -415,6 +413,8 @@ random_device = @random_device@
 resolv_conf = @resolv_conf@
 routing_table = @routing_table@
 routing_table_prio = @routing_table_prio@
+ruby_CFLAGS = @ruby_CFLAGS@
+ruby_LIBS = @ruby_LIBS@
 runstatedir = @runstatedir@
 s_plugins = @s_plugins@
 sbindir = @sbindir@
@@ -443,6 +443,10 @@ top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
 tss2_CFLAGS = @tss2_CFLAGS@
 tss2_LIBS = @tss2_LIBS@
+tss2_socket_CFLAGS = @tss2_socket_CFLAGS@
+tss2_socket_LIBS = @tss2_socket_LIBS@
+tss2_tabrmd_CFLAGS = @tss2_tabrmd_CFLAGS@
+tss2_tabrmd_LIBS = @tss2_tabrmd_LIBS@
 urandom_device = @urandom_device@
 xml_CFLAGS = @xml_CFLAGS@
 xml_LIBS = @xml_LIBS@
diff --git a/src/libcharon/plugins/duplicheck/Makefile.in b/src/libcharon/plugins/duplicheck/Makefile.in
index 69959d3..db44911 100644
--- a/src/libcharon/plugins/duplicheck/Makefile.in
+++ b/src/libcharon/plugins/duplicheck/Makefile.in
@@ -320,8 +320,6 @@ RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
 RUBYGEMDIR = @RUBYGEMDIR@
-RUBYINCLUDE = @RUBYINCLUDE@
-RUBYLIB = @RUBYLIB@
 SED = @SED@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
@@ -422,6 +420,8 @@ random_device = @random_device@
 resolv_conf = @resolv_conf@
 routing_table = @routing_table@
 routing_table_prio = @routing_table_prio@
+ruby_CFLAGS = @ruby_CFLAGS@
+ruby_LIBS = @ruby_LIBS@
 runstatedir = @runstatedir@
 s_plugins = @s_plugins@
 sbindir = @sbindir@
@@ -450,6 +450,10 @@ top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
 tss2_CFLAGS = @tss2_CFLAGS@
 tss2_LIBS = @tss2_LIBS@
+tss2_socket_CFLAGS = @tss2_socket_CFLAGS@
+tss2_socket_LIBS = @tss2_socket_LIBS@
+tss2_tabrmd_CFLAGS = @tss2_tabrmd_CFLAGS@
+tss2_tabrmd_LIBS = @tss2_tabrmd_LIBS@
 urandom_device = @urandom_device@
 xml_CFLAGS = @xml_CFLAGS@
 xml_LIBS = @xml_LIBS@
diff --git a/src/libcharon/plugins/eap_aka/Makefile.in b/src/libcharon/plugins/eap_aka/Makefile.in
index 5fff128..09291af 100644
--- a/src/libcharon/plugins/eap_aka/Makefile.in
+++ b/src/libcharon/plugins/eap_aka/Makefile.in
@@ -314,8 +314,6 @@ RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
 RUBYGEMDIR = @RUBYGEMDIR@
-RUBYINCLUDE = @RUBYINCLUDE@
-RUBYLIB = @RUBYLIB@
 SED = @SED@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
@@ -416,6 +414,8 @@ random_device = @random_device@
 resolv_conf = @resolv_conf@
 routing_table = @routing_table@
 routing_table_prio = @routing_table_prio@
+ruby_CFLAGS = @ruby_CFLAGS@
+ruby_LIBS = @ruby_LIBS@
 runstatedir = @runstatedir@
 s_plugins = @s_plugins@
 sbindir = @sbindir@
@@ -444,6 +444,10 @@ top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
 tss2_CFLAGS = @tss2_CFLAGS@
 tss2_LIBS = @tss2_LIBS@
+tss2_socket_CFLAGS = @tss2_socket_CFLAGS@
+tss2_socket_LIBS = @tss2_socket_LIBS@
+tss2_tabrmd_CFLAGS = @tss2_tabrmd_CFLAGS@
+tss2_tabrmd_LIBS = @tss2_tabrmd_LIBS@
 urandom_device = @urandom_device@
 xml_CFLAGS = @xml_CFLAGS@
 xml_LIBS = @xml_LIBS@
diff --git a/src/libcharon/plugins/eap_aka_3gpp/Makefile.am b/src/libcharon/plugins/eap_aka_3gpp/Makefile.am
new file mode 100644
index 0000000..5e230ea
--- /dev/null
+++ b/src/libcharon/plugins/eap_aka_3gpp/Makefile.am
@@ -0,0 +1,22 @@
+AM_CPPFLAGS = \
+	-I$(top_srcdir)/src/libstrongswan \
+	-I$(top_srcdir)/src/libcharon \
+	-I$(top_srcdir)/src/libsimaka
+
+AM_CFLAGS = \
+	$(PLUGIN_CFLAGS)
+
+libstrongswan_eap_aka_3gpp_la_LDFLAGS = -module -avoid-version
+
+if MONOLITHIC
+noinst_LTLIBRARIES = libstrongswan-eap-aka-3gpp.la
+else
+plugin_LTLIBRARIES = libstrongswan-eap-aka-3gpp.la
+libstrongswan_eap_aka_3gpp_la_LIBADD = $(top_builddir)/src/libsimaka/libsimaka.la
+endif
+
+libstrongswan_eap_aka_3gpp_la_SOURCES = \
+	eap_aka_3gpp_plugin.h eap_aka_3gpp_plugin.c \
+	eap_aka_3gpp_card.h eap_aka_3gpp_card.c \
+	eap_aka_3gpp_provider.h eap_aka_3gpp_provider.c \
+	eap_aka_3gpp_functions.h eap_aka_3gpp_functions.c
diff --git a/src/libcharon/plugins/eap_sim_file/Makefile.in b/src/libcharon/plugins/eap_aka_3gpp/Makefile.in
similarity index 91%
copy from src/libcharon/plugins/eap_sim_file/Makefile.in
copy to src/libcharon/plugins/eap_aka_3gpp/Makefile.in
index b247372..2b73a57 100644
--- a/src/libcharon/plugins/eap_sim_file/Makefile.in
+++ b/src/libcharon/plugins/eap_aka_3gpp/Makefile.in
@@ -88,7 +88,7 @@ PRE_UNINSTALL = :
 POST_UNINSTALL = :
 build_triplet = @build@
 host_triplet = @host@
-subdir = src/libcharon/plugins/eap_sim_file
+subdir = src/libcharon/plugins/eap_aka_3gpp
 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
 am__aclocal_m4_deps = $(top_srcdir)/m4/config/libtool.m4 \
 	$(top_srcdir)/m4/config/ltoptions.m4 \
@@ -136,24 +136,24 @@ am__uninstall_files_from_dir = { \
   }
 am__installdirs = "$(DESTDIR)$(plugindir)"
 LTLIBRARIES = $(noinst_LTLIBRARIES) $(plugin_LTLIBRARIES)
- at MONOLITHIC_FALSE@libstrongswan_eap_sim_file_la_DEPENDENCIES =  \
+ at MONOLITHIC_FALSE@libstrongswan_eap_aka_3gpp_la_DEPENDENCIES =  \
 @MONOLITHIC_FALSE@	$(top_builddir)/src/libsimaka/libsimaka.la
-am_libstrongswan_eap_sim_file_la_OBJECTS = eap_sim_file_plugin.lo \
-	eap_sim_file_card.lo eap_sim_file_provider.lo \
-	eap_sim_file_triplets.lo
-libstrongswan_eap_sim_file_la_OBJECTS =  \
-	$(am_libstrongswan_eap_sim_file_la_OBJECTS)
+am_libstrongswan_eap_aka_3gpp_la_OBJECTS = eap_aka_3gpp_plugin.lo \
+	eap_aka_3gpp_card.lo eap_aka_3gpp_provider.lo \
+	eap_aka_3gpp_functions.lo
+libstrongswan_eap_aka_3gpp_la_OBJECTS =  \
+	$(am_libstrongswan_eap_aka_3gpp_la_OBJECTS)
 AM_V_lt = $(am__v_lt_ at AM_V@)
 am__v_lt_ = $(am__v_lt_ at AM_DEFAULT_V@)
 am__v_lt_0 = --silent
 am__v_lt_1 = 
-libstrongswan_eap_sim_file_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \
+libstrongswan_eap_aka_3gpp_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \
 	$(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \
 	$(AM_CFLAGS) $(CFLAGS) \
-	$(libstrongswan_eap_sim_file_la_LDFLAGS) $(LDFLAGS) -o $@
- at MONOLITHIC_FALSE@am_libstrongswan_eap_sim_file_la_rpath = -rpath \
+	$(libstrongswan_eap_aka_3gpp_la_LDFLAGS) $(LDFLAGS) -o $@
+ at MONOLITHIC_FALSE@am_libstrongswan_eap_aka_3gpp_la_rpath = -rpath \
 @MONOLITHIC_FALSE@	$(plugindir)
- at MONOLITHIC_TRUE@am_libstrongswan_eap_sim_file_la_rpath =
+ at MONOLITHIC_TRUE@am_libstrongswan_eap_aka_3gpp_la_rpath =
 AM_V_P = $(am__v_P_ at AM_V@)
 am__v_P_ = $(am__v_P_ at AM_DEFAULT_V@)
 am__v_P_0 = false
@@ -188,8 +188,8 @@ AM_V_CCLD = $(am__v_CCLD_ at AM_V@)
 am__v_CCLD_ = $(am__v_CCLD_ at AM_DEFAULT_V@)
 am__v_CCLD_0 = @echo "  CCLD    " $@;
 am__v_CCLD_1 = 
-SOURCES = $(libstrongswan_eap_sim_file_la_SOURCES)
-DIST_SOURCES = $(libstrongswan_eap_sim_file_la_SOURCES)
+SOURCES = $(libstrongswan_eap_aka_3gpp_la_SOURCES)
+DIST_SOURCES = $(libstrongswan_eap_aka_3gpp_la_SOURCES)
 am__can_run_installinfo = \
   case $$AM_UPDATE_INFO_DIR in \
     n|no|NO) false;; \
@@ -315,8 +315,6 @@ RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
 RUBYGEMDIR = @RUBYGEMDIR@
-RUBYINCLUDE = @RUBYINCLUDE@
-RUBYLIB = @RUBYLIB@
 SED = @SED@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
@@ -417,6 +415,8 @@ random_device = @random_device@
 resolv_conf = @resolv_conf@
 routing_table = @routing_table@
 routing_table_prio = @routing_table_prio@
+ruby_CFLAGS = @ruby_CFLAGS@
+ruby_LIBS = @ruby_LIBS@
 runstatedir = @runstatedir@
 s_plugins = @s_plugins@
 sbindir = @sbindir@
@@ -445,28 +445,31 @@ top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
 tss2_CFLAGS = @tss2_CFLAGS@
 tss2_LIBS = @tss2_LIBS@
+tss2_socket_CFLAGS = @tss2_socket_CFLAGS@
+tss2_socket_LIBS = @tss2_socket_LIBS@
+tss2_tabrmd_CFLAGS = @tss2_tabrmd_CFLAGS@
+tss2_tabrmd_LIBS = @tss2_tabrmd_LIBS@
 urandom_device = @urandom_device@
 xml_CFLAGS = @xml_CFLAGS@
 xml_LIBS = @xml_LIBS@
 AM_CPPFLAGS = \
 	-I$(top_srcdir)/src/libstrongswan \
 	-I$(top_srcdir)/src/libcharon \
-	-I$(top_srcdir)/src/libsimaka \
-	-DIPSEC_CONFDIR=\"${sysconfdir}\"
+	-I$(top_srcdir)/src/libsimaka
 
 AM_CFLAGS = \
 	$(PLUGIN_CFLAGS)
 
- at MONOLITHIC_TRUE@noinst_LTLIBRARIES = libstrongswan-eap-sim-file.la
- at MONOLITHIC_FALSE@plugin_LTLIBRARIES = libstrongswan-eap-sim-file.la
- at MONOLITHIC_FALSE@libstrongswan_eap_sim_file_la_LIBADD = $(top_builddir)/src/libsimaka/libsimaka.la
-libstrongswan_eap_sim_file_la_SOURCES = \
-	eap_sim_file_plugin.h eap_sim_file_plugin.c \
-	eap_sim_file_card.h eap_sim_file_card.c \
-	eap_sim_file_provider.h eap_sim_file_provider.c \
-	eap_sim_file_triplets.h eap_sim_file_triplets.c
+libstrongswan_eap_aka_3gpp_la_LDFLAGS = -module -avoid-version
+ at MONOLITHIC_TRUE@noinst_LTLIBRARIES = libstrongswan-eap-aka-3gpp.la
+ at MONOLITHIC_FALSE@plugin_LTLIBRARIES = libstrongswan-eap-aka-3gpp.la
+ at MONOLITHIC_FALSE@libstrongswan_eap_aka_3gpp_la_LIBADD = $(top_builddir)/src/libsimaka/libsimaka.la
+libstrongswan_eap_aka_3gpp_la_SOURCES = \
+	eap_aka_3gpp_plugin.h eap_aka_3gpp_plugin.c \
+	eap_aka_3gpp_card.h eap_aka_3gpp_card.c \
+	eap_aka_3gpp_provider.h eap_aka_3gpp_provider.c \
+	eap_aka_3gpp_functions.h eap_aka_3gpp_functions.c
 
-libstrongswan_eap_sim_file_la_LDFLAGS = -module -avoid-version
 all: all-am
 
 .SUFFIXES:
@@ -480,9 +483,9 @@ $(srcdir)/Makefile.in:  $(srcdir)/Makefile.am  $(am__configure_deps)
 	      exit 1;; \
 	  esac; \
 	done; \
-	echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/libcharon/plugins/eap_sim_file/Makefile'; \
+	echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/libcharon/plugins/eap_aka_3gpp/Makefile'; \
 	$(am__cd) $(top_srcdir) && \
-	  $(AUTOMAKE) --gnu src/libcharon/plugins/eap_sim_file/Makefile
+	  $(AUTOMAKE) --gnu src/libcharon/plugins/eap_aka_3gpp/Makefile
 Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
 	@case '$?' in \
 	  *config.status*) \
@@ -547,8 +550,8 @@ clean-pluginLTLIBRARIES:
 	  rm -f $${locs}; \
 	}
 
-libstrongswan-eap-sim-file.la: $(libstrongswan_eap_sim_file_la_OBJECTS) $(libstrongswan_eap_sim_file_la_DEPENDENCIES) $(EXTRA_libstrongswan_eap_sim_file_la_DEPENDENCIES) 
-	$(AM_V_CCLD)$(libstrongswan_eap_sim_file_la_LINK) $(am_libstrongswan_eap_sim_file_la_rpath) $(libstrongswan_eap_sim_file_la_OBJECTS) $(libstrongswan_eap_sim_file_la_LIBADD) $(LIBS)
+libstrongswan-eap-aka-3gpp.la: $(libstrongswan_eap_aka_3gpp_la_OBJECTS) $(libstrongswan_eap_aka_3gpp_la_DEPENDENCIES) $(EXTRA_libstrongswan_eap_aka_3gpp_la_DEPENDENCIES) 
+	$(AM_V_CCLD)$(libstrongswan_eap_aka_3gpp_la_LINK) $(am_libstrongswan_eap_aka_3gpp_la_rpath) $(libstrongswan_eap_aka_3gpp_la_OBJECTS) $(libstrongswan_eap_aka_3gpp_la_LIBADD) $(LIBS)
 
 mostlyclean-compile:
 	-rm -f *.$(OBJEXT)
@@ -556,10 +559,10 @@ mostlyclean-compile:
 distclean-compile:
 	-rm -f *.tab.c
 
- at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/eap_sim_file_card.Plo at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/eap_sim_file_plugin.Plo at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/eap_sim_file_provider.Plo at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/eap_sim_file_triplets.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/eap_aka_3gpp_card.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/eap_aka_3gpp_functions.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/eap_aka_3gpp_plugin.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/eap_aka_3gpp_provider.Plo at am__quote@
 
 .c.o:
 @am__fastdepCC_TRUE@	$(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\
diff --git a/src/libcharon/plugins/eap_aka_3gpp/eap_aka_3gpp_card.c b/src/libcharon/plugins/eap_aka_3gpp/eap_aka_3gpp_card.c
new file mode 100644
index 0000000..22c1181
--- /dev/null
+++ b/src/libcharon/plugins/eap_aka_3gpp/eap_aka_3gpp_card.c
@@ -0,0 +1,208 @@
+/*
+ * Copyright (C) 2008-2009 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.
+ */
+/*
+ * Copyright (C) 2015 Thomas Strangert
+ * Polystar System AB, Sweden
+ *
+ * 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 "eap_aka_3gpp_card.h"
+
+#include <daemon.h>
+
+typedef struct private_eap_aka_3gpp_card_t private_eap_aka_3gpp_card_t;
+
+/**
+ * Private data of an eap_aka_3gpp_card_t object.
+ */
+struct private_eap_aka_3gpp_card_t {
+
+	/**
+	 * Public eap_aka_3gpp_card_t interface.
+	 */
+	eap_aka_3gpp_card_t public;
+
+	/**
+	 * AKA functions
+	 */
+	eap_aka_3gpp_functions_t *f;
+
+	/**
+	 * do sequence number checking?
+	 */
+	bool seq_check;
+
+	/**
+	 * SQN stored in this pseudo-USIM
+	 */
+	uint8_t sqn[AKA_SQN_LEN];
+};
+
+METHOD(simaka_card_t, get_quintuplet, status_t,
+	private_eap_aka_3gpp_card_t *this, identification_t *id,
+	char rand[AKA_RAND_LEN], char autn[AKA_AUTN_LEN], char ck[AKA_CK_LEN],
+	char ik[AKA_IK_LEN], char res[AKA_RES_MAX], int *res_len)
+{
+	uint8_t *amf, *mac;
+	uint8_t k[AKA_K_LEN], opc[AKA_OPC_LEN], ak[AKA_AK_LEN], sqn[AKA_SQN_LEN],
+			xmac[AKA_MAC_LEN];
+
+	if (!eap_aka_3gpp_get_k_opc(id, k, opc))
+	{
+		DBG1(DBG_IKE, "no EAP key found for %Y to authenticate with AKA", id);
+		return FAILED;
+	}
+	DBG4(DBG_IKE, "EAP key found for id %Y, using K %b and OPc %b", id, k,
+		 AKA_K_LEN, opc, AKA_OPC_LEN);
+
+	/* AUTN = SQN xor AK | AMF | MAC */
+	memcpy(sqn, autn, AKA_SQN_LEN);
+	amf = autn + AKA_SQN_LEN;
+	mac = autn + AKA_SQN_LEN + AKA_AMF_LEN;
+	DBG3(DBG_IKE, "received AUTN %b", autn, AKA_AUTN_LEN);
+	DBG3(DBG_IKE, "received AMF %b", amf, AKA_AMF_LEN);
+	DBG3(DBG_IKE, "received MAC %b", mac, AKA_MAC_LEN);
+
+	/* generate RES, CK, IK, AK from received RAND */
+	DBG3(DBG_IKE, "received RAND %b", rand, AKA_RAND_LEN);
+	if (!this->f->f2345(this->f, k, opc, rand, res, ck, ik, ak))
+	{
+		return FAILED;
+	}
+	*res_len = AKA_RES_LEN;
+	DBG3(DBG_IKE, "using RES %b", res, AKA_RES_LEN);
+	DBG3(DBG_IKE, "using CK %b", ck, AKA_CK_LEN);
+	DBG3(DBG_IKE, "using IK %b", ik, AKA_IK_LEN);
+	DBG3(DBG_IKE, "using AK %b", ak, AKA_AK_LEN);
+
+	/* XOR anonymity key AK into SQN to decrypt it */
+	memxor(sqn, ak, AKA_SQN_LEN);
+	DBG3(DBG_IKE, "using SQN %b", sqn, AKA_SQN_LEN);
+
+	/* calculate expected MAC and compare against received one */
+	if (!this->f->f1(this->f, k, opc, rand, sqn, amf, xmac))
+	{
+		return FAILED;
+	}
+	if (!memeq_const(mac, xmac, AKA_MAC_LEN))
+	{
+		DBG1(DBG_IKE, "received MAC does not match XMAC");
+		DBG3(DBG_IKE, "MAC %b\nXMAC %b", mac, AKA_MAC_LEN, xmac, AKA_MAC_LEN);
+		return FAILED;
+	}
+	DBG3(DBG_IKE, "MAC equals XMAC %b", mac, AKA_MAC_LEN);
+
+	if (this->seq_check && memcmp(this->sqn, sqn, AKA_SQN_LEN) >= 0)
+	{
+		DBG3(DBG_IKE, "received SQN %b\ncurrent SQN %b",
+			 sqn, AKA_SQN_LEN, this->sqn, AKA_SQN_LEN);
+		return INVALID_STATE;
+	}
+
+	/* update stored SQN to the received one */
+	memcpy(this->sqn, sqn, AKA_SQN_LEN);
+
+	return SUCCESS;
+}
+
+METHOD(simaka_card_t, resync, bool,
+	private_eap_aka_3gpp_card_t *this, identification_t *id,
+	char rand[AKA_RAND_LEN], char auts[AKA_AUTS_LEN])
+{
+	uint8_t amf[AKA_AMF_LEN], k[AKA_K_LEN], opc[AKA_OPC_LEN], aks[AKA_AK_LEN],
+			macs[AKA_MAC_LEN];
+
+	if (!eap_aka_3gpp_get_k_opc(id, k, opc))
+	{
+		DBG1(DBG_IKE, "no EAP key found for %Y to resync AKA", id);
+		return FALSE;
+	}
+	DBG4(DBG_IKE, "EAP key found for id %Y, using K %b and OPc %b to resync AKA",
+		 id, k, AKA_K_LEN, opc, AKA_OPC_LEN);
+
+	/* AMF is set to zero in resync */
+	memset(amf, 0, AKA_AMF_LEN);
+	if (!this->f->f5star(this->f, k, opc, rand, aks) ||
+	    !this->f->f1star(this->f, k, opc, rand, this->sqn, amf, macs))
+	{
+		return FALSE;
+	}
+	/* AUTS = SQN xor AKS | MACS */
+	memcpy(auts, this->sqn, AKA_SQN_LEN);
+	memxor(auts, aks, AKA_AK_LEN);
+	memcpy(auts + AKA_AK_LEN, macs, AKA_MAC_LEN);
+	DBG3(DBG_IKE, "generated AUTS %b", auts, AKA_AUTN_LEN);
+
+	return TRUE;
+}
+
+METHOD(eap_aka_3gpp_card_t, destroy, void,
+	private_eap_aka_3gpp_card_t *this)
+{
+	free(this);
+}
+
+/**
+ * See header
+ */
+eap_aka_3gpp_card_t *eap_aka_3gpp_card_create(eap_aka_3gpp_functions_t *f)
+{
+	private_eap_aka_3gpp_card_t *this;
+
+	INIT(this,
+		.public = {
+			.card = {
+				.get_triplet = (void*)return_false,
+				.get_quintuplet = _get_quintuplet,
+				.resync = _resync,
+				.get_pseudonym = (void*)return_null,
+				.set_pseudonym = (void*)nop,
+				.get_reauth = (void*)return_null,
+				.set_reauth = (void*)nop,
+			},
+			.destroy = _destroy,
+		},
+		.f = f,
+		.seq_check = lib->settings->get_bool(lib->settings,
+									"%s.plugins.eap-aka-3gpp.seq_check",
+#ifdef SEQ_CHECK /* handle legacy compile time configuration as default */
+									TRUE,
+#else /* !SEQ_CHECK */
+									FALSE,
+#endif /* SEQ_CHECK */
+									lib->ns),
+	);
+
+	eap_aka_3gpp_get_sqn(this->sqn, 0);
+
+	return &this->public;
+}
diff --git a/src/libcharon/plugins/eap_aka_3gpp/eap_aka_3gpp_card.h b/src/libcharon/plugins/eap_aka_3gpp/eap_aka_3gpp_card.h
new file mode 100644
index 0000000..0ef9068
--- /dev/null
+++ b/src/libcharon/plugins/eap_aka_3gpp/eap_aka_3gpp_card.h
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 2008-2009 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.
+ */
+/*
+ * Copyright (C) 2015 Thomas Strangert
+ * Polystar System AB, Sweden
+ *
+ * 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 eap_aka_3gpp_card eap_aka_3gpp_card
+ * @{ @ingroup eap_aka_3gpp
+ */
+
+#ifndef EAP_AKA_3GPP_CARD_H_
+#define EAP_AKA_3GPP_CARD_H_
+
+#include "eap_aka_3gpp_functions.h"
+
+#include <simaka_card.h>
+
+typedef struct eap_aka_3gpp_card_t eap_aka_3gpp_card_t;
+
+/**
+ * SIM card implementation using a set of AKA functions.
+ */
+struct eap_aka_3gpp_card_t {
+
+	/**
+	 * Implements simaka_card_t interface
+	 */
+	simaka_card_t card;
+
+	/**
+	 * Destroy a eap_aka_3gpp_card_t.
+	 */
+	void (*destroy)(eap_aka_3gpp_card_t *this);
+};
+
+/**
+ * Create a eap_aka_3gpp_card instance.
+ *
+ * @param f		AKA functions
+ */
+eap_aka_3gpp_card_t *eap_aka_3gpp_card_create(eap_aka_3gpp_functions_t *f);
+
+#endif /** EAP_AKA_3GPP_CARD_H_ @}*/
diff --git a/src/libcharon/plugins/eap_aka_3gpp/eap_aka_3gpp_functions.c b/src/libcharon/plugins/eap_aka_3gpp/eap_aka_3gpp_functions.c
new file mode 100644
index 0000000..d017d2c
--- /dev/null
+++ b/src/libcharon/plugins/eap_aka_3gpp/eap_aka_3gpp_functions.c
@@ -0,0 +1,364 @@
+/*
+ * Copyright (C) 2017 Tobias Brunner
+ * Copyright (C) 2008-2009 Martin Willi
+ * HSR Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT 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) 2015 Thomas Strangert
+ * Polystar System AB, Sweden
+ *
+ * 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 "eap_aka_3gpp_functions.h"
+
+#include <limits.h>
+#include <ctype.h>
+#include <daemon.h>
+
+typedef struct private_eap_aka_3gpp_functions_t private_eap_aka_3gpp_functions_t;
+
+/**
+ * Private data of an eap_aka_3gpp_functions_t object.
+ */
+struct private_eap_aka_3gpp_functions_t {
+
+	/**
+	 * Public eap_aka_3gpp_functions_t interface.
+	 */
+	eap_aka_3gpp_functions_t public;
+
+	/**
+	 * AES instance
+	 */
+	crypter_t *crypter;
+};
+
+/*
+ * Described in header
+ */
+bool eap_aka_3gpp_get_k_opc(identification_t *id, uint8_t k[AKA_K_LEN],
+							uint8_t opc[AKA_OPC_LEN])
+{
+	shared_key_t *shared;
+	chunk_t key;
+
+	shared = lib->credmgr->get_shared(lib->credmgr, SHARED_EAP, id, NULL);
+	if (!shared)
+	{
+		return FALSE;
+	}
+	key = shared->get_key(shared);
+
+	if (key.len == AKA_K_LEN)
+	{
+		memcpy(k, key.ptr, AKA_K_LEN);
+		/* set OPc to a neutral default value, harmless to XOR with */
+		memset(opc, '\0', AKA_OPC_LEN);
+	}
+	else if (key.len == AKA_K_LEN + AKA_OPC_LEN)
+	{
+		memcpy(k, key.ptr, AKA_K_LEN);
+		memcpy(opc, key.ptr + AKA_K_LEN, AKA_OPC_LEN);
+	}
+	else
+	{
+		DBG1(DBG_IKE, "invalid EAP K or K+OPc key found for %Y to authenticate "
+			 "with AKA, should be a %d or %d byte long binary value", id,
+			 AKA_K_LEN, AKA_K_LEN + AKA_OPC_LEN);
+		shared->destroy(shared);
+		return FALSE;
+	}
+	shared->destroy(shared);
+	return TRUE;
+}
+
+/*
+ * Described in header
+ */
+void eap_aka_3gpp_get_sqn(uint8_t sqn[AKA_SQN_LEN], int offset)
+{
+	timeval_t time;
+
+	gettimeofday(&time, NULL);
+	/* set sqn to an integer containing 4 bytes seconds + 2 bytes usecs */
+	time.tv_sec = htonl(time.tv_sec + offset);
+	/* usec's are never larger than 0x000f423f, so we shift the 12 first bits */
+	time.tv_usec = htonl(time.tv_usec << 12);
+	memcpy(sqn, (uint8_t*)&time.tv_sec + sizeof(time_t) - 4, 4);
+	memcpy(sqn + 4, &time.tv_usec, 2);
+}
+
+static bool f1andf1star(private_eap_aka_3gpp_functions_t *this,
+	const uint8_t k[AKA_K_LEN], const uint8_t opc[AKA_OPC_LEN],
+	const uint8_t rand[AKA_RAND_LEN], const uint8_t sqn[AKA_SQN_LEN],
+	const uint8_t amf[AKA_AMF_LEN], uint8_t mac[16])
+{
+	uint8_t i, data[16], in[16], iv[16] = { 0 };
+
+	if (!this->crypter->set_key(this->crypter,
+								chunk_create((uint8_t*)k, AKA_K_LEN)))
+	{
+		return FALSE;
+	}
+
+	/* XOR RAND and OPc */
+	memcpy(data, rand, sizeof(data));
+	memxor(data, opc, sizeof(data));
+	if (!this->crypter->encrypt(this->crypter, chunk_create(data, sizeof(data)),
+								chunk_create(iv, sizeof(iv)), NULL))
+	{
+		return FALSE;
+	}
+
+	/* concatenate SQN || AMF ||SQN || AMF */
+	memcpy(in, sqn, 6);
+	memcpy(&in[6], amf, 2);
+	memcpy(&in[8], in, 8);
+
+	/* XOR opc and in, rotate by r1=64, and XOR
+	 * on the constant c1 (which is all zeroes) and finally the output above */
+	for (i = 0; i < 16; i++)
+	{
+		data[(i + 8) % 16] ^= in[i] ^ opc[i];
+	}
+	if (!this->crypter->encrypt(this->crypter, chunk_create(data, sizeof(data)),
+								chunk_create(iv, sizeof(iv)), NULL))
+	{
+		return FALSE;
+	}
+	memxor(data, opc, sizeof(data));
+	memcpy(mac, data, 16);
+	return TRUE;
+}
+
+METHOD(eap_aka_3gpp_functions_t, f1, bool,
+	private_eap_aka_3gpp_functions_t *this,	const uint8_t k[AKA_K_LEN],
+	const uint8_t opc[AKA_OPC_LEN],	const uint8_t rand[AKA_RAND_LEN],
+	const uint8_t sqn[AKA_SQN_LEN],	const uint8_t amf[AKA_AMF_LEN],
+	uint8_t maca[AKA_MAC_LEN])
+{
+	uint8_t mac[16];
+
+	if (!f1andf1star(this, k, opc, rand, sqn, amf, mac))
+	{
+		return FALSE;
+	}
+	/* only diff between f1 and f1* is here:
+	 * f1  uses bytes 0-7  as MAC-A
+	 * f1* uses bytes 8-15 as MAC-S */
+	memcpy(maca, mac, AKA_MAC_LEN);
+	return TRUE;
+}
+
+METHOD(eap_aka_3gpp_functions_t, f1star, bool,
+	private_eap_aka_3gpp_functions_t *this, const uint8_t k[AKA_K_LEN],
+	const uint8_t opc[AKA_OPC_LEN], const uint8_t rand[AKA_RAND_LEN],
+	const uint8_t sqn[AKA_SQN_LEN], const uint8_t amf[AKA_AMF_LEN],
+	uint8_t macs[AKA_MAC_LEN])
+{
+	uint8_t mac[16];
+
+	if (!f1andf1star(this, k, opc, rand, sqn, amf, mac))
+	{
+		return FALSE;
+	}
+	/* only diff between f1 and f1* is here:
+	 * f1  uses bytes 0-7  as MAC-A
+	 * f1* uses bytes 8-15 as MAC-S */
+	memcpy(macs, &mac[8], AKA_MAC_LEN);
+	return TRUE;
+}
+
+METHOD(eap_aka_3gpp_functions_t, f2345, bool,
+	private_eap_aka_3gpp_functions_t *this, const uint8_t k[AKA_K_LEN],
+	const uint8_t opc[AKA_OPC_LEN], const uint8_t rand[AKA_RAND_LEN],
+	uint8_t res[AKA_RES_LEN], uint8_t ck[AKA_CK_LEN], uint8_t ik[AKA_IK_LEN],
+	uint8_t ak[AKA_AK_LEN])
+{
+	uint8_t data[16], iv[16] = { 0 };
+	chunk_t temp;
+	uint8_t i;
+
+	if (!this->crypter->set_key(this->crypter,
+								chunk_create((uint8_t*)k, AKA_K_LEN)))
+	{
+		return FALSE;
+	}
+
+	/* XOR RAND and OPc */
+	memcpy(data, rand, sizeof(data));
+	memxor(data, opc, sizeof(data));
+	if (!this->crypter->encrypt(this->crypter, chunk_create(data, sizeof(data)),
+								chunk_create(iv, sizeof(iv)), &temp))
+	{
+		return FALSE;
+	}
+
+	/* to obtain output block OUT2: XOR OPc and TEMP,
+	 * rotate by r2=0, and XOR on the constant c2 (which is all zeroes except
+	 * that the last bit is 1). */
+	for (i = 0; i < 16; i++)
+	{
+		data[i] = temp.ptr[i] ^ opc[i];
+	}
+	data[15] ^= 1;
+
+	if (!this->crypter->encrypt(this->crypter, chunk_create(data, sizeof(data)),
+								chunk_create(iv, sizeof(iv)), NULL))
+	{
+		chunk_free(&temp);
+		return FALSE;
+	}
+	memxor(data, opc, sizeof(data));
+
+	/* f5 output */
+	memcpy(ak, data, 6);
+	/* f2 output */
+	memcpy(res, &data[8], 8);
+
+	/* to obtain output block OUT3: XOR OPc and TEMP,
+	 * rotate by r3=32, and XOR on the constant c3 (which
+	 * is all zeroes except that the next to last bit is 1) */
+	for (i = 0; i < 16; i++)
+	{
+		data[(i + 12) % 16] = temp.ptr[i] ^ opc[i];
+	}
+	data[15] ^= 2;
+
+	if (!this->crypter->encrypt(this->crypter, chunk_create(data, sizeof(data)),
+								chunk_create(iv, sizeof(iv)), NULL))
+	{
+		chunk_free(&temp);
+		return FALSE;
+	}
+	memxor(data, opc, sizeof(data));
+
+	/* f3 output */
+	memcpy(ck, data, 16);
+
+	/* to obtain output block OUT4: XOR OPc and TEMP,
+	 * rotate by r4=64, and XOR on the constant c4 (which
+	 * is all zeroes except that the 2nd from last bit is 1). */
+	for (i = 0; i < 16; i++)
+	{
+		data[(i + 8) % 16] = temp.ptr[i] ^ opc[i];
+	}
+	data[15] ^= 4;
+
+	if (!this->crypter->encrypt(this->crypter, chunk_create(data, sizeof(data)),
+								chunk_create(iv, sizeof(iv)), NULL))
+	{
+		chunk_free(&temp);
+		return FALSE;
+	}
+	memxor(data, opc, sizeof(data));
+	/* f4 output */
+	memcpy(ik, data, 16);
+	chunk_free(&temp);
+	return TRUE;
+
+}
+
+METHOD(eap_aka_3gpp_functions_t, f5star, bool,
+	private_eap_aka_3gpp_functions_t *this, const uint8_t k[AKA_K_LEN],
+	const uint8_t opc[AKA_OPC_LEN], const uint8_t rand[AKA_RAND_LEN],
+	uint8_t aks[AKA_AK_LEN])
+{
+	uint8_t i, data[16], iv[16] = { 0 };
+	chunk_t temp;
+
+	if (!this->crypter->set_key(this->crypter,
+								chunk_create((uint8_t*)k, AKA_K_LEN)))
+	{
+		return FALSE;
+	}
+
+	/* XOR RAND and OPc */
+	memcpy(data, rand, sizeof(data));
+	memxor(data, opc, sizeof(data));
+	if (!this->crypter->encrypt(this->crypter, chunk_create(data, sizeof(data)),
+								chunk_create(iv, sizeof(iv)), &temp))
+	{
+		return FALSE;
+	}
+
+	/* to obtain output block OUT5: XOR OPc and the output above,
+	 * rotate by r5=96, and XOR on the constant c5 (which
+	 * is all zeroes except that the 3rd from last bit is 1). */
+	for (i = 0; i < 16; i++)
+	{
+		data[(i + 4) % 16] = temp.ptr[i] ^ opc[i];
+	}
+	data[15] ^= 8;
+	chunk_free(&temp);
+
+	if (!this->crypter->encrypt(this->crypter, chunk_create(data, sizeof(data)),
+								chunk_create(iv, sizeof(iv)), NULL))
+	{
+		return FALSE;
+	}
+	memxor(data, opc, sizeof(data));
+	memcpy(aks, data, 6);
+	return TRUE;
+}
+
+METHOD(eap_aka_3gpp_functions_t, destroy, void,
+	private_eap_aka_3gpp_functions_t *this)
+{
+	this->crypter->destroy(this->crypter);
+	free(this);
+}
+
+/**
+ * See header
+ */
+eap_aka_3gpp_functions_t *eap_aka_3gpp_functions_create()
+{
+	private_eap_aka_3gpp_functions_t *this;
+
+	INIT(this,
+		.public = {
+			.f1 = _f1,
+			.f1star = _f1star,
+			.f2345 = _f2345,
+			.f5star = _f5star,
+			.destroy = _destroy,
+		},
+		.crypter = lib->crypto->create_crypter(lib->crypto, ENCR_AES_CBC, 16),
+	);
+	if (!this->crypter)
+	{
+		DBG1(DBG_IKE, "%N not supported, unable to use 3GPP algorithm",
+			 encryption_algorithm_names, ENCR_AES_CBC);
+		free(this);
+		return NULL;
+	}
+	return &this->public;
+}
diff --git a/src/libcharon/plugins/eap_aka_3gpp/eap_aka_3gpp_functions.h b/src/libcharon/plugins/eap_aka_3gpp/eap_aka_3gpp_functions.h
new file mode 100644
index 0000000..c089cd3
--- /dev/null
+++ b/src/libcharon/plugins/eap_aka_3gpp/eap_aka_3gpp_functions.h
@@ -0,0 +1,172 @@
+/*
+ * Copyright (C) 2008-2009 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.
+ */
+/*
+ * Copyright (C) 2015 Thomas Strangert
+ * Polystar System AB, Sweden
+ *
+ * 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 eap_aka_3gpp_functions eap_aka_3gpp_functions
+ * @{ @ingroup eap_aka_3gpp
+ */
+
+#ifndef EAP_AKA_3GPP_FUNCTIONS_H_
+#define EAP_AKA_3GPP_FUNCTIONS_H_
+
+#include <credentials/keys/shared_key.h>
+#include <simaka_manager.h>
+#include "eap_aka_3gpp_plugin.h"
+
+#define AKA_SQN_LEN		 6
+#define AKA_K_LEN		16
+#define AKA_OPC_LEN		16
+#define AKA_MAC_LEN		 8
+#define AKA_AK_LEN		 6
+#define AKA_AMF_LEN		 2
+#define AKA_RES_LEN		 8
+
+typedef struct eap_aka_3gpp_functions_t eap_aka_3gpp_functions_t;
+
+/**
+ * Get a shared key K and OPc of a particular user from the credential database.
+ *
+ * @param id			user identity
+ * @param[out] k		(16 byte) scratchpad to receive secret key K
+ * @param[out] opc		(16 byte) scratchpad to receive operator variant key
+ *						derivate OPc
+ */
+bool eap_aka_3gpp_get_k_opc(identification_t *id, uint8_t k[AKA_K_LEN],
+							uint8_t opc[AKA_OPC_LEN]);
+
+/**
+ * Get SQN using current time. Only used when creating/initializing
+ * an eap_aka_3gpp_card_t or eap_aka_3gpp_provider_t object.
+ *
+ * @param offset		time offset to add to current time to avoid initial
+ *						SQN resync
+ * @param[out] sqn		(6 byte) scratchpad to receive generated SQN
+ */
+void eap_aka_3gpp_get_sqn(uint8_t sqn[AKA_SQN_LEN], int offset);
+
+/**
+ * f1, f1*(), f2345() and f5*() functions from 3GPP as specified
+ * in the TS 35.205, .206, .207, .208 standards.
+ */
+struct eap_aka_3gpp_functions_t {
+
+	/**
+	 * f1 : Calculate MAC-A from RAND, SQN, AMF using K and OPc
+	 *
+	 * @param k			(128 bit) secret key K
+	 * @param opc		(128 bit) operator variant key derivate OPc
+	 * @param rand		(128 bit) random value RAND
+	 * @param sqn		 (48 bit) sequence number SQN
+	 * @param amf		 (16 bit) authentication management field AMF
+	 * @param[out] maca	 (64 bit) scratchpad to receive network auth code MAC-A
+	 * @return				TRUE if calculations successful
+	 */
+	bool (*f1)(eap_aka_3gpp_functions_t *this,
+			const uint8_t k[AKA_K_LEN], const uint8_t opc[AKA_OPC_LEN],
+			const uint8_t rand[AKA_RAND_LEN], const uint8_t sqn[AKA_SQN_LEN],
+			const uint8_t amf[AKA_AMF_LEN],
+			uint8_t maca[AKA_MAC_LEN]);
+
+
+	/**
+	 * f1* : Calculate MAC-S from RAND, SQN, AMF using K and OPc
+	 *
+	 * @param k			(128 bit) secret key K
+	 * @param opc		(128 bit) operator variant key derivate OPc
+	 * @param rand		(128 bit) random value RAND
+	 * @param sqn		 (48 bit) sequence number SQN
+	 * @param amf		 (16 bit) authentication management field AMF
+	 * @param[out] macs	 (64 bit) scratchpad to receive resync auth code MAC-S
+	 * @return				TRUE if calculations successful
+	 */
+	bool (*f1star)(eap_aka_3gpp_functions_t *this,
+			const uint8_t k[AKA_K_LEN], const uint8_t opc[AKA_OPC_LEN],
+			const uint8_t rand[AKA_RAND_LEN], const uint8_t sqn[AKA_SQN_LEN],
+			const uint8_t amf[AKA_AMF_LEN],
+			uint8_t macs[AKA_MAC_LEN]);
+
+	/**
+	 * f2345 : Do f2, f3, f4 and f5 in a single scoop, where:
+	 * f2 : Calculates RES from RAND using K and OPc
+	 * f3 : Calculates CK  from RAND using K and OPc
+	 * f4 : Calculates IK  from RAND using K and OPc
+	 * f5 : Calculates AK  from RAND using K and OPc
+	 *
+	 * @param k			(128 bit) secret key K
+	 * @param opc		(128 bit) operator variant key derivate OPc
+	 * @param rand		(128 bit) random value RAND
+	 * @param[out] res	 (64 bit) scratchpad to receive signed response RES
+	 * @param[out] ck	(128 bit) scratchpad to receive encryption key CK
+	 * @param[out] ik	(128 bit) scratchpad to receive integrity key IK
+	 * @param[out] ak	 (48 bit) scratchpad to receive anonymity key AK
+	 * @return				TRUE if calculations successful
+	 */
+	bool (*f2345)(eap_aka_3gpp_functions_t *this,
+				  const uint8_t k[AKA_K_LEN], const uint8_t opc[AKA_OPC_LEN],
+				  const uint8_t rand[AKA_RAND_LEN],
+				  uint8_t res[AKA_RES_LEN], uint8_t ck[AKA_CK_LEN],
+				  uint8_t ik[AKA_IK_LEN], uint8_t ak[AKA_AK_LEN]);
+
+
+	/**
+	 * f5* : Calculates resync AKS from RAND using K and OPc
+	 *
+	 * @param k			(128 bit) secret key K
+	 * @param opc		(128 bit) operator variant key derivate OPc
+	 * @param rand		(128 bit) random value RAND
+	 * @param[out] aks	 (48 bit) scratchpad to receive resync anonymity key AKS
+	 * @return				TRUE if calculations successful
+	 */
+	bool (*f5star)(eap_aka_3gpp_functions_t *this,
+				   const uint8_t k[AKA_K_LEN], const uint8_t opc[AKA_OPC_LEN],
+				   const uint8_t rand[AKA_RAND_LEN],
+				   uint8_t aks[AKA_AK_LEN]);
+
+	/**
+	 * Destroy a eap_aka_3gpp_functions_t.
+	 */
+	void (*destroy)(eap_aka_3gpp_functions_t *this);
+};
+
+/**
+ * Create a eap_aka_3gpp_functions instance.
+ *
+ * @return	function set, NULL on error
+ */
+eap_aka_3gpp_functions_t *eap_aka_3gpp_functions_create();
+
+#endif /** EAP_AKA_3GPP_FUNCTIONS_H_ @}*/
diff --git a/src/libcharon/plugins/eap_aka_3gpp/eap_aka_3gpp_plugin.c b/src/libcharon/plugins/eap_aka_3gpp/eap_aka_3gpp_plugin.c
new file mode 100644
index 0000000..3d0e061
--- /dev/null
+++ b/src/libcharon/plugins/eap_aka_3gpp/eap_aka_3gpp_plugin.c
@@ -0,0 +1,164 @@
+/*
+ * Copyright (C) 2008-2009 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.
+ */
+/*
+ * Copyright (C) 2015 Thomas Strangert
+ * Polystar System AB, Sweden
+ *
+ * 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 "eap_aka_3gpp_plugin.h"
+#include "eap_aka_3gpp_card.h"
+#include "eap_aka_3gpp_provider.h"
+#include "eap_aka_3gpp_functions.h"
+
+#include <daemon.h>
+
+typedef struct private_eap_aka_3gpp_t private_eap_aka_3gpp_t;
+
+/**
+ * Private data of an eap_aka_3gpp_t object.
+ */
+struct private_eap_aka_3gpp_t {
+
+	/**
+	 * Public eap_aka_3gpp_plugin_t interface.
+	 */
+	eap_aka_3gpp_plugin_t public;
+
+	/**
+	 * USIM/EAP-AKA card
+	 */
+	eap_aka_3gpp_card_t *card;
+
+	/**
+	 * EAP-AKA provider
+	 */
+	eap_aka_3gpp_provider_t *provider;
+
+	/**
+	 * AKA functions
+	 */
+	eap_aka_3gpp_functions_t *functions;
+};
+
+METHOD(plugin_t, get_name, char*,
+	private_eap_aka_3gpp_t *this)
+{
+	return "eap-aka-3gpp";
+}
+
+/**
+ * Try to instanciate ea_aka_3gpp functions and card/provider backends
+ */
+static bool register_functions(private_eap_aka_3gpp_t *this,
+							   plugin_feature_t *feature, bool reg, void *data)
+{
+	if (reg)
+	{
+		this->functions = eap_aka_3gpp_functions_create();
+		if (!this->functions)
+		{
+			return FALSE;
+		}
+		this->card = eap_aka_3gpp_card_create(this->functions);
+		this->provider = eap_aka_3gpp_provider_create(this->functions);
+		return TRUE;
+	}
+	this->card->destroy(this->card);
+	this->provider->destroy(this->provider);
+	this->functions->destroy(this->functions);
+	this->card = NULL;
+	this->provider = NULL;
+	this->functions = NULL;
+	return TRUE;
+}
+
+/**
+ * Callback providing our card to register
+ */
+static simaka_card_t* get_card(private_eap_aka_3gpp_t *this)
+{
+	return &this->card->card;
+}
+
+/**
+ * Callback providing our provider to register
+ */
+static simaka_provider_t* get_provider(private_eap_aka_3gpp_t *this)
+{
+	return &this->provider->provider;
+}
+
+METHOD(plugin_t, get_features, int,
+	private_eap_aka_3gpp_t *this, plugin_feature_t *features[])
+{
+	static plugin_feature_t f[] = {
+		PLUGIN_CALLBACK((void*)register_functions, NULL),
+			PLUGIN_PROVIDE(CUSTOM, "eap-aka-3gpp-functions"),
+				PLUGIN_DEPENDS(CRYPTER, ENCR_AES_CBC, 16),
+		PLUGIN_CALLBACK(simaka_manager_register, get_card),
+			PLUGIN_PROVIDE(CUSTOM, "aka-card"),
+				PLUGIN_DEPENDS(CUSTOM, "aka-manager"),
+				PLUGIN_DEPENDS(CUSTOM, "eap-aka-3gpp-functions"),
+		PLUGIN_CALLBACK(simaka_manager_register, get_provider),
+			PLUGIN_PROVIDE(CUSTOM, "aka-provider"),
+				PLUGIN_DEPENDS(CUSTOM, "aka-manager"),
+				PLUGIN_DEPENDS(CUSTOM, "eap-aka-3gpp-functions"),
+	};
+	*features = f;
+	return countof(f);
+}
+
+METHOD(plugin_t, destroy, void, private_eap_aka_3gpp_t *this)
+{
+	free(this);
+}
+
+/**
+ * See header
+ */
+plugin_t *eap_aka_3gpp_plugin_create()
+{
+	private_eap_aka_3gpp_t *this;
+
+	INIT(this,
+		.public = {
+			.plugin = {
+				.get_name = _get_name,
+				.get_features = _get_features,
+				.destroy = _destroy,
+			},
+		},
+	);
+
+	return &this->public.plugin;
+}
diff --git a/src/libcharon/plugins/eap_aka_3gpp/eap_aka_3gpp_plugin.h b/src/libcharon/plugins/eap_aka_3gpp/eap_aka_3gpp_plugin.h
new file mode 100644
index 0000000..e101f4b
--- /dev/null
+++ b/src/libcharon/plugins/eap_aka_3gpp/eap_aka_3gpp_plugin.h
@@ -0,0 +1,89 @@
+/*
+ * Copyright (C) 2008-2009 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.
+ */
+/*
+ * Copyright (C) 2015 Thomas Strangert
+ * Polystar System AB, Sweden
+ *
+ * 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 eap_aka_3gpp eap_aka_3gpp
+ * @ingroup cplugins
+ *
+ * @defgroup eap_aka_3gpp_plugin eap_aka_3gpp_plugin
+ * @{ @ingroup eap_aka_3gpp
+ */
+
+#ifndef EAP_AKA_3GPP_PLUGIN_H_
+#define EAP_AKA_3GPP_PLUGIN_H_
+
+#include <plugins/plugin.h>
+
+typedef struct eap_aka_3gpp_plugin_t eap_aka_3gpp_plugin_t;
+
+/**
+ * Plugin to provide a USIM card/provider according to the 3GPP standard.
+ *
+ * This plugin implements the 3GPP standards TS 35.205, .206, .207, .208
+ * completely in software using the MILENAGE algorithm.
+ * The shared keys used for authentication (K, OPc) are from ipsec.secrets.
+ * The peers ID is used to query it.
+ *
+ * To enable SEQ sequence check by default define SEQ_CHECK. Left undefined/off,
+ * it makes the USIM 'card' to accept any SEQ number, not comparing received
+ * SQN with its own locally stored value. This potentially allows an attacker
+ * to do replay attacks. But since the server has proven his identity via IKE,
+ * such an attack is only possible between server and AAA (if any).
+ * Note that SEQ_CHECK only controls the compile-time default behaviour,
+ * but the run-time behaviour can always be controlled by setting the
+ * charon.plugins.eap-aka-3gpp.seq_check config variable.
+ */
+struct eap_aka_3gpp_plugin_t {
+
+	/**
+	 * implements plugin interface
+	 */
+	plugin_t plugin;
+};
+
+/**
+ * The AKA mechanism uses sequence numbers to detect replay attacks. The
+ * peer stores the sequence number normally in a USIM and accepts
+ * incremental sequence numbers (incremental for lifetime of the USIM). To
+ * prevent a complex sequence number management, this implementation uses
+ * a sequence number derived from time. It is initialized to the startup
+ * time of the daemon. On the provider side, an offset can optionally be
+ * added to allow for a time sqew towards the card side.
+ */
+#define SQN_TIME_OFFSET 180
+
+#endif /** EAP_AKA_3GPP_PLUGIN_H_ @}*/
diff --git a/src/libcharon/plugins/eap_aka_3gpp/eap_aka_3gpp_provider.c b/src/libcharon/plugins/eap_aka_3gpp/eap_aka_3gpp_provider.c
new file mode 100644
index 0000000..d5112d3
--- /dev/null
+++ b/src/libcharon/plugins/eap_aka_3gpp/eap_aka_3gpp_provider.c
@@ -0,0 +1,205 @@
+/*
+ * Copyright (C) 2008-2009 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.
+ */
+/*
+ * Copyright (C) 2015 Thomas Strangert
+ * Polystar System AB, Sweden
+ *
+ * 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 "eap_aka_3gpp_provider.h"
+
+#include <daemon.h>
+
+typedef struct private_eap_aka_3gpp_provider_t private_eap_aka_3gpp_provider_t;
+
+/**
+ * Private data of an eap_aka_3gpp_provider_t object.
+ */
+struct private_eap_aka_3gpp_provider_t {
+
+	/**
+	 * Public eap_aka_3gpp_provider_t interface.
+	 */
+	eap_aka_3gpp_provider_t public;
+
+	/**
+	 * AKA functions
+	 */
+	eap_aka_3gpp_functions_t *f;
+
+	/**
+	 * time based SQN, we use the same for all peers
+	 */
+	uint8_t sqn[AKA_SQN_LEN];
+};
+
+/** Authentication management field, AMF, as defined in 3GPP TS 33.102 V12.2.0
+ *
+ * The 16 bits in the AMF are numbered from "0" to "15" where bit "0" is
+ * the most significant bit and bit "15" is the least significant bit.
+ * Bit "0" is called the "AMF separation bit". It is used for the purposes
+ * of EPS (Evolved Packet System) and is specified in
+ * -	TS 33.401 [28] for E-UTRAN access to EPS;
+ * -	TS 33.402 [29] for non-3GPP access to EPS.
+ * Bits "1" to "7" are reserved for future standardization use.
+ * Bits "1" to "7" shall be set to 0 while not yet specified for a particular use.
+ * Bits "8" to "15" can be used for proprietary purposes.
+ */
+static const uint8_t amf[AKA_AMF_LEN] = {0x80, 0x00};
+
+METHOD(simaka_provider_t, get_quintuplet, bool,
+	private_eap_aka_3gpp_provider_t *this, identification_t *id,
+	char rand[AKA_RAND_LEN], char xres[AKA_RES_MAX], int *xres_len,
+	char ck[AKA_CK_LEN], char ik[AKA_IK_LEN], char autn[AKA_AUTN_LEN])
+{
+	rng_t *rng;
+	uint8_t maca[AKA_MAC_LEN], ak[AKA_AK_LEN], k[AKA_K_LEN], opc[AKA_OPC_LEN];
+
+	/* generate RAND: we use a RNG already registered as f0(). */
+	rng = lib->crypto->create_rng(lib->crypto, RNG_WEAK);
+	if (!rng || !rng->get_bytes(rng, AKA_RAND_LEN, rand))
+	{
+		DBG1(DBG_IKE, "generating RAND for AKA failed");
+		DESTROY_IF(rng);
+		return FALSE;
+	}
+	rng->destroy(rng);
+	DBG3(DBG_IKE, "generated rand %b", rand, AKA_RAND_LEN);
+
+	if (!eap_aka_3gpp_get_k_opc(id, k, opc))
+	{
+		DBG1(DBG_IKE, "no EAP key found for %Y to authenticate with AKA", id);
+		return FALSE;
+	}
+	DBG4(DBG_IKE, "EAP key found for id %Y, using K %b and OPc %b", id, k,
+		 AKA_K_LEN, opc, AKA_OPC_LEN);
+
+	/* generate MAC and XRES, CK, IK, AK */
+	if (!this->f->f1(this->f, k, opc, rand, this->sqn, amf, maca) ||
+	    !this->f->f2345(this->f, k, opc, rand, xres, ck, ik, ak))
+	{
+		return FALSE;
+	}
+	*xres_len = AKA_RES_LEN;
+
+	/* create AUTN = (SQN xor AK) || AMF || MAC */
+	memcpy(autn, this->sqn, AKA_SQN_LEN);
+	memxor(autn, ak, AKA_AK_LEN);
+	memcpy(autn + AKA_SQN_LEN, amf, AKA_AMF_LEN);
+	memcpy(autn + AKA_SQN_LEN + AKA_AMF_LEN, maca, AKA_MAC_LEN);
+	DBG3(DBG_IKE, "AUTN %b", autn, AKA_AUTN_LEN);
+
+	chunk_increment(chunk_create(this->sqn, AKA_SQN_LEN));
+
+	return TRUE;
+}
+
+METHOD(simaka_provider_t, resync, bool,
+	private_eap_aka_3gpp_provider_t *this, identification_t *id,
+	char rand[AKA_RAND_LEN], char auts[AKA_AUTS_LEN])
+{
+	uint8_t *sqn, *macs;
+	uint8_t aks[AKA_AK_LEN], k[AKA_K_LEN], opc[AKA_OPC_LEN], amfs[AKA_AMF_LEN],
+			xmacs[AKA_MAC_LEN];
+
+	if (!eap_aka_3gpp_get_k_opc(id, k, opc))
+	{
+		DBG1(DBG_IKE, "no EAP key found for %Y to authenticate with AKA", id);
+		return FALSE;
+	}
+	DBG4(DBG_IKE, "EAP key found for id %Y, using K %b and OPc %b", id, k,
+		 AKA_K_LEN, opc, AKA_OPC_LEN);
+
+	/* get SQNms out of the AUTS the card created as:
+	 * AUTS = (SQNms xor AKS) || MAC-S */
+	sqn = auts;
+	macs = auts + AKA_SQN_LEN;
+	if (!this->f->f5star(this->f, k, opc, rand, aks))
+	{
+		return FALSE;
+	}
+	memxor(sqn, aks, AKA_AK_LEN);
+
+	/* generate resync XMAC-S... */
+	memset(amfs, 0, AKA_AMF_LEN);
+	if (!this->f->f1star(this->f, k, opc, rand, sqn, amfs, xmacs))
+	{
+		return FALSE;
+	}
+	/* ...and compare it with the card's MAC-S */
+	if (!memeq_const(xmacs, macs, AKA_MAC_LEN))
+	{
+		DBG1(DBG_IKE, "received MACS does not match XMACS");
+		DBG3(DBG_IKE, "MACS %b XMACS %b",
+			 macs, AKA_MAC_LEN, xmacs, AKA_MAC_LEN);
+		return FALSE;
+	}
+	/* update stored SQN to received SQN + 1 */
+	memcpy(this->sqn, sqn, AKA_SQN_LEN);
+	chunk_increment(chunk_create(this->sqn, AKA_SQN_LEN));
+	return TRUE;
+}
+
+METHOD(eap_aka_3gpp_provider_t, destroy, void,
+	private_eap_aka_3gpp_provider_t *this)
+{
+	free(this);
+}
+
+/**
+ * See header
+ */
+eap_aka_3gpp_provider_t *eap_aka_3gpp_provider_create(
+												eap_aka_3gpp_functions_t *f)
+{
+	private_eap_aka_3gpp_provider_t *this;
+
+	INIT(this,
+		.public = {
+			.provider = {
+				.get_triplet = (void*)return_false,
+				.get_quintuplet = _get_quintuplet,
+				.resync = _resync,
+				.is_pseudonym = (void*)return_null,
+				.gen_pseudonym = (void*)return_null,
+				.is_reauth = (void*)return_null,
+				.gen_reauth = (void*)return_null,
+			},
+			.destroy = _destroy,
+		},
+		.f = f,
+	);
+	/* use an offset to accept clock skew between client/server without resync */
+	eap_aka_3gpp_get_sqn(this->sqn, SQN_TIME_OFFSET);
+
+	return &this->public;
+}
diff --git a/src/libcharon/plugins/eap_aka_3gpp/eap_aka_3gpp_provider.h b/src/libcharon/plugins/eap_aka_3gpp/eap_aka_3gpp_provider.h
new file mode 100644
index 0000000..6af8b4b
--- /dev/null
+++ b/src/libcharon/plugins/eap_aka_3gpp/eap_aka_3gpp_provider.h
@@ -0,0 +1,74 @@
+/*
+ * Copyright (C) 2008-2009 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.
+ */
+/*
+ * Copyright (C) 2015 Thomas Strangert
+ * Polystar System AB, Sweden
+ *
+ * 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 eap_aka_3gpp_provider eap_aka_3gpp_provider
+ * @{ @ingroup eap_aka_3gpp
+ */
+
+#ifndef EAP_AKA_3GPP_PROVIDER_H_
+#define EAP_AKA_3GPP_PROVIDER_H_
+
+#include "eap_aka_3gpp_functions.h"
+
+#include <simaka_provider.h>
+
+typedef struct eap_aka_3gpp_provider_t eap_aka_3gpp_provider_t;
+
+/**
+ * SIM provider implementation using a set of AKA functions.
+ */
+struct eap_aka_3gpp_provider_t {
+
+	/**
+	 * Implements simaka_provider_t interface.
+	 */
+	simaka_provider_t provider;
+
+	/**
+	 * Destroy a eap_aka_3gpp_provider_t.
+	 */
+	void (*destroy)(eap_aka_3gpp_provider_t *this);
+};
+
+/**
+ * Create a eap_aka_3gpp_provider instance.
+ */
+eap_aka_3gpp_provider_t *eap_aka_3gpp_provider_create(
+												eap_aka_3gpp_functions_t *f);
+
+#endif /** EAP_AKA_3GPP_PROVIDER_H_ @}*/
diff --git a/src/libcharon/plugins/eap_aka_3gpp2/Makefile.in b/src/libcharon/plugins/eap_aka_3gpp2/Makefile.in
index 4782255..a14afbc 100644
--- a/src/libcharon/plugins/eap_aka_3gpp2/Makefile.in
+++ b/src/libcharon/plugins/eap_aka_3gpp2/Makefile.in
@@ -315,8 +315,6 @@ RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
 RUBYGEMDIR = @RUBYGEMDIR@
-RUBYINCLUDE = @RUBYINCLUDE@
-RUBYLIB = @RUBYLIB@
 SED = @SED@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
@@ -417,6 +415,8 @@ random_device = @random_device@
 resolv_conf = @resolv_conf@
 routing_table = @routing_table@
 routing_table_prio = @routing_table_prio@
+ruby_CFLAGS = @ruby_CFLAGS@
+ruby_LIBS = @ruby_LIBS@
 runstatedir = @runstatedir@
 s_plugins = @s_plugins@
 sbindir = @sbindir@
@@ -445,6 +445,10 @@ top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
 tss2_CFLAGS = @tss2_CFLAGS@
 tss2_LIBS = @tss2_LIBS@
+tss2_socket_CFLAGS = @tss2_socket_CFLAGS@
+tss2_socket_LIBS = @tss2_socket_LIBS@
+tss2_tabrmd_CFLAGS = @tss2_tabrmd_CFLAGS@
+tss2_tabrmd_LIBS = @tss2_tabrmd_LIBS@
 urandom_device = @urandom_device@
 xml_CFLAGS = @xml_CFLAGS@
 xml_LIBS = @xml_LIBS@
diff --git a/src/libcharon/plugins/eap_dynamic/Makefile.in b/src/libcharon/plugins/eap_dynamic/Makefile.in
index 2591dee..e642710 100644
--- a/src/libcharon/plugins/eap_dynamic/Makefile.in
+++ b/src/libcharon/plugins/eap_dynamic/Makefile.in
@@ -313,8 +313,6 @@ RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
 RUBYGEMDIR = @RUBYGEMDIR@
-RUBYINCLUDE = @RUBYINCLUDE@
-RUBYLIB = @RUBYLIB@
 SED = @SED@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
@@ -415,6 +413,8 @@ random_device = @random_device@
 resolv_conf = @resolv_conf@
 routing_table = @routing_table@
 routing_table_prio = @routing_table_prio@
+ruby_CFLAGS = @ruby_CFLAGS@
+ruby_LIBS = @ruby_LIBS@
 runstatedir = @runstatedir@
 s_plugins = @s_plugins@
 sbindir = @sbindir@
@@ -443,6 +443,10 @@ top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
 tss2_CFLAGS = @tss2_CFLAGS@
 tss2_LIBS = @tss2_LIBS@
+tss2_socket_CFLAGS = @tss2_socket_CFLAGS@
+tss2_socket_LIBS = @tss2_socket_LIBS@
+tss2_tabrmd_CFLAGS = @tss2_tabrmd_CFLAGS@
+tss2_tabrmd_LIBS = @tss2_tabrmd_LIBS@
 urandom_device = @urandom_device@
 xml_CFLAGS = @xml_CFLAGS@
 xml_LIBS = @xml_LIBS@
diff --git a/src/libcharon/plugins/eap_gtc/Makefile.in b/src/libcharon/plugins/eap_gtc/Makefile.in
index 08d8ef8..0075513 100644
--- a/src/libcharon/plugins/eap_gtc/Makefile.in
+++ b/src/libcharon/plugins/eap_gtc/Makefile.in
@@ -312,8 +312,6 @@ RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
 RUBYGEMDIR = @RUBYGEMDIR@
-RUBYINCLUDE = @RUBYINCLUDE@
-RUBYLIB = @RUBYLIB@
 SED = @SED@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
@@ -414,6 +412,8 @@ random_device = @random_device@
 resolv_conf = @resolv_conf@
 routing_table = @routing_table@
 routing_table_prio = @routing_table_prio@
+ruby_CFLAGS = @ruby_CFLAGS@
+ruby_LIBS = @ruby_LIBS@
 runstatedir = @runstatedir@
 s_plugins = @s_plugins@
 sbindir = @sbindir@
@@ -442,6 +442,10 @@ top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
 tss2_CFLAGS = @tss2_CFLAGS@
 tss2_LIBS = @tss2_LIBS@
+tss2_socket_CFLAGS = @tss2_socket_CFLAGS@
+tss2_socket_LIBS = @tss2_socket_LIBS@
+tss2_tabrmd_CFLAGS = @tss2_tabrmd_CFLAGS@
+tss2_tabrmd_LIBS = @tss2_tabrmd_LIBS@
 urandom_device = @urandom_device@
 xml_CFLAGS = @xml_CFLAGS@
 xml_LIBS = @xml_LIBS@
diff --git a/src/libcharon/plugins/eap_identity/Makefile.in b/src/libcharon/plugins/eap_identity/Makefile.in
index 4859833..7481fe3 100644
--- a/src/libcharon/plugins/eap_identity/Makefile.in
+++ b/src/libcharon/plugins/eap_identity/Makefile.in
@@ -313,8 +313,6 @@ RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
 RUBYGEMDIR = @RUBYGEMDIR@
-RUBYINCLUDE = @RUBYINCLUDE@
-RUBYLIB = @RUBYLIB@
 SED = @SED@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
@@ -415,6 +413,8 @@ random_device = @random_device@
 resolv_conf = @resolv_conf@
 routing_table = @routing_table@
 routing_table_prio = @routing_table_prio@
+ruby_CFLAGS = @ruby_CFLAGS@
+ruby_LIBS = @ruby_LIBS@
 runstatedir = @runstatedir@
 s_plugins = @s_plugins@
 sbindir = @sbindir@
@@ -443,6 +443,10 @@ top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
 tss2_CFLAGS = @tss2_CFLAGS@
 tss2_LIBS = @tss2_LIBS@
+tss2_socket_CFLAGS = @tss2_socket_CFLAGS@
+tss2_socket_LIBS = @tss2_socket_LIBS@
+tss2_tabrmd_CFLAGS = @tss2_tabrmd_CFLAGS@
+tss2_tabrmd_LIBS = @tss2_tabrmd_LIBS@
 urandom_device = @urandom_device@
 xml_CFLAGS = @xml_CFLAGS@
 xml_LIBS = @xml_LIBS@
diff --git a/src/libcharon/plugins/eap_md5/Makefile.in b/src/libcharon/plugins/eap_md5/Makefile.in
index 796d42f..f26a585 100644
--- a/src/libcharon/plugins/eap_md5/Makefile.in
+++ b/src/libcharon/plugins/eap_md5/Makefile.in
@@ -312,8 +312,6 @@ RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
 RUBYGEMDIR = @RUBYGEMDIR@
-RUBYINCLUDE = @RUBYINCLUDE@
-RUBYLIB = @RUBYLIB@
 SED = @SED@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
@@ -414,6 +412,8 @@ random_device = @random_device@
 resolv_conf = @resolv_conf@
 routing_table = @routing_table@
 routing_table_prio = @routing_table_prio@
+ruby_CFLAGS = @ruby_CFLAGS@
+ruby_LIBS = @ruby_LIBS@
 runstatedir = @runstatedir@
 s_plugins = @s_plugins@
 sbindir = @sbindir@
@@ -442,6 +442,10 @@ top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
 tss2_CFLAGS = @tss2_CFLAGS@
 tss2_LIBS = @tss2_LIBS@
+tss2_socket_CFLAGS = @tss2_socket_CFLAGS@
+tss2_socket_LIBS = @tss2_socket_LIBS@
+tss2_tabrmd_CFLAGS = @tss2_tabrmd_CFLAGS@
+tss2_tabrmd_LIBS = @tss2_tabrmd_LIBS@
 urandom_device = @urandom_device@
 xml_CFLAGS = @xml_CFLAGS@
 xml_LIBS = @xml_LIBS@
diff --git a/src/libcharon/plugins/eap_mschapv2/Makefile.in b/src/libcharon/plugins/eap_mschapv2/Makefile.in
index 00a9f73..abc3081 100644
--- a/src/libcharon/plugins/eap_mschapv2/Makefile.in
+++ b/src/libcharon/plugins/eap_mschapv2/Makefile.in
@@ -313,8 +313,6 @@ RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
 RUBYGEMDIR = @RUBYGEMDIR@
-RUBYINCLUDE = @RUBYINCLUDE@
-RUBYLIB = @RUBYLIB@
 SED = @SED@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
@@ -415,6 +413,8 @@ random_device = @random_device@
 resolv_conf = @resolv_conf@
 routing_table = @routing_table@
 routing_table_prio = @routing_table_prio@
+ruby_CFLAGS = @ruby_CFLAGS@
+ruby_LIBS = @ruby_LIBS@
 runstatedir = @runstatedir@
 s_plugins = @s_plugins@
 sbindir = @sbindir@
@@ -443,6 +443,10 @@ top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
 tss2_CFLAGS = @tss2_CFLAGS@
 tss2_LIBS = @tss2_LIBS@
+tss2_socket_CFLAGS = @tss2_socket_CFLAGS@
+tss2_socket_LIBS = @tss2_socket_LIBS@
+tss2_tabrmd_CFLAGS = @tss2_tabrmd_CFLAGS@
+tss2_tabrmd_LIBS = @tss2_tabrmd_LIBS@
 urandom_device = @urandom_device@
 xml_CFLAGS = @xml_CFLAGS@
 xml_LIBS = @xml_LIBS@
diff --git a/src/libcharon/plugins/eap_peap/Makefile.in b/src/libcharon/plugins/eap_peap/Makefile.in
index df3c2ea..8e8597c 100644
--- a/src/libcharon/plugins/eap_peap/Makefile.in
+++ b/src/libcharon/plugins/eap_peap/Makefile.in
@@ -314,8 +314,6 @@ RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
 RUBYGEMDIR = @RUBYGEMDIR@
-RUBYINCLUDE = @RUBYINCLUDE@
-RUBYLIB = @RUBYLIB@
 SED = @SED@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
@@ -416,6 +414,8 @@ random_device = @random_device@
 resolv_conf = @resolv_conf@
 routing_table = @routing_table@
 routing_table_prio = @routing_table_prio@
+ruby_CFLAGS = @ruby_CFLAGS@
+ruby_LIBS = @ruby_LIBS@
 runstatedir = @runstatedir@
 s_plugins = @s_plugins@
 sbindir = @sbindir@
@@ -444,6 +444,10 @@ top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
 tss2_CFLAGS = @tss2_CFLAGS@
 tss2_LIBS = @tss2_LIBS@
+tss2_socket_CFLAGS = @tss2_socket_CFLAGS@
+tss2_socket_LIBS = @tss2_socket_LIBS@
+tss2_tabrmd_CFLAGS = @tss2_tabrmd_CFLAGS@
+tss2_tabrmd_LIBS = @tss2_tabrmd_LIBS@
 urandom_device = @urandom_device@
 xml_CFLAGS = @xml_CFLAGS@
 xml_LIBS = @xml_LIBS@
diff --git a/src/libcharon/plugins/eap_radius/Makefile.in b/src/libcharon/plugins/eap_radius/Makefile.in
index d8ebeb8..9382433 100644
--- a/src/libcharon/plugins/eap_radius/Makefile.in
+++ b/src/libcharon/plugins/eap_radius/Makefile.in
@@ -315,8 +315,6 @@ RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
 RUBYGEMDIR = @RUBYGEMDIR@
-RUBYINCLUDE = @RUBYINCLUDE@
-RUBYLIB = @RUBYLIB@
 SED = @SED@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
@@ -417,6 +415,8 @@ random_device = @random_device@
 resolv_conf = @resolv_conf@
 routing_table = @routing_table@
 routing_table_prio = @routing_table_prio@
+ruby_CFLAGS = @ruby_CFLAGS@
+ruby_LIBS = @ruby_LIBS@
 runstatedir = @runstatedir@
 s_plugins = @s_plugins@
 sbindir = @sbindir@
@@ -445,6 +445,10 @@ top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
 tss2_CFLAGS = @tss2_CFLAGS@
 tss2_LIBS = @tss2_LIBS@
+tss2_socket_CFLAGS = @tss2_socket_CFLAGS@
+tss2_socket_LIBS = @tss2_socket_LIBS@
+tss2_tabrmd_CFLAGS = @tss2_tabrmd_CFLAGS@
+tss2_tabrmd_LIBS = @tss2_tabrmd_LIBS@
 urandom_device = @urandom_device@
 xml_CFLAGS = @xml_CFLAGS@
 xml_LIBS = @xml_LIBS@
diff --git a/src/libcharon/plugins/eap_radius/eap_radius_accounting.c b/src/libcharon/plugins/eap_radius/eap_radius_accounting.c
index 0c302af..e1f5be0 100644
--- a/src/libcharon/plugins/eap_radius/eap_radius_accounting.c
+++ b/src/libcharon/plugins/eap_radius/eap_radius_accounting.c
@@ -477,7 +477,7 @@ static entry_t* get_or_create_entry(private_eap_radius_accounting_t *this,
 			.interim = {
 				.last = now,
 			},
-			/* default terminate cause, if none other catched */
+			/* default terminate cause, if none other caught */
 			.cause = ACCT_CAUSE_USER_REQUEST,
 		);
 		snprintf(entry->sid, sizeof(entry->sid), "%u-%u", this->prefix, unique);
diff --git a/src/libcharon/plugins/eap_sim/Makefile.in b/src/libcharon/plugins/eap_sim/Makefile.in
index 6c2584a..f7b2d3e 100644
--- a/src/libcharon/plugins/eap_sim/Makefile.in
+++ b/src/libcharon/plugins/eap_sim/Makefile.in
@@ -314,8 +314,6 @@ RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
 RUBYGEMDIR = @RUBYGEMDIR@
-RUBYINCLUDE = @RUBYINCLUDE@
-RUBYLIB = @RUBYLIB@
 SED = @SED@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
@@ -416,6 +414,8 @@ random_device = @random_device@
 resolv_conf = @resolv_conf@
 routing_table = @routing_table@
 routing_table_prio = @routing_table_prio@
+ruby_CFLAGS = @ruby_CFLAGS@
+ruby_LIBS = @ruby_LIBS@
 runstatedir = @runstatedir@
 s_plugins = @s_plugins@
 sbindir = @sbindir@
@@ -444,6 +444,10 @@ top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
 tss2_CFLAGS = @tss2_CFLAGS@
 tss2_LIBS = @tss2_LIBS@
+tss2_socket_CFLAGS = @tss2_socket_CFLAGS@
+tss2_socket_LIBS = @tss2_socket_LIBS@
+tss2_tabrmd_CFLAGS = @tss2_tabrmd_CFLAGS@
+tss2_tabrmd_LIBS = @tss2_tabrmd_LIBS@
 urandom_device = @urandom_device@
 xml_CFLAGS = @xml_CFLAGS@
 xml_LIBS = @xml_LIBS@
diff --git a/src/libcharon/plugins/eap_sim_file/Makefile.in b/src/libcharon/plugins/eap_sim_file/Makefile.in
index b247372..a781550 100644
--- a/src/libcharon/plugins/eap_sim_file/Makefile.in
+++ b/src/libcharon/plugins/eap_sim_file/Makefile.in
@@ -315,8 +315,6 @@ RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
 RUBYGEMDIR = @RUBYGEMDIR@
-RUBYINCLUDE = @RUBYINCLUDE@
-RUBYLIB = @RUBYLIB@
 SED = @SED@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
@@ -417,6 +415,8 @@ random_device = @random_device@
 resolv_conf = @resolv_conf@
 routing_table = @routing_table@
 routing_table_prio = @routing_table_prio@
+ruby_CFLAGS = @ruby_CFLAGS@
+ruby_LIBS = @ruby_LIBS@
 runstatedir = @runstatedir@
 s_plugins = @s_plugins@
 sbindir = @sbindir@
@@ -445,6 +445,10 @@ top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
 tss2_CFLAGS = @tss2_CFLAGS@
 tss2_LIBS = @tss2_LIBS@
+tss2_socket_CFLAGS = @tss2_socket_CFLAGS@
+tss2_socket_LIBS = @tss2_socket_LIBS@
+tss2_tabrmd_CFLAGS = @tss2_tabrmd_CFLAGS@
+tss2_tabrmd_LIBS = @tss2_tabrmd_LIBS@
 urandom_device = @urandom_device@
 xml_CFLAGS = @xml_CFLAGS@
 xml_LIBS = @xml_LIBS@
diff --git a/src/libcharon/plugins/eap_sim_pcsc/Makefile.in b/src/libcharon/plugins/eap_sim_pcsc/Makefile.in
index 88c31a9..28e7b46 100644
--- a/src/libcharon/plugins/eap_sim_pcsc/Makefile.in
+++ b/src/libcharon/plugins/eap_sim_pcsc/Makefile.in
@@ -316,8 +316,6 @@ RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
 RUBYGEMDIR = @RUBYGEMDIR@
-RUBYINCLUDE = @RUBYINCLUDE@
-RUBYLIB = @RUBYLIB@
 SED = @SED@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
@@ -418,6 +416,8 @@ random_device = @random_device@
 resolv_conf = @resolv_conf@
 routing_table = @routing_table@
 routing_table_prio = @routing_table_prio@
+ruby_CFLAGS = @ruby_CFLAGS@
+ruby_LIBS = @ruby_LIBS@
 runstatedir = @runstatedir@
 s_plugins = @s_plugins@
 sbindir = @sbindir@
@@ -446,6 +446,10 @@ top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
 tss2_CFLAGS = @tss2_CFLAGS@
 tss2_LIBS = @tss2_LIBS@
+tss2_socket_CFLAGS = @tss2_socket_CFLAGS@
+tss2_socket_LIBS = @tss2_socket_LIBS@
+tss2_tabrmd_CFLAGS = @tss2_tabrmd_CFLAGS@
+tss2_tabrmd_LIBS = @tss2_tabrmd_LIBS@
 urandom_device = @urandom_device@
 xml_CFLAGS = @xml_CFLAGS@
 xml_LIBS = @xml_LIBS@
diff --git a/src/libcharon/plugins/eap_simaka_pseudonym/Makefile.in b/src/libcharon/plugins/eap_simaka_pseudonym/Makefile.in
index 62c8ca1..98d4fe9 100644
--- a/src/libcharon/plugins/eap_simaka_pseudonym/Makefile.in
+++ b/src/libcharon/plugins/eap_simaka_pseudonym/Makefile.in
@@ -316,8 +316,6 @@ RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
 RUBYGEMDIR = @RUBYGEMDIR@
-RUBYINCLUDE = @RUBYINCLUDE@
-RUBYLIB = @RUBYLIB@
 SED = @SED@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
@@ -418,6 +416,8 @@ random_device = @random_device@
 resolv_conf = @resolv_conf@
 routing_table = @routing_table@
 routing_table_prio = @routing_table_prio@
+ruby_CFLAGS = @ruby_CFLAGS@
+ruby_LIBS = @ruby_LIBS@
 runstatedir = @runstatedir@
 s_plugins = @s_plugins@
 sbindir = @sbindir@
@@ -446,6 +446,10 @@ top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
 tss2_CFLAGS = @tss2_CFLAGS@
 tss2_LIBS = @tss2_LIBS@
+tss2_socket_CFLAGS = @tss2_socket_CFLAGS@
+tss2_socket_LIBS = @tss2_socket_LIBS@
+tss2_tabrmd_CFLAGS = @tss2_tabrmd_CFLAGS@
+tss2_tabrmd_LIBS = @tss2_tabrmd_LIBS@
 urandom_device = @urandom_device@
 xml_CFLAGS = @xml_CFLAGS@
 xml_LIBS = @xml_LIBS@
diff --git a/src/libcharon/plugins/eap_simaka_reauth/Makefile.in b/src/libcharon/plugins/eap_simaka_reauth/Makefile.in
index ef20102..539dc65 100644
--- a/src/libcharon/plugins/eap_simaka_reauth/Makefile.in
+++ b/src/libcharon/plugins/eap_simaka_reauth/Makefile.in
@@ -315,8 +315,6 @@ RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
 RUBYGEMDIR = @RUBYGEMDIR@
-RUBYINCLUDE = @RUBYINCLUDE@
-RUBYLIB = @RUBYLIB@
 SED = @SED@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
@@ -417,6 +415,8 @@ random_device = @random_device@
 resolv_conf = @resolv_conf@
 routing_table = @routing_table@
 routing_table_prio = @routing_table_prio@
+ruby_CFLAGS = @ruby_CFLAGS@
+ruby_LIBS = @ruby_LIBS@
 runstatedir = @runstatedir@
 s_plugins = @s_plugins@
 sbindir = @sbindir@
@@ -445,6 +445,10 @@ top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
 tss2_CFLAGS = @tss2_CFLAGS@
 tss2_LIBS = @tss2_LIBS@
+tss2_socket_CFLAGS = @tss2_socket_CFLAGS@
+tss2_socket_LIBS = @tss2_socket_LIBS@
+tss2_tabrmd_CFLAGS = @tss2_tabrmd_CFLAGS@
+tss2_tabrmd_LIBS = @tss2_tabrmd_LIBS@
 urandom_device = @urandom_device@
 xml_CFLAGS = @xml_CFLAGS@
 xml_LIBS = @xml_LIBS@
diff --git a/src/libcharon/plugins/eap_simaka_sql/Makefile.in b/src/libcharon/plugins/eap_simaka_sql/Makefile.in
index c9af52f..284178e 100644
--- a/src/libcharon/plugins/eap_simaka_sql/Makefile.in
+++ b/src/libcharon/plugins/eap_simaka_sql/Makefile.in
@@ -314,8 +314,6 @@ RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
 RUBYGEMDIR = @RUBYGEMDIR@
-RUBYINCLUDE = @RUBYINCLUDE@
-RUBYLIB = @RUBYLIB@
 SED = @SED@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
@@ -416,6 +414,8 @@ random_device = @random_device@
 resolv_conf = @resolv_conf@
 routing_table = @routing_table@
 routing_table_prio = @routing_table_prio@
+ruby_CFLAGS = @ruby_CFLAGS@
+ruby_LIBS = @ruby_LIBS@
 runstatedir = @runstatedir@
 s_plugins = @s_plugins@
 sbindir = @sbindir@
@@ -444,6 +444,10 @@ top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
 tss2_CFLAGS = @tss2_CFLAGS@
 tss2_LIBS = @tss2_LIBS@
+tss2_socket_CFLAGS = @tss2_socket_CFLAGS@
+tss2_socket_LIBS = @tss2_socket_LIBS@
+tss2_tabrmd_CFLAGS = @tss2_tabrmd_CFLAGS@
+tss2_tabrmd_LIBS = @tss2_tabrmd_LIBS@
 urandom_device = @urandom_device@
 xml_CFLAGS = @xml_CFLAGS@
 xml_LIBS = @xml_LIBS@
diff --git a/src/libcharon/plugins/eap_tls/Makefile.in b/src/libcharon/plugins/eap_tls/Makefile.in
index dfe6d8b..9e69e06 100644
--- a/src/libcharon/plugins/eap_tls/Makefile.in
+++ b/src/libcharon/plugins/eap_tls/Makefile.in
@@ -313,8 +313,6 @@ RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
 RUBYGEMDIR = @RUBYGEMDIR@
-RUBYINCLUDE = @RUBYINCLUDE@
-RUBYLIB = @RUBYLIB@
 SED = @SED@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
@@ -415,6 +413,8 @@ random_device = @random_device@
 resolv_conf = @resolv_conf@
 routing_table = @routing_table@
 routing_table_prio = @routing_table_prio@
+ruby_CFLAGS = @ruby_CFLAGS@
+ruby_LIBS = @ruby_LIBS@
 runstatedir = @runstatedir@
 s_plugins = @s_plugins@
 sbindir = @sbindir@
@@ -443,6 +443,10 @@ top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
 tss2_CFLAGS = @tss2_CFLAGS@
 tss2_LIBS = @tss2_LIBS@
+tss2_socket_CFLAGS = @tss2_socket_CFLAGS@
+tss2_socket_LIBS = @tss2_socket_LIBS@
+tss2_tabrmd_CFLAGS = @tss2_tabrmd_CFLAGS@
+tss2_tabrmd_LIBS = @tss2_tabrmd_LIBS@
 urandom_device = @urandom_device@
 xml_CFLAGS = @xml_CFLAGS@
 xml_LIBS = @xml_LIBS@
diff --git a/src/libcharon/plugins/eap_tnc/Makefile.in b/src/libcharon/plugins/eap_tnc/Makefile.in
index 902d79d..6f5d3a4 100644
--- a/src/libcharon/plugins/eap_tnc/Makefile.in
+++ b/src/libcharon/plugins/eap_tnc/Makefile.in
@@ -314,8 +314,6 @@ RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
 RUBYGEMDIR = @RUBYGEMDIR@
-RUBYINCLUDE = @RUBYINCLUDE@
-RUBYLIB = @RUBYLIB@
 SED = @SED@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
@@ -416,6 +414,8 @@ random_device = @random_device@
 resolv_conf = @resolv_conf@
 routing_table = @routing_table@
 routing_table_prio = @routing_table_prio@
+ruby_CFLAGS = @ruby_CFLAGS@
+ruby_LIBS = @ruby_LIBS@
 runstatedir = @runstatedir@
 s_plugins = @s_plugins@
 sbindir = @sbindir@
@@ -444,6 +444,10 @@ top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
 tss2_CFLAGS = @tss2_CFLAGS@
 tss2_LIBS = @tss2_LIBS@
+tss2_socket_CFLAGS = @tss2_socket_CFLAGS@
+tss2_socket_LIBS = @tss2_socket_LIBS@
+tss2_tabrmd_CFLAGS = @tss2_tabrmd_CFLAGS@
+tss2_tabrmd_LIBS = @tss2_tabrmd_LIBS@
 urandom_device = @urandom_device@
 xml_CFLAGS = @xml_CFLAGS@
 xml_LIBS = @xml_LIBS@
diff --git a/src/libcharon/plugins/eap_ttls/Makefile.in b/src/libcharon/plugins/eap_ttls/Makefile.in
index 53fb187..5a9310a 100644
--- a/src/libcharon/plugins/eap_ttls/Makefile.in
+++ b/src/libcharon/plugins/eap_ttls/Makefile.in
@@ -315,8 +315,6 @@ RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
 RUBYGEMDIR = @RUBYGEMDIR@
-RUBYINCLUDE = @RUBYINCLUDE@
-RUBYLIB = @RUBYLIB@
 SED = @SED@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
@@ -417,6 +415,8 @@ random_device = @random_device@
 resolv_conf = @resolv_conf@
 routing_table = @routing_table@
 routing_table_prio = @routing_table_prio@
+ruby_CFLAGS = @ruby_CFLAGS@
+ruby_LIBS = @ruby_LIBS@
 runstatedir = @runstatedir@
 s_plugins = @s_plugins@
 sbindir = @sbindir@
@@ -445,6 +445,10 @@ top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
 tss2_CFLAGS = @tss2_CFLAGS@
 tss2_LIBS = @tss2_LIBS@
+tss2_socket_CFLAGS = @tss2_socket_CFLAGS@
+tss2_socket_LIBS = @tss2_socket_LIBS@
+tss2_tabrmd_CFLAGS = @tss2_tabrmd_CFLAGS@
+tss2_tabrmd_LIBS = @tss2_tabrmd_LIBS@
 urandom_device = @urandom_device@
 xml_CFLAGS = @xml_CFLAGS@
 xml_LIBS = @xml_LIBS@
diff --git a/src/libcharon/plugins/error_notify/Makefile.in b/src/libcharon/plugins/error_notify/Makefile.in
index 1514f40..7322bc0 100644
--- a/src/libcharon/plugins/error_notify/Makefile.in
+++ b/src/libcharon/plugins/error_notify/Makefile.in
@@ -321,8 +321,6 @@ RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
 RUBYGEMDIR = @RUBYGEMDIR@
-RUBYINCLUDE = @RUBYINCLUDE@
-RUBYLIB = @RUBYLIB@
 SED = @SED@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
@@ -423,6 +421,8 @@ random_device = @random_device@
 resolv_conf = @resolv_conf@
 routing_table = @routing_table@
 routing_table_prio = @routing_table_prio@
+ruby_CFLAGS = @ruby_CFLAGS@
+ruby_LIBS = @ruby_LIBS@
 runstatedir = @runstatedir@
 s_plugins = @s_plugins@
 sbindir = @sbindir@
@@ -451,6 +451,10 @@ top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
 tss2_CFLAGS = @tss2_CFLAGS@
 tss2_LIBS = @tss2_LIBS@
+tss2_socket_CFLAGS = @tss2_socket_CFLAGS@
+tss2_socket_LIBS = @tss2_socket_LIBS@
+tss2_tabrmd_CFLAGS = @tss2_tabrmd_CFLAGS@
+tss2_tabrmd_LIBS = @tss2_tabrmd_LIBS@
 urandom_device = @urandom_device@
 xml_CFLAGS = @xml_CFLAGS@
 xml_LIBS = @xml_LIBS@
diff --git a/src/libcharon/plugins/error_notify/error_notify_socket.c b/src/libcharon/plugins/error_notify/error_notify_socket.c
index 959c4c6..6b9622a 100644
--- a/src/libcharon/plugins/error_notify/error_notify_socket.c
+++ b/src/libcharon/plugins/error_notify/error_notify_socket.c
@@ -94,7 +94,6 @@ METHOD(error_notify_socket_t, notify, void,
 					DBG1(DBG_CFG, "sending notify failed: %s", strerror(errno));
 					break;
 			}
-			break;
 		}
 	}
 	enumerator->destroy(enumerator);
@@ -146,7 +145,7 @@ error_notify_socket_t *error_notify_socket_create()
 	this->service = lib->streams->create_service(lib->streams, uri, 10);
 	if (!this->service)
 	{
-		DBG1(DBG_CFG, "creating duplicheck socket failed");
+		DBG1(DBG_CFG, "creating error-notify socket failed");
 		destroy(this);
 		return NULL;
 	}
diff --git a/src/libcharon/plugins/ext_auth/Makefile.in b/src/libcharon/plugins/ext_auth/Makefile.in
index c3a1819..8ab170b 100644
--- a/src/libcharon/plugins/ext_auth/Makefile.in
+++ b/src/libcharon/plugins/ext_auth/Makefile.in
@@ -313,8 +313,6 @@ RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
 RUBYGEMDIR = @RUBYGEMDIR@
-RUBYINCLUDE = @RUBYINCLUDE@
-RUBYLIB = @RUBYLIB@
 SED = @SED@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
@@ -415,6 +413,8 @@ random_device = @random_device@
 resolv_conf = @resolv_conf@
 routing_table = @routing_table@
 routing_table_prio = @routing_table_prio@
+ruby_CFLAGS = @ruby_CFLAGS@
+ruby_LIBS = @ruby_LIBS@
 runstatedir = @runstatedir@
 s_plugins = @s_plugins@
 sbindir = @sbindir@
@@ -443,6 +443,10 @@ top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
 tss2_CFLAGS = @tss2_CFLAGS@
 tss2_LIBS = @tss2_LIBS@
+tss2_socket_CFLAGS = @tss2_socket_CFLAGS@
+tss2_socket_LIBS = @tss2_socket_LIBS@
+tss2_tabrmd_CFLAGS = @tss2_tabrmd_CFLAGS@
+tss2_tabrmd_LIBS = @tss2_tabrmd_LIBS@
 urandom_device = @urandom_device@
 xml_CFLAGS = @xml_CFLAGS@
 xml_LIBS = @xml_LIBS@
diff --git a/src/libcharon/plugins/farp/Makefile.in b/src/libcharon/plugins/farp/Makefile.in
index 3de99da..4328db1 100644
--- a/src/libcharon/plugins/farp/Makefile.in
+++ b/src/libcharon/plugins/farp/Makefile.in
@@ -311,8 +311,6 @@ RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
 RUBYGEMDIR = @RUBYGEMDIR@
-RUBYINCLUDE = @RUBYINCLUDE@
-RUBYLIB = @RUBYLIB@
 SED = @SED@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
@@ -413,6 +411,8 @@ random_device = @random_device@
 resolv_conf = @resolv_conf@
 routing_table = @routing_table@
 routing_table_prio = @routing_table_prio@
+ruby_CFLAGS = @ruby_CFLAGS@
+ruby_LIBS = @ruby_LIBS@
 runstatedir = @runstatedir@
 s_plugins = @s_plugins@
 sbindir = @sbindir@
@@ -441,6 +441,10 @@ top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
 tss2_CFLAGS = @tss2_CFLAGS@
 tss2_LIBS = @tss2_LIBS@
+tss2_socket_CFLAGS = @tss2_socket_CFLAGS@
+tss2_socket_LIBS = @tss2_socket_LIBS@
+tss2_tabrmd_CFLAGS = @tss2_tabrmd_CFLAGS@
+tss2_tabrmd_LIBS = @tss2_tabrmd_LIBS@
 urandom_device = @urandom_device@
 xml_CFLAGS = @xml_CFLAGS@
 xml_LIBS = @xml_LIBS@
diff --git a/src/libcharon/plugins/farp/farp_listener.c b/src/libcharon/plugins/farp/farp_listener.c
index e19fc59..28ced54 100644
--- a/src/libcharon/plugins/farp/farp_listener.c
+++ b/src/libcharon/plugins/farp/farp_listener.c
@@ -101,6 +101,7 @@ METHOD(listener_t, child_updown, bool,
 				entry->remote->destroy_offset(entry->remote,
 										offsetof(traffic_selector_t, destroy));
 				free(entry);
+				break;
 			}
 		}
 		enumerator->destroy(enumerator);
diff --git a/src/libcharon/plugins/forecast/Makefile.in b/src/libcharon/plugins/forecast/Makefile.in
index 5263ccd..15589b3 100644
--- a/src/libcharon/plugins/forecast/Makefile.in
+++ b/src/libcharon/plugins/forecast/Makefile.in
@@ -314,8 +314,6 @@ RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
 RUBYGEMDIR = @RUBYGEMDIR@
-RUBYINCLUDE = @RUBYINCLUDE@
-RUBYLIB = @RUBYLIB@
 SED = @SED@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
@@ -416,6 +414,8 @@ random_device = @random_device@
 resolv_conf = @resolv_conf@
 routing_table = @routing_table@
 routing_table_prio = @routing_table_prio@
+ruby_CFLAGS = @ruby_CFLAGS@
+ruby_LIBS = @ruby_LIBS@
 runstatedir = @runstatedir@
 s_plugins = @s_plugins@
 sbindir = @sbindir@
@@ -444,6 +444,10 @@ top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
 tss2_CFLAGS = @tss2_CFLAGS@
 tss2_LIBS = @tss2_LIBS@
+tss2_socket_CFLAGS = @tss2_socket_CFLAGS@
+tss2_socket_LIBS = @tss2_socket_LIBS@
+tss2_tabrmd_CFLAGS = @tss2_tabrmd_CFLAGS@
+tss2_tabrmd_LIBS = @tss2_tabrmd_LIBS@
 urandom_device = @urandom_device@
 xml_CFLAGS = @xml_CFLAGS@
 xml_LIBS = @xml_LIBS@
diff --git a/src/libcharon/plugins/ha/Makefile.in b/src/libcharon/plugins/ha/Makefile.in
index d82bdd2..cdf33f6 100644
--- a/src/libcharon/plugins/ha/Makefile.in
+++ b/src/libcharon/plugins/ha/Makefile.in
@@ -313,8 +313,6 @@ RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
 RUBYGEMDIR = @RUBYGEMDIR@
-RUBYINCLUDE = @RUBYINCLUDE@
-RUBYLIB = @RUBYLIB@
 SED = @SED@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
@@ -415,6 +413,8 @@ random_device = @random_device@
 resolv_conf = @resolv_conf@
 routing_table = @routing_table@
 routing_table_prio = @routing_table_prio@
+ruby_CFLAGS = @ruby_CFLAGS@
+ruby_LIBS = @ruby_LIBS@
 runstatedir = @runstatedir@
 s_plugins = @s_plugins@
 sbindir = @sbindir@
@@ -443,6 +443,10 @@ top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
 tss2_CFLAGS = @tss2_CFLAGS@
 tss2_LIBS = @tss2_LIBS@
+tss2_socket_CFLAGS = @tss2_socket_CFLAGS@
+tss2_socket_LIBS = @tss2_socket_LIBS@
+tss2_tabrmd_CFLAGS = @tss2_tabrmd_CFLAGS@
+tss2_tabrmd_LIBS = @tss2_tabrmd_LIBS@
 urandom_device = @urandom_device@
 xml_CFLAGS = @xml_CFLAGS@
 xml_LIBS = @xml_LIBS@
diff --git a/src/libcharon/plugins/ipseckey/Makefile.in b/src/libcharon/plugins/ipseckey/Makefile.in
index 02243e4..adb4076 100644
--- a/src/libcharon/plugins/ipseckey/Makefile.in
+++ b/src/libcharon/plugins/ipseckey/Makefile.in
@@ -313,8 +313,6 @@ RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
 RUBYGEMDIR = @RUBYGEMDIR@
-RUBYINCLUDE = @RUBYINCLUDE@
-RUBYLIB = @RUBYLIB@
 SED = @SED@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
@@ -415,6 +413,8 @@ random_device = @random_device@
 resolv_conf = @resolv_conf@
 routing_table = @routing_table@
 routing_table_prio = @routing_table_prio@
+ruby_CFLAGS = @ruby_CFLAGS@
+ruby_LIBS = @ruby_LIBS@
 runstatedir = @runstatedir@
 s_plugins = @s_plugins@
 sbindir = @sbindir@
@@ -443,6 +443,10 @@ top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
 tss2_CFLAGS = @tss2_CFLAGS@
 tss2_LIBS = @tss2_LIBS@
+tss2_socket_CFLAGS = @tss2_socket_CFLAGS@
+tss2_socket_LIBS = @tss2_socket_LIBS@
+tss2_tabrmd_CFLAGS = @tss2_tabrmd_CFLAGS@
+tss2_tabrmd_LIBS = @tss2_tabrmd_LIBS@
 urandom_device = @urandom_device@
 xml_CFLAGS = @xml_CFLAGS@
 xml_LIBS = @xml_LIBS@
diff --git a/src/libcharon/plugins/kernel_iph/Makefile.in b/src/libcharon/plugins/kernel_iph/Makefile.in
index d9c172c..6164f5c 100644
--- a/src/libcharon/plugins/kernel_iph/Makefile.in
+++ b/src/libcharon/plugins/kernel_iph/Makefile.in
@@ -313,8 +313,6 @@ RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
 RUBYGEMDIR = @RUBYGEMDIR@
-RUBYINCLUDE = @RUBYINCLUDE@
-RUBYLIB = @RUBYLIB@
 SED = @SED@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
@@ -415,6 +413,8 @@ random_device = @random_device@
 resolv_conf = @resolv_conf@
 routing_table = @routing_table@
 routing_table_prio = @routing_table_prio@
+ruby_CFLAGS = @ruby_CFLAGS@
+ruby_LIBS = @ruby_LIBS@
 runstatedir = @runstatedir@
 s_plugins = @s_plugins@
 sbindir = @sbindir@
@@ -443,6 +443,10 @@ top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
 tss2_CFLAGS = @tss2_CFLAGS@
 tss2_LIBS = @tss2_LIBS@
+tss2_socket_CFLAGS = @tss2_socket_CFLAGS@
+tss2_socket_LIBS = @tss2_socket_LIBS@
+tss2_tabrmd_CFLAGS = @tss2_tabrmd_CFLAGS@
+tss2_tabrmd_LIBS = @tss2_tabrmd_LIBS@
 urandom_device = @urandom_device@
 xml_CFLAGS = @xml_CFLAGS@
 xml_LIBS = @xml_LIBS@
diff --git a/src/libcharon/plugins/kernel_libipsec/Makefile.in b/src/libcharon/plugins/kernel_libipsec/Makefile.in
index 9f1a490..e604be7 100644
--- a/src/libcharon/plugins/kernel_libipsec/Makefile.in
+++ b/src/libcharon/plugins/kernel_libipsec/Makefile.in
@@ -315,8 +315,6 @@ RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
 RUBYGEMDIR = @RUBYGEMDIR@
-RUBYINCLUDE = @RUBYINCLUDE@
-RUBYLIB = @RUBYLIB@
 SED = @SED@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
@@ -417,6 +415,8 @@ random_device = @random_device@
 resolv_conf = @resolv_conf@
 routing_table = @routing_table@
 routing_table_prio = @routing_table_prio@
+ruby_CFLAGS = @ruby_CFLAGS@
+ruby_LIBS = @ruby_LIBS@
 runstatedir = @runstatedir@
 s_plugins = @s_plugins@
 sbindir = @sbindir@
@@ -445,6 +445,10 @@ top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
 tss2_CFLAGS = @tss2_CFLAGS@
 tss2_LIBS = @tss2_LIBS@
+tss2_socket_CFLAGS = @tss2_socket_CFLAGS@
+tss2_socket_LIBS = @tss2_socket_LIBS@
+tss2_tabrmd_CFLAGS = @tss2_tabrmd_CFLAGS@
+tss2_tabrmd_LIBS = @tss2_tabrmd_LIBS@
 urandom_device = @urandom_device@
 xml_CFLAGS = @xml_CFLAGS@
 xml_LIBS = @xml_LIBS@
diff --git a/src/libcharon/plugins/kernel_netlink/Makefile.in b/src/libcharon/plugins/kernel_netlink/Makefile.in
index 7f25c52..8d65310 100644
--- a/src/libcharon/plugins/kernel_netlink/Makefile.in
+++ b/src/libcharon/plugins/kernel_netlink/Makefile.in
@@ -352,8 +352,6 @@ RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
 RUBYGEMDIR = @RUBYGEMDIR@
-RUBYINCLUDE = @RUBYINCLUDE@
-RUBYLIB = @RUBYLIB@
 SED = @SED@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
@@ -454,6 +452,8 @@ random_device = @random_device@
 resolv_conf = @resolv_conf@
 routing_table = @routing_table@
 routing_table_prio = @routing_table_prio@
+ruby_CFLAGS = @ruby_CFLAGS@
+ruby_LIBS = @ruby_LIBS@
 runstatedir = @runstatedir@
 s_plugins = @s_plugins@
 sbindir = @sbindir@
@@ -482,6 +482,10 @@ top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
 tss2_CFLAGS = @tss2_CFLAGS@
 tss2_LIBS = @tss2_LIBS@
+tss2_socket_CFLAGS = @tss2_socket_CFLAGS@
+tss2_socket_LIBS = @tss2_socket_LIBS@
+tss2_tabrmd_CFLAGS = @tss2_tabrmd_CFLAGS@
+tss2_tabrmd_LIBS = @tss2_tabrmd_LIBS@
 urandom_device = @urandom_device@
 xml_CFLAGS = @xml_CFLAGS@
 xml_LIBS = @xml_LIBS@
diff --git a/src/libcharon/plugins/kernel_netlink/kernel_netlink_ipsec.c b/src/libcharon/plugins/kernel_netlink/kernel_netlink_ipsec.c
index c411b82..8ddaa71 100644
--- a/src/libcharon/plugins/kernel_netlink/kernel_netlink_ipsec.c
+++ b/src/libcharon/plugins/kernel_netlink/kernel_netlink_ipsec.c
@@ -1141,7 +1141,7 @@ static bool receive_events(private_kernel_netlink_ipsec_t *this, int fd,
 METHOD(kernel_ipsec_t, get_features, kernel_feature_t,
 	private_kernel_netlink_ipsec_t *this)
 {
-	return KERNEL_ESP_V3_TFC;
+	return KERNEL_ESP_V3_TFC | KERNEL_POLICY_SPI;
 }
 
 /**
@@ -2409,11 +2409,13 @@ static status_t add_policy_internal(private_kernel_netlink_ipsec_t *this,
 		struct xfrm_user_tmpl *tmpl;
 		struct {
 			uint8_t proto;
+			uint32_t spi;
 			bool use;
 		} protos[] = {
-			{ IPPROTO_COMP, ipsec->cfg.ipcomp.transform != IPCOMP_NONE },
-			{ IPPROTO_ESP, ipsec->cfg.esp.use },
-			{ IPPROTO_AH, ipsec->cfg.ah.use },
+			{ IPPROTO_COMP, htonl(ntohs(ipsec->cfg.ipcomp.cpi)),
+			  ipsec->cfg.ipcomp.transform != IPCOMP_NONE },
+			{ IPPROTO_ESP, ipsec->cfg.esp.spi, ipsec->cfg.esp.use },
+			{ IPPROTO_AH, ipsec->cfg.ah.spi, ipsec->cfg.ah.use },
 		};
 		ipsec_mode_t proto_mode = ipsec->cfg.mode;
 		int count = 0;
@@ -2441,6 +2443,10 @@ static status_t add_policy_internal(private_kernel_netlink_ipsec_t *this,
 			}
 			tmpl->reqid = ipsec->cfg.reqid;
 			tmpl->id.proto = protos[i].proto;
+			if (policy->direction == POLICY_OUT)
+			{
+				tmpl->id.spi = protos[i].spi;
+			}
 			tmpl->aalgos = tmpl->ealgos = tmpl->calgos = ~0;
 			tmpl->mode = mode2kernel(proto_mode);
 			tmpl->optional = protos[i].proto == IPPROTO_COMP &&
diff --git a/src/libcharon/plugins/kernel_netlink/kernel_netlink_shared.c b/src/libcharon/plugins/kernel_netlink/kernel_netlink_shared.c
index cf85cb0..f3b5b1d 100644
--- a/src/libcharon/plugins/kernel_netlink/kernel_netlink_shared.c
+++ b/src/libcharon/plugins/kernel_netlink/kernel_netlink_shared.c
@@ -265,9 +265,10 @@ static bool read_and_queue(private_netlink_socket_t *this, bool block)
 {
 	struct nlmsghdr *hdr;
 	char buf[this->buflen];
-	ssize_t len;
+	ssize_t len, read_len;
+	bool wipe = FALSE;
 
-	len = read_msg(this, buf, sizeof(buf), block);
+	len = read_len = read_msg(this, buf, sizeof(buf), block);
 	if (len == -1)
 	{
 		return TRUE;
@@ -277,6 +278,11 @@ static bool read_and_queue(private_netlink_socket_t *this, bool block)
 		hdr = (struct nlmsghdr*)buf;
 		while (NLMSG_OK(hdr, len))
 		{
+			if (this->protocol == NETLINK_XFRM &&
+				hdr->nlmsg_type == XFRM_MSG_NEWSA)
+			{	/* wipe potential IPsec SA keys */
+				wipe = TRUE;
+			}
 			if (!queue(this, hdr))
 			{
 				break;
@@ -284,6 +290,10 @@ static bool read_and_queue(private_netlink_socket_t *this, bool block)
 			hdr = NLMSG_NEXT(hdr, len);
 		}
 	}
+	if (wipe)
+	{
+		memwipe(buf, read_len);
+	}
 	return FALSE;
 }
 
diff --git a/src/libcharon/plugins/kernel_pfkey/Makefile.in b/src/libcharon/plugins/kernel_pfkey/Makefile.in
index b27408a..0ef8800 100644
--- a/src/libcharon/plugins/kernel_pfkey/Makefile.in
+++ b/src/libcharon/plugins/kernel_pfkey/Makefile.in
@@ -313,8 +313,6 @@ RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
 RUBYGEMDIR = @RUBYGEMDIR@
-RUBYINCLUDE = @RUBYINCLUDE@
-RUBYLIB = @RUBYLIB@
 SED = @SED@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
@@ -415,6 +413,8 @@ random_device = @random_device@
 resolv_conf = @resolv_conf@
 routing_table = @routing_table@
 routing_table_prio = @routing_table_prio@
+ruby_CFLAGS = @ruby_CFLAGS@
+ruby_LIBS = @ruby_LIBS@
 runstatedir = @runstatedir@
 s_plugins = @s_plugins@
 sbindir = @sbindir@
@@ -443,6 +443,10 @@ top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
 tss2_CFLAGS = @tss2_CFLAGS@
 tss2_LIBS = @tss2_LIBS@
+tss2_socket_CFLAGS = @tss2_socket_CFLAGS@
+tss2_socket_LIBS = @tss2_socket_LIBS@
+tss2_tabrmd_CFLAGS = @tss2_tabrmd_CFLAGS@
+tss2_tabrmd_LIBS = @tss2_tabrmd_LIBS@
 urandom_device = @urandom_device@
 xml_CFLAGS = @xml_CFLAGS@
 xml_LIBS = @xml_LIBS@
diff --git a/src/libcharon/plugins/kernel_pfroute/Makefile.in b/src/libcharon/plugins/kernel_pfroute/Makefile.in
index e7005bb..1f23250 100644
--- a/src/libcharon/plugins/kernel_pfroute/Makefile.in
+++ b/src/libcharon/plugins/kernel_pfroute/Makefile.in
@@ -313,8 +313,6 @@ RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
 RUBYGEMDIR = @RUBYGEMDIR@
-RUBYINCLUDE = @RUBYINCLUDE@
-RUBYLIB = @RUBYLIB@
 SED = @SED@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
@@ -415,6 +413,8 @@ random_device = @random_device@
 resolv_conf = @resolv_conf@
 routing_table = @routing_table@
 routing_table_prio = @routing_table_prio@
+ruby_CFLAGS = @ruby_CFLAGS@
+ruby_LIBS = @ruby_LIBS@
 runstatedir = @runstatedir@
 s_plugins = @s_plugins@
 sbindir = @sbindir@
@@ -443,6 +443,10 @@ top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
 tss2_CFLAGS = @tss2_CFLAGS@
 tss2_LIBS = @tss2_LIBS@
+tss2_socket_CFLAGS = @tss2_socket_CFLAGS@
+tss2_socket_LIBS = @tss2_socket_LIBS@
+tss2_tabrmd_CFLAGS = @tss2_tabrmd_CFLAGS@
+tss2_tabrmd_LIBS = @tss2_tabrmd_LIBS@
 urandom_device = @urandom_device@
 xml_CFLAGS = @xml_CFLAGS@
 xml_LIBS = @xml_LIBS@
diff --git a/src/libcharon/plugins/kernel_pfroute/kernel_pfroute_net.c b/src/libcharon/plugins/kernel_pfroute/kernel_pfroute_net.c
index 6d06ee1..da7ae47 100644
--- a/src/libcharon/plugins/kernel_pfroute/kernel_pfroute_net.c
+++ b/src/libcharon/plugins/kernel_pfroute/kernel_pfroute_net.c
@@ -1831,7 +1831,7 @@ METHOD(enumerator_t, enumerate_subnets, bool,
 	for (; this->current < this->buf + this->len;
 		 this->current += rtm->rtm_msglen)
 	{
-		struct sockaddr *netmask;
+		struct sockaddr *netmask = NULL;
 		uint8_t netbits = 0;
 
 		rtm = (struct rt_msghdr*)this->current;
@@ -1864,7 +1864,7 @@ METHOD(enumerator_t, enumerate_subnets, bool,
 				this->ifname = strndup(sdl->sdl_data, sdl->sdl_nlen);
 			}
 		}
-		if (this->net)
+		if (this->net && netmask)
 		{
 			netbits = sockaddr_to_netmask(netmask, this->net);
 		}
diff --git a/src/libcharon/plugins/kernel_wfp/Makefile.in b/src/libcharon/plugins/kernel_wfp/Makefile.in
index ffdae84..263ec5d 100644
--- a/src/libcharon/plugins/kernel_wfp/Makefile.in
+++ b/src/libcharon/plugins/kernel_wfp/Makefile.in
@@ -321,8 +321,6 @@ RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
 RUBYGEMDIR = @RUBYGEMDIR@
-RUBYINCLUDE = @RUBYINCLUDE@
-RUBYLIB = @RUBYLIB@
 SED = @SED@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
@@ -423,6 +421,8 @@ random_device = @random_device@
 resolv_conf = @resolv_conf@
 routing_table = @routing_table@
 routing_table_prio = @routing_table_prio@
+ruby_CFLAGS = @ruby_CFLAGS@
+ruby_LIBS = @ruby_LIBS@
 runstatedir = @runstatedir@
 s_plugins = @s_plugins@
 sbindir = @sbindir@
@@ -451,6 +451,10 @@ top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
 tss2_CFLAGS = @tss2_CFLAGS@
 tss2_LIBS = @tss2_LIBS@
+tss2_socket_CFLAGS = @tss2_socket_CFLAGS@
+tss2_socket_LIBS = @tss2_socket_LIBS@
+tss2_tabrmd_CFLAGS = @tss2_tabrmd_CFLAGS@
+tss2_tabrmd_LIBS = @tss2_tabrmd_LIBS@
 urandom_device = @urandom_device@
 xml_CFLAGS = @xml_CFLAGS@
 xml_LIBS = @xml_LIBS@
diff --git a/src/libcharon/plugins/led/Makefile.in b/src/libcharon/plugins/led/Makefile.in
index 7f82029..54a7ccf 100644
--- a/src/libcharon/plugins/led/Makefile.in
+++ b/src/libcharon/plugins/led/Makefile.in
@@ -310,8 +310,6 @@ RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
 RUBYGEMDIR = @RUBYGEMDIR@
-RUBYINCLUDE = @RUBYINCLUDE@
-RUBYLIB = @RUBYLIB@
 SED = @SED@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
@@ -412,6 +410,8 @@ random_device = @random_device@
 resolv_conf = @resolv_conf@
 routing_table = @routing_table@
 routing_table_prio = @routing_table_prio@
+ruby_CFLAGS = @ruby_CFLAGS@
+ruby_LIBS = @ruby_LIBS@
 runstatedir = @runstatedir@
 s_plugins = @s_plugins@
 sbindir = @sbindir@
@@ -440,6 +440,10 @@ top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
 tss2_CFLAGS = @tss2_CFLAGS@
 tss2_LIBS = @tss2_LIBS@
+tss2_socket_CFLAGS = @tss2_socket_CFLAGS@
+tss2_socket_LIBS = @tss2_socket_LIBS@
+tss2_tabrmd_CFLAGS = @tss2_tabrmd_CFLAGS@
+tss2_tabrmd_LIBS = @tss2_tabrmd_LIBS@
 urandom_device = @urandom_device@
 xml_CFLAGS = @xml_CFLAGS@
 xml_LIBS = @xml_LIBS@
diff --git a/src/libcharon/plugins/load_tester/Makefile.in b/src/libcharon/plugins/load_tester/Makefile.in
index c55e357..b25f3a6 100644
--- a/src/libcharon/plugins/load_tester/Makefile.in
+++ b/src/libcharon/plugins/load_tester/Makefile.in
@@ -323,8 +323,6 @@ RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
 RUBYGEMDIR = @RUBYGEMDIR@
-RUBYINCLUDE = @RUBYINCLUDE@
-RUBYLIB = @RUBYLIB@
 SED = @SED@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
@@ -425,6 +423,8 @@ random_device = @random_device@
 resolv_conf = @resolv_conf@
 routing_table = @routing_table@
 routing_table_prio = @routing_table_prio@
+ruby_CFLAGS = @ruby_CFLAGS@
+ruby_LIBS = @ruby_LIBS@
 runstatedir = @runstatedir@
 s_plugins = @s_plugins@
 sbindir = @sbindir@
@@ -453,6 +453,10 @@ top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
 tss2_CFLAGS = @tss2_CFLAGS@
 tss2_LIBS = @tss2_LIBS@
+tss2_socket_CFLAGS = @tss2_socket_CFLAGS@
+tss2_socket_LIBS = @tss2_socket_LIBS@
+tss2_tabrmd_CFLAGS = @tss2_tabrmd_CFLAGS@
+tss2_tabrmd_LIBS = @tss2_tabrmd_LIBS@
 urandom_device = @urandom_device@
 xml_CFLAGS = @xml_CFLAGS@
 xml_LIBS = @xml_LIBS@
diff --git a/src/libcharon/plugins/lookip/Makefile.in b/src/libcharon/plugins/lookip/Makefile.in
index ba86d37..4db0b7d 100644
--- a/src/libcharon/plugins/lookip/Makefile.in
+++ b/src/libcharon/plugins/lookip/Makefile.in
@@ -319,8 +319,6 @@ RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
 RUBYGEMDIR = @RUBYGEMDIR@
-RUBYINCLUDE = @RUBYINCLUDE@
-RUBYLIB = @RUBYLIB@
 SED = @SED@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
@@ -421,6 +419,8 @@ random_device = @random_device@
 resolv_conf = @resolv_conf@
 routing_table = @routing_table@
 routing_table_prio = @routing_table_prio@
+ruby_CFLAGS = @ruby_CFLAGS@
+ruby_LIBS = @ruby_LIBS@
 runstatedir = @runstatedir@
 s_plugins = @s_plugins@
 sbindir = @sbindir@
@@ -449,6 +449,10 @@ top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
 tss2_CFLAGS = @tss2_CFLAGS@
 tss2_LIBS = @tss2_LIBS@
+tss2_socket_CFLAGS = @tss2_socket_CFLAGS@
+tss2_socket_LIBS = @tss2_socket_LIBS@
+tss2_tabrmd_CFLAGS = @tss2_tabrmd_CFLAGS@
+tss2_tabrmd_LIBS = @tss2_tabrmd_LIBS@
 urandom_device = @urandom_device@
 xml_CFLAGS = @xml_CFLAGS@
 xml_LIBS = @xml_LIBS@
diff --git a/src/libcharon/plugins/medcli/Makefile.in b/src/libcharon/plugins/medcli/Makefile.in
index e2d63be..721edbd 100644
--- a/src/libcharon/plugins/medcli/Makefile.in
+++ b/src/libcharon/plugins/medcli/Makefile.in
@@ -313,8 +313,6 @@ RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
 RUBYGEMDIR = @RUBYGEMDIR@
-RUBYINCLUDE = @RUBYINCLUDE@
-RUBYLIB = @RUBYLIB@
 SED = @SED@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
@@ -415,6 +413,8 @@ random_device = @random_device@
 resolv_conf = @resolv_conf@
 routing_table = @routing_table@
 routing_table_prio = @routing_table_prio@
+ruby_CFLAGS = @ruby_CFLAGS@
+ruby_LIBS = @ruby_LIBS@
 runstatedir = @runstatedir@
 s_plugins = @s_plugins@
 sbindir = @sbindir@
@@ -443,6 +443,10 @@ top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
 tss2_CFLAGS = @tss2_CFLAGS@
 tss2_LIBS = @tss2_LIBS@
+tss2_socket_CFLAGS = @tss2_socket_CFLAGS@
+tss2_socket_LIBS = @tss2_socket_LIBS@
+tss2_tabrmd_CFLAGS = @tss2_tabrmd_CFLAGS@
+tss2_tabrmd_LIBS = @tss2_tabrmd_LIBS@
 urandom_device = @urandom_device@
 xml_CFLAGS = @xml_CFLAGS@
 xml_LIBS = @xml_LIBS@
diff --git a/src/libcharon/plugins/medsrv/Makefile.in b/src/libcharon/plugins/medsrv/Makefile.in
index 10b48da..81d895d 100644
--- a/src/libcharon/plugins/medsrv/Makefile.in
+++ b/src/libcharon/plugins/medsrv/Makefile.in
@@ -313,8 +313,6 @@ RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
 RUBYGEMDIR = @RUBYGEMDIR@
-RUBYINCLUDE = @RUBYINCLUDE@
-RUBYLIB = @RUBYLIB@
 SED = @SED@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
@@ -415,6 +413,8 @@ random_device = @random_device@
 resolv_conf = @resolv_conf@
 routing_table = @routing_table@
 routing_table_prio = @routing_table_prio@
+ruby_CFLAGS = @ruby_CFLAGS@
+ruby_LIBS = @ruby_LIBS@
 runstatedir = @runstatedir@
 s_plugins = @s_plugins@
 sbindir = @sbindir@
@@ -443,6 +443,10 @@ top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
 tss2_CFLAGS = @tss2_CFLAGS@
 tss2_LIBS = @tss2_LIBS@
+tss2_socket_CFLAGS = @tss2_socket_CFLAGS@
+tss2_socket_LIBS = @tss2_socket_LIBS@
+tss2_tabrmd_CFLAGS = @tss2_tabrmd_CFLAGS@
+tss2_tabrmd_LIBS = @tss2_tabrmd_LIBS@
 urandom_device = @urandom_device@
 xml_CFLAGS = @xml_CFLAGS@
 xml_LIBS = @xml_LIBS@
diff --git a/src/libcharon/plugins/osx_attr/Makefile.in b/src/libcharon/plugins/osx_attr/Makefile.in
index 8e0b10e..e9bd938 100644
--- a/src/libcharon/plugins/osx_attr/Makefile.in
+++ b/src/libcharon/plugins/osx_attr/Makefile.in
@@ -313,8 +313,6 @@ RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
 RUBYGEMDIR = @RUBYGEMDIR@
-RUBYINCLUDE = @RUBYINCLUDE@
-RUBYLIB = @RUBYLIB@
 SED = @SED@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
@@ -415,6 +413,8 @@ random_device = @random_device@
 resolv_conf = @resolv_conf@
 routing_table = @routing_table@
 routing_table_prio = @routing_table_prio@
+ruby_CFLAGS = @ruby_CFLAGS@
+ruby_LIBS = @ruby_LIBS@
 runstatedir = @runstatedir@
 s_plugins = @s_plugins@
 sbindir = @sbindir@
@@ -443,6 +443,10 @@ top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
 tss2_CFLAGS = @tss2_CFLAGS@
 tss2_LIBS = @tss2_LIBS@
+tss2_socket_CFLAGS = @tss2_socket_CFLAGS@
+tss2_socket_LIBS = @tss2_socket_LIBS@
+tss2_tabrmd_CFLAGS = @tss2_tabrmd_CFLAGS@
+tss2_tabrmd_LIBS = @tss2_tabrmd_LIBS@
 urandom_device = @urandom_device@
 xml_CFLAGS = @xml_CFLAGS@
 xml_LIBS = @xml_LIBS@
diff --git a/src/libcharon/plugins/p_cscf/Makefile.in b/src/libcharon/plugins/p_cscf/Makefile.in
index 954a43d..7ccbfb1 100644
--- a/src/libcharon/plugins/p_cscf/Makefile.in
+++ b/src/libcharon/plugins/p_cscf/Makefile.in
@@ -313,8 +313,6 @@ RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
 RUBYGEMDIR = @RUBYGEMDIR@
-RUBYINCLUDE = @RUBYINCLUDE@
-RUBYLIB = @RUBYLIB@
 SED = @SED@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
@@ -415,6 +413,8 @@ random_device = @random_device@
 resolv_conf = @resolv_conf@
 routing_table = @routing_table@
 routing_table_prio = @routing_table_prio@
+ruby_CFLAGS = @ruby_CFLAGS@
+ruby_LIBS = @ruby_LIBS@
 runstatedir = @runstatedir@
 s_plugins = @s_plugins@
 sbindir = @sbindir@
@@ -443,6 +443,10 @@ top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
 tss2_CFLAGS = @tss2_CFLAGS@
 tss2_LIBS = @tss2_LIBS@
+tss2_socket_CFLAGS = @tss2_socket_CFLAGS@
+tss2_socket_LIBS = @tss2_socket_LIBS@
+tss2_tabrmd_CFLAGS = @tss2_tabrmd_CFLAGS@
+tss2_tabrmd_LIBS = @tss2_tabrmd_LIBS@
 urandom_device = @urandom_device@
 xml_CFLAGS = @xml_CFLAGS@
 xml_LIBS = @xml_LIBS@
diff --git a/src/libcharon/plugins/radattr/Makefile.in b/src/libcharon/plugins/radattr/Makefile.in
index add1f54..2e4ea25 100644
--- a/src/libcharon/plugins/radattr/Makefile.in
+++ b/src/libcharon/plugins/radattr/Makefile.in
@@ -314,8 +314,6 @@ RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
 RUBYGEMDIR = @RUBYGEMDIR@
-RUBYINCLUDE = @RUBYINCLUDE@
-RUBYLIB = @RUBYLIB@
 SED = @SED@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
@@ -416,6 +414,8 @@ random_device = @random_device@
 resolv_conf = @resolv_conf@
 routing_table = @routing_table@
 routing_table_prio = @routing_table_prio@
+ruby_CFLAGS = @ruby_CFLAGS@
+ruby_LIBS = @ruby_LIBS@
 runstatedir = @runstatedir@
 s_plugins = @s_plugins@
 sbindir = @sbindir@
@@ -444,6 +444,10 @@ top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
 tss2_CFLAGS = @tss2_CFLAGS@
 tss2_LIBS = @tss2_LIBS@
+tss2_socket_CFLAGS = @tss2_socket_CFLAGS@
+tss2_socket_LIBS = @tss2_socket_LIBS@
+tss2_tabrmd_CFLAGS = @tss2_tabrmd_CFLAGS@
+tss2_tabrmd_LIBS = @tss2_tabrmd_LIBS@
 urandom_device = @urandom_device@
 xml_CFLAGS = @xml_CFLAGS@
 xml_LIBS = @xml_LIBS@
diff --git a/src/libcharon/plugins/resolve/Makefile.in b/src/libcharon/plugins/resolve/Makefile.in
index 5e166f2..0db2cb1 100644
--- a/src/libcharon/plugins/resolve/Makefile.in
+++ b/src/libcharon/plugins/resolve/Makefile.in
@@ -313,8 +313,6 @@ RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
 RUBYGEMDIR = @RUBYGEMDIR@
-RUBYINCLUDE = @RUBYINCLUDE@
-RUBYLIB = @RUBYLIB@
 SED = @SED@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
@@ -415,6 +413,8 @@ random_device = @random_device@
 resolv_conf = @resolv_conf@
 routing_table = @routing_table@
 routing_table_prio = @routing_table_prio@
+ruby_CFLAGS = @ruby_CFLAGS@
+ruby_LIBS = @ruby_LIBS@
 runstatedir = @runstatedir@
 s_plugins = @s_plugins@
 sbindir = @sbindir@
@@ -443,6 +443,10 @@ top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
 tss2_CFLAGS = @tss2_CFLAGS@
 tss2_LIBS = @tss2_LIBS@
+tss2_socket_CFLAGS = @tss2_socket_CFLAGS@
+tss2_socket_LIBS = @tss2_socket_LIBS@
+tss2_tabrmd_CFLAGS = @tss2_tabrmd_CFLAGS@
+tss2_tabrmd_LIBS = @tss2_tabrmd_LIBS@
 urandom_device = @urandom_device@
 xml_CFLAGS = @xml_CFLAGS@
 xml_LIBS = @xml_LIBS@
diff --git a/src/libcharon/plugins/smp/Makefile.in b/src/libcharon/plugins/smp/Makefile.in
index 9aac318..5f3517c 100644
--- a/src/libcharon/plugins/smp/Makefile.in
+++ b/src/libcharon/plugins/smp/Makefile.in
@@ -311,8 +311,6 @@ RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
 RUBYGEMDIR = @RUBYGEMDIR@
-RUBYINCLUDE = @RUBYINCLUDE@
-RUBYLIB = @RUBYLIB@
 SED = @SED@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
@@ -413,6 +411,8 @@ random_device = @random_device@
 resolv_conf = @resolv_conf@
 routing_table = @routing_table@
 routing_table_prio = @routing_table_prio@
+ruby_CFLAGS = @ruby_CFLAGS@
+ruby_LIBS = @ruby_LIBS@
 runstatedir = @runstatedir@
 s_plugins = @s_plugins@
 sbindir = @sbindir@
@@ -441,6 +441,10 @@ top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
 tss2_CFLAGS = @tss2_CFLAGS@
 tss2_LIBS = @tss2_LIBS@
+tss2_socket_CFLAGS = @tss2_socket_CFLAGS@
+tss2_socket_LIBS = @tss2_socket_LIBS@
+tss2_tabrmd_CFLAGS = @tss2_tabrmd_CFLAGS@
+tss2_tabrmd_LIBS = @tss2_tabrmd_LIBS@
 urandom_device = @urandom_device@
 xml_CFLAGS = @xml_CFLAGS@
 xml_LIBS = @xml_LIBS@
diff --git a/src/libcharon/plugins/socket_default/Makefile.in b/src/libcharon/plugins/socket_default/Makefile.in
index b87afa4..54e9ed9 100644
--- a/src/libcharon/plugins/socket_default/Makefile.in
+++ b/src/libcharon/plugins/socket_default/Makefile.in
@@ -313,8 +313,6 @@ RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
 RUBYGEMDIR = @RUBYGEMDIR@
-RUBYINCLUDE = @RUBYINCLUDE@
-RUBYLIB = @RUBYLIB@
 SED = @SED@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
@@ -415,6 +413,8 @@ random_device = @random_device@
 resolv_conf = @resolv_conf@
 routing_table = @routing_table@
 routing_table_prio = @routing_table_prio@
+ruby_CFLAGS = @ruby_CFLAGS@
+ruby_LIBS = @ruby_LIBS@
 runstatedir = @runstatedir@
 s_plugins = @s_plugins@
 sbindir = @sbindir@
@@ -443,6 +443,10 @@ top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
 tss2_CFLAGS = @tss2_CFLAGS@
 tss2_LIBS = @tss2_LIBS@
+tss2_socket_CFLAGS = @tss2_socket_CFLAGS@
+tss2_socket_LIBS = @tss2_socket_LIBS@
+tss2_tabrmd_CFLAGS = @tss2_tabrmd_CFLAGS@
+tss2_tabrmd_LIBS = @tss2_tabrmd_LIBS@
 urandom_device = @urandom_device@
 xml_CFLAGS = @xml_CFLAGS@
 xml_LIBS = @xml_LIBS@
diff --git a/src/libcharon/plugins/socket_dynamic/Makefile.in b/src/libcharon/plugins/socket_dynamic/Makefile.in
index 595651f..1971282 100644
--- a/src/libcharon/plugins/socket_dynamic/Makefile.in
+++ b/src/libcharon/plugins/socket_dynamic/Makefile.in
@@ -313,8 +313,6 @@ RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
 RUBYGEMDIR = @RUBYGEMDIR@
-RUBYINCLUDE = @RUBYINCLUDE@
-RUBYLIB = @RUBYLIB@
 SED = @SED@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
@@ -415,6 +413,8 @@ random_device = @random_device@
 resolv_conf = @resolv_conf@
 routing_table = @routing_table@
 routing_table_prio = @routing_table_prio@
+ruby_CFLAGS = @ruby_CFLAGS@
+ruby_LIBS = @ruby_LIBS@
 runstatedir = @runstatedir@
 s_plugins = @s_plugins@
 sbindir = @sbindir@
@@ -443,6 +443,10 @@ top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
 tss2_CFLAGS = @tss2_CFLAGS@
 tss2_LIBS = @tss2_LIBS@
+tss2_socket_CFLAGS = @tss2_socket_CFLAGS@
+tss2_socket_LIBS = @tss2_socket_LIBS@
+tss2_tabrmd_CFLAGS = @tss2_tabrmd_CFLAGS@
+tss2_tabrmd_LIBS = @tss2_tabrmd_LIBS@
 urandom_device = @urandom_device@
 xml_CFLAGS = @xml_CFLAGS@
 xml_LIBS = @xml_LIBS@
diff --git a/src/libcharon/plugins/socket_win/Makefile.in b/src/libcharon/plugins/socket_win/Makefile.in
index 8f1e439..6efd3e1 100644
--- a/src/libcharon/plugins/socket_win/Makefile.in
+++ b/src/libcharon/plugins/socket_win/Makefile.in
@@ -313,8 +313,6 @@ RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
 RUBYGEMDIR = @RUBYGEMDIR@
-RUBYINCLUDE = @RUBYINCLUDE@
-RUBYLIB = @RUBYLIB@
 SED = @SED@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
@@ -415,6 +413,8 @@ random_device = @random_device@
 resolv_conf = @resolv_conf@
 routing_table = @routing_table@
 routing_table_prio = @routing_table_prio@
+ruby_CFLAGS = @ruby_CFLAGS@
+ruby_LIBS = @ruby_LIBS@
 runstatedir = @runstatedir@
 s_plugins = @s_plugins@
 sbindir = @sbindir@
@@ -443,6 +443,10 @@ top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
 tss2_CFLAGS = @tss2_CFLAGS@
 tss2_LIBS = @tss2_LIBS@
+tss2_socket_CFLAGS = @tss2_socket_CFLAGS@
+tss2_socket_LIBS = @tss2_socket_LIBS@
+tss2_tabrmd_CFLAGS = @tss2_tabrmd_CFLAGS@
+tss2_tabrmd_LIBS = @tss2_tabrmd_LIBS@
 urandom_device = @urandom_device@
 xml_CFLAGS = @xml_CFLAGS@
 xml_LIBS = @xml_LIBS@
diff --git a/src/libcharon/plugins/sql/Makefile.in b/src/libcharon/plugins/sql/Makefile.in
index 5c14619..e0b813d 100644
--- a/src/libcharon/plugins/sql/Makefile.in
+++ b/src/libcharon/plugins/sql/Makefile.in
@@ -311,8 +311,6 @@ RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
 RUBYGEMDIR = @RUBYGEMDIR@
-RUBYINCLUDE = @RUBYINCLUDE@
-RUBYLIB = @RUBYLIB@
 SED = @SED@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
@@ -413,6 +411,8 @@ random_device = @random_device@
 resolv_conf = @resolv_conf@
 routing_table = @routing_table@
 routing_table_prio = @routing_table_prio@
+ruby_CFLAGS = @ruby_CFLAGS@
+ruby_LIBS = @ruby_LIBS@
 runstatedir = @runstatedir@
 s_plugins = @s_plugins@
 sbindir = @sbindir@
@@ -441,6 +441,10 @@ top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
 tss2_CFLAGS = @tss2_CFLAGS@
 tss2_LIBS = @tss2_LIBS@
+tss2_socket_CFLAGS = @tss2_socket_CFLAGS@
+tss2_socket_LIBS = @tss2_socket_LIBS@
+tss2_tabrmd_CFLAGS = @tss2_tabrmd_CFLAGS@
+tss2_tabrmd_LIBS = @tss2_tabrmd_LIBS@
 urandom_device = @urandom_device@
 xml_CFLAGS = @xml_CFLAGS@
 xml_LIBS = @xml_LIBS@
diff --git a/src/libcharon/plugins/sql/sql_config.c b/src/libcharon/plugins/sql/sql_config.c
index 00ed693..8672851 100644
--- a/src/libcharon/plugins/sql/sql_config.c
+++ b/src/libcharon/plugins/sql/sql_config.c
@@ -102,10 +102,11 @@ static void add_traffic_selectors(private_sql_config_t *this,
 	bool local;
 
 	e = this->db->query(this->db,
-			"SELECT kind, type, protocol, "
-			"start_addr, end_addr, start_port, end_port "
-			"FROM traffic_selectors JOIN child_config_traffic_selector "
-			"ON id = traffic_selector WHERE child_cfg = ?",
+			"SELECT ct.kind, t.type, t.protocol, "
+			"t.start_addr, t.end_addr, t.start_port, t.end_port "
+			"FROM traffic_selectors AS t "
+			"JOIN child_config_traffic_selector AS ct "
+			"ON t.id = ct.traffic_selector WHERE ct.child_cfg = ?",
 			DB_INT, id,
 			DB_INT, DB_INT, DB_INT,
 			DB_BLOB, DB_BLOB, DB_INT, DB_INT);
@@ -131,9 +132,9 @@ static void add_esp_proposals(private_sql_config_t *this,
 	bool use_default = TRUE;
 
 	e = this->db->query(this->db,
-			"SELECT proposal "
-			"FROM proposals JOIN child_config_proposal ON id = prop "
-			"WHERE child_cfg = ? ORDER BY prio",
+			"SELECT p.proposal "
+			"FROM proposals AS p JOIN child_config_proposal AS cp "
+			"ON p.id = cp.prop WHERE cp.child_cfg = ? ORDER BY cp.prio",
 			DB_INT, id, DB_TEXT);
 	if (e)
 	{
@@ -202,10 +203,11 @@ static void add_child_cfgs(private_sql_config_t *this, peer_cfg_t *peer, int id)
 	child_cfg_t *child_cfg;
 
 	e = this->db->query(this->db,
-			"SELECT id, name, lifetime, rekeytime, jitter, updown, hostaccess, "
-			"mode, start_action, dpd_action, close_action, ipcomp, reqid "
-			"FROM child_configs JOIN peer_config_child_config ON id = child_cfg "
-			"WHERE peer_cfg = ?",
+			"SELECT c.id, c.name, c.lifetime, c.rekeytime, c.jitter, c.updown, "
+			"c.hostaccess, c.mode, c.start_action, c.dpd_action, "
+			"c.close_action, c.ipcomp, c.reqid "
+			"FROM child_configs AS c JOIN peer_config_child_config AS pc "
+			"ON c.id = pc.child_cfg WHERE pc.peer_cfg = ?",
 			DB_INT, id,
 			DB_INT, DB_TEXT, DB_INT, DB_INT, DB_INT, DB_TEXT, DB_INT,
 			DB_INT, DB_INT, DB_INT, DB_INT, DB_INT, DB_INT);
@@ -231,9 +233,10 @@ static void add_ike_proposals(private_sql_config_t *this,
 	bool use_default = TRUE;
 
 	e = this->db->query(this->db,
-			"SELECT proposal "
-			"FROM proposals JOIN ike_config_proposal ON id = prop "
-			"WHERE ike_cfg = ? ORDER BY prio",
+			"SELECT p.proposal "
+			"FROM proposals AS p "
+			"JOIN ike_config_proposal AS ip ON p.id = ip.prop "
+			"WHERE ip.ike_cfg = ? ORDER BY ip.prio",
 			DB_INT, id, DB_TEXT);
 	if (e)
 	{
@@ -288,8 +291,8 @@ static ike_cfg_t* get_ike_cfg_by_id(private_sql_config_t *this, int id)
 	ike_cfg_t *ike_cfg = NULL;
 
 	e = this->db->query(this->db,
-			"SELECT id, certreq, force_encap, local, remote "
-			"FROM ike_configs WHERE id = ?",
+			"SELECT c.id, c.certreq, c.force_encap, c.local, c.remote "
+			"FROM ike_configs AS c WHERE c.id = ?",
 			DB_INT, id,
 			DB_INT, DB_INT, DB_INT, DB_TEXT, DB_TEXT);
 	if (e)
@@ -310,16 +313,16 @@ static peer_cfg_t *get_peer_cfg_by_id(private_sql_config_t *this, int id)
 	peer_cfg_t *peer_cfg = NULL;
 
 	e = this->db->query(this->db,
-			"SELECT c.id, name, ike_cfg, l.type, l.data, r.type, r.data, "
-			"cert_policy, uniqueid, auth_method, eap_type, eap_vendor, "
-			"keyingtries, rekeytime, reauthtime, jitter, overtime, mobike, "
-			"dpd_delay, virtual, pool, "
-			"mediation, mediated_by, COALESCE(p.type, 0), p.data "
+			"SELECT c.id, c.name, c.ike_cfg, l.type, l.data, r.type, r.data, "
+			"c.cert_policy, c.uniqueid, c.auth_method, c.eap_type, "
+			"c.eap_vendor, c.keyingtries, c.rekeytime, c.reauthtime, c.jitter, "
+			"c.overtime, c.mobike, c.dpd_delay, c.virtual, c.pool, "
+			"c.mediation, c.mediated_by, COALESCE(p.type, 0), p.data "
 			"FROM peer_configs AS c "
-			"JOIN identities AS l ON local_id = l.id "
-			"JOIN identities AS r ON remote_id = r.id "
-			"LEFT JOIN identities AS p ON peer_id = p.id "
-			"WHERE id = ?",
+			"JOIN identities AS l ON c.local_id = l.id "
+			"JOIN identities AS r ON c.remote_id = r.id "
+			"LEFT JOIN identities AS p ON c.peer_id = p.id "
+			"WHERE c.id = ?",
 			DB_INT, id,
 			DB_INT, DB_TEXT, DB_INT, DB_INT, DB_BLOB, DB_INT, DB_BLOB,
 			DB_INT, DB_INT, DB_INT, DB_INT, DB_INT,
@@ -465,16 +468,16 @@ METHOD(backend_t, get_peer_cfg_by_name, peer_cfg_t*,
 	peer_cfg_t *peer_cfg = NULL;
 
 	e = this->db->query(this->db,
-			"SELECT c.id, name, ike_cfg, l.type, l.data, r.type, r.data, "
-			"cert_policy, uniqueid, auth_method, eap_type, eap_vendor, "
-			"keyingtries, rekeytime, reauthtime, jitter, overtime, mobike, "
-			"dpd_delay, virtual, pool, "
-			"mediation, mediated_by, COALESCE(p.type, 0), p.data "
+			"SELECT c.id, c.name, c.ike_cfg, l.type, l.data, r.type, r.data, "
+			"c.cert_policy, c.uniqueid, c.auth_method, c.eap_type, "
+			"c.eap_vendor, c.keyingtries, c.rekeytime, c.reauthtime, c.jitter, "
+			"c.overtime, c.mobike, c.dpd_delay, c.virtual, c.pool, "
+			"c.mediation, c.mediated_by, COALESCE(p.type, 0), p.data "
 			"FROM peer_configs AS c "
-			"JOIN identities AS l ON local_id = l.id "
-			"JOIN identities AS r ON remote_id = r.id "
-			"LEFT JOIN identities AS p ON peer_id = p.id "
-			"WHERE ike_version = ? AND name = ?",
+			"JOIN identities AS l ON c.local_id = l.id "
+			"JOIN identities AS r ON c.remote_id = r.id "
+			"LEFT JOIN identities AS p ON c.peer_id = p.id "
+			"WHERE c.ike_version = ? AND c.name = ?",
 			DB_INT, 2, DB_TEXT, name,
 			DB_INT, DB_TEXT, DB_INT, DB_INT, DB_BLOB, DB_INT, DB_BLOB,
 			DB_INT, DB_INT, DB_INT, DB_INT, DB_INT,
@@ -544,8 +547,8 @@ METHOD(backend_t, create_ike_cfg_enumerator, enumerator_t*,
 		.other = other,
 	);
 	e->inner = this->db->query(this->db,
-							   "SELECT id, certreq, force_encap, local, remote "
-							   "FROM ike_configs",
+							   "SELECT c.id, c.certreq, c.force_encap, "
+							   "c.local, c.remote FROM ike_configs AS c",
 							   DB_INT, DB_INT, DB_INT, DB_TEXT, DB_TEXT);
 	if (!e->inner)
 	{
@@ -613,16 +616,16 @@ METHOD(backend_t, create_peer_cfg_enumerator, enumerator_t*,
 
 	/* TODO: only get configs whose IDs match exactly or contain wildcards */
 	e->inner = this->db->query(this->db,
-			"SELECT c.id, name, ike_cfg, l.type, l.data, r.type, r.data, "
-			"cert_policy, uniqueid, auth_method, eap_type, eap_vendor, "
-			"keyingtries, rekeytime, reauthtime, jitter, overtime, mobike, "
-			"dpd_delay, virtual, pool, "
-			"mediation, mediated_by, COALESCE(p.type, 0), p.data "
+			"SELECT c.id, c.name, c.ike_cfg, l.type, l.data, r.type, r.data, "
+			"c.cert_policy, c.uniqueid, c.auth_method, c.eap_type, "
+			"c.eap_vendor, c.keyingtries, c.rekeytime, c.reauthtime, c.jitter, "
+			"c.overtime, c.mobike, c.dpd_delay, c.virtual, c.pool, "
+			"c.mediation, c.mediated_by, COALESCE(p.type, 0), p.data "
 			"FROM peer_configs AS c "
-			"JOIN identities AS l ON local_id = l.id "
-			"JOIN identities AS r ON remote_id = r.id "
-			"LEFT JOIN identities AS p ON peer_id = p.id "
-			"WHERE ike_version = ?",
+			"JOIN identities AS l ON c.local_id = l.id "
+			"JOIN identities AS r ON c.remote_id = r.id "
+			"LEFT JOIN identities AS p ON c.peer_id = p.id "
+			"WHERE c.ike_version = ?",
 			DB_INT, 2,
 			DB_INT, DB_TEXT, DB_INT, DB_INT, DB_BLOB, DB_INT, DB_BLOB,
 			DB_INT, DB_INT, DB_INT, DB_INT, DB_INT,
diff --git a/src/libcharon/plugins/sql/sql_cred.c b/src/libcharon/plugins/sql/sql_cred.c
index 3317de6..9ba0bf1 100644
--- a/src/libcharon/plugins/sql/sql_cred.c
+++ b/src/libcharon/plugins/sql/sql_cred.c
@@ -110,7 +110,8 @@ METHOD(credential_set_t, create_private_enumerator, enumerator_t*,
 	else
 	{
 		e->inner = this->db->query(this->db,
-				"SELECT type, data FROM private_keys WHERE (? OR type = ?)",
+				"SELECT p.type, p.data FROM private_keys AS p "
+				"WHERE (? OR p.type = ?)",
 				DB_INT, type == KEY_ANY, DB_INT, type,
 				DB_INT, DB_BLOB);
 	}
@@ -197,8 +198,8 @@ METHOD(credential_set_t, create_cert_enumerator, enumerator_t*,
 	else
 	{
 		e->inner = this->db->query(this->db,
-				"SELECT type, data FROM certificates WHERE "
-				"(? OR type = ?) AND (? OR keytype = ?)",
+				"SELECT c.type, c.data FROM certificates AS c WHERE "
+				"(? OR c.type = ?) AND (? OR c.keytype = ?)",
 				DB_INT, cert == CERT_ANY, DB_INT, cert,
 				DB_INT, key == KEY_ANY, DB_INT, key,
 				DB_INT, DB_BLOB);
@@ -286,7 +287,8 @@ METHOD(credential_set_t, create_shared_enumerator, enumerator_t*,
 	if (!me && !other)
 	{
 		e->inner = this->db->query(this->db,
-				"SELECT type, data FROM shared_secrets WHERE  (? OR type = ?)",
+				"SELECT s.type, s.data FROM shared_secrets AS s "
+				"WHERE (? OR s.type = ?)",
 				DB_INT, type == SHARED_ANY, DB_INT, type,
 				DB_INT, DB_BLOB);
 	}
diff --git a/src/libcharon/plugins/stroke/Makefile.in b/src/libcharon/plugins/stroke/Makefile.in
index 0af607f..70374b3 100644
--- a/src/libcharon/plugins/stroke/Makefile.in
+++ b/src/libcharon/plugins/stroke/Makefile.in
@@ -315,8 +315,6 @@ RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
 RUBYGEMDIR = @RUBYGEMDIR@
-RUBYINCLUDE = @RUBYINCLUDE@
-RUBYLIB = @RUBYLIB@
 SED = @SED@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
@@ -417,6 +415,8 @@ random_device = @random_device@
 resolv_conf = @resolv_conf@
 routing_table = @routing_table@
 routing_table_prio = @routing_table_prio@
+ruby_CFLAGS = @ruby_CFLAGS@
+ruby_LIBS = @ruby_LIBS@
 runstatedir = @runstatedir@
 s_plugins = @s_plugins@
 sbindir = @sbindir@
@@ -445,6 +445,10 @@ top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
 tss2_CFLAGS = @tss2_CFLAGS@
 tss2_LIBS = @tss2_LIBS@
+tss2_socket_CFLAGS = @tss2_socket_CFLAGS@
+tss2_socket_LIBS = @tss2_socket_LIBS@
+tss2_tabrmd_CFLAGS = @tss2_tabrmd_CFLAGS@
+tss2_tabrmd_LIBS = @tss2_tabrmd_LIBS@
 urandom_device = @urandom_device@
 xml_CFLAGS = @xml_CFLAGS@
 xml_LIBS = @xml_LIBS@
diff --git a/src/libcharon/plugins/stroke/stroke_config.c b/src/libcharon/plugins/stroke/stroke_config.c
index 00f7483..ac01292 100644
--- a/src/libcharon/plugins/stroke/stroke_config.c
+++ b/src/libcharon/plugins/stroke/stroke_config.c
@@ -136,7 +136,7 @@ METHOD(backend_t, get_peer_cfg_by_name, peer_cfg_t*,
 /**
  * parse a proposal string, either into ike_cfg or child_cfg
  */
-static void add_proposals(private_stroke_config_t *this, char *string,
+static bool add_proposals(private_stroke_config_t *this, char *string,
 				ike_cfg_t *ike_cfg, child_cfg_t *child_cfg, protocol_id_t proto)
 {
 	if (string)
@@ -170,10 +170,11 @@ static void add_proposals(private_stroke_config_t *this, char *string,
 				continue;
 			}
 			DBG1(DBG_CFG, "skipped invalid proposal string: %s", single);
+			return FALSE;
 		}
 		if (strict)
 		{
-			return;
+			return TRUE;
 		}
 		/* add default porposal to the end if not strict */
 	}
@@ -187,6 +188,7 @@ static void add_proposals(private_stroke_config_t *this, char *string,
 		child_cfg->add_proposal(child_cfg, proposal_create_default(proto));
 		child_cfg->add_proposal(child_cfg, proposal_create_default_aead(proto));
 	}
+	return TRUE;
 }
 
 /**
@@ -289,7 +291,12 @@ static ike_cfg_t *build_ike_cfg(private_stroke_config_t *this, stroke_msg_t *msg
 							 msg->add_conn.fragmentation,
 							 msg->add_conn.ikedscp);
 
-	add_proposals(this, msg->add_conn.algorithms.ike, ike_cfg, NULL, PROTO_IKE);
+	if (!add_proposals(this, msg->add_conn.algorithms.ike, ike_cfg,
+					   NULL, PROTO_IKE))
+	{
+		ike_cfg->destroy(ike_cfg);
+		return NULL;
+	}
 	return ike_cfg;
 }
 
@@ -1050,6 +1057,7 @@ static child_cfg_t *build_child_cfg(private_stroke_config_t *this,
 									stroke_msg_t *msg)
 {
 	child_cfg_t *child_cfg;
+	bool success;
 	child_cfg_create_t child = {
 		.lifetime = {
 			.time = {
@@ -1100,13 +1108,18 @@ static child_cfg_t *build_child_cfg(private_stroke_config_t *this,
 
 	if (msg->add_conn.algorithms.ah)
 	{
-		add_proposals(this, msg->add_conn.algorithms.ah,
-					  NULL, child_cfg, PROTO_AH);
+		success = add_proposals(this, msg->add_conn.algorithms.ah,
+								NULL, child_cfg, PROTO_AH);
 	}
 	else
 	{
-		add_proposals(this, msg->add_conn.algorithms.esp,
-					  NULL, child_cfg, PROTO_ESP);
+		success = add_proposals(this, msg->add_conn.algorithms.esp,
+								NULL, child_cfg, PROTO_ESP);
+	}
+	if (!success)
+	{
+		child_cfg->destroy(child_cfg);
+		return NULL;
 	}
 	return child_cfg;
 }
diff --git a/src/libcharon/plugins/systime_fix/Makefile.in b/src/libcharon/plugins/systime_fix/Makefile.in
index 3274430..278eaa1 100644
--- a/src/libcharon/plugins/systime_fix/Makefile.in
+++ b/src/libcharon/plugins/systime_fix/Makefile.in
@@ -313,8 +313,6 @@ RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
 RUBYGEMDIR = @RUBYGEMDIR@
-RUBYINCLUDE = @RUBYINCLUDE@
-RUBYLIB = @RUBYLIB@
 SED = @SED@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
@@ -415,6 +413,8 @@ random_device = @random_device@
 resolv_conf = @resolv_conf@
 routing_table = @routing_table@
 routing_table_prio = @routing_table_prio@
+ruby_CFLAGS = @ruby_CFLAGS@
+ruby_LIBS = @ruby_LIBS@
 runstatedir = @runstatedir@
 s_plugins = @s_plugins@
 sbindir = @sbindir@
@@ -443,6 +443,10 @@ top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
 tss2_CFLAGS = @tss2_CFLAGS@
 tss2_LIBS = @tss2_LIBS@
+tss2_socket_CFLAGS = @tss2_socket_CFLAGS@
+tss2_socket_LIBS = @tss2_socket_LIBS@
+tss2_tabrmd_CFLAGS = @tss2_tabrmd_CFLAGS@
+tss2_tabrmd_LIBS = @tss2_tabrmd_LIBS@
 urandom_device = @urandom_device@
 xml_CFLAGS = @xml_CFLAGS@
 xml_LIBS = @xml_LIBS@
diff --git a/src/libcharon/plugins/tnc_ifmap/Makefile.in b/src/libcharon/plugins/tnc_ifmap/Makefile.in
index 438001b..3b146e1 100644
--- a/src/libcharon/plugins/tnc_ifmap/Makefile.in
+++ b/src/libcharon/plugins/tnc_ifmap/Makefile.in
@@ -316,8 +316,6 @@ RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
 RUBYGEMDIR = @RUBYGEMDIR@
-RUBYINCLUDE = @RUBYINCLUDE@
-RUBYLIB = @RUBYLIB@
 SED = @SED@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
@@ -418,6 +416,8 @@ random_device = @random_device@
 resolv_conf = @resolv_conf@
 routing_table = @routing_table@
 routing_table_prio = @routing_table_prio@
+ruby_CFLAGS = @ruby_CFLAGS@
+ruby_LIBS = @ruby_LIBS@
 runstatedir = @runstatedir@
 s_plugins = @s_plugins@
 sbindir = @sbindir@
@@ -446,6 +446,10 @@ top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
 tss2_CFLAGS = @tss2_CFLAGS@
 tss2_LIBS = @tss2_LIBS@
+tss2_socket_CFLAGS = @tss2_socket_CFLAGS@
+tss2_socket_LIBS = @tss2_socket_LIBS@
+tss2_tabrmd_CFLAGS = @tss2_tabrmd_CFLAGS@
+tss2_tabrmd_LIBS = @tss2_tabrmd_LIBS@
 urandom_device = @urandom_device@
 xml_CFLAGS = @xml_CFLAGS@
 xml_LIBS = @xml_LIBS@
diff --git a/src/libcharon/plugins/tnc_pdp/Makefile.in b/src/libcharon/plugins/tnc_pdp/Makefile.in
index abc7743..3452080 100644
--- a/src/libcharon/plugins/tnc_pdp/Makefile.in
+++ b/src/libcharon/plugins/tnc_pdp/Makefile.in
@@ -317,8 +317,6 @@ RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
 RUBYGEMDIR = @RUBYGEMDIR@
-RUBYINCLUDE = @RUBYINCLUDE@
-RUBYLIB = @RUBYLIB@
 SED = @SED@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
@@ -419,6 +417,8 @@ random_device = @random_device@
 resolv_conf = @resolv_conf@
 routing_table = @routing_table@
 routing_table_prio = @routing_table_prio@
+ruby_CFLAGS = @ruby_CFLAGS@
+ruby_LIBS = @ruby_LIBS@
 runstatedir = @runstatedir@
 s_plugins = @s_plugins@
 sbindir = @sbindir@
@@ -447,6 +447,10 @@ top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
 tss2_CFLAGS = @tss2_CFLAGS@
 tss2_LIBS = @tss2_LIBS@
+tss2_socket_CFLAGS = @tss2_socket_CFLAGS@
+tss2_socket_LIBS = @tss2_socket_LIBS@
+tss2_tabrmd_CFLAGS = @tss2_tabrmd_CFLAGS@
+tss2_tabrmd_LIBS = @tss2_tabrmd_LIBS@
 urandom_device = @urandom_device@
 xml_CFLAGS = @xml_CFLAGS@
 xml_LIBS = @xml_LIBS@
diff --git a/src/libcharon/plugins/uci/Makefile.in b/src/libcharon/plugins/uci/Makefile.in
index 46f4e4f..2c12798 100644
--- a/src/libcharon/plugins/uci/Makefile.in
+++ b/src/libcharon/plugins/uci/Makefile.in
@@ -311,8 +311,6 @@ RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
 RUBYGEMDIR = @RUBYGEMDIR@
-RUBYINCLUDE = @RUBYINCLUDE@
-RUBYLIB = @RUBYLIB@
 SED = @SED@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
@@ -413,6 +411,8 @@ random_device = @random_device@
 resolv_conf = @resolv_conf@
 routing_table = @routing_table@
 routing_table_prio = @routing_table_prio@
+ruby_CFLAGS = @ruby_CFLAGS@
+ruby_LIBS = @ruby_LIBS@
 runstatedir = @runstatedir@
 s_plugins = @s_plugins@
 sbindir = @sbindir@
@@ -441,6 +441,10 @@ top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
 tss2_CFLAGS = @tss2_CFLAGS@
 tss2_LIBS = @tss2_LIBS@
+tss2_socket_CFLAGS = @tss2_socket_CFLAGS@
+tss2_socket_LIBS = @tss2_socket_LIBS@
+tss2_tabrmd_CFLAGS = @tss2_tabrmd_CFLAGS@
+tss2_tabrmd_LIBS = @tss2_tabrmd_LIBS@
 urandom_device = @urandom_device@
 xml_CFLAGS = @xml_CFLAGS@
 xml_LIBS = @xml_LIBS@
diff --git a/src/libcharon/plugins/unity/Makefile.in b/src/libcharon/plugins/unity/Makefile.in
index 245bbd4..b82c379 100644
--- a/src/libcharon/plugins/unity/Makefile.in
+++ b/src/libcharon/plugins/unity/Makefile.in
@@ -312,8 +312,6 @@ RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
 RUBYGEMDIR = @RUBYGEMDIR@
-RUBYINCLUDE = @RUBYINCLUDE@
-RUBYLIB = @RUBYLIB@
 SED = @SED@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
@@ -414,6 +412,8 @@ random_device = @random_device@
 resolv_conf = @resolv_conf@
 routing_table = @routing_table@
 routing_table_prio = @routing_table_prio@
+ruby_CFLAGS = @ruby_CFLAGS@
+ruby_LIBS = @ruby_LIBS@
 runstatedir = @runstatedir@
 s_plugins = @s_plugins@
 sbindir = @sbindir@
@@ -442,6 +442,10 @@ top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
 tss2_CFLAGS = @tss2_CFLAGS@
 tss2_LIBS = @tss2_LIBS@
+tss2_socket_CFLAGS = @tss2_socket_CFLAGS@
+tss2_socket_LIBS = @tss2_socket_LIBS@
+tss2_tabrmd_CFLAGS = @tss2_tabrmd_CFLAGS@
+tss2_tabrmd_LIBS = @tss2_tabrmd_LIBS@
 urandom_device = @urandom_device@
 xml_CFLAGS = @xml_CFLAGS@
 xml_LIBS = @xml_LIBS@
diff --git a/src/libcharon/plugins/updown/Makefile.in b/src/libcharon/plugins/updown/Makefile.in
index ef0f33c..4c648fb 100644
--- a/src/libcharon/plugins/updown/Makefile.in
+++ b/src/libcharon/plugins/updown/Makefile.in
@@ -313,8 +313,6 @@ RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
 RUBYGEMDIR = @RUBYGEMDIR@
-RUBYINCLUDE = @RUBYINCLUDE@
-RUBYLIB = @RUBYLIB@
 SED = @SED@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
@@ -415,6 +413,8 @@ random_device = @random_device@
 resolv_conf = @resolv_conf@
 routing_table = @routing_table@
 routing_table_prio = @routing_table_prio@
+ruby_CFLAGS = @ruby_CFLAGS@
+ruby_LIBS = @ruby_LIBS@
 runstatedir = @runstatedir@
 s_plugins = @s_plugins@
 sbindir = @sbindir@
@@ -443,6 +443,10 @@ top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
 tss2_CFLAGS = @tss2_CFLAGS@
 tss2_LIBS = @tss2_LIBS@
+tss2_socket_CFLAGS = @tss2_socket_CFLAGS@
+tss2_socket_LIBS = @tss2_socket_LIBS@
+tss2_tabrmd_CFLAGS = @tss2_tabrmd_CFLAGS@
+tss2_tabrmd_LIBS = @tss2_tabrmd_LIBS@
 urandom_device = @urandom_device@
 xml_CFLAGS = @xml_CFLAGS@
 xml_LIBS = @xml_LIBS@
diff --git a/src/libcharon/plugins/vici/Makefile.in b/src/libcharon/plugins/vici/Makefile.in
index fd2b898..cd3dafb 100644
--- a/src/libcharon/plugins/vici/Makefile.in
+++ b/src/libcharon/plugins/vici/Makefile.in
@@ -409,8 +409,6 @@ RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
 RUBYGEMDIR = @RUBYGEMDIR@
-RUBYINCLUDE = @RUBYINCLUDE@
-RUBYLIB = @RUBYLIB@
 SED = @SED@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
@@ -511,6 +509,8 @@ random_device = @random_device@
 resolv_conf = @resolv_conf@
 routing_table = @routing_table@
 routing_table_prio = @routing_table_prio@
+ruby_CFLAGS = @ruby_CFLAGS@
+ruby_LIBS = @ruby_LIBS@
 runstatedir = @runstatedir@
 s_plugins = @s_plugins@
 sbindir = @sbindir@
@@ -539,6 +539,10 @@ top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
 tss2_CFLAGS = @tss2_CFLAGS@
 tss2_LIBS = @tss2_LIBS@
+tss2_socket_CFLAGS = @tss2_socket_CFLAGS@
+tss2_socket_LIBS = @tss2_socket_LIBS@
+tss2_tabrmd_CFLAGS = @tss2_tabrmd_CFLAGS@
+tss2_tabrmd_LIBS = @tss2_tabrmd_LIBS@
 urandom_device = @urandom_device@
 xml_CFLAGS = @xml_CFLAGS@
 xml_LIBS = @xml_LIBS@
diff --git a/src/libcharon/plugins/vici/perl/Makefile.in b/src/libcharon/plugins/vici/perl/Makefile.in
index 0e9626a..f48eb6a 100644
--- a/src/libcharon/plugins/vici/perl/Makefile.in
+++ b/src/libcharon/plugins/vici/perl/Makefile.in
@@ -227,8 +227,6 @@ RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
 RUBYGEMDIR = @RUBYGEMDIR@
-RUBYINCLUDE = @RUBYINCLUDE@
-RUBYLIB = @RUBYLIB@
 SED = @SED@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
@@ -329,6 +327,8 @@ random_device = @random_device@
 resolv_conf = @resolv_conf@
 routing_table = @routing_table@
 routing_table_prio = @routing_table_prio@
+ruby_CFLAGS = @ruby_CFLAGS@
+ruby_LIBS = @ruby_LIBS@
 runstatedir = @runstatedir@
 s_plugins = @s_plugins@
 sbindir = @sbindir@
@@ -357,6 +357,10 @@ top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
 tss2_CFLAGS = @tss2_CFLAGS@
 tss2_LIBS = @tss2_LIBS@
+tss2_socket_CFLAGS = @tss2_socket_CFLAGS@
+tss2_socket_LIBS = @tss2_socket_LIBS@
+tss2_tabrmd_CFLAGS = @tss2_tabrmd_CFLAGS@
+tss2_tabrmd_LIBS = @tss2_tabrmd_LIBS@
 urandom_device = @urandom_device@
 xml_CFLAGS = @xml_CFLAGS@
 xml_LIBS = @xml_LIBS@
diff --git a/src/libcharon/plugins/vici/python/Makefile.in b/src/libcharon/plugins/vici/python/Makefile.in
index 7d53832..7d5944a 100644
--- a/src/libcharon/plugins/vici/python/Makefile.in
+++ b/src/libcharon/plugins/vici/python/Makefile.in
@@ -249,8 +249,6 @@ RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
 RUBYGEMDIR = @RUBYGEMDIR@
-RUBYINCLUDE = @RUBYINCLUDE@
-RUBYLIB = @RUBYLIB@
 SED = @SED@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
@@ -351,6 +349,8 @@ random_device = @random_device@
 resolv_conf = @resolv_conf@
 routing_table = @routing_table@
 routing_table_prio = @routing_table_prio@
+ruby_CFLAGS = @ruby_CFLAGS@
+ruby_LIBS = @ruby_LIBS@
 runstatedir = @runstatedir@
 s_plugins = @s_plugins@
 sbindir = @sbindir@
@@ -379,6 +379,10 @@ top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
 tss2_CFLAGS = @tss2_CFLAGS@
 tss2_LIBS = @tss2_LIBS@
+tss2_socket_CFLAGS = @tss2_socket_CFLAGS@
+tss2_socket_LIBS = @tss2_socket_LIBS@
+tss2_tabrmd_CFLAGS = @tss2_tabrmd_CFLAGS@
+tss2_tabrmd_LIBS = @tss2_tabrmd_LIBS@
 urandom_device = @urandom_device@
 xml_CFLAGS = @xml_CFLAGS@
 xml_LIBS = @xml_LIBS@
diff --git a/src/libcharon/plugins/vici/ruby/Makefile.in b/src/libcharon/plugins/vici/ruby/Makefile.in
index 5691a74..b122276 100644
--- a/src/libcharon/plugins/vici/ruby/Makefile.in
+++ b/src/libcharon/plugins/vici/ruby/Makefile.in
@@ -227,8 +227,6 @@ RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
 RUBYGEMDIR = @RUBYGEMDIR@
-RUBYINCLUDE = @RUBYINCLUDE@
-RUBYLIB = @RUBYLIB@
 SED = @SED@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
@@ -329,6 +327,8 @@ random_device = @random_device@
 resolv_conf = @resolv_conf@
 routing_table = @routing_table@
 routing_table_prio = @routing_table_prio@
+ruby_CFLAGS = @ruby_CFLAGS@
+ruby_LIBS = @ruby_LIBS@
 runstatedir = @runstatedir@
 s_plugins = @s_plugins@
 sbindir = @sbindir@
@@ -357,6 +357,10 @@ top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
 tss2_CFLAGS = @tss2_CFLAGS@
 tss2_LIBS = @tss2_LIBS@
+tss2_socket_CFLAGS = @tss2_socket_CFLAGS@
+tss2_socket_LIBS = @tss2_socket_LIBS@
+tss2_tabrmd_CFLAGS = @tss2_tabrmd_CFLAGS@
+tss2_tabrmd_LIBS = @tss2_tabrmd_LIBS@
 urandom_device = @urandom_device@
 xml_CFLAGS = @xml_CFLAGS@
 xml_LIBS = @xml_LIBS@
@@ -470,8 +474,8 @@ distclean-generic:
 maintainer-clean-generic:
 	@echo "This command is intended for maintainers to use"
 	@echo "it deletes files that may require special tools to rebuild."
- at RUBY_GEMS_INSTALL_FALSE@uninstall-local:
 @RUBY_GEMS_INSTALL_FALSE at install-data-local:
+ at RUBY_GEMS_INSTALL_FALSE@uninstall-local:
 clean: clean-am
 
 clean-am: clean-generic clean-libtool clean-local mostlyclean-am
diff --git a/src/libcharon/plugins/vici/ruby/lib/vici.rb b/src/libcharon/plugins/vici/ruby/lib/vici.rb
index bcf1a17..f846a14 100644
--- a/src/libcharon/plugins/vici/ruby/lib/vici.rb
+++ b/src/libcharon/plugins/vici/ruby/lib/vici.rb
@@ -550,7 +550,7 @@ module Vici
     # Listen for a set of event messages. This call is blocking, and invokes
     # the passed closure for each event received. The closure receives the
     # event name and the event message as argument. To stop listening, the
-    # closure may raise a StopEventListening exception, the only catched
+    # closure may raise a StopEventListening exception, the only caught
     # exception.
     def listen_events(events, &block)
       self.class.instance_eval do
diff --git a/src/libcharon/plugins/whitelist/Makefile.in b/src/libcharon/plugins/whitelist/Makefile.in
index 0347c5f..50c790a 100644
--- a/src/libcharon/plugins/whitelist/Makefile.in
+++ b/src/libcharon/plugins/whitelist/Makefile.in
@@ -320,8 +320,6 @@ RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
 RUBYGEMDIR = @RUBYGEMDIR@
-RUBYINCLUDE = @RUBYINCLUDE@
-RUBYLIB = @RUBYLIB@
 SED = @SED@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
@@ -422,6 +420,8 @@ random_device = @random_device@
 resolv_conf = @resolv_conf@
 routing_table = @routing_table@
 routing_table_prio = @routing_table_prio@
+ruby_CFLAGS = @ruby_CFLAGS@
+ruby_LIBS = @ruby_LIBS@
 runstatedir = @runstatedir@
 s_plugins = @s_plugins@
 sbindir = @sbindir@
@@ -450,6 +450,10 @@ top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
 tss2_CFLAGS = @tss2_CFLAGS@
 tss2_LIBS = @tss2_LIBS@
+tss2_socket_CFLAGS = @tss2_socket_CFLAGS@
+tss2_socket_LIBS = @tss2_socket_LIBS@
+tss2_tabrmd_CFLAGS = @tss2_tabrmd_CFLAGS@
+tss2_tabrmd_LIBS = @tss2_tabrmd_LIBS@
 urandom_device = @urandom_device@
 xml_CFLAGS = @xml_CFLAGS@
 xml_LIBS = @xml_LIBS@
diff --git a/src/libcharon/plugins/xauth_eap/Makefile.in b/src/libcharon/plugins/xauth_eap/Makefile.in
index 28158a3..7d3dc89 100644
--- a/src/libcharon/plugins/xauth_eap/Makefile.in
+++ b/src/libcharon/plugins/xauth_eap/Makefile.in
@@ -313,8 +313,6 @@ RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
 RUBYGEMDIR = @RUBYGEMDIR@
-RUBYINCLUDE = @RUBYINCLUDE@
-RUBYLIB = @RUBYLIB@
 SED = @SED@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
@@ -415,6 +413,8 @@ random_device = @random_device@
 resolv_conf = @resolv_conf@
 routing_table = @routing_table@
 routing_table_prio = @routing_table_prio@
+ruby_CFLAGS = @ruby_CFLAGS@
+ruby_LIBS = @ruby_LIBS@
 runstatedir = @runstatedir@
 s_plugins = @s_plugins@
 sbindir = @sbindir@
@@ -443,6 +443,10 @@ top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
 tss2_CFLAGS = @tss2_CFLAGS@
 tss2_LIBS = @tss2_LIBS@
+tss2_socket_CFLAGS = @tss2_socket_CFLAGS@
+tss2_socket_LIBS = @tss2_socket_LIBS@
+tss2_tabrmd_CFLAGS = @tss2_tabrmd_CFLAGS@
+tss2_tabrmd_LIBS = @tss2_tabrmd_LIBS@
 urandom_device = @urandom_device@
 xml_CFLAGS = @xml_CFLAGS@
 xml_LIBS = @xml_LIBS@
diff --git a/src/libcharon/plugins/xauth_generic/Makefile.in b/src/libcharon/plugins/xauth_generic/Makefile.in
index 1dc2675..8b937bb 100644
--- a/src/libcharon/plugins/xauth_generic/Makefile.in
+++ b/src/libcharon/plugins/xauth_generic/Makefile.in
@@ -313,8 +313,6 @@ RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
 RUBYGEMDIR = @RUBYGEMDIR@
-RUBYINCLUDE = @RUBYINCLUDE@
-RUBYLIB = @RUBYLIB@
 SED = @SED@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
@@ -415,6 +413,8 @@ random_device = @random_device@
 resolv_conf = @resolv_conf@
 routing_table = @routing_table@
 routing_table_prio = @routing_table_prio@
+ruby_CFLAGS = @ruby_CFLAGS@
+ruby_LIBS = @ruby_LIBS@
 runstatedir = @runstatedir@
 s_plugins = @s_plugins@
 sbindir = @sbindir@
@@ -443,6 +443,10 @@ top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
 tss2_CFLAGS = @tss2_CFLAGS@
 tss2_LIBS = @tss2_LIBS@
+tss2_socket_CFLAGS = @tss2_socket_CFLAGS@
+tss2_socket_LIBS = @tss2_socket_LIBS@
+tss2_tabrmd_CFLAGS = @tss2_tabrmd_CFLAGS@
+tss2_tabrmd_LIBS = @tss2_tabrmd_LIBS@
 urandom_device = @urandom_device@
 xml_CFLAGS = @xml_CFLAGS@
 xml_LIBS = @xml_LIBS@
diff --git a/src/libcharon/plugins/xauth_noauth/Makefile.in b/src/libcharon/plugins/xauth_noauth/Makefile.in
index a610bab..ff2e6e9 100644
--- a/src/libcharon/plugins/xauth_noauth/Makefile.in
+++ b/src/libcharon/plugins/xauth_noauth/Makefile.in
@@ -313,8 +313,6 @@ RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
 RUBYGEMDIR = @RUBYGEMDIR@
-RUBYINCLUDE = @RUBYINCLUDE@
-RUBYLIB = @RUBYLIB@
 SED = @SED@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
@@ -415,6 +413,8 @@ random_device = @random_device@
 resolv_conf = @resolv_conf@
 routing_table = @routing_table@
 routing_table_prio = @routing_table_prio@
+ruby_CFLAGS = @ruby_CFLAGS@
+ruby_LIBS = @ruby_LIBS@
 runstatedir = @runstatedir@
 s_plugins = @s_plugins@
 sbindir = @sbindir@
@@ -443,6 +443,10 @@ top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
 tss2_CFLAGS = @tss2_CFLAGS@
 tss2_LIBS = @tss2_LIBS@
+tss2_socket_CFLAGS = @tss2_socket_CFLAGS@
+tss2_socket_LIBS = @tss2_socket_LIBS@
+tss2_tabrmd_CFLAGS = @tss2_tabrmd_CFLAGS@
+tss2_tabrmd_LIBS = @tss2_tabrmd_LIBS@
 urandom_device = @urandom_device@
 xml_CFLAGS = @xml_CFLAGS@
 xml_LIBS = @xml_LIBS@
diff --git a/src/libcharon/plugins/xauth_pam/Makefile.in b/src/libcharon/plugins/xauth_pam/Makefile.in
index 8c31f24..0f320df 100644
--- a/src/libcharon/plugins/xauth_pam/Makefile.in
+++ b/src/libcharon/plugins/xauth_pam/Makefile.in
@@ -313,8 +313,6 @@ RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
 RUBYGEMDIR = @RUBYGEMDIR@
-RUBYINCLUDE = @RUBYINCLUDE@
-RUBYLIB = @RUBYLIB@
 SED = @SED@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
@@ -415,6 +413,8 @@ random_device = @random_device@
 resolv_conf = @resolv_conf@
 routing_table = @routing_table@
 routing_table_prio = @routing_table_prio@
+ruby_CFLAGS = @ruby_CFLAGS@
+ruby_LIBS = @ruby_LIBS@
 runstatedir = @runstatedir@
 s_plugins = @s_plugins@
 sbindir = @sbindir@
@@ -443,6 +443,10 @@ top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
 tss2_CFLAGS = @tss2_CFLAGS@
 tss2_LIBS = @tss2_LIBS@
+tss2_socket_CFLAGS = @tss2_socket_CFLAGS@
+tss2_socket_LIBS = @tss2_socket_LIBS@
+tss2_tabrmd_CFLAGS = @tss2_tabrmd_CFLAGS@
+tss2_tabrmd_LIBS = @tss2_tabrmd_LIBS@
 urandom_device = @urandom_device@
 xml_CFLAGS = @xml_CFLAGS@
 xml_LIBS = @xml_LIBS@
diff --git a/src/libcharon/sa/child_sa.c b/src/libcharon/sa/child_sa.c
index 3d9f613..4133d91 100644
--- a/src/libcharon/sa/child_sa.c
+++ b/src/libcharon/sa/child_sa.c
@@ -40,10 +40,10 @@ ENUM(child_sa_state_names, CHILD_CREATED, CHILD_DESTROYING,
 	"DESTROYING",
 );
 
-ENUM(child_sa_outbound_state_names, CHILD_OUTBOUND_NONE, CHILD_OUTBOUND_INSTALLED,
-	"NONE",
+ENUM_FLAGS(child_sa_outbound_state_names, CHILD_OUTBOUND_REGISTERED, CHILD_OUTBOUND_POLICIES,
 	"REGISTERED",
-	"INSTALLED",
+	"SA",
+	"POLICIES",
 );
 
 typedef struct private_child_sa_t private_child_sa_t;
@@ -296,12 +296,15 @@ METHOD(child_sa_t, get_config, child_cfg_t*,
 METHOD(child_sa_t, set_state, void,
 	   private_child_sa_t *this, child_sa_state_t state)
 {
-	DBG2(DBG_CHD, "CHILD_SA %s{%d} state change: %N => %N",
-		 get_name(this), this->unique_id,
-		 child_sa_state_names, this->state,
-		 child_sa_state_names, state);
-	charon->bus->child_state_change(charon->bus, &this->public, state);
-	this->state = state;
+	if (this->state != state)
+	{
+		DBG2(DBG_CHD, "CHILD_SA %s{%d} state change: %N => %N",
+			 get_name(this), this->unique_id,
+			 child_sa_state_names, this->state,
+			 child_sa_state_names, state);
+		charon->bus->child_state_change(charon->bus, &this->public, state);
+		this->state = state;
+	}
 }
 
 METHOD(child_sa_t, get_state, child_sa_state_t,
@@ -547,7 +550,7 @@ static status_t update_usebytes(private_child_sa_t *this, bool inbound)
 	}
 	else
 	{
-		if (this->other_spi && this->outbound_state == CHILD_OUTBOUND_INSTALLED)
+		if (this->other_spi && (this->outbound_state & CHILD_OUTBOUND_SA))
 		{
 			kernel_ipsec_sa_id_t id = {
 				.src = this->my_addr,
@@ -788,7 +791,7 @@ static status_t install_internal(private_child_sa_t *this, chunk_t encr,
 		{
 			tfc = this->config->get_tfc(this->config);
 		}
-		this->outbound_state = CHILD_OUTBOUND_INSTALLED;
+		this->outbound_state |= CHILD_OUTBOUND_SA;
 	}
 
 	DBG2(DBG_CHD, "adding %s %N SA", inbound ? "inbound" : "outbound",
@@ -1188,6 +1191,7 @@ METHOD(child_sa_t, install_policies, status_t,
 	linked_list_t *my_ts_list, *other_ts_list;
 	traffic_selector_t *my_ts, *other_ts;
 	status_t status = SUCCESS;
+	bool install_outbound = FALSE;
 
 	if (!this->reqid_allocated && !this->static_reqid)
 	{
@@ -1207,12 +1211,17 @@ METHOD(child_sa_t, install_policies, status_t,
 		this->reqid_allocated = TRUE;
 	}
 
+	if (!(this->outbound_state & CHILD_OUTBOUND_REGISTERED))
+	{
+		install_outbound = TRUE;
+		this->outbound_state |= CHILD_OUTBOUND_POLICIES;
+	}
+
 	if (!this->config->has_option(this->config, OPT_NO_POLICIES))
 	{
 		policy_priority_t priority;
 		ipsec_sa_cfg_t my_sa, other_sa;
 		uint32_t manual_prio;
-		bool install_outbound;
 
 		prepare_sa_cfg(this, &my_sa, &other_sa);
 		manual_prio = this->config->get_manual_prio(this->config);
@@ -1222,7 +1231,6 @@ METHOD(child_sa_t, install_policies, status_t,
 		this->trap = this->state == CHILD_CREATED;
 		priority = this->trap ? POLICY_PRIORITY_ROUTED
 							  : POLICY_PRIORITY_DEFAULT;
-		install_outbound = this->outbound_state != CHILD_OUTBOUND_REGISTERED;
 
 		/* enumerate pairs of traffic selectors */
 		enumerator = create_policy_enumerator(this);
@@ -1250,7 +1258,6 @@ METHOD(child_sa_t, install_policies, status_t,
 									this->other_addr, my_ts, other_ts,
 									&my_sa, &other_sa, POLICY_IPSEC,
 									priority, manual_prio);
-
 			}
 			if (status != SUCCESS)
 			{
@@ -1267,21 +1274,35 @@ METHOD(child_sa_t, install_policies, status_t,
 	return status;
 }
 
-METHOD(child_sa_t, register_outbound, void,
+METHOD(child_sa_t, register_outbound, status_t,
 	private_child_sa_t *this, chunk_t encr, chunk_t integ, uint32_t spi,
 	uint16_t cpi, bool tfcv3)
 {
-	DBG2(DBG_CHD, "registering outbound %N SA", protocol_id_names,
-		 this->protocol);
-	DBG2(DBG_CHD, "  SPI 0x%.8x, src %H dst %H", ntohl(spi), this->my_addr,
-		 this->other_addr);
-
-	this->other_spi = spi;
-	this->other_cpi = cpi;
-	this->encr_r = chunk_clone(encr);
-	this->integ_r = chunk_clone(integ);
-	this->tfcv3 = tfcv3;
-	this->outbound_state = CHILD_OUTBOUND_REGISTERED;
+	status_t status;
+
+	/* if the kernel supports installing SPIs with policies we install the
+	 * SA immediately as it will only be used once we update the policies */
+	if (charon->kernel->get_features(charon->kernel) & KERNEL_POLICY_SPI)
+	{
+		status = install_internal(this, encr, integ, spi, cpi, FALSE, FALSE,
+								  tfcv3);
+	}
+	else
+	{
+		DBG2(DBG_CHD, "registering outbound %N SA", protocol_id_names,
+			 this->protocol);
+		DBG2(DBG_CHD, "  SPI 0x%.8x, src %H dst %H", ntohl(spi), this->my_addr,
+			 this->other_addr);
+
+		this->other_spi = spi;
+		this->other_cpi = cpi;
+		this->encr_r = chunk_clone(encr);
+		this->integ_r = chunk_clone(integ);
+		this->tfcv3 = tfcv3;
+		status = SUCCESS;
+	}
+	this->outbound_state |= CHILD_OUTBOUND_REGISTERED;
+	return status;
 }
 
 METHOD(child_sa_t, install_outbound, status_t,
@@ -1289,18 +1310,23 @@ METHOD(child_sa_t, install_outbound, status_t,
 {
 	enumerator_t *enumerator;
 	traffic_selector_t *my_ts, *other_ts;
-	status_t status;
+	status_t status = SUCCESS;
 
-	status = install_internal(this, this->encr_r, this->integ_r,
-							  this->other_spi, this->other_cpi, FALSE, FALSE,
-							  this->tfcv3);
-	chunk_clear(&this->encr_r);
-	chunk_clear(&this->integ_r);
+	if (!(this->outbound_state & CHILD_OUTBOUND_SA))
+	{
+		status = install_internal(this, this->encr_r, this->integ_r,
+								  this->other_spi, this->other_cpi, FALSE,
+								  FALSE, this->tfcv3);
+		chunk_clear(&this->encr_r);
+		chunk_clear(&this->integ_r);
+	}
+	this->outbound_state &= ~CHILD_OUTBOUND_REGISTERED;
 	if (status != SUCCESS)
 	{
 		return status;
 	}
-	if (!this->config->has_option(this->config, OPT_NO_POLICIES))
+	if (!this->config->has_option(this->config, OPT_NO_POLICIES) &&
+		!(this->outbound_state & CHILD_OUTBOUND_POLICIES))
 	{
 		ipsec_sa_cfg_t my_sa, other_sa;
 		uint32_t manual_prio;
@@ -1331,6 +1357,7 @@ METHOD(child_sa_t, install_outbound, status_t,
 		}
 		enumerator->destroy(enumerator);
 	}
+	this->outbound_state |= CHILD_OUTBOUND_POLICIES;
 	return status;
 }
 
@@ -1340,20 +1367,19 @@ METHOD(child_sa_t, remove_outbound, void,
 	enumerator_t *enumerator;
 	traffic_selector_t *my_ts, *other_ts;
 
-	switch (this->outbound_state)
+	if (!(this->outbound_state & CHILD_OUTBOUND_SA))
 	{
-		case CHILD_OUTBOUND_INSTALLED:
-			break;
-		case CHILD_OUTBOUND_REGISTERED:
+		if (this->outbound_state & CHILD_OUTBOUND_REGISTERED)
+		{
 			chunk_clear(&this->encr_r);
 			chunk_clear(&this->integ_r);
 			this->outbound_state = CHILD_OUTBOUND_NONE;
-			/* fall-through */
-		case CHILD_OUTBOUND_NONE:
-			return;
+		}
+		return;
 	}
 
-	if (!this->config->has_option(this->config, OPT_NO_POLICIES))
+	if (!this->config->has_option(this->config, OPT_NO_POLICIES) &&
+		(this->outbound_state & CHILD_OUTBOUND_POLICIES))
 	{
 		ipsec_sa_cfg_t my_sa, other_sa;
 		uint32_t manual_prio;
@@ -1598,8 +1624,8 @@ METHOD(child_sa_t, destroy, void,
 
 		prepare_sa_cfg(this, &my_sa, &other_sa);
 		manual_prio = this->config->get_manual_prio(this->config);
-		del_outbound = this->trap ||
-					   this->outbound_state == CHILD_OUTBOUND_INSTALLED;
+		del_outbound = (this->outbound_state & CHILD_OUTBOUND_POLICIES) ||
+						this->trap;
 
 		/* delete all policies in the kernel */
 		enumerator = create_policy_enumerator(this);
@@ -1640,7 +1666,7 @@ METHOD(child_sa_t, destroy, void,
 		};
 		charon->kernel->del_sa(charon->kernel, &id, &sa);
 	}
-	if (this->other_spi && this->outbound_state == CHILD_OUTBOUND_INSTALLED)
+	if (this->other_spi && (this->outbound_state & CHILD_OUTBOUND_SA))
 	{
 		kernel_ipsec_sa_id_t id = {
 			.src = this->my_addr,
@@ -1719,7 +1745,7 @@ child_sa_t * child_sa_create(host_t *me, host_t* other,
 {
 	private_child_sa_t *this;
 	static refcount_t unique_id = 0, unique_mark = 0;
-	refcount_t mark;
+	refcount_t mark = 0;
 
 	INIT(this,
 		.public = {
@@ -1792,16 +1818,33 @@ child_sa_t * child_sa_create(host_t *me, host_t* other,
 	{
 		this->mark_out.value = mark_out;
 	}
-	if (this->mark_in.value == MARK_UNIQUE ||
-		this->mark_out.value == MARK_UNIQUE)
+
+	if (MARK_IS_UNIQUE(this->mark_in.value) ||
+		MARK_IS_UNIQUE(this->mark_out.value))
 	{
-		mark = ref_get(&unique_mark);
-		if (this->mark_in.value == MARK_UNIQUE)
+		bool unique_dir;
+
+		unique_dir = this->mark_in.value == MARK_UNIQUE_DIR ||
+					 this->mark_out.value == MARK_UNIQUE_DIR;
+
+		if (!unique_dir)
+		{
+			mark = ref_get(&unique_mark);
+		}
+		if (MARK_IS_UNIQUE(this->mark_in.value))
 		{
+			if (unique_dir)
+			{
+				mark = ref_get(&unique_mark);
+			}
 			this->mark_in.value = mark;
 		}
-		if (this->mark_out.value == MARK_UNIQUE)
+		if (MARK_IS_UNIQUE(this->mark_out.value))
 		{
+			if (unique_dir)
+			{
+				mark = ref_get(&unique_mark);
+			}
 			this->mark_out.value = mark;
 		}
 	}
diff --git a/src/libcharon/sa/child_sa.h b/src/libcharon/sa/child_sa.h
index b9a913d..082404d 100644
--- a/src/libcharon/sa/child_sa.h
+++ b/src/libcharon/sa/child_sa.h
@@ -102,17 +102,28 @@ enum child_sa_outbound_state_t {
 	/**
 	 * Outbound SA is not installed
 	 */
-	CHILD_OUTBOUND_NONE,
+	CHILD_OUTBOUND_NONE = 0,
 
 	/**
-	 * Data for the outbound SA has been registered, but not installed yet
+	 * Data for the outbound SA has been registered during a rekeying (not set
+	 * once the SA and policies are both installed)
 	 */
-	CHILD_OUTBOUND_REGISTERED,
+	CHILD_OUTBOUND_REGISTERED = (1<<0),
 
 	/**
-	 * The outbound SA is currently installed
+	 * The outbound SA has been installed
 	 */
-	CHILD_OUTBOUND_INSTALLED,
+	CHILD_OUTBOUND_SA = (1<<1),
+
+	/**
+	 * The outbound policies have been installed
+	 */
+	CHILD_OUTBOUND_POLICIES = (1<<2),
+
+	/**
+	 * The outbound SA and policies are both installed
+	 */
+	CHILD_OUTBOUND_INSTALLED = (CHILD_OUTBOUND_SA|CHILD_OUTBOUND_POLICIES),
 };
 
 /**
@@ -400,20 +411,23 @@ struct child_sa_t {
 	 * Register data for the installation of an outbound SA as responder during
 	 * a rekeying.
 	 *
-	 * The SA is not installed until install_outbound() is called.
+	 * If the kernel is able to handle SPIs on policies the SA is installed
+	 * immediately, if not it won't be installed until install_outbound() is
+	 * called.
 	 *
 	 * @param encr		encryption key, if any (cloned)
 	 * @param integ		integrity key (cloned)
 	 * @param spi		SPI to use, allocated for inbound
 	 * @param cpi		CPI to use, allocated for outbound
 	 * @param tfcv3		TRUE if peer supports ESPv3 TFC
+	 * @return			SUCCESS or FAILED
 	 */
-	void (*register_outbound)(child_sa_t *this, chunk_t encr, chunk_t integ,
-							  uint32_t spi, uint16_t cpi, bool tfcv3);
+	status_t (*register_outbound)(child_sa_t *this, chunk_t encr, chunk_t integ,
+								  uint32_t spi, uint16_t cpi, bool tfcv3);
 
 	/**
-	 * Install the outbound SA and the outbound policies as responder during a
-	 * rekeying.
+	 * Install the outbound policies and, if not already done, the outbound SA
+	 * as responder during a rekeying.
 	 *
 	 * @return			SUCCESS or FAILED
 	 */
diff --git a/src/libcharon/sa/ikev1/task_manager_v1.c b/src/libcharon/sa/ikev1/task_manager_v1.c
index 48ec3e7..3472d2c 100644
--- a/src/libcharon/sa/ikev1/task_manager_v1.c
+++ b/src/libcharon/sa/ikev1/task_manager_v1.c
@@ -1805,8 +1805,12 @@ METHOD(task_manager_t, queue_child_rekey, void,
 		if (is_redundant(this, child_sa))
 		{
 			child_sa->set_state(child_sa, CHILD_REKEYED);
-			queue_task(this, (task_t*)quick_delete_create(this->ike_sa,
+			if (lib->settings->get_bool(lib->settings, "%s.delete_rekeyed",
+										FALSE, lib->ns))
+			{
+				queue_task(this, (task_t*)quick_delete_create(this->ike_sa,
 												protocol, spi, FALSE, FALSE));
+			}
 		}
 		else
 		{
diff --git a/src/libcharon/sa/ikev1/tasks/quick_mode.c b/src/libcharon/sa/ikev1/tasks/quick_mode.c
index 8be82eb..49b476a 100644
--- a/src/libcharon/sa/ikev1/tasks/quick_mode.c
+++ b/src/libcharon/sa/ikev1/tasks/quick_mode.c
@@ -396,10 +396,6 @@ static bool install(private_quick_mode_t *this)
 	charon->bus->child_keys(charon->bus, this->child_sa, this->initiator,
 							this->dh, this->nonce_i, this->nonce_r);
 
-	/* add to IKE_SA, and remove from task */
-	this->child_sa->set_state(this->child_sa, CHILD_INSTALLED);
-	this->ike_sa->add_child_sa(this->ike_sa, this->child_sa);
-
 	my_ts = linked_list_create_from_enumerator(
 				this->child_sa->create_ts_enumerator(this->child_sa, TRUE));
 	other_ts = linked_list_create_from_enumerator(
@@ -415,6 +411,9 @@ static bool install(private_quick_mode_t *this)
 	my_ts->destroy(my_ts);
 	other_ts->destroy(other_ts);
 
+	this->child_sa->set_state(this->child_sa, CHILD_INSTALLED);
+	this->ike_sa->add_child_sa(this->ike_sa, this->child_sa);
+
 	if (this->rekey)
 	{
 		old = this->ike_sa->get_child_sa(this->ike_sa,
diff --git a/src/libcharon/sa/ikev2/keymat_v2.c b/src/libcharon/sa/ikev2/keymat_v2.c
index 70dacd1..0c41c68 100644
--- a/src/libcharon/sa/ikev2/keymat_v2.c
+++ b/src/libcharon/sa/ikev2/keymat_v2.c
@@ -342,10 +342,13 @@ METHOD(keymat_v2_t, derive_ike_keys, bool,
 	 * the nonces. */
 	switch (alg)
 	{
+		case PRF_AES128_CMAC:
+			/* while variable keys may be used according to RFC 4615, RFC 7296
+			 * explicitly limits the key size to 128 bit for this application */
 		case PRF_AES128_XCBC:
-			/* while rfc4434 defines variable keys for AES-XCBC, rfc3664 does
+			/* while RFC 4434 defines variable keys for AES-XCBC, RFC 3664 does
 			 * not and therefore fixed key semantics apply to XCBC for key
-			 * derivation. */
+			 * derivation, which is also reinforced by RFC 7296 */
 		case PRF_CAMELLIA128_XCBC:
 			/* draft-kanno-ipsecme-camellia-xcbc refers to rfc 4434, we
 			 * assume fixed key length. */
diff --git a/src/libcharon/sa/ikev2/tasks/child_create.c b/src/libcharon/sa/ikev2/tasks/child_create.c
index 896cabb..cac3bc0 100644
--- a/src/libcharon/sa/ikev2/tasks/child_create.c
+++ b/src/libcharon/sa/ikev2/tasks/child_create.c
@@ -478,6 +478,7 @@ static status_t select_and_install(private_child_create_t *this,
 								   bool no_dh, bool ike_auth)
 {
 	status_t status, status_i, status_o;
+	child_sa_outbound_state_t out_state;
 	chunk_t nonce_i, nonce_r;
 	chunk_t encr_i = chunk_empty, encr_r = chunk_empty;
 	chunk_t integ_i = chunk_empty, integ_r = chunk_empty;
@@ -678,29 +679,42 @@ static status_t select_and_install(private_child_create_t *this,
 			status_i = this->child_sa->install(this->child_sa, encr_r, integ_r,
 							this->my_spi, this->my_cpi, this->initiator,
 							TRUE, this->tfcv3);
-			status_o = this->child_sa->install(this->child_sa, encr_i, integ_i,
-							this->other_spi, this->other_cpi, this->initiator,
-							FALSE, this->tfcv3);
 		}
-		else if (!this->rekey)
+		else
 		{
 			status_i = this->child_sa->install(this->child_sa, encr_i, integ_i,
 							this->my_spi, this->my_cpi, this->initiator,
 							TRUE, this->tfcv3);
-			status_o = this->child_sa->install(this->child_sa, encr_r, integ_r,
+		}
+		if (this->rekey)
+		{	/* during rekeyings we install the outbound SA and/or policies
+			 * separately: as responder when we receive the delete for the old
+			 * SA, as initiator pretty much immediately in the ike-rekey task,
+			 * unless there was a rekey collision that we lost */
+			if (this->initiator)
+			{
+				status_o = this->child_sa->register_outbound(this->child_sa,
+							encr_i, integ_i, this->other_spi, this->other_cpi,
+							this->tfcv3);
+			}
+			else
+			{
+				status_o = this->child_sa->register_outbound(this->child_sa,
+							encr_r, integ_r, this->other_spi, this->other_cpi,
+							this->tfcv3);
+			}
+		}
+		else if (this->initiator)
+		{
+			status_o = this->child_sa->install(this->child_sa, encr_i, integ_i,
 							this->other_spi, this->other_cpi, this->initiator,
 							FALSE, this->tfcv3);
 		}
 		else
-		{	/* as responder during a rekeying we only install the inbound
-			 * SA now, the outbound SA and policies are installed when we
-			 * receive the delete for the old SA */
-			status_i = this->child_sa->install(this->child_sa, encr_i, integ_i,
-							this->my_spi, this->my_cpi, this->initiator,
-							TRUE, this->tfcv3);
-			this->child_sa->register_outbound(this->child_sa, encr_r, integ_r,
-							this->other_spi, this->other_cpi, this->tfcv3);
-			status_o = SUCCESS;
+		{
+			status_o = this->child_sa->install(this->child_sa, encr_r, integ_r,
+							this->other_spi, this->other_cpi, this->initiator,
+							FALSE, this->tfcv3);
 		}
 	}
 
@@ -745,20 +759,15 @@ static status_t select_and_install(private_child_create_t *this,
 	charon->bus->child_keys(charon->bus, this->child_sa, this->initiator,
 							this->dh, nonce_i, nonce_r);
 
-	this->child_sa->set_state(this->child_sa, CHILD_INSTALLED);
-	this->ike_sa->add_child_sa(this->ike_sa, this->child_sa);
-	this->established = TRUE;
-
-	schedule_inactivity_timeout(this);
-
 	my_ts = linked_list_create_from_enumerator(
 				this->child_sa->create_ts_enumerator(this->child_sa, TRUE));
 	other_ts = linked_list_create_from_enumerator(
 				this->child_sa->create_ts_enumerator(this->child_sa, FALSE));
+	out_state = this->child_sa->get_outbound_state(this->child_sa);
 
 	DBG0(DBG_IKE, "%sCHILD_SA %s{%d} established "
 		 "with SPIs %.8x_i %.8x_o and TS %#R === %#R",
-		 this->rekey && !this->initiator ? "inbound " : "",
+		 (out_state == CHILD_OUTBOUND_INSTALLED) ? "" : "inbound ",
 		 this->child_sa->get_name(this->child_sa),
 		 this->child_sa->get_unique_id(this->child_sa),
 		 ntohl(this->child_sa->get_spi(this->child_sa, TRUE)),
@@ -767,6 +776,12 @@ static status_t select_and_install(private_child_create_t *this,
 
 	my_ts->destroy(my_ts);
 	other_ts->destroy(other_ts);
+
+	this->child_sa->set_state(this->child_sa, CHILD_INSTALLED);
+	this->ike_sa->add_child_sa(this->ike_sa, this->child_sa);
+	this->established = TRUE;
+
+	schedule_inactivity_timeout(this);
 	return SUCCESS;
 }
 
@@ -1007,17 +1022,6 @@ METHOD(task_t, build_i, status_t,
 			break;
 	}
 
-	if (this->reqid)
-	{
-		DBG0(DBG_IKE, "establishing CHILD_SA %s{%d}",
-			 this->config->get_name(this->config), this->reqid);
-	}
-	else
-	{
-		DBG0(DBG_IKE, "establishing CHILD_SA %s",
-			 this->config->get_name(this->config));
-	}
-
 	/* check if we want a virtual IP, but don't have one */
 	list = linked_list_create();
 	peer_cfg = this->ike_sa->get_peer_cfg(this->ike_sa);
@@ -1070,6 +1074,19 @@ METHOD(task_t, build_i, status_t,
 			this->ike_sa->has_condition(this->ike_sa, COND_NAT_ANY),
 			this->mark_in, this->mark_out);
 
+	if (this->reqid)
+	{
+		DBG0(DBG_IKE, "establishing CHILD_SA %s{%d} reqid %d",
+			 this->child_sa->get_name(this->child_sa),
+			 this->child_sa->get_unique_id(this->child_sa), this->reqid);
+	}
+	else
+	{
+		DBG0(DBG_IKE, "establishing CHILD_SA %s{%d}",
+			 this->child_sa->get_name(this->child_sa),
+			 this->child_sa->get_unique_id(this->child_sa));
+	}
+
 	if (!allocate_spi(this))
 	{
 		DBG1(DBG_IKE, "unable to allocate SPIs from kernel");
diff --git a/src/libcharon/sa/ikev2/tasks/child_delete.c b/src/libcharon/sa/ikev2/tasks/child_delete.c
index 6267963..2217295 100644
--- a/src/libcharon/sa/ikev2/tasks/child_delete.c
+++ b/src/libcharon/sa/ikev2/tasks/child_delete.c
@@ -196,7 +196,6 @@ static void install_outbound(private_child_delete_t *this,
 		/* FIXME: delete the new child_sa? */
 		return;
 	}
-	child_sa->set_state(child_sa, CHILD_INSTALLED);
 
 	my_ts = linked_list_create_from_enumerator(
 							child_sa->create_ts_enumerator(child_sa, TRUE));
diff --git a/src/libcharon/sa/ikev2/tasks/child_rekey.c b/src/libcharon/sa/ikev2/tasks/child_rekey.c
index 761c860..b67e9b8 100644
--- a/src/libcharon/sa/ikev2/tasks/child_rekey.c
+++ b/src/libcharon/sa/ikev2/tasks/child_rekey.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2009-2016 Tobias Brunner
+ * Copyright (C) 2009-2017 Tobias Brunner
  * Copyright (C) 2005-2007 Martin Willi
  * Copyright (C) 2005 Jan Hutter
  * HSR Hochschule fuer Technik Rapperswil
@@ -283,7 +283,8 @@ METHOD(task_t, build_r, status_t,
 /**
  * Handle a rekey collision
  */
-static child_sa_t *handle_collision(private_child_rekey_t *this)
+static child_sa_t *handle_collision(private_child_rekey_t *this,
+									child_sa_t **to_install)
 {
 	child_sa_t *to_delete;
 
@@ -302,8 +303,11 @@ static child_sa_t *handle_collision(private_child_rekey_t *this)
 		{
 			child_sa_t *child_sa;
 
-			DBG1(DBG_IKE, "CHILD_SA rekey collision won, deleting old child");
+			*to_install = this->child_create->get_child(this->child_create);
 			to_delete = this->child_sa;
+			DBG1(DBG_IKE, "CHILD_SA rekey collision won, deleting old child "
+				 "%s{%d}", to_delete->get_name(to_delete),
+				 to_delete->get_unique_id(to_delete));
 			/* don't touch child other created, it has already been deleted */
 			if (!this->other_child_destroyed)
 			{
@@ -321,9 +325,10 @@ static child_sa_t *handle_collision(private_child_rekey_t *this)
 		}
 		else
 		{
-			DBG1(DBG_IKE, "CHILD_SA rekey collision lost, "
-				 "deleting rekeyed child");
 			to_delete = this->child_create->get_child(this->child_create);
+			DBG1(DBG_IKE, "CHILD_SA rekey collision lost, deleting redundant "
+				 "child %s{%d}", to_delete->get_name(to_delete),
+				 to_delete->get_unique_id(to_delete));
 		}
 	}
 	else
@@ -334,15 +339,17 @@ static child_sa_t *handle_collision(private_child_rekey_t *this)
 		 * the CHILD_SA the other is not deleting. */
 		if (del->get_child(del) != this->child_sa)
 		{
-			DBG1(DBG_IKE, "CHILD_SA rekey/delete collision, "
-				 "deleting rekeyed child");
 			to_delete = this->child_sa;
+			DBG1(DBG_IKE, "CHILD_SA rekey/delete collision, deleting old child "
+				 "%s{%d}", to_delete->get_name(to_delete),
+				 to_delete->get_unique_id(to_delete));
 		}
 		else
 		{
-			DBG1(DBG_IKE, "CHILD_SA rekey/delete collision, "
-				 "deleting redundant child");
 			to_delete = this->child_create->get_child(this->child_create);
+			DBG1(DBG_IKE, "CHILD_SA rekey/delete collision, deleting redundant "
+				 "child %s{%d}", to_delete->get_name(to_delete),
+				 to_delete->get_unique_id(to_delete));
 		}
 	}
 	return to_delete;
@@ -353,7 +360,7 @@ METHOD(task_t, process_i, status_t,
 {
 	protocol_id_t protocol;
 	uint32_t spi;
-	child_sa_t *to_delete;
+	child_sa_t *to_delete, *to_install = NULL;
 
 	if (message->get_notify(message, NO_ADDITIONAL_SAS))
 	{
@@ -415,19 +422,48 @@ METHOD(task_t, process_i, status_t,
 	/* check for rekey collisions */
 	if (this->collision)
 	{
-		to_delete = handle_collision(this);
+		to_delete = handle_collision(this, &to_install);
 	}
 	else
 	{
+		to_install = this->child_create->get_child(this->child_create);
 		to_delete = this->child_sa;
 	}
-
+	if (to_install)
+	{
+		if (to_install->install_outbound(to_install) != SUCCESS)
+		{
+			DBG1(DBG_IKE, "unable to install outbound IPsec SA (SAD) in kernel");
+			charon->bus->alert(charon->bus, ALERT_INSTALL_CHILD_SA_FAILED,
+							   to_install);
+			/* FIXME: delete the child_sa? fail the task? */
+		}
+		else
+		{
+			linked_list_t *my_ts, *other_ts;
+
+			my_ts = linked_list_create_from_enumerator(
+						to_install->create_ts_enumerator(to_install, TRUE));
+			other_ts = linked_list_create_from_enumerator(
+						to_install->create_ts_enumerator(to_install, FALSE));
+
+			DBG0(DBG_IKE, "outbound CHILD_SA %s{%d} established "
+				 "with SPIs %.8x_i %.8x_o and TS %#R === %#R",
+				 to_install->get_name(to_install),
+				 to_install->get_unique_id(to_install),
+				 ntohl(to_install->get_spi(to_install, TRUE)),
+				 ntohl(to_install->get_spi(to_install, FALSE)),
+				 my_ts, other_ts);
+
+			my_ts->destroy(my_ts);
+			other_ts->destroy(other_ts);
+		}
+	}
 	if (to_delete != this->child_create->get_child(this->child_create))
 	{	/* invoke rekey hook if rekeying successful */
 		charon->bus->child_rekey(charon->bus, this->child_sa,
 							this->child_create->get_child(this->child_create));
 	}
-
 	if (to_delete == NULL)
 	{
 		return SUCCESS;
diff --git a/src/libcharon/sa/trap_manager.c b/src/libcharon/sa/trap_manager.c
index f9fee5e..6436a25 100644
--- a/src/libcharon/sa/trap_manager.c
+++ b/src/libcharon/sa/trap_manager.c
@@ -158,6 +158,31 @@ CALLBACK(acquire_by_dst, bool,
 	return this->dst && this->dst->ip_equals(this->dst, dst);
 }
 
+/**
+ * Check if any remote TS are dynamic
+ */
+static bool dynamic_remote_ts(child_cfg_t *child)
+{
+	enumerator_t *enumerator;
+	linked_list_t *other_ts;
+	traffic_selector_t *ts;
+	bool found = FALSE;
+
+	other_ts = child->get_traffic_selectors(child, FALSE, NULL, NULL);
+	enumerator = other_ts->create_enumerator(other_ts);
+	while (enumerator->enumerate(enumerator, &ts))
+	{
+		if (ts->is_dynamic(ts))
+		{
+			found = TRUE;
+			break;
+		}
+	}
+	enumerator->destroy(enumerator);
+	other_ts->destroy_offset(other_ts, offsetof(traffic_selector_t, destroy));
+	return found;
+}
+
 METHOD(trap_manager_t, install, uint32_t,
 	private_trap_manager_t *this, peer_cfg_t *peer, child_cfg_t *child,
 	uint32_t reqid)
@@ -184,25 +209,39 @@ METHOD(trap_manager_t, install, uint32_t,
 		me = host_create_any(other->get_family(other));
 		wildcard = TRUE;
 	}
-	else if (!other || other->is_anyaddr(other))
+	else if (other && other->is_anyaddr(other))
 	{
-		DESTROY_IF(other);
+		other->destroy(other);
 		DBG1(DBG_CFG, "installing trap failed, remote address unknown");
 		return 0;
 	}
 	else
-	{
-		me = ike_cfg->resolve_me(ike_cfg, other->get_family(other));
-		if (!me || me->is_anyaddr(me))
+	{	/* depending on the traffic selectors we don't really need a remote
+		 * host yet, but we might fail later if no IP can be resolved */
+		if (!other && dynamic_remote_ts(child))
+		{	/* with dynamic TS we do need a host, otherwise 0.0.0.0/0 is used,
+			 * which is probably not what users expect*/
+			DBG1(DBG_CFG, "installing trap failed, remote address unknown with "
+				 "dynamic traffic selector");
+			return 0;
+		}
+		me = ike_cfg->resolve_me(ike_cfg, other ? other->get_family(other)
+												: AF_UNSPEC);
+		if (!other)
+		{
+			other = host_create_any(me ? me->get_family(me) : AF_INET);
+		}
+		other->set_port(other, ike_cfg->get_other_port(ike_cfg));
+		if ((!me || me->is_anyaddr(me)) && !other->is_anyaddr(other))
 		{
 			DESTROY_IF(me);
 			me = charon->kernel->get_source_addr(charon->kernel, other, NULL);
-			if (!me)
-			{
-				me = host_create_any(other->get_family(other));
-			}
-			me->set_port(me, ike_cfg->get_my_port(ike_cfg));
 		}
+		if (!me)
+		{
+			me = host_create_any(other->get_family(other));
+		}
+		me->set_port(me, ike_cfg->get_my_port(ike_cfg));
 	}
 
 	this->lock->write_lock(this->lock);
diff --git a/src/libcharon/tests/Makefile.in b/src/libcharon/tests/Makefile.in
index 3070f42..8a2775b 100644
--- a/src/libcharon/tests/Makefile.in
+++ b/src/libcharon/tests/Makefile.in
@@ -335,8 +335,6 @@ RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
 RUBYGEMDIR = @RUBYGEMDIR@
-RUBYINCLUDE = @RUBYINCLUDE@
-RUBYLIB = @RUBYLIB@
 SED = @SED@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
@@ -437,6 +435,8 @@ random_device = @random_device@
 resolv_conf = @resolv_conf@
 routing_table = @routing_table@
 routing_table_prio = @routing_table_prio@
+ruby_CFLAGS = @ruby_CFLAGS@
+ruby_LIBS = @ruby_LIBS@
 runstatedir = @runstatedir@
 s_plugins = @s_plugins@
 sbindir = @sbindir@
@@ -465,6 +465,10 @@ top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
 tss2_CFLAGS = @tss2_CFLAGS@
 tss2_LIBS = @tss2_LIBS@
+tss2_socket_CFLAGS = @tss2_socket_CFLAGS@
+tss2_socket_LIBS = @tss2_socket_LIBS@
+tss2_tabrmd_CFLAGS = @tss2_tabrmd_CFLAGS@
+tss2_tabrmd_LIBS = @tss2_tabrmd_LIBS@
 urandom_device = @urandom_device@
 xml_CFLAGS = @xml_CFLAGS@
 xml_LIBS = @xml_LIBS@
diff --git a/src/libcharon/tests/suites/test_child_rekey.c b/src/libcharon/tests/suites/test_child_rekey.c
index 76b23f5..ac16972 100644
--- a/src/libcharon/tests/suites/test_child_rekey.c
+++ b/src/libcharon/tests/suites/test_child_rekey.c
@@ -483,6 +483,9 @@ START_TEST(test_collision)
 							  CHILD_OUTBOUND_REGISTERED);
 		assert_child_sa_state(a, data[_i].spi_a, CHILD_INSTALLED,
 							  CHILD_OUTBOUND_INSTALLED);
+		assert_child_sa_state(a, data[_i].spi_del_a, CHILD_DELETING,
+							  CHILD_OUTBOUND_INSTALLED);
+		assert_ipsec_sas_installed(a, 1, 2, 3, 5, 6);
 	}
 	else
 	{
@@ -493,10 +496,10 @@ START_TEST(test_collision)
 							  CHILD_OUTBOUND_INSTALLED);
 		assert_child_sa_state(a, data[_i].spi_a, CHILD_INSTALLED,
 							  CHILD_OUTBOUND_REGISTERED);
+		assert_child_sa_state(a, data[_i].spi_del_a, CHILD_DELETING,
+							  CHILD_OUTBOUND_REGISTERED);
+		assert_ipsec_sas_installed(a, 1, 2, 3, 6);
 	}
-	assert_child_sa_state(a, data[_i].spi_del_a, CHILD_DELETING,
-						  CHILD_OUTBOUND_INSTALLED);
-	assert_ipsec_sas_installed(a, 1, 2, 3, 5, 6);
 	/* CREATE_CHILD_SA { SA, Nr, [KEr,] TSi, TSr } --> */
 	if (data[_i].spi_del_b == 2)
 	{
@@ -507,6 +510,9 @@ START_TEST(test_collision)
 							  CHILD_OUTBOUND_REGISTERED);
 		assert_child_sa_state(b, data[_i].spi_b, CHILD_INSTALLED,
 							  CHILD_OUTBOUND_INSTALLED);
+		assert_child_sa_state(b, data[_i].spi_del_b, CHILD_DELETING,
+							  CHILD_OUTBOUND_INSTALLED);
+		assert_ipsec_sas_installed(b, 1, 2, 4, 5, 6);
 	}
 	else
 	{
@@ -517,10 +523,10 @@ START_TEST(test_collision)
 							  CHILD_OUTBOUND_INSTALLED);
 		assert_child_sa_state(b, data[_i].spi_b, CHILD_INSTALLED,
 							  CHILD_OUTBOUND_REGISTERED);
+		assert_child_sa_state(b, data[_i].spi_del_b, CHILD_DELETING,
+							  CHILD_OUTBOUND_REGISTERED);
+		assert_ipsec_sas_installed(b, 1, 2, 4, 5);
 	}
-	assert_child_sa_state(b, data[_i].spi_del_b, CHILD_DELETING,
-						  CHILD_OUTBOUND_INSTALLED);
-	assert_ipsec_sas_installed(b, 1, 2, 4, 5, 6);
 
 	/* we don't expect this hook to get called anymore */
 	assert_hook_not_called(child_rekey);
@@ -528,27 +534,41 @@ START_TEST(test_collision)
 	assert_jobs_scheduled(1);
 	exchange_test_helper->process_message(exchange_test_helper, b, NULL);
 	assert_child_sa_state(b, data[_i].spi_del_b, CHILD_DELETING,
-						  CHILD_OUTBOUND_INSTALLED);
+						  data[_i].spi_del_b == 2 ? CHILD_OUTBOUND_INSTALLED
+												  : CHILD_OUTBOUND_REGISTERED);
 	assert_child_sa_state(b, data[_i].spi_del_a, CHILD_DELETING,
 						  CHILD_OUTBOUND_NONE);
 	assert_child_sa_state(b, data[_i].spi_b, CHILD_INSTALLED,
 						  CHILD_OUTBOUND_INSTALLED);
 	assert_child_sa_count(b, 3);
-	assert_ipsec_sas_installed(b, 2, 4, 5, 6,
-							   data[_i].spi_del_b == 2 ? 1 : 3);
+	if (data[_i].spi_del_b == 2)
+	{
+		assert_ipsec_sas_installed(b, 1, 2, 4, 5, 6);
+	}
+	else
+	{
+		assert_ipsec_sas_installed(b, 2, 3, 4, 5);
+	}
 	assert_scheduler();
 	/* <-- INFORMATIONAL { D } */
 	assert_jobs_scheduled(1);
 	exchange_test_helper->process_message(exchange_test_helper, a, NULL);
 	assert_child_sa_state(a, data[_i].spi_del_a, CHILD_DELETING,
-						  CHILD_OUTBOUND_INSTALLED);
+						  data[_i].spi_del_a == 1 ? CHILD_OUTBOUND_INSTALLED
+												  : CHILD_OUTBOUND_REGISTERED);
 	assert_child_sa_state(a, data[_i].spi_del_b, CHILD_DELETING,
 						  CHILD_OUTBOUND_NONE);
 	assert_child_sa_state(a, data[_i].spi_a, CHILD_INSTALLED,
 						  CHILD_OUTBOUND_INSTALLED);
 	assert_child_sa_count(a, 3);
-	assert_ipsec_sas_installed(a, 1, 3, 5, 6,
-							   data[_i].spi_del_a == 1 ? 2 : 4);
+	if (data[_i].spi_del_a == 1)
+	{
+		assert_ipsec_sas_installed(a, 1, 2, 3, 5, 6);
+	}
+	else
+	{
+		assert_ipsec_sas_installed(a, 1, 3, 4, 6);
+	}
 	assert_scheduler();
 	/* <-- INFORMATIONAL { D } */
 	assert_jobs_scheduled(1);
@@ -682,6 +702,9 @@ START_TEST(test_collision_delayed_response)
 							  CHILD_OUTBOUND_REGISTERED);
 		assert_child_sa_state(b, data[_i].spi_b, CHILD_INSTALLED,
 							  CHILD_OUTBOUND_INSTALLED);
+		assert_child_sa_state(b, data[_i].spi_del_b, CHILD_DELETING,
+							  CHILD_OUTBOUND_INSTALLED);
+		assert_ipsec_sas_installed(b, 1, 2, 4, 5, 6);
 	}
 	else
 	{
@@ -692,10 +715,10 @@ START_TEST(test_collision_delayed_response)
 							  CHILD_OUTBOUND_INSTALLED);
 		assert_child_sa_state(b, data[_i].spi_b, CHILD_INSTALLED,
 							  CHILD_OUTBOUND_REGISTERED);
+		assert_child_sa_state(b, data[_i].spi_del_b, CHILD_DELETING,
+							  CHILD_OUTBOUND_REGISTERED);
+		assert_ipsec_sas_installed(b, 1, 2, 4, 5);
 	}
-	assert_child_sa_state(b, data[_i].spi_del_b, CHILD_DELETING,
-						  CHILD_OUTBOUND_INSTALLED);
-	assert_ipsec_sas_installed(b, 1, 2, 4, 5, 6);
 
 	/* <-- INFORMATIONAL { D } */
 	assert_hook_not_called(child_rekey);
@@ -748,21 +771,23 @@ START_TEST(test_collision_delayed_response)
 		assert_hook_rekey(child_rekey, 1, data[_i].spi_a);
 		exchange_test_helper->process_message(exchange_test_helper, a, msg);
 		assert_hook();
+		assert_child_sa_state(a, data[_i].spi_del_a, CHILD_DELETING,
+							  CHILD_OUTBOUND_INSTALLED);
+		assert_ipsec_sas_installed(a, 1, 2, 3, 5, 6);
 	}
 	else
 	{
 		assert_hook_not_called(child_rekey);
 		exchange_test_helper->process_message(exchange_test_helper, a, msg);
 		assert_hook();
+		assert_child_sa_state(a, data[_i].spi_del_a, CHILD_DELETING,
+							  CHILD_OUTBOUND_REGISTERED);
+		assert_ipsec_sas_installed(a, 1, 3, 4, 6);
 	}
-	assert_child_sa_state(a, data[_i].spi_del_a, CHILD_DELETING,
-						  CHILD_OUTBOUND_INSTALLED);
 	assert_child_sa_state(a, data[_i].spi_del_b, CHILD_DELETING,
 						  CHILD_OUTBOUND_NONE);
 	assert_child_sa_state(a, data[_i].spi_a, CHILD_INSTALLED,
 						  CHILD_OUTBOUND_INSTALLED);
-	assert_ipsec_sas_installed(a, 1, 3, 5, 6,
-							   data[_i].spi_del_a == 1 ? 2 : 4);
 	assert_child_sa_count(a, 3);
 
 	/* we don't expect this hook to get called anymore */
@@ -1173,6 +1198,8 @@ START_TEST(test_collision_ke_invalid)
 							  CHILD_OUTBOUND_REGISTERED);
 		assert_child_sa_state(a, data[_i].spi_a, CHILD_INSTALLED,
 							  CHILD_OUTBOUND_INSTALLED);
+		assert_child_sa_state(a, data[_i].spi_del_a, CHILD_DELETING,
+							  CHILD_OUTBOUND_INSTALLED);
 	}
 	else
 	{
@@ -1181,9 +1208,9 @@ START_TEST(test_collision_ke_invalid)
 							  CHILD_OUTBOUND_INSTALLED);
 		assert_child_sa_state(a, data[_i].spi_a, CHILD_INSTALLED,
 							  CHILD_OUTBOUND_REGISTERED);
+		assert_child_sa_state(a, data[_i].spi_del_a, CHILD_DELETING,
+							  CHILD_OUTBOUND_REGISTERED);
 	}
-	assert_child_sa_state(a, data[_i].spi_del_a, CHILD_DELETING,
-						  CHILD_OUTBOUND_INSTALLED);
 	/* CREATE_CHILD_SA { SA, Nr, [KEr,] TSi, TSr } --> */
 	if (data[_i].spi_del_b == 2)
 	{
@@ -1194,6 +1221,8 @@ START_TEST(test_collision_ke_invalid)
 							  CHILD_OUTBOUND_REGISTERED);
 		assert_child_sa_state(b, data[_i].spi_b, CHILD_INSTALLED,
 							  CHILD_OUTBOUND_INSTALLED);
+		assert_child_sa_state(b, data[_i].spi_del_b, CHILD_DELETING,
+							  CHILD_OUTBOUND_INSTALLED);
 	}
 	else
 	{
@@ -1202,9 +1231,10 @@ START_TEST(test_collision_ke_invalid)
 							  CHILD_OUTBOUND_INSTALLED);
 		assert_child_sa_state(b, data[_i].spi_b, CHILD_INSTALLED,
 							  CHILD_OUTBOUND_REGISTERED);
+		assert_child_sa_state(b, data[_i].spi_del_b, CHILD_DELETING,
+							  CHILD_OUTBOUND_REGISTERED);
 	}
-	assert_child_sa_state(b, data[_i].spi_del_b, CHILD_DELETING,
-						  CHILD_OUTBOUND_INSTALLED);
+
 
 	/* we don't expect this hook to get called anymore */
 	assert_hook_not_called(child_rekey);
@@ -1212,7 +1242,8 @@ START_TEST(test_collision_ke_invalid)
 	assert_jobs_scheduled(1);
 	exchange_test_helper->process_message(exchange_test_helper, b, NULL);
 	assert_child_sa_state(b, data[_i].spi_del_b, CHILD_DELETING,
-						  CHILD_OUTBOUND_INSTALLED);
+						  data[_i].spi_del_b == 2 ? CHILD_OUTBOUND_INSTALLED
+												  : CHILD_OUTBOUND_REGISTERED);
 	assert_child_sa_state(b, data[_i].spi_del_a, CHILD_DELETING,
 						  CHILD_OUTBOUND_NONE);
 	assert_child_sa_state(b, data[_i].spi_b, CHILD_INSTALLED,
@@ -1223,7 +1254,8 @@ START_TEST(test_collision_ke_invalid)
 	assert_jobs_scheduled(1);
 	exchange_test_helper->process_message(exchange_test_helper, a, NULL);
 	assert_child_sa_state(a, data[_i].spi_del_a, CHILD_DELETING,
-						  CHILD_OUTBOUND_INSTALLED);
+						  data[_i].spi_del_a == 1 ? CHILD_OUTBOUND_INSTALLED
+												  : CHILD_OUTBOUND_REGISTERED);
 	assert_child_sa_state(a, data[_i].spi_del_b, CHILD_DELETING,
 						  CHILD_OUTBOUND_NONE);
 	assert_child_sa_state(a, data[_i].spi_a, CHILD_INSTALLED,
diff --git a/src/libcharon/tests/utils/exchange_test_asserts.h b/src/libcharon/tests/utils/exchange_test_asserts.h
index 4d363ed..ae9ac5c 100644
--- a/src/libcharon/tests/utils/exchange_test_asserts.h
+++ b/src/libcharon/tests/utils/exchange_test_asserts.h
@@ -285,7 +285,7 @@ bool exchange_test_asserts_message(listener_t *this, ike_sa_t *ike_sa,
  * @param dir			IN or OUT to check the next in- or outbound message
  */
 #define assert_message_empty(dir) \
-				_assert_payload(dir, 0)
+				_assert_payload(#dir, 0)
 
 /**
  * Assert that the next in- or outbound plaintext message contains exactly
@@ -295,7 +295,7 @@ bool exchange_test_asserts_message(listener_t *this, ike_sa_t *ike_sa,
  * @param expected		expected payload type
  */
 #define assert_single_payload(dir, expected) \
-				_assert_payload(dir, 1, { TRUE, expected, 0 })
+				_assert_payload(#dir, 1, { TRUE, expected, 0 })
 
 /**
  * Assert that the next in- or outbound plaintext message contains exactly
@@ -305,7 +305,7 @@ bool exchange_test_asserts_message(listener_t *this, ike_sa_t *ike_sa,
  * @param expected		expected notify type
  */
 #define assert_single_notify(dir, expected) \
-				_assert_payload(dir, 1, { TRUE, 0, expected })
+				_assert_payload(#dir, 1, { TRUE, 0, expected })
 
 /**
  * Assert that the next in- or outbound plaintext message contains a notify
@@ -315,7 +315,7 @@ bool exchange_test_asserts_message(listener_t *this, ike_sa_t *ike_sa,
  * @param expected		expected notify type
  */
 #define assert_notify(dir, expected) \
-				_assert_payload(dir, -1, { TRUE, 0, expected })
+				_assert_payload(#dir, -1, { TRUE, 0, expected })
 
 /**
  * Assert that the next in- or outbound plaintext message does not contain a
@@ -325,7 +325,7 @@ bool exchange_test_asserts_message(listener_t *this, ike_sa_t *ike_sa,
  * @param unexpected	not expected notify type
  */
 #define assert_no_notify(dir, unexpected) \
-				_assert_payload(dir, -1, { FALSE, 0, unexpected })
+				_assert_payload(#dir, -1, { FALSE, 0, unexpected })
 
 #define _assert_payload(dir, c, ...) ({ \
 	listener_message_rule_t _rules[] = { __VA_ARGS__ }; \
@@ -333,7 +333,7 @@ bool exchange_test_asserts_message(listener_t *this, ike_sa_t *ike_sa,
 		.listener = { .message = exchange_test_asserts_message, }, \
 		.file = __FILE__, \
 		.line = __LINE__, \
-		.incoming = streq(#dir, "IN") ? TRUE : FALSE, \
+		.incoming = streq(dir, "IN") ? TRUE : FALSE, \
 		.count = c, \
 		.rules = _rules, \
 		.num_rules = countof(_rules), \
diff --git a/src/libcharon/tests/utils/sa_asserts.h b/src/libcharon/tests/utils/sa_asserts.h
index d23f724..216c150 100644
--- a/src/libcharon/tests/utils/sa_asserts.h
+++ b/src/libcharon/tests/utils/sa_asserts.h
@@ -121,7 +121,8 @@
 	test_assert_msg(_state == _child->get_state(_child), "%N != %N", \
 					child_sa_state_names, _state, \
 					child_sa_state_names, _child->get_state(_child)); \
-	test_assert_msg(_outbound == _child->get_outbound_state(_child), "%N != %N", \
+	typeof(outbound) _cur_out = _child->get_outbound_state(_child); \
+	test_assert_msg(_outbound == _cur_out || _outbound & _cur_out, "%N != %N", \
 					child_sa_outbound_state_names, _outbound, \
 					child_sa_outbound_state_names, _child->get_outbound_state(_child)); \
 })
diff --git a/src/libfast/Makefile.in b/src/libfast/Makefile.in
index 8adf068..d147b27 100644
--- a/src/libfast/Makefile.in
+++ b/src/libfast/Makefile.in
@@ -316,8 +316,6 @@ RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
 RUBYGEMDIR = @RUBYGEMDIR@
-RUBYINCLUDE = @RUBYINCLUDE@
-RUBYLIB = @RUBYLIB@
 SED = @SED@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
@@ -418,6 +416,8 @@ random_device = @random_device@
 resolv_conf = @resolv_conf@
 routing_table = @routing_table@
 routing_table_prio = @routing_table_prio@
+ruby_CFLAGS = @ruby_CFLAGS@
+ruby_LIBS = @ruby_LIBS@
 runstatedir = @runstatedir@
 s_plugins = @s_plugins@
 sbindir = @sbindir@
@@ -446,6 +446,10 @@ top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
 tss2_CFLAGS = @tss2_CFLAGS@
 tss2_LIBS = @tss2_LIBS@
+tss2_socket_CFLAGS = @tss2_socket_CFLAGS@
+tss2_socket_LIBS = @tss2_socket_LIBS@
+tss2_tabrmd_CFLAGS = @tss2_tabrmd_CFLAGS@
+tss2_tabrmd_LIBS = @tss2_tabrmd_LIBS@
 urandom_device = @urandom_device@
 xml_CFLAGS = @xml_CFLAGS@
 xml_LIBS = @xml_LIBS@
diff --git a/src/libimcv/Android.mk b/src/libimcv/Android.mk
index 89ce580..4df3dcb 100644
--- a/src/libimcv/Android.mk
+++ b/src/libimcv/Android.mk
@@ -33,6 +33,9 @@ libimcv_la_SOURCES := \
 	ietf/ietf_attr_product_info.h ietf/ietf_attr_product_info.c \
 	ietf/ietf_attr_remediation_instr.h ietf/ietf_attr_remediation_instr.c \
 	ietf/ietf_attr_string_version.h ietf/ietf_attr_string_version.c \
+	ietf/swima/ietf_swima_attr_req.h ietf/swima/ietf_swima_attr_req.c \
+	ietf/swima/ietf_swima_attr_sw_inv.h ietf/swima/ietf_swima_attr_sw_inv.c \
+	ietf/swima/ietf_swima_attr_sw_ev.h ietf/swima/ietf_swima_attr_sw_ev.c \
 	ita/ita_attr.h ita/ita_attr.c \
 	ita/ita_attr_command.h ita/ita_attr_command.c \
 	ita/ita_attr_dummy.h ita/ita_attr_dummy.c \
@@ -68,6 +71,7 @@ libimcv_la_SOURCES := \
 	pts/components/tcg/tcg_comp_func_name.h pts/components/tcg/tcg_comp_func_name.c \
 	pwg/pwg_attr.h pwg/pwg_attr.c \
 	pwg/pwg_attr_vendor_smi_code.h pwg/pwg_attr_vendor_smi_code.c \
+	rest/rest.h rest/rest.c \
 	seg/seg_contract.h seg/seg_contract.c \
 	seg/seg_contract_manager.h seg/seg_contract_manager.c \
 	seg/seg_env.h seg/seg_env.c \
@@ -75,6 +79,13 @@ libimcv_la_SOURCES := \
 	swid/swid_inventory.h swid/swid_inventory.c \
 	swid/swid_tag.h swid/swid_tag.c \
 	swid/swid_tag_id.h swid/swid_tag_id.c \
+	swima/swima_data_model.h swima/swima_data_model.c \
+	swima/swima_record.h swima/swima_record.c \
+	swima/swima_event.h swima/swima_event.c \
+	swima/swima_events.h swima/swima_events.c \
+	swima/swima_inventory.h swima/swima_inventory.c \
+	swima/swima_collector.h swima/swima_collector.c \
+	swima/swima_error.h swima/swima_error.c \
 	tcg/tcg_attr.h tcg/tcg_attr.c \
 	tcg/pts/tcg_pts_attr_proto_caps.h tcg/pts/tcg_pts_attr_proto_caps.c \
 	tcg/pts/tcg_pts_attr_dh_nonce_params_req.h tcg/pts/tcg_pts_attr_dh_nonce_params_req.c \
diff --git a/src/libimcv/Makefile.am b/src/libimcv/Makefile.am
index 8cde4b7..a6397c5 100644
--- a/src/libimcv/Makefile.am
+++ b/src/libimcv/Makefile.am
@@ -2,7 +2,11 @@ AM_CPPFLAGS = \
 	-I$(top_srcdir)/src/libstrongswan \
 	-I$(top_srcdir)/src/libtncif \
 	-I$(top_srcdir)/src/libtpmtss \
-	-DIPSEC_SCRIPT=\"${ipsec_script}\"
+	-DIPSEC_SCRIPT=\"${ipsec_script}\" \
+	-DSWID_DIRECTORY=\"${prefix}/share\"
+
+AM_CFLAGS = \
+	$(json_CFLAGS)
 
 ipseclib_LTLIBRARIES = libimcv.la
 
@@ -12,7 +16,8 @@ libimcv_la_LDFLAGS = \
 libimcv_la_LIBADD = \
 	$(top_builddir)/src/libstrongswan/libstrongswan.la \
 	$(top_builddir)/src/libtncif/libtncif.la \
-	$(top_builddir)/src/libtpmtss/libtpmtss.la
+	$(top_builddir)/src/libtpmtss/libtpmtss.la \
+	$(json_LIBS)
 
 if USE_WINDOWS
   libimcv_la_LIBADD += -lws2_32
@@ -49,6 +54,9 @@ libimcv_la_SOURCES = \
 	ietf/ietf_attr_product_info.h ietf/ietf_attr_product_info.c \
 	ietf/ietf_attr_remediation_instr.h ietf/ietf_attr_remediation_instr.c \
 	ietf/ietf_attr_string_version.h ietf/ietf_attr_string_version.c \
+	ietf/swima/ietf_swima_attr_req.h ietf/swima/ietf_swima_attr_req.c \
+	ietf/swima/ietf_swima_attr_sw_inv.h ietf/swima/ietf_swima_attr_sw_inv.c \
+	ietf/swima/ietf_swima_attr_sw_ev.h ietf/swima/ietf_swima_attr_sw_ev.c \
 	ita/ita_attr.h ita/ita_attr.c \
 	ita/ita_attr_command.h ita/ita_attr_command.c \
 	ita/ita_attr_dummy.h ita/ita_attr_dummy.c \
@@ -84,6 +92,7 @@ libimcv_la_SOURCES = \
 	pts/components/tcg/tcg_comp_func_name.h pts/components/tcg/tcg_comp_func_name.c \
 	pwg/pwg_attr.h pwg/pwg_attr.c \
 	pwg/pwg_attr_vendor_smi_code.h pwg/pwg_attr_vendor_smi_code.c \
+	rest/rest.h rest/rest.c \
 	seg/seg_contract.h seg/seg_contract.c \
 	seg/seg_contract_manager.h seg/seg_contract_manager.c \
 	seg/seg_env.h seg/seg_env.c \
@@ -91,6 +100,15 @@ libimcv_la_SOURCES = \
 	swid/swid_inventory.h swid/swid_inventory.c \
 	swid/swid_tag.h swid/swid_tag.c \
 	swid/swid_tag_id.h swid/swid_tag_id.c \
+	swid_gen/swid_gen.h swid_gen/swid_gen.c \
+	swid_gen/swid_gen_info.h swid_gen/swid_gen_info.c \
+	swima/swima_data_model.h swima/swima_data_model.c \
+	swima/swima_record.h swima/swima_record.c \
+	swima/swima_event.h swima/swima_event.c \
+	swima/swima_events.h swima/swima_events.c \
+	swima/swima_inventory.h swima/swima_inventory.c \
+	swima/swima_collector.h swima/swima_collector.c \
+	swima/swima_error.h swima/swima_error.c \
 	tcg/tcg_attr.h tcg/tcg_attr.c \
 	tcg/pts/tcg_pts_attr_proto_caps.h tcg/pts/tcg_pts_attr_proto_caps.c \
 	tcg/pts/tcg_pts_attr_dh_nonce_params_req.h tcg/pts/tcg_pts_attr_dh_nonce_params_req.c \
@@ -173,6 +191,14 @@ if USE_IMV_SWID
   SUBDIRS += plugins/imv_swid
 endif
 
+if USE_IMC_SWIMA
+  SUBDIRS += plugins/imc_swima
+endif
+
+if USE_IMV_SWIMA
+  SUBDIRS += plugins/imv_swima
+endif
+
 if USE_IMC_HCD
   SUBDIRS += plugins/imc_hcd
 endif
@@ -190,8 +216,19 @@ imcv_tests_SOURCES = \
 	pa_tnc/pa_tnc_attr_manager.c \
 	seg/seg_env.c seg/seg_contract.c \
 	seg/seg_contract_manager.c \
+	swid_gen/swid_gen.c \
+	swima/swima_data_model.c \
+	swima/swima_event.c \
+	swima/swima_events.c \
+	swima/swima_record.c \
+	swima/swima_inventory.c \
+	swima/swima_collector.c \
 	suites/test_imcv_seg.c \
+	suites/test_imcv_swima.c \
 	ietf/ietf_attr_pa_tnc_error.c \
+	ietf/swima/ietf_swima_attr_req.c \
+	ietf/swima/ietf_swima_attr_sw_inv.c \
+	ietf/swima/ietf_swima_attr_sw_ev.c \
 	tcg/seg/tcg_seg_attr_seg_env.c \
 	imcv.c imcv_tests.h imcv_tests.c
 
diff --git a/src/libimcv/Makefile.in b/src/libimcv/Makefile.in
index e361f20..246ffe2 100644
--- a/src/libimcv/Makefile.in
+++ b/src/libimcv/Makefile.in
@@ -103,8 +103,10 @@ ipsec_PROGRAMS = imv_policy_manager$(EXEEXT)
 @USE_IMV_ATTESTATION_TRUE at am__append_9 = plugins/imv_attestation
 @USE_IMC_SWID_TRUE at am__append_10 = plugins/imc_swid
 @USE_IMV_SWID_TRUE at am__append_11 = plugins/imv_swid
- at USE_IMC_HCD_TRUE@am__append_12 = plugins/imc_hcd
- at USE_IMV_HCD_TRUE@am__append_13 = plugins/imv_hcd
+ at USE_IMC_SWIMA_TRUE@am__append_12 = plugins/imc_swima
+ at USE_IMV_SWIMA_TRUE@am__append_13 = plugins/imv_swima
+ at USE_IMC_HCD_TRUE@am__append_14 = plugins/imc_hcd
+ at USE_IMV_HCD_TRUE@am__append_15 = plugins/imv_hcd
 TESTS = imcv_tests$(EXEEXT)
 check_PROGRAMS = $(am__EXEEXT_1)
 subdir = src/libimcv
@@ -162,7 +164,7 @@ libimcv_la_DEPENDENCIES =  \
 	$(top_builddir)/src/libstrongswan/libstrongswan.la \
 	$(top_builddir)/src/libtncif/libtncif.la \
 	$(top_builddir)/src/libtpmtss/libtpmtss.la \
-	$(am__DEPENDENCIES_1)
+	$(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1)
 am__dirstamp = $(am__leading_dot)dirstamp
 am_libimcv_la_OBJECTS = imcv.lo imc/imc_agent.lo imc/imc_msg.lo \
 	imc/imc_os_info.lo imv/imv_agent.lo imv/imv_database.lo \
@@ -178,7 +180,10 @@ am_libimcv_la_OBJECTS = imcv.lo imc/imc_agent.lo imc/imc_msg.lo \
 	ietf/ietf_attr_pa_tnc_error.lo ietf/ietf_attr_port_filter.lo \
 	ietf/ietf_attr_product_info.lo \
 	ietf/ietf_attr_remediation_instr.lo \
-	ietf/ietf_attr_string_version.lo ita/ita_attr.lo \
+	ietf/ietf_attr_string_version.lo \
+	ietf/swima/ietf_swima_attr_req.lo \
+	ietf/swima/ietf_swima_attr_sw_inv.lo \
+	ietf/swima/ietf_swima_attr_sw_ev.lo ita/ita_attr.lo \
 	ita/ita_attr_command.lo ita/ita_attr_dummy.lo \
 	ita/ita_attr_get_settings.lo ita/ita_attr_settings.lo \
 	ita/ita_attr_angel.lo os_info/os_info.lo pa_tnc/pa_tnc_msg.lo \
@@ -195,10 +200,15 @@ am_libimcv_la_OBJECTS = imcv.lo imc/imc_agent.lo imc/imc_msg.lo \
 	pts/components/ita/ita_comp_tboot.lo \
 	pts/components/ita/ita_comp_tgrub.lo \
 	pts/components/tcg/tcg_comp_func_name.lo pwg/pwg_attr.lo \
-	pwg/pwg_attr_vendor_smi_code.lo seg/seg_contract.lo \
-	seg/seg_contract_manager.lo seg/seg_env.lo swid/swid_error.lo \
-	swid/swid_inventory.lo swid/swid_tag.lo swid/swid_tag_id.lo \
-	tcg/tcg_attr.lo tcg/pts/tcg_pts_attr_proto_caps.lo \
+	pwg/pwg_attr_vendor_smi_code.lo rest/rest.lo \
+	seg/seg_contract.lo seg/seg_contract_manager.lo seg/seg_env.lo \
+	swid/swid_error.lo swid/swid_inventory.lo swid/swid_tag.lo \
+	swid/swid_tag_id.lo swid_gen/swid_gen.lo \
+	swid_gen/swid_gen_info.lo swima/swima_data_model.lo \
+	swima/swima_record.lo swima/swima_event.lo \
+	swima/swima_events.lo swima/swima_inventory.lo \
+	swima/swima_collector.lo swima/swima_error.lo tcg/tcg_attr.lo \
+	tcg/pts/tcg_pts_attr_proto_caps.lo \
 	tcg/pts/tcg_pts_attr_dh_nonce_params_req.lo \
 	tcg/pts/tcg_pts_attr_dh_nonce_params_resp.lo \
 	tcg/pts/tcg_pts_attr_dh_nonce_finish.lo \
@@ -234,8 +244,19 @@ am_imcv_tests_OBJECTS = ita/imcv_tests-ita_attr_command.$(OBJEXT) \
 	seg/imcv_tests-seg_env.$(OBJEXT) \
 	seg/imcv_tests-seg_contract.$(OBJEXT) \
 	seg/imcv_tests-seg_contract_manager.$(OBJEXT) \
+	swid_gen/imcv_tests-swid_gen.$(OBJEXT) \
+	swima/imcv_tests-swima_data_model.$(OBJEXT) \
+	swima/imcv_tests-swima_event.$(OBJEXT) \
+	swima/imcv_tests-swima_events.$(OBJEXT) \
+	swima/imcv_tests-swima_record.$(OBJEXT) \
+	swima/imcv_tests-swima_inventory.$(OBJEXT) \
+	swima/imcv_tests-swima_collector.$(OBJEXT) \
 	suites/imcv_tests-test_imcv_seg.$(OBJEXT) \
+	suites/imcv_tests-test_imcv_swima.$(OBJEXT) \
 	ietf/imcv_tests-ietf_attr_pa_tnc_error.$(OBJEXT) \
+	ietf/swima/imcv_tests-ietf_swima_attr_req.$(OBJEXT) \
+	ietf/swima/imcv_tests-ietf_swima_attr_sw_inv.$(OBJEXT) \
+	ietf/swima/imcv_tests-ietf_swima_attr_sw_ev.$(OBJEXT) \
 	tcg/seg/imcv_tests-tcg_seg_attr_seg_env.$(OBJEXT) \
 	imcv_tests-imcv.$(OBJEXT) imcv_tests-imcv_tests.$(OBJEXT)
 imcv_tests_OBJECTS = $(am_imcv_tests_OBJECTS)
@@ -357,8 +378,8 @@ am__tty_colors = { \
 DIST_SUBDIRS = . plugins/imc_test plugins/imv_test plugins/imc_scanner \
 	plugins/imv_scanner plugins/imc_os plugins/imv_os \
 	plugins/imc_attestation plugins/imv_attestation \
-	plugins/imc_swid plugins/imv_swid plugins/imc_hcd \
-	plugins/imv_hcd
+	plugins/imc_swid plugins/imv_swid plugins/imc_swima \
+	plugins/imv_swima plugins/imc_hcd plugins/imv_hcd
 am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/depcomp
 DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
 am__relativize = \
@@ -485,8 +506,6 @@ RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
 RUBYGEMDIR = @RUBYGEMDIR@
-RUBYINCLUDE = @RUBYINCLUDE@
-RUBYLIB = @RUBYLIB@
 SED = @SED@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
@@ -587,6 +606,8 @@ random_device = @random_device@
 resolv_conf = @resolv_conf@
 routing_table = @routing_table@
 routing_table_prio = @routing_table_prio@
+ruby_CFLAGS = @ruby_CFLAGS@
+ruby_LIBS = @ruby_LIBS@
 runstatedir = @runstatedir@
 s_plugins = @s_plugins@
 sbindir = @sbindir@
@@ -615,6 +636,10 @@ top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
 tss2_CFLAGS = @tss2_CFLAGS@
 tss2_LIBS = @tss2_LIBS@
+tss2_socket_CFLAGS = @tss2_socket_CFLAGS@
+tss2_socket_LIBS = @tss2_socket_LIBS@
+tss2_tabrmd_CFLAGS = @tss2_tabrmd_CFLAGS@
+tss2_tabrmd_LIBS = @tss2_tabrmd_LIBS@
 urandom_device = @urandom_device@
 xml_CFLAGS = @xml_CFLAGS@
 xml_LIBS = @xml_LIBS@
@@ -622,7 +647,11 @@ AM_CPPFLAGS = \
 	-I$(top_srcdir)/src/libstrongswan \
 	-I$(top_srcdir)/src/libtncif \
 	-I$(top_srcdir)/src/libtpmtss \
-	-DIPSEC_SCRIPT=\"${ipsec_script}\"
+	-DIPSEC_SCRIPT=\"${ipsec_script}\" \
+	-DSWID_DIRECTORY=\"${prefix}/share\"
+
+AM_CFLAGS = \
+	$(json_CFLAGS)
 
 ipseclib_LTLIBRARIES = libimcv.la
 libimcv_la_LDFLAGS = \
@@ -631,7 +660,8 @@ libimcv_la_LDFLAGS = \
 libimcv_la_LIBADD =  \
 	$(top_builddir)/src/libstrongswan/libstrongswan.la \
 	$(top_builddir)/src/libtncif/libtncif.la \
-	$(top_builddir)/src/libtpmtss/libtpmtss.la $(am__append_1)
+	$(top_builddir)/src/libtpmtss/libtpmtss.la $(json_LIBS) \
+	$(am__append_1)
 libimcv_la_SOURCES = \
 	imcv.h imcv.c \
 	imc/imc_agent.h imc/imc_agent.c imc/imc_state.h \
@@ -663,6 +693,9 @@ libimcv_la_SOURCES = \
 	ietf/ietf_attr_product_info.h ietf/ietf_attr_product_info.c \
 	ietf/ietf_attr_remediation_instr.h ietf/ietf_attr_remediation_instr.c \
 	ietf/ietf_attr_string_version.h ietf/ietf_attr_string_version.c \
+	ietf/swima/ietf_swima_attr_req.h ietf/swima/ietf_swima_attr_req.c \
+	ietf/swima/ietf_swima_attr_sw_inv.h ietf/swima/ietf_swima_attr_sw_inv.c \
+	ietf/swima/ietf_swima_attr_sw_ev.h ietf/swima/ietf_swima_attr_sw_ev.c \
 	ita/ita_attr.h ita/ita_attr.c \
 	ita/ita_attr_command.h ita/ita_attr_command.c \
 	ita/ita_attr_dummy.h ita/ita_attr_dummy.c \
@@ -698,6 +731,7 @@ libimcv_la_SOURCES = \
 	pts/components/tcg/tcg_comp_func_name.h pts/components/tcg/tcg_comp_func_name.c \
 	pwg/pwg_attr.h pwg/pwg_attr.c \
 	pwg/pwg_attr_vendor_smi_code.h pwg/pwg_attr_vendor_smi_code.c \
+	rest/rest.h rest/rest.c \
 	seg/seg_contract.h seg/seg_contract.c \
 	seg/seg_contract_manager.h seg/seg_contract_manager.c \
 	seg/seg_env.h seg/seg_env.c \
@@ -705,6 +739,15 @@ libimcv_la_SOURCES = \
 	swid/swid_inventory.h swid/swid_inventory.c \
 	swid/swid_tag.h swid/swid_tag.c \
 	swid/swid_tag_id.h swid/swid_tag_id.c \
+	swid_gen/swid_gen.h swid_gen/swid_gen.c \
+	swid_gen/swid_gen_info.h swid_gen/swid_gen_info.c \
+	swima/swima_data_model.h swima/swima_data_model.c \
+	swima/swima_record.h swima/swima_record.c \
+	swima/swima_event.h swima/swima_event.c \
+	swima/swima_events.h swima/swima_events.c \
+	swima/swima_inventory.h swima/swima_inventory.c \
+	swima/swima_collector.h swima/swima_collector.c \
+	swima/swima_error.h swima/swima_error.c \
 	tcg/tcg_attr.h tcg/tcg_attr.c \
 	tcg/pts/tcg_pts_attr_proto_caps.h tcg/pts/tcg_pts_attr_proto_caps.c \
 	tcg/pts/tcg_pts_attr_dh_nonce_params_req.h tcg/pts/tcg_pts_attr_dh_nonce_params_req.c \
@@ -746,14 +789,26 @@ imv_policy_manager_LDADD = \
 SUBDIRS = . $(am__append_2) $(am__append_3) $(am__append_4) \
 	$(am__append_5) $(am__append_6) $(am__append_7) \
 	$(am__append_8) $(am__append_9) $(am__append_10) \
-	$(am__append_11) $(am__append_12) $(am__append_13)
+	$(am__append_11) $(am__append_12) $(am__append_13) \
+	$(am__append_14) $(am__append_15)
 imcv_tests_SOURCES = \
 	ita/ita_attr_command.c \
 	pa_tnc/pa_tnc_attr_manager.c \
 	seg/seg_env.c seg/seg_contract.c \
 	seg/seg_contract_manager.c \
+	swid_gen/swid_gen.c \
+	swima/swima_data_model.c \
+	swima/swima_event.c \
+	swima/swima_events.c \
+	swima/swima_record.c \
+	swima/swima_inventory.c \
+	swima/swima_collector.c \
 	suites/test_imcv_seg.c \
+	suites/test_imcv_swima.c \
 	ietf/ietf_attr_pa_tnc_error.c \
+	ietf/swima/ietf_swima_attr_req.c \
+	ietf/swima/ietf_swima_attr_sw_inv.c \
+	ietf/swima/ietf_swima_attr_sw_ev.c \
 	tcg/seg/tcg_seg_attr_seg_env.c \
 	imcv.c imcv_tests.h imcv_tests.c
 
@@ -908,6 +963,18 @@ ietf/ietf_attr_remediation_instr.lo: ietf/$(am__dirstamp) \
 	ietf/$(DEPDIR)/$(am__dirstamp)
 ietf/ietf_attr_string_version.lo: ietf/$(am__dirstamp) \
 	ietf/$(DEPDIR)/$(am__dirstamp)
+ietf/swima/$(am__dirstamp):
+	@$(MKDIR_P) ietf/swima
+	@: > ietf/swima/$(am__dirstamp)
+ietf/swima/$(DEPDIR)/$(am__dirstamp):
+	@$(MKDIR_P) ietf/swima/$(DEPDIR)
+	@: > ietf/swima/$(DEPDIR)/$(am__dirstamp)
+ietf/swima/ietf_swima_attr_req.lo: ietf/swima/$(am__dirstamp) \
+	ietf/swima/$(DEPDIR)/$(am__dirstamp)
+ietf/swima/ietf_swima_attr_sw_inv.lo: ietf/swima/$(am__dirstamp) \
+	ietf/swima/$(DEPDIR)/$(am__dirstamp)
+ietf/swima/ietf_swima_attr_sw_ev.lo: ietf/swima/$(am__dirstamp) \
+	ietf/swima/$(DEPDIR)/$(am__dirstamp)
 ita/$(am__dirstamp):
 	@$(MKDIR_P) ita
 	@: > ita/$(am__dirstamp)
@@ -1016,6 +1083,13 @@ pwg/$(DEPDIR)/$(am__dirstamp):
 pwg/pwg_attr.lo: pwg/$(am__dirstamp) pwg/$(DEPDIR)/$(am__dirstamp)
 pwg/pwg_attr_vendor_smi_code.lo: pwg/$(am__dirstamp) \
 	pwg/$(DEPDIR)/$(am__dirstamp)
+rest/$(am__dirstamp):
+	@$(MKDIR_P) rest
+	@: > rest/$(am__dirstamp)
+rest/$(DEPDIR)/$(am__dirstamp):
+	@$(MKDIR_P) rest/$(DEPDIR)
+	@: > rest/$(DEPDIR)/$(am__dirstamp)
+rest/rest.lo: rest/$(am__dirstamp) rest/$(DEPDIR)/$(am__dirstamp)
 seg/$(am__dirstamp):
 	@$(MKDIR_P) seg
 	@: > seg/$(am__dirstamp)
@@ -1039,6 +1113,36 @@ swid/swid_inventory.lo: swid/$(am__dirstamp) \
 swid/swid_tag.lo: swid/$(am__dirstamp) swid/$(DEPDIR)/$(am__dirstamp)
 swid/swid_tag_id.lo: swid/$(am__dirstamp) \
 	swid/$(DEPDIR)/$(am__dirstamp)
+swid_gen/$(am__dirstamp):
+	@$(MKDIR_P) swid_gen
+	@: > swid_gen/$(am__dirstamp)
+swid_gen/$(DEPDIR)/$(am__dirstamp):
+	@$(MKDIR_P) swid_gen/$(DEPDIR)
+	@: > swid_gen/$(DEPDIR)/$(am__dirstamp)
+swid_gen/swid_gen.lo: swid_gen/$(am__dirstamp) \
+	swid_gen/$(DEPDIR)/$(am__dirstamp)
+swid_gen/swid_gen_info.lo: swid_gen/$(am__dirstamp) \
+	swid_gen/$(DEPDIR)/$(am__dirstamp)
+swima/$(am__dirstamp):
+	@$(MKDIR_P) swima
+	@: > swima/$(am__dirstamp)
+swima/$(DEPDIR)/$(am__dirstamp):
+	@$(MKDIR_P) swima/$(DEPDIR)
+	@: > swima/$(DEPDIR)/$(am__dirstamp)
+swima/swima_data_model.lo: swima/$(am__dirstamp) \
+	swima/$(DEPDIR)/$(am__dirstamp)
+swima/swima_record.lo: swima/$(am__dirstamp) \
+	swima/$(DEPDIR)/$(am__dirstamp)
+swima/swima_event.lo: swima/$(am__dirstamp) \
+	swima/$(DEPDIR)/$(am__dirstamp)
+swima/swima_events.lo: swima/$(am__dirstamp) \
+	swima/$(DEPDIR)/$(am__dirstamp)
+swima/swima_inventory.lo: swima/$(am__dirstamp) \
+	swima/$(DEPDIR)/$(am__dirstamp)
+swima/swima_collector.lo: swima/$(am__dirstamp) \
+	swima/$(DEPDIR)/$(am__dirstamp)
+swima/swima_error.lo: swima/$(am__dirstamp) \
+	swima/$(DEPDIR)/$(am__dirstamp)
 tcg/$(am__dirstamp):
 	@$(MKDIR_P) tcg
 	@: > tcg/$(am__dirstamp)
@@ -1181,6 +1285,20 @@ seg/imcv_tests-seg_contract.$(OBJEXT): seg/$(am__dirstamp) \
 	seg/$(DEPDIR)/$(am__dirstamp)
 seg/imcv_tests-seg_contract_manager.$(OBJEXT): seg/$(am__dirstamp) \
 	seg/$(DEPDIR)/$(am__dirstamp)
+swid_gen/imcv_tests-swid_gen.$(OBJEXT): swid_gen/$(am__dirstamp) \
+	swid_gen/$(DEPDIR)/$(am__dirstamp)
+swima/imcv_tests-swima_data_model.$(OBJEXT): swima/$(am__dirstamp) \
+	swima/$(DEPDIR)/$(am__dirstamp)
+swima/imcv_tests-swima_event.$(OBJEXT): swima/$(am__dirstamp) \
+	swima/$(DEPDIR)/$(am__dirstamp)
+swima/imcv_tests-swima_events.$(OBJEXT): swima/$(am__dirstamp) \
+	swima/$(DEPDIR)/$(am__dirstamp)
+swima/imcv_tests-swima_record.$(OBJEXT): swima/$(am__dirstamp) \
+	swima/$(DEPDIR)/$(am__dirstamp)
+swima/imcv_tests-swima_inventory.$(OBJEXT): swima/$(am__dirstamp) \
+	swima/$(DEPDIR)/$(am__dirstamp)
+swima/imcv_tests-swima_collector.$(OBJEXT): swima/$(am__dirstamp) \
+	swima/$(DEPDIR)/$(am__dirstamp)
 suites/$(am__dirstamp):
 	@$(MKDIR_P) suites
 	@: > suites/$(am__dirstamp)
@@ -1189,8 +1307,19 @@ suites/$(DEPDIR)/$(am__dirstamp):
 	@: > suites/$(DEPDIR)/$(am__dirstamp)
 suites/imcv_tests-test_imcv_seg.$(OBJEXT): suites/$(am__dirstamp) \
 	suites/$(DEPDIR)/$(am__dirstamp)
+suites/imcv_tests-test_imcv_swima.$(OBJEXT): suites/$(am__dirstamp) \
+	suites/$(DEPDIR)/$(am__dirstamp)
 ietf/imcv_tests-ietf_attr_pa_tnc_error.$(OBJEXT):  \
 	ietf/$(am__dirstamp) ietf/$(DEPDIR)/$(am__dirstamp)
+ietf/swima/imcv_tests-ietf_swima_attr_req.$(OBJEXT):  \
+	ietf/swima/$(am__dirstamp) \
+	ietf/swima/$(DEPDIR)/$(am__dirstamp)
+ietf/swima/imcv_tests-ietf_swima_attr_sw_inv.$(OBJEXT):  \
+	ietf/swima/$(am__dirstamp) \
+	ietf/swima/$(DEPDIR)/$(am__dirstamp)
+ietf/swima/imcv_tests-ietf_swima_attr_sw_ev.$(OBJEXT):  \
+	ietf/swima/$(am__dirstamp) \
+	ietf/swima/$(DEPDIR)/$(am__dirstamp)
 tcg/seg/imcv_tests-tcg_seg_attr_seg_env.$(OBJEXT):  \
 	tcg/seg/$(am__dirstamp) tcg/seg/$(DEPDIR)/$(am__dirstamp)
 
@@ -1247,6 +1376,8 @@ mostlyclean-compile:
 	-rm -f generic/*.lo
 	-rm -f ietf/*.$(OBJEXT)
 	-rm -f ietf/*.lo
+	-rm -f ietf/swima/*.$(OBJEXT)
+	-rm -f ietf/swima/*.lo
 	-rm -f imc/*.$(OBJEXT)
 	-rm -f imc/*.lo
 	-rm -f imv/*.$(OBJEXT)
@@ -1267,11 +1398,17 @@ mostlyclean-compile:
 	-rm -f pts/components/tcg/*.lo
 	-rm -f pwg/*.$(OBJEXT)
 	-rm -f pwg/*.lo
+	-rm -f rest/*.$(OBJEXT)
+	-rm -f rest/*.lo
 	-rm -f seg/*.$(OBJEXT)
 	-rm -f seg/*.lo
 	-rm -f suites/*.$(OBJEXT)
 	-rm -f swid/*.$(OBJEXT)
 	-rm -f swid/*.lo
+	-rm -f swid_gen/*.$(OBJEXT)
+	-rm -f swid_gen/*.lo
+	-rm -f swima/*.$(OBJEXT)
+	-rm -f swima/*.lo
 	-rm -f tcg/*.$(OBJEXT)
 	-rm -f tcg/*.lo
 	-rm -f tcg/pts/*.$(OBJEXT)
@@ -1303,6 +1440,12 @@ distclean-compile:
 @AMDEP_TRUE@@am__include@ @am__quote at ietf/$(DEPDIR)/ietf_attr_remediation_instr.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ietf/$(DEPDIR)/ietf_attr_string_version.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ietf/$(DEPDIR)/imcv_tests-ietf_attr_pa_tnc_error.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ietf/swima/$(DEPDIR)/ietf_swima_attr_req.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ietf/swima/$(DEPDIR)/ietf_swima_attr_sw_ev.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ietf/swima/$(DEPDIR)/ietf_swima_attr_sw_inv.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ietf/swima/$(DEPDIR)/imcv_tests-ietf_swima_attr_req.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ietf/swima/$(DEPDIR)/imcv_tests-ietf_swima_attr_sw_ev.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ietf/swima/$(DEPDIR)/imcv_tests-ietf_swima_attr_sw_inv.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at imc/$(DEPDIR)/imc_agent.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at imc/$(DEPDIR)/imc_msg.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at imc/$(DEPDIR)/imc_os_info.Plo at am__quote@
@@ -1351,6 +1494,7 @@ distclean-compile:
 @AMDEP_TRUE@@am__include@ @am__quote at pts/components/tcg/$(DEPDIR)/tcg_comp_func_name.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at pwg/$(DEPDIR)/pwg_attr.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at pwg/$(DEPDIR)/pwg_attr_vendor_smi_code.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at rest/$(DEPDIR)/rest.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at seg/$(DEPDIR)/imcv_tests-seg_contract.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at seg/$(DEPDIR)/imcv_tests-seg_contract_manager.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at seg/$(DEPDIR)/imcv_tests-seg_env.Po at am__quote@
@@ -1358,10 +1502,27 @@ distclean-compile:
 @AMDEP_TRUE@@am__include@ @am__quote at seg/$(DEPDIR)/seg_contract_manager.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at seg/$(DEPDIR)/seg_env.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at suites/$(DEPDIR)/imcv_tests-test_imcv_seg.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at suites/$(DEPDIR)/imcv_tests-test_imcv_swima.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at swid/$(DEPDIR)/swid_error.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at swid/$(DEPDIR)/swid_inventory.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at swid/$(DEPDIR)/swid_tag.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at swid/$(DEPDIR)/swid_tag_id.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at swid_gen/$(DEPDIR)/imcv_tests-swid_gen.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at swid_gen/$(DEPDIR)/swid_gen.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at swid_gen/$(DEPDIR)/swid_gen_info.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at swima/$(DEPDIR)/imcv_tests-swima_collector.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at swima/$(DEPDIR)/imcv_tests-swima_data_model.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at swima/$(DEPDIR)/imcv_tests-swima_event.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at swima/$(DEPDIR)/imcv_tests-swima_events.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at swima/$(DEPDIR)/imcv_tests-swima_inventory.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at swima/$(DEPDIR)/imcv_tests-swima_record.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at swima/$(DEPDIR)/swima_collector.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at swima/$(DEPDIR)/swima_data_model.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at swima/$(DEPDIR)/swima_error.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at swima/$(DEPDIR)/swima_event.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at swima/$(DEPDIR)/swima_events.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at swima/$(DEPDIR)/swima_inventory.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at swima/$(DEPDIR)/swima_record.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at tcg/$(DEPDIR)/tcg_attr.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at tcg/pts/$(DEPDIR)/tcg_pts_attr_aik.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at tcg/pts/$(DEPDIR)/tcg_pts_attr_dh_nonce_finish.Plo at am__quote@
@@ -1482,6 +1643,104 @@ seg/imcv_tests-seg_contract_manager.obj: seg/seg_contract_manager.c
 @AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
 @am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(imcv_tests_CFLAGS) $(CFLAGS) -c -o seg/imcv_tests-seg_contract_manager.obj `if test -f 'seg/seg_contract_manager.c'; then $(CYGPATH_W) 'seg/seg_contract_manager.c'; else $(CYGPATH_W) '$(srcdir)/seg/seg_contract_manager.c'; fi`
 
+swid_gen/imcv_tests-swid_gen.o: swid_gen/swid_gen.c
+ at am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(imcv_tests_CFLAGS) $(CFLAGS) -MT swid_gen/imcv_tests-swid_gen.o -MD -MP -MF swid_gen/$(DEPDIR)/imcv_tests-swid_gen.Tpo -c -o swid_gen/imcv_tests-swid_gen.o `test -f 'swid_gen/swid_gen.c' || echo '$(srcdir)/'`swid_gen/swid_gen.c
+ at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) swid_gen/$(DEPDIR)/imcv_tests-swid_gen.Tpo swid_gen/$(DEPDIR)/imcv_tests-swid_gen.Po
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='swid_gen/swid_gen.c' object='swid_gen/imcv_tests-swid_gen.o' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(imcv_tests_CFLAGS) $(CFLAGS) -c -o swid_gen/imcv_tests-swid_gen.o `test -f 'swid_gen/swid_gen.c' || echo '$(srcdir)/'`swid_gen/swid_gen.c
+
+swid_gen/imcv_tests-swid_gen.obj: swid_gen/swid_gen.c
+ at am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(imcv_tests_CFLAGS) $(CFLAGS) -MT swid_gen/imcv_tests-swid_gen.obj -MD -MP -MF swid_gen/$(DEPDIR)/imcv_tests-swid_gen.Tpo -c -o swid_gen/imcv_tests-swid_gen.obj `if test -f 'swid_gen/swid_gen.c'; then $(CYGPATH_W) 'swid_gen/swid_gen.c'; else $(CYGPATH_W) '$(srcdir)/swid_gen/swid_gen.c'; fi`
+ at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) swid_gen/$(DEPDIR)/imcv_tests-swid_gen.Tpo swid_gen/$(DEPDIR)/imcv_tests-swid_gen.Po
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='swid_gen/swid_gen.c' object='swid_gen/imcv_tests-swid_gen.obj' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(imcv_tests_CFLAGS) $(CFLAGS) -c -o swid_gen/imcv_tests-swid_gen.obj `if test -f 'swid_gen/swid_gen.c'; then $(CYGPATH_W) 'swid_gen/swid_gen.c'; else $(CYGPATH_W) '$(srcdir)/swid_gen/swid_gen.c'; fi`
+
+swima/imcv_tests-swima_data_model.o: swima/swima_data_model.c
+ at am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(imcv_tests_CFLAGS) $(CFLAGS) -MT swima/imcv_tests-swima_data_model.o -MD -MP -MF swima/$(DEPDIR)/imcv_tests-swima_data_model.Tpo -c -o swima/imcv_tests-swima_data_model.o `test -f 'swima/swima_data_model.c' || echo '$(srcdir)/'`swima/swima_data_model.c
+ at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) swima/$(DEPDIR)/imcv_tests-swima_data_model.Tpo swima/$(DEPDIR)/imcv_tests-swima_data_model.Po
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='swima/swima_data_model.c' object='swima/imcv_tests-swima_data_model.o' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(imcv_tests_CFLAGS) $(CFLAGS) -c -o swima/imcv_tests-swima_data_model.o `test -f 'swima/swima_data_model.c' || echo '$(srcdir)/'`swima/swima_data_model.c
+
+swima/imcv_tests-swima_data_model.obj: swima/swima_data_model.c
+ at am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(imcv_tests_CFLAGS) $(CFLAGS) -MT swima/imcv_tests-swima_data_model.obj -MD -MP -MF swima/$(DEPDIR)/imcv_tests-swima_data_model.Tpo -c -o swima/imcv_tests-swima_data_model.obj `if test -f 'swima/swima_data_model.c'; then $(CYGPATH_W) 'swima/swima_data_model.c'; else $(CYGPATH_W) '$(srcdir)/swima/swima_data_model.c'; fi`
+ at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) swima/$(DEPDIR)/imcv_tests-swima_data_model.Tpo swima/$(DEPDIR)/imcv_tests-swima_data_model.Po
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='swima/swima_data_model.c' object='swima/imcv_tests-swima_data_model.obj' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(imcv_tests_CFLAGS) $(CFLAGS) -c -o swima/imcv_tests-swima_data_model.obj `if test -f 'swima/swima_data_model.c'; then $(CYGPATH_W) 'swima/swima_data_model.c'; else $(CYGPATH_W) '$(srcdir)/swima/swima_data_model.c'; fi`
+
+swima/imcv_tests-swima_event.o: swima/swima_event.c
+ at am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(imcv_tests_CFLAGS) $(CFLAGS) -MT swima/imcv_tests-swima_event.o -MD -MP -MF swima/$(DEPDIR)/imcv_tests-swima_event.Tpo -c -o swima/imcv_tests-swima_event.o `test -f 'swima/swima_event.c' || echo '$(srcdir)/'`swima/swima_event.c
+ at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) swima/$(DEPDIR)/imcv_tests-swima_event.Tpo swima/$(DEPDIR)/imcv_tests-swima_event.Po
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='swima/swima_event.c' object='swima/imcv_tests-swima_event.o' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(imcv_tests_CFLAGS) $(CFLAGS) -c -o swima/imcv_tests-swima_event.o `test -f 'swima/swima_event.c' || echo '$(srcdir)/'`swima/swima_event.c
+
+swima/imcv_tests-swima_event.obj: swima/swima_event.c
+ at am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(imcv_tests_CFLAGS) $(CFLAGS) -MT swima/imcv_tests-swima_event.obj -MD -MP -MF swima/$(DEPDIR)/imcv_tests-swima_event.Tpo -c -o swima/imcv_tests-swima_event.obj `if test -f 'swima/swima_event.c'; then $(CYGPATH_W) 'swima/swima_event.c'; else $(CYGPATH_W) '$(srcdir)/swima/swima_event.c'; fi`
+ at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) swima/$(DEPDIR)/imcv_tests-swima_event.Tpo swima/$(DEPDIR)/imcv_tests-swima_event.Po
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='swima/swima_event.c' object='swima/imcv_tests-swima_event.obj' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(imcv_tests_CFLAGS) $(CFLAGS) -c -o swima/imcv_tests-swima_event.obj `if test -f 'swima/swima_event.c'; then $(CYGPATH_W) 'swima/swima_event.c'; else $(CYGPATH_W) '$(srcdir)/swima/swima_event.c'; fi`
+
+swima/imcv_tests-swima_events.o: swima/swima_events.c
+ at am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(imcv_tests_CFLAGS) $(CFLAGS) -MT swima/imcv_tests-swima_events.o -MD -MP -MF swima/$(DEPDIR)/imcv_tests-swima_events.Tpo -c -o swima/imcv_tests-swima_events.o `test -f 'swima/swima_events.c' || echo '$(srcdir)/'`swima/swima_events.c
+ at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) swima/$(DEPDIR)/imcv_tests-swima_events.Tpo swima/$(DEPDIR)/imcv_tests-swima_events.Po
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='swima/swima_events.c' object='swima/imcv_tests-swima_events.o' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(imcv_tests_CFLAGS) $(CFLAGS) -c -o swima/imcv_tests-swima_events.o `test -f 'swima/swima_events.c' || echo '$(srcdir)/'`swima/swima_events.c
+
+swima/imcv_tests-swima_events.obj: swima/swima_events.c
+ at am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(imcv_tests_CFLAGS) $(CFLAGS) -MT swima/imcv_tests-swima_events.obj -MD -MP -MF swima/$(DEPDIR)/imcv_tests-swima_events.Tpo -c -o swima/imcv_tests-swima_events.obj `if test -f 'swima/swima_events.c'; then $(CYGPATH_W) 'swima/swima_events.c'; else $(CYGPATH_W) '$(srcdir)/swima/swima_events.c'; fi`
+ at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) swima/$(DEPDIR)/imcv_tests-swima_events.Tpo swima/$(DEPDIR)/imcv_tests-swima_events.Po
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='swima/swima_events.c' object='swima/imcv_tests-swima_events.obj' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(imcv_tests_CFLAGS) $(CFLAGS) -c -o swima/imcv_tests-swima_events.obj `if test -f 'swima/swima_events.c'; then $(CYGPATH_W) 'swima/swima_events.c'; else $(CYGPATH_W) '$(srcdir)/swima/swima_events.c'; fi`
+
+swima/imcv_tests-swima_record.o: swima/swima_record.c
+ at am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(imcv_tests_CFLAGS) $(CFLAGS) -MT swima/imcv_tests-swima_record.o -MD -MP -MF swima/$(DEPDIR)/imcv_tests-swima_record.Tpo -c -o swima/imcv_tests-swima_record.o `test -f 'swima/swima_record.c' || echo '$(srcdir)/'`swima/swima_record.c
+ at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) swima/$(DEPDIR)/imcv_tests-swima_record.Tpo swima/$(DEPDIR)/imcv_tests-swima_record.Po
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='swima/swima_record.c' object='swima/imcv_tests-swima_record.o' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(imcv_tests_CFLAGS) $(CFLAGS) -c -o swima/imcv_tests-swima_record.o `test -f 'swima/swima_record.c' || echo '$(srcdir)/'`swima/swima_record.c
+
+swima/imcv_tests-swima_record.obj: swima/swima_record.c
+ at am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(imcv_tests_CFLAGS) $(CFLAGS) -MT swima/imcv_tests-swima_record.obj -MD -MP -MF swima/$(DEPDIR)/imcv_tests-swima_record.Tpo -c -o swima/imcv_tests-swima_record.obj `if test -f 'swima/swima_record.c'; then $(CYGPATH_W) 'swima/swima_record.c'; else $(CYGPATH_W) '$(srcdir)/swima/swima_record.c'; fi`
+ at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) swima/$(DEPDIR)/imcv_tests-swima_record.Tpo swima/$(DEPDIR)/imcv_tests-swima_record.Po
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='swima/swima_record.c' object='swima/imcv_tests-swima_record.obj' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(imcv_tests_CFLAGS) $(CFLAGS) -c -o swima/imcv_tests-swima_record.obj `if test -f 'swima/swima_record.c'; then $(CYGPATH_W) 'swima/swima_record.c'; else $(CYGPATH_W) '$(srcdir)/swima/swima_record.c'; fi`
+
+swima/imcv_tests-swima_inventory.o: swima/swima_inventory.c
+ at am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(imcv_tests_CFLAGS) $(CFLAGS) -MT swima/imcv_tests-swima_inventory.o -MD -MP -MF swima/$(DEPDIR)/imcv_tests-swima_inventory.Tpo -c -o swima/imcv_tests-swima_inventory.o `test -f 'swima/swima_inventory.c' || echo '$(srcdir)/'`swima/swima_inventory.c
+ at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) swima/$(DEPDIR)/imcv_tests-swima_inventory.Tpo swima/$(DEPDIR)/imcv_tests-swima_inventory.Po
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='swima/swima_inventory.c' object='swima/imcv_tests-swima_inventory.o' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(imcv_tests_CFLAGS) $(CFLAGS) -c -o swima/imcv_tests-swima_inventory.o `test -f 'swima/swima_inventory.c' || echo '$(srcdir)/'`swima/swima_inventory.c
+
+swima/imcv_tests-swima_inventory.obj: swima/swima_inventory.c
+ at am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(imcv_tests_CFLAGS) $(CFLAGS) -MT swima/imcv_tests-swima_inventory.obj -MD -MP -MF swima/$(DEPDIR)/imcv_tests-swima_inventory.Tpo -c -o swima/imcv_tests-swima_inventory.obj `if test -f 'swima/swima_inventory.c'; then $(CYGPATH_W) 'swima/swima_inventory.c'; else $(CYGPATH_W) '$(srcdir)/swima/swima_inventory.c'; fi`
+ at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) swima/$(DEPDIR)/imcv_tests-swima_inventory.Tpo swima/$(DEPDIR)/imcv_tests-swima_inventory.Po
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='swima/swima_inventory.c' object='swima/imcv_tests-swima_inventory.obj' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(imcv_tests_CFLAGS) $(CFLAGS) -c -o swima/imcv_tests-swima_inventory.obj `if test -f 'swima/swima_inventory.c'; then $(CYGPATH_W) 'swima/swima_inventory.c'; else $(CYGPATH_W) '$(srcdir)/swima/swima_inventory.c'; fi`
+
+swima/imcv_tests-swima_collector.o: swima/swima_collector.c
+ at am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(imcv_tests_CFLAGS) $(CFLAGS) -MT swima/imcv_tests-swima_collector.o -MD -MP -MF swima/$(DEPDIR)/imcv_tests-swima_collector.Tpo -c -o swima/imcv_tests-swima_collector.o `test -f 'swima/swima_collector.c' || echo '$(srcdir)/'`swima/swima_collector.c
+ at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) swima/$(DEPDIR)/imcv_tests-swima_collector.Tpo swima/$(DEPDIR)/imcv_tests-swima_collector.Po
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='swima/swima_collector.c' object='swima/imcv_tests-swima_collector.o' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(imcv_tests_CFLAGS) $(CFLAGS) -c -o swima/imcv_tests-swima_collector.o `test -f 'swima/swima_collector.c' || echo '$(srcdir)/'`swima/swima_collector.c
+
+swima/imcv_tests-swima_collector.obj: swima/swima_collector.c
+ at am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(imcv_tests_CFLAGS) $(CFLAGS) -MT swima/imcv_tests-swima_collector.obj -MD -MP -MF swima/$(DEPDIR)/imcv_tests-swima_collector.Tpo -c -o swima/imcv_tests-swima_collector.obj `if test -f 'swima/swima_collector.c'; then $(CYGPATH_W) 'swima/swima_collector.c'; else $(CYGPATH_W) '$(srcdir)/swima/swima_collector.c'; fi`
+ at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) swima/$(DEPDIR)/imcv_tests-swima_collector.Tpo swima/$(DEPDIR)/imcv_tests-swima_collector.Po
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='swima/swima_collector.c' object='swima/imcv_tests-swima_collector.obj' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(imcv_tests_CFLAGS) $(CFLAGS) -c -o swima/imcv_tests-swima_collector.obj `if test -f 'swima/swima_collector.c'; then $(CYGPATH_W) 'swima/swima_collector.c'; else $(CYGPATH_W) '$(srcdir)/swima/swima_collector.c'; fi`
+
 suites/imcv_tests-test_imcv_seg.o: suites/test_imcv_seg.c
 @am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(imcv_tests_CFLAGS) $(CFLAGS) -MT suites/imcv_tests-test_imcv_seg.o -MD -MP -MF suites/$(DEPDIR)/imcv_tests-test_imcv_seg.Tpo -c -o suites/imcv_tests-test_imcv_seg.o `test -f 'suites/test_imcv_seg.c' || echo '$(srcdir)/'`suites/test_imcv_seg.c
 @am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) suites/$(DEPDIR)/imcv_tests-test_imcv_seg.Tpo suites/$(DEPDIR)/imcv_tests-test_imcv_seg.Po
@@ -1496,6 +1755,20 @@ suites/imcv_tests-test_imcv_seg.obj: suites/test_imcv_seg.c
 @AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
 @am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(imcv_tests_CFLAGS) $(CFLAGS) -c -o suites/imcv_tests-test_imcv_seg.obj `if test -f 'suites/test_imcv_seg.c'; then $(CYGPATH_W) 'suites/test_imcv_seg.c'; else $(CYGPATH_W) '$(srcdir)/suites/test_imcv_seg.c'; fi`
 
+suites/imcv_tests-test_imcv_swima.o: suites/test_imcv_swima.c
+ at am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(imcv_tests_CFLAGS) $(CFLAGS) -MT suites/imcv_tests-test_imcv_swima.o -MD -MP -MF suites/$(DEPDIR)/imcv_tests-test_imcv_swima.Tpo -c -o suites/imcv_tests-test_imcv_swima.o `test -f 'suites/test_imcv_swima.c' || echo '$(srcdir)/'`suites/test_imcv_swima.c
+ at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) suites/$(DEPDIR)/imcv_tests-test_imcv_swima.Tpo suites/$(DEPDIR)/imcv_tests-test_imcv_swima.Po
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='suites/test_imcv_swima.c' object='suites/imcv_tests-test_imcv_swima.o' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(imcv_tests_CFLAGS) $(CFLAGS) -c -o suites/imcv_tests-test_imcv_swima.o `test -f 'suites/test_imcv_swima.c' || echo '$(srcdir)/'`suites/test_imcv_swima.c
+
+suites/imcv_tests-test_imcv_swima.obj: suites/test_imcv_swima.c
+ at am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(imcv_tests_CFLAGS) $(CFLAGS) -MT suites/imcv_tests-test_imcv_swima.obj -MD -MP -MF suites/$(DEPDIR)/imcv_tests-test_imcv_swima.Tpo -c -o suites/imcv_tests-test_imcv_swima.obj `if test -f 'suites/test_imcv_swima.c'; then $(CYGPATH_W) 'suites/test_imcv_swima.c'; else $(CYGPATH_W) '$(srcdir)/suites/test_imcv_swima.c'; fi`
+ at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) suites/$(DEPDIR)/imcv_tests-test_imcv_swima.Tpo suites/$(DEPDIR)/imcv_tests-test_imcv_swima.Po
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='suites/test_imcv_swima.c' object='suites/imcv_tests-test_imcv_swima.obj' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(imcv_tests_CFLAGS) $(CFLAGS) -c -o suites/imcv_tests-test_imcv_swima.obj `if test -f 'suites/test_imcv_swima.c'; then $(CYGPATH_W) 'suites/test_imcv_swima.c'; else $(CYGPATH_W) '$(srcdir)/suites/test_imcv_swima.c'; fi`
+
 ietf/imcv_tests-ietf_attr_pa_tnc_error.o: ietf/ietf_attr_pa_tnc_error.c
 @am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(imcv_tests_CFLAGS) $(CFLAGS) -MT ietf/imcv_tests-ietf_attr_pa_tnc_error.o -MD -MP -MF ietf/$(DEPDIR)/imcv_tests-ietf_attr_pa_tnc_error.Tpo -c -o ietf/imcv_tests-ietf_attr_pa_tnc_error.o `test -f 'ietf/ietf_attr_pa_tnc_error.c' || echo '$(srcdir)/'`ietf/ietf_attr_pa_tnc_error.c
 @am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) ietf/$(DEPDIR)/imcv_tests-ietf_attr_pa_tnc_error.Tpo ietf/$(DEPDIR)/imcv_tests-ietf_attr_pa_tnc_error.Po
@@ -1510,6 +1783,48 @@ ietf/imcv_tests-ietf_attr_pa_tnc_error.obj: ietf/ietf_attr_pa_tnc_error.c
 @AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
 @am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(imcv_tests_CFLAGS) $(CFLAGS) -c -o ietf/imcv_tests-ietf_attr_pa_tnc_error.obj `if test -f 'ietf/ietf_attr_pa_tnc_error.c'; then $(CYGPATH_W) 'ietf/ietf_attr_pa_tnc_error.c'; else $(CYGPATH_W) '$(srcdir)/ietf/ietf_attr_pa_tnc_error.c'; fi`
 
+ietf/swima/imcv_tests-ietf_swima_attr_req.o: ietf/swima/ietf_swima_attr_req.c
+ at am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(imcv_tests_CFLAGS) $(CFLAGS) -MT ietf/swima/imcv_tests-ietf_swima_attr_req.o -MD -MP -MF ietf/swima/$(DEPDIR)/imcv_tests-ietf_swima_attr_req.Tpo -c -o ietf/swima/imcv_tests-ietf_swima_attr_req.o `test -f 'ietf/swima/ietf_swima_attr_req.c' || echo '$(srcdir)/'`ietf/swima/ietf_swima_attr_req.c
+ at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) ietf/swima/$(DEPDIR)/imcv_tests-ietf_swima_attr_req.Tpo ietf/swima/$(DEPDIR)/imcv_tests-ietf_swima_attr_req.Po
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='ietf/swima/ietf_swima_attr_req.c' object='ietf/swima/imcv_tests-ietf_swima_attr_req.o' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(imcv_tests_CFLAGS) $(CFLAGS) -c -o ietf/swima/imcv_tests-ietf_swima_attr_req.o `test -f 'ietf/swima/ietf_swima_attr_req.c' || echo '$(srcdir)/'`ietf/swima/ietf_swima_attr_req.c
+
+ietf/swima/imcv_tests-ietf_swima_attr_req.obj: ietf/swima/ietf_swima_attr_req.c
+ at am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(imcv_tests_CFLAGS) $(CFLAGS) -MT ietf/swima/imcv_tests-ietf_swima_attr_req.obj -MD -MP -MF ietf/swima/$(DEPDIR)/imcv_tests-ietf_swima_attr_req.Tpo -c -o ietf/swima/imcv_tests-ietf_swima_attr_req.obj `if test -f 'ietf/swima/ietf_swima_attr_req.c'; then $(CYGPATH_W) 'ietf/swima/ietf_swima_attr_req.c'; else $(CYGPATH_W) '$(srcdir)/ietf/swima/ietf_swima_attr_req.c'; fi`
+ at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) ietf/swima/$(DEPDIR)/imcv_tests-ietf_swima_attr_req.Tpo ietf/swima/$(DEPDIR)/imcv_tests-ietf_swima_attr_req.Po
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='ietf/swima/ietf_swima_attr_req.c' object='ietf/swima/imcv_tests-ietf_swima_attr_req.obj' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(imcv_tests_CFLAGS) $(CFLAGS) -c -o ietf/swima/imcv_tests-ietf_swima_attr_req.obj `if test -f 'ietf/swima/ietf_swima_attr_req.c'; then $(CYGPATH_W) 'ietf/swima/ietf_swima_attr_req.c'; else $(CYGPATH_W) '$(srcdir)/ietf/swima/ietf_swima_attr_req.c'; fi`
+
+ietf/swima/imcv_tests-ietf_swima_attr_sw_inv.o: ietf/swima/ietf_swima_attr_sw_inv.c
+ at am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(imcv_tests_CFLAGS) $(CFLAGS) -MT ietf/swima/imcv_tests-ietf_swima_attr_sw_inv.o -MD -MP -MF ietf/swima/$(DEPDIR)/imcv_tests-ietf_swima_attr_sw_inv.Tpo -c -o ietf/swima/imcv_tests-ietf_swima_attr_sw_inv.o `test -f 'ietf/swima/ietf_swima_attr_sw_inv.c' || echo '$(srcdir)/'`ietf/swima/ietf_swima_attr_sw_inv.c
+ at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) ietf/swima/$(DEPDIR)/imcv_tests-ietf_swima_attr_sw_inv.Tpo ietf/swima/$(DEPDIR)/imcv_tests-ietf_swima_attr_sw_inv.Po
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='ietf/swima/ietf_swima_attr_sw_inv.c' object='ietf/swima/imcv_tests-ietf_swima_attr_sw_inv.o' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(imcv_tests_CFLAGS) $(CFLAGS) -c -o ietf/swima/imcv_tests-ietf_swima_attr_sw_inv.o `test -f 'ietf/swima/ietf_swima_attr_sw_inv.c' || echo '$(srcdir)/'`ietf/swima/ietf_swima_attr_sw_inv.c
+
+ietf/swima/imcv_tests-ietf_swima_attr_sw_inv.obj: ietf/swima/ietf_swima_attr_sw_inv.c
+ at am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(imcv_tests_CFLAGS) $(CFLAGS) -MT ietf/swima/imcv_tests-ietf_swima_attr_sw_inv.obj -MD -MP -MF ietf/swima/$(DEPDIR)/imcv_tests-ietf_swima_attr_sw_inv.Tpo -c -o ietf/swima/imcv_tests-ietf_swima_attr_sw_inv.obj `if test -f 'ietf/swima/ietf_swima_attr_sw_inv.c'; then $(CYGPATH_W) 'ietf/swima/ietf_swima_attr_sw_inv.c'; else $(CYGPATH_W) '$(srcdir)/ietf/swima/ietf_swima_attr_sw_inv.c'; fi`
+ at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) ietf/swima/$(DEPDIR)/imcv_tests-ietf_swima_attr_sw_inv.Tpo ietf/swima/$(DEPDIR)/imcv_tests-ietf_swima_attr_sw_inv.Po
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='ietf/swima/ietf_swima_attr_sw_inv.c' object='ietf/swima/imcv_tests-ietf_swima_attr_sw_inv.obj' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(imcv_tests_CFLAGS) $(CFLAGS) -c -o ietf/swima/imcv_tests-ietf_swima_attr_sw_inv.obj `if test -f 'ietf/swima/ietf_swima_attr_sw_inv.c'; then $(CYGPATH_W) 'ietf/swima/ietf_swima_attr_sw_inv.c'; else $(CYGPATH_W) '$(srcdir)/ietf/swima/ietf_swima_attr_sw_inv.c'; fi`
+
+ietf/swima/imcv_tests-ietf_swima_attr_sw_ev.o: ietf/swima/ietf_swima_attr_sw_ev.c
+ at am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(imcv_tests_CFLAGS) $(CFLAGS) -MT ietf/swima/imcv_tests-ietf_swima_attr_sw_ev.o -MD -MP -MF ietf/swima/$(DEPDIR)/imcv_tests-ietf_swima_attr_sw_ev.Tpo -c -o ietf/swima/imcv_tests-ietf_swima_attr_sw_ev.o `test -f 'ietf/swima/ietf_swima_attr_sw_ev.c' || echo '$(srcdir)/'`ietf/swima/ietf_swima_attr_sw_ev.c
+ at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) ietf/swima/$(DEPDIR)/imcv_tests-ietf_swima_attr_sw_ev.Tpo ietf/swima/$(DEPDIR)/imcv_tests-ietf_swima_attr_sw_ev.Po
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='ietf/swima/ietf_swima_attr_sw_ev.c' object='ietf/swima/imcv_tests-ietf_swima_attr_sw_ev.o' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(imcv_tests_CFLAGS) $(CFLAGS) -c -o ietf/swima/imcv_tests-ietf_swima_attr_sw_ev.o `test -f 'ietf/swima/ietf_swima_attr_sw_ev.c' || echo '$(srcdir)/'`ietf/swima/ietf_swima_attr_sw_ev.c
+
+ietf/swima/imcv_tests-ietf_swima_attr_sw_ev.obj: ietf/swima/ietf_swima_attr_sw_ev.c
+ at am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(imcv_tests_CFLAGS) $(CFLAGS) -MT ietf/swima/imcv_tests-ietf_swima_attr_sw_ev.obj -MD -MP -MF ietf/swima/$(DEPDIR)/imcv_tests-ietf_swima_attr_sw_ev.Tpo -c -o ietf/swima/imcv_tests-ietf_swima_attr_sw_ev.obj `if test -f 'ietf/swima/ietf_swima_attr_sw_ev.c'; then $(CYGPATH_W) 'ietf/swima/ietf_swima_attr_sw_ev.c'; else $(CYGPATH_W) '$(srcdir)/ietf/swima/ietf_swima_attr_sw_ev.c'; fi`
+ at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) ietf/swima/$(DEPDIR)/imcv_tests-ietf_swima_attr_sw_ev.Tpo ietf/swima/$(DEPDIR)/imcv_tests-ietf_swima_attr_sw_ev.Po
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='ietf/swima/ietf_swima_attr_sw_ev.c' object='ietf/swima/imcv_tests-ietf_swima_attr_sw_ev.obj' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(imcv_tests_CFLAGS) $(CFLAGS) -c -o ietf/swima/imcv_tests-ietf_swima_attr_sw_ev.obj `if test -f 'ietf/swima/ietf_swima_attr_sw_ev.c'; then $(CYGPATH_W) 'ietf/swima/ietf_swima_attr_sw_ev.c'; else $(CYGPATH_W) '$(srcdir)/ietf/swima/ietf_swima_attr_sw_ev.c'; fi`
+
 tcg/seg/imcv_tests-tcg_seg_attr_seg_env.o: tcg/seg/tcg_seg_attr_seg_env.c
 @am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(imcv_tests_CFLAGS) $(CFLAGS) -MT tcg/seg/imcv_tests-tcg_seg_attr_seg_env.o -MD -MP -MF tcg/seg/$(DEPDIR)/imcv_tests-tcg_seg_attr_seg_env.Tpo -c -o tcg/seg/imcv_tests-tcg_seg_attr_seg_env.o `test -f 'tcg/seg/tcg_seg_attr_seg_env.c' || echo '$(srcdir)/'`tcg/seg/tcg_seg_attr_seg_env.c
 @am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) tcg/seg/$(DEPDIR)/imcv_tests-tcg_seg_attr_seg_env.Tpo tcg/seg/$(DEPDIR)/imcv_tests-tcg_seg_attr_seg_env.Po
@@ -1559,6 +1874,7 @@ clean-libtool:
 	-rm -rf .libs _libs
 	-rm -rf generic/.libs generic/_libs
 	-rm -rf ietf/.libs ietf/_libs
+	-rm -rf ietf/swima/.libs ietf/swima/_libs
 	-rm -rf imc/.libs imc/_libs
 	-rm -rf imv/.libs imv/_libs
 	-rm -rf ita/.libs ita/_libs
@@ -1569,8 +1885,11 @@ clean-libtool:
 	-rm -rf pts/components/ita/.libs pts/components/ita/_libs
 	-rm -rf pts/components/tcg/.libs pts/components/tcg/_libs
 	-rm -rf pwg/.libs pwg/_libs
+	-rm -rf rest/.libs rest/_libs
 	-rm -rf seg/.libs seg/_libs
 	-rm -rf swid/.libs swid/_libs
+	-rm -rf swid_gen/.libs swid_gen/_libs
+	-rm -rf swima/.libs swima/_libs
 	-rm -rf tcg/.libs tcg/_libs
 	-rm -rf tcg/pts/.libs tcg/pts/_libs
 	-rm -rf tcg/seg/.libs tcg/seg/_libs
@@ -1884,6 +2203,8 @@ distclean-generic:
 	-rm -f generic/$(am__dirstamp)
 	-rm -f ietf/$(DEPDIR)/$(am__dirstamp)
 	-rm -f ietf/$(am__dirstamp)
+	-rm -f ietf/swima/$(DEPDIR)/$(am__dirstamp)
+	-rm -f ietf/swima/$(am__dirstamp)
 	-rm -f imc/$(DEPDIR)/$(am__dirstamp)
 	-rm -f imc/$(am__dirstamp)
 	-rm -f imv/$(DEPDIR)/$(am__dirstamp)
@@ -1904,12 +2225,18 @@ distclean-generic:
 	-rm -f pts/components/tcg/$(am__dirstamp)
 	-rm -f pwg/$(DEPDIR)/$(am__dirstamp)
 	-rm -f pwg/$(am__dirstamp)
+	-rm -f rest/$(DEPDIR)/$(am__dirstamp)
+	-rm -f rest/$(am__dirstamp)
 	-rm -f seg/$(DEPDIR)/$(am__dirstamp)
 	-rm -f seg/$(am__dirstamp)
 	-rm -f suites/$(DEPDIR)/$(am__dirstamp)
 	-rm -f suites/$(am__dirstamp)
 	-rm -f swid/$(DEPDIR)/$(am__dirstamp)
 	-rm -f swid/$(am__dirstamp)
+	-rm -f swid_gen/$(DEPDIR)/$(am__dirstamp)
+	-rm -f swid_gen/$(am__dirstamp)
+	-rm -f swima/$(DEPDIR)/$(am__dirstamp)
+	-rm -f swima/$(am__dirstamp)
 	-rm -f tcg/$(DEPDIR)/$(am__dirstamp)
 	-rm -f tcg/$(am__dirstamp)
 	-rm -f tcg/pts/$(DEPDIR)/$(am__dirstamp)
@@ -1928,7 +2255,7 @@ clean-am: clean-checkPROGRAMS clean-generic clean-ipsecPROGRAMS \
 	clean-ipseclibLTLIBRARIES clean-libtool mostlyclean-am
 
 distclean: distclean-recursive
-	-rm -rf ./$(DEPDIR) generic/$(DEPDIR) ietf/$(DEPDIR) imc/$(DEPDIR) imv/$(DEPDIR) ita/$(DEPDIR) os_info/$(DEPDIR) pa_tnc/$(DEPDIR) pts/$(DEPDIR) pts/components/$(DEPDIR) pts/components/ita/$(DEPDIR) pts/components/tcg/$(DEPDIR) pwg/$(DEPDIR) seg/$(DEPDIR) suites/$(DEPDIR) swid/$(DEPDIR) tcg/$(DEPDIR) tcg/pts/$(DEPDIR) tcg/seg/$(DEPDIR) tcg/swid/$(DEPDIR)
+	-rm -rf ./$(DEPDIR) generic/$(DEPDIR) ietf/$(DEPDIR) ietf/swima/$(DEPDIR) imc/$(DEPDIR) imv/$(DEPDIR) ita/$(DEPDIR) os_info/$(DEPDIR) pa_tnc/$(DEPDIR) pts/$(DEPDIR) pts/components/$(DEPDIR) pts/components/ita/$(DEPDIR) pts/components/tcg/$(DEPDIR) pwg/$(DEPDIR) rest/$(DEPDIR) seg/$(DEPDIR) suites/$(DEPDIR) swid/$(DEPDIR) swid_gen/$(DEPDIR) swima/$(DEPDIR) tcg/$(DEPDIR) tcg/pts/$(DEPDIR) tcg/seg/$(DEPDIR) tcg/swid/$(DEPDIR)
 	-rm -f Makefile
 distclean-am: clean-am distclean-compile distclean-generic \
 	distclean-tags
@@ -1975,7 +2302,7 @@ install-ps-am:
 installcheck-am:
 
 maintainer-clean: maintainer-clean-recursive
-	-rm -rf ./$(DEPDIR) generic/$(DEPDIR) ietf/$(DEPDIR) imc/$(DEPDIR) imv/$(DEPDIR) ita/$(DEPDIR) os_info/$(DEPDIR) pa_tnc/$(DEPDIR) pts/$(DEPDIR) pts/components/$(DEPDIR) pts/components/ita/$(DEPDIR) pts/components/tcg/$(DEPDIR) pwg/$(DEPDIR) seg/$(DEPDIR) suites/$(DEPDIR) swid/$(DEPDIR) tcg/$(DEPDIR) tcg/pts/$(DEPDIR) tcg/seg/$(DEPDIR) tcg/swid/$(DEPDIR)
+	-rm -rf ./$(DEPDIR) generic/$(DEPDIR) ietf/$(DEPDIR) ietf/swima/$(DEPDIR) imc/$(DEPDIR) imv/$(DEPDIR) ita/$(DEPDIR) os_info/$(DEPDIR) pa_tnc/$(DEPDIR) pts/$(DEPDIR) pts/components/$(DEPDIR) pts/components/ita/$(DEPDIR) pts/components/tcg/$(DEPDIR) pwg/$(DEPDIR) rest/$(DEPDIR) seg/$(DEPDIR) suites/$(DEPDIR) swid/$(DEPDIR) swid_gen/$(DEPDIR) swima/$(DEPDIR) tcg/$(DEPDIR) tcg/pts/$(DEPDIR) tcg/seg/$(DEPDIR) tcg/swid/$(DEPDIR)
 	-rm -f Makefile
 maintainer-clean-am: distclean-am maintainer-clean-generic
 
diff --git a/src/libimcv/ietf/ietf_attr.c b/src/libimcv/ietf/ietf_attr.c
index cfac6ed..9e3e83d 100644
--- a/src/libimcv/ietf/ietf_attr.c
+++ b/src/libimcv/ietf/ietf_attr.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2011-2015 Andreas Steffen
+ * Copyright (C) 2011-2017 Andreas Steffen
  * HSR Hochschule fuer Technik Rapperswil
  *
  * This program is free software; you can redistribute it and/or modify it
@@ -25,10 +25,14 @@
 #include "ietf/ietf_attr_product_info.h"
 #include "ietf/ietf_attr_remediation_instr.h"
 #include "ietf/ietf_attr_string_version.h"
+#include "ietf/swima/ietf_swima_attr_req.h"
+#include "ietf/swima/ietf_swima_attr_sw_inv.h"
+#include "ietf/swima/ietf_swima_attr_sw_ev.h"
 #include "generic/generic_attr_bool.h"
 
 
-ENUM(ietf_attr_names, IETF_ATTR_TESTING, IETF_ATTR_FACTORY_DEFAULT_PWD_ENABLED,
+ENUM_BEGIN(ietf_attr_names, IETF_ATTR_TESTING,
+							IETF_ATTR_FACTORY_DEFAULT_PWD_ENABLED,
 	"Testing",
 	"Attribute Request",
 	"Product Information",
@@ -43,6 +47,20 @@ ENUM(ietf_attr_names, IETF_ATTR_TESTING, IETF_ATTR_FACTORY_DEFAULT_PWD_ENABLED,
 	"Forwarding Enabled",
 	"Factory Default Password Enabled",
 );
+ENUM_NEXT(ietf_attr_names,  IETF_ATTR_SW_REQUEST,
+							IETF_ATTR_SRC_METADATA_RESP,
+							IETF_ATTR_FACTORY_DEFAULT_PWD_ENABLED,
+	"SW Request",
+	"SW Identifier Inventory",
+	"SW Identifier Events",
+	"SW Inventory",
+	"SW Events",
+	"SW Subscription Status Request",
+	"SW Subscription Status Response",
+	"SW Source Metadata Request",
+	"SW Source Metadata Response",
+);
+ENUM_END(ietf_attr_names,	IETF_ATTR_SRC_METADATA_RESP);
 
 /**
  * See header
@@ -79,8 +97,23 @@ pa_tnc_attr_t* ietf_attr_create_from_data(uint32_t type, size_t length,
 		case IETF_ATTR_FACTORY_DEFAULT_PWD_ENABLED:
 			return generic_attr_bool_create_from_data(length, value,
 									pen_type_create(PEN_IETF, type));
+		case IETF_ATTR_SW_REQUEST:
+			return ietf_swima_attr_req_create_from_data(length, value);
+		case IETF_ATTR_SW_ID_INVENTORY:
+			return ietf_swima_attr_sw_inv_create_from_data(length, value, TRUE);
+		case IETF_ATTR_SW_INVENTORY:
+			return ietf_swima_attr_sw_inv_create_from_data(length, value, FALSE);
+		case IETF_ATTR_SW_ID_EVENTS:
+			return ietf_swima_attr_sw_ev_create_from_data(length, value, TRUE);
+		case IETF_ATTR_SW_EVENTS:
+			return ietf_swima_attr_sw_ev_create_from_data(length, value, FALSE);
 		case IETF_ATTR_TESTING:
 		case IETF_ATTR_RESERVED:
+		/* unsupported IETF/SWIMA attributes */
+		case IETF_ATTR_SUBSCRIPTION_STATUS_REQ:
+		case IETF_ATTR_SUBSCRIPTION_STATUS_RESP:
+		case IETF_ATTR_SRC_METADATA_REQ:
+		case IETF_ATTR_SRC_METADATA_RESP:
 		default:
 			return NULL;
 	}
diff --git a/src/libimcv/ietf/ietf_attr.h b/src/libimcv/ietf/ietf_attr.h
index 7154674..d2ea982 100644
--- a/src/libimcv/ietf/ietf_attr.h
+++ b/src/libimcv/ietf/ietf_attr.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2011-2014 Andreas Steffen
+ * Copyright (C) 2011-2017 Andreas Steffen
  * HSR Hochschule fuer Technik Rapperswil
  *
  * This program is free software; you can redistribute it and/or modify it
@@ -28,9 +28,11 @@
 typedef enum ietf_attr_t ietf_attr_t;
 
 /**
- * IETF standard PA-TNC attribute types defined by RFC 5792
+ * IETF standard PA-TNC attribute types
  */
 enum ietf_attr_t {
+
+	/* RFC 5792 */
 	IETF_ATTR_TESTING =                            0,
 	IETF_ATTR_ATTRIBUTE_REQUEST =                  1,
 	IETF_ATTR_PRODUCT_INFORMATION =                2,
@@ -44,6 +46,18 @@ enum ietf_attr_t {
 	IETF_ATTR_REMEDIATION_INSTRUCTIONS =          10,
 	IETF_ATTR_FORWARDING_ENABLED =                11,
 	IETF_ATTR_FACTORY_DEFAULT_PWD_ENABLED =       12,
+
+	/* draft-ietf-sacm-nea-swid-patnc */
+	IETF_ATTR_SW_REQUEST =                        17,
+	IETF_ATTR_SW_ID_INVENTORY =                   18,
+	IETF_ATTR_SW_ID_EVENTS =                      19,
+	IETF_ATTR_SW_INVENTORY =                      20,
+	IETF_ATTR_SW_EVENTS =                         21,
+	IETF_ATTR_SUBSCRIPTION_STATUS_REQ =           22,
+	IETF_ATTR_SUBSCRIPTION_STATUS_RESP =          23,
+	IETF_ATTR_SRC_METADATA_REQ =                  24,
+	IETF_ATTR_SRC_METADATA_RESP =                 25,
+
 	IETF_ATTR_RESERVED =                  0xffffffff,
 };
 
diff --git a/src/libimcv/ietf/ietf_attr_pa_tnc_error.c b/src/libimcv/ietf/ietf_attr_pa_tnc_error.c
index 0dbb4aa..966c095 100644
--- a/src/libimcv/ietf/ietf_attr_pa_tnc_error.c
+++ b/src/libimcv/ietf/ietf_attr_pa_tnc_error.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2011-2014 Andreas Steffen
+ * Copyright (C) 2011-2017 Andreas Steffen
  * HSR Hochschule fuer Technik Rapperswil
  *
  * This program is free software; you can redistribute it and/or modify it
@@ -20,13 +20,23 @@
 #include <bio/bio_reader.h>
 #include <utils/debug.h>
 
-ENUM(pa_tnc_error_code_names, PA_ERROR_RESERVED,
-							  PA_ERROR_ATTR_TYPE_NOT_SUPPORTED,
+ENUM_BEGIN(pa_tnc_error_code_names,	PA_ERROR_RESERVED,
+									PA_ERROR_ATTR_TYPE_NOT_SUPPORTED,
 	"Reserved",
 	"Invalid Parameter",
 	"Version Not Supported",
 	"Attribute Type Not Supported"
 );
+ENUM_NEXT(pa_tnc_error_code_names,	PA_ERROR_SW,
+									PA_ERROR_SW_SUBSCRIPTION_ID_REUSE,
+									PA_ERROR_ATTR_TYPE_NOT_SUPPORTED,
+	"SW Error",
+	"SW Subscription Denied",
+	"SW Response Too Large",
+	"SW Subscription Fulfillment Error",
+	"SW Subscription ID Reuse"
+);
+ENUM_END(pa_tnc_error_code_names,	PA_ERROR_SW_SUBSCRIPTION_ID_REUSE);
 
 typedef struct private_ietf_attr_pa_tnc_error_t private_ietf_attr_pa_tnc_error_t;
 
@@ -246,7 +256,8 @@ METHOD(pa_tnc_attr_t, process, status_t,
 	reader->read_uint24(reader, &this->error_code.vendor_id);
 	reader->read_uint32(reader, &this->error_code.type);
 
-	if (this->error_code.vendor_id == PEN_IETF)
+	if (this->error_code.vendor_id == PEN_IETF &&
+		this->error_code.type <= PA_ERROR_PA_TNC_MSG_ROOF)
 	{
 		if (!reader->read_data(reader, PA_ERROR_MSG_INFO_SIZE, &this->msg_info))
 		{
@@ -396,7 +407,8 @@ pa_tnc_attr_t *ietf_attr_pa_tnc_error_create(pen_type_t error_code,
 {
 	private_ietf_attr_pa_tnc_error_t *this;
 
-	if (error_code.vendor_id == PEN_IETF)
+	if (error_code.vendor_id == PEN_IETF &&
+		error_code.type <= PA_ERROR_PA_TNC_MSG_ROOF)
 	{
 		msg_info.len = PA_ERROR_MSG_INFO_SIZE;
 	}
diff --git a/src/libimcv/ietf/ietf_attr_pa_tnc_error.h b/src/libimcv/ietf/ietf_attr_pa_tnc_error.h
index b1df194..7dbc338 100644
--- a/src/libimcv/ietf/ietf_attr_pa_tnc_error.h
+++ b/src/libimcv/ietf/ietf_attr_pa_tnc_error.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2011-2014 Andreas Steffen
+ * Copyright (C) 2011-2017 Andreas Steffen
  * HSR Hochschule fuer Technik Rapperswil
  *
  * This program is free software; you can redistribute it and/or modify it
@@ -27,15 +27,24 @@ typedef enum pa_tnc_error_code_t pa_tnc_error_code_t;
 #include "ietf_attr.h"
 #include "pa_tnc/pa_tnc_attr.h"
 
-
 /**
  * IETF Standard PA-TNC Error Codes as defined in section 4.2.8 of RFC 5792
  */
 enum  pa_tnc_error_code_t {
-    PA_ERROR_RESERVED =                 0,
-	PA_ERROR_INVALID_PARAMETER =        1,
-	PA_ERROR_VERSION_NOT_SUPPORTED =    2,
-	PA_ERROR_ATTR_TYPE_NOT_SUPPORTED =  3,
+
+	/* RFC 5792 PA-TNC */
+	PA_ERROR_RESERVED =                      0,
+	PA_ERROR_INVALID_PARAMETER =             1,
+	PA_ERROR_VERSION_NOT_SUPPORTED =         2,
+	PA_ERROR_ATTR_TYPE_NOT_SUPPORTED =       3,
+	PA_ERROR_PA_TNC_MSG_ROOF =               3,
+
+	/* draft-ietf-sacm-nea-swid-patnc (SWIMA) */
+	PA_ERROR_SW =                           32,
+	PA_ERROR_SW_SUBSCRIPTION_DENIED =       33,
+	PA_ERROR_SW_RESPONSE_TOO_LARGE =        34,
+	PA_ERROR_SW_SUBSCRIPTION_FULFILLMENT =  35,
+	PA_ERROR_SW_SUBSCRIPTION_ID_REUSE =     36
 };
 
 /**
diff --git a/src/libimcv/tcg/swid/tcg_swid_attr_req.c b/src/libimcv/ietf/swima/ietf_swima_attr_req.c
similarity index 55%
copy from src/libimcv/tcg/swid/tcg_swid_attr_req.c
copy to src/libimcv/ietf/swima/ietf_swima_attr_req.c
index f02bbcb..07d0b0c 100644
--- a/src/libimcv/tcg/swid/tcg_swid_attr_req.c
+++ b/src/libimcv/ietf/swima/ietf_swima_attr_req.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2013-2014 Andreas Steffen
+ * Copyright (C) 2017 Andreas Steffen
  * HSR Hochschule fuer Technik Rapperswil
  *
  * This program is free software; you can redistribute it and/or modify it
@@ -13,9 +13,8 @@
  * for more details.
  */
 
-#include "tcg_swid_attr_req.h"
-
-#include "swid/swid_tag_id.h"
+#include "ietf_swima_attr_req.h"
+#include "swima/swima_record.h"
 
 #include <pa_tnc/pa_tnc_msg.h>
 #include <bio/bio_writer.h>
@@ -23,38 +22,36 @@
 #include <utils/debug.h>
 #include <collections/linked_list.h>
 
-typedef struct private_tcg_swid_attr_req_t private_tcg_swid_attr_req_t;
+typedef struct private_ietf_swima_attr_req_t private_ietf_swima_attr_req_t;
 
 /**
- * SWID Request
- * see section 4.7 of TCG TNC SWID Message and Attributes for IF-M
+ * SW Request
+ * see section 5.7 of IETF SW Inventory Message and Attributes for PA-TNC
  *
  *                       1                   2                   3
  *   0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
  *  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- *  |R|S|C| Reserved|                   Tag ID Count                |
+ *  |C|S|R| Reserved|           Software Identifier Count           |
  *  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  *  |                          Request ID                           |
  *  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  *  |                         Earliest EID                          |
  *  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- *  |       Tag Creator Length      | Tag Creator (variable length) |
- *  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- *  |    Unique Software ID Length  |Unique Software ID (var length)|
+ *  |   Software Identifier Length  | Software Identifier (Var Len) |
  *  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  */
 
-#define SWID_REQ_RESERVED_MASK			0xE0
+#define SW_REQ_RESERVED_MASK			0xE0
 
 /**
- * Private data of an tcg_swid_attr_req_t object.
+ * Private data of an ietf_swima_attr_req_t object.
  */
-struct private_tcg_swid_attr_req_t {
+struct private_ietf_swima_attr_req_t {
 
 	/**
-	 * Public members of tcg_swid_attr_req_t
+	 * Public members of ietf_swima_attr_req_t
 	 */
-	tcg_swid_attr_req_t public;
+	ietf_swima_attr_req_t public;
 
 	/**
 	 * Vendor-specific attribute type
@@ -66,7 +63,6 @@ struct private_tcg_swid_attr_req_t {
 	 */
 	size_t length;
 
-
 	/**
 	 * Attribute value or segment
 	 */
@@ -88,14 +84,9 @@ struct private_tcg_swid_attr_req_t {
 	uint32_t request_id;
 
 	/**
-	 * Earliest EID
-	 */
-	uint32_t earliest_eid;
-
-	/**
-	 * List of Target Tag Identifiers
+	 * Inventory of Target Software Identifiers
 	 */
-	swid_inventory_t *targets;
+	swima_inventory_t *targets;
 
 	/**
 	 * Reference count
@@ -104,55 +95,55 @@ struct private_tcg_swid_attr_req_t {
 };
 
 METHOD(pa_tnc_attr_t, get_type, pen_type_t,
-	private_tcg_swid_attr_req_t *this)
+	private_ietf_swima_attr_req_t *this)
 {
 	return this->type;
 }
 
 METHOD(pa_tnc_attr_t, get_value, chunk_t,
-	private_tcg_swid_attr_req_t *this)
+	private_ietf_swima_attr_req_t *this)
 {
 	return this->value;
 }
 
 METHOD(pa_tnc_attr_t, get_noskip_flag, bool,
-	private_tcg_swid_attr_req_t *this)
+	private_ietf_swima_attr_req_t *this)
 {
 	return this->noskip_flag;
 }
 
 METHOD(pa_tnc_attr_t, set_noskip_flag,void,
-	private_tcg_swid_attr_req_t *this, bool noskip)
+	private_ietf_swima_attr_req_t *this, bool noskip)
 {
 	this->noskip_flag = noskip;
 }
 
 METHOD(pa_tnc_attr_t, build, void,
-	private_tcg_swid_attr_req_t *this)
+	private_ietf_swima_attr_req_t *this)
 {
 	bio_writer_t *writer;
-	chunk_t tag_creator, unique_sw_id;
-	swid_tag_id_t *tag_id;
+	swima_record_t *sw_record;
+	uint32_t earliest_eid;
+	chunk_t sw_id;
 	enumerator_t *enumerator;
 
 	if (this->value.ptr)
 	{
 		return;
 	}
+	earliest_eid = this->targets->get_eid(this->targets, NULL);
 
-	writer = bio_writer_create(TCG_SWID_REQ_MIN_SIZE);
+	writer = bio_writer_create(IETF_SWIMA_REQ_MIN_SIZE);
 	writer->write_uint8 (writer, this->flags);
 	writer->write_uint24(writer, this->targets->get_count(this->targets));
 	writer->write_uint32(writer, this->request_id);
-	writer->write_uint32(writer, this->earliest_eid);
+	writer->write_uint32(writer, earliest_eid);
 
 	enumerator = this->targets->create_enumerator(this->targets);
-	while (enumerator->enumerate(enumerator, &tag_id))
+	while (enumerator->enumerate(enumerator, &sw_record))
 	{
-		tag_creator = tag_id->get_tag_creator(tag_id);
-		unique_sw_id = tag_id->get_unique_sw_id(tag_id, NULL);
-		writer->write_data16(writer, tag_creator);
-		writer->write_data16(writer, unique_sw_id);
+		sw_id = sw_record->get_sw_id(sw_record, NULL);
+		writer->write_data16(writer, sw_id);
 	}
 	enumerator->destroy(enumerator);
 
@@ -162,12 +153,12 @@ METHOD(pa_tnc_attr_t, build, void,
 }
 
 METHOD(pa_tnc_attr_t, process, status_t,
-	private_tcg_swid_attr_req_t *this, uint32_t *offset)
+	private_ietf_swima_attr_req_t *this, uint32_t *offset)
 {
 	bio_reader_t *reader;
-	uint32_t tag_id_count;
-	chunk_t tag_creator, unique_sw_id;
-	swid_tag_id_t *tag_id;
+	swima_record_t *sw_record;
+	uint32_t sw_id_count, earliest_eid;
+	chunk_t sw_id;
 
 	*offset = 0;
 
@@ -175,45 +166,34 @@ METHOD(pa_tnc_attr_t, process, status_t,
 	{
 		return NEED_MORE;
 	}
-	if (this->value.len < TCG_SWID_REQ_MIN_SIZE)
+	if (this->value.len < IETF_SWIMA_REQ_MIN_SIZE)
 	{
-		DBG1(DBG_TNC, "insufficient data for SWID Request");
+		DBG1(DBG_TNC, "insufficient data for SW Request");
 		return FAILED;
 	}
 
 	reader = bio_reader_create(this->value);
 	reader->read_uint8 (reader, &this->flags);
-	reader->read_uint24(reader, &tag_id_count);
+	reader->read_uint24(reader, &sw_id_count);
 	reader->read_uint32(reader, &this->request_id);
-	reader->read_uint32(reader, &this->earliest_eid);
+	reader->read_uint32(reader, &earliest_eid);
 
-	if (this->request_id == 0)
-	{
-		*offset = 4;
-		return FAILED;
-	}
-	*offset = TCG_SWID_REQ_MIN_SIZE;
-
-	this->flags &= SWID_REQ_RESERVED_MASK;
+	*offset = IETF_SWIMA_REQ_MIN_SIZE;
+	this->flags &= SW_REQ_RESERVED_MASK;
+	this->targets->set_eid(this->targets, earliest_eid, 0);
 
-	while (tag_id_count--)
+	while (sw_id_count--)
 	{
-		if (!reader->read_data16(reader, &tag_creator))
+		if (!reader->read_data16(reader, &sw_id))
 		{
-			DBG1(DBG_TNC, "insufficient data for Tag Creator field");
+			DBG1(DBG_TNC, "insufficient data for Software ID");
+			reader->destroy(reader);
 			return FAILED;
 		}
-		*offset += 2 + tag_creator.len;
-
-		if (!reader->read_data16(reader, &unique_sw_id))
-		{
-			DBG1(DBG_TNC, "insufficient data for Unique Software ID");
-			return FAILED;
-		}
-		*offset += 2 + unique_sw_id.len;
+		*offset += 2 + sw_id.len;
 		
-		tag_id = swid_tag_id_create(tag_creator, unique_sw_id, chunk_empty);
-		this->targets->add(this->targets, tag_id);
+		sw_record = swima_record_create(0, sw_id, chunk_empty);
+		this->targets->add(this->targets, sw_record);
 	}
 	reader->destroy(reader);
 
@@ -221,20 +201,20 @@ METHOD(pa_tnc_attr_t, process, status_t,
 }
 
 METHOD(pa_tnc_attr_t, add_segment, void,
-	private_tcg_swid_attr_req_t *this, chunk_t segment)
+	private_ietf_swima_attr_req_t *this, chunk_t segment)
 {
 	this->value = chunk_cat("mc", this->value, segment);
 }
 
 METHOD(pa_tnc_attr_t, get_ref, pa_tnc_attr_t*,
-	private_tcg_swid_attr_req_t *this)
+	private_ietf_swima_attr_req_t *this)
 {
 	ref_get(&this->ref);
 	return &this->public.pa_tnc_attribute;
 }
 
 METHOD(pa_tnc_attr_t, destroy, void,
-	private_tcg_swid_attr_req_t *this)
+	private_ietf_swima_attr_req_t *this)
 {
 	if (ref_put(&this->ref))
 	{
@@ -244,32 +224,27 @@ METHOD(pa_tnc_attr_t, destroy, void,
 	}
 }
 
-METHOD(tcg_swid_attr_req_t, get_flags, uint8_t,
-	private_tcg_swid_attr_req_t *this)
+METHOD(ietf_swima_attr_req_t, get_flags, uint8_t,
+	private_ietf_swima_attr_req_t *this)
 {
 	return this->flags;
 }
 
-METHOD(tcg_swid_attr_req_t, get_request_id, uint32_t,
-	private_tcg_swid_attr_req_t *this)
+METHOD(ietf_swima_attr_req_t, get_request_id, uint32_t,
+	private_ietf_swima_attr_req_t *this)
 {
 	return this->request_id;
 }
 
-METHOD(tcg_swid_attr_req_t, get_earliest_eid, uint32_t,
-	private_tcg_swid_attr_req_t *this)
-{
-	return this->earliest_eid;
-}
-
-METHOD(tcg_swid_attr_req_t, add_target, void,
-	private_tcg_swid_attr_req_t *this, swid_tag_id_t *tag_id)
+METHOD(ietf_swima_attr_req_t, set_targets, void,
+	private_ietf_swima_attr_req_t *this, swima_inventory_t *targets)
 {
-	this->targets->add(this->targets, tag_id);
+	this->targets->destroy(this->targets);
+	this->targets = targets->get_ref(targets);
 }
 
-METHOD(tcg_swid_attr_req_t, get_targets, swid_inventory_t*,
-	private_tcg_swid_attr_req_t *this)
+METHOD(ietf_swima_attr_req_t, get_targets, swima_inventory_t*,
+	private_ietf_swima_attr_req_t *this)
 {
 	return this->targets;
 }
@@ -277,10 +252,9 @@ METHOD(tcg_swid_attr_req_t, get_targets, swid_inventory_t*,
 /**
  * Described in header.
  */
-pa_tnc_attr_t *tcg_swid_attr_req_create(uint8_t flags, uint32_t request_id,
-										uint32_t eid)
+pa_tnc_attr_t *ietf_swima_attr_req_create(uint8_t flags, uint32_t request_id)
 {
-	private_tcg_swid_attr_req_t *this;
+	private_ietf_swima_attr_req_t *this;
 
 	INIT(this,
 		.public = {
@@ -297,15 +271,13 @@ pa_tnc_attr_t *tcg_swid_attr_req_create(uint8_t flags, uint32_t request_id,
 			},
 			.get_flags = _get_flags,
 			.get_request_id = _get_request_id,
-			.get_earliest_eid = _get_earliest_eid,
-			.add_target = _add_target,
+			.set_targets = _set_targets,
 			.get_targets = _get_targets,
 		},
-		.type = { PEN_TCG, TCG_SWID_REQUEST },
-		.flags = flags & SWID_REQ_RESERVED_MASK,
+		.type = { PEN_IETF, IETF_ATTR_SW_REQUEST },
+		.flags = flags & SW_REQ_RESERVED_MASK,
 		.request_id = request_id,
-		.earliest_eid = eid,
-		.targets = swid_inventory_create(FALSE),
+		.targets = swima_inventory_create(),
 		.ref = 1,
 	);
 
@@ -315,9 +287,9 @@ pa_tnc_attr_t *tcg_swid_attr_req_create(uint8_t flags, uint32_t request_id,
 /**
  * Described in header.
  */
-pa_tnc_attr_t *tcg_swid_attr_req_create_from_data(size_t length, chunk_t data)
+pa_tnc_attr_t *ietf_swima_attr_req_create_from_data(size_t length, chunk_t data)
 {
-	private_tcg_swid_attr_req_t *this;
+	private_ietf_swima_attr_req_t *this;
 
 	INIT(this,
 		.public = {
@@ -334,14 +306,13 @@ pa_tnc_attr_t *tcg_swid_attr_req_create_from_data(size_t length, chunk_t data)
 			},
 			.get_flags = _get_flags,
 			.get_request_id = _get_request_id,
-			.get_earliest_eid = _get_earliest_eid,
-			.add_target = _add_target,
+			.set_targets = _set_targets,
 			.get_targets = _get_targets,
 		},
-		.type = { PEN_TCG, TCG_SWID_REQUEST },
+		.type = { PEN_IETF, IETF_ATTR_SW_REQUEST },
 		.length = length,
 		.value = chunk_clone(data),
-		.targets = swid_inventory_create(FALSE),
+		.targets = swima_inventory_create(),
 		.ref = 1,
 	);
 
diff --git a/src/libimcv/ietf/swima/ietf_swima_attr_req.h b/src/libimcv/ietf/swima/ietf_swima_attr_req.h
new file mode 100644
index 0000000..21155d6
--- /dev/null
+++ b/src/libimcv/ietf/swima/ietf_swima_attr_req.h
@@ -0,0 +1,96 @@
+/*
+ * Copyright (C) 2017 Andreas Steffen
+ * HSR Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT 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 ietf_swima_attr_req ietf_swima_attr_req
+ * @{ @ingroup ietf_attr
+ */
+
+#ifndef IETF_SWIMA_ATTR_REQ_H_
+#define IETF_SWIMA_ATTR_REQ_H_
+
+#define IETF_SWIMA_REQ_MIN_SIZE	12
+
+typedef struct ietf_swima_attr_req_t ietf_swima_attr_req_t;
+typedef enum ietf_swima_attr_req_flag_t ietf_swima_attr_req_flag_t;
+
+enum ietf_swima_attr_req_flag_t {
+	IETF_SWIMA_ATTR_REQ_FLAG_NONE = 0,
+	IETF_SWIMA_ATTR_REQ_FLAG_C =   (1 << 7),
+	IETF_SWIMA_ATTR_REQ_FLAG_S =   (1 << 6),
+	IETF_SWIMA_ATTR_REQ_FLAG_R =   (1 << 5)
+};
+
+#include "swima/swima_inventory.h"
+#include "ietf/ietf_attr.h"
+#include "pa_tnc/pa_tnc_attr.h"
+
+/**
+ * Class implementing the IETF SW Request attribute
+ */
+struct ietf_swima_attr_req_t {
+
+	/**
+	 * Public PA-TNC attribute interface
+	 */
+	pa_tnc_attr_t pa_tnc_attribute;
+
+	/**
+	 * Get SW request flags
+	 *
+	 * @return				Flags
+	 */
+	uint8_t (*get_flags)(ietf_swima_attr_req_t *this);
+
+	/**
+	 * Get Request ID
+	 *
+	 * @return				Request ID
+	 */
+	uint32_t (*get_request_id)(ietf_swima_attr_req_t *this);
+
+	/**
+	 * Set Software Identity targets
+	 *
+	 * @param targets		SW ID inventory containing targets (not cloned)
+	 */
+	void (*set_targets)(ietf_swima_attr_req_t *this, swima_inventory_t *targets);
+
+	/**
+	 * Get Software Identity targets
+	 *
+	 * @return				SW ID inventory containing targets
+	 */
+	swima_inventory_t* (*get_targets)(ietf_swima_attr_req_t *this);
+
+};
+
+/**
+ * Creates an ietf_swima_attr_req_t object
+ *
+ * @param flags				Sets the C|S|R flags
+ * @param request_id		Request ID
+ */
+pa_tnc_attr_t* ietf_swima_attr_req_create(uint8_t flags, uint32_t request_id);
+
+/**
+ * Creates an ietf_swima_attr_req_t object from received data
+ *
+ * @param length			Total length of attribute value
+ * @param value				Unparsed attribute value (might be a segment)
+ */
+pa_tnc_attr_t* ietf_swima_attr_req_create_from_data(size_t length, chunk_t value);
+
+#endif /** IETF_SWIMA_ATTR_REQ_H_ @}*/
diff --git a/src/libimcv/ietf/swima/ietf_swima_attr_sw_ev.c b/src/libimcv/ietf/swima/ietf_swima_attr_sw_ev.c
new file mode 100644
index 0000000..e315c3d
--- /dev/null
+++ b/src/libimcv/ietf/swima/ietf_swima_attr_sw_ev.c
@@ -0,0 +1,482 @@
+/*
+ * Copyright (C) 2017 Andreas Steffen
+ * HSR Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT 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 "ietf_swima_attr_sw_ev.h"
+#include "swima/swima_event.h"
+
+#include <pa_tnc/pa_tnc_msg.h>
+#include <bio/bio_writer.h>
+#include <bio/bio_reader.h>
+#include <utils/debug.h>
+
+#define SW_EV_TIMESTAMP_SIZE	20
+
+typedef struct private_ietf_swima_attr_sw_ev_t private_ietf_swima_attr_sw_ev_t;
+
+/**
+ * Software [Identifier] Events
+ * see sections 5.9/5.11 of IETF SW Inventory Message and Attributes for PA-TNC
+ *
+ *                       1                   2                   3
+ *   0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+ *  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ *  |     Flags     |           Software Identifier Count           |
+ *  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ *  |               Request ID Copy / Subscription ID               |
+ *  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ *  |                           EID Epoch                           |
+ *  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ *  |                           Last EID                            |
+ *  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ *  |                       Last Consulted EID                      |
+ *  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ *  |                              EID                              |
+ *  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ *  |                           Timestamp                           |
+ *  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ *  |                           Timestamp                           |
+ *  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ *  |                           Timestamp                           |
+ *  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ *  |                           Timestamp                           |
+ *  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ *  |                           Timestamp                           |
+ *  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ *  |                       Record Identifier                       |
+ *  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ *  |              Data Model Type PEN              |Data Model Type|
+ *  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ *  | Source ID Num |    Action     |  Software Identifier Length   |
+ *  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ *  |             Software Identifier (Variable Length)             |
+ *  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ *  |    Software Locator Length    |  Software Locator (Var. Len)  |
+ *  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ *
+ * Software Event only
+ * see section 5.11 of IETF SW Inventory Message and Attributes for PA-TNC
+ *
+ *  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ *  |                          Record Length                        |
+ *  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ *  |                   Record (Variable length)                    |
+ *  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ */
+
+/**
+ * Private data of an ietf_swima_attr_sw_ev_t object.
+ */
+struct private_ietf_swima_attr_sw_ev_t {
+
+	/**
+	 * Public members of ietf_swima_attr_sw_ev_t
+	 */
+	ietf_swima_attr_sw_ev_t public;
+
+	/**
+	 * Vendor-specific attribute type
+	 */
+	pen_type_t type;
+
+	/**
+	 * Length of attribute value
+	 */
+	size_t length;
+
+	/**
+	 * Offset up to which attribute value has been processed
+	 */
+	size_t offset;
+
+	/**
+	 * Current position of attribute value pointer
+	 */
+	chunk_t value;
+
+	/**
+	 * Contains complete attribute or current segment
+	 */
+	chunk_t segment;
+
+	/**
+	 * Noskip flag
+	 */
+	bool noskip_flag;
+
+	/**
+	 * Request ID
+	 */
+	uint32_t request_id;
+
+	/**
+	 * Attribute flags
+	 */
+	uint8_t flags;
+
+	/**
+	 * Number of unprocessed software events in attribute
+	 */
+	uint32_t event_count;
+
+	/**
+	 * Event list
+	 */
+	swima_events_t *events;
+
+	/**
+	 * Reference count
+	 */
+	refcount_t ref;
+};
+
+METHOD(pa_tnc_attr_t, get_type, pen_type_t,
+	private_ietf_swima_attr_sw_ev_t *this)
+{
+	return this->type;
+}
+
+METHOD(pa_tnc_attr_t, get_value, chunk_t,
+	private_ietf_swima_attr_sw_ev_t *this)
+{
+	return this->value;
+}
+
+METHOD(pa_tnc_attr_t, get_noskip_flag, bool,
+	private_ietf_swima_attr_sw_ev_t *this)
+{
+	return this->noskip_flag;
+}
+
+METHOD(pa_tnc_attr_t, set_noskip_flag,void,
+	private_ietf_swima_attr_sw_ev_t *this, bool noskip)
+{
+	this->noskip_flag = noskip;
+}
+
+METHOD(pa_tnc_attr_t, build, void,
+	private_ietf_swima_attr_sw_ev_t *this)
+{
+	bio_writer_t *writer;
+	swima_event_t *sw_event;
+	swima_record_t *sw_record;
+	chunk_t timestamp, sw_id, sw_locator, record;
+	pen_type_t data_model;
+	uint32_t eid, record_id, last_eid, last_consulted_eid, eid_epoch;
+	uint8_t action, source_id;
+	enumerator_t *enumerator;
+
+	if (this->value.ptr)
+	{
+		return;
+	}
+	last_consulted_eid = this->events->get_eid(this->events, &eid_epoch,
+															 &last_eid);
+
+	writer = bio_writer_create(IETF_SWIMA_SW_EV_MIN_SIZE);
+	writer->write_uint8 (writer, this->flags);
+	writer->write_uint24(writer, this->events->get_count(this->events));
+	writer->write_uint32(writer, this->request_id);
+	writer->write_uint32(writer, eid_epoch);
+	writer->write_uint32(writer, last_eid);
+	writer->write_uint32(writer, last_consulted_eid);
+
+	enumerator = this->events->create_enumerator(this->events);
+	while (enumerator->enumerate(enumerator, &sw_event))
+	{
+		eid        = sw_event->get_eid(sw_event, &timestamp);
+		action     = sw_event->get_action(sw_event);
+		sw_record  = sw_event->get_sw_record(sw_event);
+		record_id  = sw_record->get_record_id(sw_record);
+		data_model = sw_record->get_data_model(sw_record);
+		source_id  = sw_record->get_source_id(sw_record);
+		sw_id      = sw_record->get_sw_id(sw_record, &sw_locator);
+
+		writer->write_uint32(writer, eid);
+		writer->write_data  (writer, timestamp);
+		writer->write_uint32(writer, record_id);
+		writer->write_uint24(writer, data_model.vendor_id);
+		writer->write_uint8 (writer, data_model.type);
+		writer->write_uint8 (writer, source_id);
+		writer->write_uint8 (writer, action);
+		writer->write_data16(writer, sw_id);
+		writer->write_data16(writer, sw_locator);
+
+		if (this->type.type == IETF_ATTR_SW_EVENTS)
+		{
+			record = sw_record->get_record(sw_record);
+			writer->write_data32(writer, record);
+		}
+	}
+	enumerator->destroy(enumerator);
+
+	this->value = writer->extract_buf(writer);
+	this->segment = this->value;
+	this->length = this->value.len;
+	writer->destroy(writer);
+}
+
+METHOD(pa_tnc_attr_t, process, status_t,
+	private_ietf_swima_attr_sw_ev_t *this, uint32_t *offset)
+{
+	bio_reader_t *reader;
+	uint32_t data_model_pen, record_id;
+	uint32_t eid, eid_epoch, last_eid, last_consulted_eid;
+	uint8_t  data_model_type, source_id, action;
+	pen_type_t data_model;
+	chunk_t sw_id, sw_locator, record, timestamp;
+	swima_event_t *sw_event;
+	swima_record_t *sw_record;
+	status_t status = NEED_MORE;
+
+	if (this->offset == 0)
+	{
+		if (this->length < IETF_SWIMA_SW_EV_MIN_SIZE)
+		{
+			DBG1(DBG_TNC, "insufficient data for %N/%N", pen_names, PEN_IETF,
+						   ietf_attr_names, this->type.type);
+			*offset = this->offset;
+			return FAILED;
+		}
+		if (this->value.len < IETF_SWIMA_SW_EV_MIN_SIZE)
+		{
+			return NEED_MORE;
+		}
+		reader = bio_reader_create(this->value);
+		reader->read_uint8 (reader, &this->flags);
+		reader->read_uint24(reader, &this->event_count);
+		reader->read_uint32(reader, &this->request_id);
+		reader->read_uint32(reader, &eid_epoch);
+		reader->read_uint32(reader, &last_eid);
+		reader->read_uint32(reader, &last_consulted_eid);
+		this->offset = IETF_SWIMA_SW_EV_MIN_SIZE;
+		this->events->set_eid(this->events, last_consulted_eid, eid_epoch);
+		this->events->set_last_eid(this->events, last_eid);
+		this->value = reader->peek(reader);
+		reader->destroy(reader);
+	}
+
+	reader = bio_reader_create(this->value);
+
+	while (this->event_count)
+	{
+		if (!reader->read_uint32(reader, &eid) ||
+			!reader->read_data  (reader, SW_EV_TIMESTAMP_SIZE, &timestamp) ||
+			!reader->read_uint32(reader, &record_id) ||
+			!reader->read_uint24(reader, &data_model_pen) ||
+			!reader->read_uint8 (reader, &data_model_type) ||
+			!reader->read_uint8 (reader, &source_id) ||
+			!reader->read_uint8 (reader, &action) ||
+			!reader->read_data16(reader, &sw_id) ||
+			!reader->read_data16(reader, &sw_locator))
+		{
+			goto end;
+		}
+		record = chunk_empty;
+
+		if (action == 0 || action > SWIMA_EVENT_ACTION_LAST)
+		{
+			DBG1(DBG_TNC, "invalid event action value for %N/%N", pen_names,
+						   PEN_IETF, ietf_attr_names, this->type.type);
+			*offset = this->offset;
+			reader->destroy(reader);
+
+			return FAILED;
+		}
+
+		if (this->type.type == IETF_ATTR_SW_EVENTS &&
+			!reader->read_data32(reader, &record))
+		{
+			goto end;
+		}
+		data_model = pen_type_create(data_model_pen, data_model_type);
+		sw_record = swima_record_create(record_id, sw_id, sw_locator);
+		sw_record->set_data_model(sw_record, data_model);
+		sw_record->set_source_id(sw_record, source_id);
+		sw_record->set_record(sw_record, record);
+		sw_event = swima_event_create(eid, timestamp, action, sw_record);
+		this->events->add(this->events, sw_event);
+		this->offset += this->value.len - reader->remaining(reader);
+		this->value = reader->peek(reader);
+
+		/* at least one software event was processed */
+		status = SUCCESS;
+		this->event_count--;
+	}
+
+	if (this->length == this->offset)
+	{
+		status = SUCCESS;
+	}
+	else
+	{
+		DBG1(DBG_TNC, "inconsistent length for %N/%N", pen_names, PEN_IETF,
+					   ietf_attr_names, this->type.type);
+		*offset = this->offset;
+		status = FAILED;
+	}
+
+end:
+	reader->destroy(reader);
+	return status;
+}
+
+METHOD(pa_tnc_attr_t, add_segment, void,
+	private_ietf_swima_attr_sw_ev_t *this, chunk_t segment)
+{
+	this->value = chunk_cat("cc", this->value, segment);
+	chunk_free(&this->segment);
+	this->segment = this->value;
+}
+
+METHOD(pa_tnc_attr_t, get_ref, pa_tnc_attr_t*,
+	private_ietf_swima_attr_sw_ev_t *this)
+{
+	ref_get(&this->ref);
+	return &this->public.pa_tnc_attribute;
+}
+
+METHOD(pa_tnc_attr_t, destroy, void,
+	private_ietf_swima_attr_sw_ev_t *this)
+{
+	if (ref_put(&this->ref))
+	{
+		this->events->destroy(this->events);
+		free(this->segment.ptr);
+		free(this);
+	}
+}
+
+METHOD(ietf_swima_attr_sw_ev_t, get_flags, uint8_t,
+	private_ietf_swima_attr_sw_ev_t *this)
+{
+	return this->flags;
+}
+
+METHOD(ietf_swima_attr_sw_ev_t, get_request_id, uint32_t,
+	private_ietf_swima_attr_sw_ev_t *this)
+{
+	return this->request_id;
+}
+
+METHOD(ietf_swima_attr_sw_ev_t, get_event_count, uint32_t,
+	private_ietf_swima_attr_sw_ev_t *this)
+{
+	return this->event_count;
+}
+
+METHOD(ietf_swima_attr_sw_ev_t, set_events, void,
+	private_ietf_swima_attr_sw_ev_t *this, swima_events_t *events)
+{
+	this->events->destroy(this->events);
+	this->events = events->get_ref(events);
+}
+
+METHOD(ietf_swima_attr_sw_ev_t, get_events, swima_events_t*,
+	private_ietf_swima_attr_sw_ev_t *this)
+{
+	return this->events;
+}
+
+METHOD(ietf_swima_attr_sw_ev_t, clear_events, void,
+	private_ietf_swima_attr_sw_ev_t *this)
+{
+	this->events->clear(this->events);
+}
+
+/**
+ * Described in header.
+ */
+pa_tnc_attr_t *ietf_swima_attr_sw_ev_create(uint8_t flags, uint32_t request_id,
+											 bool sw_id_only)
+{
+	private_ietf_swima_attr_sw_ev_t *this;
+	ietf_attr_t type;
+
+	type = sw_id_only ? IETF_ATTR_SW_ID_EVENTS : IETF_ATTR_SW_EVENTS;
+
+	INIT(this,
+		.public = {
+			.pa_tnc_attribute = {
+				.get_type = _get_type,
+				.get_value = _get_value,
+				.get_noskip_flag = _get_noskip_flag,
+				.set_noskip_flag = _set_noskip_flag,
+				.build = _build,
+				.process = _process,
+				.add_segment = _add_segment,
+				.get_ref = _get_ref,
+				.destroy = _destroy,
+			},
+			.get_flags = _get_flags,
+			.get_request_id = _get_request_id,
+			.get_event_count = _get_event_count,
+			.set_events = _set_events,
+			.get_events = _get_events,
+			.clear_events = _clear_events,
+		},
+		.type = { PEN_IETF, type },
+		.flags = flags,
+		.request_id = request_id,
+		.events = swima_events_create(),
+		.ref = 1,
+	);
+
+	return &this->public.pa_tnc_attribute;
+}
+
+
+/**
+ * Described in header.
+ */
+pa_tnc_attr_t *ietf_swima_attr_sw_ev_create_from_data(size_t length,
+										chunk_t data, bool sw_id_only)
+{
+	private_ietf_swima_attr_sw_ev_t *this;
+	ietf_attr_t type;
+
+	type = sw_id_only ? IETF_ATTR_SW_ID_EVENTS : IETF_ATTR_SW_EVENTS;
+
+	INIT(this,
+		.public = {
+			.pa_tnc_attribute = {
+				.get_type = _get_type,
+				.get_value = _get_value,
+				.get_noskip_flag = _get_noskip_flag,
+				.set_noskip_flag = _set_noskip_flag,
+				.build = _build,
+				.process = _process,
+				.add_segment = _add_segment,
+				.get_ref = _get_ref,
+				.destroy = _destroy,
+			},
+			.get_flags = _get_flags,
+			.get_request_id = _get_request_id,
+			.get_event_count = _get_event_count,
+			.set_events = _set_events,
+			.get_events = _get_events,
+			.clear_events = _clear_events,
+		},
+		.type = { PEN_IETF, type },
+		.length = length,
+		.segment = chunk_clone(data),
+		.events = swima_events_create(),
+		.ref = 1,
+	);
+
+	/* received either complete attribute value or first segment */
+	this->value = this->segment;
+
+	return &this->public.pa_tnc_attribute;
+}
diff --git a/src/libimcv/ietf/swima/ietf_swima_attr_sw_ev.h b/src/libimcv/ietf/swima/ietf_swima_attr_sw_ev.h
new file mode 100644
index 0000000..00f64dd
--- /dev/null
+++ b/src/libimcv/ietf/swima/ietf_swima_attr_sw_ev.h
@@ -0,0 +1,111 @@
+/*
+ * Copyright (C) 2017 Andreas Steffen
+ * HSR Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT 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 ietf_swima_attr_sw_ev ietf_swima_attr_sw_ev
+ * @{ @ingroup ietf_attr
+ */
+
+#ifndef IETF_SWIMA_ATTR_SW_EV_H_
+#define IETF_SWIMA_ATTR_SW_EV_H_
+
+#define IETF_SWIMA_SW_EV_MIN_SIZE	20
+
+typedef struct ietf_swima_attr_sw_ev_t ietf_swima_attr_sw_ev_t;
+typedef enum ietf_swima_attr_sw_ev_flag_t ietf_swima_attr_sw_ev_flag_t;
+
+enum ietf_swima_attr_sw_ev_flag_t {
+	IETF_SWIMA_ATTR_SW_EV_FLAG_NONE =   0,
+	IETF_SWIMA_ATTR_SW_EV_FLAG_S_F  =  (1 << 7)
+};
+
+#include "ietf/ietf_attr.h"
+#include "swima/swima_events.h"
+#include "pa_tnc/pa_tnc_attr.h"
+
+/**
+ * Class implementing the IETF SW Identifier Inventory attribute
+ *
+ */
+struct ietf_swima_attr_sw_ev_t {
+
+	/**
+	 * Public PA-TNC attribute interface
+	 */
+	pa_tnc_attr_t pa_tnc_attribute;
+
+	/**
+	 * Get Software Inventory flags
+	 *
+	 * @return				Flags
+	 */
+	uint8_t (*get_flags)(ietf_swima_attr_sw_ev_t *this);
+
+	/**
+	 * Get Request ID
+	 *
+	 * @return				Request ID
+	 */
+	uint32_t (*get_request_id)(ietf_swima_attr_sw_ev_t *this);
+
+	/**
+	 * Get number of Software [Identifier] Events
+	 *
+	 * @return				Software [Identifier] event count
+	 */
+	uint32_t (*get_event_count)(ietf_swima_attr_sw_ev_t *this);
+
+	/**
+	 * Add Software [Identifier] Events
+	 *
+	 * @param sw_events		List of Software [Identifier] events to be added
+	 */
+	void (*set_events)(ietf_swima_attr_sw_ev_t *this,
+					   swima_events_t *sw_events);
+	/**
+	 * Get Software [Identifier] Events
+	 *
+	 * @result				Software [Identifier] events
+	 */
+	swima_events_t* (*get_events)(ietf_swima_attr_sw_ev_t *this);
+
+	/**
+	 * Remove all Software [Identifier] events
+	 */
+	void (*clear_events)(ietf_swima_attr_sw_ev_t *this);
+
+};
+
+/**
+ * Creates an ietf_swima_attr_sw_ev_t object
+ *
+ * @param flags				Sets the flags
+ * @param request_id		Copy of the Request ID
+ * @param sw_id_only		TRUE if the Software ID, only is transmitted
+ */
+pa_tnc_attr_t* ietf_swima_attr_sw_ev_create(uint8_t flags, uint32_t request_id,
+											bool sw_id_only);
+
+/**
+ * Creates an ietf_swima_attr_sw_ev_t object from received data
+ *
+ * @param length			Total length of attribute value
+ * @param value				Unparsed attribute value (might be a segment)
+ * @param sw_id_only		TRUE if the Software ID, only is transmitted
+ */
+pa_tnc_attr_t* ietf_swima_attr_sw_ev_create_from_data(size_t length,
+										chunk_t value, bool sw_id_only);
+
+#endif /** IETF_SWIMA_ATTR_SW_EV_H_ @}*/
diff --git a/src/libimcv/ietf/swima/ietf_swima_attr_sw_inv.c b/src/libimcv/ietf/swima/ietf_swima_attr_sw_inv.c
new file mode 100644
index 0000000..ee5b16b
--- /dev/null
+++ b/src/libimcv/ietf/swima/ietf_swima_attr_sw_inv.c
@@ -0,0 +1,438 @@
+/*
+ * Copyright (C) 2017 Andreas Steffen
+ * HSR Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT 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 "ietf_swima_attr_sw_inv.h"
+#include "swima/swima_record.h"
+
+#include <pa_tnc/pa_tnc_msg.h>
+#include <bio/bio_writer.h>
+#include <bio/bio_reader.h>
+#include <utils/debug.h>
+
+
+typedef struct private_ietf_swima_attr_sw_inv_t private_ietf_swima_attr_sw_inv_t;
+
+/**
+ * Software [Identifier] Inventory
+ * see sections 5.8/5.10 of IETF SW Inventory Message and Attributes for PA-TNC
+ *
+ *                       1                   2                   3
+ *   0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+ *  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ *  |     Flags     |           Software Identifier Count           |
+ *  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ *  |               Request ID Copy / Subscription ID               |
+ *  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ *  |                           EID Epoch                           |
+ *  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ *  |                           Last EID                            |
+ *  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ *  |                       Record Identifier                       |
+ *  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ *  |              Data Model Type PEN              |Data Model Type|
+ *  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ *  | Source ID Num |  Software Identifier Length   |Software Id (v)|
+ *  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ *  |    Software Locator Length    |  Software Locator (Var. Len)  |
+ *  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ *
+ * Software Inventory only
+ * see section 5.10 of IETF SW Inventory Message and Attributes for PA-TNC
+ *
+ *  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ *  |                          Record Length                        |
+ *  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ *  |                   Record (Variable length)                    |
+ *  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ */
+
+/**
+ * Private data of an ietf_swima_attr_sw_inv_t object.
+ */
+struct private_ietf_swima_attr_sw_inv_t {
+
+	/**
+	 * Public members of ietf_swima_attr_sw_inv_t
+	 */
+	ietf_swima_attr_sw_inv_t public;
+
+	/**
+	 * Vendor-specific attribute type
+	 */
+	pen_type_t type;
+
+	/**
+	 * Length of attribute value
+	 */
+	size_t length;
+
+	/**
+	 * Offset up to which attribute value has been processed
+	 */
+	size_t offset;
+
+	/**
+	 * Current position of attribute value pointer
+	 */
+	chunk_t value;
+
+	/**
+	 * Contains complete attribute or current segment
+	 */
+	chunk_t segment;
+
+	/**
+	 * Noskip flag
+	 */
+	bool noskip_flag;
+
+	/**
+	 * Request ID
+	 */
+	uint32_t request_id;
+
+	/**
+	 * Attribute flags
+	 */
+	uint8_t flags;
+
+	/**
+	 * Number of unprocessed software inventory evidence records in attribute
+	 */
+	uint32_t record_count;
+
+	/**
+	 * SWID Tag ID Inventory
+	 */
+	swima_inventory_t *inventory;
+
+	/**
+	 * Reference count
+	 */
+	refcount_t ref;
+};
+
+METHOD(pa_tnc_attr_t, get_type, pen_type_t,
+	private_ietf_swima_attr_sw_inv_t *this)
+{
+	return this->type;
+}
+
+METHOD(pa_tnc_attr_t, get_value, chunk_t,
+	private_ietf_swima_attr_sw_inv_t *this)
+{
+	return this->value;
+}
+
+METHOD(pa_tnc_attr_t, get_noskip_flag, bool,
+	private_ietf_swima_attr_sw_inv_t *this)
+{
+	return this->noskip_flag;
+}
+
+METHOD(pa_tnc_attr_t, set_noskip_flag,void,
+	private_ietf_swima_attr_sw_inv_t *this, bool noskip)
+{
+	this->noskip_flag = noskip;
+}
+
+METHOD(pa_tnc_attr_t, build, void,
+	private_ietf_swima_attr_sw_inv_t *this)
+{
+	bio_writer_t *writer;
+	swima_record_t *sw_record;
+	chunk_t sw_id, sw_locator, record;
+	pen_type_t data_model;
+	uint32_t record_id, last_eid, eid_epoch;
+	uint8_t source_id;
+	enumerator_t *enumerator;
+
+	if (this->value.ptr)
+	{
+		return;
+	}
+	last_eid = this->inventory->get_eid(this->inventory, &eid_epoch);
+
+	writer = bio_writer_create(IETF_SWIMA_SW_INV_MIN_SIZE);
+	writer->write_uint8 (writer, this->flags);
+	writer->write_uint24(writer, this->inventory->get_count(this->inventory));
+	writer->write_uint32(writer, this->request_id);
+	writer->write_uint32(writer, eid_epoch);
+	writer->write_uint32(writer, last_eid);
+
+	enumerator = this->inventory->create_enumerator(this->inventory);
+	while (enumerator->enumerate(enumerator, &sw_record))
+	{
+		record_id  = sw_record->get_record_id(sw_record);
+		data_model = sw_record->get_data_model(sw_record);
+		source_id  = sw_record->get_source_id(sw_record);
+		sw_id      = sw_record->get_sw_id(sw_record, &sw_locator);
+
+		writer->write_uint32(writer, record_id);
+		writer->write_uint24(writer, data_model.vendor_id);
+		writer->write_uint8 (writer, data_model.type);
+		writer->write_uint8 (writer, source_id);
+		writer->write_data16(writer, sw_id);
+		writer->write_data16(writer, sw_locator);
+
+		if (this->type.type == IETF_ATTR_SW_INVENTORY)
+		{
+			record = sw_record->get_record(sw_record);
+			writer->write_data32(writer, record);
+		}
+	}
+	enumerator->destroy(enumerator);
+
+	this->value = writer->extract_buf(writer);
+	this->segment = this->value;
+	this->length = this->value.len;
+	writer->destroy(writer);
+}
+
+METHOD(pa_tnc_attr_t, process, status_t,
+	private_ietf_swima_attr_sw_inv_t *this, uint32_t *offset)
+{
+	bio_reader_t *reader;
+	uint32_t data_model_pen, record_id, last_eid, eid_epoch;
+	uint8_t  data_model_type, source_id;
+	pen_type_t data_model;
+	chunk_t sw_id, sw_locator, record;
+	swima_record_t *sw_record;
+	status_t status = NEED_MORE;
+
+	if (this->offset == 0)
+	{
+		if (this->length < IETF_SWIMA_SW_INV_MIN_SIZE)
+		{
+			DBG1(DBG_TNC, "insufficient data for %N/%N", pen_names, PEN_IETF,
+						   ietf_attr_names, this->type.type);
+			*offset = this->offset;
+			return FAILED;
+		}
+		if (this->value.len < IETF_SWIMA_SW_INV_MIN_SIZE)
+		{
+			return NEED_MORE;
+		}
+		reader = bio_reader_create(this->value);
+		reader->read_uint8 (reader, &this->flags);
+		reader->read_uint24(reader, &this->record_count);
+		reader->read_uint32(reader, &this->request_id);
+		reader->read_uint32(reader, &eid_epoch);
+		reader->read_uint32(reader, &last_eid);
+		this->offset = IETF_SWIMA_SW_INV_MIN_SIZE;
+		this->value = reader->peek(reader);
+		this->inventory->set_eid(this->inventory, last_eid, eid_epoch);
+		reader->destroy(reader);
+	}
+
+	reader = bio_reader_create(this->value);
+
+	while (this->record_count)
+	{
+		if (!reader->read_uint32(reader, &record_id) ||
+			!reader->read_uint24(reader, &data_model_pen) ||
+			!reader->read_uint8 (reader, &data_model_type) ||
+			!reader->read_uint8 (reader, &source_id) ||
+			!reader->read_data16(reader, &sw_id) ||
+			!reader->read_data16(reader, &sw_locator))
+		{
+			goto end;
+		}
+		record = chunk_empty;
+
+		if (this->type.type == IETF_ATTR_SW_INVENTORY &&
+			!reader->read_data32(reader, &record))
+		{
+			goto end;
+		}
+		data_model = pen_type_create(data_model_pen, data_model_type);
+		sw_record = swima_record_create(record_id, sw_id, sw_locator);
+		sw_record->set_data_model(sw_record, data_model);
+		sw_record->set_source_id(sw_record, source_id);
+		sw_record->set_record(sw_record, record);
+		this->inventory->add(this->inventory, sw_record);
+		this->offset += this->value.len - reader->remaining(reader);
+		this->value = reader->peek(reader);
+
+		/* at least one software inventory evidence record was processed */
+		status = SUCCESS;
+		this->record_count--;
+	}
+
+	if (this->length == this->offset)
+	{
+		status = SUCCESS;
+	}
+	else
+	{
+		DBG1(DBG_TNC, "inconsistent length for %N/%N", pen_names, PEN_IETF,
+					   ietf_attr_names, this->type.type);
+		*offset = this->offset;
+		status = FAILED;
+	}
+
+end:
+	reader->destroy(reader);
+	return status;
+}
+
+METHOD(pa_tnc_attr_t, add_segment, void,
+	private_ietf_swima_attr_sw_inv_t *this, chunk_t segment)
+{
+	this->value = chunk_cat("cc", this->value, segment);
+	chunk_free(&this->segment);
+	this->segment = this->value;
+}
+
+METHOD(pa_tnc_attr_t, get_ref, pa_tnc_attr_t*,
+	private_ietf_swima_attr_sw_inv_t *this)
+{
+	ref_get(&this->ref);
+	return &this->public.pa_tnc_attribute;
+}
+
+METHOD(pa_tnc_attr_t, destroy, void,
+	private_ietf_swima_attr_sw_inv_t *this)
+{
+	if (ref_put(&this->ref))
+	{
+		this->inventory->destroy(this->inventory);
+		free(this->segment.ptr);
+		free(this);
+	}
+}
+
+METHOD(ietf_swima_attr_sw_inv_t, get_flags, uint8_t,
+	private_ietf_swima_attr_sw_inv_t *this)
+{
+	return this->flags;
+}
+
+METHOD(ietf_swima_attr_sw_inv_t, get_request_id, uint32_t,
+	private_ietf_swima_attr_sw_inv_t *this)
+{
+	return this->request_id;
+}
+
+METHOD(ietf_swima_attr_sw_inv_t, get_record_count, uint32_t,
+	private_ietf_swima_attr_sw_inv_t *this)
+{
+	return this->record_count;
+}
+
+METHOD(ietf_swima_attr_sw_inv_t, set_inventory, void,
+	private_ietf_swima_attr_sw_inv_t *this, swima_inventory_t *inventory)
+{
+	this->inventory->destroy(this->inventory);
+	this->inventory = inventory->get_ref(inventory);
+}
+
+METHOD(ietf_swima_attr_sw_inv_t, get_inventory, swima_inventory_t*,
+	private_ietf_swima_attr_sw_inv_t *this)
+{
+	return this->inventory;
+}
+
+METHOD(ietf_swima_attr_sw_inv_t, clear_inventory, void,
+	private_ietf_swima_attr_sw_inv_t *this)
+{
+	this->inventory->clear(this->inventory);
+}
+
+/**
+ * Described in header.
+ */
+pa_tnc_attr_t *ietf_swima_attr_sw_inv_create(uint8_t flags, uint32_t request_id,
+											 bool sw_id_only)
+{
+	private_ietf_swima_attr_sw_inv_t *this;
+	ietf_attr_t type;
+
+	type = sw_id_only ? IETF_ATTR_SW_ID_INVENTORY : IETF_ATTR_SW_INVENTORY;
+
+	INIT(this,
+		.public = {
+			.pa_tnc_attribute = {
+				.get_type = _get_type,
+				.get_value = _get_value,
+				.get_noskip_flag = _get_noskip_flag,
+				.set_noskip_flag = _set_noskip_flag,
+				.build = _build,
+				.process = _process,
+				.add_segment = _add_segment,
+				.get_ref = _get_ref,
+				.destroy = _destroy,
+			},
+			.get_flags = _get_flags,
+			.get_request_id = _get_request_id,
+			.get_record_count = _get_record_count,
+			.set_inventory = _set_inventory,
+			.get_inventory = _get_inventory,
+			.clear_inventory = _clear_inventory,
+		},
+		.type = { PEN_IETF, type },
+		.flags = flags,
+		.request_id = request_id,
+		.inventory = swima_inventory_create(),
+		.ref = 1,
+	);
+
+	return &this->public.pa_tnc_attribute;
+}
+
+
+/**
+ * Described in header.
+ */
+pa_tnc_attr_t *ietf_swima_attr_sw_inv_create_from_data(size_t length,
+										chunk_t data, bool sw_id_only)
+{
+	private_ietf_swima_attr_sw_inv_t *this;
+	ietf_attr_t type;
+
+	type = sw_id_only ? IETF_ATTR_SW_ID_INVENTORY : IETF_ATTR_SW_INVENTORY;
+
+	INIT(this,
+		.public = {
+			.pa_tnc_attribute = {
+				.get_type = _get_type,
+				.get_value = _get_value,
+				.get_noskip_flag = _get_noskip_flag,
+				.set_noskip_flag = _set_noskip_flag,
+				.build = _build,
+				.process = _process,
+				.add_segment = _add_segment,
+				.get_ref = _get_ref,
+				.destroy = _destroy,
+			},
+			.get_flags = _get_flags,
+			.get_request_id = _get_request_id,
+			.get_record_count = _get_record_count,
+			.set_inventory = _set_inventory,
+			.get_inventory = _get_inventory,
+			.clear_inventory = _clear_inventory,
+		},
+		.type = { PEN_IETF, type },
+		.length = length,
+		.segment = chunk_clone(data),
+		.inventory = swima_inventory_create(),
+		.ref = 1,
+	);
+
+	/* received either complete attribute value or first segment */
+	this->value = this->segment;
+
+	return &this->public.pa_tnc_attribute;
+}
diff --git a/src/libimcv/ietf/swima/ietf_swima_attr_sw_inv.h b/src/libimcv/ietf/swima/ietf_swima_attr_sw_inv.h
new file mode 100644
index 0000000..a50cf29
--- /dev/null
+++ b/src/libimcv/ietf/swima/ietf_swima_attr_sw_inv.h
@@ -0,0 +1,112 @@
+/*
+ * Copyright (C) 2017 Andreas Steffen
+ * HSR Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT 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 ietf_swima_attr_sw_inv ietf_swima_attr_sw_inv
+ * @{ @ingroup ietf_attr
+ */
+
+#ifndef IETF_SWIMA_ATTR_SW_INV_H_
+#define IETF_SWIMA_ATTR_SW_INV_H_
+
+#define IETF_SWIMA_SW_INV_MIN_SIZE	16
+
+typedef struct ietf_swima_attr_sw_inv_t ietf_swima_attr_sw_inv_t;
+typedef enum ietf_swima_attr_sw_inv_flag_t ietf_swima_attr_sw_inv_flag_t;
+
+enum ietf_swima_attr_sw_inv_flag_t {
+	IETF_SWIMA_ATTR_SW_INV_FLAG_NONE =   0,
+	IETF_SWIMA_ATTR_SW_INV_FLAG_S_F  =  (1 << 7)
+};
+
+#include "ietf/ietf_attr.h"
+#include "swima/swima_inventory.h"
+#include "pa_tnc/pa_tnc_attr.h"
+
+/**
+ * Class implementing the IETF SW Identifier Inventory attribute
+ *
+ */
+struct ietf_swima_attr_sw_inv_t {
+
+	/**
+	 * Public PA-TNC attribute interface
+	 */
+	pa_tnc_attr_t pa_tnc_attribute;
+
+	/**
+	 * Get Software Inventory flags
+	 *
+	 * @return				Flags
+	 */
+	uint8_t (*get_flags)(ietf_swima_attr_sw_inv_t *this);
+
+	/**
+	 * Get Request ID
+	 *
+	 * @return					Request ID
+	 */
+	uint32_t (*get_request_id)(ietf_swima_attr_sw_inv_t *this);
+
+	/**
+	 * Get number of Software [Identifier] Inventory records
+	 *
+	 * @return					Software ID count
+	 */
+	uint32_t (*get_record_count)(ietf_swima_attr_sw_inv_t *this);
+
+	/**
+	 * Add a Software [Identifier] Inventory
+	 *
+	 * @param sw_inventory		Software [Identifier] record to be added
+	 */
+	void (*set_inventory)(ietf_swima_attr_sw_inv_t *this,
+						  swima_inventory_t *sw_inventory);
+	/**
+	 * Get Software [Identifier] Inventory
+	 *
+	 * @result					Software [Identifier] Inventory
+	 */
+	swima_inventory_t* (*get_inventory)(ietf_swima_attr_sw_inv_t *this);
+
+	/**
+	 * Remove all Software [Identifier] records from the inventory
+	 */
+	void (*clear_inventory)(ietf_swima_attr_sw_inv_t *this);
+
+
+};
+
+/**
+ * Creates an ietf_swima_attr_sw_inv_t object
+ *
+ * @param flags					Sets the flags
+ * @param request_id			Copy of the Request ID
+ * @param sw_id_only			TRUE if the Software ID, only is transmitted
+ */
+pa_tnc_attr_t* ietf_swima_attr_sw_inv_create(uint8_t flags, uint32_t request_id,
+											 bool sw_id_only);
+
+/**
+ * Creates an ietf_swima_attr_sw_inv_t object from received data
+ *
+ * @param length				Total length of attribute value
+ * @param value					Unparsed attribute value (might be a segment)
+ * @param sw_id_only			TRUE if the Software ID, only is transmitted
+ */
+pa_tnc_attr_t* ietf_swima_attr_sw_inv_create_from_data(size_t length,
+										chunk_t value, bool sw_id_only);
+
+#endif /** IETF_SWIMA_ATTR_SW_INV_H_ @}*/
diff --git a/src/libimcv/imcv.h b/src/libimcv/imcv.h
index e260ff8..0f44d8f 100644
--- a/src/libimcv/imcv.h
+++ b/src/libimcv/imcv.h
@@ -36,6 +36,9 @@
  * @defgroup libimcv_swid swid
  * @ingroup libimcv
  *
+ * @defgroup libimcv_swima swima
+ * @ingroup libimcv
+ *
  * @addtogroup libimcv
  * @{
  */
diff --git a/src/libimcv/imcv_tests.h b/src/libimcv/imcv_tests.h
index d3ea24b..2a0e132 100644
--- a/src/libimcv/imcv_tests.h
+++ b/src/libimcv/imcv_tests.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2014 Andreas Steffen
+ * Copyright (C) 2014-2017 Andreas Steffen
  * HSR Hochschule fuer Technik Rapperswil
  *
  * This program is free software; you can redistribute it and/or modify it
@@ -14,4 +14,4 @@
  */
 
 TEST_SUITE(imcv_seg_suite_create)
-
+TEST_SUITE(imcv_swima_suite_create)
diff --git a/src/libimcv/imv/data.sql b/src/libimcv/imv/data.sql
index fb0db91..a872499 100644
--- a/src/libimcv/imv/data.sql
+++ b/src/libimcv/imv/data.sql
@@ -652,114 +652,120 @@ INSERT INTO algorithms (
   8192, 'SHA384'
 );
 
+INSERT INTO algorithms (
+  id, name
+) VALUES (
+  4096, 'SHA512'
+);
+
 /* File Hashes */
 
 INSERT INTO file_hashes (
-  product, file, algo, hash
+  version, file, algo, hash
 ) VALUES (
-  28, 2, 32768, X'6c6f8e12f6cbfba612e780374c4cdcd40f20968a'
+  2, 2, 32768, '6c6f8e12f6cbfba612e780374c4cdcd40f20968a'
 );
 
 INSERT INTO file_hashes (
-  product, file, algo, hash
+  version, file, algo, hash
 ) VALUES (
-  28, 2, 16384, X'dbcecd19d59310183cf5c31ddee29e8d7bec64d3f9583aad074330a1b3024b07'
+  2, 2, 16384, 'dbcecd19d59310183cf5c31ddee29e8d7bec64d3f9583aad074330a1b3024b07'
 );
 
 INSERT INTO file_hashes (
-  product, file, algo, hash
+  version, file, algo, hash
 ) VALUES (
-  28, 2, 8192, X'197c5385e5853003188833d4f991136c1b0875fa416a60b1159f64e57e457b3184762c884a802a2bda194c058e3bd953'
+  2, 2, 8192, '197c5385e5853003188833d4f991136c1b0875fa416a60b1159f64e57e457b3184762c884a802a2bda194c058e3bd953'
 );
 
 INSERT INTO file_hashes (
-  product, file, algo, hash
+  version, file, algo, hash
 ) VALUES (
-  28, 4, 32768, X'3ad204f99eb7262efab79cfca02628870ea76361'
+  2, 4, 32768, '3ad204f99eb7262efab79cfca02628870ea76361'
 );
 
 INSERT INTO file_hashes (
-  product, file, algo, hash
+  version, file, algo, hash
 ) VALUES (
-  28, 4, 16384, X'3a2170aad92fdd58b55e0e199822bc873cf587b2d1eb1ed7ed8dcea97ae86376'
+  2, 4, 16384, '3a2170aad92fdd58b55e0e199822bc873cf587b2d1eb1ed7ed8dcea97ae86376'
 );
 
 INSERT INTO file_hashes (
-  product, file, algo, hash
+ version, file, algo, hash
 ) VALUES (
-  28, 4, 8192, X'f778076baa876b5e4b502494a3db081fb09dd870dee6991d54104a74b7e009c58fe261db5ffd13c11e08ef0cefcfa59f'
+  2, 4, 8192, 'f778076baa876b5e4b502494a3db081fb09dd870dee6991d54104a74b7e009c58fe261db5ffd13c11e08ef0cefcfa59f'
 );
 
 INSERT INTO file_hashes (
-  product, file, algo, hash
+  version, file, algo, hash
 ) VALUES (
-  28, 5, 32768, X'ecd9c7076cc0572724c7a67db7f19c2831e0445f'
+  4, 5, 32768, 'ecd9c7076cc0572724c7a67db7f19c2831e0445f'
 );
 
 INSERT INTO file_hashes (
-  product, file, algo, hash
+  version, file, algo, hash
 ) VALUES (
-  28, 5, 16384, X'28f3ea5afd34444c8232ea75003131e294a0c9b847de300e4b205d38c1a41305'
+  4, 5, 16384, '28f3ea5afd34444c8232ea75003131e294a0c9b847de300e4b205d38c1a41305'
 );
 
 INSERT INTO file_hashes (
-  product, file, algo, hash
+  version, file, algo, hash
 ) VALUES (
-  28, 5, 8192, X'51921a8b9322f2d3f06d55002ff40a79da67e70cb563b2a50977642d603dfac2ccbb68b3d32a8bb350769b75d6254208'
+  4, 5, 8192, '51921a8b9322f2d3f06d55002ff40a79da67e70cb563b2a50977642d603dfac2ccbb68b3d32a8bb350769b75d6254208'
 );
 
 INSERT INTO file_hashes (
-  product, file, algo, hash
+  version, file, algo, hash
 ) VALUES (
-  18, 1, 32768, X'd9309b9e45928239d7a7b18711e690792632cce4'
+  5, 1, 32768, 'd9309b9e45928239d7a7b18711e690792632cce4'
 );
 
 INSERT INTO file_hashes (
-  product, file, algo, hash
+  version, file, algo, hash
 ) VALUES (
-  18, 1, 16384, X'dbfa1856d278d8707c4989b30dd065b4bcd309908f0f2e6e66ff2aa83ff93f59'
+  5, 1, 16384, 'dbfa1856d278d8707c4989b30dd065b4bcd309908f0f2e6e66ff2aa83ff93f59'
 );
 
 INSERT INTO file_hashes (
-  product, file, algo, hash
+  version, file, algo, hash
 ) VALUES (
-  18, 1, 8192, X'fb8d027f03bb5ebb47741ed247eb9e174127b714d20229885feb37e0979aeb14a1b74020cded891d680441093625729c'
+  5, 1, 8192, 'fb8d027f03bb5ebb47741ed247eb9e174127b714d20229885feb37e0979aeb14a1b74020cded891d680441093625729c'
 );
 
 INSERT INTO file_hashes (
-  product, file, algo, hash
+  version, file, algo, hash
 ) VALUES (
-  18, 3, 32768, X'3715f2f94016a91fab5bbc503f0f1d43c5a9fc2b'
+  5, 3, 32768, '3715f2f94016a91fab5bbc503f0f1d43c5a9fc2b'
 );
 
 INSERT INTO file_hashes (
-  product, file, algo, hash
+  version, file, algo, hash
 ) VALUES (
-  18, 3, 16384, X'c03a5296b5decb87b01517f9927a8b2349dfb29ff9f5ba084f994c155ca5d4be'
+  5, 3, 16384, 'c03a5296b5decb87b01517f9927a8b2349dfb29ff9f5ba084f994c155ca5d4be'
 );
 
 INSERT INTO file_hashes (
-  product, file, algo, hash
+  version, file, algo, hash
 ) VALUES (
-  18, 3, 8192, X'b8bc345f56115235cc6091f61e312ce43ea54a5b99e7295002ae7b415fd35e06ec4c731ab70ad00d784bb53a318a2fa0'
+  5, 3, 8192, 'b8bc345f56115235cc6091f61e312ce43ea54a5b99e7295002ae7b415fd35e06ec4c731ab70ad00d784bb53a318a2fa0'
 );
 
 INSERT INTO file_hashes (
-  product, file, algo, hash
+  version, file, algo, hash
 ) VALUES (
-  18, 5, 32768, X'e59602f4edf24c1b36199588886d06665d4adcd7'
+  6, 5, 32768, 'e59602f4edf24c1b36199588886d06665d4adcd7'
 );
 
 INSERT INTO file_hashes (
-  product, file, algo, hash
+  version, file, algo, hash
 ) VALUES (
-  18, 5, 16384, X'090e1b77bda7fe665e498c6b5e09dbb7ddc5cfe57f213de48f4fb6736484f500'
+  6, 5, 16384, '090e1b77bda7fe665e498c6b5e09dbb7ddc5cfe57f213de48f4fb6736484f500'
 );
 
 INSERT INTO file_hashes (
-  product, file, algo, hash
+  version, file, algo, hash
 ) VALUES (
-  18, 5, 8192, X'7cbdb4612a13443dba910ecdef5161f2213e52c9b4a2eef14bcee5d287e9df931cd022e9e9715518ad9c9b6e3384a668'
+  6, 5, 8192, '7cbdb4612a13443dba910ecdef5161f2213e52c9b4a2eef14bcee5d287e9df931cd022e9e9715518ad9c9b6e3384a668'
 );
 
 /* Packages */
@@ -790,30 +796,42 @@ INSERT INTO packages (			/*  4 */
 
 /* Versions */
 
-INSERT INTO versions (
+INSERT INTO versions (             /*  1 */
   package, product, release, time
 ) VALUES (
   1, 28, '1.0.1e-2', 1366531494
 );
 
-INSERT INTO versions (
+INSERT INTO versions (             /*  2 */
   package, product, release, time
 ) VALUES (
   2, 28, '1.0.1e-2', 1366531494
 );
 
-INSERT INTO versions (
+INSERT INTO versions (             /*  3 */
   package, product, release, time
 ) VALUES (
   3, 28, '1.0.1e-2', 1366531494
 );
 
-INSERT INTO versions (
+INSERT INTO versions (             /*  4 */
   package, product, release, time
 ) VALUES (
   4, 28, '1.0.1e-2', 1366531494
 );
 
+INSERT INTO versions (             /*  5 */
+  package, product, time
+) VALUES (
+  2, 18, 1350544774
+);
+
+INSERT INTO versions (             /*  6 */
+  package, product, time
+) VALUES (
+  4, 18, 1350544774
+);
+
 /* Components */
 
 INSERT INTO components (
@@ -1681,59 +1699,59 @@ INSERT INTO enforcements (      /* 18 */
 INSERT INTO "swid_entities" (		/*  1 */
   "name", "regid"
 ) VALUES (
-  'strongSwan Project', 'regid.2004-03.org.strongswan'
+  'strongSwan Project', 'strongswan.org'
 );
 
 INSERT INTO swid_entities (			/*  2 */
   "name", "regid"
 ) VALUES (
-  'Adobe Systems Inc.', 'regid.1986-12.com.adobe'
+  'Adobe Systems Inc.', 'adobe.com'
 );
 
 INSERT INTO swid_entities (			/*  3 */
   "name", "regid"
 ) VALUES (
-  'Microsoft Corporation', 'regid.1991-06.com.microsoft'
+  'Microsoft Corporation', 'microsoft.com'
 );
 
 INSERT INTO swid_entities (			/*  4 */
   "name", "regid"
 ) VALUES (
-  'Ubuntu Project', 'regid.2004-05.com.ubuntu'
+  'Ubuntu Project', 'ubuntu.com'
 );
 
 INSERT INTO swid_entities (			/*  5 */
   "name", "regid"
 ) VALUES (
-  'Apache Software Foundation', 'regid.1995-04.org.apache'
+  'Apache Software Foundation', 'apache.org'
 );
 
 INSERT INTO swid_entities (			/*  6 */
   "name", "regid"
 ) VALUES (
-  'Debian Project', 'regid.1999-03.org.debian'
+  'Debian Project', 'debian.org'
 );
 
 INSERT INTO swid_entities (			/*  7 */
   "name", "regid"
 ) VALUES (
-  'Internet Systems Consortium', 'regid.1994-04.org.isc'
+  'Internet Systems Consortium', 'isc.org'
 );
 
 INSERT INTO swid_entities (			/*  8 */
   "name", "regid"
 ) VALUES (
-  'OpenSSL Project', 'regid.1998-12.org.openssl'
+  'OpenSSL Project', 'openssl.org'
 );
 
 INSERT INTO swid_entities (			/*  9 */
   "name", "regid"
 ) VALUES (
-  'Samba Project', 'regid.1998-01.org.samba'
+  'Samba Project', 'samba.org'
 );
 
 INSERT INTO swid_entities (			/* 10 */
   "name", "regid"
 ) VALUES (
-  'SQLite Project', 'regid.2002-08.org.sqlite'
+  'SQLite Project', 'sqlite.org'
 );
diff --git a/src/libimcv/imv/imv_policy_manager.c b/src/libimcv/imv/imv_policy_manager.c
index b730f8c..1988873 100644
--- a/src/libimcv/imv/imv_policy_manager.c
+++ b/src/libimcv/imv/imv_policy_manager.c
@@ -130,6 +130,31 @@ static bool iterate_enforcements(database_t *db, int device_id, int session_id,
 				case IMV_WORKITEM_DIR_META:
 					arg_int = dir;
 					break;
+				case IMV_WORKITEM_SWID_TAGS:
+					/* software [identifier] inventory by default */
+					arg_int = 0;
+
+					/* software identifiers only? */
+					if (device_id && strchr(argument, 'R'))
+					{
+						/* get last EID in order to set earliest EID */
+						e2 = db->query(db,
+							"SELECT eid FROM swid_events where device == ? "
+							"ORDER BY eid DESC", DB_UINT, device_id, DB_INT);
+						if (e2)
+						{
+							if (e2->enumerate(e2, &arg_int))
+							{
+								arg_int++;
+							}
+							else
+							{
+								arg_int = 1;
+							}
+							e2->destroy(e2);
+						}
+					}
+					break;
 				default:
 					arg_int = 0;
 			}
diff --git a/src/libimcv/imv/tables.sql b/src/libimcv/imv/tables.sql
index 5c2a656..8bde889 100644
--- a/src/libimcv/imv/tables.sql
+++ b/src/libimcv/imv/tables.sql
@@ -41,11 +41,15 @@ DROP TABLE IF EXISTS file_hashes;
 CREATE TABLE file_hashes (
   id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
   file INTEGER NOT NULL REFERENCES files(id),
-  product INTEGER NOT NULL REFERENCES products(id),
-  device INTEGER DEFAULT 0 REFERENCES devices(id),
+  version INTEGER REFERENCES versions(id),
+  device INTEGER REFERENCES devices(id),
+  size INTEGER,
   algo INTEGER NOT NULL REFERENCES algorithms(id),
-  hash BLOB NOT NULL
+  hash VARCHAR(64) NOT NULL,
+  mutable INTEGER DEFAULT 0
 );
+DROP INDEX IF EXISTS "file_hashes_idx";
+CREATE INDEX "file_hashes_idx" ON "file_hashes" ("file", "version", "algo");
 
 DROP TABLE IF EXISTS groups;
 CREATE TABLE groups (
@@ -177,9 +181,9 @@ CREATE INDEX packages_name ON packages (
 DROP TABLE IF EXISTS versions;
 CREATE TABLE versions (
   id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
-  package INTEGER NOT NULL REFERENCES packages(id),
   product INTEGER NOT NULL REFERENCES products(id),
-  release TEXT NOT NULL,
+  package INTEGER NOT NULL REFERENCES packages(id),
+  release TEXT,
   security INTEGER DEFAULT 0,
   blacklist INTEGER DEFAULT 0,
   time INTEGER DEFAULT 0
@@ -302,14 +306,47 @@ CREATE INDEX "swid_tags_sessions_session_id" ON "swid_tags_sessions" (
 
 DROP TABLE IF EXISTS "swid_tagstats";
 CREATE TABLE "swid_tagstats" (
-  "id" integer NOT NULL PRIMARY KEY,
-  "tag_id" integer NOT NULL REFERENCES "swid_tags" ("id"),
-  "device_id" integer NOT NULL REFERENCES "devices" ("id"),
-  "first_seen_id" integer NOT NULL REFERENCES "sessions" ("id"),
-  "last_seen_id" integer NOT NULL REFERENCES "sessions" ("id"),
+  "id" INTEGER NOT NULL PRIMARY KEY,
+  "tag_id" INTEGER NOT NULL REFERENCES "swid_tags" ("id"),
+  "device_id" INTEGER NOT NULL REFERENCES "devices" ("id"),
+  "first_seen_id" INTEGER NOT NULL REFERENCES "sessions" ("id"),
+  "last_seen_id" INTEGER NOT NULL REFERENCES "sessions" ("id"),
+  "first_installed_id" INTEGER REFERENCES "swid_events" ("id"),
+  "last_deleted_id" INTEGER REFERENCES "swid_events" ("id"),
   UNIQUE ("tag_id", "device_id")
 );
 CREATE INDEX "swid_tagstats_tag_id" ON "swid_tagstats" ("tag_id");
 CREATE INDEX "swid_tagstats_device_id" ON "swid_tagstats" ("device_id");
 CREATE INDEX "swid_tagstats_first_seen_id" ON "swid_tagstats" ("first_seen_id");
 CREATE INDEX "swid_tagstats_last_seen_id" ON "swid_tagstats" ("last_seen_id");
+
+DROP TABLE IF EXISTS "swid_events";
+CREATE TABLE "swid_events" (
+  "id" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
+  "device" INTEGER REFERENCES "devices" ("id"),
+  "epoch" INTEGER NOT NULL,
+  "eid" INTEGER NOT NULL,
+  "timestamp" CHAR(20) NOT NULL
+);
+DROP INDEX IF EXISTS "swid_events_device";
+CREATE INDEX "swid_events_device" ON "swid_events" (
+  "device"
+);
+
+DROP TABLE IF EXISTS "swid_tags_events";
+CREATE TABLE "swid_tags_events" (
+  "id" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
+  "tag_id" INTEGER NOT NULL REFERENCES "swid_tags" ("id"),
+  "event_id" INTEGER NOT NULL REFERENCES "swid_events" ("id"),
+  "action" INTEGER NOT NULL,
+  "record_id" INTEGER DEFAULT 0,
+  "source_id" INTEGER DEFAULT 0
+);
+DROP INDEX IF EXISTS "swid_tags_events_event_id";
+DROP INDEX IF EXISTS "swid_tags_events_tag_id";
+CREATE INDEX "swid_tags_events_event_id" ON "swid_tags_events" (
+  "event_id"
+);
+CREATE INDEX "swid_tags_events_tag_id" ON "swid_tags_events" (
+  "tag_id"
+);
diff --git a/src/libimcv/pa_tnc/pa_tnc_msg.c b/src/libimcv/pa_tnc/pa_tnc_msg.c
index 17c649d..5f5add7 100644
--- a/src/libimcv/pa_tnc/pa_tnc_msg.c
+++ b/src/libimcv/pa_tnc/pa_tnc_msg.c
@@ -299,8 +299,9 @@ METHOD(pa_tnc_msg_t, process_ietf_std_errors, bool,
 			error_code = error_attr->get_error_code(error_attr);
 			msg_info = error_attr->get_msg_info(error_attr);
 
-			/* skip errors from non-IETF namespaces */
-			if (error_code.vendor_id != PEN_IETF)
+			/* skip errors from non-IETF namespaces and non PA-TNC msg errors */
+			if (error_code.vendor_id != PEN_IETF ||
+				error_code.type > PA_ERROR_PA_TNC_MSG_ROOF)
 			{
 				continue;
 			}
diff --git a/src/libimcv/plugins/imc_attestation/Makefile.in b/src/libimcv/plugins/imc_attestation/Makefile.in
index d67050f..1600d4d 100644
--- a/src/libimcv/plugins/imc_attestation/Makefile.in
+++ b/src/libimcv/plugins/imc_attestation/Makefile.in
@@ -311,8 +311,6 @@ RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
 RUBYGEMDIR = @RUBYGEMDIR@
-RUBYINCLUDE = @RUBYINCLUDE@
-RUBYLIB = @RUBYLIB@
 SED = @SED@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
@@ -413,6 +411,8 @@ random_device = @random_device@
 resolv_conf = @resolv_conf@
 routing_table = @routing_table@
 routing_table_prio = @routing_table_prio@
+ruby_CFLAGS = @ruby_CFLAGS@
+ruby_LIBS = @ruby_LIBS@
 runstatedir = @runstatedir@
 s_plugins = @s_plugins@
 sbindir = @sbindir@
@@ -441,6 +441,10 @@ top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
 tss2_CFLAGS = @tss2_CFLAGS@
 tss2_LIBS = @tss2_LIBS@
+tss2_socket_CFLAGS = @tss2_socket_CFLAGS@
+tss2_socket_LIBS = @tss2_socket_LIBS@
+tss2_tabrmd_CFLAGS = @tss2_tabrmd_CFLAGS@
+tss2_tabrmd_LIBS = @tss2_tabrmd_LIBS@
 urandom_device = @urandom_device@
 xml_CFLAGS = @xml_CFLAGS@
 xml_LIBS = @xml_LIBS@
diff --git a/src/libimcv/plugins/imc_hcd/Makefile.in b/src/libimcv/plugins/imc_hcd/Makefile.in
index 981af39..b12499d 100644
--- a/src/libimcv/plugins/imc_hcd/Makefile.in
+++ b/src/libimcv/plugins/imc_hcd/Makefile.in
@@ -308,8 +308,6 @@ RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
 RUBYGEMDIR = @RUBYGEMDIR@
-RUBYINCLUDE = @RUBYINCLUDE@
-RUBYLIB = @RUBYLIB@
 SED = @SED@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
@@ -410,6 +408,8 @@ random_device = @random_device@
 resolv_conf = @resolv_conf@
 routing_table = @routing_table@
 routing_table_prio = @routing_table_prio@
+ruby_CFLAGS = @ruby_CFLAGS@
+ruby_LIBS = @ruby_LIBS@
 runstatedir = @runstatedir@
 s_plugins = @s_plugins@
 sbindir = @sbindir@
@@ -438,6 +438,10 @@ top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
 tss2_CFLAGS = @tss2_CFLAGS@
 tss2_LIBS = @tss2_LIBS@
+tss2_socket_CFLAGS = @tss2_socket_CFLAGS@
+tss2_socket_LIBS = @tss2_socket_LIBS@
+tss2_tabrmd_CFLAGS = @tss2_tabrmd_CFLAGS@
+tss2_tabrmd_LIBS = @tss2_tabrmd_LIBS@
 urandom_device = @urandom_device@
 xml_CFLAGS = @xml_CFLAGS@
 xml_LIBS = @xml_LIBS@
diff --git a/src/libimcv/plugins/imc_os/Makefile.in b/src/libimcv/plugins/imc_os/Makefile.in
index aa0c49a..14c6e02 100644
--- a/src/libimcv/plugins/imc_os/Makefile.in
+++ b/src/libimcv/plugins/imc_os/Makefile.in
@@ -308,8 +308,6 @@ RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
 RUBYGEMDIR = @RUBYGEMDIR@
-RUBYINCLUDE = @RUBYINCLUDE@
-RUBYLIB = @RUBYLIB@
 SED = @SED@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
@@ -410,6 +408,8 @@ random_device = @random_device@
 resolv_conf = @resolv_conf@
 routing_table = @routing_table@
 routing_table_prio = @routing_table_prio@
+ruby_CFLAGS = @ruby_CFLAGS@
+ruby_LIBS = @ruby_LIBS@
 runstatedir = @runstatedir@
 s_plugins = @s_plugins@
 sbindir = @sbindir@
@@ -438,6 +438,10 @@ top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
 tss2_CFLAGS = @tss2_CFLAGS@
 tss2_LIBS = @tss2_LIBS@
+tss2_socket_CFLAGS = @tss2_socket_CFLAGS@
+tss2_socket_LIBS = @tss2_socket_LIBS@
+tss2_tabrmd_CFLAGS = @tss2_tabrmd_CFLAGS@
+tss2_tabrmd_LIBS = @tss2_tabrmd_LIBS@
 urandom_device = @urandom_device@
 xml_CFLAGS = @xml_CFLAGS@
 xml_LIBS = @xml_LIBS@
diff --git a/src/libimcv/plugins/imc_scanner/Makefile.in b/src/libimcv/plugins/imc_scanner/Makefile.in
index 63b4315..664ffdf 100644
--- a/src/libimcv/plugins/imc_scanner/Makefile.in
+++ b/src/libimcv/plugins/imc_scanner/Makefile.in
@@ -309,8 +309,6 @@ RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
 RUBYGEMDIR = @RUBYGEMDIR@
-RUBYINCLUDE = @RUBYINCLUDE@
-RUBYLIB = @RUBYLIB@
 SED = @SED@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
@@ -411,6 +409,8 @@ random_device = @random_device@
 resolv_conf = @resolv_conf@
 routing_table = @routing_table@
 routing_table_prio = @routing_table_prio@
+ruby_CFLAGS = @ruby_CFLAGS@
+ruby_LIBS = @ruby_LIBS@
 runstatedir = @runstatedir@
 s_plugins = @s_plugins@
 sbindir = @sbindir@
@@ -439,6 +439,10 @@ top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
 tss2_CFLAGS = @tss2_CFLAGS@
 tss2_LIBS = @tss2_LIBS@
+tss2_socket_CFLAGS = @tss2_socket_CFLAGS@
+tss2_socket_LIBS = @tss2_socket_LIBS@
+tss2_tabrmd_CFLAGS = @tss2_tabrmd_CFLAGS@
+tss2_tabrmd_LIBS = @tss2_tabrmd_LIBS@
 urandom_device = @urandom_device@
 xml_CFLAGS = @xml_CFLAGS@
 xml_LIBS = @xml_LIBS@
diff --git a/src/libimcv/plugins/imc_swid/Makefile.am b/src/libimcv/plugins/imc_swid/Makefile.am
index c1cdb98..22f2e37 100644
--- a/src/libimcv/plugins/imc_swid/Makefile.am
+++ b/src/libimcv/plugins/imc_swid/Makefile.am
@@ -1,21 +1,20 @@
-regid = regid.2004-03.org.strongswan
+regid = strongswan.org
 unique_sw_id = strongSwan-$(PACKAGE_VERSION_MAJOR)-$(PACKAGE_VERSION_MINOR)-$(PACKAGE_VERSION_BUILD)$(PACKAGE_VERSION_REVIEW)
-swid_tag = $(regid)_$(unique_sw_id).swidtag
+swid_tag = $(regid)__$(unique_sw_id).swidtag
 
-swiddir = $(prefix)/share/$(regid)
-swid_DATA = $(swid_tag)
-ipsec_DATA = $(swid_tag)
-EXTRA_DIST = $(regid)_strongSwan.swidtag.in
-CLEANFILES = $(regid)_strongSwan*.swidtag
+swiddir = $(pkgdatadir)/swidtag
+dist_swid_DATA = $(swid_tag)
+EXTRA_DIST = $(regid)__strongSwan.swidtag.in
+CLEANFILES = $(regid)__strongSwan*.swidtag
 
-$(swid_tag) : regid.2004-03.org.strongswan_strongSwan.swidtag.in
+$(swid_tag) : $(regid)__strongSwan.swidtag.in
 	$(AM_V_GEN) \
 	sed \
 	-e "s:@VERSION_MAJOR@:$(PACKAGE_VERSION_MAJOR):" \
 	-e "s:@VERSION_MINOR@:$(PACKAGE_VERSION_MINOR):" \
 	-e "s:@VERSION_BUILD@:$(PACKAGE_VERSION_BUILD):" \
 	-e "s:@VERSION_REVIEW@:$(PACKAGE_VERSION_REVIEW):" \
-	$(srcdir)/$(regid)_strongSwan.swidtag.in > $@
+	$(srcdir)/$(regid)__strongSwan.swidtag.in > $@
 
 AM_CPPFLAGS = \
 	-I$(top_srcdir)/src/libstrongswan \
diff --git a/src/libimcv/plugins/imc_swid/Makefile.in b/src/libimcv/plugins/imc_swid/Makefile.in
index 02bc2bf..b6a77dd 100644
--- a/src/libimcv/plugins/imc_swid/Makefile.in
+++ b/src/libimcv/plugins/imc_swid/Makefile.in
@@ -103,7 +103,8 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/config/libtool.m4 \
 	$(top_srcdir)/configure.ac
 am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
 	$(ACLOCAL_M4)
-DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON)
+DIST_COMMON = $(srcdir)/Makefile.am $(dist_swid_DATA) \
+	$(am__DIST_COMMON)
 mkinstalldirs = $(install_sh) -d
 CONFIG_HEADER = $(top_builddir)/config.h
 CONFIG_CLEAN_FILES =
@@ -135,8 +136,7 @@ am__uninstall_files_from_dir = { \
     || { echo " ( cd '$$dir' && rm -f" $$files ")"; \
          $(am__cd) "$$dir" && rm -f $$files; }; \
   }
-am__installdirs = "$(DESTDIR)$(imcvdir)" "$(DESTDIR)$(ipsecdir)" \
-	"$(DESTDIR)$(swiddir)"
+am__installdirs = "$(DESTDIR)$(imcvdir)" "$(DESTDIR)$(swiddir)"
 LTLIBRARIES = $(imcv_LTLIBRARIES)
 imc_swid_la_DEPENDENCIES = $(top_builddir)/src/libimcv/libimcv.la \
 	$(top_builddir)/src/libstrongswan/libstrongswan.la
@@ -190,7 +190,7 @@ am__can_run_installinfo = \
     n|no|NO) false;; \
     *) (install-info --version) >/dev/null 2>&1;; \
   esac
-DATA = $(ipsec_DATA) $(swid_DATA)
+DATA = $(dist_swid_DATA)
 am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
 # Read a list of newline-separated strings from the standard input,
 # and print each of them once, without duplicates.  Input order is
@@ -311,8 +311,6 @@ RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
 RUBYGEMDIR = @RUBYGEMDIR@
-RUBYINCLUDE = @RUBYINCLUDE@
-RUBYLIB = @RUBYLIB@
 SED = @SED@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
@@ -413,6 +411,8 @@ random_device = @random_device@
 resolv_conf = @resolv_conf@
 routing_table = @routing_table@
 routing_table_prio = @routing_table_prio@
+ruby_CFLAGS = @ruby_CFLAGS@
+ruby_LIBS = @ruby_LIBS@
 runstatedir = @runstatedir@
 s_plugins = @s_plugins@
 sbindir = @sbindir@
@@ -441,17 +441,20 @@ top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
 tss2_CFLAGS = @tss2_CFLAGS@
 tss2_LIBS = @tss2_LIBS@
+tss2_socket_CFLAGS = @tss2_socket_CFLAGS@
+tss2_socket_LIBS = @tss2_socket_LIBS@
+tss2_tabrmd_CFLAGS = @tss2_tabrmd_CFLAGS@
+tss2_tabrmd_LIBS = @tss2_tabrmd_LIBS@
 urandom_device = @urandom_device@
 xml_CFLAGS = @xml_CFLAGS@
 xml_LIBS = @xml_LIBS@
-regid = regid.2004-03.org.strongswan
+regid = strongswan.org
 unique_sw_id = strongSwan-$(PACKAGE_VERSION_MAJOR)-$(PACKAGE_VERSION_MINOR)-$(PACKAGE_VERSION_BUILD)$(PACKAGE_VERSION_REVIEW)
-swid_tag = $(regid)_$(unique_sw_id).swidtag
-swiddir = $(prefix)/share/$(regid)
-swid_DATA = $(swid_tag)
-ipsec_DATA = $(swid_tag)
-EXTRA_DIST = $(regid)_strongSwan.swidtag.in
-CLEANFILES = $(regid)_strongSwan*.swidtag
+swid_tag = $(regid)__$(unique_sw_id).swidtag
+swiddir = $(pkgdatadir)/swidtag
+dist_swid_DATA = $(swid_tag)
+EXTRA_DIST = $(regid)__strongSwan.swidtag.in
+CLEANFILES = $(regid)__strongSwan*.swidtag
 AM_CPPFLAGS = \
 	-I$(top_srcdir)/src/libstrongswan \
 	-I$(top_srcdir)/src/libtncif \
@@ -578,30 +581,9 @@ mostlyclean-libtool:
 
 clean-libtool:
 	-rm -rf .libs _libs
-install-ipsecDATA: $(ipsec_DATA)
+install-dist_swidDATA: $(dist_swid_DATA)
 	@$(NORMAL_INSTALL)
-	@list='$(ipsec_DATA)'; test -n "$(ipsecdir)" || list=; \
-	if test -n "$$list"; then \
-	  echo " $(MKDIR_P) '$(DESTDIR)$(ipsecdir)'"; \
-	  $(MKDIR_P) "$(DESTDIR)$(ipsecdir)" || exit 1; \
-	fi; \
-	for p in $$list; do \
-	  if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
-	  echo "$$d$$p"; \
-	done | $(am__base_list) | \
-	while read files; do \
-	  echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(ipsecdir)'"; \
-	  $(INSTALL_DATA) $$files "$(DESTDIR)$(ipsecdir)" || exit $$?; \
-	done
-
-uninstall-ipsecDATA:
-	@$(NORMAL_UNINSTALL)
-	@list='$(ipsec_DATA)'; test -n "$(ipsecdir)" || list=; \
-	files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
-	dir='$(DESTDIR)$(ipsecdir)'; $(am__uninstall_files_from_dir)
-install-swidDATA: $(swid_DATA)
-	@$(NORMAL_INSTALL)
-	@list='$(swid_DATA)'; test -n "$(swiddir)" || list=; \
+	@list='$(dist_swid_DATA)'; test -n "$(swiddir)" || list=; \
 	if test -n "$$list"; then \
 	  echo " $(MKDIR_P) '$(DESTDIR)$(swiddir)'"; \
 	  $(MKDIR_P) "$(DESTDIR)$(swiddir)" || exit 1; \
@@ -615,9 +597,9 @@ install-swidDATA: $(swid_DATA)
 	  $(INSTALL_DATA) $$files "$(DESTDIR)$(swiddir)" || exit $$?; \
 	done
 
-uninstall-swidDATA:
+uninstall-dist_swidDATA:
 	@$(NORMAL_UNINSTALL)
-	@list='$(swid_DATA)'; test -n "$(swiddir)" || list=; \
+	@list='$(dist_swid_DATA)'; test -n "$(swiddir)" || list=; \
 	files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
 	dir='$(DESTDIR)$(swiddir)'; $(am__uninstall_files_from_dir)
 
@@ -707,7 +689,7 @@ check-am: all-am
 check: check-am
 all-am: Makefile $(LTLIBRARIES) $(DATA)
 installdirs:
-	for dir in "$(DESTDIR)$(imcvdir)" "$(DESTDIR)$(ipsecdir)" "$(DESTDIR)$(swiddir)"; do \
+	for dir in "$(DESTDIR)$(imcvdir)" "$(DESTDIR)$(swiddir)"; do \
 	  test -z "$$dir" || $(MKDIR_P) "$$dir"; \
 	done
 install: install-am
@@ -764,8 +746,7 @@ info: info-am
 
 info-am:
 
-install-data-am: install-imcvLTLIBRARIES install-ipsecDATA \
-	install-swidDATA
+install-data-am: install-dist_swidDATA install-imcvLTLIBRARIES
 
 install-dvi: install-dvi-am
 
@@ -811,8 +792,7 @@ ps: ps-am
 
 ps-am:
 
-uninstall-am: uninstall-imcvLTLIBRARIES uninstall-ipsecDATA \
-	uninstall-swidDATA
+uninstall-am: uninstall-dist_swidDATA uninstall-imcvLTLIBRARIES
 
 .MAKE: install-am install-strip
 
@@ -821,28 +801,28 @@ uninstall-am: uninstall-imcvLTLIBRARIES uninstall-ipsecDATA \
 	ctags-am 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-imcvLTLIBRARIES install-info install-info-am \
-	install-ipsecDATA install-man install-pdf install-pdf-am \
-	install-ps install-ps-am install-strip install-swidDATA \
-	installcheck installcheck-am installdirs maintainer-clean \
+	install-data-am install-dist_swidDATA install-dvi \
+	install-dvi-am install-exec install-exec-am install-html \
+	install-html-am install-imcvLTLIBRARIES install-info \
+	install-info-am install-man install-pdf install-pdf-am \
+	install-ps install-ps-am install-strip installcheck \
+	installcheck-am installdirs maintainer-clean \
 	maintainer-clean-generic mostlyclean mostlyclean-compile \
 	mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
-	tags tags-am uninstall uninstall-am uninstall-imcvLTLIBRARIES \
-	uninstall-ipsecDATA uninstall-swidDATA
+	tags tags-am uninstall uninstall-am uninstall-dist_swidDATA \
+	uninstall-imcvLTLIBRARIES
 
 .PRECIOUS: Makefile
 
 
-$(swid_tag) : regid.2004-03.org.strongswan_strongSwan.swidtag.in
+$(swid_tag) : $(regid)__strongSwan.swidtag.in
 	$(AM_V_GEN) \
 	sed \
 	-e "s:@VERSION_MAJOR@:$(PACKAGE_VERSION_MAJOR):" \
 	-e "s:@VERSION_MINOR@:$(PACKAGE_VERSION_MINOR):" \
 	-e "s:@VERSION_BUILD@:$(PACKAGE_VERSION_BUILD):" \
 	-e "s:@VERSION_REVIEW@:$(PACKAGE_VERSION_REVIEW):" \
-	$(srcdir)/$(regid)_strongSwan.swidtag.in > $@
+	$(srcdir)/$(regid)__strongSwan.swidtag.in > $@
 
 # 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/libimcv/plugins/imc_swid/imc_swid.c b/src/libimcv/plugins/imc_swid/imc_swid.c
index 0dcb9af..1468a59 100644
--- a/src/libimcv/plugins/imc_swid/imc_swid.c
+++ b/src/libimcv/plugins/imc_swid/imc_swid.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2013-2015 Andreas Steffen
+ * Copyright (C) 2013-2017 Andreas Steffen
  * HSR Hochschule fuer Technik Rapperswil
  *
  * This program is free software; you can redistribute it and/or modify it
@@ -30,8 +30,6 @@
 #include <pen/pen.h>
 #include <utils/debug.h>
 
-#define SWID_GENERATOR	"/usr/local/bin/swid_generator"
-
 /* IMC definitions */
 
 static const char imc_name[] = "SWID";
@@ -165,7 +163,7 @@ static bool add_swid_inventory(imc_state_t *state, imc_msg_t *msg,
 	pa_tnc_attr_t *attr, *attr_error;
 	imc_swid_state_t *swid_state;
 	swid_inventory_t *swid_inventory;
-	char *swid_directory, *swid_generator;
+	char *swid_directory;
 	uint32_t eid_epoch;
 	bool swid_pretty, swid_full;
 	enumerator_t *enumerator;
@@ -173,9 +171,6 @@ static bool add_swid_inventory(imc_state_t *state, imc_msg_t *msg,
 	swid_directory = lib->settings->get_str(lib->settings,
 								"%s.plugins.imc-swid.swid_directory",
 								 SWID_DIRECTORY, lib->ns);
-	swid_generator = lib->settings->get_str(lib->settings,
-								"%s.plugins.imc-swid.swid_generator",
-								 SWID_GENERATOR, lib->ns);
 	swid_pretty = lib->settings->get_bool(lib->settings,
 								"%s.plugins.imc-swid.swid_pretty",
 								 FALSE, lib->ns);
@@ -184,8 +179,8 @@ static bool add_swid_inventory(imc_state_t *state, imc_msg_t *msg,
 								 FALSE, lib->ns);
 
 	swid_inventory = swid_inventory_create(full_tags);
-	if (!swid_inventory->collect(swid_inventory, swid_directory, swid_generator,
-								 targets, swid_pretty, swid_full))
+	if (!swid_inventory->collect(swid_inventory, swid_directory, targets,
+								 swid_pretty, swid_full))
 	{
 		swid_inventory->destroy(swid_inventory);
 		attr_error = swid_error_create(TCG_SWID_ERROR, request_id,
diff --git a/src/libimcv/plugins/imc_swid/strongswan.org__strongSwan-5-6-0.swidtag b/src/libimcv/plugins/imc_swid/strongswan.org__strongSwan-5-6-0.swidtag
new file mode 100644
index 0000000..644c098
--- /dev/null
+++ b/src/libimcv/plugins/imc_swid/strongswan.org__strongSwan-5-6-0.swidtag
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="utf-8"?>
+<SoftwareIdentity
+  name="strongSwan"
+  tagId="strongSwan-5-6-0"
+  version="5.6.0" versionScheme="alphanumeric"
+  xmlns="http://standards.iso.org/iso/19770/-2/2015/schema.xsd">
+  <Entity
+    name="strongSwan Project"
+    regid="strongswan.org"
+    role="softwareCreator licensor tagCreator"/>
+</SoftwareIdentity>
diff --git a/src/libimcv/plugins/imc_swid/regid.2004-03.org.strongswan_strongSwan.swidtag.in b/src/libimcv/plugins/imc_swid/strongswan.org__strongSwan.swidtag.in
similarity index 50%
copy from src/libimcv/plugins/imc_swid/regid.2004-03.org.strongswan_strongSwan.swidtag.in
copy to src/libimcv/plugins/imc_swid/strongswan.org__strongSwan.swidtag.in
index 8b7b50f..0e5aa8d 100644
--- a/src/libimcv/plugins/imc_swid/regid.2004-03.org.strongswan_strongSwan.swidtag.in
+++ b/src/libimcv/plugins/imc_swid/strongswan.org__strongSwan.swidtag.in
@@ -1,12 +1,11 @@
 <?xml version="1.0" encoding="utf-8"?>
-
 <SoftwareIdentity
   name="strongSwan"
-  uniqueId="strongSwan- at VERSION_MAJOR@- at VERSION_MINOR@- at VERSION_BUILD@@VERSION_REVIEW@"
+  tagId="strongSwan- at VERSION_MAJOR@- at VERSION_MINOR@- at VERSION_BUILD@@VERSION_REVIEW@"
   version="@VERSION_MAJOR at .@VERSION_MINOR at .@VERSION_BUILD@@VERSION_REVIEW@" versionScheme="alphanumeric"
-  xmlns="http://standards.iso.org/iso/19770/-2/2014/schema.xsd">
+  xmlns="http://standards.iso.org/iso/19770/-2/2015/schema.xsd">
   <Entity
     name="strongSwan Project"
-    regid="regid.2004-03.org.strongswan"
-    role="publisher licensor tagcreator"/>
+    regid="strongswan.org"
+    role="softwareCreator licensor tagCreator"/>
 </SoftwareIdentity>
diff --git a/src/libimcv/plugins/imc_swima/Makefile.am b/src/libimcv/plugins/imc_swima/Makefile.am
new file mode 100644
index 0000000..4a29e79
--- /dev/null
+++ b/src/libimcv/plugins/imc_swima/Makefile.am
@@ -0,0 +1,33 @@
+regid = strongswan.org
+unique_sw_id = strongSwan-$(PACKAGE_VERSION_MAJOR)-$(PACKAGE_VERSION_MINOR)-$(PACKAGE_VERSION_BUILD)$(PACKAGE_VERSION_REVIEW)
+swid_tag = $(regid)__$(unique_sw_id).swidtag
+
+swiddir = $(pkgdatadir)/swidtag
+dist_swid_DATA = $(swid_tag)
+EXTRA_DIST = $(regid)__strongSwan.swidtag.in
+CLEANFILES = $(regid)__strongSwan*.swidtag
+
+$(swid_tag) : $(regid)__strongSwan.swidtag.in
+	$(AM_V_GEN) \
+	sed \
+	-e "s:@VERSION_MAJOR@:$(PACKAGE_VERSION_MAJOR):" \
+	-e "s:@VERSION_MINOR@:$(PACKAGE_VERSION_MINOR):" \
+	-e "s:@VERSION_BUILD@:$(PACKAGE_VERSION_BUILD):" \
+	-e "s:@VERSION_REVIEW@:$(PACKAGE_VERSION_REVIEW):" \
+	$(srcdir)/$(regid)__strongSwan.swidtag.in > $@
+
+AM_CPPFLAGS = \
+	-I$(top_srcdir)/src/libstrongswan \
+	-I$(top_srcdir)/src/libtncif \
+	-I$(top_srcdir)/src/libimcv
+
+AM_CFLAGS = \
+	$(PLUGIN_CFLAGS) $(json_CFLAGS)
+
+imcv_LTLIBRARIES = imc-swima.la
+
+imc_swima_la_LIBADD = \
+	$(top_builddir)/src/libimcv/libimcv.la \
+	$(top_builddir)/src/libstrongswan/libstrongswan.la
+imc_swima_la_SOURCES = imc_swima.c imc_swima_state.h imc_swima_state.c
+imc_swima_la_LDFLAGS = -module -avoid-version -no-undefined
diff --git a/src/libimcv/plugins/imc_swid/Makefile.in b/src/libimcv/plugins/imc_swima/Makefile.in
similarity index 87%
copy from src/libimcv/plugins/imc_swid/Makefile.in
copy to src/libimcv/plugins/imc_swima/Makefile.in
index 02bc2bf..ae1d024 100644
--- a/src/libimcv/plugins/imc_swid/Makefile.in
+++ b/src/libimcv/plugins/imc_swima/Makefile.in
@@ -89,7 +89,7 @@ PRE_UNINSTALL = :
 POST_UNINSTALL = :
 build_triplet = @build@
 host_triplet = @host@
-subdir = src/libimcv/plugins/imc_swid
+subdir = src/libimcv/plugins/imc_swima
 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
 am__aclocal_m4_deps = $(top_srcdir)/m4/config/libtool.m4 \
 	$(top_srcdir)/m4/config/ltoptions.m4 \
@@ -103,7 +103,8 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/config/libtool.m4 \
 	$(top_srcdir)/configure.ac
 am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
 	$(ACLOCAL_M4)
-DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON)
+DIST_COMMON = $(srcdir)/Makefile.am $(dist_swid_DATA) \
+	$(am__DIST_COMMON)
 mkinstalldirs = $(install_sh) -d
 CONFIG_HEADER = $(top_builddir)/config.h
 CONFIG_CLEAN_FILES =
@@ -135,20 +136,19 @@ am__uninstall_files_from_dir = { \
     || { echo " ( cd '$$dir' && rm -f" $$files ")"; \
          $(am__cd) "$$dir" && rm -f $$files; }; \
   }
-am__installdirs = "$(DESTDIR)$(imcvdir)" "$(DESTDIR)$(ipsecdir)" \
-	"$(DESTDIR)$(swiddir)"
+am__installdirs = "$(DESTDIR)$(imcvdir)" "$(DESTDIR)$(swiddir)"
 LTLIBRARIES = $(imcv_LTLIBRARIES)
-imc_swid_la_DEPENDENCIES = $(top_builddir)/src/libimcv/libimcv.la \
+imc_swima_la_DEPENDENCIES = $(top_builddir)/src/libimcv/libimcv.la \
 	$(top_builddir)/src/libstrongswan/libstrongswan.la
-am_imc_swid_la_OBJECTS = imc_swid.lo imc_swid_state.lo
-imc_swid_la_OBJECTS = $(am_imc_swid_la_OBJECTS)
+am_imc_swima_la_OBJECTS = imc_swima.lo imc_swima_state.lo
+imc_swima_la_OBJECTS = $(am_imc_swima_la_OBJECTS)
 AM_V_lt = $(am__v_lt_ at AM_V@)
 am__v_lt_ = $(am__v_lt_ at AM_DEFAULT_V@)
 am__v_lt_0 = --silent
 am__v_lt_1 = 
-imc_swid_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+imc_swima_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
 	$(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
-	$(imc_swid_la_LDFLAGS) $(LDFLAGS) -o $@
+	$(imc_swima_la_LDFLAGS) $(LDFLAGS) -o $@
 AM_V_P = $(am__v_P_ at AM_V@)
 am__v_P_ = $(am__v_P_ at AM_DEFAULT_V@)
 am__v_P_0 = false
@@ -183,14 +183,14 @@ AM_V_CCLD = $(am__v_CCLD_ at AM_V@)
 am__v_CCLD_ = $(am__v_CCLD_ at AM_DEFAULT_V@)
 am__v_CCLD_0 = @echo "  CCLD    " $@;
 am__v_CCLD_1 = 
-SOURCES = $(imc_swid_la_SOURCES)
-DIST_SOURCES = $(imc_swid_la_SOURCES)
+SOURCES = $(imc_swima_la_SOURCES)
+DIST_SOURCES = $(imc_swima_la_SOURCES)
 am__can_run_installinfo = \
   case $$AM_UPDATE_INFO_DIR in \
     n|no|NO) false;; \
     *) (install-info --version) >/dev/null 2>&1;; \
   esac
-DATA = $(ipsec_DATA) $(swid_DATA)
+DATA = $(dist_swid_DATA)
 am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
 # Read a list of newline-separated strings from the standard input,
 # and print each of them once, without duplicates.  Input order is
@@ -311,8 +311,6 @@ RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
 RUBYGEMDIR = @RUBYGEMDIR@
-RUBYINCLUDE = @RUBYINCLUDE@
-RUBYLIB = @RUBYLIB@
 SED = @SED@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
@@ -413,6 +411,8 @@ random_device = @random_device@
 resolv_conf = @resolv_conf@
 routing_table = @routing_table@
 routing_table_prio = @routing_table_prio@
+ruby_CFLAGS = @ruby_CFLAGS@
+ruby_LIBS = @ruby_LIBS@
 runstatedir = @runstatedir@
 s_plugins = @s_plugins@
 sbindir = @sbindir@
@@ -441,33 +441,35 @@ top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
 tss2_CFLAGS = @tss2_CFLAGS@
 tss2_LIBS = @tss2_LIBS@
+tss2_socket_CFLAGS = @tss2_socket_CFLAGS@
+tss2_socket_LIBS = @tss2_socket_LIBS@
+tss2_tabrmd_CFLAGS = @tss2_tabrmd_CFLAGS@
+tss2_tabrmd_LIBS = @tss2_tabrmd_LIBS@
 urandom_device = @urandom_device@
 xml_CFLAGS = @xml_CFLAGS@
 xml_LIBS = @xml_LIBS@
-regid = regid.2004-03.org.strongswan
+regid = strongswan.org
 unique_sw_id = strongSwan-$(PACKAGE_VERSION_MAJOR)-$(PACKAGE_VERSION_MINOR)-$(PACKAGE_VERSION_BUILD)$(PACKAGE_VERSION_REVIEW)
-swid_tag = $(regid)_$(unique_sw_id).swidtag
-swiddir = $(prefix)/share/$(regid)
-swid_DATA = $(swid_tag)
-ipsec_DATA = $(swid_tag)
-EXTRA_DIST = $(regid)_strongSwan.swidtag.in
-CLEANFILES = $(regid)_strongSwan*.swidtag
+swid_tag = $(regid)__$(unique_sw_id).swidtag
+swiddir = $(pkgdatadir)/swidtag
+dist_swid_DATA = $(swid_tag)
+EXTRA_DIST = $(regid)__strongSwan.swidtag.in
+CLEANFILES = $(regid)__strongSwan*.swidtag
 AM_CPPFLAGS = \
 	-I$(top_srcdir)/src/libstrongswan \
 	-I$(top_srcdir)/src/libtncif \
-	-I$(top_srcdir)/src/libimcv \
-	-DSWID_DIRECTORY=\"${prefix}/share\"
+	-I$(top_srcdir)/src/libimcv
 
 AM_CFLAGS = \
-	$(PLUGIN_CFLAGS)
+	$(PLUGIN_CFLAGS) $(json_CFLAGS)
 
-imcv_LTLIBRARIES = imc-swid.la
-imc_swid_la_LIBADD = \
+imcv_LTLIBRARIES = imc-swima.la
+imc_swima_la_LIBADD = \
 	$(top_builddir)/src/libimcv/libimcv.la \
 	$(top_builddir)/src/libstrongswan/libstrongswan.la
 
-imc_swid_la_SOURCES = imc_swid.c imc_swid_state.h imc_swid_state.c
-imc_swid_la_LDFLAGS = -module -avoid-version -no-undefined
+imc_swima_la_SOURCES = imc_swima.c imc_swima_state.h imc_swima_state.c
+imc_swima_la_LDFLAGS = -module -avoid-version -no-undefined
 all: all-am
 
 .SUFFIXES:
@@ -481,9 +483,9 @@ $(srcdir)/Makefile.in:  $(srcdir)/Makefile.am  $(am__configure_deps)
 	      exit 1;; \
 	  esac; \
 	done; \
-	echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/libimcv/plugins/imc_swid/Makefile'; \
+	echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/libimcv/plugins/imc_swima/Makefile'; \
 	$(am__cd) $(top_srcdir) && \
-	  $(AUTOMAKE) --gnu src/libimcv/plugins/imc_swid/Makefile
+	  $(AUTOMAKE) --gnu src/libimcv/plugins/imc_swima/Makefile
 Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
 	@case '$?' in \
 	  *config.status*) \
@@ -537,8 +539,8 @@ clean-imcvLTLIBRARIES:
 	  rm -f $${locs}; \
 	}
 
-imc-swid.la: $(imc_swid_la_OBJECTS) $(imc_swid_la_DEPENDENCIES) $(EXTRA_imc_swid_la_DEPENDENCIES) 
-	$(AM_V_CCLD)$(imc_swid_la_LINK) -rpath $(imcvdir) $(imc_swid_la_OBJECTS) $(imc_swid_la_LIBADD) $(LIBS)
+imc-swima.la: $(imc_swima_la_OBJECTS) $(imc_swima_la_DEPENDENCIES) $(EXTRA_imc_swima_la_DEPENDENCIES) 
+	$(AM_V_CCLD)$(imc_swima_la_LINK) -rpath $(imcvdir) $(imc_swima_la_OBJECTS) $(imc_swima_la_LIBADD) $(LIBS)
 
 mostlyclean-compile:
 	-rm -f *.$(OBJEXT)
@@ -546,8 +548,8 @@ mostlyclean-compile:
 distclean-compile:
 	-rm -f *.tab.c
 
- at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/imc_swid.Plo at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/imc_swid_state.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/imc_swima.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/imc_swima_state.Plo at am__quote@
 
 .c.o:
 @am__fastdepCC_TRUE@	$(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\
@@ -578,30 +580,9 @@ mostlyclean-libtool:
 
 clean-libtool:
 	-rm -rf .libs _libs
-install-ipsecDATA: $(ipsec_DATA)
+install-dist_swidDATA: $(dist_swid_DATA)
 	@$(NORMAL_INSTALL)
-	@list='$(ipsec_DATA)'; test -n "$(ipsecdir)" || list=; \
-	if test -n "$$list"; then \
-	  echo " $(MKDIR_P) '$(DESTDIR)$(ipsecdir)'"; \
-	  $(MKDIR_P) "$(DESTDIR)$(ipsecdir)" || exit 1; \
-	fi; \
-	for p in $$list; do \
-	  if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
-	  echo "$$d$$p"; \
-	done | $(am__base_list) | \
-	while read files; do \
-	  echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(ipsecdir)'"; \
-	  $(INSTALL_DATA) $$files "$(DESTDIR)$(ipsecdir)" || exit $$?; \
-	done
-
-uninstall-ipsecDATA:
-	@$(NORMAL_UNINSTALL)
-	@list='$(ipsec_DATA)'; test -n "$(ipsecdir)" || list=; \
-	files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
-	dir='$(DESTDIR)$(ipsecdir)'; $(am__uninstall_files_from_dir)
-install-swidDATA: $(swid_DATA)
-	@$(NORMAL_INSTALL)
-	@list='$(swid_DATA)'; test -n "$(swiddir)" || list=; \
+	@list='$(dist_swid_DATA)'; test -n "$(swiddir)" || list=; \
 	if test -n "$$list"; then \
 	  echo " $(MKDIR_P) '$(DESTDIR)$(swiddir)'"; \
 	  $(MKDIR_P) "$(DESTDIR)$(swiddir)" || exit 1; \
@@ -615,9 +596,9 @@ install-swidDATA: $(swid_DATA)
 	  $(INSTALL_DATA) $$files "$(DESTDIR)$(swiddir)" || exit $$?; \
 	done
 
-uninstall-swidDATA:
+uninstall-dist_swidDATA:
 	@$(NORMAL_UNINSTALL)
-	@list='$(swid_DATA)'; test -n "$(swiddir)" || list=; \
+	@list='$(dist_swid_DATA)'; test -n "$(swiddir)" || list=; \
 	files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
 	dir='$(DESTDIR)$(swiddir)'; $(am__uninstall_files_from_dir)
 
@@ -707,7 +688,7 @@ check-am: all-am
 check: check-am
 all-am: Makefile $(LTLIBRARIES) $(DATA)
 installdirs:
-	for dir in "$(DESTDIR)$(imcvdir)" "$(DESTDIR)$(ipsecdir)" "$(DESTDIR)$(swiddir)"; do \
+	for dir in "$(DESTDIR)$(imcvdir)" "$(DESTDIR)$(swiddir)"; do \
 	  test -z "$$dir" || $(MKDIR_P) "$$dir"; \
 	done
 install: install-am
@@ -764,8 +745,7 @@ info: info-am
 
 info-am:
 
-install-data-am: install-imcvLTLIBRARIES install-ipsecDATA \
-	install-swidDATA
+install-data-am: install-dist_swidDATA install-imcvLTLIBRARIES
 
 install-dvi: install-dvi-am
 
@@ -811,8 +791,7 @@ ps: ps-am
 
 ps-am:
 
-uninstall-am: uninstall-imcvLTLIBRARIES uninstall-ipsecDATA \
-	uninstall-swidDATA
+uninstall-am: uninstall-dist_swidDATA uninstall-imcvLTLIBRARIES
 
 .MAKE: install-am install-strip
 
@@ -821,28 +800,28 @@ uninstall-am: uninstall-imcvLTLIBRARIES uninstall-ipsecDATA \
 	ctags-am 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-imcvLTLIBRARIES install-info install-info-am \
-	install-ipsecDATA install-man install-pdf install-pdf-am \
-	install-ps install-ps-am install-strip install-swidDATA \
-	installcheck installcheck-am installdirs maintainer-clean \
+	install-data-am install-dist_swidDATA install-dvi \
+	install-dvi-am install-exec install-exec-am install-html \
+	install-html-am install-imcvLTLIBRARIES install-info \
+	install-info-am install-man install-pdf install-pdf-am \
+	install-ps install-ps-am install-strip installcheck \
+	installcheck-am installdirs maintainer-clean \
 	maintainer-clean-generic mostlyclean mostlyclean-compile \
 	mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
-	tags tags-am uninstall uninstall-am uninstall-imcvLTLIBRARIES \
-	uninstall-ipsecDATA uninstall-swidDATA
+	tags tags-am uninstall uninstall-am uninstall-dist_swidDATA \
+	uninstall-imcvLTLIBRARIES
 
 .PRECIOUS: Makefile
 
 
-$(swid_tag) : regid.2004-03.org.strongswan_strongSwan.swidtag.in
+$(swid_tag) : $(regid)__strongSwan.swidtag.in
 	$(AM_V_GEN) \
 	sed \
 	-e "s:@VERSION_MAJOR@:$(PACKAGE_VERSION_MAJOR):" \
 	-e "s:@VERSION_MINOR@:$(PACKAGE_VERSION_MINOR):" \
 	-e "s:@VERSION_BUILD@:$(PACKAGE_VERSION_BUILD):" \
 	-e "s:@VERSION_REVIEW@:$(PACKAGE_VERSION_REVIEW):" \
-	$(srcdir)/$(regid)_strongSwan.swidtag.in > $@
+	$(srcdir)/$(regid)__strongSwan.swidtag.in > $@
 
 # 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/libimcv/plugins/imc_swid/imc_swid.c b/src/libimcv/plugins/imc_swima/imc_swima.c
similarity index 60%
copy from src/libimcv/plugins/imc_swid/imc_swid.c
copy to src/libimcv/plugins/imc_swima/imc_swima.c
index 0dcb9af..e120cf7 100644
--- a/src/libimcv/plugins/imc_swid/imc_swid.c
+++ b/src/libimcv/plugins/imc_swima/imc_swima.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2013-2015 Andreas Steffen
+ * Copyright (C) 2017 Andreas Steffen
  * HSR Hochschule fuer Technik Rapperswil
  *
  * This program is free software; you can redistribute it and/or modify it
@@ -13,34 +13,32 @@
  * for more details.
  */
 
-#include "imc_swid_state.h"
+#include "imc_swima_state.h"
 
 #include <imc/imc_agent.h>
 #include <imc/imc_msg.h>
+#include "ietf/swima/ietf_swima_attr_req.h"
+#include "ietf/swima/ietf_swima_attr_sw_inv.h"
+#include "ietf/swima/ietf_swima_attr_sw_ev.h"
+#include "swima/swima_inventory.h"
+#include "swima/swima_collector.h"
+#include "swima/swima_error.h"
 #include "tcg/seg/tcg_seg_attr_max_size.h"
 #include "tcg/seg/tcg_seg_attr_seg_env.h"
-#include "tcg/swid/tcg_swid_attr_req.h"
-#include "tcg/swid/tcg_swid_attr_tag_inv.h"
-#include "tcg/swid/tcg_swid_attr_tag_id_inv.h"
-#include "swid/swid_inventory.h"
-#include "swid/swid_error.h"
 
 #include <tncif_pa_subtypes.h>
-
 #include <pen/pen.h>
 #include <utils/debug.h>
 
-#define SWID_GENERATOR	"/usr/local/bin/swid_generator"
-
 /* IMC definitions */
 
-static const char imc_name[] = "SWID";
+static const char imc_name[] = "SWIMA";
 
 static pen_type_t msg_types[] = {
-	{ PEN_TCG, PA_SUBTYPE_TCG_SWID }
+	{ PEN_IETF, PA_SUBTYPE_IETF_SW }
 };
 
-static imc_agent_t *imc_swid;
+static imc_agent_t *imc_swima;
 
 /**
  * see section 3.8.1 of TCG TNC IF-IMC Specification 1.3
@@ -50,14 +48,14 @@ TNC_Result TNC_IMC_Initialize(TNC_IMCID imc_id,
 							  TNC_Version max_version,
 							  TNC_Version *actual_version)
 {
-	if (imc_swid)
+	if (imc_swima)
 	{
 		DBG1(DBG_IMC, "IMC \"%s\" has already been initialized", imc_name);
 		return TNC_RESULT_ALREADY_INITIALIZED;
 	}
-	imc_swid = imc_agent_create(imc_name, msg_types, countof(msg_types),
-							  imc_id, actual_version);
-	if (!imc_swid)
+	imc_swima = imc_agent_create(imc_name, msg_types, countof(msg_types),
+								 imc_id, actual_version);
+	if (!imc_swima)
 	{
 		return TNC_RESULT_FATAL;
 	}
@@ -78,7 +76,7 @@ TNC_Result TNC_IMC_NotifyConnectionChange(TNC_IMCID imc_id,
 {
 	imc_state_t *state;
 
-	if (!imc_swid)
+	if (!imc_swima)
 	{
 		DBG1(DBG_IMC, "IMC \"%s\" has not been initialized", imc_name);
 		return TNC_RESULT_NOT_INITIALIZED;
@@ -86,10 +84,10 @@ TNC_Result TNC_IMC_NotifyConnectionChange(TNC_IMCID imc_id,
 	switch (new_state)
 	{
 		case TNC_CONNECTION_STATE_CREATE:
-			state = imc_swid_state_create(connection_id);
-			return imc_swid->create_state(imc_swid, state);
+			state = imc_swima_state_create(connection_id);
+			return imc_swima->create_state(imc_swima, state);
 		case TNC_CONNECTION_STATE_HANDSHAKE:
-			if (imc_swid->change_state(imc_swid, connection_id, new_state,
+			if (imc_swima->change_state(imc_swima, connection_id, new_state,
 				&state) != TNC_RESULT_SUCCESS)
 			{
 				return TNC_RESULT_FATAL;
@@ -98,10 +96,10 @@ TNC_Result TNC_IMC_NotifyConnectionChange(TNC_IMCID imc_id,
 							  TNC_IMV_EVALUATION_RESULT_DONT_KNOW);
 			return TNC_RESULT_SUCCESS;
 		case TNC_CONNECTION_STATE_DELETE:
-			return imc_swid->delete_state(imc_swid, connection_id);
+			return imc_swima->delete_state(imc_swima, connection_id);
 		default:
-			return imc_swid->change_state(imc_swid, connection_id,
-										  new_state, NULL);
+			return imc_swima->change_state(imc_swima, connection_id,
+										   new_state, NULL);
 	}
 }
 
@@ -116,17 +114,17 @@ TNC_Result TNC_IMC_BeginHandshake(TNC_IMCID imc_id,
 	pa_tnc_attr_t *attr;
 	seg_contract_t *contract;
 	seg_contract_manager_t *contracts;
-	size_t max_attr_size = SWID_MAX_ATTR_SIZE;
+	size_t max_attr_size = SWIMA_MAX_ATTR_SIZE;
 	size_t max_seg_size;
 	char buf[BUF_LEN];
 	TNC_Result result = TNC_RESULT_SUCCESS;
 
-	if (!imc_swid)
+	if (!imc_swima)
 	{
 		DBG1(DBG_IMC, "IMC \"%s\" has not been initialized", imc_name);
 		return TNC_RESULT_NOT_INITIALIZED;
 	}
-	if (!imc_swid->get_state(imc_swid, connection_id, &state))
+	if (!imc_swima->get_state(imc_swima, connection_id, &state))
 	{
 		return TNC_RESULT_FATAL;
 	}
@@ -138,7 +136,7 @@ TNC_Result TNC_IMC_BeginHandshake(TNC_IMCID imc_id,
 
 	/* Announce support of PA-TNC segmentation to IMV */
 	contract = seg_contract_create(msg_types[0], max_attr_size, max_seg_size,
-									 TRUE, imc_id, TRUE);
+								   TRUE, imc_id, TRUE);
 	contract->get_info_string(contract, buf, BUF_LEN, TRUE);
 	DBG2(DBG_IMC, "%s", buf);
 	contracts = state->get_contracts(state);
@@ -146,7 +144,7 @@ TNC_Result TNC_IMC_BeginHandshake(TNC_IMCID imc_id,
 	attr = tcg_seg_attr_max_size_create(max_attr_size, max_seg_size, TRUE);
 
 	/* send PA-TNC message with the excl flag not set */
-	out_msg = imc_msg_create(imc_swid, state, connection_id, imc_id,
+	out_msg = imc_msg_create(imc_swima, state, connection_id, imc_id,
 							 TNC_IMVID_ANY, msg_types[0]);
 	out_msg->add_attribute(out_msg, attr);
 	result = out_msg->send(out_msg, FALSE);
@@ -156,87 +154,76 @@ TNC_Result TNC_IMC_BeginHandshake(TNC_IMCID imc_id,
 }
 
 /**
- * Add one or multiple SWID Inventory attributes to the send queue
+ * Add SWID Inventory or Event attribute to the send queue
  */
-static bool add_swid_inventory(imc_state_t *state, imc_msg_t *msg,
-							   uint32_t request_id, bool full_tags,
-							   swid_inventory_t *targets)
+static void fulfill_request(imc_state_t *state, imc_msg_t *msg,
+							uint32_t request_id, bool sw_id_only,
+							swima_inventory_t *targets)
 {
-	pa_tnc_attr_t *attr, *attr_error;
-	imc_swid_state_t *swid_state;
-	swid_inventory_t *swid_inventory;
-	char *swid_directory, *swid_generator;
-	uint32_t eid_epoch;
-	bool swid_pretty, swid_full;
-	enumerator_t *enumerator;
-
-	swid_directory = lib->settings->get_str(lib->settings,
-								"%s.plugins.imc-swid.swid_directory",
-								 SWID_DIRECTORY, lib->ns);
-	swid_generator = lib->settings->get_str(lib->settings,
-								"%s.plugins.imc-swid.swid_generator",
-								 SWID_GENERATOR, lib->ns);
-	swid_pretty = lib->settings->get_bool(lib->settings,
-								"%s.plugins.imc-swid.swid_pretty",
-								 FALSE, lib->ns);
-	swid_full = lib->settings->get_bool(lib->settings,
-								"%s.plugins.imc-swid.swid_full",
-								 FALSE, lib->ns);
-
-	swid_inventory = swid_inventory_create(full_tags);
-	if (!swid_inventory->collect(swid_inventory, swid_directory, swid_generator,
-								 targets, swid_pretty, swid_full))
-	{
-		swid_inventory->destroy(swid_inventory);
-		attr_error = swid_error_create(TCG_SWID_ERROR, request_id,
-								 0, "error in SWID tag collection");
-		msg->add_attribute(msg, attr_error);
-		return FALSE;
-	}
-	DBG1(DBG_IMC, "collected %d SWID tag%s%s",
-		 swid_inventory->get_count(swid_inventory), full_tags ? "" : " ID",
-		 swid_inventory->get_count(swid_inventory) == 1 ? "" : "s");
+	pa_tnc_attr_t *attr;
+	swima_collector_t  *collector;
+	size_t msg_len = 64;
+	char error_msg[msg_len], *id_str;
+	bool collect_inventory = TRUE;
+	int items;
 
-	swid_state = (imc_swid_state_t*)state;
-	eid_epoch = swid_state->get_eid_epoch(swid_state);
+	collector = swima_collector_create();
+	id_str = sw_id_only ? " ID" : "";
 
-	if (full_tags)
+	if (targets->get_eid(targets, NULL) > 0)
 	{
-		tcg_swid_attr_tag_inv_t *swid_attr;
-		swid_tag_t *tag;
-
-		/* Send a TCG SWID Tag Inventory attribute */
-		attr = tcg_swid_attr_tag_inv_create(request_id, eid_epoch, 1);
-		swid_attr = (tcg_swid_attr_tag_inv_t*)attr;
+		swima_events_t *sw_ev;
+		ietf_swima_attr_sw_ev_t *sw_ev_attr;
 
-		enumerator = swid_inventory->create_enumerator(swid_inventory);
-		while (enumerator->enumerate(enumerator, &tag))
+		sw_ev = collector->collect_events(collector, sw_id_only, targets);
+		if (!sw_ev)
 		{
-			swid_attr->add(swid_attr, tag->get_ref(tag));
+			snprintf(error_msg, msg_len, "failed to collect SW%s events, "
+					 "fallback to SW%s inventory", id_str, id_str);
+			attr = swima_error_create(PA_ERROR_SW, request_id, 0, error_msg);
+			msg->add_attribute(msg, attr);
+		}
+		else {
+			items = sw_ev->get_count(sw_ev);
+			DBG1(DBG_IMC, "collected %d SW%s event%s", items, id_str,
+													   items == 1 ? "" : "s");
+
+			/* Send an IETF SW [Identity] Events attribute */
+			attr = ietf_swima_attr_sw_ev_create(IETF_SWIMA_ATTR_SW_INV_FLAG_NONE,
+											 request_id, sw_id_only);
+			sw_ev_attr = (ietf_swima_attr_sw_ev_t*)attr;
+			sw_ev_attr->set_events(sw_ev_attr, sw_ev);
+			collect_inventory = FALSE;
 		}
-		enumerator->destroy(enumerator);
 	}
-	else
-	{
-		tcg_swid_attr_tag_id_inv_t *swid_id_attr;
-		swid_tag_id_t *tag_id;
 
-		/* Send a TCG SWID Tag ID Inventory attribute */
-		attr = tcg_swid_attr_tag_id_inv_create(request_id, eid_epoch, 1);
-		swid_id_attr = (tcg_swid_attr_tag_id_inv_t*)attr;
+	if (collect_inventory)
+	{
+		swima_inventory_t *sw_inv;
+		ietf_swima_attr_sw_inv_t *sw_inv_attr;
 
-		enumerator = swid_inventory->create_enumerator(swid_inventory);
-		while (enumerator->enumerate(enumerator, &tag_id))
+		sw_inv = collector->collect_inventory(collector, sw_id_only, targets);
+		if (!sw_inv)
 		{
-			swid_id_attr->add(swid_id_attr, tag_id->get_ref(tag_id));
+			snprintf(error_msg, msg_len, "failed to collect SW%s inventory",
+					 id_str);
+			attr = swima_error_create(PA_ERROR_SW, request_id, 0, error_msg);
+		}
+		else
+		{
+			items = sw_inv->get_count(sw_inv);
+			DBG1(DBG_IMC, "collected %d SW%s record%s", items, id_str,
+														items == 1 ? "" : "s");
+
+			/* Send an IETF SW [Identity] Inventory attribute */
+			attr = ietf_swima_attr_sw_inv_create(IETF_SWIMA_ATTR_SW_INV_FLAG_NONE,
+												 request_id, sw_id_only);
+			sw_inv_attr = (ietf_swima_attr_sw_inv_t*)attr;
+			sw_inv_attr->set_inventory(sw_inv_attr, sw_inv);
 		}
-		enumerator->destroy(enumerator);
 	}
-
 	msg->add_attribute(msg, attr);
-	swid_inventory->destroy(swid_inventory);
-
-	return TRUE;
+	collector->destroy(collector);
 }
 
 static TNC_Result receive_message(imc_state_t *state, imc_msg_t *in_msg)
@@ -263,37 +250,35 @@ static TNC_Result receive_message(imc_state_t *state, imc_msg_t *in_msg)
 	enumerator = in_msg->create_attribute_enumerator(in_msg);
 	while (enumerator->enumerate(enumerator, &attr))
 	{
-		tcg_swid_attr_req_t *attr_req;
+		ietf_swima_attr_req_t *attr_req;
 		uint8_t flags;
 		uint32_t request_id;
-		bool full_tags;
-		swid_inventory_t *targets;
+		bool sw_id_only;
+		swima_inventory_t *targets;
 
 		type = attr->get_type(attr);
 
-		if (type.vendor_id != PEN_TCG || type.type != TCG_SWID_REQUEST)
+		if (type.vendor_id != PEN_IETF || type.type != IETF_ATTR_SW_REQUEST)
 		{
 			continue;
 		}
 
-		attr_req = (tcg_swid_attr_req_t*)attr;
+		attr_req = (ietf_swima_attr_req_t*)attr;
 		flags = attr_req->get_flags(attr_req);
 		request_id = attr_req->get_request_id(attr_req);
 		targets = attr_req->get_targets(attr_req);
 
-		if (flags & (TCG_SWID_ATTR_REQ_FLAG_S | TCG_SWID_ATTR_REQ_FLAG_C))
+		if (flags & (IETF_SWIMA_ATTR_REQ_FLAG_S | IETF_SWIMA_ATTR_REQ_FLAG_C))
 		{
-			attr = swid_error_create(TCG_SWID_SUBSCRIPTION_DENIED, request_id,
-									 0, "no subscription available yet");
+			attr = swima_error_create(PA_ERROR_SW_SUBSCRIPTION_DENIED,
+						request_id, 0, "no subscription available yet");
 			out_msg->add_attribute(out_msg, attr);
 			break;
 		}
-		full_tags = (flags & TCG_SWID_ATTR_REQ_FLAG_R) == 0;
+		sw_id_only = (flags & IETF_SWIMA_ATTR_REQ_FLAG_R);
 
-		if (!add_swid_inventory(state, out_msg, request_id, full_tags, targets))
-		{
-			break;
-		}
+		fulfill_request(state, out_msg, request_id, sw_id_only, targets);
+		break;
 	}
 	enumerator->destroy(enumerator);
 
@@ -325,16 +310,16 @@ TNC_Result TNC_IMC_ReceiveMessage(TNC_IMCID imc_id,
 	imc_msg_t *in_msg;
 	TNC_Result result;
 
-	if (!imc_swid)
+	if (!imc_swima)
 	{
 		DBG1(DBG_IMC, "IMC \"%s\" has not been initialized", imc_name);
 		return TNC_RESULT_NOT_INITIALIZED;
 	}
-	if (!imc_swid->get_state(imc_swid, connection_id, &state))
+	if (!imc_swima->get_state(imc_swima, connection_id, &state))
 	{
 		return TNC_RESULT_FATAL;
 	}
-	in_msg = imc_msg_create_from_data(imc_swid, state, connection_id, msg_type,
+	in_msg = imc_msg_create_from_data(imc_swima, state, connection_id, msg_type,
 									  chunk_create(msg, msg_len));
 	result = receive_message(state, in_msg);
 	in_msg->destroy(in_msg);
@@ -359,16 +344,16 @@ TNC_Result TNC_IMC_ReceiveMessageLong(TNC_IMCID imc_id,
 	imc_msg_t *in_msg;
 	TNC_Result result;
 
-	if (!imc_swid)
+	if (!imc_swima)
 	{
 		DBG1(DBG_IMC, "IMC \"%s\" has not been initialized", imc_name);
 		return TNC_RESULT_NOT_INITIALIZED;
 	}
-	if (!imc_swid->get_state(imc_swid, connection_id, &state))
+	if (!imc_swima->get_state(imc_swima, connection_id, &state))
 	{
 		return TNC_RESULT_FATAL;
 	}
-	in_msg = imc_msg_create_from_long_data(imc_swid, state, connection_id,
+	in_msg = imc_msg_create_from_long_data(imc_swima, state, connection_id,
 								src_imv_id, dst_imc_id,msg_vid, msg_subtype,
 								chunk_create(msg, msg_len));
 	result =receive_message(state, in_msg);
@@ -383,7 +368,7 @@ TNC_Result TNC_IMC_ReceiveMessageLong(TNC_IMCID imc_id,
 TNC_Result TNC_IMC_BatchEnding(TNC_IMCID imc_id,
 							   TNC_ConnectionID connection_id)
 {
-	if (!imc_swid)
+	if (!imc_swima)
 	{
 		DBG1(DBG_IMC, "IMC \"%s\" has not been initialized", imc_name);
 		return TNC_RESULT_NOT_INITIALIZED;
@@ -396,13 +381,13 @@ TNC_Result TNC_IMC_BatchEnding(TNC_IMCID imc_id,
  */
 TNC_Result TNC_IMC_Terminate(TNC_IMCID imc_id)
 {
-	if (!imc_swid)
+	if (!imc_swima)
 	{
 		DBG1(DBG_IMC, "IMC \"%s\" has not been initialized", imc_name);
 		return TNC_RESULT_NOT_INITIALIZED;
 	}
-	imc_swid->destroy(imc_swid);
-	imc_swid = NULL;
+	imc_swima->destroy(imc_swima);
+	imc_swima = NULL;
 
 	return TNC_RESULT_SUCCESS;
 }
@@ -413,10 +398,10 @@ TNC_Result TNC_IMC_Terminate(TNC_IMCID imc_id)
 TNC_Result TNC_IMC_ProvideBindFunction(TNC_IMCID imc_id,
 									   TNC_TNCC_BindFunctionPointer bind_function)
 {
-	if (!imc_swid)
+	if (!imc_swima)
 	{
 		DBG1(DBG_IMC, "IMC \"%s\" has not been initialized", imc_name);
 		return TNC_RESULT_NOT_INITIALIZED;
 	}
-	return imc_swid->bind_functions(imc_swid, bind_function);
+	return imc_swima->bind_functions(imc_swima, bind_function);
 }
diff --git a/src/libimcv/plugins/imc_swima/imc_swima_state.c b/src/libimcv/plugins/imc_swima/imc_swima_state.c
new file mode 100644
index 0000000..70b2434
--- /dev/null
+++ b/src/libimcv/plugins/imc_swima/imc_swima_state.c
@@ -0,0 +1,176 @@
+/*
+ * Copyright (C) 2017 Andreas Steffen
+ * HSR Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT 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 "imc_swima_state.h"
+
+#include <tncif_names.h>
+
+#include <utils/debug.h>
+
+typedef struct private_imc_swima_state_t private_imc_swima_state_t;
+
+/**
+ * Private data of an imc_swima_state_t object.
+ */
+struct private_imc_swima_state_t {
+
+	/**
+	 * Public members of imc_swima_state_t
+	 */
+	imc_swima_state_t public;
+
+	/**
+	 * TNCCS connection ID
+	 */
+	TNC_ConnectionID connection_id;
+
+	/**
+	 * TNCCS connection state
+	 */
+	TNC_ConnectionState state;
+
+	/**
+	 * Assessment/Evaluation Result
+	 */
+	TNC_IMV_Evaluation_Result result;
+
+	/**
+	 * Does the TNCCS connection support long message types?
+	 */
+	bool has_long;
+
+	/**
+	 * Does the TNCCS connection support exclusive delivery?
+	 */
+	bool has_excl;
+
+	/**
+	 * Maximum PA-TNC message size for this TNCCS connection
+	 */
+	uint32_t max_msg_len;
+
+	/**
+	 * PA-TNC attribute segmentation contracts associated with TNCCS connection
+	 */
+	seg_contract_manager_t *contracts;
+};
+
+METHOD(imc_state_t, get_connection_id, TNC_ConnectionID,
+	private_imc_swima_state_t *this)
+{
+	return this->connection_id;
+}
+
+METHOD(imc_state_t, has_long, bool,
+	private_imc_swima_state_t *this)
+{
+	return this->has_long;
+}
+
+METHOD(imc_state_t, has_excl, bool,
+	private_imc_swima_state_t *this)
+{
+	return this->has_excl;
+}
+
+METHOD(imc_state_t, set_flags, void,
+	private_imc_swima_state_t *this, bool has_long, bool has_excl)
+{
+	this->has_long = has_long;
+	this->has_excl = has_excl;
+}
+
+METHOD(imc_state_t, set_max_msg_len, void,
+	private_imc_swima_state_t *this, uint32_t max_msg_len)
+{
+	this->max_msg_len = max_msg_len;
+}
+
+METHOD(imc_state_t, get_max_msg_len, uint32_t,
+	private_imc_swima_state_t *this)
+{
+	return this->max_msg_len;
+}
+
+METHOD(imc_state_t, get_contracts, seg_contract_manager_t*,
+	private_imc_swima_state_t *this)
+{
+	return this->contracts;
+}
+
+METHOD(imc_state_t, change_state, void,
+	private_imc_swima_state_t *this, TNC_ConnectionState new_state)
+{
+	this->state = new_state;
+}
+
+METHOD(imc_state_t, set_result, void,
+	private_imc_swima_state_t *this, TNC_IMCID id,
+	TNC_IMV_Evaluation_Result result)
+{
+	this->result = result;
+}
+
+METHOD(imc_state_t, get_result, bool,
+	private_imc_swima_state_t *this, TNC_IMCID id,
+	TNC_IMV_Evaluation_Result *result)
+{
+	if (result)
+	{
+		*result = this->result;
+	}
+	return this->result != TNC_IMV_EVALUATION_RESULT_DONT_KNOW;
+}
+
+METHOD(imc_state_t, destroy, void,
+	private_imc_swima_state_t *this)
+{
+	this->contracts->destroy(this->contracts);
+	free(this);
+}
+
+/**
+ * Described in header.
+ */
+imc_state_t *imc_swima_state_create(TNC_ConnectionID connection_id)
+{
+	private_imc_swima_state_t *this;
+
+	INIT(this,
+		.public = {
+			.interface = {
+				.get_connection_id = _get_connection_id,
+				.has_long = _has_long,
+				.has_excl = _has_excl,
+				.set_flags = _set_flags,
+				.set_max_msg_len = _set_max_msg_len,
+				.get_max_msg_len = _get_max_msg_len,
+				.get_contracts = _get_contracts,
+				.change_state = _change_state,
+				.set_result = _set_result,
+				.get_result = _get_result,
+				.destroy = _destroy,
+			},
+		},
+		.state = TNC_CONNECTION_STATE_CREATE,
+		.result = TNC_IMV_EVALUATION_RESULT_DONT_KNOW,
+		.connection_id = connection_id,
+		.contracts = seg_contract_manager_create(),
+	);
+	
+	return &this->public.interface;
+}
+
+
diff --git a/src/libimcv/plugins/imc_swima/imc_swima_state.h b/src/libimcv/plugins/imc_swima/imc_swima_state.h
new file mode 100644
index 0000000..4e4e3b1
--- /dev/null
+++ b/src/libimcv/plugins/imc_swima/imc_swima_state.h
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2017 Andreas Steffen
+ * HSR Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT 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 imc_swima imc_swima
+ * @ingroup libimcv_plugins
+ *
+ * @defgroup imc_swima_state_t imc_swima_state
+ * @{ @ingroup imc_swima
+ */
+
+#ifndef IMC_SWIMA_STATE_H_
+#define IMC_SWIMA_STATE_H_
+
+#include <imc/imc_state.h>
+#include <library.h>
+
+typedef struct imc_swima_state_t imc_swima_state_t;
+
+/**
+ * Internal state of an imc_swima_t connection instance
+ */
+struct imc_swima_state_t {
+
+	/**
+	 * imc_state_t interface
+	 */
+	imc_state_t interface;
+
+};
+
+/**
+ * Create an imc_swima_state_t instance
+ *
+ * @param id		connection ID
+ */
+imc_state_t* imc_swima_state_create(TNC_ConnectionID id);
+
+#endif /** IMC_SWIMA_STATE_H_ @}*/
diff --git a/src/libimcv/plugins/imc_swima/strongswan.org__strongSwan-5-6-0.swidtag b/src/libimcv/plugins/imc_swima/strongswan.org__strongSwan-5-6-0.swidtag
new file mode 100644
index 0000000..644c098
--- /dev/null
+++ b/src/libimcv/plugins/imc_swima/strongswan.org__strongSwan-5-6-0.swidtag
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="utf-8"?>
+<SoftwareIdentity
+  name="strongSwan"
+  tagId="strongSwan-5-6-0"
+  version="5.6.0" versionScheme="alphanumeric"
+  xmlns="http://standards.iso.org/iso/19770/-2/2015/schema.xsd">
+  <Entity
+    name="strongSwan Project"
+    regid="strongswan.org"
+    role="softwareCreator licensor tagCreator"/>
+</SoftwareIdentity>
diff --git a/src/libimcv/plugins/imc_swid/regid.2004-03.org.strongswan_strongSwan.swidtag.in b/src/libimcv/plugins/imc_swima/strongswan.org__strongSwan.swidtag.in
similarity index 50%
rename from src/libimcv/plugins/imc_swid/regid.2004-03.org.strongswan_strongSwan.swidtag.in
rename to src/libimcv/plugins/imc_swima/strongswan.org__strongSwan.swidtag.in
index 8b7b50f..0e5aa8d 100644
--- a/src/libimcv/plugins/imc_swid/regid.2004-03.org.strongswan_strongSwan.swidtag.in
+++ b/src/libimcv/plugins/imc_swima/strongswan.org__strongSwan.swidtag.in
@@ -1,12 +1,11 @@
 <?xml version="1.0" encoding="utf-8"?>
-
 <SoftwareIdentity
   name="strongSwan"
-  uniqueId="strongSwan- at VERSION_MAJOR@- at VERSION_MINOR@- at VERSION_BUILD@@VERSION_REVIEW@"
+  tagId="strongSwan- at VERSION_MAJOR@- at VERSION_MINOR@- at VERSION_BUILD@@VERSION_REVIEW@"
   version="@VERSION_MAJOR at .@VERSION_MINOR at .@VERSION_BUILD@@VERSION_REVIEW@" versionScheme="alphanumeric"
-  xmlns="http://standards.iso.org/iso/19770/-2/2014/schema.xsd">
+  xmlns="http://standards.iso.org/iso/19770/-2/2015/schema.xsd">
   <Entity
     name="strongSwan Project"
-    regid="regid.2004-03.org.strongswan"
-    role="publisher licensor tagcreator"/>
+    regid="strongswan.org"
+    role="softwareCreator licensor tagCreator"/>
 </SoftwareIdentity>
diff --git a/src/libimcv/plugins/imc_test/Makefile.in b/src/libimcv/plugins/imc_test/Makefile.in
index 93c0748..a002f0b 100644
--- a/src/libimcv/plugins/imc_test/Makefile.in
+++ b/src/libimcv/plugins/imc_test/Makefile.in
@@ -308,8 +308,6 @@ RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
 RUBYGEMDIR = @RUBYGEMDIR@
-RUBYINCLUDE = @RUBYINCLUDE@
-RUBYLIB = @RUBYLIB@
 SED = @SED@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
@@ -410,6 +408,8 @@ random_device = @random_device@
 resolv_conf = @resolv_conf@
 routing_table = @routing_table@
 routing_table_prio = @routing_table_prio@
+ruby_CFLAGS = @ruby_CFLAGS@
+ruby_LIBS = @ruby_LIBS@
 runstatedir = @runstatedir@
 s_plugins = @s_plugins@
 sbindir = @sbindir@
@@ -438,6 +438,10 @@ top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
 tss2_CFLAGS = @tss2_CFLAGS@
 tss2_LIBS = @tss2_LIBS@
+tss2_socket_CFLAGS = @tss2_socket_CFLAGS@
+tss2_socket_LIBS = @tss2_socket_LIBS@
+tss2_tabrmd_CFLAGS = @tss2_tabrmd_CFLAGS@
+tss2_tabrmd_LIBS = @tss2_tabrmd_LIBS@
 urandom_device = @urandom_device@
 xml_CFLAGS = @xml_CFLAGS@
 xml_LIBS = @xml_LIBS@
diff --git a/src/libimcv/plugins/imv_attestation/Makefile.in b/src/libimcv/plugins/imv_attestation/Makefile.in
index 02bd5f5..3872b9a 100644
--- a/src/libimcv/plugins/imv_attestation/Makefile.in
+++ b/src/libimcv/plugins/imv_attestation/Makefile.in
@@ -322,8 +322,6 @@ RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
 RUBYGEMDIR = @RUBYGEMDIR@
-RUBYINCLUDE = @RUBYINCLUDE@
-RUBYLIB = @RUBYLIB@
 SED = @SED@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
@@ -424,6 +422,8 @@ random_device = @random_device@
 resolv_conf = @resolv_conf@
 routing_table = @routing_table@
 routing_table_prio = @routing_table_prio@
+ruby_CFLAGS = @ruby_CFLAGS@
+ruby_LIBS = @ruby_LIBS@
 runstatedir = @runstatedir@
 s_plugins = @s_plugins@
 sbindir = @sbindir@
@@ -452,6 +452,10 @@ top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
 tss2_CFLAGS = @tss2_CFLAGS@
 tss2_LIBS = @tss2_LIBS@
+tss2_socket_CFLAGS = @tss2_socket_CFLAGS@
+tss2_socket_LIBS = @tss2_socket_LIBS@
+tss2_tabrmd_CFLAGS = @tss2_tabrmd_CFLAGS@
+tss2_tabrmd_LIBS = @tss2_tabrmd_LIBS@
 urandom_device = @urandom_device@
 xml_CFLAGS = @xml_CFLAGS@
 xml_LIBS = @xml_LIBS@
diff --git a/src/libimcv/plugins/imv_attestation/attest_db.c b/src/libimcv/plugins/imv_attestation/attest_db.c
index 0344184..fb894f3 100644
--- a/src/libimcv/plugins/imv_attestation/attest_db.c
+++ b/src/libimcv/plugins/imv_attestation/attest_db.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2011-2014 Andreas Steffen
+ * Copyright (C) 2011-2017 Andreas Steffen
  * HSR Hochschule fuer Technik Rapperswil
  *
  * This program is free software; you can redistribute it and/or modify it
@@ -134,6 +134,11 @@ struct private_attest_db_t {
 	char *version;
 
 	/**
+	 * Primary key of software package version to be queried
+	 */
+	int vid;
+
+	/**
 	 * TRUE if version has been set
 	 */
 	bool version_set;
@@ -975,7 +980,7 @@ METHOD(attest_db_t, list_files, void,
 		{
 			while (e->enumerate(e, &fid, &file))
 			{
-				printf("%4d: %s\n", fid, file);
+				printf("%6d: %s\n", fid, file);
 				count++;
 			}
 			e->destroy(e);
@@ -996,10 +1001,10 @@ METHOD(attest_db_t, list_files, void,
 			{
 				if (did != last_did)
 				{
-					printf("%4d: %s\n", did, dir);
+					printf("%6d: %s\n", did, dir);
 					last_did = did;
 				}
-				printf("%4d:   %s\n", fid, file);
+				printf("%6d:   %s\n", fid, file);
 				count++;
 			}
 			e->destroy(e);
@@ -1182,24 +1187,24 @@ METHOD(attest_db_t, list_hashes, void,
 	private_attest_db_t *this)
 {
 	enumerator_t *e;
-	chunk_t hash;
-	char *file, *dir, *product;
+	char *file, *dir, *product, *hash;
 	int id, fid, fid_old = 0, did, did_old = 0, pid, pid_old = 0, count = 0;
 
 	if (this->pid && this->fid && this->did)
 	{
-		printf("%4d: %s\n", this->did, this->dir);
-		printf("%4d:   %s\n", this->fid, this->file);
+		printf("%6d: %s\n", this->did, this->dir);
+		printf("%6d:   %s\n", this->fid, this->file);
 		e = this->db->query(this->db,
-				"SELECT id, hash FROM file_hashes "
-				"WHERE algo = ? AND file = ? AND product = ?",
+				"SELECT h.id, h.hash FROM file_hashes AS h "
+				"JOIN versions AS v ON h.version = v.id "
+				"WHERE h.algo = ? AND h.file = ? AND v.product = ?",
 				DB_INT, this->algo, DB_INT, this->fid, DB_INT, this->pid,
-				DB_INT, DB_BLOB);
+				DB_INT, DB_TEXT);
 		if (e)
 		{
 			while (e->enumerate(e, &id, &hash))
 			{
-				printf("%4d:     %#B\n", id, &hash);
+				printf("%6d:     %s\n", id, hash);
 				count++;
 			}
 			e->destroy(e);
@@ -1216,25 +1221,26 @@ METHOD(attest_db_t, list_hashes, void,
 				"FROM file_hashes AS h "
 				"JOIN files AS f ON h.file = f.id "
 				"JOIN directories AS d ON f.dir = d.id "
-				"WHERE h.algo = ? AND h.product = ? AND f.name = ? "
+				"JOIN versions AS v ON h.version = v.id "
+				"WHERE h.algo = ? AND v.product = ? AND f.name = ? "
 				"ORDER BY d.path, f.name, h.hash",
 				DB_INT, this->algo, DB_INT, this->pid, DB_TEXT, this->file,
-				DB_INT, DB_BLOB, DB_INT, DB_INT, DB_TEXT);
+				DB_INT, DB_TEXT, DB_INT, DB_INT, DB_TEXT);
 		if (e)
 		{
 			while (e->enumerate(e, &id, &hash, &fid, &did, &dir))
 			{
 				if (did != did_old)
 				{
-					printf("%4d: %s\n", did, dir);
+					printf("%6d: %s\n", did, dir);
 					did_old = did;
 				}
 				if (fid != fid_old)
 				{
-					printf("%4d:   %s\n", fid, this->file);
+					printf("%6d:   %s\n", fid, this->file);
 					fid_old = fid;
 				}
-				printf("%4d:     %#B\n", id, &hash);
+				printf("%6d:     %s\n", id, hash);
 				count++;
 			}
 			e->destroy(e);
@@ -1246,25 +1252,26 @@ METHOD(attest_db_t, list_hashes, void,
 	}
 	else if (this->pid && this->did)
 	{
-		printf("%4d: %s\n", this->did, this->dir);
+		printf("%6d: %s\n", this->did, this->dir);
 		e = this->db->query(this->db,
 				"SELECT h.id, h.hash, f.id, f.name "
 				"FROM file_hashes AS h "
 				"JOIN files AS f ON h.file = f.id "
-				"WHERE h.algo = ? AND h.product = ? AND f.dir = ? "
+				"JOIN versions AS v ON h.version = v.id "
+				"WHERE h.algo = ? AND v.product = ? AND f.dir = ? "
 				"ORDER BY f.name, h.hash",
 				DB_INT, this->algo, DB_INT, this->pid, DB_INT, this->did,
-				DB_INT, DB_BLOB, DB_INT, DB_TEXT);
+				DB_INT, DB_TEXT, DB_INT, DB_TEXT);
 		if (e)
 		{
 			while (e->enumerate(e, &id, &hash, &fid, &file))
 			{
 				if (fid != fid_old)
 				{
-					printf("%4d:   %s\n", fid, file);
+					printf("%6d:   %s\n", fid, file);
 					fid_old = fid;
 				}
-				printf("%4d:     %#B\n", id, &hash);
+				printf("%6d:     %s\n", id, hash);
 				count++;
 			}
 			e->destroy(e);
@@ -1281,25 +1288,26 @@ METHOD(attest_db_t, list_hashes, void,
 				"FROM file_hashes AS h "
 				"JOIN files AS f ON h.file = f.id "
 				"JOIN directories AS d ON f.dir = d.id "
-				"WHERE h.algo = ? AND h.product = ? "
+				"JOIN versions AS v ON h.version = v.id "
+				"WHERE h.algo = ? AND v.product = ? "
 				"ORDER BY d.path, f.name, h.hash",
 				DB_INT, this->algo, DB_INT, this->pid,
-				DB_INT, DB_BLOB, DB_INT, DB_TEXT, DB_INT, DB_TEXT);
+				DB_INT, DB_TEXT, DB_INT, DB_TEXT, DB_INT, DB_TEXT);
 		if (e)
 		{
 			while (e->enumerate(e, &id, &hash, &fid, &file, &did, &dir))
 			{
 				if (did != did_old)
 				{
-					printf("%4d: %s\n", did, dir);
+					printf("%6d: %s\n", did, dir);
 					did_old = did;
 				}
 				if (fid != fid_old)
 				{
-					printf("%4d:   %s\n", fid, file);
+					printf("%6d:   %s\n", fid, file);
 					fid_old = fid;
 				}
-				printf("%4d:     %#B\n", id, &hash);
+				printf("%6d:     %s\n", id, hash);
 				count++;
 			}
 			e->destroy(e);
@@ -1313,21 +1321,22 @@ METHOD(attest_db_t, list_hashes, void,
 	{
 		e = this->db->query(this->db,
 				"SELECT h.id, h.hash, p.id, p.name FROM file_hashes AS h "
-				"JOIN products AS p ON h.product = p.id "
+				"JOIN versions AS v ON h.version = v.id "
+				"JOIN products AS p ON v.product = p.id "
 				"WHERE h.algo = ? AND h.file = ? "
 				"ORDER BY p.name, h.hash",
 				DB_INT, this->algo, DB_INT, this->fid,
-				DB_INT, DB_BLOB, DB_INT, DB_TEXT);
+				DB_INT, DB_TEXT, DB_INT, DB_TEXT);
 		if (e)
 		{
 			while (e->enumerate(e, &id, &hash, &pid, &product))
 			{
 				if (pid != pid_old)
 				{
-					printf("%4d: %s\n", pid, product);
+					printf("%6d: %s\n", pid, product);
 					pid_old = pid;
 				}
-				printf("%4d:   %#B\n", id, &hash);
+				printf("%6d:   %s\n", id, hash);
 				count++;
 			}
 			e->destroy(e);
@@ -1345,32 +1354,33 @@ METHOD(attest_db_t, list_hashes, void,
 				"FROM file_hashes AS h "
 				"JOIN files AS f ON h.file = f.id "
 				"JOIN directories AS d ON f.dir = d.id "
-				"JOIN products AS p ON h.product = p.id "
+				"JOIN versions AS v ON h.version = v.id "
+				"JOIN products AS p ON v.product = p.id "
 				"WHERE h.algo = ? AND f.name = ? "
 				"ORDER BY d.path, f.name, p.name, h.hash",
 				DB_INT, this->algo, DB_TEXT, this->file,
-				DB_INT, DB_BLOB, DB_INT, DB_INT, DB_TEXT, DB_INT, DB_TEXT);
+				DB_INT, DB_TEXT, DB_INT, DB_INT, DB_TEXT, DB_INT, DB_TEXT);
 		if (e)
 		{
 			while (e->enumerate(e, &id, &hash, &fid, &did, &dir, &pid, &product))
 			{
 				if (did != did_old)
 				{
-					printf("%4d: %s\n", did, dir);
+					printf("%6d: %s\n", did, dir);
 					did_old = did;
 				}
 				if (fid != fid_old)
 				{
-					printf("%4d:   %s\n", fid, this->file);
+					printf("%6d:   %s\n", fid, this->file);
 					fid_old = fid;
 					pid_old = 0;
 				}
 				if (pid != pid_old)
 				{
-					printf("%4d:     %s\n", pid, product);
+					printf("%6d:     %s\n", pid, product);
 					pid_old = pid;
 				}
-				printf("%4d:     %#B\n", id, &hash);
+				printf("%6d:     %s\n", id, hash);
 				count++;
 			}
 			e->destroy(e);
@@ -1386,27 +1396,28 @@ METHOD(attest_db_t, list_hashes, void,
 				"SELECT h.id, h.hash, f.id, f.name, p.id, p.name "
 				"FROM file_hashes AS h "
 				"JOIN files AS f ON h.file = f.id "
-				"JOIN products AS p ON h.product = p.id "
+				"JOIN versions AS v ON h.version = v.id "
+				"JOIN products AS p ON v.product = p.id "
 				"WHERE h.algo = ? AND f.dir = ? "
 				"ORDER BY f.name, p.name, h.hash",
 				DB_INT, this->algo, DB_INT, this->did,
-				DB_INT, DB_BLOB, DB_INT, DB_TEXT, DB_INT, DB_TEXT);
+				DB_INT, DB_TEXT, DB_INT, DB_TEXT, DB_INT, DB_TEXT);
 		if (e)
 		{
 			while (e->enumerate(e, &id, &hash, &fid, &file, &pid, &product))
 			{
 				if (fid != fid_old)
 				{
-					printf("%4d: %s\n", fid, file);
+					printf("%6d: %s\n", fid, file);
 					fid_old = fid;
 					pid_old = 0;
 				}
 				if (pid != pid_old)
 				{
-					printf("%4d:   %s\n", pid, product);
+					printf("%6d:   %s\n", pid, product);
 					pid_old = pid;
 				}
-				printf("%4d:     %#B\n", id, &hash);
+				printf("%6d:     %s\n", id, hash);
 				count++;
 			}
 			e->destroy(e);
@@ -1423,10 +1434,11 @@ METHOD(attest_db_t, list_hashes, void,
 				"FROM file_hashes AS h "
 				"JOIN files AS f ON h.file = f.id "
 				"JOIN directories AS d ON f.dir = d.id "
-				"JOIN products AS p on h.product = p.id "
+				"JOIN versions AS v ON h.version = v.id "
+				"JOIN products AS p on v.product = p.id "
 				"WHERE h.algo = ? "
 				"ORDER BY d.path, f.name, p.name, h.hash",
-				DB_INT, this->algo, DB_INT, DB_BLOB, DB_INT, DB_TEXT,
+				DB_INT, this->algo, DB_INT, DB_TEXT, DB_INT, DB_TEXT,
 				DB_INT, DB_TEXT, DB_INT, DB_TEXT);
 		if (e)
 		{
@@ -1435,21 +1447,21 @@ METHOD(attest_db_t, list_hashes, void,
 			{
 				if (did != did_old)
 				{
-					printf("%4d: %s\n", did, dir);
+					printf("%6d: %s\n", did, dir);
 					did_old = did;
 				}
 				if (fid != fid_old)
 				{
-					printf("%4d:   %s\n", fid, file);
+					printf("%6d:   %s\n", fid, file);
 					fid_old = fid;
 					pid_old = 0;
 				}
 				if (pid != pid_old)
 				{
-					printf("%4d:     %s\n", pid, product);
+					printf("%6d:     %s\n", pid, product);
 					pid_old = pid;
 				}
-				printf("%4d:       %#B\n", id, &hash);
+				printf("%6d:       %s\n", id, hash);
 				count++;
 			}
 			e->destroy(e);
@@ -1610,28 +1622,32 @@ static bool insert_file_hash(private_attest_db_t *this,
 							 int *hashes_added, int *hashes_updated)
 {
 	enumerator_t *e;
-	chunk_t hash;
+	uint8_t hex_measurement_buf[2*HASH_SIZE_SHA512 + 1];
+	uint8_t *hex_hash_buf;
+	chunk_t hex_hash, hex_measurement;
 	char *label;
 	bool insert = TRUE, update = FALSE;
 
 	label = "could not be created";
 
 	e = this->db->query(this->db,
-		"SELECT hash FROM file_hashes WHERE algo = ? "
-		"AND file = ? AND product = ? AND device = 0",
-		DB_INT, algo, DB_UINT, fid, DB_UINT, this->pid, DB_BLOB);
+		"SELECT hash FROM file_hashes "
+		"WHERE algo = ? AND file = ? AND version = ?",
+		DB_INT, algo, DB_UINT, fid, DB_UINT, this->vid, DB_TEXT);
 
 	if (!e)
 	{
 		printf("file_hashes query failed\n");
 		return FALSE;
 	}
+	hex_measurement = chunk_to_hex(measurement, hex_measurement_buf, FALSE);
 
-	while (e->enumerate(e, &hash))
+	while (e->enumerate(e, &hex_hash_buf))
 	{
 		update = TRUE;
+		hex_hash = chunk_from_str(hex_hash_buf);
 
-		if (chunk_equals(measurement, hash))
+		if (chunk_equals(hex_measurement, hex_hash))
 		{
 			label = "exists and equals";
 			insert = FALSE;
@@ -1644,10 +1660,10 @@ static bool insert_file_hash(private_attest_db_t *this,
 	{
 		if (this->db->execute(this->db, NULL,
 			"INSERT INTO file_hashes "
-			"(file, product, device, algo, hash) "
-			"VALUES (?, ?, 0, ?, ?)",
-			DB_UINT, fid, DB_UINT, this->pid,
-			DB_INT, algo, DB_BLOB, measurement) != 1)
+			"(file, version, algo, hash) "
+			"VALUES (?, ?, ?, ?)",
+			DB_UINT, fid, DB_UINT, this->vid,
+			DB_INT, algo, DB_TEXT, hex_measurement) != 1)
 		{
 			printf("file_hash insertion failed\n");
 			return FALSE;
@@ -1668,6 +1684,75 @@ static bool insert_file_hash(private_attest_db_t *this,
 }
 
 /**
+ * Add a package version
+ */
+static bool add_version(private_attest_db_t *this)
+{
+	int vid, security_old, security, blacklist_old, blacklist;
+	time_t t = time(NULL);
+	enumerator_t *e;
+	bool success;
+
+	security =  this->package_state == OS_PACKAGE_STATE_SECURITY;
+	blacklist = this->package_state == OS_PACKAGE_STATE_BLACKLIST;
+
+	e = this->db->query(this->db,
+				"SELECT id, security, blacklist FROM versions "
+				"WHERE package = ? AND product = ? AND release = ?",
+				DB_UINT, this->gid, DB_UINT, this->pid, DB_TEXT, this->version,
+				DB_INT, DB_INT, DB_INT, DB_INT);
+	if (e)
+	{
+		if (e->enumerate(e, &vid, &security_old, &blacklist_old))
+		{
+			this->vid = vid;
+		}
+		e->destroy(e);
+	}
+	if (this->vid)
+	{
+		if (security != security_old || blacklist != blacklist_old)
+		{
+			/* update security and/or blacklist flag */
+			success = this->db->execute(this->db, NULL, "UPDATE versions "
+					"SET security = ?, blacklist = ?, time = ? WHERE id = ?",
+					DB_INT, security, DB_INT, blacklist, DB_INT, t,
+					DB_INT, this->vid) == 1;
+
+			printf("'%s' package %s (%s)%N %s updated in database\n",
+				   this->product, this->package, this->version,
+				   os_package_state_names, this->package_state,
+				   success ? "" : "could not be ");
+		}
+		else
+		{
+			success = TRUE;
+
+			printf("'%s' package %s (%s)%N exists in database\n",
+				   this->product, this->package, this->version,
+				   os_package_state_names, this->package_state);
+		}
+		return success;
+	}
+
+	/* create a new version */
+	success = this->db->execute(this->db, NULL,
+				"INSERT INTO versions "
+				"(package, product, release, security, blacklist, time) "
+				"VALUES (?, ?, ?, ?, ?, ?)",
+				DB_UINT, this->gid, DB_INT, this->pid, DB_TEXT,
+				this->version, DB_INT, security, DB_INT, blacklist,
+				DB_INT, t) == 1;
+
+	printf("'%s' package %s (%s)%N %sinserted into database\n",
+			this->product, this->package, this->version,
+			os_package_state_names, this->package_state,
+			success ? "" : "could not be ");
+
+	return success;
+}
+
+/**
  * Add hash measurement for a single file or all files in a directory
  */
 static bool add_hash(private_attest_db_t *this)
@@ -1771,7 +1856,14 @@ static bool add_hash(private_attest_db_t *this)
 METHOD(attest_db_t, add, bool,
 	private_attest_db_t *this)
 {
-	bool success = FALSE;
+	/* insert package version */
+	if (this->version_set && this->gid && this->pid)
+	{
+		if (!add_version(this))
+		{
+			return FALSE;
+		}
+	}
 
 	/* add directory or file hash measurement for a given product */
 	if (this->did && this->pid)
@@ -1779,29 +1871,7 @@ METHOD(attest_db_t, add, bool,
 		return add_hash(this);
 	}
 
-	/* insert package version */
-	if (this->version_set && this->gid && this->pid)
-	{
-		time_t t = time(NULL);
-		int security, blacklist;
-
-		security =  this->package_state == OS_PACKAGE_STATE_SECURITY;
-		blacklist = this->package_state == OS_PACKAGE_STATE_BLACKLIST;
-
-		success = this->db->execute(this->db, NULL,
-					"INSERT INTO versions "
-					"(package, product, release, security, blacklist, time) "
-					"VALUES (?, ?, ?, ?, ?, ?)",
-					DB_UINT, this->gid, DB_INT, this->pid, DB_TEXT,
-					this->version, DB_INT, security, DB_INT, blacklist,
-					DB_INT, t) == 1;
-
-		printf("'%s' package %s (%s)%N %sinserted into database\n",
-				this->product, this->package, this->version,
-				os_package_state_names, this->package_state,
-				success ? "" : "could not be ");
-	}
-	return success;
+	return FALSE;
 }
 
 METHOD(attest_db_t, delete, bool,
@@ -1816,8 +1886,9 @@ METHOD(attest_db_t, delete, bool,
 	if (this->algo && this->pid && this->fid)
 	{
 		success = this->db->execute(this->db, NULL,
-								"DELETE FROM file_hashes "
-								"WHERE algo = ? AND product = ? AND file = ?",
+								"DELETE FROM file_hashes AS h "
+								"JOIN versions AS v ON h.version = v.id "
+								"WHERE h.algo = ? AND v.product = ? AND h.file = ?",
 								DB_UINT, this->algo, DB_UINT, this->pid,
 								DB_UINT, this->fid) > 0;
 
diff --git a/src/libimcv/plugins/imv_attestation/attest_usage.c b/src/libimcv/plugins/imv_attestation/attest_usage.c
index 8f4afdb..2966529 100644
--- a/src/libimcv/plugins/imv_attestation/attest_usage.c
+++ b/src/libimcv/plugins/imv_attestation/attest_usage.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2011-2014 Andreas Steffen
+ * Copyright (C) 2011-2017 Andreas Steffen
  * HSR Hochschule fuer Technik Rapperswil
  *
  * This program is free software; you can redistribute it and/or modify it
@@ -77,8 +77,9 @@ Usage:\n\
   ipsec attest --add [--owner <name>] --key <digest>|--aik <path>\n\
     Add an AIK public key digest entry preceded by an optional owner name\n\
   \n\
-  ipsec attest --add --product <name>|--pid <id> --sha1|--sha1-ima|--sha256|--sha384\n\
-              [--relative|--rel] --dir <path>|--file <path>\n\
+  ipsec attest --add --product <name>|--pid <id> --sha1|--sha256|--sha384\n\
+              [--relative|--rel] [--package <name> --version <string>]\n\
+               --dir <path>|--file <path>\n\
     Add hashes of a single file or all files in a directory under absolute or relative filenames\n\
   \n\
   ipsec attest --add --key <digest|--kid <id> --component <cfn>|--cid <id> --sequence <no>|--seq <no>\n\
diff --git a/src/libimcv/plugins/imv_hcd/Makefile.in b/src/libimcv/plugins/imv_hcd/Makefile.in
index b19cb4a..fda666b 100644
--- a/src/libimcv/plugins/imv_hcd/Makefile.in
+++ b/src/libimcv/plugins/imv_hcd/Makefile.in
@@ -308,8 +308,6 @@ RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
 RUBYGEMDIR = @RUBYGEMDIR@
-RUBYINCLUDE = @RUBYINCLUDE@
-RUBYLIB = @RUBYLIB@
 SED = @SED@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
@@ -410,6 +408,8 @@ random_device = @random_device@
 resolv_conf = @resolv_conf@
 routing_table = @routing_table@
 routing_table_prio = @routing_table_prio@
+ruby_CFLAGS = @ruby_CFLAGS@
+ruby_LIBS = @ruby_LIBS@
 runstatedir = @runstatedir@
 s_plugins = @s_plugins@
 sbindir = @sbindir@
@@ -438,6 +438,10 @@ top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
 tss2_CFLAGS = @tss2_CFLAGS@
 tss2_LIBS = @tss2_LIBS@
+tss2_socket_CFLAGS = @tss2_socket_CFLAGS@
+tss2_socket_LIBS = @tss2_socket_LIBS@
+tss2_tabrmd_CFLAGS = @tss2_tabrmd_CFLAGS@
+tss2_tabrmd_LIBS = @tss2_tabrmd_LIBS@
 urandom_device = @urandom_device@
 xml_CFLAGS = @xml_CFLAGS@
 xml_LIBS = @xml_LIBS@
diff --git a/src/libimcv/plugins/imv_os/Makefile.in b/src/libimcv/plugins/imv_os/Makefile.in
index f2804f3..a8d80b3 100644
--- a/src/libimcv/plugins/imv_os/Makefile.in
+++ b/src/libimcv/plugins/imv_os/Makefile.in
@@ -316,8 +316,6 @@ RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
 RUBYGEMDIR = @RUBYGEMDIR@
-RUBYINCLUDE = @RUBYINCLUDE@
-RUBYLIB = @RUBYLIB@
 SED = @SED@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
@@ -418,6 +416,8 @@ random_device = @random_device@
 resolv_conf = @resolv_conf@
 routing_table = @routing_table@
 routing_table_prio = @routing_table_prio@
+ruby_CFLAGS = @ruby_CFLAGS@
+ruby_LIBS = @ruby_LIBS@
 runstatedir = @runstatedir@
 s_plugins = @s_plugins@
 sbindir = @sbindir@
@@ -446,6 +446,10 @@ top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
 tss2_CFLAGS = @tss2_CFLAGS@
 tss2_LIBS = @tss2_LIBS@
+tss2_socket_CFLAGS = @tss2_socket_CFLAGS@
+tss2_socket_LIBS = @tss2_socket_LIBS@
+tss2_tabrmd_CFLAGS = @tss2_tabrmd_CFLAGS@
+tss2_tabrmd_LIBS = @tss2_tabrmd_LIBS@
 urandom_device = @urandom_device@
 xml_CFLAGS = @xml_CFLAGS@
 xml_LIBS = @xml_LIBS@
diff --git a/src/libimcv/plugins/imv_scanner/Makefile.in b/src/libimcv/plugins/imv_scanner/Makefile.in
index 6cc107e..b851f84 100644
--- a/src/libimcv/plugins/imv_scanner/Makefile.in
+++ b/src/libimcv/plugins/imv_scanner/Makefile.in
@@ -310,8 +310,6 @@ RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
 RUBYGEMDIR = @RUBYGEMDIR@
-RUBYINCLUDE = @RUBYINCLUDE@
-RUBYLIB = @RUBYLIB@
 SED = @SED@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
@@ -412,6 +410,8 @@ random_device = @random_device@
 resolv_conf = @resolv_conf@
 routing_table = @routing_table@
 routing_table_prio = @routing_table_prio@
+ruby_CFLAGS = @ruby_CFLAGS@
+ruby_LIBS = @ruby_LIBS@
 runstatedir = @runstatedir@
 s_plugins = @s_plugins@
 sbindir = @sbindir@
@@ -440,6 +440,10 @@ top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
 tss2_CFLAGS = @tss2_CFLAGS@
 tss2_LIBS = @tss2_LIBS@
+tss2_socket_CFLAGS = @tss2_socket_CFLAGS@
+tss2_socket_LIBS = @tss2_socket_LIBS@
+tss2_tabrmd_CFLAGS = @tss2_tabrmd_CFLAGS@
+tss2_tabrmd_LIBS = @tss2_tabrmd_LIBS@
 urandom_device = @urandom_device@
 xml_CFLAGS = @xml_CFLAGS@
 xml_LIBS = @xml_LIBS@
diff --git a/src/libimcv/plugins/imv_swid/Makefile.am b/src/libimcv/plugins/imv_swid/Makefile.am
index 73da84b..e573ea0 100644
--- a/src/libimcv/plugins/imv_swid/Makefile.am
+++ b/src/libimcv/plugins/imv_swid/Makefile.am
@@ -16,7 +16,6 @@ imv_swid_la_LIBADD = \
 
 imv_swid_la_SOURCES = \
 	imv_swid.c imv_swid_state.h imv_swid_state.c \
-	imv_swid_agent.h imv_swid_agent.c \
-	imv_swid_rest.h imv_swid_rest.c
+	imv_swid_agent.h imv_swid_agent.c
 
 imv_swid_la_LDFLAGS = -module -avoid-version -no-undefined
diff --git a/src/libimcv/plugins/imv_swid/Makefile.in b/src/libimcv/plugins/imv_swid/Makefile.in
index 3560752..c745b45 100644
--- a/src/libimcv/plugins/imv_swid/Makefile.in
+++ b/src/libimcv/plugins/imv_swid/Makefile.in
@@ -141,7 +141,7 @@ imv_swid_la_DEPENDENCIES = $(top_builddir)/src/libimcv/libimcv.la \
 	$(top_builddir)/src/libstrongswan/libstrongswan.la \
 	$(am__DEPENDENCIES_1)
 am_imv_swid_la_OBJECTS = imv_swid.lo imv_swid_state.lo \
-	imv_swid_agent.lo imv_swid_rest.lo
+	imv_swid_agent.lo
 imv_swid_la_OBJECTS = $(am_imv_swid_la_OBJECTS)
 AM_V_lt = $(am__v_lt_ at AM_V@)
 am__v_lt_ = $(am__v_lt_ at AM_DEFAULT_V@)
@@ -311,8 +311,6 @@ RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
 RUBYGEMDIR = @RUBYGEMDIR@
-RUBYINCLUDE = @RUBYINCLUDE@
-RUBYLIB = @RUBYLIB@
 SED = @SED@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
@@ -413,6 +411,8 @@ random_device = @random_device@
 resolv_conf = @resolv_conf@
 routing_table = @routing_table@
 routing_table_prio = @routing_table_prio@
+ruby_CFLAGS = @ruby_CFLAGS@
+ruby_LIBS = @ruby_LIBS@
 runstatedir = @runstatedir@
 s_plugins = @s_plugins@
 sbindir = @sbindir@
@@ -441,6 +441,10 @@ top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
 tss2_CFLAGS = @tss2_CFLAGS@
 tss2_LIBS = @tss2_LIBS@
+tss2_socket_CFLAGS = @tss2_socket_CFLAGS@
+tss2_socket_LIBS = @tss2_socket_LIBS@
+tss2_tabrmd_CFLAGS = @tss2_tabrmd_CFLAGS@
+tss2_tabrmd_LIBS = @tss2_tabrmd_LIBS@
 urandom_device = @urandom_device@
 xml_CFLAGS = @xml_CFLAGS@
 xml_LIBS = @xml_LIBS@
@@ -461,8 +465,7 @@ imv_swid_la_LIBADD = \
 
 imv_swid_la_SOURCES = \
 	imv_swid.c imv_swid_state.h imv_swid_state.c \
-	imv_swid_agent.h imv_swid_agent.c \
-	imv_swid_rest.h imv_swid_rest.c
+	imv_swid_agent.h imv_swid_agent.c
 
 imv_swid_la_LDFLAGS = -module -avoid-version -no-undefined
 all: all-am
@@ -545,7 +548,6 @@ distclean-compile:
 
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/imv_swid.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/imv_swid_agent.Plo at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/imv_swid_rest.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/imv_swid_state.Plo at am__quote@
 
 .c.o:
diff --git a/src/libimcv/plugins/imv_swid/imv_swid_agent.c b/src/libimcv/plugins/imv_swid/imv_swid_agent.c
index c057e7e..2884a16 100644
--- a/src/libimcv/plugins/imv_swid/imv_swid_agent.c
+++ b/src/libimcv/plugins/imv_swid/imv_swid_agent.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2013-2016 Andreas Steffen
+ * Copyright (C) 2013-2017 Andreas Steffen
  * HSR Hochschule fuer Technik Rapperswil
  *
  * This program is free software; you can redistribute it and/or modify it
@@ -18,12 +18,12 @@
 
 #include "imv_swid_agent.h"
 #include "imv_swid_state.h"
-#include "imv_swid_rest.h"
 
 #include <imcv.h>
 #include <imv/imv_agent.h>
 #include <imv/imv_msg.h>
 #include <ietf/ietf_attr_pa_tnc_error.h>
+#include "rest/rest.h"
 #include "tcg/seg/tcg_seg_attr_max_size.h"
 #include "tcg/seg/tcg_seg_attr_seg_env.h"
 #include "tcg/swid/tcg_swid_attr_req.h"
@@ -72,7 +72,7 @@ struct private_imv_swid_agent_t {
 	/**
 	 * REST API to strongTNC manager
 	 */
-	imv_swid_rest_t *rest_api;
+	rest_t *rest_api;
 
 };
 
@@ -590,7 +590,7 @@ METHOD(imv_agent_if_t, batch_ending, TNC_Result,
 					DBG1(DBG_IMV, "  %s", target);
 
 					/* Separate target into tag_creator and unique_sw_id */
-					separator = strchr(target, '_');
+					separator = strstr(target, "__");
 					if (!separator)
 					{
 						error_str = "separation of regid from "
@@ -598,9 +598,9 @@ METHOD(imv_agent_if_t, batch_ending, TNC_Result,
 						break;
 					}
 					tag_creator = chunk_create(target, separator - target);
-					separator++;
+					separator += 2;
 					unique_sw_id = chunk_create(separator, strlen(target) -
-												tag_creator.len - 1);
+												tag_creator.len - 2);
 					tag_id = swid_tag_id_create(tag_creator, unique_sw_id,
 												chunk_empty);
 					cast_attr = (tcg_swid_attr_req_t*)attr;
@@ -719,7 +719,7 @@ imv_agent_if_t *imv_swid_agent_create(const char *name, TNC_IMVID id,
 						"%s.plugins.imv-swid.rest_api_timeout", 120, lib->ns);
 	if (rest_api_uri)
 	{
-		this->rest_api = imv_swid_rest_create(rest_api_uri, rest_api_timeout);
+		this->rest_api = rest_create(rest_api_uri, rest_api_timeout);
 	}
 
 	return &this->public;
diff --git a/src/libimcv/plugins/imv_swid/imv_swid_rest.c b/src/libimcv/plugins/imv_swid/imv_swid_rest.c
deleted file mode 100644
index 0fe96ed..0000000
--- a/src/libimcv/plugins/imv_swid/imv_swid_rest.c
+++ /dev/null
@@ -1,124 +0,0 @@
-/*
- * Copyright (C) 2014 Andreas Steffen
- * HSR Hochschule fuer Technik Rapperswil
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * for more details.
- */
-
-#define _GNU_SOURCE
-#include <stdio.h>
-
-#include "imv_swid_rest.h"
-
-typedef struct private_imv_swid_rest_t private_imv_swid_rest_t;
-
-/**
- * Private data of an imv_swid_rest_t object.
- */
-struct private_imv_swid_rest_t {
-
-	/**
-	 * Public members of imv_swid_rest_t
-	 */
-	imv_swid_rest_t public;
-
-	/**
-	 * URI of REST API
-	 */
-	char *uri;
-
-	/**
-	 * Timeout of REST API connection
-	 */
-	u_int timeout;
-
-};
-
-#define HTTP_STATUS_CODE_PRECONDITION_FAILED	412
-
-METHOD(imv_swid_rest_t, post, status_t,
-	private_imv_swid_rest_t *this, char *command, json_object *jrequest,
-	json_object **jresponse)
-{
-	struct json_tokener *tokener;
-	chunk_t data, response = chunk_empty;
-	status_t status;
-	char *uri;
-	int code;
-
-	if (asprintf(&uri, "%s%s",this->uri, command) < 0)
-	{
-		return FAILED;
-	}
-	data = chunk_from_str((char*)json_object_to_json_string(jrequest));
-
-	status = lib->fetcher->fetch(lib->fetcher, uri, &response,
-				FETCH_TIMEOUT, this->timeout,
-				FETCH_REQUEST_DATA, data,
-				FETCH_REQUEST_TYPE, "application/json; charset=utf-8",
-				FETCH_REQUEST_HEADER, "Accept: application/json",
-				FETCH_REQUEST_HEADER, "Expect:",
-				FETCH_RESPONSE_CODE, &code,
-				FETCH_END);
-	free(uri);
-
-	if (status != SUCCESS)
-	{
-		if (code != HTTP_STATUS_CODE_PRECONDITION_FAILED || !response.ptr)
-		{
-			DBG2(DBG_IMV, "REST http request failed with status code: %d", code);
-			status = FAILED;
-		}
-		else
-		{
-			if (jresponse)
-			{
-				/* Parse HTTP response into a JSON object */
-				tokener = json_tokener_new();
-				*jresponse = json_tokener_parse_ex(tokener, response.ptr,
-															response.len);
-				json_tokener_free(tokener);
-			}
-			status = NEED_MORE;
-		}
-	}
-	free(response.ptr);
-
-	return status;
-}
-
-METHOD(imv_swid_rest_t, destroy, void,
-	private_imv_swid_rest_t *this)
-{
-	free(this->uri);
-	free(this);
-}
-
-/**
- * Described in header.
- */
-imv_swid_rest_t *imv_swid_rest_create(char *uri, u_int timeout)
-{
-	private_imv_swid_rest_t *this;
-
-	INIT(this,
-		.public = {
-			.post = _post,
-			.destroy = _destroy,
-		},
-		.uri = strdup(uri),
-		.timeout = timeout,
-	);
-
-	return &this->public;
-}
-
-
diff --git a/src/libimcv/plugins/imv_swid/imv_swid_state.c b/src/libimcv/plugins/imv_swid/imv_swid_state.c
index fb9493a..50e9f48 100644
--- a/src/libimcv/plugins/imv_swid/imv_swid_state.c
+++ b/src/libimcv/plugins/imv_swid/imv_swid_state.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2013-2016 Andreas Steffen
+ * Copyright (C) 2013-2017 Andreas Steffen
  * HSR Hochschule fuer Technik Rapperswil
  *
  * This program is free software; you can redistribute it and/or modify it
@@ -288,8 +288,8 @@ METHOD(imv_swid_state_t, get_request_id, uint32_t,
 METHOD(imv_swid_state_t, set_swid_inventory, void,
     private_imv_swid_state_t *this, swid_inventory_t *inventory)
 {
-	chunk_t tag_creator, unique_sw_id;
-	char software_id[256];
+	chunk_t tag_creator, sw_id;
+	char software_id[BUF_LEN];
 	json_object *jstring;
 	swid_tag_id_t *tag_id;
 	enumerator_t *enumerator;
@@ -299,10 +299,10 @@ METHOD(imv_swid_state_t, set_swid_inventory, void,
 	{
 		/* Construct software ID from tag creator and unique software ID */
 		tag_creator = tag_id->get_tag_creator(tag_id);
-		unique_sw_id = tag_id->get_unique_sw_id(tag_id, NULL);
-		snprintf(software_id, 256, "%.*s_%.*s",
-				 tag_creator.len, tag_creator.ptr,
-				 unique_sw_id.len, unique_sw_id.ptr);
+		sw_id = tag_id->get_unique_sw_id(tag_id, NULL);
+		snprintf(software_id, BUF_LEN, "%.*s__%.*s",
+				 (int)tag_creator.len, tag_creator.ptr,
+				 (int)sw_id.len, sw_id.ptr);
 		DBG3(DBG_IMV, "  %s", software_id);
 
 		/* Add software ID to JSON array */
diff --git a/src/libimcv/plugins/imv_swid/Makefile.am b/src/libimcv/plugins/imv_swima/Makefile.am
similarity index 54%
copy from src/libimcv/plugins/imv_swid/Makefile.am
copy to src/libimcv/plugins/imv_swima/Makefile.am
index 73da84b..b1726f0 100644
--- a/src/libimcv/plugins/imv_swid/Makefile.am
+++ b/src/libimcv/plugins/imv_swima/Makefile.am
@@ -7,16 +7,15 @@ AM_CPPFLAGS = \
 AM_CFLAGS = \
 	$(PLUGIN_CFLAGS) $(json_CFLAGS)
 
-imcv_LTLIBRARIES = imv-swid.la
+imcv_LTLIBRARIES = imv-swima.la
 
-imv_swid_la_LIBADD = \
+imv_swima_la_LIBADD = \
 	$(top_builddir)/src/libimcv/libimcv.la \
 	$(top_builddir)/src/libstrongswan/libstrongswan.la \
 	$(json_LIBS)
 
-imv_swid_la_SOURCES = \
-	imv_swid.c imv_swid_state.h imv_swid_state.c \
-	imv_swid_agent.h imv_swid_agent.c \
-	imv_swid_rest.h imv_swid_rest.c
+imv_swima_la_SOURCES = \
+	imv_swima.c imv_swima_state.h imv_swima_state.c \
+	imv_swima_agent.h imv_swima_agent.c
 
-imv_swid_la_LDFLAGS = -module -avoid-version -no-undefined
+imv_swima_la_LDFLAGS = -module -avoid-version -no-undefined
diff --git a/src/libimcv/plugins/imv_swid/Makefile.in b/src/libimcv/plugins/imv_swima/Makefile.in
similarity index 94%
copy from src/libimcv/plugins/imv_swid/Makefile.in
copy to src/libimcv/plugins/imv_swima/Makefile.in
index 3560752..56eafa5 100644
--- a/src/libimcv/plugins/imv_swid/Makefile.in
+++ b/src/libimcv/plugins/imv_swima/Makefile.in
@@ -88,7 +88,7 @@ PRE_UNINSTALL = :
 POST_UNINSTALL = :
 build_triplet = @build@
 host_triplet = @host@
-subdir = src/libimcv/plugins/imv_swid
+subdir = src/libimcv/plugins/imv_swima
 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
 am__aclocal_m4_deps = $(top_srcdir)/m4/config/libtool.m4 \
 	$(top_srcdir)/m4/config/ltoptions.m4 \
@@ -137,19 +137,19 @@ am__uninstall_files_from_dir = { \
 am__installdirs = "$(DESTDIR)$(imcvdir)"
 LTLIBRARIES = $(imcv_LTLIBRARIES)
 am__DEPENDENCIES_1 =
-imv_swid_la_DEPENDENCIES = $(top_builddir)/src/libimcv/libimcv.la \
+imv_swima_la_DEPENDENCIES = $(top_builddir)/src/libimcv/libimcv.la \
 	$(top_builddir)/src/libstrongswan/libstrongswan.la \
 	$(am__DEPENDENCIES_1)
-am_imv_swid_la_OBJECTS = imv_swid.lo imv_swid_state.lo \
-	imv_swid_agent.lo imv_swid_rest.lo
-imv_swid_la_OBJECTS = $(am_imv_swid_la_OBJECTS)
+am_imv_swima_la_OBJECTS = imv_swima.lo imv_swima_state.lo \
+	imv_swima_agent.lo
+imv_swima_la_OBJECTS = $(am_imv_swima_la_OBJECTS)
 AM_V_lt = $(am__v_lt_ at AM_V@)
 am__v_lt_ = $(am__v_lt_ at AM_DEFAULT_V@)
 am__v_lt_0 = --silent
 am__v_lt_1 = 
-imv_swid_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+imv_swima_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
 	$(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
-	$(imv_swid_la_LDFLAGS) $(LDFLAGS) -o $@
+	$(imv_swima_la_LDFLAGS) $(LDFLAGS) -o $@
 AM_V_P = $(am__v_P_ at AM_V@)
 am__v_P_ = $(am__v_P_ at AM_DEFAULT_V@)
 am__v_P_0 = false
@@ -184,8 +184,8 @@ AM_V_CCLD = $(am__v_CCLD_ at AM_V@)
 am__v_CCLD_ = $(am__v_CCLD_ at AM_DEFAULT_V@)
 am__v_CCLD_0 = @echo "  CCLD    " $@;
 am__v_CCLD_1 = 
-SOURCES = $(imv_swid_la_SOURCES)
-DIST_SOURCES = $(imv_swid_la_SOURCES)
+SOURCES = $(imv_swima_la_SOURCES)
+DIST_SOURCES = $(imv_swima_la_SOURCES)
 am__can_run_installinfo = \
   case $$AM_UPDATE_INFO_DIR in \
     n|no|NO) false;; \
@@ -311,8 +311,6 @@ RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
 RUBYGEMDIR = @RUBYGEMDIR@
-RUBYINCLUDE = @RUBYINCLUDE@
-RUBYLIB = @RUBYLIB@
 SED = @SED@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
@@ -413,6 +411,8 @@ random_device = @random_device@
 resolv_conf = @resolv_conf@
 routing_table = @routing_table@
 routing_table_prio = @routing_table_prio@
+ruby_CFLAGS = @ruby_CFLAGS@
+ruby_LIBS = @ruby_LIBS@
 runstatedir = @runstatedir@
 s_plugins = @s_plugins@
 sbindir = @sbindir@
@@ -441,6 +441,10 @@ top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
 tss2_CFLAGS = @tss2_CFLAGS@
 tss2_LIBS = @tss2_LIBS@
+tss2_socket_CFLAGS = @tss2_socket_CFLAGS@
+tss2_socket_LIBS = @tss2_socket_LIBS@
+tss2_tabrmd_CFLAGS = @tss2_tabrmd_CFLAGS@
+tss2_tabrmd_LIBS = @tss2_tabrmd_LIBS@
 urandom_device = @urandom_device@
 xml_CFLAGS = @xml_CFLAGS@
 xml_LIBS = @xml_LIBS@
@@ -453,18 +457,17 @@ AM_CPPFLAGS = \
 AM_CFLAGS = \
 	$(PLUGIN_CFLAGS) $(json_CFLAGS)
 
-imcv_LTLIBRARIES = imv-swid.la
-imv_swid_la_LIBADD = \
+imcv_LTLIBRARIES = imv-swima.la
+imv_swima_la_LIBADD = \
 	$(top_builddir)/src/libimcv/libimcv.la \
 	$(top_builddir)/src/libstrongswan/libstrongswan.la \
 	$(json_LIBS)
 
-imv_swid_la_SOURCES = \
-	imv_swid.c imv_swid_state.h imv_swid_state.c \
-	imv_swid_agent.h imv_swid_agent.c \
-	imv_swid_rest.h imv_swid_rest.c
+imv_swima_la_SOURCES = \
+	imv_swima.c imv_swima_state.h imv_swima_state.c \
+	imv_swima_agent.h imv_swima_agent.c
 
-imv_swid_la_LDFLAGS = -module -avoid-version -no-undefined
+imv_swima_la_LDFLAGS = -module -avoid-version -no-undefined
 all: all-am
 
 .SUFFIXES:
@@ -478,9 +481,9 @@ $(srcdir)/Makefile.in:  $(srcdir)/Makefile.am  $(am__configure_deps)
 	      exit 1;; \
 	  esac; \
 	done; \
-	echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/libimcv/plugins/imv_swid/Makefile'; \
+	echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/libimcv/plugins/imv_swima/Makefile'; \
 	$(am__cd) $(top_srcdir) && \
-	  $(AUTOMAKE) --gnu src/libimcv/plugins/imv_swid/Makefile
+	  $(AUTOMAKE) --gnu src/libimcv/plugins/imv_swima/Makefile
 Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
 	@case '$?' in \
 	  *config.status*) \
@@ -534,8 +537,8 @@ clean-imcvLTLIBRARIES:
 	  rm -f $${locs}; \
 	}
 
-imv-swid.la: $(imv_swid_la_OBJECTS) $(imv_swid_la_DEPENDENCIES) $(EXTRA_imv_swid_la_DEPENDENCIES) 
-	$(AM_V_CCLD)$(imv_swid_la_LINK) -rpath $(imcvdir) $(imv_swid_la_OBJECTS) $(imv_swid_la_LIBADD) $(LIBS)
+imv-swima.la: $(imv_swima_la_OBJECTS) $(imv_swima_la_DEPENDENCIES) $(EXTRA_imv_swima_la_DEPENDENCIES) 
+	$(AM_V_CCLD)$(imv_swima_la_LINK) -rpath $(imcvdir) $(imv_swima_la_OBJECTS) $(imv_swima_la_LIBADD) $(LIBS)
 
 mostlyclean-compile:
 	-rm -f *.$(OBJEXT)
@@ -543,10 +546,9 @@ mostlyclean-compile:
 distclean-compile:
 	-rm -f *.tab.c
 
- at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/imv_swid.Plo at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/imv_swid_agent.Plo at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/imv_swid_rest.Plo at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/imv_swid_state.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/imv_swima.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/imv_swima_agent.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/imv_swima_state.Plo at am__quote@
 
 .c.o:
 @am__fastdepCC_TRUE@	$(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\
diff --git a/src/libimcv/imcv_tests.h b/src/libimcv/plugins/imv_swima/imv_swima.c
similarity index 69%
copy from src/libimcv/imcv_tests.h
copy to src/libimcv/plugins/imv_swima/imv_swima.c
index d3ea24b..0d78ea0 100644
--- a/src/libimcv/imcv_tests.h
+++ b/src/libimcv/plugins/imv_swima/imv_swima.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2014 Andreas Steffen
+ * Copyright (C) 2017 Andreas Steffen
  * HSR Hochschule fuer Technik Rapperswil
  *
  * This program is free software; you can redistribute it and/or modify it
@@ -13,5 +13,12 @@
  * for more details.
  */
 
-TEST_SUITE(imcv_seg_suite_create)
+#include "imv_swima_agent.h"
+
+static const char imv_name[] = "SWIMA";
+static const imv_agent_create_t imv_agent_create = imv_swima_agent_create;
+
+/* include generic TGC TNC IF-IMV API code below */
+
+#include <imv/imv_if.h>
 
diff --git a/src/libimcv/plugins/imv_swid/imv_swid_agent.c b/src/libimcv/plugins/imv_swima/imv_swima_agent.c
similarity index 57%
copy from src/libimcv/plugins/imv_swid/imv_swid_agent.c
copy to src/libimcv/plugins/imv_swima/imv_swima_agent.c
index c057e7e..efa2b11 100644
--- a/src/libimcv/plugins/imv_swid/imv_swid_agent.c
+++ b/src/libimcv/plugins/imv_swima/imv_swima_agent.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2013-2016 Andreas Steffen
+ * Copyright (C) 2017 Andreas Steffen
  * HSR Hochschule fuer Technik Rapperswil
  *
  * This program is free software; you can redistribute it and/or modify it
@@ -16,21 +16,22 @@
 #define _GNU_SOURCE
 #include <stdio.h>
 
-#include "imv_swid_agent.h"
-#include "imv_swid_state.h"
-#include "imv_swid_rest.h"
+#include "imv_swima_agent.h"
+#include "imv_swima_state.h"
 
 #include <imcv.h>
 #include <imv/imv_agent.h>
 #include <imv/imv_msg.h>
-#include <ietf/ietf_attr_pa_tnc_error.h>
+#include "rest/rest.h"
 #include "tcg/seg/tcg_seg_attr_max_size.h"
 #include "tcg/seg/tcg_seg_attr_seg_env.h"
-#include "tcg/swid/tcg_swid_attr_req.h"
-#include "tcg/swid/tcg_swid_attr_tag_inv.h"
-#include "tcg/swid/tcg_swid_attr_tag_id_inv.h"
-#include "swid/swid_error.h"
-#include "swid/swid_inventory.h"
+#include "ietf/swima/ietf_swima_attr_req.h"
+#include "ietf/swima/ietf_swima_attr_sw_inv.h"
+#include "ietf/swima/ietf_swima_attr_sw_ev.h"
+#include "swima/swima_error.h"
+#include "swima/swima_inventory.h"
+#include "swima/swima_events.h"
+#include "swima/swima_data_model.h"
 
 #include <tncif_names.h>
 #include <tncif_pa_subtypes.h>
@@ -39,28 +40,30 @@
 #include <utils/debug.h>
 #include <bio/bio_reader.h>
 
-typedef struct private_imv_swid_agent_t private_imv_swid_agent_t;
+typedef struct private_imv_swima_agent_t private_imv_swima_agent_t;
 
 /* Subscribed PA-TNC message subtypes */
 static pen_type_t msg_types[] = {
-	{ PEN_TCG, PA_SUBTYPE_TCG_SWID }
+	{ PEN_IETF, PA_SUBTYPE_IETF_SW }
 };
 
 /**
  * Flag set when corresponding attribute has been received
  */
-enum imv_swid_attr_t {
-	IMV_SWID_ATTR_TAG_INV =    (1<<0),
-	IMV_SWID_ATTR_TAG_ID_INV = (1<<1)
+enum imv_swima_attr_t {
+	IMV_SWIMA_ATTR_SW_INV =    (1<<0),
+	IMV_SWIMA_ATTR_SW_ID_INV = (1<<1),
+	IMV_SWIMA_ATTR_SW_EV =     (1<<2),
+	IMV_SWIMA_ATTR_SW_ID_EV =  (1<<2)
 };
 
 /**
- * Private data of an imv_swid_agent_t object.
+ * Private data of an imv_swima_agent_t object.
  */
-struct private_imv_swid_agent_t {
+struct private_imv_swima_agent_t {
 
 	/**
-	 * Public members of imv_swid_agent_t
+	 * Public members of imv_swima_agent_t
 	 */
 	imv_agent_if_t public;
 
@@ -72,18 +75,18 @@ struct private_imv_swid_agent_t {
 	/**
 	 * REST API to strongTNC manager
 	 */
-	imv_swid_rest_t *rest_api;
+	rest_t *rest_api;
 
 };
 
 METHOD(imv_agent_if_t, bind_functions, TNC_Result,
-	private_imv_swid_agent_t *this, TNC_TNCS_BindFunctionPointer bind_function)
+	private_imv_swima_agent_t *this, TNC_TNCS_BindFunctionPointer bind_function)
 {
 	return this->agent->bind_functions(this->agent, bind_function);
 }
 
 METHOD(imv_agent_if_t, notify_connection_change, TNC_Result,
-	private_imv_swid_agent_t *this, TNC_ConnectionID id,
+	private_imv_swima_agent_t *this, TNC_ConnectionID id,
 	TNC_ConnectionState new_state)
 {
 	imv_state_t *state;
@@ -91,7 +94,7 @@ METHOD(imv_agent_if_t, notify_connection_change, TNC_Result,
 	switch (new_state)
 	{
 		case TNC_CONNECTION_STATE_CREATE:
-			state = imv_swid_state_create(id);
+			state = imv_swima_state_create(id);
 			return this->agent->create_state(this->agent, state);
 		case TNC_CONNECTION_STATE_DELETE:
 			return this->agent->delete_state(this->agent, id);
@@ -103,10 +106,10 @@ METHOD(imv_agent_if_t, notify_connection_change, TNC_Result,
 /**
  * Process a received message
  */
-static TNC_Result receive_msg(private_imv_swid_agent_t *this,
+static TNC_Result receive_msg(private_imv_swima_agent_t *this,
 							  imv_state_t *state, imv_msg_t *in_msg)
 {
-	imv_swid_state_t *swid_state;
+	imv_swima_state_t *swima_state;
 	imv_msg_t *out_msg;
 	enumerator_t *enumerator;
 	pa_tnc_attr_t *attr;
@@ -124,45 +127,55 @@ static TNC_Result receive_msg(private_imv_swid_agent_t *this,
 		return result;
 	}
 
-	swid_state = (imv_swid_state_t*)state;
+	swima_state = (imv_swima_state_t*)state;
 
 	/* analyze PA-TNC attributes */
 	enumerator = in_msg->create_attribute_enumerator(in_msg);
 	while (enumerator->enumerate(enumerator, &attr))
 	{
 		uint32_t request_id = 0, last_eid, eid_epoch;
-		swid_inventory_t *inventory;
+		swima_inventory_t *inventory;
+		swima_events_t *events;
 		pen_type_t type;
 
 		type = attr->get_type(attr);
 
-		if (type.vendor_id == PEN_IETF && type.type == IETF_ATTR_PA_TNC_ERROR)
-		{
-			ietf_attr_pa_tnc_error_t *error_attr;
-			pen_type_t error_code;
-			chunk_t msg_info, description;
-			bio_reader_t *reader;
-			uint32_t max_attr_size;
-			bool success;
-
-			error_attr = (ietf_attr_pa_tnc_error_t*)attr;
-			error_code = error_attr->get_error_code(error_attr);
+        if (type.vendor_id != PEN_IETF)
+        {
+            continue;
+        }
 
-			if (error_code.vendor_id == PEN_TCG)
+		switch (type.type)
+		{
+			case IETF_ATTR_PA_TNC_ERROR:
 			{
-				fatal_error = TRUE;
+				ietf_attr_pa_tnc_error_t *error_attr;
+				pen_type_t error_code;
+				chunk_t msg_info, description;
+				bio_reader_t *reader;
+				uint32_t max_attr_size;
+				bool success;
+
+				error_attr = (ietf_attr_pa_tnc_error_t*)attr;
+				error_code = error_attr->get_error_code(error_attr);
+
+				if (error_code.vendor_id != PEN_IETF ||
+					error_code.type <= PA_ERROR_PA_TNC_MSG_ROOF)
+				{
+					continue;
+				}
 				msg_info = error_attr->get_msg_info(error_attr);
 				reader = bio_reader_create(msg_info);
 				success = reader->read_uint32(reader, &request_id);
 
-				DBG1(DBG_IMV, "received TCG error '%N' for request %d",
-					 swid_error_code_names, error_code.type, request_id);
+				DBG1(DBG_IMV, "received PA-TNC error '%N' for request %d",
+					 pa_tnc_error_code_names, error_code.type, request_id);
 				if (!success)
 				{
 					reader->destroy(reader);
 					continue;
 				}
-				if (error_code.type == TCG_SWID_RESPONSE_TOO_LARGE)
+				if (error_code.type == PA_ERROR_SW_RESPONSE_TOO_LARGE)
 				{
 					if (!reader->read_uint32(reader, &max_attr_size))
 					{
@@ -179,80 +192,74 @@ static TNC_Result receive_msg(private_imv_swid_agent_t *this,
 														 description.ptr);
 				}
 				reader->destroy(reader);
+				break;
 			}
-		}
-		else if (type.vendor_id != PEN_TCG)
-		{
-			continue;
-		}
-
-		switch (type.type)
-		{
-			case TCG_SWID_TAG_ID_INVENTORY:
+			case IETF_ATTR_SW_ID_INVENTORY:
 			{
-				tcg_swid_attr_tag_id_inv_t *attr_cast;
+				ietf_swima_attr_sw_inv_t *attr_cast;
 				uint32_t missing;
-				int tag_id_count;
+				int sw_id_count;
 
-				state->set_action_flags(state, IMV_SWID_ATTR_TAG_ID_INV);
+				state->set_action_flags(state, IMV_SWIMA_ATTR_SW_ID_INV);
 
-				attr_cast = (tcg_swid_attr_tag_id_inv_t*)attr;
+				attr_cast = (ietf_swima_attr_sw_inv_t*)attr;
 				request_id = attr_cast->get_request_id(attr_cast);
-				last_eid = attr_cast->get_last_eid(attr_cast, &eid_epoch);
 				inventory = attr_cast->get_inventory(attr_cast);
-				tag_id_count = inventory->get_count(inventory);
-				missing = attr_cast->get_tag_id_count(attr_cast);
-				swid_state->set_missing(swid_state, missing);
-
-				DBG2(DBG_IMV, "received SWID tag ID inventory with %d item%s "
-					 "for request %d at eid %d of epoch 0x%08x, %d item%s to "
-					 "follow", tag_id_count, (tag_id_count == 1) ? "" : "s",
-					 request_id, last_eid, eid_epoch, missing,
-					 (missing == 1) ? "" : "s");
-
-				if (request_id == swid_state->get_request_id(swid_state))
+				last_eid = inventory->get_eid(inventory, &eid_epoch);
+				sw_id_count = inventory->get_count(inventory);
+				missing = attr_cast->get_record_count(attr_cast);
+				swima_state->set_missing(swima_state, missing);
+
+				DBG2(DBG_IMV, "received software ID inventory with "
+					 "%d item%s for request %d at last eid %d of epoch 0x%08x, "
+					 "%d item%s to follow", sw_id_count,
+					 (sw_id_count == 1) ? "" : "s", request_id, last_eid,
+					 eid_epoch, missing, (missing == 1) ? "" : "s");
+
+				if (request_id == swima_state->get_request_id(swima_state))
 				{
-					swid_state->set_swid_inventory(swid_state, inventory);
-					swid_state->set_count(swid_state, tag_id_count, 0,
-										  in_msg->get_src_id(in_msg));
+					swima_state->set_inventory(swima_state, inventory);
+					swima_state->set_count(swima_state, sw_id_count, 0,
+										   in_msg->get_src_id(in_msg));
 				}
 				else
 				{
-					DBG1(DBG_IMV, "no workitem found for SWID tag ID inventory "
-								  "with request ID %d", request_id);
+					DBG1(DBG_IMV, "no workitem found for software ID "
+								  "inventory with request ID %d", request_id);
 				}
 				attr_cast->clear_inventory(attr_cast);
 				break;
 			 }
-			case TCG_SWID_TAG_INVENTORY:
+			case IETF_ATTR_SW_INVENTORY:
 			{
-				tcg_swid_attr_tag_inv_t *attr_cast;
-				swid_tag_t *tag;
-				chunk_t tag_encoding;
+				ietf_swima_attr_sw_inv_t *attr_cast;
+				swima_record_t *sw_record;
 				json_object *jobj, *jarray, *jstring;
+				pen_type_t data_model;
+				chunk_t tag;
 				char *tag_str;
 				uint32_t missing;
-				int tag_count;
+				int sw_count;
 				enumerator_t *e;
 
-				state->set_action_flags(state, IMV_SWID_ATTR_TAG_INV);
+				state->set_action_flags(state, IMV_SWIMA_ATTR_SW_INV);
 
-				attr_cast = (tcg_swid_attr_tag_inv_t*)attr;
+				attr_cast = (ietf_swima_attr_sw_inv_t*)attr;
 				request_id = attr_cast->get_request_id(attr_cast);
-				last_eid = attr_cast->get_last_eid(attr_cast, &eid_epoch);
 				inventory = attr_cast->get_inventory(attr_cast);
-				tag_count = inventory->get_count(inventory);
-				missing = attr_cast->get_tag_count(attr_cast);
-				swid_state->set_missing(swid_state, missing);
+				last_eid = inventory->get_eid(inventory, &eid_epoch);
+				sw_count = inventory->get_count(inventory);
+				missing = attr_cast->get_record_count(attr_cast);
+				swima_state->set_missing(swima_state, missing);
 
-				DBG2(DBG_IMV, "received SWID tag inventory with %d item%s for "
-					 "request %d at eid %d of epoch 0x%08x, %d item%s to follow",
-					 tag_count, (tag_count == 1) ? "" : "s", request_id,
-					 last_eid, eid_epoch, missing, (missing == 1) ? "" : "s");
+				DBG2(DBG_IMV, "received software inventory with %d item%s for "
+					 "request %d at last eid %d of epoch 0x%08x, %d item%s to "
+					 "follow", sw_count, (sw_count == 1) ? "" : "s", request_id,
+					  last_eid, eid_epoch, missing, (missing == 1) ? "" : "s");
 
-				if (request_id == swid_state->get_request_id(swid_state))
+				if (request_id == swima_state->get_request_id(swima_state))
 				{
-					swid_state->set_count(swid_state, 0, tag_count,
+					swima_state->set_count(swima_state, 0, sw_count,
 										  in_msg->get_src_id(in_msg));
 
 					if (this->rest_api)
@@ -262,11 +269,21 @@ static TNC_Result receive_msg(private_imv_swid_agent_t *this,
 						json_object_object_add(jobj, "data", jarray);
 
 						e = inventory->create_enumerator(inventory);
-						while (e->enumerate(e, &tag))
+						while (e->enumerate(e, &sw_record))
 						{
-							tag_encoding = tag->get_encoding(tag);
-							tag_str = strndup(tag_encoding.ptr, tag_encoding.len);
-							DBG3(DBG_IMV, "%s", tag_str);
+							tag = sw_record->get_record(sw_record);
+							DBG3(DBG_IMV, "%.*s", tag.len, tag.ptr);
+
+							data_model = sw_record->get_data_model(sw_record);
+							if (!pen_type_equals(data_model,
+										swima_data_model_iso_2015_swid_xml))
+							{
+								DBG1(DBG_IMV, "only ISO/IEC 19770-2-2015 XML "
+											  "data model supported");
+								continue;
+							}
+
+							tag_str = strndup(tag.ptr, tag.len);
 							jstring = json_object_new_string(tag_str);
 							json_object_array_add(jarray, jstring);
 							free(tag_str);
@@ -289,6 +306,43 @@ static TNC_Result receive_msg(private_imv_swid_agent_t *this,
 				attr_cast->clear_inventory(attr_cast);
 				break;
 			}
+			case IETF_ATTR_SW_ID_EVENTS:
+			{
+				ietf_swima_attr_sw_ev_t *attr_cast;
+				uint32_t missing;
+				int sw_ev_count;
+
+				state->set_action_flags(state, IMV_SWIMA_ATTR_SW_ID_EV);
+
+				attr_cast = (ietf_swima_attr_sw_ev_t*)attr;
+				request_id = attr_cast->get_request_id(attr_cast);
+				events = attr_cast->get_events(attr_cast);
+				last_eid = events->get_eid(events, &eid_epoch, NULL);
+				sw_ev_count = events->get_count(events);
+				missing = attr_cast->get_event_count(attr_cast);
+				swima_state->set_missing(swima_state, missing);
+
+				DBG2(DBG_IMV, "received software ID events with "
+					 "%d item%s for request %d at last eid %d of epoch 0x%08x, "
+					 "%d item%s to follow", sw_ev_count,
+					 (sw_ev_count == 1) ? "" : "s", request_id, last_eid,
+					 eid_epoch, missing, (missing == 1) ? "" : "s");
+
+				if (request_id == swima_state->get_request_id(swima_state))
+				{
+					swima_state->set_events(swima_state, events);
+					swima_state->set_count(swima_state, sw_ev_count, 0,
+										   in_msg->get_src_id(in_msg));
+				}
+				else
+				{
+					DBG1(DBG_IMV, "no workitem found for software ID events "
+								  "with request ID %d", request_id);
+				}
+				attr_cast->clear_events(attr_cast);
+				break;
+
+			}
 			default:
 				break;
 		 }
@@ -317,7 +371,7 @@ static TNC_Result receive_msg(private_imv_swid_agent_t *this,
 }
 
 METHOD(imv_agent_if_t, receive_message, TNC_Result,
-	private_imv_swid_agent_t *this, TNC_ConnectionID id,
+	private_imv_swima_agent_t *this, TNC_ConnectionID id,
 	TNC_MessageType msg_type, chunk_t msg)
 {
 	imv_state_t *state;
@@ -336,7 +390,7 @@ METHOD(imv_agent_if_t, receive_message, TNC_Result,
 }
 
 METHOD(imv_agent_if_t, receive_message_long, TNC_Result,
-	private_imv_swid_agent_t *this, TNC_ConnectionID id,
+	private_imv_swima_agent_t *this, TNC_ConnectionID id,
 	TNC_UInt32 src_imc_id, TNC_UInt32 dst_imv_id,
 	TNC_VendorID msg_vid, TNC_MessageSubtype msg_subtype, chunk_t msg)
 {
@@ -358,14 +412,14 @@ METHOD(imv_agent_if_t, receive_message_long, TNC_Result,
 }
 
 METHOD(imv_agent_if_t, batch_ending, TNC_Result,
-	private_imv_swid_agent_t *this, TNC_ConnectionID id)
+	private_imv_swima_agent_t *this, TNC_ConnectionID id)
 {
 	imv_msg_t *out_msg;
 	imv_state_t *state;
 	imv_session_t *session;
 	imv_workitem_t *workitem;
-	imv_swid_state_t *swid_state;
-	imv_swid_handshake_state_t handshake_state;
+	imv_swima_state_t *swima_state;
+	imv_swima_handshake_state_t handshake_state;
 	pa_tnc_attr_t *attr;
 	TNC_IMVID imv_id;
 	TNC_Result result = TNC_RESULT_SUCCESS;
@@ -378,19 +432,19 @@ METHOD(imv_agent_if_t, batch_ending, TNC_Result,
 	{
 		return TNC_RESULT_FATAL;
 	}
-	swid_state = (imv_swid_state_t*)state;
-	handshake_state = swid_state->get_handshake_state(swid_state);
+	swima_state = (imv_swima_state_t*)state;
+	handshake_state = swima_state->get_handshake_state(swima_state);
 	session = state->get_session(state);
 	imv_id = this->agent->get_id(this->agent);
 
-	if (handshake_state == IMV_SWID_STATE_END)
+	if (handshake_state == IMV_SWIMA_STATE_END)
 	{
 		return TNC_RESULT_SUCCESS;
 	}
 
 	/* Create an empty out message - we might need it */
 	out_msg = imv_msg_create(this->agent, state, id, imv_id,
-							 swid_state->get_imc_id(swid_state),
+							 swima_state->get_imc_id(swima_state),
 							 msg_types[0]);
 
 	if (!imcv_db)
@@ -401,7 +455,7 @@ METHOD(imv_agent_if_t, batch_ending, TNC_Result,
 							TNC_IMV_EVALUATION_RESULT_DONT_KNOW);
 		result = out_msg->send_assessment(out_msg);
 		out_msg->destroy(out_msg);
-		swid_state->set_handshake_state(swid_state, IMV_SWID_STATE_END);
+		swima_state->set_handshake_state(swima_state, IMV_SWIMA_STATE_END);
 
 		if (result != TNC_RESULT_SUCCESS)
 		{
@@ -411,13 +465,16 @@ METHOD(imv_agent_if_t, batch_ending, TNC_Result,
 	}
 
 	/* Look for SWID tag workitem and create SWID tag request */
-	if (handshake_state == IMV_SWID_STATE_INIT &&
+	if (handshake_state == IMV_SWIMA_STATE_INIT &&
 		session->get_policy_started(session))
 	{
-		size_t max_attr_size = SWID_MAX_ATTR_SIZE;
+		size_t max_attr_size = SWIMA_MAX_ATTR_SIZE;
 		size_t max_seg_size;
+		ietf_swima_attr_req_t *cast_attr;
 		seg_contract_t *contract;
 		seg_contract_manager_t *contracts;
+		swima_inventory_t *targets;
+		uint32_t earliest_eid = 0;
 		char buf[BUF_LEN];
 
 		enumerator = session->create_workitem_enumerator(session);
@@ -431,19 +488,20 @@ METHOD(imv_agent_if_t, batch_ending, TNC_Result,
 					continue;
 				}
 				
-				flags = TCG_SWID_ATTR_REQ_FLAG_NONE;
+				flags = IETF_SWIMA_ATTR_REQ_FLAG_NONE;
 				if (strchr(workitem->get_arg_str(workitem), 'R'))
 				{
-					flags |= TCG_SWID_ATTR_REQ_FLAG_R;
+					flags |= IETF_SWIMA_ATTR_REQ_FLAG_R;
 				}
 				if (strchr(workitem->get_arg_str(workitem), 'S'))
 				{
-					flags |= TCG_SWID_ATTR_REQ_FLAG_S;
+					flags |= IETF_SWIMA_ATTR_REQ_FLAG_S;
 				}
 				if (strchr(workitem->get_arg_str(workitem), 'C'))
 				{
-					flags |= TCG_SWID_ATTR_REQ_FLAG_C;
+					flags |= IETF_SWIMA_ATTR_REQ_FLAG_C;
 				}
+				earliest_eid = workitem->get_arg_int(workitem);
 
 				/* Determine maximum PA-TNC attribute segment size */
 				max_seg_size = state->get_max_msg_len(state)
@@ -464,13 +522,21 @@ METHOD(imv_agent_if_t, batch_ending, TNC_Result,
 
 				/* Issue a SWID request */
 				request_id = workitem->get_id(workitem);
-				swid_state->set_request_id(swid_state, request_id);
-				attr = tcg_swid_attr_req_create(flags, request_id, 0);
+				swima_state->set_request_id(swima_state, request_id);
+				attr = ietf_swima_attr_req_create(flags, request_id);
+
+				/* Request software identifier events */
+				targets = swima_inventory_create();
+				targets->set_eid(targets, earliest_eid, 0);
+				cast_attr = (ietf_swima_attr_req_t*)attr;
+				cast_attr->set_targets(cast_attr, targets);
+				targets->destroy(targets);
+
 				out_msg->add_attribute(out_msg, attr);
 				workitem->set_imv_id(workitem, imv_id);
 				no_workitems = FALSE;
-				DBG2(DBG_IMV, "IMV %d issues SWID request %d",
-							   imv_id, request_id);
+				DBG2(DBG_IMV, "IMV %d issues sw request %d with earliest eid %d",
+							   imv_id, request_id, earliest_eid);
 				break;
 			}
 			enumerator->destroy(enumerator);
@@ -483,44 +549,57 @@ METHOD(imv_agent_if_t, batch_ending, TNC_Result,
 								TNC_IMV_ACTION_RECOMMENDATION_ALLOW,
 								TNC_IMV_EVALUATION_RESULT_DONT_KNOW);
 			}
-			handshake_state = IMV_SWID_STATE_WORKITEMS;
-			swid_state->set_handshake_state(swid_state, handshake_state);
+			handshake_state = IMV_SWIMA_STATE_WORKITEMS;
+			swima_state->set_handshake_state(swima_state, handshake_state);
 		}
 	}
 
 	received = state->get_action_flags(state);
 
-	if (handshake_state == IMV_SWID_STATE_WORKITEMS &&
-	   (received & (IMV_SWID_ATTR_TAG_INV|IMV_SWID_ATTR_TAG_ID_INV)) &&
-		swid_state->get_missing(swid_state) == 0)
+	if (handshake_state == IMV_SWIMA_STATE_WORKITEMS &&
+	   (received & (IMV_SWIMA_ATTR_SW_INV|IMV_SWIMA_ATTR_SW_ID_INV|
+					IMV_SWIMA_ATTR_SW_EV |IMV_SWIMA_ATTR_SW_ID_EV)) &&
+		swima_state->get_missing(swima_state) == 0)
 	{
 		TNC_IMV_Evaluation_Result eval;
 		TNC_IMV_Action_Recommendation rec;
-		char result_str[BUF_LEN], *error_str = "", *command;
-		char *target, *separator;
-		int tag_id_count, tag_count, i;
-		chunk_t tag_creator, unique_sw_id;
+		char result_str[BUF_LEN], *format = NULL, *cmd = NULL, *command;
+		char *target_str, *error_str = "";
+		int sw_id_count, tag_count, i, res;
 		json_object *jrequest, *jresponse, *jvalue;
-		tcg_swid_attr_req_t *cast_attr;
-		swid_tag_id_t *tag_id;
+		ietf_swima_attr_req_t *cast_attr;
+		swima_inventory_t *targets;
+		swima_record_t *target;
 		status_t status = SUCCESS;
 
-		if (this->rest_api && (received & IMV_SWID_ATTR_TAG_ID_INV))
+		if (received & IMV_SWIMA_ATTR_SW_ID_INV)
+		{
+			cmd = "swid-measurement";
+			format = "received inventory of %d SW ID%s and %d SWID tag%s";
+		}
+		else if (received & IMV_SWIMA_ATTR_SW_ID_EV)
+		{
+			cmd = "swid-events";
+			format = "received %d SW ID event%s and %d SWID tag%s";
+		}
+
+		if (cmd && this->rest_api)
 		{
-			if (asprintf(&command, "sessions/%d/swid-measurement/",
-						 session->get_session_id(session, NULL, NULL)) < 0)
+			res = asprintf(&command, "sessions/%d/%s/",
+					 session->get_session_id(session, NULL, NULL), cmd);
+			if (res < 0)
 			{
 				error_str = "allocation of command string failed";
 				status = FAILED;
 			}
 			else
 			{
-				jrequest = swid_state->get_swid_inventory(swid_state);
+				jrequest = swima_state->get_jrequest(swima_state);
 				status = this->rest_api->post(this->rest_api, command,
 											  jrequest, &jresponse);
 				if (status == FAILED)
 				{
-					error_str = "error in REST API swid-measurement request";
+						error_str = "error in REST API request";
 				}
 				free(command);
 			}
@@ -534,12 +613,20 @@ METHOD(imv_agent_if_t, batch_ending, TNC_Result,
 				{
 					if (workitem->get_type(workitem) == IMV_WORKITEM_SWID_TAGS)
 					{
-						swid_state->get_count(swid_state, &tag_id_count,
+						swima_state->get_count(swima_state, &sw_id_count,
 														  &tag_count);
-						snprintf(result_str, BUF_LEN, "received inventory of "
-								 "%d SWID tag ID%s and %d SWID tag%s",
-								 tag_id_count, (tag_id_count == 1) ? "" : "s",
-								 tag_count, (tag_count == 1) ? "" : "s");
+						if (format)
+						{
+							snprintf(result_str, BUF_LEN, format,
+								sw_id_count, (sw_id_count == 1) ? "" : "s",
+								tag_count,   (tag_count   == 1) ? "" : "s");
+						}
+						else
+						{
+							snprintf(result_str, BUF_LEN, "received %d SWID tag"
+								"%s", tag_count, (tag_count == 1) ? "" : "s");
+
+						}
 						session->remove_workitem(session, enumerator);
 
 						eval = TNC_IMV_EVALUATION_RESULT_COMPLIANT;
@@ -553,7 +640,7 @@ METHOD(imv_agent_if_t, batch_ending, TNC_Result,
 				enumerator->destroy(enumerator);
 				break;
 			case NEED_MORE:
-				if (received & IMV_SWID_ATTR_TAG_INV)
+				if (received & IMV_SWIMA_ATTR_SW_INV)
 				{
 					error_str = "not all requested SWID tags were received";
 					status = FAILED;
@@ -568,15 +655,16 @@ METHOD(imv_agent_if_t, batch_ending, TNC_Result,
 					break;
 				}
 
-				/* Create a TCG SWID Request attribute */
-				attr = tcg_swid_attr_req_create(TCG_SWID_ATTR_REQ_FLAG_NONE,
-								swid_state->get_request_id(swid_state), 0);
-				tag_id_count = json_object_array_length(jresponse);
-				DBG1(DBG_IMV, "%d SWID tag target%s", tag_id_count,
-							  (tag_id_count == 1) ? "" : "s");
-				swid_state->set_missing(swid_state, tag_id_count);
+				/* Create an IETF SW Request attribute */
+				attr = ietf_swima_attr_req_create(IETF_SWIMA_ATTR_REQ_FLAG_NONE,
+								swima_state->get_request_id(swima_state));
+				sw_id_count = json_object_array_length(jresponse);
+				DBG1(DBG_IMV, "%d SWID tag target%s", sw_id_count,
+							  (sw_id_count == 1) ? "" : "s");
+				swima_state->set_missing(swima_state, sw_id_count);
+				targets = swima_inventory_create();
 
-				for (i = 0; i < tag_id_count; i++)
+				for (i = 0; i < sw_id_count; i++)
 				{
 					jvalue = json_object_array_get_idx(jresponse, i);
 					if (json_object_get_type(jvalue) != json_type_string)
@@ -586,28 +674,17 @@ METHOD(imv_agent_if_t, batch_ending, TNC_Result,
 						json_object_put(jresponse);
 						break;
 					}
-					target = (char*)json_object_get_string(jvalue);
-					DBG1(DBG_IMV, "  %s", target);
-
-					/* Separate target into tag_creator and unique_sw_id */
-					separator = strchr(target, '_');
-					if (!separator)
-					{
-						error_str = "separation of regid from "
-									"unique software ID failed";
-						break;
-					}
-					tag_creator = chunk_create(target, separator - target);
-					separator++;
-					unique_sw_id = chunk_create(separator, strlen(target) -
-												tag_creator.len - 1);
-					tag_id = swid_tag_id_create(tag_creator, unique_sw_id,
-												chunk_empty);
-					cast_attr = (tcg_swid_attr_req_t*)attr;
-					cast_attr->add_target(cast_attr, tag_id);
+					target_str = (char*)json_object_get_string(jvalue);
+					DBG1(DBG_IMV, "  %s", target_str);
+					target = swima_record_create(0, chunk_from_str(target_str),
+													chunk_empty);
+					targets->add(targets, target);
 				}
 				json_object_put(jresponse);
 
+				cast_attr = (ietf_swima_attr_req_t*)attr;
+				cast_attr->set_targets(cast_attr, targets);
+				targets->destroy(targets);
 				out_msg->add_attribute(out_msg, attr);
 				break;
 			case FAILED:
@@ -636,12 +713,12 @@ METHOD(imv_agent_if_t, batch_ending, TNC_Result,
 	}
 
 	/* finalized all workitems ? */
-	if (handshake_state == IMV_SWID_STATE_WORKITEMS &&
+	if (handshake_state == IMV_SWIMA_STATE_WORKITEMS &&
 		session->get_workitem_count(session, imv_id) == 0)
 	{
 		result = out_msg->send_assessment(out_msg);
 		out_msg->destroy(out_msg);
-		swid_state->set_handshake_state(swid_state, IMV_SWID_STATE_END);
+		swima_state->set_handshake_state(swima_state, IMV_SWIMA_STATE_END);
 
 		if (result != TNC_RESULT_SUCCESS)
 		{
@@ -661,7 +738,7 @@ METHOD(imv_agent_if_t, batch_ending, TNC_Result,
 }
 
 METHOD(imv_agent_if_t, solicit_recommendation, TNC_Result,
-	private_imv_swid_agent_t *this, TNC_ConnectionID id)
+	private_imv_swima_agent_t *this, TNC_ConnectionID id)
 {
 	imv_state_t *state;
 
@@ -673,7 +750,7 @@ METHOD(imv_agent_if_t, solicit_recommendation, TNC_Result,
 }
 
 METHOD(imv_agent_if_t, destroy, void,
-	private_imv_swid_agent_t *this)
+	private_imv_swima_agent_t *this)
 {
 	DESTROY_IF(this->rest_api);
 	this->agent->destroy(this->agent);
@@ -683,13 +760,13 @@ METHOD(imv_agent_if_t, destroy, void,
 /**
  * Described in header.
  */
-imv_agent_if_t *imv_swid_agent_create(const char *name, TNC_IMVID id,
+imv_agent_if_t *imv_swima_agent_create(const char *name, TNC_IMVID id,
 										 TNC_Version *actual_version)
 {
-	private_imv_swid_agent_t *this;
+	private_imv_swima_agent_t *this;
 	imv_agent_t *agent;
-	char *rest_api_uri;
-	u_int rest_api_timeout;
+	char *uri;
+	u_int timeout;
 
 	agent = imv_agent_create(name, msg_types, countof(msg_types), id,
 							 actual_version);
@@ -713,13 +790,13 @@ imv_agent_if_t *imv_swid_agent_create(const char *name, TNC_IMVID id,
 		.agent = agent,
 	);
 
-	rest_api_uri = lib->settings->get_str(lib->settings,
-						"%s.plugins.imv-swid.rest_api_uri", NULL, lib->ns);
-	rest_api_timeout = lib->settings->get_int(lib->settings,
-						"%s.plugins.imv-swid.rest_api_timeout", 120, lib->ns);
-	if (rest_api_uri)
+	uri = lib->settings->get_str(lib->settings,
+					"%s.plugins.imv-swima.rest_api.uri", NULL, lib->ns);
+	timeout = lib->settings->get_int(lib->settings,
+					"%s.plugins.imv-swima.rest_api.timeout", 120, lib->ns);
+	if (uri)
 	{
-		this->rest_api = imv_swid_rest_create(rest_api_uri, rest_api_timeout);
+		this->rest_api = rest_create(uri, timeout);
 	}
 
 	return &this->public;
diff --git a/src/libimcv/imcv_tests.h b/src/libimcv/plugins/imv_swima/imv_swima_agent.h
similarity index 54%
copy from src/libimcv/imcv_tests.h
copy to src/libimcv/plugins/imv_swima/imv_swima_agent.h
index d3ea24b..d07c774 100644
--- a/src/libimcv/imcv_tests.h
+++ b/src/libimcv/plugins/imv_swima/imv_swima_agent.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2014 Andreas Steffen
+ * Copyright (C) 2017 Andreas Steffen
  * HSR Hochschule fuer Technik Rapperswil
  *
  * This program is free software; you can redistribute it and/or modify it
@@ -13,5 +13,24 @@
  * for more details.
  */
 
-TEST_SUITE(imcv_seg_suite_create)
+/**
+ * @defgroup imv_swima_agent_t imv_swima_agent
+ * @{ @ingroup imv_swima
+ */
+
+#ifndef IMV_SWIMA_AGENT_H_
+#define IMV_SWIMA_AGENT_H_
+
+#include <imv/imv_agent_if.h>
+
+/**
+ * Creates an SWID IMV agent
+ *
+ * @param name					Name of the IMV
+ * @param id					ID of the IMV
+ * @param actual_version		TNC IF-IMV version
+ */
+imv_agent_if_t* imv_swima_agent_create(const char* name, TNC_IMVID id,
+									   TNC_Version *actual_version);
 
+#endif /** IMV_SWIMA_AGENT_H_ @}*/
diff --git a/src/libimcv/plugins/imv_swid/imv_swid_state.c b/src/libimcv/plugins/imv_swima/imv_swima_state.c
similarity index 52%
copy from src/libimcv/plugins/imv_swid/imv_swid_state.c
copy to src/libimcv/plugins/imv_swima/imv_swima_state.c
index fb9493a..03500bc 100644
--- a/src/libimcv/plugins/imv_swid/imv_swid_state.c
+++ b/src/libimcv/plugins/imv_swima/imv_swima_state.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2013-2016 Andreas Steffen
+ * Copyright (C) 2017 Andreas Steffen
  * HSR Hochschule fuer Technik Rapperswil
  *
  * This program is free software; you can redistribute it and/or modify it
@@ -13,29 +13,27 @@
  * for more details.
  */
 
-#include "imv_swid_state.h"
+#include "imv_swima_state.h"
 
 #include <imv/imv_lang_string.h>
 #include <imv/imv_reason_string.h>
 #include <imv/imv_remediation_string.h>
-#include <swid/swid_tag_id.h>
 
 #include <tncif_policy.h>
 
-#include <utils/lexparser.h>
 #include <utils/debug.h>
 
-typedef struct private_imv_swid_state_t private_imv_swid_state_t;
+typedef struct private_imv_swima_state_t private_imv_swima_state_t;
 
 /**
- * Private data of an imv_swid_state_t object.
+ * Private data of an imv_swima_state_t object.
  */
-struct private_imv_swid_state_t {
+struct private_imv_swima_state_t {
 
 	/**
-	 * Public members of imv_swid_state_t
+	 * Public members of imv_swima_state_t
 	 */
-	imv_swid_state_t public;
+	imv_swima_state_t public;
 
 	/**
 	 * TNCCS connection ID
@@ -90,7 +88,7 @@ struct private_imv_swid_state_t {
 	/**
 	 * IMV Scanner handshake state
 	 */
-	imv_swid_handshake_state_t handshake_state;
+	imv_swima_handshake_state_t handshake_state;
 
 	/**
 	 * TNC Reason String
@@ -108,9 +106,9 @@ struct private_imv_swid_state_t {
 	uint32_t request_id;
 
 	/**
-	 * Number of processed SWID Tag IDs
+	 * Number of processed Software Identifiers
 	 */
-	int tag_id_count;
+	int sw_id_count;
 
 	/**
 	 * Number of processed SWID Tags
@@ -118,7 +116,7 @@ struct private_imv_swid_state_t {
 	int tag_count;
 
 	/**
-	 * Number of missing SWID Tags or Tag IDs
+	 * Number of missing Software Identifiers or SWID Tags
 	 */
 	uint32_t missing;
 
@@ -133,87 +131,87 @@ struct private_imv_swid_state_t {
 	json_object *jobj;
 
 	/**
-	 * JSON array containing an inventory of SWID Tag IDs
+	 * JSON array containing either a SW [ID] inventory or SW ID events
 	 */
 	json_object *jarray;
 
 };
 
 METHOD(imv_state_t, get_connection_id, TNC_ConnectionID,
-	private_imv_swid_state_t *this)
+	private_imv_swima_state_t *this)
 {
 	return this->connection_id;
 }
 
 METHOD(imv_state_t, has_long, bool,
-	private_imv_swid_state_t *this)
+	private_imv_swima_state_t *this)
 {
 	return this->has_long;
 }
 
 METHOD(imv_state_t, has_excl, bool,
-	private_imv_swid_state_t *this)
+	private_imv_swima_state_t *this)
 {
 	return this->has_excl;
 }
 
 METHOD(imv_state_t, set_flags, void,
-	private_imv_swid_state_t *this, bool has_long, bool has_excl)
+	private_imv_swima_state_t *this, bool has_long, bool has_excl)
 {
 	this->has_long = has_long;
 	this->has_excl = has_excl;
 }
 
 METHOD(imv_state_t, set_max_msg_len, void,
-	private_imv_swid_state_t *this, uint32_t max_msg_len)
+	private_imv_swima_state_t *this, uint32_t max_msg_len)
 {
 	this->max_msg_len = max_msg_len;
 }
 
 METHOD(imv_state_t, get_max_msg_len, uint32_t,
-	private_imv_swid_state_t *this)
+	private_imv_swima_state_t *this)
 {
 	return this->max_msg_len;
 }
 
 METHOD(imv_state_t, set_action_flags, void,
-	private_imv_swid_state_t *this, uint32_t flags)
+	private_imv_swima_state_t *this, uint32_t flags)
 {
 	this->action_flags |= flags;
 }
 
 METHOD(imv_state_t, get_action_flags, uint32_t,
-	private_imv_swid_state_t *this)
+	private_imv_swima_state_t *this)
 {
 	return this->action_flags;
 }
 
 METHOD(imv_state_t, set_session, void,
-	private_imv_swid_state_t *this, imv_session_t *session)
+	private_imv_swima_state_t *this, imv_session_t *session)
 {
 	this->session = session;
 }
 
 METHOD(imv_state_t, get_session, imv_session_t*,
-	private_imv_swid_state_t *this)
+	private_imv_swima_state_t *this)
 {
 	return this->session;
 }
 
 METHOD(imv_state_t, get_contracts, seg_contract_manager_t*,
-	private_imv_swid_state_t *this)
+	private_imv_swima_state_t *this)
 {
 	return this->contracts;
 }
 
 METHOD(imv_state_t, change_state, void,
-	private_imv_swid_state_t *this, TNC_ConnectionState new_state)
+	private_imv_swima_state_t *this, TNC_ConnectionState new_state)
 {
 	this->state = new_state;
 }
 
 METHOD(imv_state_t, get_recommendation, void,
-	private_imv_swid_state_t *this, TNC_IMV_Action_Recommendation *rec,
+	private_imv_swima_state_t *this, TNC_IMV_Action_Recommendation *rec,
 									   TNC_IMV_Evaluation_Result *eval)
 {
 	*rec = this->rec;
@@ -221,7 +219,7 @@ METHOD(imv_state_t, get_recommendation, void,
 }
 
 METHOD(imv_state_t, set_recommendation, void,
-	private_imv_swid_state_t *this, TNC_IMV_Action_Recommendation rec,
+	private_imv_swima_state_t *this, TNC_IMV_Action_Recommendation rec,
 									   TNC_IMV_Evaluation_Result eval)
 {
 	this->rec = rec;
@@ -229,7 +227,7 @@ METHOD(imv_state_t, set_recommendation, void,
 }
 
 METHOD(imv_state_t, update_recommendation, void,
-	private_imv_swid_state_t *this, TNC_IMV_Action_Recommendation rec,
+	private_imv_swima_state_t *this, TNC_IMV_Action_Recommendation rec,
 									   TNC_IMV_Evaluation_Result eval)
 {
 	this->rec  = tncif_policy_update_recommendation(this->rec, rec);
@@ -237,21 +235,21 @@ METHOD(imv_state_t, update_recommendation, void,
 }
 
 METHOD(imv_state_t, get_reason_string, bool,
-	private_imv_swid_state_t *this, enumerator_t *language_enumerator,
+	private_imv_swima_state_t *this, enumerator_t *language_enumerator,
 	chunk_t *reason_string, char **reason_language)
 {
 	return FALSE;
 }
 
 METHOD(imv_state_t, get_remediation_instructions, bool,
-	private_imv_swid_state_t *this, enumerator_t *language_enumerator,
+	private_imv_swima_state_t *this, enumerator_t *language_enumerator,
 	chunk_t *string, char **lang_code, char **uri)
 {
 	return FALSE;
 }
 
 METHOD(imv_state_t, destroy, void,
-	private_imv_swid_state_t *this)
+	private_imv_swima_state_t *this)
 {
 	json_object_put(this->jobj);
 	DESTROY_IF(this->session);
@@ -261,90 +259,160 @@ METHOD(imv_state_t, destroy, void,
 	free(this);
 }
 
-METHOD(imv_swid_state_t, set_handshake_state, void,
-	private_imv_swid_state_t *this, imv_swid_handshake_state_t new_state)
+METHOD(imv_swima_state_t, set_handshake_state, void,
+	private_imv_swima_state_t *this, imv_swima_handshake_state_t new_state)
 {
 	this->handshake_state = new_state;
 }
 
-METHOD(imv_swid_state_t, get_handshake_state, imv_swid_handshake_state_t,
-	private_imv_swid_state_t *this)
+METHOD(imv_swima_state_t, get_handshake_state, imv_swima_handshake_state_t,
+	private_imv_swima_state_t *this)
 {
 	return this->handshake_state;
 }
 
-METHOD(imv_swid_state_t, set_request_id, void,
-	private_imv_swid_state_t *this, uint32_t request_id)
+METHOD(imv_swima_state_t, set_request_id, void,
+	private_imv_swima_state_t *this, uint32_t request_id)
 {
 	this->request_id = request_id;
 }
 
-METHOD(imv_swid_state_t, get_request_id, uint32_t,
-	private_imv_swid_state_t *this)
+METHOD(imv_swima_state_t, get_request_id, uint32_t,
+	private_imv_swima_state_t *this)
 {
 	return this->request_id;
 }
 
-METHOD(imv_swid_state_t, set_swid_inventory, void,
-    private_imv_swid_state_t *this, swid_inventory_t *inventory)
+METHOD(imv_swima_state_t, set_inventory, void,
+    private_imv_swima_state_t *this, swima_inventory_t *inventory)
 {
-	chunk_t tag_creator, unique_sw_id;
-	char software_id[256];
+	chunk_t sw_id, sw_locator;
+	uint32_t record_id;
+	char *sw_id_str;
 	json_object *jstring;
-	swid_tag_id_t *tag_id;
+	swima_record_t *sw_record;
 	enumerator_t *enumerator;
 
+	if (this->sw_id_count == 0)
+	{
+		this->jarray = json_object_new_array();
+		json_object_object_add(this->jobj, "data", this->jarray);
+	}
+
 	enumerator = inventory->create_enumerator(inventory);
-	while (enumerator->enumerate(enumerator, &tag_id))
+	while (enumerator->enumerate(enumerator, &sw_record))
 	{
-		/* Construct software ID from tag creator and unique software ID */
-		tag_creator = tag_id->get_tag_creator(tag_id);
-		unique_sw_id = tag_id->get_unique_sw_id(tag_id, NULL);
-		snprintf(software_id, 256, "%.*s_%.*s",
-				 tag_creator.len, tag_creator.ptr,
-				 unique_sw_id.len, unique_sw_id.ptr);
-		DBG3(DBG_IMV, "  %s", software_id);
-
-		/* Add software ID to JSON array */
-		jstring = json_object_new_string(software_id);
+		record_id = sw_record->get_record_id(sw_record);
+		sw_id = sw_record->get_sw_id(sw_record, &sw_locator);
+		sw_id_str = strndup(sw_id.ptr, sw_id.len);
+		if (sw_locator.len)
+		{
+			DBG3(DBG_IMV, "%6u: %s @ %.*s", record_id, sw_id_str,
+						   sw_locator.len, sw_locator.ptr);
+		}
+		else
+		{
+			DBG3(DBG_IMV, "%6u: %s", record_id, sw_id_str);
+		}
+
+		/* Add software identity to JSON array */
+		jstring = json_object_new_string(sw_id_str);
 		json_object_array_add(this->jarray, jstring);
+		free(sw_id_str);
 	}
 	enumerator->destroy(enumerator);
 }
 
-METHOD(imv_swid_state_t, get_swid_inventory, json_object*,
-	private_imv_swid_state_t *this)
+METHOD(imv_swima_state_t, set_events, void,
+    private_imv_swima_state_t *this, swima_events_t *events)
+{
+	chunk_t sw_id, timestamp;
+	uint32_t record_id, eid, last_eid, epoch, source_id, action;
+	char *sw_id_str, *timestamp_str;
+	json_object *jevent, *jvalue, *jstring;
+	swima_event_t *sw_event;
+	swima_record_t *sw_record;
+	enumerator_t *enumerator;
+
+	if (this->sw_id_count == 0)
+	{
+		last_eid = events->get_eid(events, &epoch, NULL);
+		jvalue = json_object_new_int(epoch);
+		json_object_object_add(this->jobj, "epoch", jvalue);
+		jvalue = json_object_new_int(last_eid);
+		json_object_object_add(this->jobj, "lastEid", jvalue);
+		this->jarray = json_object_new_array();
+		json_object_object_add(this->jobj, "events", this->jarray);
+	}
+
+	enumerator = events->create_enumerator(events);
+	while (enumerator->enumerate(enumerator, &sw_event))
+	{
+		eid = sw_event->get_eid(sw_event, &timestamp);
+		timestamp_str = strndup(timestamp.ptr, timestamp.len);
+		action = sw_event->get_action(sw_event);
+		sw_record = sw_event->get_sw_record(sw_event);
+		record_id = sw_record->get_record_id(sw_record);
+		source_id = sw_record->get_source_id(sw_record);
+		sw_id = sw_record->get_sw_id(sw_record, NULL);
+		sw_id_str = strndup(sw_id.ptr, sw_id.len);
+		DBG3(DBG_IMV, "%3u %.*s %u %5u: %s", eid, timestamp.len, timestamp.ptr,
+											 action, record_id, sw_id_str);
+
+		/* Add software event to JSON array */
+		jevent = json_object_new_object();
+		jvalue = json_object_new_int(eid);
+		json_object_object_add(jevent, "eid", jvalue);
+		jstring = json_object_new_string(timestamp_str);
+		json_object_object_add(jevent, "timestamp", jstring);
+		jvalue = json_object_new_int(record_id);
+		json_object_object_add(jevent, "recordId", jvalue);
+		jvalue = json_object_new_int(source_id);
+		json_object_object_add(jevent, "sourceId", jvalue);
+		jvalue = json_object_new_int(action);
+		json_object_object_add(jevent, "action", jvalue);
+		jstring = json_object_new_string(sw_id_str);
+		json_object_object_add(jevent, "softwareId", jstring);
+		json_object_array_add(this->jarray, jevent);
+		free(timestamp_str);
+		free(sw_id_str);
+	}
+	enumerator->destroy(enumerator);
+}
+
+METHOD(imv_swima_state_t, get_jrequest, json_object*,
+	private_imv_swima_state_t *this)
 {
 	return this->jobj;
 }
 
-METHOD(imv_swid_state_t, set_missing, void,
-	private_imv_swid_state_t *this, uint32_t count)
+METHOD(imv_swima_state_t, set_missing, void,
+	private_imv_swima_state_t *this, uint32_t count)
 {
 	this->missing = count;
 }
 
-METHOD(imv_swid_state_t, get_missing, uint32_t,
-	private_imv_swid_state_t *this)
+METHOD(imv_swima_state_t, get_missing, uint32_t,
+	private_imv_swima_state_t *this)
 {
 	return this->missing;
 }
 
-METHOD(imv_swid_state_t, set_count, void,
-	private_imv_swid_state_t *this, int tag_id_count, int tag_count,
+METHOD(imv_swima_state_t, set_count, void,
+	private_imv_swima_state_t *this, int sw_id_count, int tag_count,
 	TNC_UInt32 imc_id)
 {
-	this->tag_id_count += tag_id_count;
+	this->sw_id_count += sw_id_count;
 	this->tag_count += tag_count;
 	this->imc_id = imc_id;
 }
 
-METHOD(imv_swid_state_t, get_count, void,
-	private_imv_swid_state_t *this, int *tag_id_count, int *tag_count)
+METHOD(imv_swima_state_t, get_count, void,
+	private_imv_swima_state_t *this, int *sw_id_count, int *tag_count)
 {
-	if (tag_id_count)
+	if (sw_id_count)
 	{
-		*tag_id_count = this->tag_id_count;
+		*sw_id_count = this->sw_id_count;
 	}
 	if (tag_count)
 	{
@@ -352,8 +420,8 @@ METHOD(imv_swid_state_t, get_count, void,
 	}
 }
 
-METHOD(imv_swid_state_t, get_imc_id, TNC_UInt32,
-	private_imv_swid_state_t *this)
+METHOD(imv_swima_state_t, get_imc_id, TNC_UInt32,
+	private_imv_swima_state_t *this)
 {
 	return this->imc_id;
 }
@@ -361,9 +429,9 @@ METHOD(imv_swid_state_t, get_imc_id, TNC_UInt32,
 /**
  * Described in header.
  */
-imv_state_t *imv_swid_state_create(TNC_ConnectionID connection_id)
+imv_state_t *imv_swima_state_create(TNC_ConnectionID connection_id)
 {
-	private_imv_swid_state_t *this;
+	private_imv_swima_state_t *this;
 
 	INIT(this,
 		.public = {
@@ -391,8 +459,9 @@ imv_state_t *imv_swid_state_create(TNC_ConnectionID connection_id)
 			.get_handshake_state = _get_handshake_state,
 			.set_request_id = _set_request_id,
 			.get_request_id = _get_request_id,
-			.set_swid_inventory = _set_swid_inventory,
-			.get_swid_inventory = _get_swid_inventory,
+			.set_inventory = _set_inventory,
+			.set_events = _set_events,
+			.get_jrequest = _get_jrequest,
 			.set_missing = _set_missing,
 			.get_missing = _get_missing,
 			.set_count = _set_count,
@@ -406,11 +475,8 @@ imv_state_t *imv_swid_state_create(TNC_ConnectionID connection_id)
 		.contracts = seg_contract_manager_create(),
 		.imc_id = TNC_IMCID_ANY,
 		.jobj = json_object_new_object(),
-		.jarray = json_object_new_array(),
 	);
 
-	json_object_object_add(this->jobj, "data", this->jarray);
-
 	return &this->public.interface;
 }
 
diff --git a/src/libimcv/plugins/imv_swima/imv_swima_state.h b/src/libimcv/plugins/imv_swima/imv_swima_state.h
new file mode 100644
index 0000000..4fa32da
--- /dev/null
+++ b/src/libimcv/plugins/imv_swima/imv_swima_state.h
@@ -0,0 +1,153 @@
+/*
+ * Copyright (C) 2017 Andreas Steffen
+ * HSR Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT 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 imv_swima imv_swima
+ * @ingroup libimcv_plugins
+ *
+ * @defgroup imv_swima_state_t imv_swima_state
+ * @{ @ingroup imv_swima
+ */
+
+#ifndef IMV_SWIMA_STATE_H_
+#define IMV_SWIMA_STATE_H_
+
+#include <imv/imv_state.h>
+#include <swima/swima_inventory.h>
+#include <swima/swima_events.h>
+#include <library.h>
+
+#include <json.h>
+
+typedef struct imv_swima_state_t imv_swima_state_t;
+typedef enum imv_swima_handshake_state_t imv_swima_handshake_state_t;
+
+/**
+ * IMV OS Handshake States (state machine)
+ */
+enum imv_swima_handshake_state_t {
+	IMV_SWIMA_STATE_INIT,
+	IMV_SWIMA_STATE_WORKITEMS,
+	IMV_SWIMA_STATE_END
+};
+
+/**
+ * Internal state of an imv_swima_t connection instance
+ */
+struct imv_swima_state_t {
+
+	/**
+	 * imv_state_t interface
+	 */
+	imv_state_t interface;
+
+	/**
+	 * Set state of the handshake
+	 *
+	 * @param new_state			the handshake state of IMV
+	 */
+	void (*set_handshake_state)(imv_swima_state_t *this,
+								imv_swima_handshake_state_t new_state);
+
+	/**
+	 * Get state of the handshake
+	 *
+	 * @return					the handshake state of IMV
+	 */
+	imv_swima_handshake_state_t (*get_handshake_state)(imv_swima_state_t *this);
+
+	/**
+	 * Set the SWID request ID
+	 *
+	 * @param request_id		SWID request ID to be set
+	 */
+	void (*set_request_id)(imv_swima_state_t *this, uint32_t request_id);
+
+	/**
+	 * Get the SWID request ID
+	 *
+	 * @return					SWID request ID
+	 */
+	uint32_t (*get_request_id)(imv_swima_state_t *this);
+
+	/**
+	 * Set or extend the SW ID inventory in the state
+	 *
+	 * @param inventory			SW ID inventory to be added
+	 */
+	void (*set_inventory)(imv_swima_state_t *this, swima_inventory_t *inventory);
+
+	/**
+	 * Set or extend the SW ID events in the state
+	 *
+	 * @param events			SW ID events to be added
+	 */
+	void (*set_events)(imv_swima_state_t *this, swima_events_t *events);
+
+	/**
+	 * Get the JSON encoding of the complete SW ID inventory or SW ID events
+	 *
+	 * @return			       JSON encoding
+	 */
+	json_object* (*get_jrequest)(imv_swima_state_t *this);
+
+	/**
+	 * Set the number of still missing SW [ID] records or envents
+	 *
+	 * @param count				Number of missing SW [ID] records or envents
+	 */
+	void (*set_missing)(imv_swima_state_t *this, uint32_t count);
+
+	/**
+	 * Get the number of still missing SWID Tags or Tag IDs
+	 *
+	 * @result					Number of missing SWID Tags or Tag IDs
+	 */
+	uint32_t (*get_missing)(imv_swima_state_t *this);
+
+	/**
+	 * Set [or with multiple attributes increment] SWID Tag [ID] counters
+	 *
+	 * @param tag_id_count		Number of received SWID Tag IDs
+	 * @param tag_count			Number of received SWID Tags
+	 * @param imc_id			SWID IMC ID
+	 */
+	void (*set_count)(imv_swima_state_t *this, int tag_id_count, int tag_count,
+					  TNC_UInt32 imc_id);
+
+	/**
+	 * Set [or with multiple attributes increment] SWID Tag [ID] counters
+	 *
+	 * @param tag_id_count		Number of received SWID Tag IDs
+	 * @param tag_count			Number of received SWID Tags
+	 */
+	void (*get_count)(imv_swima_state_t *this, int *tag_id_count, int *tag_count);
+
+	/**
+	 * Get SWID IMC ID
+	 *
+	 * @return					SWID IMC ID
+	 */
+	TNC_UInt32 (*get_imc_id)(imv_swima_state_t *this);
+};
+
+/**
+ * Create an imv_swima_state_t instance
+ *
+ * @param id			connection ID
+ */
+imv_state_t* imv_swima_state_create(TNC_ConnectionID id);
+
+#endif /** IMV_SWIMA_STATE_H_ @}*/
diff --git a/src/libimcv/plugins/imv_test/Makefile.in b/src/libimcv/plugins/imv_test/Makefile.in
index 9aebfef..8a6b9ed 100644
--- a/src/libimcv/plugins/imv_test/Makefile.in
+++ b/src/libimcv/plugins/imv_test/Makefile.in
@@ -309,8 +309,6 @@ RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
 RUBYGEMDIR = @RUBYGEMDIR@
-RUBYINCLUDE = @RUBYINCLUDE@
-RUBYLIB = @RUBYLIB@
 SED = @SED@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
@@ -411,6 +409,8 @@ random_device = @random_device@
 resolv_conf = @resolv_conf@
 routing_table = @routing_table@
 routing_table_prio = @routing_table_prio@
+ruby_CFLAGS = @ruby_CFLAGS@
+ruby_LIBS = @ruby_LIBS@
 runstatedir = @runstatedir@
 s_plugins = @s_plugins@
 sbindir = @sbindir@
@@ -439,6 +439,10 @@ top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
 tss2_CFLAGS = @tss2_CFLAGS@
 tss2_LIBS = @tss2_LIBS@
+tss2_socket_CFLAGS = @tss2_socket_CFLAGS@
+tss2_socket_LIBS = @tss2_socket_LIBS@
+tss2_tabrmd_CFLAGS = @tss2_tabrmd_CFLAGS@
+tss2_tabrmd_LIBS = @tss2_tabrmd_LIBS@
 urandom_device = @urandom_device@
 xml_CFLAGS = @xml_CFLAGS@
 xml_LIBS = @xml_LIBS@
diff --git a/src/libimcv/pts/components/ita/ita_comp_ima.c b/src/libimcv/pts/components/ita/ita_comp_ima.c
index 448ca9f..9ba72d0 100644
--- a/src/libimcv/pts/components/ita/ita_comp_ima.c
+++ b/src/libimcv/pts/components/ita/ita_comp_ima.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2011-2014 Andreas Steffen
+ * Copyright (C) 2011-2017 Andreas Steffen
  * HSR Hochschule fuer Technik Rapperswil
  *
  * This program is free software; you can redistribute it and/or modify it
@@ -667,7 +667,8 @@ METHOD(pts_component_t, verify, status_t,
 			case IMA_STATE_RUNTIME:
 			{
 				uint8_t hash_buf[HASH_SIZE_SHA512];
-				chunk_t digest, hash;
+				uint8_t digest_buf[HASH_SIZE_SHA512], *hex_digest_buf;
+				chunk_t hex_digest, digest, hash;
 				enumerator_t *e;
 
 				this->count++;
@@ -685,8 +686,10 @@ METHOD(pts_component_t, verify, status_t,
 												hash_algo, ima_name);
 				if (e)
 				{
-					while (e->enumerate(e, &digest))
+					while (e->enumerate(e, &hex_digest_buf))
 					{
+						hex_digest = chunk_from_str(hex_digest_buf);
+						digest = chunk_from_hex(hex_digest, digest_buf);
 						if (!ima_hash(digest, ima_algo, ima_name,
 									  FALSE, algo, hash_buf))
 						{
diff --git a/src/libimcv/pts/pts_database.c b/src/libimcv/pts/pts_database.c
index 1a4c421..4a47b06 100644
--- a/src/libimcv/pts/pts_database.c
+++ b/src/libimcv/pts/pts_database.c
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 2011-2012 Sansar Choinyambuu
- * Copyright (C) 2012-2014 Andreas Steffen
+ * Copyright (C) 2012-2017 Andreas Steffen
  * HSR Hochschule fuer Technik Rapperswil
  *
  * This program is free software; you can redistribute it and/or modify it
@@ -104,17 +104,19 @@ METHOD(pts_database_t, create_file_hash_enumerator, enumerator_t*,
 				"SELECT f.id, f.name, fh.hash FROM file_hashes AS fh "
 				"JOIN files AS f ON f.id = fh.file "
 				"JOIN directories as d ON d.id = f.dir "
-				"WHERE fh.product = ? AND fh.algo = ? AND d.id = ? "
+				"JOIN versions as v ON v.id = fh.version "
+				"WHERE v.product = ? AND fh.algo = ? AND d.id = ? "
 				"ORDER BY f.name",
-				DB_INT, pid, DB_INT, algo, DB_INT, id, DB_INT, DB_TEXT, DB_BLOB);
+				DB_INT, pid, DB_INT, algo, DB_INT, id, DB_INT, DB_TEXT, DB_TEXT);
 	}
 	else
 	{
 		e = this->db->query(this->db,
 				"SELECT f.id, f.name, fh.hash FROM file_hashes AS fh "
 				"JOIN files AS f ON f.id = fh.file "
-				"WHERE fh.product = ? AND fh.algo = ? AND fh.file = ?",
-				DB_INT, pid, DB_INT, algo, DB_INT, id, DB_INT, DB_TEXT, DB_BLOB);
+				"JOIN versions AS v ON v.id = fh.version "
+				"WHERE v.product = ? AND fh.algo = ? AND fh.file = ?",
+				DB_INT, pid, DB_INT, algo, DB_INT, id, DB_INT, DB_TEXT, DB_TEXT);
 	}
 	return e;
 }
@@ -179,7 +181,8 @@ METHOD(pts_database_t, add_file_measurement, status_t,
 	/* does hash measurement value already exist? */
 	e = this->db->query(this->db,
 			"SELECT fh.id, fh.hash FROM file_hashes AS fh "
-			"WHERE fh.product = ? AND fh.algo = ? AND fh.file = ?",
+			"JOIN versions AS v ON v.id = fh.version "
+			"WHERE v.product = ? AND fh.algo = ? AND fh.file = ?",
 			 DB_INT, pid, DB_INT, algo, DB_INT, fid, DB_INT, DB_BLOB);
 	if (!e)
 	{
@@ -235,8 +238,10 @@ METHOD(pts_database_t, create_file_meas_enumerator, enumerator_t*,
 		e = this->db->query(this->db,
 				"SELECT fh.hash FROM file_hashes AS fh "
 				"JOIN files AS f ON f.id = fh.file "
-				"WHERE fh.product = ? AND f.name = ? AND fh.algo = ?",
-				DB_INT, pid, DB_TEXT, file, DB_INT, algo, DB_BLOB);
+				"JOIN versions AS v ON v.id = fh.version "
+				"WHERE v.product = ? AND f.name = ? AND fh.algo = ? "
+				"ORDER BY v.time DESC",
+				DB_INT, pid, DB_TEXT, file, DB_INT, algo, DB_TEXT);
 	}
 	else
 	{	/* absolute pathname */
@@ -256,8 +261,10 @@ METHOD(pts_database_t, create_file_meas_enumerator, enumerator_t*,
 		e = this->db->query(this->db,
 				"SELECT fh.hash FROM file_hashes AS fh "
 				"JOIN files AS f ON f.id = fh.file "
-				"WHERE fh.product = ? AND f.dir = ? AND f.name = ? AND fh.algo = ?",
-				DB_INT, pid, DB_INT, did, DB_TEXT, file, DB_INT, algo, DB_BLOB);
+				"JOIN versions AS v ON v.id = fh.version "
+				"WHERE v.product = ? AND f.dir = ? AND f.name = ? AND fh.algo = ? "
+				"ORDER BY v.time DESC",
+				DB_INT, pid, DB_INT, did, DB_TEXT, file, DB_INT, algo, DB_TEXT);
 	}
 
 err:
diff --git a/src/libimcv/rest/rest.c b/src/libimcv/rest/rest.c
new file mode 100644
index 0000000..531da09
--- /dev/null
+++ b/src/libimcv/rest/rest.c
@@ -0,0 +1,167 @@
+/*
+ * Copyright (C) 2017 Andreas Steffen
+ * HSR Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * for more details.
+ */
+
+#ifdef USE_JSON
+
+#define _GNU_SOURCE
+#include <stdio.h>
+
+#include "rest.h"
+
+typedef struct private_rest_t private_rest_t;
+
+/**
+ * Private data of an rest_t object.
+ */
+struct private_rest_t {
+
+	/**
+	 * Public members of rest_t
+	 */
+	rest_t public;
+
+	/**
+	 * URI of REST API
+	 */
+	char *uri;
+
+	/**
+	 * Timeout of REST API connection
+	 */
+	u_int timeout;
+
+};
+
+METHOD(rest_t, get, status_t,
+	private_rest_t *this, char *command, json_object **jresponse)
+{
+	struct json_tokener *tokener;
+	chunk_t response = chunk_empty;
+	status_t status;
+	char *uri;
+
+	if (asprintf(&uri, "%s%s",this->uri, command) < 0)
+	{
+		return FAILED;
+	}
+
+	status = lib->fetcher->fetch(lib->fetcher, uri, &response,
+				FETCH_TIMEOUT, this->timeout,
+				FETCH_END);
+	free(uri);
+
+	if (status == SUCCESS && jresponse)
+	{
+		/* Parse HTTP response into a JSON object */
+		tokener = json_tokener_new();
+		*jresponse = json_tokener_parse_ex(tokener, response.ptr, response.len);
+		json_tokener_free(tokener);
+	}
+	free(response.ptr);
+
+	return status;
+}
+
+#define HTTP_STATUS_CODE_NOT_FOUND				404
+#define HTTP_STATUS_CODE_PRECONDITION_FAILED	412
+
+METHOD(rest_t, post, status_t,
+	private_rest_t *this, char *command, json_object *jrequest,
+	json_object **jresponse)
+{
+	struct json_tokener *tokener;
+	chunk_t data, response = chunk_empty;
+	status_t status;
+	char *uri;
+	int code;
+
+	if (asprintf(&uri, "%s%s",this->uri, command) < 0)
+	{
+		return FAILED;
+	}
+	data = chunk_from_str((char*)json_object_to_json_string(jrequest));
+
+	status = lib->fetcher->fetch(lib->fetcher, uri, &response,
+				FETCH_TIMEOUT, this->timeout,
+				FETCH_REQUEST_DATA, data,
+				FETCH_REQUEST_TYPE, "application/json; charset=utf-8",
+				FETCH_REQUEST_HEADER, "Accept: application/json",
+				FETCH_REQUEST_HEADER, "Expect:",
+				FETCH_RESPONSE_CODE, &code,
+				FETCH_END);
+	free(uri);
+
+	if (status != SUCCESS)
+	{
+		switch (code)
+		{
+			case HTTP_STATUS_CODE_NOT_FOUND:
+				status = NOT_FOUND;
+				break;
+			case HTTP_STATUS_CODE_PRECONDITION_FAILED:
+				if (!response.ptr)
+				{
+					return FAILED;
+				}
+				if (jresponse)
+				{
+					/* Parse HTTP response into a JSON object */
+					tokener = json_tokener_new();
+					*jresponse = json_tokener_parse_ex(tokener, response.ptr,
+																response.len);
+					json_tokener_free(tokener);
+				}
+				status = NEED_MORE;
+				break;
+			default:
+				DBG2(DBG_IMV, "REST http request failed with status code: %d",
+							   code);
+				status = FAILED;
+				break;
+		}
+	}
+	free(response.ptr);
+
+	return status;
+}
+
+METHOD(rest_t, destroy, void,
+	private_rest_t *this)
+{
+	free(this->uri);
+	free(this);
+}
+
+/**
+ * Described in header.
+ */
+rest_t *rest_create(char *uri, u_int timeout)
+{
+	private_rest_t *this;
+
+	INIT(this,
+		.public = {
+			.get = _get,
+			.post = _post,
+			.destroy = _destroy,
+		},
+		.uri = strdup(uri),
+		.timeout = timeout,
+	);
+
+	return &this->public;
+}
+
+#endif /* USE_JSON */
diff --git a/src/libimcv/plugins/imv_swid/imv_swid_rest.h b/src/libimcv/rest/rest.h
similarity index 59%
rename from src/libimcv/plugins/imv_swid/imv_swid_rest.h
rename to src/libimcv/rest/rest.h
index 32392cb..bddb881 100644
--- a/src/libimcv/plugins/imv_swid/imv_swid_rest.h
+++ b/src/libimcv/rest/rest.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2013-2014 Andreas Steffen
+ * Copyright (C) 2017 Andreas Steffen
  * HSR Hochschule fuer Technik Rapperswil
  *
  * This program is free software; you can redistribute it and/or modify it
@@ -14,50 +14,61 @@
  */
 
 /**
- * @defgroup imv_swid imv_swid
+ * @defgroup imv_swima imv_swima
  * @ingroup libimcv_plugins
  *
- * @defgroup imv_swid_rest_t imv_swid_rest
- * @{ @ingroup imv_swid
+ * @defgroup rest_t rest
+ * @{ @ingroup imv_swima
  */
 
-#ifndef IMV_SWID_REST_H_
-#define IMV_SWID_REST_H_
+#ifndef REST_H_
+#define REST_H_
 
-#include <library.h>
+#ifdef USE_JSON
 
+#include <library.h>
 #include <json.h>
 
-typedef struct imv_swid_rest_t imv_swid_rest_t;
+typedef struct rest_t rest_t;
 
 /**
  * Public REST interface
  */
-struct imv_swid_rest_t {
+struct rest_t {
 
 	/**
-	 * Post a HTTP request including a JSON object
+	 * Send an HTTP GET request returning a JSON object
+	 *
+	 * @param jresp		JSON object in HTTP
+	 * @return			Status (SUCCESS or FAILED)
+	 */
+	status_t (*get)(rest_t *this, char *command, json_object **jresp);
+
+	/**
+	 * Send an HTTP POST request including a JSON object
 	 *
 	 * @param jreq		JSON object in HTTP request
 	 * @param jresp		JSON object in HTTP response if NEED_MORE
 	 * @return			Status (SUCCESS, NEED_MORE or FAILED)
 	 */
-	status_t (*post)(imv_swid_rest_t *this, char *command, json_object *jreq,
+	status_t (*post)(rest_t *this, char *command, json_object *jreq,
 					 json_object **jresp);
 
 	/**
-	 * Destroy imv_swid_rest_t object
+	 * Destroy rest_t object
 	 */
-	void (*destroy)(imv_swid_rest_t *this);
+	void (*destroy)(rest_t *this);
 
 };
 
 /**
- * Create an imv_swid_rest_t instance
+ * Create an rest_t instance
  *
  * @param uri			REST URI (http://username:password@hostname[:port]/api/)
  * @param timeout		Timeout of the REST connection
  */
-imv_swid_rest_t* imv_swid_rest_create(char *uri, u_int timeout);
+rest_t* rest_create(char *uri, u_int timeout);
+
+#endif /* USE_JSON */
 
-#endif /** IMV_SWID_REST_H_ @}*/
+#endif /** REST_H_ @}*/
diff --git a/src/libimcv/suites/test_imcv_swima.c b/src/libimcv/suites/test_imcv_swima.c
new file mode 100644
index 0000000..c54669d
--- /dev/null
+++ b/src/libimcv/suites/test_imcv_swima.c
@@ -0,0 +1,1117 @@
+/*
+ * Copyright (C) 2017 Andreas Steffen
+ * HSR Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT 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 "test_suite.h"
+
+#include "swima/swima_record.h"
+#include "swima/swima_data_model.h"
+#include "swima/swima_inventory.h"
+#include "swima/swima_event.h"
+#include "swima/swima_events.h"
+#include "swima/swima_collector.h"
+#include "ietf/swima/ietf_swima_attr_req.h"
+#include "ietf/swima/ietf_swima_attr_sw_inv.h"
+#include "ietf/swima/ietf_swima_attr_sw_ev.h"
+
+static pen_type_t ita_data_model = { PEN_ITA, 0x19 };
+
+static char* sw_id_str[] = {
+	"strongswan.org_strongSwan_5.3.3",
+	"strongswan.org_62251aa6-1a01-479b-aea6-f3dcf0ab1f1a"
+};
+static char sw_locator_str[] = "/usr/share/strongswan";
+
+static char* sw_record_str[] = {
+	"<SoftwareIdentity tagId=\"abc\"></SoftwareIdentity>",
+	"<SoftwareIdentity tagId=\"def\"></SoftwareIdentity>"
+};
+
+START_TEST(test_imcv_swima_record)
+{
+	chunk_t sw_id, sw_locator, locator;
+	swima_record_t *sw_record, *sw_record_cp;
+	uint32_t record_id = 1;
+	uint8_t source_id = 2;
+	chunk_t record = chunk_from_str(sw_record_str[0]);
+
+	sw_id = chunk_from_str(sw_id_str[0]);
+	sw_locator = chunk_from_str(sw_locator_str);
+
+	/* Software Identity with Software Locator */
+	sw_record = swima_record_create(record_id, sw_id, sw_locator),
+	ck_assert(sw_record);
+	sw_record_cp = sw_record->get_ref(sw_record);
+
+	ck_assert(record_id == sw_record->get_record_id(sw_record));
+	ck_assert_chunk_eq(sw_id, sw_record->get_sw_id(sw_record, NULL));
+	ck_assert_chunk_eq(sw_id, sw_record->get_sw_id(sw_record, &locator));
+	ck_assert_chunk_eq(locator, sw_locator);
+
+	sw_record->set_data_model(sw_record, ita_data_model);
+	ck_assert(pen_type_equals(sw_record->get_data_model(sw_record),
+							  ita_data_model));
+
+	sw_record->set_source_id(sw_record, source_id);
+	ck_assert(source_id == sw_record->get_source_id(sw_record));
+
+	sw_record->set_record(sw_record, record);
+	ck_assert_chunk_eq(record, sw_record->get_record(sw_record));
+
+	sw_record->destroy(sw_record);
+	sw_record_cp->destroy(sw_record);
+
+	/* Software Identity without Software Locator */
+	sw_record = swima_record_create(record_id, sw_id, chunk_empty),
+	ck_assert(sw_record);
+	ck_assert_chunk_eq(sw_id, sw_record->get_sw_id(sw_record, &locator));
+	ck_assert(locator.ptr == NULL && locator.len == 0);
+
+	ck_assert(pen_type_equals(swima_data_model_iso_2015_swid_xml,
+							  sw_record->get_data_model(sw_record)));
+
+	sw_record->destroy(sw_record);
+}
+END_TEST
+
+typedef struct req_data_t req_data_t;
+
+struct req_data_t {
+	uint8_t flags;
+	uint32_t request_id;
+	uint32_t earliest_eid;
+	uint32_t sw_id_count;
+	chunk_t  value;
+};
+
+static req_data_t req_data[] = {
+	{ IETF_SWIMA_ATTR_REQ_FLAG_NONE, 1,   0, 0, chunk_from_chars(
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
+		0x00, 0x00)
+	},
+	{ IETF_SWIMA_ATTR_REQ_FLAG_R,    2,  15, 1, chunk_from_chars(
+		0x20, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00,
+		0x00, 0x0F, 0x00, 0x1f, 0x73, 0x74, 0x72, 0x6f, 0x6e, 0x67,
+		0x73, 0x77, 0x61, 0x6e, 0x2e, 0x6f, 0x72, 0x67, 0x5f, 0x73,
+		0x74, 0x72, 0x6f, 0x6e, 0x67, 0x53, 0x77, 0x61, 0x6e, 0x5f,
+		0x35, 0x2e, 0x33, 0x2e, 0x33)
+	},
+	{ IETF_SWIMA_ATTR_REQ_FLAG_S,    3, 256, 2, chunk_from_chars(
+		0x40, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00,
+		0x01, 0x00, 0x00, 0x1f, 0x73, 0x74, 0x72, 0x6f, 0x6e, 0x67,
+		0x73, 0x77, 0x61, 0x6e, 0x2e, 0x6f, 0x72, 0x67, 0x5f, 0x73,
+		0x74, 0x72, 0x6f, 0x6e, 0x67, 0x53, 0x77, 0x61, 0x6e, 0x5f,
+		0x35, 0x2e, 0x33, 0x2e, 0x33, 0x00, 0x33, 0x73, 0x74, 0x72,
+		0x6f, 0x6e, 0x67, 0x73, 0x77, 0x61, 0x6e, 0x2e, 0x6f, 0x72,
+		0x67, 0x5f, 0x36, 0x32, 0x32, 0x35, 0x31, 0x61, 0x61, 0x36,
+		0x2d, 0x31, 0x61, 0x30, 0x31, 0x2d, 0x34, 0x37, 0x39, 0x62,
+		0x2d, 0x61, 0x65, 0x61, 0x36, 0x2d, 0x66, 0x33, 0x64, 0x63,
+		0x66, 0x30, 0x61, 0x62, 0x31, 0x66, 0x31, 0x61)
+	},
+};
+
+START_TEST(test_imcv_swima_sw_req)
+{
+	pen_type_t type;
+	pen_type_t pen_type = { PEN_IETF, IETF_ATTR_SW_REQUEST };
+	pa_tnc_attr_t *attr, *attr1, *attr2;
+	ietf_swima_attr_req_t *c_attr;
+	swima_record_t *target;
+	swima_inventory_t *targets;
+	chunk_t sw_id, value;
+	enumerator_t *enumerator;
+	uint32_t offset;
+	int n;
+
+	attr = ietf_swima_attr_req_create(req_data[_i].flags,
+									  req_data[_i].request_id);
+	ck_assert(attr);
+
+	type = attr->get_type(attr);
+	ck_assert(pen_type_equals(type, pen_type));
+
+	ck_assert(attr->get_noskip_flag(attr) == FALSE);
+	attr->set_noskip_flag(attr, TRUE);
+	ck_assert(attr->get_noskip_flag(attr) == TRUE);
+
+	targets = swima_inventory_create();
+	targets->set_eid(targets, req_data[_i].earliest_eid, 0);
+
+	for (n = 0; n < req_data[_i].sw_id_count; n++)
+	{
+		sw_id = chunk_from_str(sw_id_str[n]);
+		target = swima_record_create(0, sw_id, chunk_empty);
+		targets->add(targets, target);
+	}
+	c_attr = (ietf_swima_attr_req_t*)attr;
+	c_attr->set_targets(c_attr, targets);
+	c_attr->set_targets(c_attr, targets);
+	targets->destroy(targets);
+
+	attr->build(attr);
+	attr->build(attr);
+	value = attr->get_value(attr);
+	ck_assert_chunk_eq(value, req_data[_i].value);
+
+	attr1 = attr->get_ref(attr);
+	attr->destroy(attr);
+
+	attr2 = ietf_swima_attr_req_create_from_data(value.len, value);
+	ck_assert(attr2);
+
+	attr1->destroy(attr1);
+	ck_assert(attr2->process(attr2, &offset) == SUCCESS);
+
+	type = attr2->get_type(attr2);
+	ck_assert(pen_type_equals(type, pen_type));
+
+	c_attr = (ietf_swima_attr_req_t*)attr2;
+	ck_assert(c_attr->get_flags(c_attr) == req_data[_i].flags);
+	ck_assert(c_attr->get_request_id(c_attr) == req_data[_i].request_id);
+
+	targets = c_attr->get_targets(c_attr);
+	ck_assert(targets->get_eid(targets, NULL) == req_data[_i].earliest_eid);
+	
+	enumerator = targets->create_enumerator(targets);
+	ck_assert(enumerator);
+	n = 0;
+	while (enumerator->enumerate(enumerator, &target))
+	{
+		sw_id = target->get_sw_id(target, NULL);
+		ck_assert(chunk_equals(sw_id, chunk_from_str(sw_id_str[n++])));
+	}
+	enumerator->destroy(enumerator);
+
+	attr2->destroy(attr2);
+}
+END_TEST
+
+START_TEST(test_imcv_swima_sw_req_trunc)
+{
+	pa_tnc_attr_t *attr;
+	chunk_t data;
+	uint32_t offset = 100;
+
+	/* Data smaller than minimum size */
+	attr = ietf_swima_attr_req_create_from_data(0, chunk_empty);
+	ck_assert(attr);
+	ck_assert(attr->process(attr, &offset) == FAILED && offset == 0);
+	attr->destroy(attr);
+
+	/* Truncate first SW ID */
+	data = req_data[2].value;
+	data.len = 14;
+	attr = ietf_swima_attr_req_create_from_data(data.len, data);
+	ck_assert(attr);
+	ck_assert(attr->process(attr, &offset) == FAILED && offset == 12);
+	attr->destroy(attr);
+
+	/* Truncate second SW ID */
+	data = req_data[2].value;
+	data.len = 47;
+	attr = ietf_swima_attr_req_create_from_data(data.len, data);
+	ck_assert(attr);
+	ck_assert(attr->process(attr, &offset) == FAILED && offset == 45);
+	attr->destroy(attr);
+
+	/* Segmentation */
+	data = req_data[2].value;
+	data.len = 50;
+	attr = ietf_swima_attr_req_create_from_data(req_data[2].value.len, data);
+	ck_assert(attr);
+	ck_assert(attr->process(attr, &offset) == NEED_MORE);
+	data = chunk_skip(req_data[2].value, 50);
+	attr->add_segment(attr, data);
+	ck_assert(attr->process(attr, &offset) == SUCCESS);
+	attr->destroy(attr);
+}
+END_TEST
+
+static pen_type_t sw_inv_types[] = {
+	{ PEN_IETF, IETF_ATTR_SW_INVENTORY },
+	{ PEN_IETF, IETF_ATTR_SW_ID_INVENTORY }
+};
+
+typedef struct sw_inv_data_t sw_inv_data_t;
+
+struct sw_inv_data_t {
+	uint8_t flags;
+	uint32_t request_id;
+	uint32_t eid_epoch;
+	uint32_t last_eid;
+	chunk_t  value;
+};
+
+static sw_inv_data_t sw_inv_data[] = {
+	{ IETF_SWIMA_ATTR_SW_INV_FLAG_NONE, 0xaabbccd0, 0x87654321, 0x00000007,
+	  chunk_from_chars(
+		0x00, 0x00, 0x00, 0x00, 0xAA, 0xBB, 0xCC, 0xD0, 0x87, 0x65,
+		0x43, 0x21, 0x00, 0x00, 0x00, 0x07)
+	},
+	{ IETF_SWIMA_ATTR_SW_INV_FLAG_NONE, 0xaabbccd1, 0x87654321, 0x00000007,
+	  chunk_from_chars(
+		0x00, 0x00, 0x00, 0x00, 0xAA, 0xBB, 0xCC, 0xD1, 0x87, 0x65,
+		0x43, 0x21, 0x00, 0x00, 0x00, 0x07)
+	},
+	{ IETF_SWIMA_ATTR_SW_INV_FLAG_NONE, 0xaabbccd2, 0x12345678, 0x00000030,
+	  chunk_from_chars(
+		0x00, 0x00, 0x00, 0x01, 0xAA, 0xBB, 0xCC, 0xD2, 0x12, 0x34,
+		0x56, 0x78, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x1F, 0x73, 0x74, 0x72,
+		0x6F, 0x6E, 0x67, 0x73, 0x77, 0x61, 0x6E, 0x2E, 0x6F, 0x72,
+		0x67, 0x5F, 0x73, 0x74, 0x72, 0x6F, 0x6E, 0x67, 0x53, 0x77,
+		0x61, 0x6E, 0x5F, 0x35, 0x2E, 0x33, 0x2E, 0x33, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x31, 0x3C, 0x53, 0x6F, 0x66, 0x74, 0x77,
+		0x61, 0x72, 0x65, 0x49, 0x64, 0x65, 0x6E, 0x74, 0x69, 0x74,
+		0x79, 0x20, 0x74, 0x61, 0x67, 0x49, 0x64, 0x3D, 0x22, 0x61,
+		0x62, 0x63, 0x22, 0x3E, 0x3C, 0x2F, 0x53, 0x6F, 0x66, 0x74,
+		0x77, 0x61, 0x72, 0x65, 0x49, 0x64, 0x65, 0x6E, 0x74, 0x69,
+		0x74, 0x79, 0x3E)
+	},
+	{ IETF_SWIMA_ATTR_SW_INV_FLAG_NONE, 0xaabbccd3, 0x12345678, 0x00000030,
+	  chunk_from_chars(
+		0x00, 0x00, 0x00, 0x01, 0xAA, 0xBB, 0xCC, 0xD3, 0x12, 0x34,
+		0x56, 0x78, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x1F, 0x73, 0x74, 0x72,
+		0x6F, 0x6E, 0x67, 0x73, 0x77, 0x61, 0x6E, 0x2E, 0x6F, 0x72,
+		0x67, 0x5F, 0x73, 0x74, 0x72, 0x6F, 0x6E, 0x67, 0x53, 0x77,
+        0x61, 0x6E, 0x5F, 0x35, 0x2E, 0x33, 0x2E, 0x33, 0x00, 0x00)
+	},
+	{ IETF_SWIMA_ATTR_SW_INV_FLAG_S_F, 0xaabbccd4, 0x12345678, 0x00000034,
+	  chunk_from_chars(
+		0x80, 0x00, 0x00, 0x02, 0xAA, 0xBB, 0xCC, 0xD4, 0x12, 0x34,
+		0x56, 0x78, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x1F, 0x73, 0x74, 0x72,
+		0x6F, 0x6E, 0x67, 0x73, 0x77, 0x61, 0x6E, 0x2E, 0x6F, 0x72,
+		0x67, 0x5F, 0x73, 0x74, 0x72, 0x6F, 0x6E, 0x67, 0x53, 0x77,
+		0x61, 0x6E, 0x5F, 0x35, 0x2E, 0x33, 0x2E, 0x33, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x31, 0x3C, 0x53, 0x6F, 0x66, 0x74, 0x77,
+		0x61, 0x72, 0x65, 0x49, 0x64, 0x65, 0x6E, 0x74, 0x69, 0x74,
+		0x79, 0x20, 0x74, 0x61, 0x67, 0x49, 0x64, 0x3D, 0x22, 0x61,
+		0x62, 0x63, 0x22, 0x3E, 0x3C, 0x2F, 0x53, 0x6F, 0x66, 0x74,
+		0x77, 0x61, 0x72, 0x65, 0x49, 0x64, 0x65, 0x6E, 0x74, 0x69,
+		0x74, 0x79, 0x3E, 0x00, 0x00, 0x00, 0x01, 0x00, 0x90, 0x2A,
+		0x19, 0x11, 0x00, 0x33, 0x73, 0x74, 0x72, 0x6F,	0x6E, 0x67,
+		0x73, 0x77, 0x61, 0x6E, 0x2E, 0x6F, 0x72, 0x67,	0x5F, 0x36,
+		0x32, 0x32, 0x35, 0x31, 0x61, 0x61, 0x36, 0x2D,	0x31, 0x61,
+		0x30, 0x31, 0x2D, 0x34, 0x37, 0x39, 0x62, 0x2D,	0x61, 0x65,
+		0x61, 0x36, 0x2D, 0x66, 0x33, 0x64, 0x63, 0x66, 0x30, 0x61,
+		0x62, 0x31, 0x66, 0x31, 0x61, 0x00, 0x00, 0x00,	0x00, 0x00,
+		0x31, 0x3C, 0x53, 0x6F, 0x66, 0x74, 0x77, 0x61,	0x72, 0x65,
+		0x49, 0x64, 0x65, 0x6E, 0x74, 0x69, 0x74, 0x79,	0x20, 0x74,
+		0x61, 0x67, 0x49, 0x64, 0x3D, 0x22, 0x64, 0x65,	0x66, 0x22,
+		0x3E, 0x3C, 0x2F, 0x53, 0x6F, 0x66, 0x74, 0x77,	0x61, 0x72,
+		0x65, 0x49, 0x64, 0x65, 0x6E, 0x74, 0x69, 0x74,	0x79, 0x3E)
+	},
+	{ IETF_SWIMA_ATTR_SW_INV_FLAG_S_F, 0xaabbccd5, 0x12345678, 0x00000034,
+	  chunk_from_chars(
+		0x80, 0x00, 0x00, 0x02, 0xAA, 0xBB, 0xCC, 0xD5, 0x12, 0x34,
+		0x56, 0x78, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x1F, 0x73, 0x74, 0x72,
+		0x6F, 0x6E, 0x67, 0x73, 0x77, 0x61, 0x6E, 0x2E, 0x6F, 0x72,
+		0x67, 0x5F, 0x73, 0x74, 0x72, 0x6F, 0x6E, 0x67, 0x53, 0x77,
+		0x61, 0x6E, 0x5F, 0x35, 0x2E, 0x33, 0x2E, 0x33, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x01, 0x00, 0x90, 0x2A, 0x19, 0x11, 0x00,
+		0x33, 0x73, 0x74, 0x72, 0x6F, 0x6E, 0x67, 0x73, 0x77, 0x61,
+		0x6E, 0x2E, 0x6F, 0x72, 0x67, 0x5F, 0x36, 0x32,	0x32, 0x35,
+		0x31, 0x61, 0x61, 0x36, 0x2D, 0x31, 0x61, 0x30,	0x31, 0x2D,
+		0x34, 0x37, 0x39, 0x62, 0x2D, 0x61, 0x65, 0x61,	0x36, 0x2D,
+		0x66, 0x33, 0x64, 0x63, 0x66, 0x30, 0x61, 0x62,	0x31, 0x66,
+		0x31, 0x61, 0x00, 0x00)
+	}
+};
+
+START_TEST(test_imcv_swima_inv)
+{
+	pen_type_t type, data_model;
+	chunk_t sw_id, record, value;
+	ietf_swima_attr_sw_inv_t *c_attr;
+	pa_tnc_attr_t *attr, *attr1, *attr2;
+	swima_record_t *sw_record;
+	swima_inventory_t *sw_inv;
+	enumerator_t *enumerator;
+	uint32_t offset, epoch;
+	uint8_t source_id;
+	bool sw_id_only = _i % 2;
+	int n;
+
+	attr = ietf_swima_attr_sw_inv_create(sw_inv_data[_i].flags,
+										 sw_inv_data[_i].request_id,
+										 sw_id_only);
+
+	sw_inv = swima_inventory_create();
+	sw_inv->set_eid(sw_inv, sw_inv_data[_i].last_eid, sw_inv_data[_i].eid_epoch); 
+	for (n = 0; n < _i/2; n++)
+	{
+		sw_id = chunk_from_str(sw_id_str[n]);
+		sw_record = swima_record_create(n, sw_id, chunk_empty);
+
+		if (n == 1)
+		{
+			sw_record->set_data_model(sw_record, ita_data_model);
+			sw_record->set_source_id(sw_record, 0x11);
+		}
+		if (!sw_id_only)
+		{
+			record = chunk_from_str(sw_record_str[n]);
+			sw_record->set_record(sw_record, record);
+		}
+		sw_inv->add(sw_inv, sw_record);
+	}
+	c_attr = (ietf_swima_attr_sw_inv_t*)attr;
+	c_attr->set_inventory(c_attr, sw_inv);
+	c_attr->set_inventory(c_attr, sw_inv);
+
+	attr->build(attr);
+	attr->build(attr);
+	sw_inv->destroy(sw_inv);
+
+	type = attr->get_type(attr);
+	ck_assert(pen_type_equals(type, sw_inv_types[sw_id_only]));
+
+	ck_assert(attr->get_noskip_flag(attr) == FALSE);
+	attr->set_noskip_flag(attr, TRUE);
+	ck_assert(attr->get_noskip_flag(attr) == TRUE);
+
+	value = attr->get_value(attr);
+	ck_assert_chunk_eq(value, sw_inv_data[_i].value);
+
+	attr1 = attr->get_ref(attr);
+	attr->destroy(attr);
+
+	attr2 = ietf_swima_attr_sw_inv_create_from_data(value.len, value,
+													sw_id_only);
+	ck_assert(attr2);
+	attr1->destroy(attr1);
+	ck_assert(attr2->process(attr2, &offset) == SUCCESS);
+
+	type = attr2->get_type(attr2);
+	ck_assert(pen_type_equals(type, sw_inv_types[sw_id_only]));
+
+	c_attr = (ietf_swima_attr_sw_inv_t*)attr2;
+	ck_assert(c_attr->get_flags(c_attr) == sw_inv_data[_i].flags);
+	ck_assert(c_attr->get_record_count(c_attr) == 0);
+	ck_assert(c_attr->get_request_id(c_attr) == sw_inv_data[_i].request_id);
+
+	sw_inv =  c_attr->get_inventory(c_attr);
+	ck_assert(sw_inv->get_eid(sw_inv, NULL) == sw_inv_data[_i].last_eid);
+	ck_assert(sw_inv->get_eid(sw_inv, &epoch) == sw_inv_data[_i].last_eid);
+	ck_assert(epoch == sw_inv_data[_i].eid_epoch);
+	ck_assert(sw_inv);
+	ck_assert(sw_inv->get_count(sw_inv) == _i/2);
+
+	enumerator = sw_inv->create_enumerator(sw_inv);
+	ck_assert(enumerator);
+
+	n = 0;
+	while (enumerator->enumerate(enumerator, &sw_record))
+	{
+		ck_assert(sw_record->get_record_id(sw_record) == n);
+		data_model = sw_record->get_data_model(sw_record);
+		ck_assert(pen_type_equals(data_model, (n == 1) ? ita_data_model :
+								  swima_data_model_iso_2015_swid_xml));
+		source_id = sw_record->get_source_id(sw_record);
+		ck_assert(source_id == (n == 1 ? 0x11 : 0x00));
+		n++;
+	}
+	enumerator->destroy(enumerator);
+	ck_assert(n == _i/2);
+
+	attr2->destroy(attr2);
+}
+END_TEST
+
+/**
+ * Offsets in sw_inv_data[4].value
+ *
+ *   0 constant header
+ *  12   segment  1  -  12 octets
+ *  16 record_id
+ *  18   segment  2  -   6 octets
+ *  20 data_model_pen
+ *  22   segment  3  -   4 octets
+ *  23   segment  4  -   1 octet
+ *  23 data_model_type
+ *  24   segment  5  -   1 octet
+ *  24 source_id
+ *  25 sw_id
+ *  26   segment  6  -   2 octets
+ *  58 sw_locator
+ *  59   segment  7  -  33 octets
+ *  60 record
+ *  62   segment  8  -   3 octets
+ * 113 sw record 2
+ * 114   segment  9  -  52 octets
+ * 230   segment 10  - 116 octets
+ */
+
+START_TEST(test_imcv_swima_sw_inv_trunc)
+{
+	pa_tnc_attr_t *attr;
+	ietf_swima_attr_sw_inv_t *c_attr;
+	chunk_t data;
+	swima_inventory_t *sw_inv;
+	size_t len = sw_inv_data[4].value.len;
+	uint32_t offset = 100;
+
+	/* Data smaller than minimum size */
+	attr = ietf_swima_attr_sw_inv_create_from_data(0, chunk_empty, FALSE);
+	ck_assert(attr);
+	ck_assert(attr->process(attr, &offset) == FAILED && offset == 0);
+	attr->destroy(attr);
+
+	/* Length larger than data */
+	data = sw_inv_data[4].value;
+	attr = ietf_swima_attr_sw_inv_create_from_data(len + 2, data, FALSE);
+	ck_assert(attr);
+	ck_assert(attr->process(attr, &offset) == FAILED && offset == len);
+	attr->destroy(attr);
+
+	/* Segment 1 truncates minimum size */
+	data = sw_inv_data[4].value;
+	data.len = 12;
+	attr = ietf_swima_attr_sw_inv_create_from_data(len, data, FALSE);
+	ck_assert(attr);
+	ck_assert(attr->process(attr, &offset) == NEED_MORE);
+
+	/* Segment 2 truncates record_id */
+	data = chunk_skip(sw_inv_data[4].value, 12);
+	data.len = 6;
+	attr->add_segment(attr, data);
+	ck_assert(attr->process(attr, &offset) == NEED_MORE);
+
+	/* Segment 3 truncates data_model_pen */
+	data = chunk_skip(sw_inv_data[4].value, 18);
+	data.len = 4;
+	attr->add_segment(attr, data);
+	ck_assert(attr->process(attr, &offset) == NEED_MORE);
+
+	/* Segment 4 truncates data_model_type */
+	data = chunk_skip(sw_inv_data[4].value, 22);
+	data.len = 1;
+	attr->add_segment(attr, data);
+	ck_assert(attr->process(attr, &offset) == NEED_MORE);
+
+	/* Segment 5 truncates source_id */
+	data = chunk_skip(sw_inv_data[4].value, 23);
+	data.len = 1;
+	attr->add_segment(attr, data);
+	ck_assert(attr->process(attr, &offset) == NEED_MORE);
+
+	/* Segment 6 truncates sw_id */
+	data = chunk_skip(sw_inv_data[4].value, 24);
+	data.len = 2;
+	attr->add_segment(attr, data);
+	ck_assert(attr->process(attr, &offset) == NEED_MORE);
+
+	/* Segment 7 truncates sw_locator */
+	data = chunk_skip(sw_inv_data[4].value, 26);
+	data.len = 33;
+	attr->add_segment(attr, data);
+	ck_assert(attr->process(attr, &offset) == NEED_MORE);
+
+	/* Segment 8 truncates record */
+	data = chunk_skip(sw_inv_data[4].value, 59);
+	data.len = 3;
+	attr->add_segment(attr, data);
+	ck_assert(attr->process(attr, &offset) == NEED_MORE);
+
+	/* Segment 9 truncates second sw_record */
+	data = chunk_skip(sw_inv_data[4].value, 62);
+	data.len = 52;
+	attr->add_segment(attr, data);
+	ck_assert(attr->process(attr, &offset) == SUCCESS);
+
+	/* Process first inventory entry */
+	c_attr = (ietf_swima_attr_sw_inv_t*)attr;
+	sw_inv = c_attr->get_inventory(c_attr);
+	ck_assert(sw_inv->get_count(sw_inv) == 1);
+	c_attr->clear_inventory(c_attr);
+
+	/* Segment 10 truncates second sw_record */
+	data = chunk_skip(sw_inv_data[4].value, 114);
+	data.len = 116;
+	attr->add_segment(attr, data);
+	ck_assert(attr->process(attr, &offset) == SUCCESS);
+
+	/* Process second inventory entry */
+	sw_inv = c_attr->get_inventory(c_attr);
+	ck_assert(sw_inv->get_count(sw_inv) == 1);
+	c_attr->clear_inventory(c_attr);
+
+	attr->destroy(attr);
+}
+END_TEST
+
+static char* sw_ev_timestamp_str[] = {
+	"2017-05-30T18:09:25Z",
+	"2017-06-14T15:38:00Z"
+};
+
+START_TEST(test_imcv_swima_event)
+{
+	chunk_t sw_id, sw_timestamp, timestamp;
+	swima_event_t *sw_event, *sw_event_cp;
+	swima_record_t *sw_record;
+	uint32_t record_id = 1, eid = 7;
+	uint8_t action = SWIMA_EVENT_ACTION_CREATION;
+
+	sw_id = chunk_from_str(sw_id_str[0]);
+	sw_timestamp = chunk_from_str(sw_ev_timestamp_str[0]);
+
+	/* Software Identity without Software Locator */
+	sw_record = swima_record_create(record_id, sw_id, chunk_empty),
+	ck_assert(sw_record);
+
+	sw_event = swima_event_create(eid, sw_timestamp, action, sw_record);
+	ck_assert(sw_event);
+	sw_event_cp = sw_event->get_ref(sw_event);
+
+	ck_assert(sw_event->get_eid(sw_event, NULL) == eid);
+	ck_assert(sw_event->get_eid(sw_event, &timestamp) == eid);
+	ck_assert_chunk_eq(sw_timestamp, timestamp);
+	ck_assert(sw_event->get_action(sw_event) == action);
+	sw_event->destroy(sw_event);
+
+	sw_record = sw_event_cp->get_sw_record(sw_event_cp);
+	ck_assert(sw_record);
+	ck_assert(sw_record->get_record_id(sw_record) == record_id);
+	ck_assert_chunk_eq(sw_record->get_sw_id(sw_record, NULL), sw_id);
+	sw_event_cp->destroy(sw_event_cp);
+}
+END_TEST
+
+static pen_type_t sw_ev_types[] = {
+	{ PEN_IETF, IETF_ATTR_SW_EVENTS },
+	{ PEN_IETF, IETF_ATTR_SW_ID_EVENTS }
+};
+
+typedef struct sw_ev_data_t sw_ev_data_t;
+
+struct sw_ev_data_t {
+	uint8_t flags;
+	uint32_t request_id;
+	uint32_t eid_epoch;
+	uint32_t last_eid;
+	uint32_t last_consulted_eid;
+	chunk_t  value;
+};
+
+static sw_ev_data_t sw_ev_data[] = {
+	{ IETF_SWIMA_ATTR_SW_EV_FLAG_NONE, 0xaabbccd0, 0x87654321, 0x00000007,
+	  0x00000007, chunk_from_chars(
+		0x00, 0x00, 0x00, 0x00, 0xAA, 0xBB, 0xCC, 0xD0, 0x87, 0x65,
+		0x43, 0x21, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x07)
+	},
+	{ IETF_SWIMA_ATTR_SW_EV_FLAG_NONE, 0xaabbccd1, 0x87654321, 0x00000007,
+	  0x00000007, chunk_from_chars(
+		0x00, 0x00, 0x00, 0x00, 0xAA, 0xBB, 0xCC, 0xD1, 0x87, 0x65,
+		0x43, 0x21, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x07)
+	},
+	{ IETF_SWIMA_ATTR_SW_EV_FLAG_NONE, 0xaabbccd2, 0x12345678, 0x00000030,
+	  0x00000030, chunk_from_chars(
+		0x00, 0x00, 0x00, 0x01, 0xAA, 0xBB, 0xCC, 0xD2, 0x12, 0x34,
+		0x56, 0x78, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x30,
+		0x00, 0x00, 0x00, 0x30,  '2',  '0',  '1',  '7',  '-',  '0',
+		 '5',  '-',  '3',  '0',  'T',  '1',  '8',  ':',  '0',  '9',
+		 ':',  '2',  '5',  'Z', 0x00, 0x00, 0x00, 0x00,	0x00, 0x00,
+		0x00, 0x01, 0x00, 0x01, 0x00, 0x1F, 0x73, 0x74,	0x72, 0x6F,
+		0x6E, 0x67, 0x73, 0x77, 0x61, 0x6E, 0x2E, 0x6F,	0x72, 0x67,
+		0x5F, 0x73, 0x74, 0x72, 0x6F, 0x6E, 0x67, 0x53,	0x77, 0x61,
+		0x6E, 0x5F, 0x35, 0x2E, 0x33, 0x2E, 0x33, 0x00,	0x00, 0x00,
+		0x00, 0x00, 0x31, 0x3C, 0x53, 0x6F, 0x66, 0x74,	0x77, 0x61,
+		0x72, 0x65, 0x49, 0x64, 0x65, 0x6E, 0x74, 0x69,	0x74, 0x79,
+		0x20, 0x74, 0x61, 0x67, 0x49, 0x64, 0x3D, 0x22,	0x61, 0x62,
+		0x63, 0x22, 0x3E, 0x3C, 0x2F, 0x53, 0x6F, 0x66,	0x74, 0x77,
+		0x61, 0x72, 0x65, 0x49, 0x64, 0x65, 0x6E, 0x74,	0x69, 0x74,
+		0x79, 0x3E)
+	},
+	{ IETF_SWIMA_ATTR_SW_EV_FLAG_NONE, 0xaabbccd3, 0x12345678, 0x00000030,
+	  0x00000030, chunk_from_chars(
+		0x00, 0x00, 0x00, 0x01, 0xAA, 0xBB, 0xCC, 0xD3, 0x12, 0x34,
+		0x56, 0x78, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x30,
+		0x00, 0x00, 0x00, 0x30,  '2',  '0',  '1',  '7',  '-',  '0',
+		 '5',  '-',  '3',  '0',  'T',  '1',  '8',  ':',  '0',  '9',
+		 ':',  '2',  '5',  'Z', 0x00, 0x00, 0x00, 0x00,	0x00, 0x00,
+		0x00, 0x01, 0x00, 0x01, 0x00, 0x1F, 0x73, 0x74,	0x72, 0x6F,
+		0x6E, 0x67, 0x73, 0x77, 0x61, 0x6E, 0x2E, 0x6F,	0x72, 0x67,
+		0x5F, 0x73, 0x74, 0x72, 0x6F, 0x6E, 0x67, 0x53,	0x77, 0x61,
+		0x6E, 0x5F, 0x35, 0x2E, 0x33, 0x2E, 0x33, 0x00,	0x00)
+	},
+	{ IETF_SWIMA_ATTR_SW_EV_FLAG_S_F, 0xaabbccd4, 0x12345678, 0x00000050,
+	  0x00000034, chunk_from_chars(
+		0x80, 0x00, 0x00, 0x02, 0xAA, 0xBB, 0xCC, 0xD4, 0x12, 0x34,
+		0x56, 0x78, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x34,
+		0x00, 0x00, 0x00, 0x30,  '2',  '0',  '1',  '7',  '-',  '0',
+		 '5',  '-',  '3',  '0',  'T',  '1',  '8',  ':',  '0',  '9',
+		 ':',  '2',  '5',  'Z', 0x00, 0x00, 0x00, 0x00,	0x00, 0x00,
+		0x00, 0x01, 0x00, 0x01, 0x00, 0x1F, 0x73, 0x74,	0x72, 0x6F,
+		0x6E, 0x67, 0x73, 0x77, 0x61, 0x6E, 0x2E, 0x6F,	0x72, 0x67,
+		0x5F, 0x73, 0x74, 0x72, 0x6F, 0x6E, 0x67, 0x53,	0x77, 0x61,
+		0x6E, 0x5F, 0x35, 0x2E, 0x33, 0x2E, 0x33, 0x00,	0x00, 0x00,
+		0x00, 0x00, 0x31, 0x3C, 0x53, 0x6F, 0x66, 0x74,	0x77, 0x61,
+		0x72, 0x65, 0x49, 0x64, 0x65, 0x6E, 0x74, 0x69,	0x74, 0x79,
+		0x20, 0x74, 0x61, 0x67, 0x49, 0x64, 0x3D, 0x22,	0x61, 0x62,
+		0x63, 0x22, 0x3E, 0x3C, 0x2F, 0x53, 0x6F, 0x66,	0x74, 0x77,
+		0x61, 0x72, 0x65, 0x49, 0x64, 0x65, 0x6E, 0x74,	0x69, 0x74,
+		0x79, 0x3E, 0x00, 0x00, 0x00, 0x34,  '2',  '0',  '1',  '7',
+		 '-',  '0',  '6',  '-',  '1',  '4',  'T',  '1',  '5',  ':',
+		 '3',  '8',  ':',  '0',  '0',  'Z', 0x00, 0x00, 0x00, 0x01,
+		0x00, 0x90, 0x2A, 0x19, 0x11, 0x02, 0x00, 0x33, 0x73, 0x74,
+		0x72, 0x6F, 0x6E, 0x67, 0x73, 0x77, 0x61, 0x6E, 0x2E, 0x6F,
+		0x72, 0x67, 0x5F, 0x36, 0x32, 0x32, 0x35, 0x31, 0x61, 0x61,
+		0x36, 0x2D, 0x31, 0x61, 0x30, 0x31, 0x2D, 0x34, 0x37, 0x39,
+		0x62, 0x2D, 0x61, 0x65, 0x61, 0x36, 0x2D, 0x66, 0x33, 0x64,
+		0x63, 0x66, 0x30, 0x61, 0x62, 0x31, 0x66, 0x31, 0x61, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x31, 0x3C, 0x53, 0x6F, 0x66, 0x74,
+		0x77, 0x61, 0x72, 0x65, 0x49, 0x64, 0x65, 0x6E, 0x74, 0x69,
+		0x74, 0x79, 0x20, 0x74, 0x61, 0x67, 0x49, 0x64, 0x3D, 0x22,
+		0x64, 0x65, 0x66, 0x22, 0x3E, 0x3C, 0x2F, 0x53, 0x6F, 0x66,
+		0x74, 0x77, 0x61, 0x72, 0x65, 0x49, 0x64, 0x65, 0x6E, 0x74,
+		0x69, 0x74, 0x79, 0x3E)
+	},
+	{ IETF_SWIMA_ATTR_SW_EV_FLAG_S_F, 0xaabbccd5, 0x12345678, 0x00000050,
+	  0x00000034, chunk_from_chars(
+		0x80, 0x00, 0x00, 0x02, 0xAA, 0xBB, 0xCC, 0xD5, 0x12, 0x34,
+		0x56, 0x78, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x34,
+		0x00, 0x00, 0x00, 0x30,  '2',  '0',  '1',  '7',  '-',  '0',
+		 '5',  '-',  '3',  '0',  'T',  '1',  '8',  ':',  '0',  '9',
+		 ':',  '2',  '5',  'Z', 0x00, 0x00, 0x00, 0x00,	0x00, 0x00,
+		0x00, 0x01, 0x00, 0x01, 0x00, 0x1F, 0x73, 0x74,	0x72, 0x6F,
+		0x6E, 0x67, 0x73, 0x77, 0x61, 0x6E, 0x2E, 0x6F,	0x72, 0x67,
+		0x5F, 0x73, 0x74, 0x72, 0x6F, 0x6E, 0x67, 0x53,	0x77, 0x61,
+		0x6E, 0x5F, 0x35, 0x2E, 0x33, 0x2E, 0x33, 0x00,	0x00, 0x00,
+		0x00, 0x00, 0x34,  '2',  '0',  '1',  '7', '-',   '0',  '6',
+		 '-',  '1',  '4',  'T',  '1',  '5',  ':', '3',  '8',  ':',
+		 '0',  '0',  'Z', 0x00, 0x00, 0x00, 0x01, 0x00, 0x90, 0x2A,
+		0x19, 0x11, 0x02, 0x00, 0x33, 0x73, 0x74, 0x72, 0x6F, 0x6E,
+		0x67, 0x73, 0x77, 0x61, 0x6E, 0x2E, 0x6F, 0x72, 0x67, 0x5F,
+		0x36, 0x32, 0x32, 0x35, 0x31, 0x61, 0x61, 0x36, 0x2D, 0x31,
+		0x61, 0x30, 0x31, 0x2D, 0x34, 0x37, 0x39, 0x62, 0x2D, 0x61,
+		0x65, 0x61, 0x36, 0x2D, 0x66, 0x33, 0x64, 0x63, 0x66, 0x30,
+		0x61, 0x62, 0x31, 0x66, 0x31, 0x61, 0x00, 0x00)
+	}
+};
+
+START_TEST(test_imcv_swima_ev)
+{
+	pen_type_t type, data_model;
+	chunk_t sw_id, record, timestamp, value;
+	ietf_swima_attr_sw_ev_t *c_attr;
+	pa_tnc_attr_t *attr, *attr1, *attr2;
+	swima_record_t *sw_record;
+	swima_event_t *sw_event;
+	swima_events_t *sw_ev;
+	enumerator_t *enumerator;
+	uint32_t offset, epoch, eid, last_eid;
+	uint8_t source_id, action;
+	bool sw_id_only = _i % 2;
+	int n;
+
+	attr = ietf_swima_attr_sw_ev_create(sw_ev_data[_i].flags,
+										sw_ev_data[_i].request_id,
+										sw_id_only);
+	sw_ev = swima_events_create();
+	sw_ev->set_eid(sw_ev, sw_ev_data[_i].last_consulted_eid,
+						  sw_ev_data[_i].eid_epoch);
+	if (sw_ev_data[_i].last_consulted_eid < sw_ev_data[_i].last_eid)
+	{
+		sw_ev->set_last_eid(sw_ev, sw_ev_data[_i].last_eid);
+	}
+
+	for (n = 0; n < _i/2; n++)
+	{
+		sw_id = chunk_from_str(sw_id_str[n]);
+		sw_record = swima_record_create(n, sw_id, chunk_empty);
+
+		if (n == 1)
+		{
+			sw_record->set_data_model(sw_record, ita_data_model);
+			sw_record->set_source_id(sw_record, 0x11);
+		}
+		if (!sw_id_only)
+		{
+			record = chunk_from_str(sw_record_str[n]);
+			sw_record->set_record(sw_record, record);
+		}
+		eid = 0x30 + 4 * n;
+		timestamp = chunk_from_str(sw_ev_timestamp_str[n]);
+		action = n + 1;
+		sw_event = swima_event_create(eid, timestamp, action, sw_record);
+		sw_ev->add(sw_ev, sw_event);
+	}
+	c_attr = (ietf_swima_attr_sw_ev_t*)attr;
+	c_attr->set_events(c_attr, sw_ev);
+	c_attr->set_events(c_attr, sw_ev);
+
+	attr->build(attr);
+	attr->build(attr);
+	sw_ev->destroy(sw_ev);
+
+	type = attr->get_type(attr);
+	ck_assert(pen_type_equals(type, sw_ev_types[sw_id_only]));
+
+	ck_assert(attr->get_noskip_flag(attr) == FALSE);
+	attr->set_noskip_flag(attr, TRUE);
+	ck_assert(attr->get_noskip_flag(attr) == TRUE);
+
+	value = attr->get_value(attr);
+	ck_assert_chunk_eq(value, sw_ev_data[_i].value);
+
+	attr1 = attr->get_ref(attr);
+	attr->destroy(attr);
+
+	attr2 = ietf_swima_attr_sw_ev_create_from_data(value.len, value,
+												   sw_id_only);
+	ck_assert(attr2);
+	attr1->destroy(attr1);
+	ck_assert(attr2->process(attr2, &offset) == SUCCESS);
+
+	type = attr2->get_type(attr2);
+	ck_assert(pen_type_equals(type, sw_ev_types[sw_id_only]));
+
+	c_attr = (ietf_swima_attr_sw_ev_t*)attr2;
+	ck_assert(c_attr->get_flags(c_attr) == sw_ev_data[_i].flags);
+	ck_assert(c_attr->get_event_count(c_attr) == 0);
+	ck_assert(c_attr->get_request_id(c_attr) == sw_ev_data[_i].request_id);
+
+	sw_ev =  c_attr->get_events(c_attr);
+	ck_assert(sw_ev);
+	eid = sw_ev->get_eid(sw_ev, NULL, NULL);
+	ck_assert(eid == sw_ev_data[_i].last_consulted_eid);
+	eid = sw_ev->get_eid(sw_ev, &epoch, &last_eid);
+	ck_assert(eid == sw_ev_data[_i].last_consulted_eid);
+	ck_assert(epoch == sw_ev_data[_i].eid_epoch);
+	ck_assert(last_eid == sw_ev_data[_i].last_eid);
+	ck_assert(sw_ev->get_count(sw_ev) == _i/2);
+
+	enumerator = sw_ev->create_enumerator(sw_ev);
+	ck_assert(enumerator);
+
+	n = 0;
+	while (enumerator->enumerate(enumerator, &sw_event))
+	{
+		ck_assert(sw_event->get_eid(sw_event, &timestamp) == 0x30 + 4 * n);
+		ck_assert_chunk_eq(timestamp, chunk_from_str(sw_ev_timestamp_str[n]));
+		sw_record = sw_event->get_sw_record(sw_event);
+		ck_assert(sw_record);
+		ck_assert(sw_record->get_record_id(sw_record) == n);
+		data_model = sw_record->get_data_model(sw_record);
+		ck_assert(pen_type_equals(data_model, (n == 1) ? ita_data_model :
+								  swima_data_model_iso_2015_swid_xml));
+		source_id = sw_record->get_source_id(sw_record);
+		ck_assert(source_id == (n == 1 ? 0x11 : 0x00));
+		n++;
+	}
+	enumerator->destroy(enumerator);
+	ck_assert(n == _i/2);
+
+	attr2->destroy(attr2);
+}
+END_TEST
+
+
+/**
+ * Offsets in sw_ev_data[4].value
+ *
+ *   0 constant header
+ *  16   segment  1  -  16 octets
+ *  20 eid 
+ *  22   segment  2  -   6 octets 
+ *  24 timestamp
+ *  26   segment  3  -   4 octets
+ *  44 record_id
+ *  46   segment  4  -  20 octets
+ *  48 data_model_pen
+ *  50   segment  5  -   4 octets
+ *  51   segment  6  -   1 octet
+ *  51 data_model_type
+ *  52   segment  7  -   1 octet
+ *  52 source_id
+ *  53   segment  8  -   1 octet
+ *  53 action
+ *  54 sw_id
+ *  55   segment  9  -   2 octets
+ *  87 sw_locator
+ *  88   segment 10  -  33 octets
+ *  89 record
+ *  91   segment 11  -   3 octets
+ * 142 sw record 2
+ * 143   segment 12  -  52 octets
+ * 284   segment 13  - 141 octets
+ */
+
+START_TEST(test_imcv_swima_sw_ev_trunc)
+{
+	pa_tnc_attr_t *attr;
+	ietf_swima_attr_sw_ev_t *c_attr;
+	chunk_t data;
+	swima_events_t *sw_ev;
+	size_t len = sw_ev_data[4].value.len;
+	uint32_t offset = 100;
+
+	/* Data smaller than minimum size */
+	attr = ietf_swima_attr_sw_ev_create_from_data(0, chunk_empty, FALSE);
+	ck_assert(attr);
+	ck_assert(attr->process(attr, &offset) == FAILED && offset == 0);
+	attr->destroy(attr);
+
+	/* Length larger than data */
+	data = sw_ev_data[4].value;
+	attr = ietf_swima_attr_sw_ev_create_from_data(len + 2, data, FALSE);
+	ck_assert(attr);
+	ck_assert(attr->process(attr, &offset) == FAILED && offset == len);
+	attr->destroy(attr);
+
+	/* Segment 1 truncates minimum size */
+	data = sw_ev_data[4].value;
+	data.len = 16;
+	attr = ietf_swima_attr_sw_ev_create_from_data(len, data, FALSE);
+	ck_assert(attr);
+	ck_assert(attr->process(attr, &offset) == NEED_MORE);
+
+	/* Segment 2 truncates eid */
+	data = chunk_skip(sw_ev_data[4].value, 16);
+	data.len = 6;
+	attr->add_segment(attr, data);
+	ck_assert(attr->process(attr, &offset) == NEED_MORE);
+
+	/* Segment 3 truncates timestamp */
+	data = chunk_skip(sw_ev_data[4].value, 22);
+	data.len = 4;
+	attr->add_segment(attr, data);
+	ck_assert(attr->process(attr, &offset) == NEED_MORE);
+
+	/* Segment 4 truncates record_id */
+	data = chunk_skip(sw_ev_data[4].value, 26);
+	data.len = 20;
+	attr->add_segment(attr, data);
+	ck_assert(attr->process(attr, &offset) == NEED_MORE);
+
+	/* Segment 5 truncates data_model_pen */
+	data = chunk_skip(sw_ev_data[4].value, 46);
+	data.len = 4;
+	attr->add_segment(attr, data);
+	ck_assert(attr->process(attr, &offset) == NEED_MORE);
+
+	/* Segment 6 truncates data_model_type */
+	data = chunk_skip(sw_ev_data[4].value, 50);
+	data.len = 1;
+	attr->add_segment(attr, data);
+	ck_assert(attr->process(attr, &offset) == NEED_MORE);
+
+	/* Segment 7 truncates source_id */
+	data = chunk_skip(sw_ev_data[4].value, 51);
+	data.len = 1;
+	attr->add_segment(attr, data);
+	ck_assert(attr->process(attr, &offset) == NEED_MORE);
+
+	/* Segment 8 truncates action */
+	data = chunk_skip(sw_ev_data[4].value, 52);
+	data.len = 1;
+	attr->add_segment(attr, data);
+	ck_assert(attr->process(attr, &offset) == NEED_MORE);
+
+	/* Segment 9 truncates sw_id */
+	data = chunk_skip(sw_ev_data[4].value, 53);
+	data.len = 2;
+	attr->add_segment(attr, data);
+	ck_assert(attr->process(attr, &offset) == NEED_MORE);
+
+	/* Segment 10 truncates sw_locator */
+	data = chunk_skip(sw_ev_data[4].value, 55);
+	data.len = 33;
+	attr->add_segment(attr, data);
+	ck_assert(attr->process(attr, &offset) == NEED_MORE);
+
+	/* Segment 11 truncates record */
+	data = chunk_skip(sw_ev_data[4].value, 88);
+	data.len = 3;
+	attr->add_segment(attr, data);
+	ck_assert(attr->process(attr, &offset) == NEED_MORE);
+
+	/* Segment 12 truncates second sw_entry */
+	data = chunk_skip(sw_ev_data[4].value, 91);
+	data.len = 52;
+	attr->add_segment(attr, data);
+	ck_assert(attr->process(attr, &offset) == SUCCESS);
+
+	/* Process first event entry */
+	c_attr = (ietf_swima_attr_sw_ev_t*)attr;
+	sw_ev = c_attr->get_events(c_attr);
+	ck_assert(sw_ev->get_count(sw_ev) == 1);
+	c_attr->clear_events(c_attr);
+
+	/* Segment 13 truncates second sw_record */
+	data = chunk_skip(sw_ev_data[4].value, 143);
+	data.len = 141;
+	attr->add_segment(attr, data);
+	ck_assert(attr->process(attr, &offset) == SUCCESS);
+
+	/* Process second event entry */
+	sw_ev = c_attr->get_events(c_attr);
+	ck_assert(sw_ev->get_count(sw_ev) == 1);
+	c_attr->clear_events(c_attr);
+	attr->destroy(attr);
+
+	/* Invalid Action values */
+	data = chunk_clone(sw_ev_data[2].value);
+	data.ptr[53] = 0;
+	attr = ietf_swima_attr_sw_ev_create_from_data(data.len, data, FALSE);
+	ck_assert(attr);
+	ck_assert(attr->process(attr, &offset) == FAILED);
+	attr->destroy(attr);
+
+	data.ptr[53] = SWIMA_EVENT_ACTION_LAST + 1;
+	attr = ietf_swima_attr_sw_ev_create_from_data(data.len, data, FALSE);
+	ck_assert(attr);
+	ck_assert(attr->process(attr, &offset) == FAILED && offset == 20);
+	attr->destroy(attr);
+	chunk_free(&data);
+}
+END_TEST
+
+START_TEST(test_imcv_swima_sw_collector)
+{
+	swima_collector_t *collector;
+	swima_inventory_t *targets, *inventory;
+	swima_events_t *events;
+	swima_record_t *sw_record;
+	swima_event_t *sw_event;
+	chunk_t sw_id, sw_locator, swid_tag;
+	enumerator_t *enumerator;
+	uint8_t source_id;
+	int item = 0, items;
+
+	targets = swima_inventory_create();
+	collector = swima_collector_create();
+
+	/* software identifier events only */
+	events = collector->collect_events(collector, TRUE, targets);
+	if (events)
+	{
+		items = events->get_count(events);
+		DBG1(DBG_IMC, "%d software identifiers collected", items);
+
+		enumerator = events->create_enumerator(events);
+		while (enumerator->enumerate(enumerator, &sw_event))
+		{
+			item++;
+			if ( item == 1 || item == items)
+			{
+				sw_record = sw_event->get_sw_record(sw_event);
+				sw_id = sw_record->get_sw_id(sw_record, NULL);
+				source_id =sw_record->get_source_id(sw_record);
+				DBG1(DBG_IMC, "source %u: %.*s", source_id, sw_id.len, sw_id.ptr);
+			}
+		}
+		enumerator->destroy(enumerator);
+	}
+
+	/* software identifier inventory only */
+	inventory = collector->collect_inventory(collector, TRUE, targets);
+	if (inventory)
+	{
+		items = inventory->get_count(inventory);
+		DBG1(DBG_IMC, "%d software identifiers collected", items);
+
+		enumerator = inventory->create_enumerator(inventory);
+		while (enumerator->enumerate(enumerator, &sw_record))
+		{
+			item++;
+			if ( item == 1 || item == items)
+			{
+				sw_id = sw_record->get_sw_id(sw_record, &sw_locator);
+				source_id =sw_record->get_source_id(sw_record);
+				DBG1(DBG_IMC, "source %u: %.*s", source_id, sw_id.len, sw_id.ptr);
+				if (sw_locator.len > 0)
+				{
+					DBG1(DBG_IMC, "          locator: %.*s",
+						 sw_locator.len, sw_locator.ptr);
+				}
+				targets->add(targets, sw_record->get_ref(sw_record));
+			}
+		}
+		enumerator->destroy(enumerator);
+	}
+
+	/* targeted software inventory */
+	inventory = collector->collect_inventory(collector, FALSE, targets);
+	if (inventory)
+	{
+		items = inventory->get_count(inventory);
+		DBG1(DBG_IMC, "%d SWID tags collected", items);
+
+		enumerator = inventory->create_enumerator(inventory);
+		while (enumerator->enumerate(enumerator, &sw_record))
+		{
+			sw_id = sw_record->get_sw_id(sw_record, NULL);
+			source_id =sw_record->get_source_id(sw_record);
+			swid_tag = sw_record->get_record(sw_record);
+			DBG1(DBG_IMC, "source %u: %.*s", source_id, sw_id.len, sw_id.ptr);
+			DBG2(DBG_IMC, "%B", &swid_tag);
+		}
+		enumerator->destroy(enumerator);
+	}
+
+	collector->destroy(collector);
+	targets->destroy(targets);
+}
+END_TEST
+
+Suite *imcv_swima_suite_create()
+{
+	Suite *s;
+	TCase *tc;
+
+	s = suite_create("imcv_swima");
+
+	tc = tcase_create("sw_record");
+	tcase_add_test(tc, test_imcv_swima_record);
+	suite_add_tcase(s, tc);
+
+	tc = tcase_create("sw_req");
+	tcase_add_loop_test(tc, test_imcv_swima_sw_req, 0, countof(req_data));
+	suite_add_tcase(s, tc);
+
+	tc = tcase_create("sw_req_trunc");
+	tcase_add_test(tc, test_imcv_swima_sw_req_trunc);
+	suite_add_tcase(s, tc);
+
+	tc = tcase_create("sw_inv");
+	tcase_add_loop_test(tc, test_imcv_swima_inv, 0, 6);
+	suite_add_tcase(s, tc);
+
+	tc = tcase_create("sw_inv_trunc");
+	tcase_add_test(tc, test_imcv_swima_sw_inv_trunc);
+	suite_add_tcase(s, tc);
+
+	tc = tcase_create("sw_event");
+	tcase_add_test(tc, test_imcv_swima_event);
+	suite_add_tcase(s, tc);
+
+	tc = tcase_create("sw_ev");
+	tcase_add_loop_test(tc, test_imcv_swima_ev, 0, 6);
+	suite_add_tcase(s, tc);
+
+	tc = tcase_create("sw_ev_trunc");
+	tcase_add_test(tc, test_imcv_swima_sw_ev_trunc);
+	suite_add_tcase(s, tc);
+
+	tc = tcase_create("sw_collector");
+	tcase_add_test(tc, test_imcv_swima_sw_collector);
+	suite_add_tcase(s, tc);
+
+	return s;
+}
diff --git a/src/libimcv/swid/swid_inventory.c b/src/libimcv/swid/swid_inventory.c
index a492869..5f6e50c 100644
--- a/src/libimcv/swid/swid_inventory.c
+++ b/src/libimcv/swid/swid_inventory.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2013-2014 Andreas Steffen
+ * Copyright (C) 2013-2017 Andreas Steffen
  * HSR Hochschule fuer Technik Rapperswil
  *
  * This program is free software; you can redistribute it and/or modify it
@@ -16,9 +16,10 @@
 #include "swid_inventory.h"
 #include "swid_tag.h"
 #include "swid_tag_id.h"
+#include "swid_gen/swid_gen.h"
 
 #include <collections/linked_list.h>
-#include <bio/bio_writer.h>
+#include <utils/lexparser.h>
 #include <utils/debug.h>
 
 #include <stdio.h>
@@ -52,192 +53,99 @@ struct private_swid_inventory_t {
 	linked_list_t *list;
 };
 
-/**
- * Read SWID tags issued by the swid_generator tool
- */
-static status_t read_swid_tags(private_swid_inventory_t *this, FILE *file)
+static status_t generate_tags(private_swid_inventory_t *this,
+							  swid_inventory_t *targets, bool pretty, bool full)
 {
+	swid_gen_t *swid_gen;
 	swid_tag_t *tag;
-	bio_writer_t *writer;
-	chunk_t tag_encoding, tag_file_path = chunk_empty;
-	bool more_tags = TRUE, last_newline;
-	char line[8192];
-	size_t len;
-
-	while (more_tags)
-	{
-		last_newline = TRUE;
-		writer = bio_writer_create(512);
-		while (TRUE)
-		{
-			if (!fgets(line, sizeof(line), file))
-			{
-				more_tags = FALSE;
-				break;
-			}
-			len = strlen(line);
-
-			if (last_newline && line[0] == '\n')
-			{
-				break;
-			}
-			else
-			{
-				last_newline = (line[len-1] == '\n');
-				writer->write_data(writer, chunk_create(line, len));
-			}
-		}
-
-		tag_encoding = writer->get_buf(writer);
-
-		if (tag_encoding.len > 1)
-		{
-			/* remove trailing newline if present */
-			if (tag_encoding.ptr[tag_encoding.len - 1] == '\n')
-			{
-				tag_encoding.len--;
-			}
-			DBG3(DBG_IMC, "  %.*s", tag_encoding.len, tag_encoding.ptr);
-
-			tag = swid_tag_create(tag_encoding, tag_file_path);
-			this->list->insert_last(this->list, tag);
-		}
-		writer->destroy(writer);
-	}
-
-	return SUCCESS;
-}
-
-/**
- * Read SWID tag or software IDs issued by the swid_generator tool
- */
-static status_t read_swid_tag_ids(private_swid_inventory_t *this, FILE *file)
-{
 	swid_tag_id_t *tag_id;
-	chunk_t tag_creator, unique_sw_id, tag_file_path = chunk_empty;
-	char line[BUF_LEN];
-
-	while (TRUE)
-	{
-		char *separator;
-		size_t len;
-
-		if (!fgets(line, sizeof(line), file))
-		{
-			return SUCCESS;
-		}
-		len = strlen(line);
-
-		/* remove trailing newline if present */
-		if (len > 0 && line[len - 1] == '\n')
-		{
-			len--;
-		}
-		DBG3(DBG_IMC, "  %.*s", len, line);
-
-		separator = strchr(line, '_');
-		if (!separator)
-		{
-			DBG1(DBG_IMC, "separation of regid from unique software ID failed");
-			return FAILED;
-		}
-		tag_creator = chunk_create(line, separator - line);
-		separator++;
-
-		unique_sw_id = chunk_create(separator, len - (separator - line));
-		tag_id = swid_tag_id_create(tag_creator, unique_sw_id, tag_file_path);
-		this->list->insert_last(this->list, tag_id);
-	}
-}
-
-static status_t generate_tags(private_swid_inventory_t *this, char *generator,
-							  swid_inventory_t *targets, bool pretty, bool full)
-{
-	FILE *file;
-	char command[BUF_LEN];
-	char doc_separator[] = "'\n\n'";
-
+	enumerator_t *enumerator;
 	status_t status = SUCCESS;
+	chunk_t out;
+
+	swid_gen = swid_gen_create();
 
 	if (targets->get_count(targets) == 0)
 	{
-		/* Assemble the SWID generator command */
-		if (this->full_tags)
-		{
-			snprintf(command, BUF_LEN, "%s swid --doc-separator %s%s%s",
-					 generator, doc_separator, pretty ? " --pretty" : "",
-											   full   ? " --full"   : "");
-		}
-		else
-		{
-			snprintf(command, BUF_LEN, "%s software-id", generator);
-		}
+		DBG2(DBG_IMC, "SWID tag%s generation by package manager",
+					   this->full_tags ? "" : " ID");
 
-		/* Open a pipe stream for reading the SWID generator output */
-		file = popen(command, "r");
-		if (!file)
+		enumerator = swid_gen->create_tag_enumerator(swid_gen, !this->full_tags,
+													 full, pretty);
+		if (enumerator)
 		{
-			DBG1(DBG_IMC, "failed to run swid_generator command");
-			return NOT_SUPPORTED;
-		}
+			while (enumerator->enumerate(enumerator, &out))
+			{
+				if (this->full_tags)
+				{
+					chunk_t swid_tag = out;
 
-		if (this->full_tags)
-		{
-			DBG2(DBG_IMC, "SWID tag generation by package manager");
-			status = read_swid_tags(this, file);
+					tag = swid_tag_create(swid_tag, chunk_empty);
+					this->list->insert_last(this->list, tag);
+				}
+				else
+				{
+					chunk_t tag_creator, sw_id = out;
+
+					if (extract_token_str(&tag_creator, "__", &sw_id))
+					{
+						tag_id = swid_tag_id_create(tag_creator, sw_id,
+													chunk_empty);
+						this->list->insert_last(this->list, tag_id);
+					}
+					else
+					{
+						DBG1(DBG_IMC, "separation of regid from unique "
+									  "software ID failed");
+						status = FAILED;
+						chunk_free(&out);
+						break;
+					}
+				}
+				chunk_free(&out);
+			}
+			enumerator->destroy(enumerator);
 		}
 		else
 		{
-			DBG2(DBG_IMC, "SWID tag ID generation by package manager");
-			status = read_swid_tag_ids(this, file);
+			status = NOT_SUPPORTED;
 		}
-		pclose(file);
 	}
 	else if (this->full_tags)
 	{
-		swid_tag_id_t *tag_id;
-		enumerator_t *enumerator;
+		DBG2(DBG_IMC, "targeted SWID tag generation");
 
 		enumerator = targets->create_enumerator(targets);
 		while (enumerator->enumerate(enumerator, &tag_id))
 		{
-			char software_id[BUF_LEN];
-			chunk_t tag_creator, unique_sw_id;
+			char software_id[BUF_LEN], *swid_tag;
+			chunk_t tag_creator, sw_id;
 
+			/* Construct software ID from tag creator and unique software ID */
 			tag_creator  = tag_id->get_tag_creator(tag_id);
-			unique_sw_id = tag_id->get_unique_sw_id(tag_id, NULL);
-			snprintf(software_id, BUF_LEN, "%.*s_%.*s",
-					 tag_creator.len, tag_creator.ptr,
-					 unique_sw_id.len, unique_sw_id.ptr);
-
-			/* Assemble the SWID generator command */
-			snprintf(command, BUF_LEN, "%s swid --software-id %s%s%s",
-					 generator, software_id, pretty ? " --pretty" : "",
-											 full   ? " --full"   : "");
-
-			/* Open a pipe stream for reading the SWID generator output */
-			file = popen(command, "r");
-			if (!file)
-			{
-				DBG1(DBG_IMC, "failed to run swid_generator command");
-				return NOT_SUPPORTED;
-			}
-			status = read_swid_tags(this, file);
-			pclose(file);
-
-			if (status != SUCCESS)
+			sw_id = tag_id->get_unique_sw_id(tag_id, NULL);
+			snprintf(software_id, BUF_LEN, "%.*s__%.*s",
+					 (int)tag_creator.len, tag_creator.ptr,
+					 (int)sw_id.len, sw_id.ptr);
+
+			swid_tag = swid_gen->generate_tag(swid_gen, software_id, NULL, NULL,
+										 full, pretty);
+			if (swid_tag)
 			{
-				break;
+				tag = swid_tag_create(chunk_from_str(swid_tag), chunk_empty);
+				this->list->insert_last(this->list, tag);
+				free(swid_tag);
 			}
 		}
 		enumerator->destroy(enumerator);
 	}
+	swid_gen->destroy(swid_gen);
 
 	return status;
 }
 
 static bool collect_tags(private_swid_inventory_t *this, char *pathname,
-						 swid_inventory_t *targets)
+						 swid_inventory_t *targets, bool is_swidtag_dir)
 {
 	char *rel_name, *abs_name;
 	struct stat st;
@@ -251,72 +159,49 @@ static bool collect_tags(private_swid_inventory_t *this, char *pathname,
 			 pathname, strerror(errno));
 		return FALSE;
 	}
-	DBG2(DBG_IMC, "entering %s", pathname);
+	if (is_swidtag_dir)
+	{
+			DBG2(DBG_IMC, "entering %s", pathname);
+	}
 
 	while (enumerator->enumerate(enumerator, &rel_name, &abs_name, &st))
 	{
-		char * start, *stop;
+		char *separator, *suffix;
 		chunk_t tag_creator;
 		chunk_t unique_sw_id = chunk_empty, tag_file_path = chunk_empty;
 
-		if (!strstr(rel_name, "regid."))
-		{
-			continue;
-		}
 		if (S_ISDIR(st.st_mode))
 		{
-			/* In case of a targeted request */
-			if (targets->get_count(targets))
-			{
-				enumerator_t *target_enumerator;
-				swid_tag_id_t *tag_id;
-				bool match = FALSE;
-
-				target_enumerator = targets->create_enumerator(targets);
-				while (target_enumerator->enumerate(target_enumerator, &tag_id))
-				{
-					if (chunk_equals(tag_id->get_tag_creator(tag_id),
-						chunk_from_str(rel_name)))
-					{
-						match = TRUE;
-						break;
-					}
-				}
-				target_enumerator->destroy(target_enumerator);
-
-				if (!match)
-				{
-					continue;
-				}
-			}
-
-			if (!collect_tags(this, abs_name, targets))
+			if (!collect_tags(this, abs_name, targets, is_swidtag_dir ||
+							  streq(rel_name, "swidtag")))
 			{
 				goto end;
 			}
 			continue;
 		}
+		if (!is_swidtag_dir)
+		{
+			continue;
+		}
 
-		/* parse the regid filename into its components */
-		start = rel_name;
-		stop = strchr(start, '_');
-		if (!stop)
+		/* found a swidtag file? */
+		suffix = strstr(rel_name, ".swidtag");
+		if (!suffix)
 		{
-			DBG1(DBG_IMC, "  %s", rel_name);
-			DBG1(DBG_IMC, "  '_' separator not found");
-			goto end;
+			continue;
 		}
-		tag_creator = chunk_create(start, stop-start);
-		start = stop + 1;
 
-		stop = strstr(start, ".swidtag");
-		if (!stop)
+		/* parse the swidtag filename into its components */
+		separator = strstr(rel_name, "__");
+		if (!separator)
 		{
 			DBG1(DBG_IMC, "  %s", rel_name);
-			DBG1(DBG_IMC, "  swidtag postfix not found");
+			DBG1(DBG_IMC, "  '__' separator not found");
 			goto end;
 		}
-		unique_sw_id = chunk_create(start, stop-start);
+		tag_creator = chunk_create(rel_name, separator-rel_name);
+
+		unique_sw_id = chunk_create(separator+2, suffix-separator-2);
 		tag_file_path = chunk_from_str(abs_name);
 
 		/* In case of a targeted request */
@@ -334,7 +219,7 @@ static bool collect_tags(private_swid_inventory_t *this, char *pathname,
 				target_tag_creator  = tag_id->get_tag_creator(tag_id);
 
 				if (chunk_equals(target_unique_sw_id, unique_sw_id) &&
-					chunk_equals(target_tag_creator, tag_creator))
+				    chunk_equals(target_tag_creator, tag_creator))
 				{
 					match = TRUE;
 					break;
@@ -358,7 +243,7 @@ static bool collect_tags(private_swid_inventory_t *this, char *pathname,
 			if (!xml_tag)
 			{
 				DBG1(DBG_IMC, "  opening '%s' failed: %s", abs_name,
-					 strerror(errno));
+				     strerror(errno));
 				goto end;
 			}
 
@@ -378,25 +263,28 @@ static bool collect_tags(private_swid_inventory_t *this, char *pathname,
 
 end:
 	enumerator->destroy(enumerator);
-	DBG2(DBG_IMC, "leaving %s", pathname);
+	if (is_swidtag_dir)
+	{
+		DBG2(DBG_IMC, "leaving %s", pathname);
+	}
 
 	return success;
 }
 
 METHOD(swid_inventory_t, collect, bool,
-	private_swid_inventory_t *this, char *directory, char *generator,
-	swid_inventory_t *targets, bool pretty, bool full)
+	private_swid_inventory_t *this, char *directory, swid_inventory_t *targets,
+	bool pretty, bool full)
 {
 	/**
 	 * Tags are generated by a package manager
 	 */
-	generate_tags(this, generator, targets, pretty, full);
+	generate_tags(this, targets, pretty, full);
 
 	/**
 	 * Collect swidtag files by iteratively entering all directories in
 	 * the tree under the "directory" path.
 	 */
-	return collect_tags(this, directory, targets);
+	return collect_tags(this, directory, targets, FALSE);
 }
 
 METHOD(swid_inventory_t, add, void,
diff --git a/src/libimcv/swid/swid_inventory.h b/src/libimcv/swid/swid_inventory.h
index 0402907..ba2518e 100644
--- a/src/libimcv/swid/swid_inventory.h
+++ b/src/libimcv/swid/swid_inventory.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2013-2014 Andreas Steffen
+ * Copyright (C) 2013-2017 Andreas Steffen
  * HSR Hochschule fuer Technik Rapperswil
  *
  * This program is free software; you can redistribute it and/or modify it
@@ -37,13 +37,12 @@ struct swid_inventory_t {
 	 * Collect the SWID tags stored on the endpoint
 	 *
 	 * @param directory		SWID directory path
-	 * @param generator		Path to SWID generator
 	 * @param targets		List of target tag IDs
 	 * @param pretty		Generate indented XML SWID tags
 	 * @param full			Include file information in SWID tags
 	 * @return				TRUE if successful
 	 */
-	bool (*collect)(swid_inventory_t *this, char *directory, char *generator,
+	bool (*collect)(swid_inventory_t *this, char *directory,
 					swid_inventory_t *targets, bool pretty, bool full);
 
 	/**
diff --git a/src/libimcv/swid_gen/swid_gen.c b/src/libimcv/swid_gen/swid_gen.c
new file mode 100644
index 0000000..206d41d
--- /dev/null
+++ b/src/libimcv/swid_gen/swid_gen.c
@@ -0,0 +1,291 @@
+/*
+ * Copyright (C) 2017 Andreas Steffen
+ * HSR Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * for more details.
+ */
+
+#define _GNU_SOURCE
+#include <stdio.h>
+
+#include "swid_gen.h"
+
+#include <bio/bio_writer.h>
+
+#define SWID_GENERATOR	"/usr/local/bin/swid_generator"
+
+typedef struct private_swid_gen_t private_swid_gen_t;
+
+/**
+ * Private data of a swid_gen_t object.
+ *
+ */
+struct private_swid_gen_t {
+
+	/**
+	 * Public swid_gen_t interface.
+	 */
+	swid_gen_t public;
+
+	/**
+	 * Path of the SWID generator command
+	 */
+	char *generator;
+
+	/**
+	 * Entity name of the tagCreator
+	 */
+	char *entity;
+
+	/**
+	 * Regid of the tagCreator
+	 */
+	char *regid;
+
+};
+
+METHOD(swid_gen_t, generate_tag, char*,
+	private_swid_gen_t *this, char *sw_id, char *package, char *version,
+	bool full, bool pretty)
+{
+	char *tag = NULL;
+	size_t tag_buf_len = 8192;
+	char tag_buf[tag_buf_len], command[BUF_LEN];
+	bio_writer_t *writer;
+	chunk_t swid_tag;
+	FILE *file;
+
+	/* Compose the SWID generator command */
+	if (full || !package || !version)
+	{ 
+		snprintf(command, BUF_LEN, "%s swid --entity-name \"%s\" "
+				 "--regid %s --software-id %s%s%s",
+				 this->generator, this->entity, this->regid, sw_id,
+				 full ? " --full" : "", pretty ? " --pretty" : "");
+	}
+	else
+	{ 
+		snprintf(command, BUF_LEN, "%s swid --entity-name \"%s\" "
+				 "--regid %s --name %s --version-string %s%s",
+				 this->generator, this->entity, this->regid, package,
+				 version, pretty ? " --pretty" : "");
+	}
+
+	/* Open a pipe stream for reading the SWID generator output */
+	file = popen(command, "r");
+	if (file)
+	{
+		writer = bio_writer_create(tag_buf_len);
+		while (TRUE)
+		{
+			if (!fgets(tag_buf, tag_buf_len, file))
+			{
+				break;
+			}
+			writer->write_data(writer, chunk_create(tag_buf, strlen(tag_buf)));
+		}
+		pclose(file);
+		swid_tag = writer->extract_buf(writer);
+		writer->destroy(writer);
+
+		if (swid_tag.len > 0)
+		{
+			tag = swid_tag.ptr;
+			tag[swid_tag.len - 1] = '\0';
+		}
+		else
+		{
+			chunk_free(&swid_tag);
+		}
+	}
+	else
+	{
+		DBG1(DBG_IMC, "failed to run swid_generator command");
+	}
+
+	return tag;
+}
+
+typedef struct {
+	/** public enumerator interface */
+	enumerator_t public;
+	/** swid_generator output stream */
+	FILE *file;
+	/** generate software identifier only */
+	bool sw_id_only;
+} swid_gen_enumerator_t;
+
+METHOD(enumerator_t, enumerate, bool,
+	swid_gen_enumerator_t *this, va_list args)
+{
+	chunk_t *out;
+
+	VA_ARGS_VGET(args, out);
+
+	if (this->sw_id_only)
+	{
+		char line[BUF_LEN];
+		size_t len;
+
+		if (!fgets(line, sizeof(line), this->file))
+		{
+			return FALSE;
+		}
+		len = strlen(line);
+
+		if (len == 0)
+		{
+			return FALSE;
+		}
+
+		/* remove trailing newline if present */
+		if (line[len - 1] == '\n')
+		{
+			len--;
+		}
+		DBG3(DBG_IMC, "  %.*s", len, line);
+		*out = chunk_clone(chunk_create(line, len));
+	}
+	else
+	{
+		bool last_newline = TRUE;
+		size_t len, line_len = 8192;
+		char line[line_len];
+		bio_writer_t *writer;
+		chunk_t swid_tag;
+
+		writer = bio_writer_create(line_len);
+		while (TRUE)
+		{
+			if (!fgets(line, line_len, this->file))
+			{
+				break;
+			}
+			len = strlen(line);
+
+			if (last_newline && line[0] == '\n')
+			{
+				break;
+			}
+			else
+			{
+				last_newline = (line[len-1] == '\n');
+				writer->write_data(writer, chunk_create(line, len));
+			}
+		}
+		swid_tag = writer->extract_buf(writer);
+		writer->destroy(writer);
+
+		if (swid_tag.len <= 1)
+		{
+			chunk_free(&swid_tag);
+			return FALSE;
+		}
+
+		/* remove trailing newline if present */
+		if (swid_tag.ptr[swid_tag.len - 1] == '\n')
+		{
+			swid_tag.len--;
+		}
+		DBG3(DBG_IMC, "  %.*s", swid_tag.len, swid_tag.ptr);
+		*out = swid_tag;
+	}
+
+	return TRUE;
+}
+
+METHOD(enumerator_t, enumerator_destroy, void,
+	swid_gen_enumerator_t *this)
+{
+	pclose(this->file);
+	free(this);
+}
+
+METHOD(swid_gen_t, create_tag_enumerator, enumerator_t*,
+	private_swid_gen_t *this, bool sw_id_only, bool full, bool pretty)
+{
+	swid_gen_enumerator_t *enumerator;
+	char command[BUF_LEN];
+	char doc_separator[] = "'\n\n'";
+	FILE *file;
+
+	/* Assemble the SWID generator command */
+	if (sw_id_only)
+	{
+		snprintf(command, BUF_LEN, "%s software-id --regid %s ",
+				 this->generator, this->regid);
+	}
+	else
+	{
+		snprintf(command, BUF_LEN, "%s swid --entity-name \"%s\" --regid %s "
+				 "--doc-separator %s%s%s", this->generator, this->entity,
+				 this->regid, doc_separator, pretty ? " --pretty" : "",
+											 full   ? " --full"   : "");
+	}
+
+	/* Open a pipe stream for reading the SWID generator output */
+	file = popen(command, "r");
+	if (!file)
+	{
+		DBG1(DBG_IMC, "failed to run swid_generator command");
+		return NULL;
+	}
+
+	INIT(enumerator,
+		.public = {
+			.enumerate = enumerator_enumerate_default,
+			.venumerate = _enumerate,
+			.destroy = _enumerator_destroy,
+		},
+		.sw_id_only = sw_id_only,
+		.file = file,
+	);
+
+	return &enumerator->public;
+}
+
+METHOD(swid_gen_t, destroy, void,
+	private_swid_gen_t *this)
+{
+	free(this->generator);
+	free(this->entity);
+	free(this->regid);
+	free(this);
+}
+
+/**
+ * See header
+ */
+swid_gen_t *swid_gen_create(void)
+{
+	private_swid_gen_t *this;
+	char *entity, *regid, *generator;
+
+	entity = lib->settings->get_str(lib->settings,
+				"libimcv.swid_gen.tag_creator.name", "strongSwan Project");
+	regid  = lib->settings->get_str(lib->settings,
+				"libimcv.swid_gen.tag_creator.regid", "strongswan.org");
+	generator = lib->settings->get_str(lib->settings,
+				"libimcv.swid_gen.command", SWID_GENERATOR);
+
+	INIT(this,
+		.public = {
+			.generate_tag = _generate_tag,
+			.create_tag_enumerator = _create_tag_enumerator,
+			.destroy = _destroy,
+		},
+		.generator = strdup(generator),
+		.entity = strdup(entity),
+		.regid = strdup(regid),
+	);
+
+	return &this->public;
+}
diff --git a/src/libimcv/swid_gen/swid_gen.h b/src/libimcv/swid_gen/swid_gen.h
new file mode 100644
index 0000000..c143f29
--- /dev/null
+++ b/src/libimcv/swid_gen/swid_gen.h
@@ -0,0 +1,69 @@
+/*
+ * Copyright (C) 2017 Andreas Steffen
+ * HSR Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT 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 swid_gen swid_gen
+ * @{ @ingroup libimcv
+ */
+
+#ifndef SWID_GEN_H_
+#define SWID_GEN_H_
+
+#include <library.h>
+
+typedef struct swid_gen_t swid_gen_t;
+
+/**
+ * Class generating a either a full or a minimalistic ISO 19770-2:2015 SWID tag
+ */
+struct swid_gen_t {
+
+	/**
+	 * Generate a SWID tag
+	 *
+	 * @param sw_id 		Software identifier
+	 * @param package		Package name (can be NULL)
+	 * @param version		Package version (can be NULL)
+	 * @param full			Generate full SWID tags with file information
+	 * @param pretty		Generate SWID tags with pretty formatting
+	 * @return				SWID tag
+	 */
+	char* (*generate_tag)(swid_gen_t *this, char *sw_id, char *package,
+						  char *version, bool full, bool pretty);
+
+	/**
+	 * Generate a SWID tag
+	 *
+	 * @param sw_id_only 	Return software identifier only
+	 * @param full			Generate full SWID tags with file information
+	 * @param pretty		Generate SWID tags with pretty formatting
+	 * @return				Tag enumerator (sw_id, tag)
+	 */
+	enumerator_t* (*create_tag_enumerator)(swid_gen_t *this, bool sw_id_only,
+										   bool full, bool pretty);
+
+	/**
+	 * Destroys a swid_gen_t object.
+	 */
+	void (*destroy)(swid_gen_t *this);
+
+};
+
+/**
+ * Creates a swid_gen_t object
+ */
+swid_gen_t* swid_gen_create(void);
+
+#endif /** SWID_GEN_H_ @}*/
diff --git a/src/libimcv/swid_gen/swid_gen_info.c b/src/libimcv/swid_gen/swid_gen_info.c
new file mode 100644
index 0000000..bdaeedc
--- /dev/null
+++ b/src/libimcv/swid_gen/swid_gen_info.c
@@ -0,0 +1,174 @@
+/*
+ * Copyright (C) 2017 Andreas Steffen
+ * HSR Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * for more details.
+ */
+
+#define _GNU_SOURCE
+#include <stdio.h>
+
+#include "swid_gen_info.h"
+
+#include <library.h>
+#include <utils/lexparser.h>
+
+typedef struct private_swid_gen_info_t private_swid_gen_info_t;
+
+/**
+ * Private data of an swid_gen_info_t object.
+ */
+struct private_swid_gen_info_t {
+
+	/**
+	 * Public members of swid_gen_info_state_t
+	 */
+	swid_gen_info_t public;
+
+	/**
+	 * tagCreator
+	 */
+	char *tag_creator;
+
+	/**
+	 * OS string 'Name_Version-Arch'
+	 */
+	char *os;
+
+	/**
+	 * Product string 'Name Version Arch'
+	 */
+	char *product;
+
+	/**
+	 * OS info about endpoint
+	 */
+	imc_os_info_t *os_info;
+
+};
+
+/**
+ * Replaces invalid character by a valid one
+ */
+static void sanitize_uri(char *uri, char a, char b)
+{
+	char *pos = uri;
+
+	while (TRUE)
+	{
+		pos = strchr(pos, a);
+		if (!pos)
+		{
+			break;
+		}
+		*pos = b;
+		pos++;
+	}
+}
+
+METHOD(swid_gen_info_t, get_os_type, os_type_t,
+	private_swid_gen_info_t *this)
+{
+	return this->os_info->get_type(this->os_info);
+}
+
+METHOD(swid_gen_info_t, get_os, char*,
+	private_swid_gen_info_t *this, char **product)
+{
+	if (product)
+	{
+		*product = this->product;
+	}
+	return this->os;
+}
+
+METHOD(swid_gen_info_t, create_sw_id, char*,
+	private_swid_gen_info_t *this, char *package, char *version)
+{
+	char *sw_id;
+
+	if (asprintf(&sw_id, "%s__%s-%s%s%s", this->tag_creator, this->os,
+				 package, strlen(version) ? "-" : "", version) == -1)
+	{
+		return NULL;
+	}
+	sanitize_uri(sw_id, ':', '~');
+	sanitize_uri(sw_id, '+', '~');
+
+	return sw_id;
+}
+
+METHOD(swid_gen_info_t, destroy, void,
+	private_swid_gen_info_t *this)
+{
+	this->os_info->destroy(this->os_info);
+	free(this->os);
+	free(this->product);
+	free(this->tag_creator);
+	free(this);
+}
+
+/**
+ * Described in header.
+ */
+swid_gen_info_t *swid_gen_info_create(void)
+{
+	private_swid_gen_info_t *this;
+	chunk_t os_name, os_version, os_arch;
+	char *tag_creator;
+
+	tag_creator = lib->settings->get_str(lib->settings,
+					"libimcv.swid_gen.tag_creator.regid", "strongswan.org");
+
+	INIT(this,
+		.public = {
+			.get_os_type = _get_os_type,
+			.get_os = _get_os,
+			.create_sw_id = _create_sw_id,
+			.destroy = _destroy,
+		},
+		.os_info = imc_os_info_create(),
+		.tag_creator = strdup(tag_creator),
+	);
+
+	os_name = this->os_info->get_name(this->os_info);
+	os_arch = this->os_info->get_version(this->os_info);
+
+	/* get_version() returns version followed by arch */
+	if (!extract_token(&os_version, ' ', &os_arch))
+	{
+		DBG1(DBG_IMC, "separation of OS version from arch failed");
+		destroy(this);
+		return NULL;
+	}
+
+	/* construct OS string */
+	if (asprintf(&this->os, "%.*s_%.*s-%.*s", (int)os_name.len, os_name.ptr,
+				 (int)os_version.len, os_version.ptr, (int)os_arch.len,
+				 os_arch.ptr) == -1)
+	{
+		DBG1(DBG_IMC, "constructon of OS string failed");
+		destroy(this);
+		return NULL;
+	}
+
+	/* construct product string */
+	if (asprintf(&this->product, "%.*s %.*s %.*s", (int)os_name.len,
+				 os_name.ptr, (int)os_version.len, os_version.ptr,
+				 (int)os_arch.len, os_arch.ptr) == -1)
+	{
+		DBG1(DBG_IMC, "constructon of product string failed");
+		destroy(this);
+		return NULL;
+	}
+
+	return &this->public;
+}
diff --git a/src/libimcv/swid_gen/swid_gen_info.h b/src/libimcv/swid_gen/swid_gen_info.h
new file mode 100644
index 0000000..b99fec4
--- /dev/null
+++ b/src/libimcv/swid_gen/swid_gen_info.h
@@ -0,0 +1,69 @@
+/*
+ * Copyright (C) 2017 Andreas Steffen
+ * HSR Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT 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 sw_collector sw-collector
+ *
+ * @defgroup swid_gen_info_t swid_gen_info
+ * @{ @ingroup sw_collector
+ */
+
+#ifndef SWID_GEN_INFO_H_
+#define SWID_GEN_INFO_H_
+
+typedef struct swid_gen_info_t swid_gen_info_t;
+
+#include "imc/imc_os_info.h"
+
+struct swid_gen_info_t {
+
+	/**
+	 * Get OS type
+	 *
+	 * @return				OS type
+	 */
+	os_type_t (*get_os_type)(swid_gen_info_t *this);
+
+	/**
+	 * Get OS and product strings
+	 *
+	 * @param product		Product string 'Name Version Arch'
+	 * @return				OS string      'Name_Version-Arch'
+	 */
+	char* (*get_os)(swid_gen_info_t *this, char **product);
+
+	/**
+	 * Create software identifier including tagCreator and OS
+	 *
+	 * @param package		Package string
+	 * @param version		Version string
+	 * @return				Software Identifier string
+	 */
+	char* (*create_sw_id)(swid_gen_info_t *this, char *package,
+												 char *version);
+
+	/**
+	 * Destroy swid_gen_info_t object
+	 */
+	void (*destroy)(swid_gen_info_t *this);
+
+};
+
+/**
+ * Create an swid_gen_info_t instance
+ */
+swid_gen_info_t* swid_gen_info_create(void);
+
+#endif /** SWID_GEN_INFO_H_ @}*/
diff --git a/src/libimcv/swima/swima_collector.c b/src/libimcv/swima/swima_collector.c
new file mode 100644
index 0000000..096093b
--- /dev/null
+++ b/src/libimcv/swima/swima_collector.c
@@ -0,0 +1,592 @@
+/*
+ * Copyright (C) 2017 Andreas Steffen
+ * HSR Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT 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 "swima_collector.h"
+
+#include <swid_gen/swid_gen.h>
+
+#include <collections/linked_list.h>
+#include <utils/debug.h>
+
+#include <stdio.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <sys/stat.h>
+#include <libgen.h>
+#include <errno.h>
+
+#define SOURCE_ID_GENERATOR		1
+#define SOURCE_ID_COLLECTOR		2
+
+#ifndef SWID_DIRECTORY
+#define SWID_DIRECTORY NULL
+#endif
+
+/**
+ * Directories to be skipped by collector
+ */
+static const char* skip_directories[] = {
+	"/usr/share/doc",
+	"/usr/share/help",
+	"/usr/share/icons",
+	"/usr/share/gnome/help"
+};
+
+typedef struct private_swima_collector_t private_swima_collector_t;
+
+/**
+ * Private data of a swima_collector_t object.
+ *
+ */
+struct private_swima_collector_t {
+
+	/**
+	 * Public swima_collector_t interface.
+	 */
+	swima_collector_t public;
+
+	/**
+	 * Collect Software Identifiers only
+	 */
+	bool sw_id_only;
+
+	/**
+	 * Software Collector Database [if it exists]
+	 */
+	database_t *db;
+
+	/**
+	 * List of Software [Identifier] records
+	 */
+	swima_inventory_t *inventory;
+
+	/**
+	 * List of Software [Identifier] events
+	 */
+	swima_events_t *events;
+
+};
+
+/**
+ * Extract Software Identifier from SWID tag
+ */
+static status_t extract_sw_id(chunk_t swid_tag, chunk_t *sw_id)
+{
+	char *pos, *tag, *tagid, *regid;
+	size_t len, tagid_len, regid_len;
+	status_t status = NOT_FOUND;
+
+	/* Copy at most 1023 bytes of the SWID tag and null-terminate it */
+	len = min(1023, swid_tag.len);
+	pos = tag = strndup(swid_tag.ptr, len);
+
+	tagid= strstr(pos, "tagId=\"");
+	if (tagid == NULL)
+	{
+		goto end;
+	}
+	tagid += 7;
+	len -= tagid - pos - 7;
+
+	pos = strchr(tagid, '"');
+	if (pos == NULL)
+	{
+		goto end;
+	}
+	tagid_len = pos - tagid;
+
+	regid= strstr(pos, "regid=\"");
+	if (regid == NULL)
+	{
+		goto end;
+	}
+	regid += 7;
+	len -= regid - pos - 7;
+
+	pos = strchr(regid, '"');
+	if (pos == NULL)
+	{
+		goto end;
+	}
+	regid_len = pos - regid;
+
+	*sw_id = chunk_cat("ccc", chunk_create(regid, regid_len),
+							  chunk_from_chars('_','_'),
+							  chunk_create(tagid, tagid_len));
+	status = SUCCESS;
+end:
+	free(tag);
+
+	return status;
+}
+
+static status_t retrieve_inventory(private_swima_collector_t *this,
+								   swima_inventory_t *targets)
+{
+	char *name;
+	uint32_t record_id, source;
+	swima_record_t *sw_record;
+	chunk_t sw_id;
+	enumerator_t *e;
+
+	/* Retrieve complete software identifier inventory */
+	e = this->db->query(this->db,
+			"SELECT id, name, source FROM sw_identifiers WHERE installed = 1 "
+			"ORDER BY name ASC", DB_UINT, DB_TEXT, DB_UINT);
+	if (!e)
+	{
+		DBG1(DBG_IMC, "database query for installed sw_identifiers failed");
+		return FAILED;
+	}
+	while (e->enumerate(e, &record_id, &name, &source))
+	{
+		sw_id = chunk_from_str(name);
+		sw_record = swima_record_create(record_id, sw_id, chunk_empty);
+		sw_record->set_source_id(sw_record, source);
+		this->inventory->add(this->inventory, sw_record);
+	}
+	e->destroy(e);
+
+	return SUCCESS;
+}
+
+static status_t retrieve_events(private_swima_collector_t *this,
+							  	swima_inventory_t *targets)
+{
+	enumerator_t *e;
+	char *name, *timestamp;
+	uint32_t record_id, source, action, eid, earliest_eid;
+	chunk_t sw_id, ev_ts;
+	swima_record_t *sw_record;
+	swima_event_t *sw_event;
+
+	earliest_eid = targets->get_eid(targets, NULL);
+
+	/* Retrieve complete software identifier inventory */
+	e = this->db->query(this->db,
+		"SELECT e.id, e.timestamp, i.id, i.name, i.source, s.action "
+		"FROM sw_events as s JOIN events AS e ON s.eid = e.id "
+		"JOIN sw_identifiers as i ON s.sw_id = i.id WHERE s.eid >= ?"
+		"ORDER BY s.eid, i.name, s.action ASC", DB_UINT, earliest_eid,
+		 DB_UINT, DB_TEXT, DB_UINT, DB_TEXT, DB_UINT, DB_UINT);
+	if (!e)
+	{
+		DBG1(DBG_IMC, "database query for sw_events failed");
+		return FAILED;
+	}
+	while (e->enumerate(e, &eid, &timestamp, &record_id, &name, &source, &action))
+	{
+		sw_id = chunk_from_str(name);
+		ev_ts = chunk_from_str(timestamp);
+		sw_record = swima_record_create(record_id, sw_id, chunk_empty);
+		sw_record->set_source_id(sw_record, source);
+		sw_event = swima_event_create(eid, ev_ts, action, sw_record);
+		this->events->add(this->events, sw_event);
+	}
+	e->destroy(e);
+
+	return SUCCESS;
+}
+
+static status_t generate_tags(private_swima_collector_t *this,
+							  swima_inventory_t *targets, bool pretty, bool full)
+{
+	swid_gen_t *swid_gen;
+	swima_record_t *target, *sw_record;
+	enumerator_t *enumerator;
+	status_t status = SUCCESS;
+
+	swid_gen = swid_gen_create();
+
+	if (targets->get_count(targets) == 0)
+	{
+		chunk_t out, sw_id, swid_tag = chunk_empty;
+
+		DBG2(DBG_IMC, "SWID tag%s generation by package manager",
+					   this->sw_id_only ? " ID" : "");
+
+		enumerator = swid_gen->create_tag_enumerator(swid_gen, this->sw_id_only,
+													 full, pretty);
+		if (enumerator)
+		{
+			while (enumerator->enumerate(enumerator, &out))
+			{
+				if (this->sw_id_only)
+				{
+					sw_id = out;
+				}
+				else
+				{
+					swid_tag = out;
+					status = extract_sw_id(swid_tag, &sw_id);
+					if (status != SUCCESS)
+					{
+						DBG1(DBG_IMC, "software id could not be extracted "
+									  "from tag");
+						chunk_free(&swid_tag);
+						break;
+					}
+				}
+				sw_record = swima_record_create(0, sw_id, chunk_empty);
+				sw_record->set_source_id(sw_record, SOURCE_ID_GENERATOR);
+				if (!this->sw_id_only)
+				{
+					sw_record->set_record(sw_record, swid_tag);
+					chunk_free(&swid_tag);
+				}
+				this->inventory->add(this->inventory, sw_record);
+				chunk_free(&sw_id);
+			}
+			enumerator->destroy(enumerator);
+		}
+		else
+		{
+			status = NOT_SUPPORTED;
+		}
+	}
+	else if (!this->sw_id_only)
+	{
+		DBG2(DBG_IMC, "targeted SWID tag generation");
+
+		enumerator = targets->create_enumerator(targets);
+		while (enumerator->enumerate(enumerator, &target))
+		{
+			swima_record_t *sw_record;
+			char *tag = NULL, *name, *package, *version;
+			u_int installed;
+			chunk_t sw_id;
+			enumerator_t *e;
+
+			sw_id = target->get_sw_id(target, NULL);
+			name = strndup(sw_id.ptr, sw_id.len);
+
+			if (this->db)
+			{
+				e = this->db->query(this->db,
+						"SELECT package, version, installed "
+						"FROM sw_identifiers WHERE name = ?", DB_TEXT, name,
+						 DB_TEXT, DB_TEXT, DB_UINT);
+				if (!e)
+				{
+					DBG1(DBG_IMC, "database query for sw_identifiers failed");
+					status = FAILED;
+					free(name);
+					break;
+				}
+				if (e->enumerate(e, &package, &version, &installed))
+				{
+					tag = swid_gen->generate_tag(swid_gen, name, package,
+									version, full && installed, pretty);
+				}
+				e->destroy(e);
+			}
+			else
+			{
+				tag = swid_gen->generate_tag(swid_gen, name, NULL, NULL,
+											 full, pretty);
+			}
+			free(name);
+
+			if (tag)
+			{
+				DBG2(DBG_IMC, "  %.*s", sw_id.len, sw_id.ptr);
+				sw_record = swima_record_create(0, sw_id, chunk_empty);
+				sw_record->set_source_id(sw_record, SOURCE_ID_GENERATOR);
+				sw_record->set_record(sw_record, chunk_from_str(tag));
+				this->inventory->add(this->inventory, sw_record);
+				free(tag);
+			}
+		}
+		enumerator->destroy(enumerator);
+	}
+	swid_gen->destroy(swid_gen);
+
+	return status;
+}
+
+static bool collect_tags(private_swima_collector_t *this, char *pathname,
+						 swima_inventory_t *targets, bool is_swidtag_dir)
+{
+	char *rel_name, *abs_name, *suffix, *pos;
+	chunk_t *swid_tag, sw_id, sw_locator;
+	swima_record_t *sw_record;
+	struct stat st;
+	bool success = FALSE, skip, is_new_swidtag_dir;
+	enumerator_t *enumerator;
+	int i;
+
+	if (!pathname)
+	{
+		return TRUE;
+	}
+
+	enumerator = enumerator_create_directory(pathname);
+	if (!enumerator)
+	{
+		DBG1(DBG_IMC, "directory '%s' can not be opened, %s",
+					   pathname, strerror(errno));
+		return FALSE;
+	}
+
+	while (enumerator->enumerate(enumerator, &rel_name, &abs_name, &st))
+	{
+		if (S_ISDIR(st.st_mode))
+		{
+			skip = FALSE;
+
+			for (i = 0; i < countof(skip_directories); i++)
+			{
+				if (streq(abs_name, skip_directories[i]))
+				{
+					skip = TRUE;
+					break;
+				}
+			}
+
+			if (skip)
+			{
+				continue;
+			}
+
+			is_new_swidtag_dir =  streq(rel_name, "swidtag");
+			if (is_new_swidtag_dir)
+			{
+				DBG2(DBG_IMC, "entering %s", pathname);
+			}
+			if (!collect_tags(this, abs_name, targets, is_swidtag_dir ||
+													   is_new_swidtag_dir))
+			{
+				goto end;
+			}
+			if (is_new_swidtag_dir)
+			{
+				DBG2(DBG_IMC, "leaving %s", pathname);
+			}
+		}
+
+		if (!is_swidtag_dir)
+		{
+			continue;
+		}
+
+		/* found a swidtag file? */
+		suffix = strstr(rel_name, ".swidtag");
+		if (!suffix)
+		{
+			continue;
+		}
+
+		/* load the swidtag file */
+		swid_tag = chunk_map(abs_name, FALSE);
+		if (!swid_tag)
+		{
+			DBG1(DBG_IMC, "  opening '%s' failed: %s", abs_name,
+						  strerror(errno));
+			goto end;
+		}
+
+		/* extract software identity from SWID tag */
+		if (extract_sw_id(*swid_tag, &sw_id) != SUCCESS)
+		{
+			DBG1(DBG_IMC, "software id could not be extracted from SWID tag");
+			chunk_unmap(swid_tag);
+			goto end;
+		}
+
+		/* In case of a targeted request */
+		if (targets->get_count(targets))
+		{
+			enumerator_t *target_enumerator;
+			swima_record_t *target;
+			bool match = FALSE;
+
+			target_enumerator = targets->create_enumerator(targets);
+			while (target_enumerator->enumerate(target_enumerator, &target))
+			{
+				if (chunk_equals(target->get_sw_id(target, NULL), sw_id))
+				{
+					DBG2(DBG_IMC, "  %.*s", sw_id.len, sw_id.ptr);
+					match = TRUE;
+					break;
+				}
+			}
+			target_enumerator->destroy(target_enumerator);
+
+			if (!match)
+			{
+				chunk_unmap(swid_tag);
+				chunk_free(&sw_id);
+				continue;
+			}
+		}
+		DBG2(DBG_IMC, "  %s", rel_name);
+
+		pos = strstr(pathname, "/swidtag");
+		sw_locator = pos ? chunk_create(pathname, pos - pathname) : chunk_empty;
+		sw_record = swima_record_create(0, sw_id, sw_locator);
+		sw_record->set_source_id(sw_record, SOURCE_ID_COLLECTOR);
+		if (!this->sw_id_only)
+		{
+			sw_record->set_record(sw_record, *swid_tag);
+		}
+		this->inventory->add(this->inventory, sw_record);
+		chunk_unmap(swid_tag);
+		chunk_free(&sw_id);
+	}
+	success = TRUE;
+
+end:
+	enumerator->destroy(enumerator);
+
+	return success;
+}
+
+METHOD(swima_collector_t, collect_inventory, swima_inventory_t*,
+	private_swima_collector_t *this, bool sw_id_only, swima_inventory_t *targets)
+{
+	bool pretty, full;
+	char *directory;
+	status_t status;
+
+	directory = lib->settings->get_str(lib->settings,
+									"%s.plugins.imc-swima.swid_directory",
+									 SWID_DIRECTORY, lib->ns);
+	pretty = lib->settings->get_bool(lib->settings,
+									"%s.plugins.imc-swima.swid_pretty",
+									 FALSE, lib->ns);
+	full = lib->settings->get_bool(lib->settings,
+									"%s.plugins.imc-swima.swid_full",
+									 FALSE, lib->ns);
+
+	/**
+	 * Re-initialize collector
+	 */
+	this->sw_id_only = sw_id_only;
+	this->inventory->clear(this->inventory);
+
+	/**
+	 * Source 1: Tags are generated by a package manager
+	 */
+	if (sw_id_only && this->db)
+	{
+		status = retrieve_inventory(this, targets);
+	}
+	else
+	{
+		status = generate_tags(this, targets, pretty, full);
+	}
+
+	/**
+	 * Source 2: Collect swidtag files by iteratively entering all
+	 *           directories in the tree under the "directory" path.
+	 */
+	DBG2(DBG_IMC, "SWID tag%s collection", sw_id_only ? " ID" : "");
+	collect_tags(this, directory, targets, FALSE);
+
+	return status == SUCCESS ? this->inventory : NULL;
+}
+
+METHOD(swima_collector_t, collect_events, swima_events_t*,
+	private_swima_collector_t *this, bool sw_id_only, swima_inventory_t *targets)
+{
+	if (!sw_id_only || !this->db)
+	{
+		return NULL;
+	}
+
+	/**
+	 * Re-initialize collector
+	 */
+	this->sw_id_only = sw_id_only;
+	this->events->clear(this->events);
+
+	return retrieve_events(this, targets) == SUCCESS ? this->events : NULL;
+}
+
+METHOD(swima_collector_t, destroy, void,
+	private_swima_collector_t *this)
+{
+	DESTROY_IF(this->db);
+	this->inventory->destroy(this->inventory);
+	this->events->destroy(this->events);
+	free(this);
+}
+
+/**
+ * See header
+ */
+swima_collector_t *swima_collector_create(void)
+{
+	private_swima_collector_t *this;
+	char *database;
+	uint32_t last_eid = 1, eid_epoch = 0x11223344;
+
+	INIT(this,
+		.public = {
+			.collect_inventory = _collect_inventory,
+			.collect_events = _collect_events,
+			.destroy = _destroy,
+		},
+		.inventory = swima_inventory_create(),
+		.events = swima_events_create(),
+	);
+
+	database = lib->settings->get_str(lib->settings,
+					"%s.plugins.imc-swima.swid_database", NULL, lib->ns);
+
+	/* If we have an URI, try to connect to sw_collector database */
+	if (database)
+	{
+		database_t *db = lib->db->create(lib->db, database);
+
+		if (db)
+		{
+			enumerator_t *e;
+
+			/* Get last event ID and corresponding epoch */
+			e = db->query(db,
+					"SELECT id, epoch FROM events ORDER BY timestamp DESC",
+					 DB_UINT, DB_UINT);
+			if (!e || !e->enumerate(e, &last_eid, &eid_epoch))
+			{
+				DBG1(DBG_IMC, "database query for last event failed");
+				DESTROY_IF(e);
+				db->destroy(db);
+			}
+			else
+			{
+				/* The query worked, attach collector database permanently */
+				e->destroy(e);
+				this->db = db;
+			}
+		}
+		else
+		{
+			DBG1(DBG_IMC, "opening sw-collector database URI '%s' failed",
+						   database);
+		}
+	}
+	if (!this->db)
+	{
+		/* Set the event ID epoch and last event ID smanually */
+		eid_epoch = lib->settings->get_int(lib->settings,
+								"%s.plugins.imc-swima.eid_epoch",
+								 eid_epoch, lib->ns);
+	}
+	this->inventory->set_eid(this->inventory, last_eid, eid_epoch);
+	this->events->set_eid(this->events, last_eid, eid_epoch);
+
+	return &this->public;
+}
diff --git a/src/libimcv/swima/swima_collector.h b/src/libimcv/swima/swima_collector.h
new file mode 100644
index 0000000..848dc16
--- /dev/null
+++ b/src/libimcv/swima/swima_collector.h
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 2017 Andreas Steffen
+ * HSR Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT 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 swima_collector swima_collector
+ * @{ @ingroup libimcv_swima
+ */
+
+#ifndef SWIMA_COLLECTOR_H_
+#define SWIMA_COLLECTOR_H_
+
+#include "swima/swima_inventory.h"
+#include "swima/swima_events.h"
+
+typedef struct swima_collector_t swima_collector_t;
+
+/**
+ * Class collecting Software [Identity] Inventory
+ */
+struct swima_collector_t {
+
+	/**
+	 * Collect the Software [Identity] Inventory
+	 *
+	 * @param sw_id_only	TRUE to request Software Identity Inventory only
+	 * @param targets		Software Identity targets
+	 * @return				Software [Identity] Inventory
+	 */
+	swima_inventory_t* (*collect_inventory)(swima_collector_t *this,
+											bool sw_id_only, 
+											swima_inventory_t *targets);
+
+	/**
+	 * Collect Software [Identity] Events
+	 *
+	 * @param sw_id_only	TRUE to request Software Identity Inventory only
+	 * @param targets		Software Identity targets
+	 * @return				Software [Identity] Events
+	 */
+	swima_events_t* (*collect_events)(swima_collector_t *this,
+									  bool sw_id_only,
+									  swima_inventory_t *targets);
+
+	/**
+	 * Destroys a swima_collector_t object.
+	 */
+	void (*destroy)(swima_collector_t *this);
+
+};
+
+/**
+ * Creates a swima_collector_t object
+ */
+swima_collector_t* swima_collector_create(void);
+
+#endif /** SWIMA_COLLECTOR_H_ @}*/
diff --git a/src/libimcv/imcv_tests.h b/src/libimcv/swima/swima_data_model.c
similarity index 56%
copy from src/libimcv/imcv_tests.h
copy to src/libimcv/swima/swima_data_model.c
index d3ea24b..f444724 100644
--- a/src/libimcv/imcv_tests.h
+++ b/src/libimcv/swima/swima_data_model.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2014 Andreas Steffen
+ * Copyright (C) 2017 Andreas Steffen
  * HSR Hochschule fuer Technik Rapperswil
  *
  * This program is free software; you can redistribute it and/or modify it
@@ -13,5 +13,16 @@
  * for more details.
  */
 
-TEST_SUITE(imcv_seg_suite_create)
+#include "swima/swima_data_model.h"
 
+/**
+ * ISO/IEC 19770-2-2015: Information Technology - Software Asset Management -
+ * Part 2: Software Identification Tag
+ */
+pen_type_t swima_data_model_iso_2015_swid_xml = { PEN_IETF, 1 };
+
+/**
+ * ISO/IEC 19770-2-2009: Information Technology - Software Asset Management -
+ * Part 2: Software Identification Tag
+ */
+pen_type_t swima_data_model_iso_2009_swid_xml = { PEN_IETF, 2 };
diff --git a/src/libimcv/imcv_tests.h b/src/libimcv/swima/swima_data_model.h
similarity index 50%
copy from src/libimcv/imcv_tests.h
copy to src/libimcv/swima/swima_data_model.h
index d3ea24b..40f0ba7 100644
--- a/src/libimcv/imcv_tests.h
+++ b/src/libimcv/swima/swima_data_model.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2014 Andreas Steffen
+ * Copyright (C) 2017 Andreas Steffen
  * HSR Hochschule fuer Technik Rapperswil
  *
  * This program is free software; you can redistribute it and/or modify it
@@ -13,5 +13,26 @@
  * for more details.
  */
 
-TEST_SUITE(imcv_seg_suite_create)
+/**
+ * @defgroup swima_data_model swima_data_model
+ * @{ @ingroup libimcv_swima
+ */
+
+#ifndef SWIMA_DATA_MODEL_H_
+#define SWIMA_DATA_MODEL_H_
+
+#include <pen/pen.h>
+
+/**
+ * ISO/IEC 19770-2-2015: Information Technology - Software Asset Management -
+ * Part 2: Software Identification Tag
+ */
+extern pen_type_t swima_data_model_iso_2015_swid_xml;
+
+/**
+ * ISO/IEC 19770-2-2009: Information Technology - Software Asset Management -
+ * Part 2: Software Identification Tag
+ */
+extern pen_type_t swima_data_model_iso_2009_swid_xml;
 
+#endif /** SWIMA_DATA_MODEL_H_ @}*/
diff --git a/src/libimcv/swima/swima_error.c b/src/libimcv/swima/swima_error.c
new file mode 100644
index 0000000..2aed296
--- /dev/null
+++ b/src/libimcv/swima/swima_error.c
@@ -0,0 +1,77 @@
+/*
+ * Copyright (C) 2017 Andreas Steffen
+ * HSR Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT 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 "swima_error.h"
+
+#include <bio/bio_writer.h>
+#include <ietf/ietf_attr_pa_tnc_error.h>
+
+/**
+ * SW_ERROR, SW_SUBSCRIPTION_DENIED_ERROR and SW_SUBSCRIPTION_ID_REUSE_ERROR
+ *
+ *                       1                   2                   3
+ *   0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+ *  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ *  |            Copy of Request ID / Subscription ID               |
+ *  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ *  |                Description (variable length)                  |
+ *  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ */
+
+/**
+ * SW_RESPONSE_TOO_LARGE_ERROR 
+ *
+ *                       1                   2                   3
+ *   0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+ *  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ *  |            Copy of Request ID / Subscription ID               |
+ *  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ *  |                    Maximum Allowed Size                       |
+ *  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ *  |                Description (variable length)                  |
+ *  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ */
+
+/**
+ * Described in header.
+ */
+pa_tnc_attr_t* swima_error_create(pa_tnc_error_code_t code, uint32_t request_id,
+								  uint32_t max_attr_size, char *description)
+{
+	bio_writer_t *writer;
+	chunk_t msg_info;
+	pa_tnc_attr_t *attr;
+	pen_type_t error_code;
+
+	error_code = pen_type_create( PEN_IETF, code);
+	writer = bio_writer_create(4);
+	writer->write_uint32(writer, request_id);
+
+	if (code == PA_ERROR_SW_RESPONSE_TOO_LARGE)
+	{
+		writer->write_uint32(writer, max_attr_size);
+	}
+
+	if (description)
+	{
+		writer->write_data(writer, chunk_from_str(description));
+	}
+	msg_info = writer->get_buf(writer);
+	attr = ietf_attr_pa_tnc_error_create(error_code, msg_info);
+	writer->destroy(writer);
+
+	return attr;
+}
+
diff --git a/src/libimcv/swima/swima_error.h b/src/libimcv/swima/swima_error.h
new file mode 100644
index 0000000..4073b07
--- /dev/null
+++ b/src/libimcv/swima/swima_error.h
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2017 Andreas Steffen
+ * HSR Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT 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 swima_error swima_error
+ * @{ @ingroup libimcv_swima
+ */
+
+#ifndef SWIMA_ERROR_H_
+#define SWIMA_ERROR_H_
+
+typedef enum swima_error_code_t swima_error_code_t;
+
+#include "pa_tnc/pa_tnc_attr.h"
+#include "ietf/ietf_attr_pa_tnc_error.h"
+
+#include <library.h>
+
+/**
+ * Creates a SWIMA Error Attribute
+ * see section 5.16 of IETF SW Inventory Message and Attributes for PA-TNC
+ *
+ * @param code				PA-TNC error code
+ * @param request			SWID request ID
+ * @param max_attr_size		Maximum PA-TNC attribute size (if applicable)
+ * @param description		Optional description string or NULL
+ */
+pa_tnc_attr_t* swima_error_create(pa_tnc_error_code_t code, uint32_t request,
+								  uint32_t max_attr_size, char *description);
+
+#endif /** SWIMA_ERROR_H_ @}*/
diff --git a/src/libimcv/swima/swima_event.c b/src/libimcv/swima/swima_event.c
new file mode 100644
index 0000000..20cfa8d
--- /dev/null
+++ b/src/libimcv/swima/swima_event.c
@@ -0,0 +1,124 @@
+/*
+ * Copyright (C) 2017 Andreas Steffen
+ * HSR Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT 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 "swima_event.h"
+#include "swima_data_model.h"
+
+typedef struct private_swima_event_t private_swima_event_t;
+
+/**
+ * Private data of a swima_event_t object.
+ *
+ */
+struct private_swima_event_t {
+
+	/**
+	 * Public swima_event_t interface.
+	 */
+	swima_event_t public;
+
+	/**
+	 * Event ID
+	 */
+	uint32_t eid;
+
+	/**
+	 * Timestamp
+	 */
+	chunk_t timestamp;
+
+	/**
+	 * Action
+	 */
+	uint8_t action;
+
+	/**
+	 * Software [Identifier] record
+	 */
+	swima_record_t *sw_record;
+
+	/**
+	 * Reference count
+	 */
+	refcount_t ref;
+};
+
+METHOD(swima_event_t, get_eid, uint32_t,
+	private_swima_event_t *this, chunk_t *timestamp)
+{
+	if (timestamp)
+	{
+		*timestamp = this->timestamp;
+	}
+	return this->eid;
+}
+
+METHOD(swima_event_t, get_action, uint8_t,
+	private_swima_event_t *this)
+{
+	return this->action;
+}
+
+METHOD(swima_event_t, get_sw_record, swima_record_t*,
+	private_swima_event_t *this)
+{
+	return this->sw_record;
+}
+
+
+METHOD(swima_event_t, get_ref, swima_event_t*,
+	private_swima_event_t *this)
+{
+	ref_get(&this->ref);
+	return &this->public;
+}
+
+METHOD(swima_event_t, destroy, void,
+	private_swima_event_t *this)
+{
+	if (ref_put(&this->ref))
+	{
+		this->sw_record->destroy(this->sw_record);
+		free(this->timestamp.ptr);
+		free(this);
+	}
+}
+
+/**
+ * See header
+ */
+swima_event_t *swima_event_create(uint32_t eid, chunk_t timestamp,
+								  uint8_t action, swima_record_t *sw_record)
+{
+	private_swima_event_t *this;
+
+	INIT(this,
+		.public = {
+			.get_eid = _get_eid,
+			.get_action = _get_action,
+			.get_sw_record = _get_sw_record,
+			.get_ref = _get_ref,
+			.destroy = _destroy,
+		},
+		.eid = eid,
+		.timestamp = chunk_clone(timestamp),
+		.action = action,
+		.sw_record = sw_record,
+		.ref = 1,
+	);
+
+	return &this->public;
+}
+
diff --git a/src/libimcv/swima/swima_event.h b/src/libimcv/swima/swima_event.h
new file mode 100644
index 0000000..fe69d6a
--- /dev/null
+++ b/src/libimcv/swima/swima_event.h
@@ -0,0 +1,87 @@
+/*
+ * Copyright (C) 2017 Andreas Steffen
+ * HSR Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT 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 swima_event swima_event
+ * @{ @ingroup libimcv_swima
+ */
+
+#ifndef SWIMA_EVENT_H_
+#define SWIMA_EVENT_H_
+
+#include "swima_record.h"
+
+#include <library.h>
+
+#define SWIMA_EVENT_ACTION_CREATION		1
+#define SWIMA_EVENT_ACTION_DELETION		2
+#define SWIMA_EVENT_ACTION_ALTERATION	3
+#define SWIMA_EVENT_ACTION_LAST			3
+
+typedef struct swima_event_t swima_event_t;
+
+/**
+ * Class storing a Software [Identifier] event
+ */
+struct swima_event_t {
+
+	/**
+	 * Get Event ID and optionally the associated timestamp
+	 *
+	 * @param timestamp		Timestamp associated with Event
+	 * @return				Event ID
+	 */
+	uint32_t (*get_eid)(swima_event_t *this, chunk_t *timestamp);
+
+	/**
+	 * Get Action associated with Event
+	 *
+	 * @return				Action associated with event
+	 */
+	uint8_t (*get_action)(swima_event_t *this);
+
+	/**
+	 * Get Software [Identifier] record
+	 *
+	 * @return				Software [Identifier] record
+	 */
+	swima_record_t* (*get_sw_record)(swima_event_t *this);
+
+	/**
+	 * Get a new reference to a swima_event object
+	 *
+	 * @return			this, with an increased refcount
+	 */
+	swima_event_t* (*get_ref)(swima_event_t *this);
+
+	/**
+	 * Destroys a swima_event_t object.
+	 */
+	void (*destroy)(swima_event_t *this);
+
+};
+
+/**
+ * Creates a swima_event_t object
+ *
+ * @param eid				Event ID
+ * @param timestamp			Time of Event
+ * @param action			Action (CREATION, DELETION, ALTERATION)
+ * @param sw_record			Software [Identifier] record
+ */
+swima_event_t* swima_event_create(uint32_t eid, chunk_t timestamp,
+								  uint8_t action, swima_record_t *sw_record);
+
+#endif /** SWIMA_EVENT_H_ @}*/
diff --git a/src/libimcv/swima/swima_events.c b/src/libimcv/swima/swima_events.c
new file mode 100644
index 0000000..ba0810d
--- /dev/null
+++ b/src/libimcv/swima/swima_events.c
@@ -0,0 +1,155 @@
+/*
+ * Copyright (C) 2017 Andreas Steffen
+ * HSR Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT 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 "swima_events.h"
+#include "swima_record.h"
+
+#include <collections/linked_list.h>
+#include <utils/debug.h>
+
+typedef struct private_swima_events_t private_swima_events_t;
+
+/**
+ * Private data of a swima_events_t object.
+ *
+ */
+struct private_swima_events_t {
+
+	/**
+	 * Public swima_events_t interface.
+	 */
+	swima_events_t public;
+
+	/**
+	 * Epoch of Event IDs
+	 */
+	uint32_t epoch;
+
+	/**
+	 * Last Event ID
+	 */
+	uint32_t last_eid;
+
+	/**
+	 * Last Consulted Event ID
+	 */
+	uint32_t last_consulted_eid;
+
+	/**
+	 * List of SW records
+	 */
+	linked_list_t *list;
+
+	/**
+	 * Reference count
+	 */
+	refcount_t ref;
+
+};
+
+METHOD(swima_events_t, add, void,
+	private_swima_events_t *this, swima_event_t *event)
+{
+	this->list->insert_last(this->list, event);
+}
+
+METHOD(swima_events_t, get_count, int,
+	private_swima_events_t *this)
+{
+	return this->list->get_count(this->list);
+}
+
+METHOD(swima_events_t, set_eid, void,
+	private_swima_events_t *this, uint32_t eid, uint32_t epoch)
+{
+	this->last_eid = this->last_consulted_eid = eid;
+	this->epoch = epoch;
+}
+
+METHOD(swima_events_t, set_last_eid, void,
+	private_swima_events_t *this, uint32_t last_eid)
+{
+	this->last_eid = last_eid;
+}
+
+METHOD(swima_events_t, get_eid, uint32_t,
+	private_swima_events_t *this, uint32_t *epoch, uint32_t *last_eid)
+{
+	if (epoch)
+	{
+		*epoch = this->epoch;
+	}
+	if (last_eid)
+	{
+		*last_eid = this->last_eid;
+	}
+	return this->last_consulted_eid;
+}
+
+METHOD(swima_events_t, create_enumerator, enumerator_t*,
+	private_swima_events_t *this)
+{
+	return this->list->create_enumerator(this->list);
+}
+
+METHOD(swima_events_t, get_ref, swima_events_t*,
+	private_swima_events_t *this)
+{
+	ref_get(&this->ref);
+	return &this->public;
+}
+
+METHOD(swima_events_t, clear, void,
+	private_swima_events_t *this)
+{
+	this->list->destroy_offset(this->list, offsetof(swima_event_t, destroy));
+	this->list = linked_list_create();
+}
+
+METHOD(swima_events_t, destroy, void,
+	private_swima_events_t *this)
+{
+	if (ref_put(&this->ref))
+	{
+		this->list->destroy_offset(this->list, offsetof(swima_event_t, destroy));
+		free(this);
+	}
+}
+
+/**
+ * See header
+ */
+swima_events_t *swima_events_create(void)
+{
+	private_swima_events_t *this;
+
+	INIT(this,
+		.public = {
+			.add = _add,
+			.get_count = _get_count,
+			.set_eid = _set_eid,
+			.set_last_eid = _set_last_eid,
+			.get_eid = _get_eid,
+			.create_enumerator = _create_enumerator,
+			.get_ref = _get_ref,
+			.clear = _clear,
+			.destroy = _destroy,
+		},
+		.list = linked_list_create(),
+		.ref = 1,
+	);
+
+	return &this->public;
+}
diff --git a/src/libimcv/swima/swima_events.h b/src/libimcv/swima/swima_events.h
new file mode 100644
index 0000000..66bbedf
--- /dev/null
+++ b/src/libimcv/swima/swima_events.h
@@ -0,0 +1,106 @@
+/*
+ * Copyright (C) 2017 Andreas Steffen
+ * HSR Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT 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 swima_events swima_events
+ * @{ @ingroup libimcv_swima
+ */
+
+#ifndef SWIMA_EVENTS_H_
+#define SWIMA_EVENTS_H_
+
+#define SWIMA_MAX_ATTR_SIZE	10000000
+
+#include "swima_event.h"
+
+#include <library.h>
+
+typedef struct swima_events_t swima_events_t;
+
+/**
+ * Class managing list of Software [Identifier] Events
+ */
+struct swima_events_t {
+
+	/**
+	 * Add event to list
+	 *
+	 * @param event		Event to be added
+	 */
+	void (*add)(swima_events_t *this, swima_event_t *event);
+
+	/**
+	 * Get the number of events in the event list
+	 *
+	 * @return				Number of events
+	 */
+	int (*get_count)(swima_events_t *this);
+
+	/**
+	 * Set both the Last and Last Consulted Event ID
+	 *
+	 * @param				Last [Consulted] Event ID
+	 * @param				Epoch of event IDs
+	 */
+	void (*set_eid)(swima_events_t *this, uint32_t eid, uint32_t epoch);
+
+	/**
+	 * Set Last Event ID if different from Last Consulted Event ID
+	 *
+	 * @param last_eid		Last Event ID
+	 */
+	void (*set_last_eid)(swima_events_t *this, uint32_t last_eid);
+
+	/**
+	 * Get both the Last and Last Consulted Event ID
+	 *
+	 * @param eid_epoch		Event ID Epoch
+	 * @param last_eid		Last Event ID
+	 * @return				Last Consulted Event ID
+	 */
+	uint32_t (*get_eid)(swima_events_t *this, uint32_t *epoch, uint32_t *last_eid);
+
+	/**
+	  * Create an event enumerator
+	  *
+	  * @return				Enumerator returning events
+	  */
+	enumerator_t* (*create_enumerator)(swima_events_t *this);
+
+	/**
+	 * Get a new reference to a swima_events object
+	 *
+	 * @return			this, with an increased refcount
+	 */
+	swima_events_t* (*get_ref)(swima_events_t *this);
+
+	/**
+	 * Clears the events, keeping the eid and epoch values.
+	 */
+	void (*clear)(swima_events_t *this);
+
+	/**
+	 * Destroys a swima_events_t object.
+	 */
+	void (*destroy)(swima_events_t *this);
+
+};
+
+/**
+ * Creates a swima_events_t object
+ */
+swima_events_t* swima_events_create(void);
+
+#endif /** SWIMA_EVENTS_H_ @}*/
diff --git a/src/libimcv/swima/swima_inventory.c b/src/libimcv/swima/swima_inventory.c
new file mode 100644
index 0000000..acb69b9
--- /dev/null
+++ b/src/libimcv/swima/swima_inventory.c
@@ -0,0 +1,140 @@
+/*
+ * Copyright (C) 2017 Andreas Steffen
+ * HSR Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT 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 "swima_inventory.h"
+#include "swima_record.h"
+
+#include <collections/linked_list.h>
+#include <utils/debug.h>
+
+typedef struct private_swima_inventory_t private_swima_inventory_t;
+
+/**
+ * Private data of a swima_inventory_t object.
+ *
+ */
+struct private_swima_inventory_t {
+
+	/**
+	 * Public swima_inventory_t interface.
+	 */
+	swima_inventory_t public;
+
+	/**
+	 * Earliest or last event ID of the inventory
+	 */
+	uint32_t eid;
+
+	/**
+	 * Epoch of event IDs
+	 */
+	uint32_t epoch;
+
+	/**
+	 * List of SW records
+	 */
+	linked_list_t *list;
+
+
+	/**
+	 * Reference count
+	 */
+	refcount_t ref;
+
+};
+
+METHOD(swima_inventory_t, add, void,
+	private_swima_inventory_t *this, swima_record_t *record)
+{
+	this->list->insert_last(this->list, record);
+}
+
+METHOD(swima_inventory_t, get_count, int,
+	private_swima_inventory_t *this)
+{
+	return this->list->get_count(this->list);
+}
+
+METHOD(swima_inventory_t, set_eid, void,
+	private_swima_inventory_t *this, uint32_t eid, uint32_t epoch)
+{
+	this->eid = eid;
+	this->epoch = epoch;
+}
+
+METHOD(swima_inventory_t, get_eid, uint32_t,
+	private_swima_inventory_t *this, uint32_t *epoch)
+{
+	if (epoch)
+	{
+		*epoch = this->epoch;
+	}
+	return this->eid;
+}
+
+METHOD(swima_inventory_t, create_enumerator, enumerator_t*,
+	private_swima_inventory_t *this)
+{
+	return this->list->create_enumerator(this->list);
+}
+
+METHOD(swima_inventory_t, get_ref, swima_inventory_t*,
+	private_swima_inventory_t *this)
+{
+	ref_get(&this->ref);
+	return &this->public;
+}
+
+METHOD(swima_inventory_t, clear, void,
+	private_swima_inventory_t *this)
+{
+		this->list->destroy_offset(this->list, offsetof(swima_record_t, destroy));
+		this->list = linked_list_create();
+}
+
+METHOD(swima_inventory_t, destroy, void,
+	private_swima_inventory_t *this)
+{
+	if (ref_put(&this->ref))
+	{
+		this->list->destroy_offset(this->list, offsetof(swima_record_t, destroy));
+		free(this);
+	}
+}
+
+/**
+ * See header
+ */
+swima_inventory_t *swima_inventory_create(void)
+{
+	private_swima_inventory_t *this;
+
+	INIT(this,
+		.public = {
+			.add = _add,
+			.get_count = _get_count,
+			.set_eid = _set_eid,
+			.get_eid = _get_eid,
+			.create_enumerator = _create_enumerator,
+			.get_ref = _get_ref,
+			.clear = _clear,
+			.destroy = _destroy,
+		},
+		.list = linked_list_create(),
+		.ref = 1,
+	);
+
+	return &this->public;
+}
diff --git a/src/libimcv/swima/swima_inventory.h b/src/libimcv/swima/swima_inventory.h
new file mode 100644
index 0000000..21953bb
--- /dev/null
+++ b/src/libimcv/swima/swima_inventory.h
@@ -0,0 +1,99 @@
+/*
+ * Copyright (C) 2017 Andreas Steffen
+ * HSR Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT 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 swima_inventory swima_inventory
+ * @{ @ingroup libimcv_swima
+ */
+
+#ifndef SWIMA_INVENTORY_H_
+#define SWIMA_INVENTORY_H_
+
+#define SWIMA_MAX_ATTR_SIZE	10000000
+
+#include "swima_record.h"
+
+#include <library.h>
+
+typedef struct swima_inventory_t swima_inventory_t;
+
+/**
+ * Class managing software inventory
+ */
+struct swima_inventory_t {
+
+	/**
+	 * Add evidence record to software inventory
+	 *
+	 * @param record		Software evidence record to be added
+	 */
+	void (*add)(swima_inventory_t *this, swima_record_t *record);
+
+	/**
+	 * Get the number of evidence records in the software inventory
+	 *
+	 * @return				Number evidence records
+	 */
+	int (*get_count)(swima_inventory_t *this);
+
+	/**
+	 * Set the earliest or last event ID of the inventory
+	 *
+	 * @param				Event ID
+	 * @param				Epoch of event IDs
+	 */
+	void (*set_eid)(swima_inventory_t *this, uint32_t eid, uint32_t epoch);
+
+	/**
+	 * Get the earliest or last event ID of the inventory
+	 *
+	 * @param				Epoch of event IDs
+	 * @return				Event ID
+	 */
+	uint32_t (*get_eid)(swima_inventory_t *this, uint32_t *epoch);
+
+	/**
+	  * Create a software inventory evidence record enumerator
+	  *
+	  * @return				Enumerator returning evidence records
+	  */
+	enumerator_t* (*create_enumerator)(swima_inventory_t *this);
+
+	/**
+	 * Get a new reference to a swima_inventory object
+	 *
+	 * @return				This, with an increased refcount
+	 */
+	swima_inventory_t* (*get_ref)(swima_inventory_t *this);
+
+	/**
+	 * Clears the inventory, keeping the eid and epoch values
+	 */
+	void (*clear)(swima_inventory_t *this);
+
+	/**
+	 * Destroys a swima_inventory_t object
+	 */
+	void (*destroy)(swima_inventory_t *this);
+
+};
+
+/**
+ * Creates a swima_inventory_t object
+ *
+ */
+swima_inventory_t* swima_inventory_create(void);
+
+#endif /** SWIMA_INVENTORY_H_ @}*/
diff --git a/src/libimcv/swima/swima_record.c b/src/libimcv/swima/swima_record.c
new file mode 100644
index 0000000..dc6a541
--- /dev/null
+++ b/src/libimcv/swima/swima_record.c
@@ -0,0 +1,174 @@
+/*
+ * Copyright (C) 2017 Andreas Steffen
+ * HSR Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT 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 "swima_record.h"
+#include "swima_data_model.h"
+
+typedef struct private_swima_record_t private_swima_record_t;
+
+/**
+ * Private data of a swima_record_t object.
+ *
+ */
+struct private_swima_record_t {
+
+	/**
+	 * Public swima_record_t interface.
+	 */
+	swima_record_t public;
+
+	/**
+	 * Record ID
+	 */
+	uint32_t record_id;
+
+	/**
+	 * Software Identity
+	 */
+	chunk_t sw_id;
+
+	/**
+	 * Optional Software Locator
+	 */
+	chunk_t sw_locator;
+
+	/**
+	 * Data Model
+	 */
+	pen_type_t data_model;
+
+	/**
+	 * Source ID
+	 */
+	uint8_t source_id;
+
+	/**g
+	 * Optional Software Inventory Evidence Record
+	 */
+	chunk_t record;
+
+	/**
+	 * Reference count
+	 */
+	refcount_t ref;
+};
+
+METHOD(swima_record_t, get_record_id, uint32_t,
+	private_swima_record_t *this)
+{
+	return this->record_id;
+}
+
+METHOD(swima_record_t, get_sw_id, chunk_t,
+	private_swima_record_t *this, chunk_t *sw_locator)
+{
+	if (sw_locator)
+	{
+		*sw_locator = this->sw_locator;
+	}
+	return this->sw_id;
+}
+
+METHOD(swima_record_t, set_data_model, void,
+	private_swima_record_t *this, pen_type_t data_model)
+{
+	this->data_model = data_model;
+}
+
+METHOD(swima_record_t, get_data_model, pen_type_t,
+	private_swima_record_t *this)
+{
+	return this->data_model;
+}
+
+METHOD(swima_record_t, set_source_id, void,
+	private_swima_record_t *this, uint8_t source_id)
+{
+	this->source_id = source_id;
+}
+
+METHOD(swima_record_t, get_source_id, uint8_t,
+	private_swima_record_t *this)
+{
+	return this->source_id;
+}
+
+METHOD(swima_record_t, set_record, void,
+	private_swima_record_t *this, chunk_t record)
+{
+	chunk_free(&this->record);
+	this->record = chunk_clone(record);
+}
+
+METHOD(swima_record_t, get_record, chunk_t,
+	private_swima_record_t *this)
+{
+	return this->record;
+}
+
+METHOD(swima_record_t, get_ref, swima_record_t*,
+	private_swima_record_t *this)
+{
+	ref_get(&this->ref);
+	return &this->public;
+}
+
+METHOD(swima_record_t, destroy, void,
+	private_swima_record_t *this)
+{
+	if (ref_put(&this->ref))
+	{
+		free(this->sw_id.ptr);
+		free(this->sw_locator.ptr);
+		free(this->record.ptr);
+		free(this);
+	}
+}
+
+/**
+ * See header
+ */
+swima_record_t *swima_record_create(uint32_t record_id, chunk_t sw_id,
+									chunk_t sw_locator)
+{
+	private_swima_record_t *this;
+
+	INIT(this,
+		.public = {
+			.get_record_id = _get_record_id,
+			.get_sw_id = _get_sw_id,
+			.set_data_model = _set_data_model,
+			.get_data_model = _get_data_model,
+			.set_source_id = _set_source_id,
+			.get_source_id = _get_source_id,
+			.set_record = _set_record,
+			.get_record = _get_record,
+			.get_ref = _get_ref,
+			.destroy = _destroy,
+		},
+		.record_id = record_id,
+		.data_model = swima_data_model_iso_2015_swid_xml,
+		.sw_id = chunk_clone(sw_id),
+		.ref = 1,
+	);
+
+	if (sw_locator.len > 0)
+	{
+		this->sw_locator = chunk_clone(sw_locator);
+	}
+
+	return &this->public;
+}
+
diff --git a/src/libimcv/swima/swima_record.h b/src/libimcv/swima/swima_record.h
new file mode 100644
index 0000000..c26ffdf
--- /dev/null
+++ b/src/libimcv/swima/swima_record.h
@@ -0,0 +1,115 @@
+/*
+ * Copyright (C) 2017 Andreas Steffen
+ * HSR Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT 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 swima_record swima_record
+ * @{ @ingroup libimcv_swima
+ */
+
+#ifndef SWIMA_RECORD_H_
+#define SWIMA_RECORD_H_
+
+#include <library.h>
+#include <pen/pen.h>
+
+typedef struct swima_record_t swima_record_t;
+
+/**
+ * Class storing a Software Inventory Evidence Collection record
+ */
+struct swima_record_t {
+
+	/**
+	 * Get Software Identifier and optional Software Location
+	 *
+	 * @return				Record ID
+	 */
+	uint32_t (*get_record_id)(swima_record_t *this);
+
+	/**
+	 * Get Software Identifier and optional Software Location
+	 *
+	 * @param sw_locator	Optional Software Locator
+	 * @return				Software Identifier
+	 */
+	chunk_t (*get_sw_id)(swima_record_t *this, chunk_t *sw_locator);
+
+	/**
+	 * Set Data Model
+	 *
+	 * @param				Data model type in PEN namespace
+	 */
+	void (*set_data_model)(swima_record_t *this, pen_type_t data_model);
+
+	/**
+	 * Get Data Model
+	 *
+	 * @return				Data model type in PEN namespace
+	 */
+	pen_type_t (*get_data_model)(swima_record_t *this);
+
+	/**
+	 * Set Source ID
+	 *
+	 * @param				Source ID
+	 */
+	void (*set_source_id)(swima_record_t *this, uint8_t source_id);
+
+	/**
+	 * Get Source ID
+	 *
+	 * @return				Source ID
+	 */
+	uint8_t (*get_source_id)(swima_record_t *this);
+
+	/**
+	 * Set Software Inventory Evidence Record
+	 *
+	 * @param				Software Inventory Evidence Record
+	 */
+	void (*set_record)(swima_record_t *this, chunk_t record);
+
+	/**
+	 * Get Software Inventory Evidence Record
+	 *
+	 * @return				Software Inventory Evidence Record
+	 */
+	chunk_t (*get_record)(swima_record_t *this);
+
+	/**
+	 * Get a new reference to a swima_record object
+	 *
+	 * @return			this, with an increased refcount
+	 */
+	swima_record_t* (*get_ref)(swima_record_t *this);
+
+	/**
+	 * Destroys a swima_record_t object.
+	 */
+	void (*destroy)(swima_record_t *this);
+
+};
+
+/**
+ * Creates a swima_record_t object
+ *
+ * @param record_id			Record ID
+ * @param sw_id				Software Identifierl
+ * @param sw_locator		Software Locator or empty chunk
+ */
+swima_record_t* swima_record_create(uint32_t record_id, chunk_t sw_id,
+									chunk_t sw_locator);
+
+#endif /** SWIMA_RECORD_H_ @}*/
diff --git a/src/libimcv/tcg/swid/tcg_swid_attr_req.c b/src/libimcv/tcg/swid/tcg_swid_attr_req.c
index f02bbcb..be35ee4 100644
--- a/src/libimcv/tcg/swid/tcg_swid_attr_req.c
+++ b/src/libimcv/tcg/swid/tcg_swid_attr_req.c
@@ -32,7 +32,7 @@ typedef struct private_tcg_swid_attr_req_t private_tcg_swid_attr_req_t;
  *                       1                   2                   3
  *   0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
  *  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- *  |R|S|C| Reserved|                   Tag ID Count                |
+ *  |C|S|R| Reserved|                   Tag ID Count                |
  *  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  *  |                          Request ID                           |
  *  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
@@ -201,6 +201,7 @@ METHOD(pa_tnc_attr_t, process, status_t,
 		if (!reader->read_data16(reader, &tag_creator))
 		{
 			DBG1(DBG_TNC, "insufficient data for Tag Creator field");
+			reader->destroy(reader);
 			return FAILED;
 		}
 		*offset += 2 + tag_creator.len;
@@ -208,6 +209,7 @@ METHOD(pa_tnc_attr_t, process, status_t,
 		if (!reader->read_data16(reader, &unique_sw_id))
 		{
 			DBG1(DBG_TNC, "insufficient data for Unique Software ID");
+			reader->destroy(reader);
 			return FAILED;
 		}
 		*offset += 2 + unique_sw_id.len;
diff --git a/src/libimcv/tcg/swid/tcg_swid_attr_req.h b/src/libimcv/tcg/swid/tcg_swid_attr_req.h
index b28c33a..2c85aaf 100644
--- a/src/libimcv/tcg/swid/tcg_swid_attr_req.h
+++ b/src/libimcv/tcg/swid/tcg_swid_attr_req.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2013-2014 Andreas Steffen
+ * Copyright (C) 2013-2017 Andreas Steffen
  * HSR Hochschule fuer Technik Rapperswil
  *
  * This program is free software; you can redistribute it and/or modify it
@@ -28,9 +28,9 @@ typedef enum tcg_swid_attr_req_flag_t tcg_swid_attr_req_flag_t;
 
 enum tcg_swid_attr_req_flag_t {
 	TCG_SWID_ATTR_REQ_FLAG_NONE = 0,
-	TCG_SWID_ATTR_REQ_FLAG_R =   (1 << 7),
+	TCG_SWID_ATTR_REQ_FLAG_C =   (1 << 7),
 	TCG_SWID_ATTR_REQ_FLAG_S =   (1 << 6),
-	TCG_SWID_ATTR_REQ_FLAG_C =   (1 << 5)
+	TCG_SWID_ATTR_REQ_FLAG_R =   (1 << 5)
 };
 
 #include "tcg/tcg_attr.h"
diff --git a/src/libipsec/Makefile.in b/src/libipsec/Makefile.in
index 55d1d58..e4f0c44 100644
--- a/src/libipsec/Makefile.in
+++ b/src/libipsec/Makefile.in
@@ -353,8 +353,6 @@ RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
 RUBYGEMDIR = @RUBYGEMDIR@
-RUBYINCLUDE = @RUBYINCLUDE@
-RUBYLIB = @RUBYLIB@
 SED = @SED@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
@@ -455,6 +453,8 @@ random_device = @random_device@
 resolv_conf = @resolv_conf@
 routing_table = @routing_table@
 routing_table_prio = @routing_table_prio@
+ruby_CFLAGS = @ruby_CFLAGS@
+ruby_LIBS = @ruby_LIBS@
 runstatedir = @runstatedir@
 s_plugins = @s_plugins@
 sbindir = @sbindir@
@@ -483,6 +483,10 @@ top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
 tss2_CFLAGS = @tss2_CFLAGS@
 tss2_LIBS = @tss2_LIBS@
+tss2_socket_CFLAGS = @tss2_socket_CFLAGS@
+tss2_socket_LIBS = @tss2_socket_LIBS@
+tss2_tabrmd_CFLAGS = @tss2_tabrmd_CFLAGS@
+tss2_tabrmd_LIBS = @tss2_tabrmd_LIBS@
 urandom_device = @urandom_device@
 xml_CFLAGS = @xml_CFLAGS@
 xml_LIBS = @xml_LIBS@
diff --git a/src/libipsec/tests/Makefile.in b/src/libipsec/tests/Makefile.in
index b1fdea4..5b6c530 100644
--- a/src/libipsec/tests/Makefile.in
+++ b/src/libipsec/tests/Makefile.in
@@ -306,8 +306,6 @@ RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
 RUBYGEMDIR = @RUBYGEMDIR@
-RUBYINCLUDE = @RUBYINCLUDE@
-RUBYLIB = @RUBYLIB@
 SED = @SED@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
@@ -408,6 +406,8 @@ random_device = @random_device@
 resolv_conf = @resolv_conf@
 routing_table = @routing_table@
 routing_table_prio = @routing_table_prio@
+ruby_CFLAGS = @ruby_CFLAGS@
+ruby_LIBS = @ruby_LIBS@
 runstatedir = @runstatedir@
 s_plugins = @s_plugins@
 sbindir = @sbindir@
@@ -436,6 +436,10 @@ top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
 tss2_CFLAGS = @tss2_CFLAGS@
 tss2_LIBS = @tss2_LIBS@
+tss2_socket_CFLAGS = @tss2_socket_CFLAGS@
+tss2_socket_LIBS = @tss2_socket_LIBS@
+tss2_tabrmd_CFLAGS = @tss2_tabrmd_CFLAGS@
+tss2_tabrmd_LIBS = @tss2_tabrmd_LIBS@
 urandom_device = @urandom_device@
 xml_CFLAGS = @xml_CFLAGS@
 xml_LIBS = @xml_LIBS@
diff --git a/src/libpttls/Makefile.in b/src/libpttls/Makefile.in
index 803d687..0185a39 100644
--- a/src/libpttls/Makefile.in
+++ b/src/libpttls/Makefile.in
@@ -311,8 +311,6 @@ RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
 RUBYGEMDIR = @RUBYGEMDIR@
-RUBYINCLUDE = @RUBYINCLUDE@
-RUBYLIB = @RUBYLIB@
 SED = @SED@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
@@ -413,6 +411,8 @@ random_device = @random_device@
 resolv_conf = @resolv_conf@
 routing_table = @routing_table@
 routing_table_prio = @routing_table_prio@
+ruby_CFLAGS = @ruby_CFLAGS@
+ruby_LIBS = @ruby_LIBS@
 runstatedir = @runstatedir@
 s_plugins = @s_plugins@
 sbindir = @sbindir@
@@ -441,6 +441,10 @@ top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
 tss2_CFLAGS = @tss2_CFLAGS@
 tss2_LIBS = @tss2_LIBS@
+tss2_socket_CFLAGS = @tss2_socket_CFLAGS@
+tss2_socket_LIBS = @tss2_socket_LIBS@
+tss2_tabrmd_CFLAGS = @tss2_tabrmd_CFLAGS@
+tss2_tabrmd_LIBS = @tss2_tabrmd_LIBS@
 urandom_device = @urandom_device@
 xml_CFLAGS = @xml_CFLAGS@
 xml_LIBS = @xml_LIBS@
diff --git a/src/libradius/Makefile.in b/src/libradius/Makefile.in
index 9e7b737..794b4b4 100644
--- a/src/libradius/Makefile.in
+++ b/src/libradius/Makefile.in
@@ -306,8 +306,6 @@ RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
 RUBYGEMDIR = @RUBYGEMDIR@
-RUBYINCLUDE = @RUBYINCLUDE@
-RUBYLIB = @RUBYLIB@
 SED = @SED@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
@@ -408,6 +406,8 @@ random_device = @random_device@
 resolv_conf = @resolv_conf@
 routing_table = @routing_table@
 routing_table_prio = @routing_table_prio@
+ruby_CFLAGS = @ruby_CFLAGS@
+ruby_LIBS = @ruby_LIBS@
 runstatedir = @runstatedir@
 s_plugins = @s_plugins@
 sbindir = @sbindir@
@@ -436,6 +436,10 @@ top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
 tss2_CFLAGS = @tss2_CFLAGS@
 tss2_LIBS = @tss2_LIBS@
+tss2_socket_CFLAGS = @tss2_socket_CFLAGS@
+tss2_socket_LIBS = @tss2_socket_LIBS@
+tss2_tabrmd_CFLAGS = @tss2_tabrmd_CFLAGS@
+tss2_tabrmd_LIBS = @tss2_tabrmd_LIBS@
 urandom_device = @urandom_device@
 xml_CFLAGS = @xml_CFLAGS@
 xml_LIBS = @xml_LIBS@
diff --git a/src/libsimaka/Makefile.in b/src/libsimaka/Makefile.in
index 6ecbaec..df1da70 100644
--- a/src/libsimaka/Makefile.in
+++ b/src/libsimaka/Makefile.in
@@ -309,8 +309,6 @@ RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
 RUBYGEMDIR = @RUBYGEMDIR@
-RUBYINCLUDE = @RUBYINCLUDE@
-RUBYLIB = @RUBYLIB@
 SED = @SED@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
@@ -411,6 +409,8 @@ random_device = @random_device@
 resolv_conf = @resolv_conf@
 routing_table = @routing_table@
 routing_table_prio = @routing_table_prio@
+ruby_CFLAGS = @ruby_CFLAGS@
+ruby_LIBS = @ruby_LIBS@
 runstatedir = @runstatedir@
 s_plugins = @s_plugins@
 sbindir = @sbindir@
@@ -439,6 +439,10 @@ top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
 tss2_CFLAGS = @tss2_CFLAGS@
 tss2_LIBS = @tss2_LIBS@
+tss2_socket_CFLAGS = @tss2_socket_CFLAGS@
+tss2_socket_LIBS = @tss2_socket_LIBS@
+tss2_tabrmd_CFLAGS = @tss2_tabrmd_CFLAGS@
+tss2_tabrmd_LIBS = @tss2_tabrmd_LIBS@
 urandom_device = @urandom_device@
 xml_CFLAGS = @xml_CFLAGS@
 xml_LIBS = @xml_LIBS@
diff --git a/src/libstrongswan/Android.mk b/src/libstrongswan/Android.mk
index a5e6b72..afca134 100644
--- a/src/libstrongswan/Android.mk
+++ b/src/libstrongswan/Android.mk
@@ -113,6 +113,8 @@ LOCAL_SRC_FILES += $(call add_plugin, pubkey)
 
 LOCAL_SRC_FILES += $(call add_plugin, random)
 
+LOCAL_SRC_FILES += $(call add_plugin, revocation)
+
 LOCAL_SRC_FILES += $(call add_plugin, sha1)
 
 LOCAL_SRC_FILES += $(call add_plugin, sha2)
@@ -133,6 +135,6 @@ LOCAL_ARM_MODE := arm
 
 LOCAL_PRELINK_MODULE := false
 
-LOCAL_SHARED_LIBRARIES += libdl
+LOCAL_LDLIBS += -ldl
 
 include $(BUILD_SHARED_LIBRARY)
diff --git a/src/libstrongswan/Makefile.in b/src/libstrongswan/Makefile.in
index 9b1c26b..16e5856 100644
--- a/src/libstrongswan/Makefile.in
+++ b/src/libstrongswan/Makefile.in
@@ -786,8 +786,6 @@ RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
 RUBYGEMDIR = @RUBYGEMDIR@
-RUBYINCLUDE = @RUBYINCLUDE@
-RUBYLIB = @RUBYLIB@
 SED = @SED@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
@@ -888,6 +886,8 @@ random_device = @random_device@
 resolv_conf = @resolv_conf@
 routing_table = @routing_table@
 routing_table_prio = @routing_table_prio@
+ruby_CFLAGS = @ruby_CFLAGS@
+ruby_LIBS = @ruby_LIBS@
 runstatedir = @runstatedir@
 s_plugins = @s_plugins@
 sbindir = @sbindir@
@@ -916,6 +916,10 @@ top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
 tss2_CFLAGS = @tss2_CFLAGS@
 tss2_LIBS = @tss2_LIBS@
+tss2_socket_CFLAGS = @tss2_socket_CFLAGS@
+tss2_socket_LIBS = @tss2_socket_LIBS@
+tss2_tabrmd_CFLAGS = @tss2_tabrmd_CFLAGS@
+tss2_tabrmd_LIBS = @tss2_tabrmd_LIBS@
 urandom_device = @urandom_device@
 xml_CFLAGS = @xml_CFLAGS@
 xml_LIBS = @xml_LIBS@
diff --git a/src/libstrongswan/credentials/auth_cfg.c b/src/libstrongswan/credentials/auth_cfg.c
index a9c8b39..07da596 100644
--- a/src/libstrongswan/credentials/auth_cfg.c
+++ b/src/libstrongswan/credentials/auth_cfg.c
@@ -840,7 +840,7 @@ METHOD(auth_cfg_t, complies, bool,
 					{	/* also verify identity against subjectAltNames */
 						certificate_t *cert;
 
-						cert = get(this, AUTH_HELPER_SUBJECT_CERT);
+						cert = get(this, AUTH_RULE_SUBJECT_CERT);
 						if (cert && cert->has_subject(cert, id1))
 						{
 							break;
diff --git a/src/libstrongswan/credentials/credential_manager.c b/src/libstrongswan/credentials/credential_manager.c
index 0a8d3d1..9be7407 100644
--- a/src/libstrongswan/credentials/credential_manager.c
+++ b/src/libstrongswan/credentials/credential_manager.c
@@ -774,6 +774,8 @@ static bool verify_trust_chain(private_credential_manager_t *this,
 			{
 				DBG1(DBG_CFG, "no issuer certificate found for \"%Y\"",
 					 current->get_subject(current));
+				DBG1(DBG_CFG, "  issuer is \"%Y\"",
+					 current->get_issuer(current));
 				call_hook(this, CRED_HOOK_NO_ISSUER, current);
 				break;
 			}
diff --git a/src/libstrongswan/crypto/crypto_tester.h b/src/libstrongswan/crypto/crypto_tester.h
index 34dfa94..1b02cb4 100644
--- a/src/libstrongswan/crypto/crypto_tester.h
+++ b/src/libstrongswan/crypto/crypto_tester.h
@@ -83,7 +83,7 @@ struct signer_test_vector_t {
 	size_t len;
 	/** input data */
 	u_char *data;
-	/** expected output, with ouput size of the tested algorithm */
+	/** expected output, with output size of the tested algorithm */
 	u_char *mac;
 };
 
diff --git a/src/libstrongswan/crypto/prf_plus.c b/src/libstrongswan/crypto/prf_plus.c
index 6b7f8f8..a26010a 100644
--- a/src/libstrongswan/crypto/prf_plus.c
+++ b/src/libstrongswan/crypto/prf_plus.c
@@ -115,8 +115,8 @@ METHOD(prf_plus_t, allocate_bytes, bool,
 METHOD(prf_plus_t, destroy, void,
 	private_prf_plus_t *this)
 {
-	free(this->buffer.ptr);
-	free(this->seed.ptr);
+	chunk_clear(&this->buffer);
+	chunk_clear(&this->seed);
 	free(this);
 }
 
diff --git a/src/libstrongswan/ipsec/ipsec_types.c b/src/libstrongswan/ipsec/ipsec_types.c
index a52a1eb..68c3935 100644
--- a/src/libstrongswan/ipsec/ipsec_types.c
+++ b/src/libstrongswan/ipsec/ipsec_types.c
@@ -66,8 +66,21 @@ bool mark_from_string(const char *value, mark_t *mark)
 	}
 	if (strcasepfx(value, "%unique"))
 	{
-		mark->value = MARK_UNIQUE;
 		endptr = (char*)value + strlen("%unique");
+		if (strcasepfx(endptr, "-dir"))
+		{
+			mark->value = MARK_UNIQUE_DIR;
+			endptr += strlen("-dir");
+		}
+		else if (!*endptr || *endptr == '/')
+		{
+			mark->value = MARK_UNIQUE;
+		}
+		else
+		{
+			DBG1(DBG_APP, "invalid mark value: %s", value);
+			return FALSE;
+		}
 	}
 	else
 	{
diff --git a/src/libstrongswan/ipsec/ipsec_types.h b/src/libstrongswan/ipsec/ipsec_types.h
index c93d955..1db78ba 100644
--- a/src/libstrongswan/ipsec/ipsec_types.h
+++ b/src/libstrongswan/ipsec/ipsec_types.h
@@ -178,9 +178,11 @@ struct mark_t {
 };
 
 /**
- * Special mark value that uses a unique mark for each CHILD_SA
+ * Special mark value that uses a unique mark for each CHILD_SA (and direction)
  */
 #define MARK_UNIQUE (0xFFFFFFFF)
+#define MARK_UNIQUE_DIR (0xFFFFFFFE)
+#define MARK_IS_UNIQUE(m) ((m) == MARK_UNIQUE || (m) == MARK_UNIQUE_DIR)
 
 /**
  * Try to parse a mark_t from the given string of the form mark[/mask].
diff --git a/src/libstrongswan/math/libnttfft/Makefile.in b/src/libstrongswan/math/libnttfft/Makefile.in
index 93bd935..439c0f3 100644
--- a/src/libstrongswan/math/libnttfft/Makefile.in
+++ b/src/libstrongswan/math/libnttfft/Makefile.in
@@ -304,8 +304,6 @@ RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
 RUBYGEMDIR = @RUBYGEMDIR@
-RUBYINCLUDE = @RUBYINCLUDE@
-RUBYLIB = @RUBYLIB@
 SED = @SED@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
@@ -406,6 +404,8 @@ random_device = @random_device@
 resolv_conf = @resolv_conf@
 routing_table = @routing_table@
 routing_table_prio = @routing_table_prio@
+ruby_CFLAGS = @ruby_CFLAGS@
+ruby_LIBS = @ruby_LIBS@
 runstatedir = @runstatedir@
 s_plugins = @s_plugins@
 sbindir = @sbindir@
@@ -434,6 +434,10 @@ top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
 tss2_CFLAGS = @tss2_CFLAGS@
 tss2_LIBS = @tss2_LIBS@
+tss2_socket_CFLAGS = @tss2_socket_CFLAGS@
+tss2_socket_LIBS = @tss2_socket_LIBS@
+tss2_tabrmd_CFLAGS = @tss2_tabrmd_CFLAGS@
+tss2_tabrmd_LIBS = @tss2_tabrmd_LIBS@
 urandom_device = @urandom_device@
 xml_CFLAGS = @xml_CFLAGS@
 xml_LIBS = @xml_LIBS@
diff --git a/src/libstrongswan/math/libnttfft/tests/Makefile.in b/src/libstrongswan/math/libnttfft/tests/Makefile.in
index 80ecd3e..1f3ee6d 100644
--- a/src/libstrongswan/math/libnttfft/tests/Makefile.in
+++ b/src/libstrongswan/math/libnttfft/tests/Makefile.in
@@ -308,8 +308,6 @@ RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
 RUBYGEMDIR = @RUBYGEMDIR@
-RUBYINCLUDE = @RUBYINCLUDE@
-RUBYLIB = @RUBYLIB@
 SED = @SED@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
@@ -410,6 +408,8 @@ random_device = @random_device@
 resolv_conf = @resolv_conf@
 routing_table = @routing_table@
 routing_table_prio = @routing_table_prio@
+ruby_CFLAGS = @ruby_CFLAGS@
+ruby_LIBS = @ruby_LIBS@
 runstatedir = @runstatedir@
 s_plugins = @s_plugins@
 sbindir = @sbindir@
@@ -438,6 +438,10 @@ top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
 tss2_CFLAGS = @tss2_CFLAGS@
 tss2_LIBS = @tss2_LIBS@
+tss2_socket_CFLAGS = @tss2_socket_CFLAGS@
+tss2_socket_LIBS = @tss2_socket_LIBS@
+tss2_tabrmd_CFLAGS = @tss2_tabrmd_CFLAGS@
+tss2_tabrmd_LIBS = @tss2_tabrmd_LIBS@
 urandom_device = @urandom_device@
 xml_CFLAGS = @xml_CFLAGS@
 xml_LIBS = @xml_LIBS@
diff --git a/src/libstrongswan/plugins/acert/Makefile.in b/src/libstrongswan/plugins/acert/Makefile.in
index 1dcc048..10e6fa4 100644
--- a/src/libstrongswan/plugins/acert/Makefile.in
+++ b/src/libstrongswan/plugins/acert/Makefile.in
@@ -311,8 +311,6 @@ RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
 RUBYGEMDIR = @RUBYGEMDIR@
-RUBYINCLUDE = @RUBYINCLUDE@
-RUBYLIB = @RUBYLIB@
 SED = @SED@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
@@ -413,6 +411,8 @@ random_device = @random_device@
 resolv_conf = @resolv_conf@
 routing_table = @routing_table@
 routing_table_prio = @routing_table_prio@
+ruby_CFLAGS = @ruby_CFLAGS@
+ruby_LIBS = @ruby_LIBS@
 runstatedir = @runstatedir@
 s_plugins = @s_plugins@
 sbindir = @sbindir@
@@ -441,6 +441,10 @@ top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
 tss2_CFLAGS = @tss2_CFLAGS@
 tss2_LIBS = @tss2_LIBS@
+tss2_socket_CFLAGS = @tss2_socket_CFLAGS@
+tss2_socket_LIBS = @tss2_socket_LIBS@
+tss2_tabrmd_CFLAGS = @tss2_tabrmd_CFLAGS@
+tss2_tabrmd_LIBS = @tss2_tabrmd_LIBS@
 urandom_device = @urandom_device@
 xml_CFLAGS = @xml_CFLAGS@
 xml_LIBS = @xml_LIBS@
diff --git a/src/libstrongswan/plugins/aes/Makefile.in b/src/libstrongswan/plugins/aes/Makefile.in
index 2b16ae7..08f9655 100644
--- a/src/libstrongswan/plugins/aes/Makefile.in
+++ b/src/libstrongswan/plugins/aes/Makefile.in
@@ -310,8 +310,6 @@ RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
 RUBYGEMDIR = @RUBYGEMDIR@
-RUBYINCLUDE = @RUBYINCLUDE@
-RUBYLIB = @RUBYLIB@
 SED = @SED@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
@@ -412,6 +410,8 @@ random_device = @random_device@
 resolv_conf = @resolv_conf@
 routing_table = @routing_table@
 routing_table_prio = @routing_table_prio@
+ruby_CFLAGS = @ruby_CFLAGS@
+ruby_LIBS = @ruby_LIBS@
 runstatedir = @runstatedir@
 s_plugins = @s_plugins@
 sbindir = @sbindir@
@@ -440,6 +440,10 @@ top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
 tss2_CFLAGS = @tss2_CFLAGS@
 tss2_LIBS = @tss2_LIBS@
+tss2_socket_CFLAGS = @tss2_socket_CFLAGS@
+tss2_socket_LIBS = @tss2_socket_LIBS@
+tss2_tabrmd_CFLAGS = @tss2_tabrmd_CFLAGS@
+tss2_tabrmd_LIBS = @tss2_tabrmd_LIBS@
 urandom_device = @urandom_device@
 xml_CFLAGS = @xml_CFLAGS@
 xml_LIBS = @xml_LIBS@
diff --git a/src/libstrongswan/plugins/aesni/Makefile.in b/src/libstrongswan/plugins/aesni/Makefile.in
index d32e7f5..fbc7d92 100644
--- a/src/libstrongswan/plugins/aesni/Makefile.in
+++ b/src/libstrongswan/plugins/aesni/Makefile.in
@@ -313,8 +313,6 @@ RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
 RUBYGEMDIR = @RUBYGEMDIR@
-RUBYINCLUDE = @RUBYINCLUDE@
-RUBYLIB = @RUBYLIB@
 SED = @SED@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
@@ -415,6 +413,8 @@ random_device = @random_device@
 resolv_conf = @resolv_conf@
 routing_table = @routing_table@
 routing_table_prio = @routing_table_prio@
+ruby_CFLAGS = @ruby_CFLAGS@
+ruby_LIBS = @ruby_LIBS@
 runstatedir = @runstatedir@
 s_plugins = @s_plugins@
 sbindir = @sbindir@
@@ -443,6 +443,10 @@ top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
 tss2_CFLAGS = @tss2_CFLAGS@
 tss2_LIBS = @tss2_LIBS@
+tss2_socket_CFLAGS = @tss2_socket_CFLAGS@
+tss2_socket_LIBS = @tss2_socket_LIBS@
+tss2_tabrmd_CFLAGS = @tss2_tabrmd_CFLAGS@
+tss2_tabrmd_LIBS = @tss2_tabrmd_LIBS@
 urandom_device = @urandom_device@
 xml_CFLAGS = @xml_CFLAGS@
 xml_LIBS = @xml_LIBS@
diff --git a/src/libstrongswan/plugins/af_alg/Makefile.in b/src/libstrongswan/plugins/af_alg/Makefile.in
index e931402..2c45ce5 100644
--- a/src/libstrongswan/plugins/af_alg/Makefile.in
+++ b/src/libstrongswan/plugins/af_alg/Makefile.in
@@ -314,8 +314,6 @@ RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
 RUBYGEMDIR = @RUBYGEMDIR@
-RUBYINCLUDE = @RUBYINCLUDE@
-RUBYLIB = @RUBYLIB@
 SED = @SED@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
@@ -416,6 +414,8 @@ random_device = @random_device@
 resolv_conf = @resolv_conf@
 routing_table = @routing_table@
 routing_table_prio = @routing_table_prio@
+ruby_CFLAGS = @ruby_CFLAGS@
+ruby_LIBS = @ruby_LIBS@
 runstatedir = @runstatedir@
 s_plugins = @s_plugins@
 sbindir = @sbindir@
@@ -444,6 +444,10 @@ top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
 tss2_CFLAGS = @tss2_CFLAGS@
 tss2_LIBS = @tss2_LIBS@
+tss2_socket_CFLAGS = @tss2_socket_CFLAGS@
+tss2_socket_LIBS = @tss2_socket_LIBS@
+tss2_tabrmd_CFLAGS = @tss2_tabrmd_CFLAGS@
+tss2_tabrmd_LIBS = @tss2_tabrmd_LIBS@
 urandom_device = @urandom_device@
 xml_CFLAGS = @xml_CFLAGS@
 xml_LIBS = @xml_LIBS@
diff --git a/src/libstrongswan/plugins/agent/Makefile.in b/src/libstrongswan/plugins/agent/Makefile.in
index a4e7e29..8183de9 100644
--- a/src/libstrongswan/plugins/agent/Makefile.in
+++ b/src/libstrongswan/plugins/agent/Makefile.in
@@ -312,8 +312,6 @@ RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
 RUBYGEMDIR = @RUBYGEMDIR@
-RUBYINCLUDE = @RUBYINCLUDE@
-RUBYLIB = @RUBYLIB@
 SED = @SED@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
@@ -414,6 +412,8 @@ random_device = @random_device@
 resolv_conf = @resolv_conf@
 routing_table = @routing_table@
 routing_table_prio = @routing_table_prio@
+ruby_CFLAGS = @ruby_CFLAGS@
+ruby_LIBS = @ruby_LIBS@
 runstatedir = @runstatedir@
 s_plugins = @s_plugins@
 sbindir = @sbindir@
@@ -442,6 +442,10 @@ top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
 tss2_CFLAGS = @tss2_CFLAGS@
 tss2_LIBS = @tss2_LIBS@
+tss2_socket_CFLAGS = @tss2_socket_CFLAGS@
+tss2_socket_LIBS = @tss2_socket_LIBS@
+tss2_tabrmd_CFLAGS = @tss2_tabrmd_CFLAGS@
+tss2_tabrmd_LIBS = @tss2_tabrmd_LIBS@
 urandom_device = @urandom_device@
 xml_CFLAGS = @xml_CFLAGS@
 xml_LIBS = @xml_LIBS@
diff --git a/src/libstrongswan/plugins/bliss/Makefile.am b/src/libstrongswan/plugins/bliss/Makefile.am
index b2d0942..cbe4706 100644
--- a/src/libstrongswan/plugins/bliss/Makefile.am
+++ b/src/libstrongswan/plugins/bliss/Makefile.am
@@ -3,8 +3,7 @@ AM_CPPFLAGS = \
 	-I$(top_srcdir)/src/libstrongswan/math/libnttfft
 
 AM_CFLAGS = \
-	$(PLUGIN_CFLAGS) \
-	@COVERAGE_CFLAGS@
+	$(PLUGIN_CFLAGS)
 
 # these file are also used by bliss_huffman
 noinst_LTLIBRARIES = libbliss-params.la
diff --git a/src/libstrongswan/plugins/bliss/Makefile.in b/src/libstrongswan/plugins/bliss/Makefile.in
index a6caf7b..eb8eaec 100644
--- a/src/libstrongswan/plugins/bliss/Makefile.in
+++ b/src/libstrongswan/plugins/bliss/Makefile.in
@@ -335,8 +335,6 @@ RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
 RUBYGEMDIR = @RUBYGEMDIR@
-RUBYINCLUDE = @RUBYINCLUDE@
-RUBYLIB = @RUBYLIB@
 SED = @SED@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
@@ -437,6 +435,8 @@ random_device = @random_device@
 resolv_conf = @resolv_conf@
 routing_table = @routing_table@
 routing_table_prio = @routing_table_prio@
+ruby_CFLAGS = @ruby_CFLAGS@
+ruby_LIBS = @ruby_LIBS@
 runstatedir = @runstatedir@
 s_plugins = @s_plugins@
 sbindir = @sbindir@
@@ -465,6 +465,10 @@ top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
 tss2_CFLAGS = @tss2_CFLAGS@
 tss2_LIBS = @tss2_LIBS@
+tss2_socket_CFLAGS = @tss2_socket_CFLAGS@
+tss2_socket_LIBS = @tss2_socket_LIBS@
+tss2_tabrmd_CFLAGS = @tss2_tabrmd_CFLAGS@
+tss2_tabrmd_LIBS = @tss2_tabrmd_LIBS@
 urandom_device = @urandom_device@
 xml_CFLAGS = @xml_CFLAGS@
 xml_LIBS = @xml_LIBS@
@@ -473,8 +477,7 @@ AM_CPPFLAGS = \
 	-I$(top_srcdir)/src/libstrongswan/math/libnttfft
 
 AM_CFLAGS = \
-	$(PLUGIN_CFLAGS) \
-	@COVERAGE_CFLAGS@
+	$(PLUGIN_CFLAGS)
 
 
 # these file are also used by bliss_huffman
diff --git a/src/libstrongswan/plugins/bliss/tests/Makefile.in b/src/libstrongswan/plugins/bliss/tests/Makefile.in
index 5dbaf9b..a2d56cd 100644
--- a/src/libstrongswan/plugins/bliss/tests/Makefile.in
+++ b/src/libstrongswan/plugins/bliss/tests/Makefile.in
@@ -314,8 +314,6 @@ RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
 RUBYGEMDIR = @RUBYGEMDIR@
-RUBYINCLUDE = @RUBYINCLUDE@
-RUBYLIB = @RUBYLIB@
 SED = @SED@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
@@ -416,6 +414,8 @@ random_device = @random_device@
 resolv_conf = @resolv_conf@
 routing_table = @routing_table@
 routing_table_prio = @routing_table_prio@
+ruby_CFLAGS = @ruby_CFLAGS@
+ruby_LIBS = @ruby_LIBS@
 runstatedir = @runstatedir@
 s_plugins = @s_plugins@
 sbindir = @sbindir@
@@ -444,6 +444,10 @@ top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
 tss2_CFLAGS = @tss2_CFLAGS@
 tss2_LIBS = @tss2_LIBS@
+tss2_socket_CFLAGS = @tss2_socket_CFLAGS@
+tss2_socket_LIBS = @tss2_socket_LIBS@
+tss2_tabrmd_CFLAGS = @tss2_tabrmd_CFLAGS@
+tss2_tabrmd_LIBS = @tss2_tabrmd_LIBS@
 urandom_device = @urandom_device@
 xml_CFLAGS = @xml_CFLAGS@
 xml_LIBS = @xml_LIBS@
diff --git a/src/libstrongswan/plugins/blowfish/Makefile.in b/src/libstrongswan/plugins/blowfish/Makefile.in
index 0876475..0d091d1 100644
--- a/src/libstrongswan/plugins/blowfish/Makefile.in
+++ b/src/libstrongswan/plugins/blowfish/Makefile.in
@@ -313,8 +313,6 @@ RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
 RUBYGEMDIR = @RUBYGEMDIR@
-RUBYINCLUDE = @RUBYINCLUDE@
-RUBYLIB = @RUBYLIB@
 SED = @SED@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
@@ -415,6 +413,8 @@ random_device = @random_device@
 resolv_conf = @resolv_conf@
 routing_table = @routing_table@
 routing_table_prio = @routing_table_prio@
+ruby_CFLAGS = @ruby_CFLAGS@
+ruby_LIBS = @ruby_LIBS@
 runstatedir = @runstatedir@
 s_plugins = @s_plugins@
 sbindir = @sbindir@
@@ -443,6 +443,10 @@ top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
 tss2_CFLAGS = @tss2_CFLAGS@
 tss2_LIBS = @tss2_LIBS@
+tss2_socket_CFLAGS = @tss2_socket_CFLAGS@
+tss2_socket_LIBS = @tss2_socket_LIBS@
+tss2_tabrmd_CFLAGS = @tss2_tabrmd_CFLAGS@
+tss2_tabrmd_LIBS = @tss2_tabrmd_LIBS@
 urandom_device = @urandom_device@
 xml_CFLAGS = @xml_CFLAGS@
 xml_LIBS = @xml_LIBS@
diff --git a/src/libstrongswan/plugins/ccm/Makefile.in b/src/libstrongswan/plugins/ccm/Makefile.in
index 5f768ec..0084070 100644
--- a/src/libstrongswan/plugins/ccm/Makefile.in
+++ b/src/libstrongswan/plugins/ccm/Makefile.in
@@ -310,8 +310,6 @@ RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
 RUBYGEMDIR = @RUBYGEMDIR@
-RUBYINCLUDE = @RUBYINCLUDE@
-RUBYLIB = @RUBYLIB@
 SED = @SED@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
@@ -412,6 +410,8 @@ random_device = @random_device@
 resolv_conf = @resolv_conf@
 routing_table = @routing_table@
 routing_table_prio = @routing_table_prio@
+ruby_CFLAGS = @ruby_CFLAGS@
+ruby_LIBS = @ruby_LIBS@
 runstatedir = @runstatedir@
 s_plugins = @s_plugins@
 sbindir = @sbindir@
@@ -440,6 +440,10 @@ top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
 tss2_CFLAGS = @tss2_CFLAGS@
 tss2_LIBS = @tss2_LIBS@
+tss2_socket_CFLAGS = @tss2_socket_CFLAGS@
+tss2_socket_LIBS = @tss2_socket_LIBS@
+tss2_tabrmd_CFLAGS = @tss2_tabrmd_CFLAGS@
+tss2_tabrmd_LIBS = @tss2_tabrmd_LIBS@
 urandom_device = @urandom_device@
 xml_CFLAGS = @xml_CFLAGS@
 xml_LIBS = @xml_LIBS@
diff --git a/src/libstrongswan/plugins/chapoly/Makefile.in b/src/libstrongswan/plugins/chapoly/Makefile.in
index 12ad6f1..0b2998c 100644
--- a/src/libstrongswan/plugins/chapoly/Makefile.in
+++ b/src/libstrongswan/plugins/chapoly/Makefile.in
@@ -325,8 +325,6 @@ RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
 RUBYGEMDIR = @RUBYGEMDIR@
-RUBYINCLUDE = @RUBYINCLUDE@
-RUBYLIB = @RUBYLIB@
 SED = @SED@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
@@ -427,6 +425,8 @@ random_device = @random_device@
 resolv_conf = @resolv_conf@
 routing_table = @routing_table@
 routing_table_prio = @routing_table_prio@
+ruby_CFLAGS = @ruby_CFLAGS@
+ruby_LIBS = @ruby_LIBS@
 runstatedir = @runstatedir@
 s_plugins = @s_plugins@
 sbindir = @sbindir@
@@ -455,6 +455,10 @@ top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
 tss2_CFLAGS = @tss2_CFLAGS@
 tss2_LIBS = @tss2_LIBS@
+tss2_socket_CFLAGS = @tss2_socket_CFLAGS@
+tss2_socket_LIBS = @tss2_socket_LIBS@
+tss2_tabrmd_CFLAGS = @tss2_tabrmd_CFLAGS@
+tss2_tabrmd_LIBS = @tss2_tabrmd_LIBS@
 urandom_device = @urandom_device@
 xml_CFLAGS = @xml_CFLAGS@
 xml_LIBS = @xml_LIBS@
diff --git a/src/libstrongswan/plugins/cmac/Makefile.in b/src/libstrongswan/plugins/cmac/Makefile.in
index c6bb24a..2586d77 100644
--- a/src/libstrongswan/plugins/cmac/Makefile.in
+++ b/src/libstrongswan/plugins/cmac/Makefile.in
@@ -310,8 +310,6 @@ RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
 RUBYGEMDIR = @RUBYGEMDIR@
-RUBYINCLUDE = @RUBYINCLUDE@
-RUBYLIB = @RUBYLIB@
 SED = @SED@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
@@ -412,6 +410,8 @@ random_device = @random_device@
 resolv_conf = @resolv_conf@
 routing_table = @routing_table@
 routing_table_prio = @routing_table_prio@
+ruby_CFLAGS = @ruby_CFLAGS@
+ruby_LIBS = @ruby_LIBS@
 runstatedir = @runstatedir@
 s_plugins = @s_plugins@
 sbindir = @sbindir@
@@ -440,6 +440,10 @@ top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
 tss2_CFLAGS = @tss2_CFLAGS@
 tss2_LIBS = @tss2_LIBS@
+tss2_socket_CFLAGS = @tss2_socket_CFLAGS@
+tss2_socket_LIBS = @tss2_socket_LIBS@
+tss2_tabrmd_CFLAGS = @tss2_tabrmd_CFLAGS@
+tss2_tabrmd_LIBS = @tss2_tabrmd_LIBS@
 urandom_device = @urandom_device@
 xml_CFLAGS = @xml_CFLAGS@
 xml_LIBS = @xml_LIBS@
diff --git a/src/libstrongswan/plugins/constraints/Makefile.in b/src/libstrongswan/plugins/constraints/Makefile.in
index aa2fd79..25632d7 100644
--- a/src/libstrongswan/plugins/constraints/Makefile.in
+++ b/src/libstrongswan/plugins/constraints/Makefile.in
@@ -313,8 +313,6 @@ RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
 RUBYGEMDIR = @RUBYGEMDIR@
-RUBYINCLUDE = @RUBYINCLUDE@
-RUBYLIB = @RUBYLIB@
 SED = @SED@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
@@ -415,6 +413,8 @@ random_device = @random_device@
 resolv_conf = @resolv_conf@
 routing_table = @routing_table@
 routing_table_prio = @routing_table_prio@
+ruby_CFLAGS = @ruby_CFLAGS@
+ruby_LIBS = @ruby_LIBS@
 runstatedir = @runstatedir@
 s_plugins = @s_plugins@
 sbindir = @sbindir@
@@ -443,6 +443,10 @@ top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
 tss2_CFLAGS = @tss2_CFLAGS@
 tss2_LIBS = @tss2_LIBS@
+tss2_socket_CFLAGS = @tss2_socket_CFLAGS@
+tss2_socket_LIBS = @tss2_socket_LIBS@
+tss2_tabrmd_CFLAGS = @tss2_tabrmd_CFLAGS@
+tss2_tabrmd_LIBS = @tss2_tabrmd_LIBS@
 urandom_device = @urandom_device@
 xml_CFLAGS = @xml_CFLAGS@
 xml_LIBS = @xml_LIBS@
diff --git a/src/libstrongswan/plugins/ctr/Makefile.in b/src/libstrongswan/plugins/ctr/Makefile.in
index d112676..275a762 100644
--- a/src/libstrongswan/plugins/ctr/Makefile.in
+++ b/src/libstrongswan/plugins/ctr/Makefile.in
@@ -310,8 +310,6 @@ RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
 RUBYGEMDIR = @RUBYGEMDIR@
-RUBYINCLUDE = @RUBYINCLUDE@
-RUBYLIB = @RUBYLIB@
 SED = @SED@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
@@ -412,6 +410,8 @@ random_device = @random_device@
 resolv_conf = @resolv_conf@
 routing_table = @routing_table@
 routing_table_prio = @routing_table_prio@
+ruby_CFLAGS = @ruby_CFLAGS@
+ruby_LIBS = @ruby_LIBS@
 runstatedir = @runstatedir@
 s_plugins = @s_plugins@
 sbindir = @sbindir@
@@ -440,6 +440,10 @@ top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
 tss2_CFLAGS = @tss2_CFLAGS@
 tss2_LIBS = @tss2_LIBS@
+tss2_socket_CFLAGS = @tss2_socket_CFLAGS@
+tss2_socket_LIBS = @tss2_socket_LIBS@
+tss2_tabrmd_CFLAGS = @tss2_tabrmd_CFLAGS@
+tss2_tabrmd_LIBS = @tss2_tabrmd_LIBS@
 urandom_device = @urandom_device@
 xml_CFLAGS = @xml_CFLAGS@
 xml_LIBS = @xml_LIBS@
diff --git a/src/libstrongswan/plugins/curl/Makefile.in b/src/libstrongswan/plugins/curl/Makefile.in
index 2aedb2f..0dbcca8 100644
--- a/src/libstrongswan/plugins/curl/Makefile.in
+++ b/src/libstrongswan/plugins/curl/Makefile.in
@@ -310,8 +310,6 @@ RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
 RUBYGEMDIR = @RUBYGEMDIR@
-RUBYINCLUDE = @RUBYINCLUDE@
-RUBYLIB = @RUBYLIB@
 SED = @SED@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
@@ -412,6 +410,8 @@ random_device = @random_device@
 resolv_conf = @resolv_conf@
 routing_table = @routing_table@
 routing_table_prio = @routing_table_prio@
+ruby_CFLAGS = @ruby_CFLAGS@
+ruby_LIBS = @ruby_LIBS@
 runstatedir = @runstatedir@
 s_plugins = @s_plugins@
 sbindir = @sbindir@
@@ -440,6 +440,10 @@ top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
 tss2_CFLAGS = @tss2_CFLAGS@
 tss2_LIBS = @tss2_LIBS@
+tss2_socket_CFLAGS = @tss2_socket_CFLAGS@
+tss2_socket_LIBS = @tss2_socket_LIBS@
+tss2_tabrmd_CFLAGS = @tss2_tabrmd_CFLAGS@
+tss2_tabrmd_LIBS = @tss2_tabrmd_LIBS@
 urandom_device = @urandom_device@
 xml_CFLAGS = @xml_CFLAGS@
 xml_LIBS = @xml_LIBS@
diff --git a/src/libstrongswan/plugins/curl/curl_fetcher.c b/src/libstrongswan/plugins/curl/curl_fetcher.c
index 9207f11..b52b35b 100644
--- a/src/libstrongswan/plugins/curl/curl_fetcher.c
+++ b/src/libstrongswan/plugins/curl/curl_fetcher.c
@@ -58,6 +58,11 @@ struct private_curl_fetcher_t {
 	 * Timeout for a transfer
 	 */
 	long timeout;
+
+	/**
+	 * Maximum number of redirects to follow
+	 */
+	long redir;
 };
 
 /**
@@ -85,7 +90,7 @@ static size_t curl_cb(void *ptr, size_t size, size_t nmemb, cb_data_t *data)
 METHOD(fetcher_t, fetch, status_t,
 	private_curl_fetcher_t *this, char *uri, void *userdata)
 {
-	char error[CURL_ERROR_SIZE], *enc_uri;
+	char error[CURL_ERROR_SIZE], *enc_uri, *p1, *p2;
 	CURLcode curl_status;
 	status_t status;
 	long result = 0;
@@ -116,6 +121,8 @@ METHOD(fetcher_t, fetch, status_t,
 		curl_easy_setopt(this->curl, CURLOPT_TIMEOUT, this->timeout);
 	}
 	curl_easy_setopt(this->curl, CURLOPT_CONNECTTIMEOUT, CONNECT_TIMEOUT);
+	curl_easy_setopt(this->curl, CURLOPT_FOLLOWLOCATION, TRUE);
+	curl_easy_setopt(this->curl, CURLOPT_MAXREDIRS, this->redir);
 	curl_easy_setopt(this->curl, CURLOPT_WRITEFUNCTION, (void*)curl_cb);
 	curl_easy_setopt(this->curl, CURLOPT_WRITEDATA, &data);
 	if (this->headers)
@@ -123,7 +130,17 @@ METHOD(fetcher_t, fetch, status_t,
 		curl_easy_setopt(this->curl, CURLOPT_HTTPHEADER, this->headers);
 	}
 
-	DBG2(DBG_LIB, "  sending request to '%s'...", uri);
+	/* if the URI contains a username[:password] prefix then mask it */
+	p1 = strstr(uri, "://");
+	p2 = strchr(uri, '@');
+	if (p1 && p2)
+	{
+		DBG2(DBG_LIB, "  sending request to '%.*sxxxx%s'...", p1+3-uri, uri, p2);
+	}
+	else
+	{
+		DBG2(DBG_LIB, "  sending request to '%s'...", uri);
+	}
 	curl_status = curl_easy_perform(this->curl);
 	switch (curl_status)
 	{
@@ -250,6 +267,8 @@ curl_fetcher_t *curl_fetcher_create()
 		},
 		.curl = curl_easy_init(),
 		.cb = fetcher_default_callback,
+		.redir = lib->settings->get_int(lib->settings, "%s.plugins.curl.redir",
+										-1, lib->ns),
 	);
 
 	if (!this->curl)
diff --git a/src/libstrongswan/plugins/curve25519/Makefile.in b/src/libstrongswan/plugins/curve25519/Makefile.in
index 616f3d8..21b0e75 100644
--- a/src/libstrongswan/plugins/curve25519/Makefile.in
+++ b/src/libstrongswan/plugins/curve25519/Makefile.in
@@ -317,8 +317,6 @@ RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
 RUBYGEMDIR = @RUBYGEMDIR@
-RUBYINCLUDE = @RUBYINCLUDE@
-RUBYLIB = @RUBYLIB@
 SED = @SED@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
@@ -419,6 +417,8 @@ random_device = @random_device@
 resolv_conf = @resolv_conf@
 routing_table = @routing_table@
 routing_table_prio = @routing_table_prio@
+ruby_CFLAGS = @ruby_CFLAGS@
+ruby_LIBS = @ruby_LIBS@
 runstatedir = @runstatedir@
 s_plugins = @s_plugins@
 sbindir = @sbindir@
@@ -447,6 +447,10 @@ top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
 tss2_CFLAGS = @tss2_CFLAGS@
 tss2_LIBS = @tss2_LIBS@
+tss2_socket_CFLAGS = @tss2_socket_CFLAGS@
+tss2_socket_LIBS = @tss2_socket_LIBS@
+tss2_tabrmd_CFLAGS = @tss2_tabrmd_CFLAGS@
+tss2_tabrmd_LIBS = @tss2_tabrmd_LIBS@
 urandom_device = @urandom_device@
 xml_CFLAGS = @xml_CFLAGS@
 xml_LIBS = @xml_LIBS@
diff --git a/src/libstrongswan/plugins/des/Makefile.in b/src/libstrongswan/plugins/des/Makefile.in
index c3f3775..89b2798 100644
--- a/src/libstrongswan/plugins/des/Makefile.in
+++ b/src/libstrongswan/plugins/des/Makefile.in
@@ -310,8 +310,6 @@ RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
 RUBYGEMDIR = @RUBYGEMDIR@
-RUBYINCLUDE = @RUBYINCLUDE@
-RUBYLIB = @RUBYLIB@
 SED = @SED@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
@@ -412,6 +410,8 @@ random_device = @random_device@
 resolv_conf = @resolv_conf@
 routing_table = @routing_table@
 routing_table_prio = @routing_table_prio@
+ruby_CFLAGS = @ruby_CFLAGS@
+ruby_LIBS = @ruby_LIBS@
 runstatedir = @runstatedir@
 s_plugins = @s_plugins@
 sbindir = @sbindir@
@@ -440,6 +440,10 @@ top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
 tss2_CFLAGS = @tss2_CFLAGS@
 tss2_LIBS = @tss2_LIBS@
+tss2_socket_CFLAGS = @tss2_socket_CFLAGS@
+tss2_socket_LIBS = @tss2_socket_LIBS@
+tss2_tabrmd_CFLAGS = @tss2_tabrmd_CFLAGS@
+tss2_tabrmd_LIBS = @tss2_tabrmd_LIBS@
 urandom_device = @urandom_device@
 xml_CFLAGS = @xml_CFLAGS@
 xml_LIBS = @xml_LIBS@
diff --git a/src/libstrongswan/plugins/dnskey/Makefile.in b/src/libstrongswan/plugins/dnskey/Makefile.in
index 26c69e2..385749a 100644
--- a/src/libstrongswan/plugins/dnskey/Makefile.in
+++ b/src/libstrongswan/plugins/dnskey/Makefile.in
@@ -313,8 +313,6 @@ RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
 RUBYGEMDIR = @RUBYGEMDIR@
-RUBYINCLUDE = @RUBYINCLUDE@
-RUBYLIB = @RUBYLIB@
 SED = @SED@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
@@ -415,6 +413,8 @@ random_device = @random_device@
 resolv_conf = @resolv_conf@
 routing_table = @routing_table@
 routing_table_prio = @routing_table_prio@
+ruby_CFLAGS = @ruby_CFLAGS@
+ruby_LIBS = @ruby_LIBS@
 runstatedir = @runstatedir@
 s_plugins = @s_plugins@
 sbindir = @sbindir@
@@ -443,6 +443,10 @@ top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
 tss2_CFLAGS = @tss2_CFLAGS@
 tss2_LIBS = @tss2_LIBS@
+tss2_socket_CFLAGS = @tss2_socket_CFLAGS@
+tss2_socket_LIBS = @tss2_socket_LIBS@
+tss2_tabrmd_CFLAGS = @tss2_tabrmd_CFLAGS@
+tss2_tabrmd_LIBS = @tss2_tabrmd_LIBS@
 urandom_device = @urandom_device@
 xml_CFLAGS = @xml_CFLAGS@
 xml_LIBS = @xml_LIBS@
diff --git a/src/libstrongswan/plugins/files/Makefile.in b/src/libstrongswan/plugins/files/Makefile.in
index d8c7dae..7708f95 100644
--- a/src/libstrongswan/plugins/files/Makefile.in
+++ b/src/libstrongswan/plugins/files/Makefile.in
@@ -311,8 +311,6 @@ RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
 RUBYGEMDIR = @RUBYGEMDIR@
-RUBYINCLUDE = @RUBYINCLUDE@
-RUBYLIB = @RUBYLIB@
 SED = @SED@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
@@ -413,6 +411,8 @@ random_device = @random_device@
 resolv_conf = @resolv_conf@
 routing_table = @routing_table@
 routing_table_prio = @routing_table_prio@
+ruby_CFLAGS = @ruby_CFLAGS@
+ruby_LIBS = @ruby_LIBS@
 runstatedir = @runstatedir@
 s_plugins = @s_plugins@
 sbindir = @sbindir@
@@ -441,6 +441,10 @@ top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
 tss2_CFLAGS = @tss2_CFLAGS@
 tss2_LIBS = @tss2_LIBS@
+tss2_socket_CFLAGS = @tss2_socket_CFLAGS@
+tss2_socket_LIBS = @tss2_socket_LIBS@
+tss2_tabrmd_CFLAGS = @tss2_tabrmd_CFLAGS@
+tss2_tabrmd_LIBS = @tss2_tabrmd_LIBS@
 urandom_device = @urandom_device@
 xml_CFLAGS = @xml_CFLAGS@
 xml_LIBS = @xml_LIBS@
diff --git a/src/libstrongswan/plugins/fips_prf/Makefile.in b/src/libstrongswan/plugins/fips_prf/Makefile.in
index 45934d7..478ae81 100644
--- a/src/libstrongswan/plugins/fips_prf/Makefile.in
+++ b/src/libstrongswan/plugins/fips_prf/Makefile.in
@@ -312,8 +312,6 @@ RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
 RUBYGEMDIR = @RUBYGEMDIR@
-RUBYINCLUDE = @RUBYINCLUDE@
-RUBYLIB = @RUBYLIB@
 SED = @SED@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
@@ -414,6 +412,8 @@ random_device = @random_device@
 resolv_conf = @resolv_conf@
 routing_table = @routing_table@
 routing_table_prio = @routing_table_prio@
+ruby_CFLAGS = @ruby_CFLAGS@
+ruby_LIBS = @ruby_LIBS@
 runstatedir = @runstatedir@
 s_plugins = @s_plugins@
 sbindir = @sbindir@
@@ -442,6 +442,10 @@ top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
 tss2_CFLAGS = @tss2_CFLAGS@
 tss2_LIBS = @tss2_LIBS@
+tss2_socket_CFLAGS = @tss2_socket_CFLAGS@
+tss2_socket_LIBS = @tss2_socket_LIBS@
+tss2_tabrmd_CFLAGS = @tss2_tabrmd_CFLAGS@
+tss2_tabrmd_LIBS = @tss2_tabrmd_LIBS@
 urandom_device = @urandom_device@
 xml_CFLAGS = @xml_CFLAGS@
 xml_LIBS = @xml_LIBS@
diff --git a/src/libstrongswan/plugins/gcm/Makefile.in b/src/libstrongswan/plugins/gcm/Makefile.in
index 5d6c1a4..91ea7c6 100644
--- a/src/libstrongswan/plugins/gcm/Makefile.in
+++ b/src/libstrongswan/plugins/gcm/Makefile.in
@@ -310,8 +310,6 @@ RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
 RUBYGEMDIR = @RUBYGEMDIR@
-RUBYINCLUDE = @RUBYINCLUDE@
-RUBYLIB = @RUBYLIB@
 SED = @SED@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
@@ -412,6 +410,8 @@ random_device = @random_device@
 resolv_conf = @resolv_conf@
 routing_table = @routing_table@
 routing_table_prio = @routing_table_prio@
+ruby_CFLAGS = @ruby_CFLAGS@
+ruby_LIBS = @ruby_LIBS@
 runstatedir = @runstatedir@
 s_plugins = @s_plugins@
 sbindir = @sbindir@
@@ -440,6 +440,10 @@ top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
 tss2_CFLAGS = @tss2_CFLAGS@
 tss2_LIBS = @tss2_LIBS@
+tss2_socket_CFLAGS = @tss2_socket_CFLAGS@
+tss2_socket_LIBS = @tss2_socket_LIBS@
+tss2_tabrmd_CFLAGS = @tss2_tabrmd_CFLAGS@
+tss2_tabrmd_LIBS = @tss2_tabrmd_LIBS@
 urandom_device = @urandom_device@
 xml_CFLAGS = @xml_CFLAGS@
 xml_LIBS = @xml_LIBS@
diff --git a/src/libstrongswan/plugins/gcrypt/Makefile.in b/src/libstrongswan/plugins/gcrypt/Makefile.in
index 26930dc..2212be0 100644
--- a/src/libstrongswan/plugins/gcrypt/Makefile.in
+++ b/src/libstrongswan/plugins/gcrypt/Makefile.in
@@ -314,8 +314,6 @@ RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
 RUBYGEMDIR = @RUBYGEMDIR@
-RUBYINCLUDE = @RUBYINCLUDE@
-RUBYLIB = @RUBYLIB@
 SED = @SED@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
@@ -416,6 +414,8 @@ random_device = @random_device@
 resolv_conf = @resolv_conf@
 routing_table = @routing_table@
 routing_table_prio = @routing_table_prio@
+ruby_CFLAGS = @ruby_CFLAGS@
+ruby_LIBS = @ruby_LIBS@
 runstatedir = @runstatedir@
 s_plugins = @s_plugins@
 sbindir = @sbindir@
@@ -444,6 +444,10 @@ top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
 tss2_CFLAGS = @tss2_CFLAGS@
 tss2_LIBS = @tss2_LIBS@
+tss2_socket_CFLAGS = @tss2_socket_CFLAGS@
+tss2_socket_LIBS = @tss2_socket_LIBS@
+tss2_tabrmd_CFLAGS = @tss2_tabrmd_CFLAGS@
+tss2_tabrmd_LIBS = @tss2_tabrmd_LIBS@
 urandom_device = @urandom_device@
 xml_CFLAGS = @xml_CFLAGS@
 xml_LIBS = @xml_LIBS@
diff --git a/src/libstrongswan/plugins/gmp/Makefile.in b/src/libstrongswan/plugins/gmp/Makefile.in
index 2fcdce7..39a2bca 100644
--- a/src/libstrongswan/plugins/gmp/Makefile.in
+++ b/src/libstrongswan/plugins/gmp/Makefile.in
@@ -311,8 +311,6 @@ RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
 RUBYGEMDIR = @RUBYGEMDIR@
-RUBYINCLUDE = @RUBYINCLUDE@
-RUBYLIB = @RUBYLIB@
 SED = @SED@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
@@ -413,6 +411,8 @@ random_device = @random_device@
 resolv_conf = @resolv_conf@
 routing_table = @routing_table@
 routing_table_prio = @routing_table_prio@
+ruby_CFLAGS = @ruby_CFLAGS@
+ruby_LIBS = @ruby_LIBS@
 runstatedir = @runstatedir@
 s_plugins = @s_plugins@
 sbindir = @sbindir@
@@ -441,6 +441,10 @@ top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
 tss2_CFLAGS = @tss2_CFLAGS@
 tss2_LIBS = @tss2_LIBS@
+tss2_socket_CFLAGS = @tss2_socket_CFLAGS@
+tss2_socket_LIBS = @tss2_socket_LIBS@
+tss2_tabrmd_CFLAGS = @tss2_tabrmd_CFLAGS@
+tss2_tabrmd_LIBS = @tss2_tabrmd_LIBS@
 urandom_device = @urandom_device@
 xml_CFLAGS = @xml_CFLAGS@
 xml_LIBS = @xml_LIBS@
diff --git a/src/libstrongswan/plugins/gmp/gmp_rsa_public_key.c b/src/libstrongswan/plugins/gmp/gmp_rsa_public_key.c
index 32a72ac..065c889 100644
--- a/src/libstrongswan/plugins/gmp/gmp_rsa_public_key.c
+++ b/src/libstrongswan/plugins/gmp/gmp_rsa_public_key.c
@@ -78,11 +78,17 @@ static chunk_t rsaep(private_gmp_rsa_public_key_t *this, chunk_t data)
 	mpz_t m, c;
 	chunk_t encrypted;
 
-	mpz_init(c);
 	mpz_init(m);
-
 	mpz_import(m, data.len, 1, 1, 1, 0, data.ptr);
 
+	if (mpz_cmp_ui(m, 0) <= 0 || mpz_cmp(m, this->n) >= 0)
+	{	/* m must be <= n-1, and while 0 is technically a valid value, it
+		 * doesn't really make sense here, so we filter that too */
+		mpz_clear(m);
+		return chunk_empty;
+	}
+
+	mpz_init(c);
 	mpz_powm(c, m, this->e, this->n);
 
 	encrypted.len = this->k;
@@ -150,7 +156,7 @@ static bool verify_emsa_pkcs1_signature(private_gmp_rsa_public_key_t *this,
 	 */
 
 	/* check magic bytes */
-	if (*(em.ptr) != 0x00 || *(em.ptr+1) != 0x01)
+	if (em.len < 2 || *(em.ptr) != 0x00 || *(em.ptr+1) != 0x01)
 	{
 		goto end;
 	}
diff --git a/src/libstrongswan/plugins/hmac/Makefile.in b/src/libstrongswan/plugins/hmac/Makefile.in
index aa64015..cddeace 100644
--- a/src/libstrongswan/plugins/hmac/Makefile.in
+++ b/src/libstrongswan/plugins/hmac/Makefile.in
@@ -310,8 +310,6 @@ RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
 RUBYGEMDIR = @RUBYGEMDIR@
-RUBYINCLUDE = @RUBYINCLUDE@
-RUBYLIB = @RUBYLIB@
 SED = @SED@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
@@ -412,6 +410,8 @@ random_device = @random_device@
 resolv_conf = @resolv_conf@
 routing_table = @routing_table@
 routing_table_prio = @routing_table_prio@
+ruby_CFLAGS = @ruby_CFLAGS@
+ruby_LIBS = @ruby_LIBS@
 runstatedir = @runstatedir@
 s_plugins = @s_plugins@
 sbindir = @sbindir@
@@ -440,6 +440,10 @@ top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
 tss2_CFLAGS = @tss2_CFLAGS@
 tss2_LIBS = @tss2_LIBS@
+tss2_socket_CFLAGS = @tss2_socket_CFLAGS@
+tss2_socket_LIBS = @tss2_socket_LIBS@
+tss2_tabrmd_CFLAGS = @tss2_tabrmd_CFLAGS@
+tss2_tabrmd_LIBS = @tss2_tabrmd_LIBS@
 urandom_device = @urandom_device@
 xml_CFLAGS = @xml_CFLAGS@
 xml_LIBS = @xml_LIBS@
diff --git a/src/libstrongswan/plugins/keychain/Makefile.in b/src/libstrongswan/plugins/keychain/Makefile.in
index c9e4e40..e072c92 100644
--- a/src/libstrongswan/plugins/keychain/Makefile.in
+++ b/src/libstrongswan/plugins/keychain/Makefile.in
@@ -313,8 +313,6 @@ RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
 RUBYGEMDIR = @RUBYGEMDIR@
-RUBYINCLUDE = @RUBYINCLUDE@
-RUBYLIB = @RUBYLIB@
 SED = @SED@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
@@ -415,6 +413,8 @@ random_device = @random_device@
 resolv_conf = @resolv_conf@
 routing_table = @routing_table@
 routing_table_prio = @routing_table_prio@
+ruby_CFLAGS = @ruby_CFLAGS@
+ruby_LIBS = @ruby_LIBS@
 runstatedir = @runstatedir@
 s_plugins = @s_plugins@
 sbindir = @sbindir@
@@ -443,6 +443,10 @@ top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
 tss2_CFLAGS = @tss2_CFLAGS@
 tss2_LIBS = @tss2_LIBS@
+tss2_socket_CFLAGS = @tss2_socket_CFLAGS@
+tss2_socket_LIBS = @tss2_socket_LIBS@
+tss2_tabrmd_CFLAGS = @tss2_tabrmd_CFLAGS@
+tss2_tabrmd_LIBS = @tss2_tabrmd_LIBS@
 urandom_device = @urandom_device@
 xml_CFLAGS = @xml_CFLAGS@
 xml_LIBS = @xml_LIBS@
diff --git a/src/libstrongswan/plugins/ldap/Makefile.in b/src/libstrongswan/plugins/ldap/Makefile.in
index 1f4d447..229a0ca 100644
--- a/src/libstrongswan/plugins/ldap/Makefile.in
+++ b/src/libstrongswan/plugins/ldap/Makefile.in
@@ -310,8 +310,6 @@ RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
 RUBYGEMDIR = @RUBYGEMDIR@
-RUBYINCLUDE = @RUBYINCLUDE@
-RUBYLIB = @RUBYLIB@
 SED = @SED@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
@@ -412,6 +410,8 @@ random_device = @random_device@
 resolv_conf = @resolv_conf@
 routing_table = @routing_table@
 routing_table_prio = @routing_table_prio@
+ruby_CFLAGS = @ruby_CFLAGS@
+ruby_LIBS = @ruby_LIBS@
 runstatedir = @runstatedir@
 s_plugins = @s_plugins@
 sbindir = @sbindir@
@@ -440,6 +440,10 @@ top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
 tss2_CFLAGS = @tss2_CFLAGS@
 tss2_LIBS = @tss2_LIBS@
+tss2_socket_CFLAGS = @tss2_socket_CFLAGS@
+tss2_socket_LIBS = @tss2_socket_LIBS@
+tss2_tabrmd_CFLAGS = @tss2_tabrmd_CFLAGS@
+tss2_tabrmd_LIBS = @tss2_tabrmd_LIBS@
 urandom_device = @urandom_device@
 xml_CFLAGS = @xml_CFLAGS@
 xml_LIBS = @xml_LIBS@
diff --git a/src/libstrongswan/plugins/md4/Makefile.in b/src/libstrongswan/plugins/md4/Makefile.in
index eb9426c..d135c29 100644
--- a/src/libstrongswan/plugins/md4/Makefile.in
+++ b/src/libstrongswan/plugins/md4/Makefile.in
@@ -310,8 +310,6 @@ RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
 RUBYGEMDIR = @RUBYGEMDIR@
-RUBYINCLUDE = @RUBYINCLUDE@
-RUBYLIB = @RUBYLIB@
 SED = @SED@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
@@ -412,6 +410,8 @@ random_device = @random_device@
 resolv_conf = @resolv_conf@
 routing_table = @routing_table@
 routing_table_prio = @routing_table_prio@
+ruby_CFLAGS = @ruby_CFLAGS@
+ruby_LIBS = @ruby_LIBS@
 runstatedir = @runstatedir@
 s_plugins = @s_plugins@
 sbindir = @sbindir@
@@ -440,6 +440,10 @@ top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
 tss2_CFLAGS = @tss2_CFLAGS@
 tss2_LIBS = @tss2_LIBS@
+tss2_socket_CFLAGS = @tss2_socket_CFLAGS@
+tss2_socket_LIBS = @tss2_socket_LIBS@
+tss2_tabrmd_CFLAGS = @tss2_tabrmd_CFLAGS@
+tss2_tabrmd_LIBS = @tss2_tabrmd_LIBS@
 urandom_device = @urandom_device@
 xml_CFLAGS = @xml_CFLAGS@
 xml_LIBS = @xml_LIBS@
diff --git a/src/libstrongswan/plugins/md5/Makefile.in b/src/libstrongswan/plugins/md5/Makefile.in
index eaafd9f..e81213c 100644
--- a/src/libstrongswan/plugins/md5/Makefile.in
+++ b/src/libstrongswan/plugins/md5/Makefile.in
@@ -310,8 +310,6 @@ RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
 RUBYGEMDIR = @RUBYGEMDIR@
-RUBYINCLUDE = @RUBYINCLUDE@
-RUBYLIB = @RUBYLIB@
 SED = @SED@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
@@ -412,6 +410,8 @@ random_device = @random_device@
 resolv_conf = @resolv_conf@
 routing_table = @routing_table@
 routing_table_prio = @routing_table_prio@
+ruby_CFLAGS = @ruby_CFLAGS@
+ruby_LIBS = @ruby_LIBS@
 runstatedir = @runstatedir@
 s_plugins = @s_plugins@
 sbindir = @sbindir@
@@ -440,6 +440,10 @@ top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
 tss2_CFLAGS = @tss2_CFLAGS@
 tss2_LIBS = @tss2_LIBS@
+tss2_socket_CFLAGS = @tss2_socket_CFLAGS@
+tss2_socket_LIBS = @tss2_socket_LIBS@
+tss2_tabrmd_CFLAGS = @tss2_tabrmd_CFLAGS@
+tss2_tabrmd_LIBS = @tss2_tabrmd_LIBS@
 urandom_device = @urandom_device@
 xml_CFLAGS = @xml_CFLAGS@
 xml_LIBS = @xml_LIBS@
diff --git a/src/libstrongswan/plugins/mgf1/Makefile.in b/src/libstrongswan/plugins/mgf1/Makefile.in
index 991c542..8a27883 100644
--- a/src/libstrongswan/plugins/mgf1/Makefile.in
+++ b/src/libstrongswan/plugins/mgf1/Makefile.in
@@ -310,8 +310,6 @@ RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
 RUBYGEMDIR = @RUBYGEMDIR@
-RUBYINCLUDE = @RUBYINCLUDE@
-RUBYLIB = @RUBYLIB@
 SED = @SED@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
@@ -412,6 +410,8 @@ random_device = @random_device@
 resolv_conf = @resolv_conf@
 routing_table = @routing_table@
 routing_table_prio = @routing_table_prio@
+ruby_CFLAGS = @ruby_CFLAGS@
+ruby_LIBS = @ruby_LIBS@
 runstatedir = @runstatedir@
 s_plugins = @s_plugins@
 sbindir = @sbindir@
@@ -440,6 +440,10 @@ top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
 tss2_CFLAGS = @tss2_CFLAGS@
 tss2_LIBS = @tss2_LIBS@
+tss2_socket_CFLAGS = @tss2_socket_CFLAGS@
+tss2_socket_LIBS = @tss2_socket_LIBS@
+tss2_tabrmd_CFLAGS = @tss2_tabrmd_CFLAGS@
+tss2_tabrmd_LIBS = @tss2_tabrmd_LIBS@
 urandom_device = @urandom_device@
 xml_CFLAGS = @xml_CFLAGS@
 xml_LIBS = @xml_LIBS@
diff --git a/src/libstrongswan/plugins/mysql/Makefile.in b/src/libstrongswan/plugins/mysql/Makefile.in
index d549f2e..c99e4f8 100644
--- a/src/libstrongswan/plugins/mysql/Makefile.in
+++ b/src/libstrongswan/plugins/mysql/Makefile.in
@@ -312,8 +312,6 @@ RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
 RUBYGEMDIR = @RUBYGEMDIR@
-RUBYINCLUDE = @RUBYINCLUDE@
-RUBYLIB = @RUBYLIB@
 SED = @SED@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
@@ -414,6 +412,8 @@ random_device = @random_device@
 resolv_conf = @resolv_conf@
 routing_table = @routing_table@
 routing_table_prio = @routing_table_prio@
+ruby_CFLAGS = @ruby_CFLAGS@
+ruby_LIBS = @ruby_LIBS@
 runstatedir = @runstatedir@
 s_plugins = @s_plugins@
 sbindir = @sbindir@
@@ -442,6 +442,10 @@ top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
 tss2_CFLAGS = @tss2_CFLAGS@
 tss2_LIBS = @tss2_LIBS@
+tss2_socket_CFLAGS = @tss2_socket_CFLAGS@
+tss2_socket_LIBS = @tss2_socket_LIBS@
+tss2_tabrmd_CFLAGS = @tss2_tabrmd_CFLAGS@
+tss2_tabrmd_LIBS = @tss2_tabrmd_LIBS@
 urandom_device = @urandom_device@
 xml_CFLAGS = @xml_CFLAGS@
 xml_LIBS = @xml_LIBS@
diff --git a/src/libstrongswan/plugins/newhope/Makefile.am b/src/libstrongswan/plugins/newhope/Makefile.am
index b01987d..8dd6c5f 100644
--- a/src/libstrongswan/plugins/newhope/Makefile.am
+++ b/src/libstrongswan/plugins/newhope/Makefile.am
@@ -3,8 +3,7 @@ AM_CPPFLAGS = \
 	-I$(top_srcdir)/src/libstrongswan/math/libnttfft
 
 AM_CFLAGS = \
-	$(PLUGIN_CFLAGS) \
-	@COVERAGE_CFLAGS@
+	$(PLUGIN_CFLAGS)
 
 # these files are also used by the tests, we can't directly refer to them
 # because of the subdirectory, which would cause distclean to fail
diff --git a/src/libstrongswan/plugins/newhope/Makefile.in b/src/libstrongswan/plugins/newhope/Makefile.in
index a884b30..7863374 100644
--- a/src/libstrongswan/plugins/newhope/Makefile.in
+++ b/src/libstrongswan/plugins/newhope/Makefile.in
@@ -319,8 +319,6 @@ RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
 RUBYGEMDIR = @RUBYGEMDIR@
-RUBYINCLUDE = @RUBYINCLUDE@
-RUBYLIB = @RUBYLIB@
 SED = @SED@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
@@ -421,6 +419,8 @@ random_device = @random_device@
 resolv_conf = @resolv_conf@
 routing_table = @routing_table@
 routing_table_prio = @routing_table_prio@
+ruby_CFLAGS = @ruby_CFLAGS@
+ruby_LIBS = @ruby_LIBS@
 runstatedir = @runstatedir@
 s_plugins = @s_plugins@
 sbindir = @sbindir@
@@ -449,6 +449,10 @@ top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
 tss2_CFLAGS = @tss2_CFLAGS@
 tss2_LIBS = @tss2_LIBS@
+tss2_socket_CFLAGS = @tss2_socket_CFLAGS@
+tss2_socket_LIBS = @tss2_socket_LIBS@
+tss2_tabrmd_CFLAGS = @tss2_tabrmd_CFLAGS@
+tss2_tabrmd_LIBS = @tss2_tabrmd_LIBS@
 urandom_device = @urandom_device@
 xml_CFLAGS = @xml_CFLAGS@
 xml_LIBS = @xml_LIBS@
@@ -457,8 +461,7 @@ AM_CPPFLAGS = \
 	-I$(top_srcdir)/src/libstrongswan/math/libnttfft
 
 AM_CFLAGS = \
-	$(PLUGIN_CFLAGS) \
-	@COVERAGE_CFLAGS@
+	$(PLUGIN_CFLAGS)
 
 
 # these files are also used by the tests, we can't directly refer to them
diff --git a/src/libstrongswan/plugins/newhope/tests/Makefile.in b/src/libstrongswan/plugins/newhope/tests/Makefile.in
index 80fcf4d..be6ffef 100644
--- a/src/libstrongswan/plugins/newhope/tests/Makefile.in
+++ b/src/libstrongswan/plugins/newhope/tests/Makefile.in
@@ -311,8 +311,6 @@ RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
 RUBYGEMDIR = @RUBYGEMDIR@
-RUBYINCLUDE = @RUBYINCLUDE@
-RUBYLIB = @RUBYLIB@
 SED = @SED@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
@@ -413,6 +411,8 @@ random_device = @random_device@
 resolv_conf = @resolv_conf@
 routing_table = @routing_table@
 routing_table_prio = @routing_table_prio@
+ruby_CFLAGS = @ruby_CFLAGS@
+ruby_LIBS = @ruby_LIBS@
 runstatedir = @runstatedir@
 s_plugins = @s_plugins@
 sbindir = @sbindir@
@@ -441,6 +441,10 @@ top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
 tss2_CFLAGS = @tss2_CFLAGS@
 tss2_LIBS = @tss2_LIBS@
+tss2_socket_CFLAGS = @tss2_socket_CFLAGS@
+tss2_socket_LIBS = @tss2_socket_LIBS@
+tss2_tabrmd_CFLAGS = @tss2_tabrmd_CFLAGS@
+tss2_tabrmd_LIBS = @tss2_tabrmd_LIBS@
 urandom_device = @urandom_device@
 xml_CFLAGS = @xml_CFLAGS@
 xml_LIBS = @xml_LIBS@
diff --git a/src/libstrongswan/plugins/nonce/Makefile.in b/src/libstrongswan/plugins/nonce/Makefile.in
index 783eaf4..fca8309 100644
--- a/src/libstrongswan/plugins/nonce/Makefile.in
+++ b/src/libstrongswan/plugins/nonce/Makefile.in
@@ -311,8 +311,6 @@ RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
 RUBYGEMDIR = @RUBYGEMDIR@
-RUBYINCLUDE = @RUBYINCLUDE@
-RUBYLIB = @RUBYLIB@
 SED = @SED@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
@@ -413,6 +411,8 @@ random_device = @random_device@
 resolv_conf = @resolv_conf@
 routing_table = @routing_table@
 routing_table_prio = @routing_table_prio@
+ruby_CFLAGS = @ruby_CFLAGS@
+ruby_LIBS = @ruby_LIBS@
 runstatedir = @runstatedir@
 s_plugins = @s_plugins@
 sbindir = @sbindir@
@@ -441,6 +441,10 @@ top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
 tss2_CFLAGS = @tss2_CFLAGS@
 tss2_LIBS = @tss2_LIBS@
+tss2_socket_CFLAGS = @tss2_socket_CFLAGS@
+tss2_socket_LIBS = @tss2_socket_LIBS@
+tss2_tabrmd_CFLAGS = @tss2_tabrmd_CFLAGS@
+tss2_tabrmd_LIBS = @tss2_tabrmd_LIBS@
 urandom_device = @urandom_device@
 xml_CFLAGS = @xml_CFLAGS@
 xml_LIBS = @xml_LIBS@
diff --git a/src/libstrongswan/plugins/ntru/Makefile.am b/src/libstrongswan/plugins/ntru/Makefile.am
index c9fcee9..4045544 100644
--- a/src/libstrongswan/plugins/ntru/Makefile.am
+++ b/src/libstrongswan/plugins/ntru/Makefile.am
@@ -2,8 +2,7 @@ AM_CPPFLAGS = \
 	-I$(top_srcdir)/src/libstrongswan
 
 AM_CFLAGS = \
-	$(PLUGIN_CFLAGS) \
-	@COVERAGE_CFLAGS@
+	$(PLUGIN_CFLAGS)
 
 if MONOLITHIC
 noinst_LTLIBRARIES = libstrongswan-ntru.la
diff --git a/src/libstrongswan/plugins/ntru/Makefile.in b/src/libstrongswan/plugins/ntru/Makefile.in
index 41ec4ce..2ef9aa8 100644
--- a/src/libstrongswan/plugins/ntru/Makefile.in
+++ b/src/libstrongswan/plugins/ntru/Makefile.in
@@ -312,8 +312,6 @@ RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
 RUBYGEMDIR = @RUBYGEMDIR@
-RUBYINCLUDE = @RUBYINCLUDE@
-RUBYLIB = @RUBYLIB@
 SED = @SED@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
@@ -414,6 +412,8 @@ random_device = @random_device@
 resolv_conf = @resolv_conf@
 routing_table = @routing_table@
 routing_table_prio = @routing_table_prio@
+ruby_CFLAGS = @ruby_CFLAGS@
+ruby_LIBS = @ruby_LIBS@
 runstatedir = @runstatedir@
 s_plugins = @s_plugins@
 sbindir = @sbindir@
@@ -442,6 +442,10 @@ top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
 tss2_CFLAGS = @tss2_CFLAGS@
 tss2_LIBS = @tss2_LIBS@
+tss2_socket_CFLAGS = @tss2_socket_CFLAGS@
+tss2_socket_LIBS = @tss2_socket_LIBS@
+tss2_tabrmd_CFLAGS = @tss2_tabrmd_CFLAGS@
+tss2_tabrmd_LIBS = @tss2_tabrmd_LIBS@
 urandom_device = @urandom_device@
 xml_CFLAGS = @xml_CFLAGS@
 xml_LIBS = @xml_LIBS@
@@ -449,8 +453,7 @@ AM_CPPFLAGS = \
 	-I$(top_srcdir)/src/libstrongswan
 
 AM_CFLAGS = \
-	$(PLUGIN_CFLAGS) \
-	@COVERAGE_CFLAGS@
+	$(PLUGIN_CFLAGS)
 
 @MONOLITHIC_TRUE at noinst_LTLIBRARIES = libstrongswan-ntru.la
 @MONOLITHIC_FALSE at plugin_LTLIBRARIES = libstrongswan-ntru.la
diff --git a/src/libstrongswan/plugins/openssl/Makefile.in b/src/libstrongswan/plugins/openssl/Makefile.in
index 9c05236..dcf4c2c 100644
--- a/src/libstrongswan/plugins/openssl/Makefile.in
+++ b/src/libstrongswan/plugins/openssl/Makefile.in
@@ -320,8 +320,6 @@ RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
 RUBYGEMDIR = @RUBYGEMDIR@
-RUBYINCLUDE = @RUBYINCLUDE@
-RUBYLIB = @RUBYLIB@
 SED = @SED@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
@@ -422,6 +420,8 @@ random_device = @random_device@
 resolv_conf = @resolv_conf@
 routing_table = @routing_table@
 routing_table_prio = @routing_table_prio@
+ruby_CFLAGS = @ruby_CFLAGS@
+ruby_LIBS = @ruby_LIBS@
 runstatedir = @runstatedir@
 s_plugins = @s_plugins@
 sbindir = @sbindir@
@@ -450,6 +450,10 @@ top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
 tss2_CFLAGS = @tss2_CFLAGS@
 tss2_LIBS = @tss2_LIBS@
+tss2_socket_CFLAGS = @tss2_socket_CFLAGS@
+tss2_socket_LIBS = @tss2_socket_LIBS@
+tss2_tabrmd_CFLAGS = @tss2_tabrmd_CFLAGS@
+tss2_tabrmd_LIBS = @tss2_tabrmd_LIBS@
 urandom_device = @urandom_device@
 xml_CFLAGS = @xml_CFLAGS@
 xml_LIBS = @xml_LIBS@
diff --git a/src/libstrongswan/plugins/openssl/openssl_x509.c b/src/libstrongswan/plugins/openssl/openssl_x509.c
index e95eb72..e03a425 100644
--- a/src/libstrongswan/plugins/openssl/openssl_x509.c
+++ b/src/libstrongswan/plugins/openssl/openssl_x509.c
@@ -686,15 +686,13 @@ static bool parse_keyUsage_ext(private_openssl_x509_t *this,
 			{
 				flags |= usage->data[1] << 8;
 			}
-			switch (flags)
+			if (flags & X509v3_KU_CRL_SIGN)
 			{
-				case X509v3_KU_CRL_SIGN:
-					this->flags |= X509_CRL_SIGN;
-					break;
-				case X509v3_KU_KEY_CERT_SIGN:
-					/* we use the caBasicContraint, MUST be set */
-				default:
-					break;
+				this->flags |= X509_CRL_SIGN;
+			}
+			if (flags & X509v3_KU_KEY_CERT_SIGN)
+			{
+				/* we use the caBasicContraint, MUST be set */
 			}
 		}
 		ASN1_BIT_STRING_free(usage);
diff --git a/src/libstrongswan/plugins/padlock/Makefile.in b/src/libstrongswan/plugins/padlock/Makefile.in
index b717495..1011193 100644
--- a/src/libstrongswan/plugins/padlock/Makefile.in
+++ b/src/libstrongswan/plugins/padlock/Makefile.in
@@ -313,8 +313,6 @@ RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
 RUBYGEMDIR = @RUBYGEMDIR@
-RUBYINCLUDE = @RUBYINCLUDE@
-RUBYLIB = @RUBYLIB@
 SED = @SED@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
@@ -415,6 +413,8 @@ random_device = @random_device@
 resolv_conf = @resolv_conf@
 routing_table = @routing_table@
 routing_table_prio = @routing_table_prio@
+ruby_CFLAGS = @ruby_CFLAGS@
+ruby_LIBS = @ruby_LIBS@
 runstatedir = @runstatedir@
 s_plugins = @s_plugins@
 sbindir = @sbindir@
@@ -443,6 +443,10 @@ top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
 tss2_CFLAGS = @tss2_CFLAGS@
 tss2_LIBS = @tss2_LIBS@
+tss2_socket_CFLAGS = @tss2_socket_CFLAGS@
+tss2_socket_LIBS = @tss2_socket_LIBS@
+tss2_tabrmd_CFLAGS = @tss2_tabrmd_CFLAGS@
+tss2_tabrmd_LIBS = @tss2_tabrmd_LIBS@
 urandom_device = @urandom_device@
 xml_CFLAGS = @xml_CFLAGS@
 xml_LIBS = @xml_LIBS@
diff --git a/src/libstrongswan/plugins/pem/Makefile.in b/src/libstrongswan/plugins/pem/Makefile.in
index 8ff3dd0..4b69f9f 100644
--- a/src/libstrongswan/plugins/pem/Makefile.in
+++ b/src/libstrongswan/plugins/pem/Makefile.in
@@ -311,8 +311,6 @@ RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
 RUBYGEMDIR = @RUBYGEMDIR@
-RUBYINCLUDE = @RUBYINCLUDE@
-RUBYLIB = @RUBYLIB@
 SED = @SED@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
@@ -413,6 +411,8 @@ random_device = @random_device@
 resolv_conf = @resolv_conf@
 routing_table = @routing_table@
 routing_table_prio = @routing_table_prio@
+ruby_CFLAGS = @ruby_CFLAGS@
+ruby_LIBS = @ruby_LIBS@
 runstatedir = @runstatedir@
 s_plugins = @s_plugins@
 sbindir = @sbindir@
@@ -441,6 +441,10 @@ top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
 tss2_CFLAGS = @tss2_CFLAGS@
 tss2_LIBS = @tss2_LIBS@
+tss2_socket_CFLAGS = @tss2_socket_CFLAGS@
+tss2_socket_LIBS = @tss2_socket_LIBS@
+tss2_tabrmd_CFLAGS = @tss2_tabrmd_CFLAGS@
+tss2_tabrmd_LIBS = @tss2_tabrmd_LIBS@
 urandom_device = @urandom_device@
 xml_CFLAGS = @xml_CFLAGS@
 xml_LIBS = @xml_LIBS@
diff --git a/src/libstrongswan/plugins/pgp/Makefile.in b/src/libstrongswan/plugins/pgp/Makefile.in
index 3ffafd0..8104a2a 100644
--- a/src/libstrongswan/plugins/pgp/Makefile.in
+++ b/src/libstrongswan/plugins/pgp/Makefile.in
@@ -311,8 +311,6 @@ RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
 RUBYGEMDIR = @RUBYGEMDIR@
-RUBYINCLUDE = @RUBYINCLUDE@
-RUBYLIB = @RUBYLIB@
 SED = @SED@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
@@ -413,6 +411,8 @@ random_device = @random_device@
 resolv_conf = @resolv_conf@
 routing_table = @routing_table@
 routing_table_prio = @routing_table_prio@
+ruby_CFLAGS = @ruby_CFLAGS@
+ruby_LIBS = @ruby_LIBS@
 runstatedir = @runstatedir@
 s_plugins = @s_plugins@
 sbindir = @sbindir@
@@ -441,6 +441,10 @@ top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
 tss2_CFLAGS = @tss2_CFLAGS@
 tss2_LIBS = @tss2_LIBS@
+tss2_socket_CFLAGS = @tss2_socket_CFLAGS@
+tss2_socket_LIBS = @tss2_socket_LIBS@
+tss2_tabrmd_CFLAGS = @tss2_tabrmd_CFLAGS@
+tss2_tabrmd_LIBS = @tss2_tabrmd_LIBS@
 urandom_device = @urandom_device@
 xml_CFLAGS = @xml_CFLAGS@
 xml_LIBS = @xml_LIBS@
diff --git a/src/libstrongswan/plugins/pkcs1/Makefile.in b/src/libstrongswan/plugins/pkcs1/Makefile.in
index cbf2276..6f6c623 100644
--- a/src/libstrongswan/plugins/pkcs1/Makefile.in
+++ b/src/libstrongswan/plugins/pkcs1/Makefile.in
@@ -312,8 +312,6 @@ RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
 RUBYGEMDIR = @RUBYGEMDIR@
-RUBYINCLUDE = @RUBYINCLUDE@
-RUBYLIB = @RUBYLIB@
 SED = @SED@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
@@ -414,6 +412,8 @@ random_device = @random_device@
 resolv_conf = @resolv_conf@
 routing_table = @routing_table@
 routing_table_prio = @routing_table_prio@
+ruby_CFLAGS = @ruby_CFLAGS@
+ruby_LIBS = @ruby_LIBS@
 runstatedir = @runstatedir@
 s_plugins = @s_plugins@
 sbindir = @sbindir@
@@ -442,6 +442,10 @@ top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
 tss2_CFLAGS = @tss2_CFLAGS@
 tss2_LIBS = @tss2_LIBS@
+tss2_socket_CFLAGS = @tss2_socket_CFLAGS@
+tss2_socket_LIBS = @tss2_socket_LIBS@
+tss2_tabrmd_CFLAGS = @tss2_tabrmd_CFLAGS@
+tss2_tabrmd_LIBS = @tss2_tabrmd_LIBS@
 urandom_device = @urandom_device@
 xml_CFLAGS = @xml_CFLAGS@
 xml_LIBS = @xml_LIBS@
diff --git a/src/libstrongswan/plugins/pkcs11/Makefile.in b/src/libstrongswan/plugins/pkcs11/Makefile.in
index ca7b5a8..7bf33d9 100644
--- a/src/libstrongswan/plugins/pkcs11/Makefile.in
+++ b/src/libstrongswan/plugins/pkcs11/Makefile.in
@@ -315,8 +315,6 @@ RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
 RUBYGEMDIR = @RUBYGEMDIR@
-RUBYINCLUDE = @RUBYINCLUDE@
-RUBYLIB = @RUBYLIB@
 SED = @SED@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
@@ -417,6 +415,8 @@ random_device = @random_device@
 resolv_conf = @resolv_conf@
 routing_table = @routing_table@
 routing_table_prio = @routing_table_prio@
+ruby_CFLAGS = @ruby_CFLAGS@
+ruby_LIBS = @ruby_LIBS@
 runstatedir = @runstatedir@
 s_plugins = @s_plugins@
 sbindir = @sbindir@
@@ -445,6 +445,10 @@ top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
 tss2_CFLAGS = @tss2_CFLAGS@
 tss2_LIBS = @tss2_LIBS@
+tss2_socket_CFLAGS = @tss2_socket_CFLAGS@
+tss2_socket_LIBS = @tss2_socket_LIBS@
+tss2_tabrmd_CFLAGS = @tss2_tabrmd_CFLAGS@
+tss2_tabrmd_LIBS = @tss2_tabrmd_LIBS@
 urandom_device = @urandom_device@
 xml_CFLAGS = @xml_CFLAGS@
 xml_LIBS = @xml_LIBS@
diff --git a/src/libstrongswan/plugins/pkcs12/Makefile.in b/src/libstrongswan/plugins/pkcs12/Makefile.in
index 73f15d2..d25a1af 100644
--- a/src/libstrongswan/plugins/pkcs12/Makefile.in
+++ b/src/libstrongswan/plugins/pkcs12/Makefile.in
@@ -312,8 +312,6 @@ RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
 RUBYGEMDIR = @RUBYGEMDIR@
-RUBYINCLUDE = @RUBYINCLUDE@
-RUBYLIB = @RUBYLIB@
 SED = @SED@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
@@ -414,6 +412,8 @@ random_device = @random_device@
 resolv_conf = @resolv_conf@
 routing_table = @routing_table@
 routing_table_prio = @routing_table_prio@
+ruby_CFLAGS = @ruby_CFLAGS@
+ruby_LIBS = @ruby_LIBS@
 runstatedir = @runstatedir@
 s_plugins = @s_plugins@
 sbindir = @sbindir@
@@ -442,6 +442,10 @@ top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
 tss2_CFLAGS = @tss2_CFLAGS@
 tss2_LIBS = @tss2_LIBS@
+tss2_socket_CFLAGS = @tss2_socket_CFLAGS@
+tss2_socket_LIBS = @tss2_socket_LIBS@
+tss2_tabrmd_CFLAGS = @tss2_tabrmd_CFLAGS@
+tss2_tabrmd_LIBS = @tss2_tabrmd_LIBS@
 urandom_device = @urandom_device@
 xml_CFLAGS = @xml_CFLAGS@
 xml_LIBS = @xml_LIBS@
diff --git a/src/libstrongswan/plugins/pkcs7/Makefile.in b/src/libstrongswan/plugins/pkcs7/Makefile.in
index 3bf44de..e5698a3 100644
--- a/src/libstrongswan/plugins/pkcs7/Makefile.in
+++ b/src/libstrongswan/plugins/pkcs7/Makefile.in
@@ -314,8 +314,6 @@ RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
 RUBYGEMDIR = @RUBYGEMDIR@
-RUBYINCLUDE = @RUBYINCLUDE@
-RUBYLIB = @RUBYLIB@
 SED = @SED@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
@@ -416,6 +414,8 @@ random_device = @random_device@
 resolv_conf = @resolv_conf@
 routing_table = @routing_table@
 routing_table_prio = @routing_table_prio@
+ruby_CFLAGS = @ruby_CFLAGS@
+ruby_LIBS = @ruby_LIBS@
 runstatedir = @runstatedir@
 s_plugins = @s_plugins@
 sbindir = @sbindir@
@@ -444,6 +444,10 @@ top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
 tss2_CFLAGS = @tss2_CFLAGS@
 tss2_LIBS = @tss2_LIBS@
+tss2_socket_CFLAGS = @tss2_socket_CFLAGS@
+tss2_socket_LIBS = @tss2_socket_LIBS@
+tss2_tabrmd_CFLAGS = @tss2_tabrmd_CFLAGS@
+tss2_tabrmd_LIBS = @tss2_tabrmd_LIBS@
 urandom_device = @urandom_device@
 xml_CFLAGS = @xml_CFLAGS@
 xml_LIBS = @xml_LIBS@
diff --git a/src/libstrongswan/plugins/pkcs8/Makefile.in b/src/libstrongswan/plugins/pkcs8/Makefile.in
index 2066d87..3ff09f5 100644
--- a/src/libstrongswan/plugins/pkcs8/Makefile.in
+++ b/src/libstrongswan/plugins/pkcs8/Makefile.in
@@ -311,8 +311,6 @@ RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
 RUBYGEMDIR = @RUBYGEMDIR@
-RUBYINCLUDE = @RUBYINCLUDE@
-RUBYLIB = @RUBYLIB@
 SED = @SED@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
@@ -413,6 +411,8 @@ random_device = @random_device@
 resolv_conf = @resolv_conf@
 routing_table = @routing_table@
 routing_table_prio = @routing_table_prio@
+ruby_CFLAGS = @ruby_CFLAGS@
+ruby_LIBS = @ruby_LIBS@
 runstatedir = @runstatedir@
 s_plugins = @s_plugins@
 sbindir = @sbindir@
@@ -441,6 +441,10 @@ top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
 tss2_CFLAGS = @tss2_CFLAGS@
 tss2_LIBS = @tss2_LIBS@
+tss2_socket_CFLAGS = @tss2_socket_CFLAGS@
+tss2_socket_LIBS = @tss2_socket_LIBS@
+tss2_tabrmd_CFLAGS = @tss2_tabrmd_CFLAGS@
+tss2_tabrmd_LIBS = @tss2_tabrmd_LIBS@
 urandom_device = @urandom_device@
 xml_CFLAGS = @xml_CFLAGS@
 xml_LIBS = @xml_LIBS@
diff --git a/src/libstrongswan/plugins/pubkey/Makefile.in b/src/libstrongswan/plugins/pubkey/Makefile.in
index 04888cd..0260795 100644
--- a/src/libstrongswan/plugins/pubkey/Makefile.in
+++ b/src/libstrongswan/plugins/pubkey/Makefile.in
@@ -312,8 +312,6 @@ RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
 RUBYGEMDIR = @RUBYGEMDIR@
-RUBYINCLUDE = @RUBYINCLUDE@
-RUBYLIB = @RUBYLIB@
 SED = @SED@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
@@ -414,6 +412,8 @@ random_device = @random_device@
 resolv_conf = @resolv_conf@
 routing_table = @routing_table@
 routing_table_prio = @routing_table_prio@
+ruby_CFLAGS = @ruby_CFLAGS@
+ruby_LIBS = @ruby_LIBS@
 runstatedir = @runstatedir@
 s_plugins = @s_plugins@
 sbindir = @sbindir@
@@ -442,6 +442,10 @@ top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
 tss2_CFLAGS = @tss2_CFLAGS@
 tss2_LIBS = @tss2_LIBS@
+tss2_socket_CFLAGS = @tss2_socket_CFLAGS@
+tss2_socket_LIBS = @tss2_socket_LIBS@
+tss2_tabrmd_CFLAGS = @tss2_tabrmd_CFLAGS@
+tss2_tabrmd_LIBS = @tss2_tabrmd_LIBS@
 urandom_device = @urandom_device@
 xml_CFLAGS = @xml_CFLAGS@
 xml_LIBS = @xml_LIBS@
diff --git a/src/libstrongswan/plugins/random/Makefile.in b/src/libstrongswan/plugins/random/Makefile.in
index 940c557..98702d0 100644
--- a/src/libstrongswan/plugins/random/Makefile.in
+++ b/src/libstrongswan/plugins/random/Makefile.in
@@ -312,8 +312,6 @@ RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
 RUBYGEMDIR = @RUBYGEMDIR@
-RUBYINCLUDE = @RUBYINCLUDE@
-RUBYLIB = @RUBYLIB@
 SED = @SED@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
@@ -414,6 +412,8 @@ random_device = @random_device@
 resolv_conf = @resolv_conf@
 routing_table = @routing_table@
 routing_table_prio = @routing_table_prio@
+ruby_CFLAGS = @ruby_CFLAGS@
+ruby_LIBS = @ruby_LIBS@
 runstatedir = @runstatedir@
 s_plugins = @s_plugins@
 sbindir = @sbindir@
@@ -442,6 +442,10 @@ top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
 tss2_CFLAGS = @tss2_CFLAGS@
 tss2_LIBS = @tss2_LIBS@
+tss2_socket_CFLAGS = @tss2_socket_CFLAGS@
+tss2_socket_LIBS = @tss2_socket_LIBS@
+tss2_tabrmd_CFLAGS = @tss2_tabrmd_CFLAGS@
+tss2_tabrmd_LIBS = @tss2_tabrmd_LIBS@
 urandom_device = @urandom_device@
 xml_CFLAGS = @xml_CFLAGS@
 xml_LIBS = @xml_LIBS@
diff --git a/src/libstrongswan/plugins/rc2/Makefile.in b/src/libstrongswan/plugins/rc2/Makefile.in
index c432cf8..b874e90 100644
--- a/src/libstrongswan/plugins/rc2/Makefile.in
+++ b/src/libstrongswan/plugins/rc2/Makefile.in
@@ -310,8 +310,6 @@ RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
 RUBYGEMDIR = @RUBYGEMDIR@
-RUBYINCLUDE = @RUBYINCLUDE@
-RUBYLIB = @RUBYLIB@
 SED = @SED@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
@@ -412,6 +410,8 @@ random_device = @random_device@
 resolv_conf = @resolv_conf@
 routing_table = @routing_table@
 routing_table_prio = @routing_table_prio@
+ruby_CFLAGS = @ruby_CFLAGS@
+ruby_LIBS = @ruby_LIBS@
 runstatedir = @runstatedir@
 s_plugins = @s_plugins@
 sbindir = @sbindir@
@@ -440,6 +440,10 @@ top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
 tss2_CFLAGS = @tss2_CFLAGS@
 tss2_LIBS = @tss2_LIBS@
+tss2_socket_CFLAGS = @tss2_socket_CFLAGS@
+tss2_socket_LIBS = @tss2_socket_LIBS@
+tss2_tabrmd_CFLAGS = @tss2_tabrmd_CFLAGS@
+tss2_tabrmd_LIBS = @tss2_tabrmd_LIBS@
 urandom_device = @urandom_device@
 xml_CFLAGS = @xml_CFLAGS@
 xml_LIBS = @xml_LIBS@
diff --git a/src/libstrongswan/plugins/rdrand/Makefile.in b/src/libstrongswan/plugins/rdrand/Makefile.in
index 849c896..40b1d76 100644
--- a/src/libstrongswan/plugins/rdrand/Makefile.in
+++ b/src/libstrongswan/plugins/rdrand/Makefile.in
@@ -312,8 +312,6 @@ RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
 RUBYGEMDIR = @RUBYGEMDIR@
-RUBYINCLUDE = @RUBYINCLUDE@
-RUBYLIB = @RUBYLIB@
 SED = @SED@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
@@ -414,6 +412,8 @@ random_device = @random_device@
 resolv_conf = @resolv_conf@
 routing_table = @routing_table@
 routing_table_prio = @routing_table_prio@
+ruby_CFLAGS = @ruby_CFLAGS@
+ruby_LIBS = @ruby_LIBS@
 runstatedir = @runstatedir@
 s_plugins = @s_plugins@
 sbindir = @sbindir@
@@ -442,6 +442,10 @@ top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
 tss2_CFLAGS = @tss2_CFLAGS@
 tss2_LIBS = @tss2_LIBS@
+tss2_socket_CFLAGS = @tss2_socket_CFLAGS@
+tss2_socket_LIBS = @tss2_socket_LIBS@
+tss2_tabrmd_CFLAGS = @tss2_tabrmd_CFLAGS@
+tss2_tabrmd_LIBS = @tss2_tabrmd_LIBS@
 urandom_device = @urandom_device@
 xml_CFLAGS = @xml_CFLAGS@
 xml_LIBS = @xml_LIBS@
diff --git a/src/libstrongswan/plugins/revocation/Makefile.in b/src/libstrongswan/plugins/revocation/Makefile.in
index 5840c7d..8254c14 100644
--- a/src/libstrongswan/plugins/revocation/Makefile.in
+++ b/src/libstrongswan/plugins/revocation/Makefile.in
@@ -313,8 +313,6 @@ RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
 RUBYGEMDIR = @RUBYGEMDIR@
-RUBYINCLUDE = @RUBYINCLUDE@
-RUBYLIB = @RUBYLIB@
 SED = @SED@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
@@ -415,6 +413,8 @@ random_device = @random_device@
 resolv_conf = @resolv_conf@
 routing_table = @routing_table@
 routing_table_prio = @routing_table_prio@
+ruby_CFLAGS = @ruby_CFLAGS@
+ruby_LIBS = @ruby_LIBS@
 runstatedir = @runstatedir@
 s_plugins = @s_plugins@
 sbindir = @sbindir@
@@ -443,6 +443,10 @@ top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
 tss2_CFLAGS = @tss2_CFLAGS@
 tss2_LIBS = @tss2_LIBS@
+tss2_socket_CFLAGS = @tss2_socket_CFLAGS@
+tss2_socket_LIBS = @tss2_socket_LIBS@
+tss2_tabrmd_CFLAGS = @tss2_tabrmd_CFLAGS@
+tss2_tabrmd_LIBS = @tss2_tabrmd_LIBS@
 urandom_device = @urandom_device@
 xml_CFLAGS = @xml_CFLAGS@
 xml_LIBS = @xml_LIBS@
diff --git a/src/libstrongswan/plugins/sha1/Makefile.in b/src/libstrongswan/plugins/sha1/Makefile.in
index fa596e6..0c68798 100644
--- a/src/libstrongswan/plugins/sha1/Makefile.in
+++ b/src/libstrongswan/plugins/sha1/Makefile.in
@@ -311,8 +311,6 @@ RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
 RUBYGEMDIR = @RUBYGEMDIR@
-RUBYINCLUDE = @RUBYINCLUDE@
-RUBYLIB = @RUBYLIB@
 SED = @SED@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
@@ -413,6 +411,8 @@ random_device = @random_device@
 resolv_conf = @resolv_conf@
 routing_table = @routing_table@
 routing_table_prio = @routing_table_prio@
+ruby_CFLAGS = @ruby_CFLAGS@
+ruby_LIBS = @ruby_LIBS@
 runstatedir = @runstatedir@
 s_plugins = @s_plugins@
 sbindir = @sbindir@
@@ -441,6 +441,10 @@ top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
 tss2_CFLAGS = @tss2_CFLAGS@
 tss2_LIBS = @tss2_LIBS@
+tss2_socket_CFLAGS = @tss2_socket_CFLAGS@
+tss2_socket_LIBS = @tss2_socket_LIBS@
+tss2_tabrmd_CFLAGS = @tss2_tabrmd_CFLAGS@
+tss2_tabrmd_LIBS = @tss2_tabrmd_LIBS@
 urandom_device = @urandom_device@
 xml_CFLAGS = @xml_CFLAGS@
 xml_LIBS = @xml_LIBS@
diff --git a/src/libstrongswan/plugins/sha2/Makefile.in b/src/libstrongswan/plugins/sha2/Makefile.in
index 6e3d6a3..109726b 100644
--- a/src/libstrongswan/plugins/sha2/Makefile.in
+++ b/src/libstrongswan/plugins/sha2/Makefile.in
@@ -310,8 +310,6 @@ RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
 RUBYGEMDIR = @RUBYGEMDIR@
-RUBYINCLUDE = @RUBYINCLUDE@
-RUBYLIB = @RUBYLIB@
 SED = @SED@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
@@ -412,6 +410,8 @@ random_device = @random_device@
 resolv_conf = @resolv_conf@
 routing_table = @routing_table@
 routing_table_prio = @routing_table_prio@
+ruby_CFLAGS = @ruby_CFLAGS@
+ruby_LIBS = @ruby_LIBS@
 runstatedir = @runstatedir@
 s_plugins = @s_plugins@
 sbindir = @sbindir@
@@ -440,6 +440,10 @@ top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
 tss2_CFLAGS = @tss2_CFLAGS@
 tss2_LIBS = @tss2_LIBS@
+tss2_socket_CFLAGS = @tss2_socket_CFLAGS@
+tss2_socket_LIBS = @tss2_socket_LIBS@
+tss2_tabrmd_CFLAGS = @tss2_tabrmd_CFLAGS@
+tss2_tabrmd_LIBS = @tss2_tabrmd_LIBS@
 urandom_device = @urandom_device@
 xml_CFLAGS = @xml_CFLAGS@
 xml_LIBS = @xml_LIBS@
diff --git a/src/libstrongswan/plugins/sha2/sha2_hasher.c b/src/libstrongswan/plugins/sha2/sha2_hasher.c
index 89e7675..2c56a2f 100644
--- a/src/libstrongswan/plugins/sha2/sha2_hasher.c
+++ b/src/libstrongswan/plugins/sha2/sha2_hasher.c
@@ -226,7 +226,7 @@ static void sha256_write(private_sha256_hasher_t *ctx,
 /**
  * finalize SHA256 hash
  */
-static void sha256_final(private_sha256_hasher_t *ctx)
+static void sha256_final(private_sha256_hasher_t *ctx, u_char *buf, size_t len)
 {
 	register int    j;
 	uint64_t       bitLength;
@@ -255,8 +255,7 @@ static void sha256_final(private_sha256_hasher_t *ctx)
 	ctx->sha_out[63] = bitLength;
 	sha256_transform(ctx, &ctx->sha_out[0]);
 
-	/* return results in ctx->sha_out[0...31] */
-	datap = &ctx->sha_out[0];
+	datap = buf;
 	j = 0;
 	do {
 		i = ctx->sha_H[j];
@@ -265,7 +264,7 @@ static void sha256_final(private_sha256_hasher_t *ctx)
 		datap[2] = i >> 8;
 		datap[3] = i;
 		datap += 4;
-	} while(++j < 8);
+	} while(++j < len / 4);
 }
 
 /* update macros for SHA512 */
@@ -371,7 +370,7 @@ static void sha512_write(private_sha512_hasher_t *ctx,
 /**
  * Finalize a SHA384/SHA512 hash
  */
-static void sha512_final(private_sha512_hasher_t *ctx)
+static void sha512_final(private_sha512_hasher_t *ctx, u_char *buf, size_t len)
 {
 	register int    j;
 	uint64_t       bitLength, bitLengthMSB;
@@ -409,8 +408,7 @@ static void sha512_final(private_sha512_hasher_t *ctx)
 	ctx->sha_out[127] = bitLength;
 	sha512_transform(ctx, &ctx->sha_out[0]);
 
-	/* return results in ctx->sha_out[0...63] */
-	datap = &ctx->sha_out[0];
+	datap = buf;
 	j = 0;
 	do {
 		i = ctx->sha_H[j];
@@ -423,7 +421,7 @@ static void sha512_final(private_sha512_hasher_t *ctx)
 		datap[6] = i >> 8;
 		datap[7] = i;
 		datap += 8;
-	} while(++j < 8);
+	} while(++j < len / 8);
 }
 
 METHOD(hasher_t, reset224, bool,
@@ -432,7 +430,6 @@ METHOD(hasher_t, reset224, bool,
 	memcpy(&this->sha_H[0], &sha224_hashInit[0], sizeof(this->sha_H));
 	this->sha_blocks = 0;
 	this->sha_bufCnt = 0;
-
 	return TRUE;
 }
 
@@ -442,7 +439,6 @@ METHOD(hasher_t, reset256, bool,
 	memcpy(&this->sha_H[0], &sha256_hashInit[0], sizeof(this->sha_H));
 	this->sha_blocks = 0;
 	this->sha_bufCnt = 0;
-
 	return TRUE;
 }
 
@@ -453,7 +449,6 @@ METHOD(hasher_t, reset384, bool,
 	this->sha_blocks = 0;
 	this->sha_blocksMSB = 0;
 	this->sha_bufCnt = 0;
-
 	return TRUE;
 }
 
@@ -464,7 +459,6 @@ METHOD(hasher_t, reset512, bool,
 	this->sha_blocks = 0;
 	this->sha_blocksMSB = 0;
 	this->sha_bufCnt = 0;
-
 	return TRUE;
 }
 
@@ -474,8 +468,7 @@ METHOD(hasher_t, get_hash224, bool,
 	sha256_write(this, chunk.ptr, chunk.len);
 	if (buffer != NULL)
 	{
-		sha256_final(this);
-		memcpy(buffer, this->sha_out, HASH_SIZE_SHA224);
+		sha256_final(this, buffer, HASH_SIZE_SHA224);
 		reset224(this);
 	}
 	return TRUE;
@@ -487,8 +480,7 @@ METHOD(hasher_t, get_hash256, bool,
 	sha256_write(this, chunk.ptr, chunk.len);
 	if (buffer != NULL)
 	{
-		sha256_final(this);
-		memcpy(buffer, this->sha_out, HASH_SIZE_SHA256);
+		sha256_final(this, buffer, HASH_SIZE_SHA256);
 		reset256(this);
 	}
 	return TRUE;
@@ -500,8 +492,7 @@ METHOD(hasher_t, get_hash384, bool,
 	sha512_write(this, chunk.ptr, chunk.len);
 	if (buffer != NULL)
 	{
-		sha512_final(this);
-		memcpy(buffer, this->sha_out, HASH_SIZE_SHA384);
+		sha512_final(this, buffer, HASH_SIZE_SHA384);
 		reset384(this);
 	}
 	return TRUE;
@@ -513,8 +504,7 @@ METHOD(hasher_t, get_hash512, bool,
 	sha512_write(this, chunk.ptr, chunk.len);
 	if (buffer != NULL)
 	{
-		sha512_final(this);
-		memcpy(buffer, this->sha_out, HASH_SIZE_SHA512);
+		sha512_final(this, buffer, HASH_SIZE_SHA512);
 		reset512(this);
 	}
 	return TRUE;
@@ -523,69 +513,49 @@ METHOD(hasher_t, get_hash512, bool,
 METHOD(hasher_t, allocate_hash224, bool,
 	private_sha256_hasher_t *this, chunk_t chunk, chunk_t *hash)
 {
-	chunk_t allocated_hash;
+	chunk_t allocated_hash = chunk_empty;
 
-	sha256_write(this, chunk.ptr, chunk.len);
-	if (hash != NULL)
+	if (hash)
 	{
-		sha256_final(this);
-		allocated_hash = chunk_alloc(HASH_SIZE_SHA224);
-		memcpy(allocated_hash.ptr, this->sha_out, HASH_SIZE_SHA224);
-		reset224(this);
-		*hash = allocated_hash;
+		*hash = allocated_hash = chunk_alloc(HASH_SIZE_SHA224);
 	}
-	return TRUE;
+	return get_hash224(this, chunk, allocated_hash.ptr);
 }
 
 METHOD(hasher_t, allocate_hash256, bool,
 	private_sha256_hasher_t *this, chunk_t chunk, chunk_t *hash)
 {
-	chunk_t allocated_hash;
+	chunk_t allocated_hash = chunk_empty;
 
-	sha256_write(this, chunk.ptr, chunk.len);
-	if (hash != NULL)
+	if (hash)
 	{
-		sha256_final(this);
-		allocated_hash = chunk_alloc(HASH_SIZE_SHA256);
-		memcpy(allocated_hash.ptr, this->sha_out, HASH_SIZE_SHA256);
-		reset256(this);
-		*hash = allocated_hash;
+		*hash = allocated_hash = chunk_alloc(HASH_SIZE_SHA256);
 	}
-	return TRUE;
+	return get_hash256(this, chunk, allocated_hash.ptr);
 }
 
 METHOD(hasher_t, allocate_hash384, bool,
 	private_sha512_hasher_t *this, chunk_t chunk, chunk_t *hash)
 {
-	chunk_t allocated_hash;
+	chunk_t allocated_hash = chunk_empty;
 
-	sha512_write(this, chunk.ptr, chunk.len);
-	if (hash != NULL)
+	if (hash)
 	{
-		sha512_final(this);
-		allocated_hash = chunk_alloc(HASH_SIZE_SHA384);
-		memcpy(allocated_hash.ptr, this->sha_out, HASH_SIZE_SHA384);
-		reset384(this);
-		*hash = allocated_hash;
+		*hash = allocated_hash = chunk_alloc(HASH_SIZE_SHA384);
 	}
-	return TRUE;
+	return get_hash384(this, chunk, allocated_hash.ptr);
 }
 
 METHOD(hasher_t, allocate_hash512, bool,
 	private_sha512_hasher_t *this, chunk_t chunk, chunk_t *hash)
 {
-	chunk_t allocated_hash;
+	chunk_t allocated_hash = chunk_empty;
 
-	sha512_write(this, chunk.ptr, chunk.len);
-	if (hash != NULL)
+	if (hash)
 	{
-		sha512_final(this);
-		allocated_hash = chunk_alloc(HASH_SIZE_SHA512);
-		memcpy(allocated_hash.ptr, this->sha_out, HASH_SIZE_SHA512);
-		reset512(this);
-		*hash = allocated_hash;
+		*hash = allocated_hash = chunk_alloc(HASH_SIZE_SHA512);
 	}
-	return TRUE;
+	return get_hash512(this, chunk, allocated_hash.ptr);
 }
 
 METHOD(hasher_t, get_hash_size224, size_t,
diff --git a/src/libstrongswan/plugins/sha3/Makefile.in b/src/libstrongswan/plugins/sha3/Makefile.in
index 2c24934..a1f7974 100644
--- a/src/libstrongswan/plugins/sha3/Makefile.in
+++ b/src/libstrongswan/plugins/sha3/Makefile.in
@@ -311,8 +311,6 @@ RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
 RUBYGEMDIR = @RUBYGEMDIR@
-RUBYINCLUDE = @RUBYINCLUDE@
-RUBYLIB = @RUBYLIB@
 SED = @SED@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
@@ -413,6 +411,8 @@ random_device = @random_device@
 resolv_conf = @resolv_conf@
 routing_table = @routing_table@
 routing_table_prio = @routing_table_prio@
+ruby_CFLAGS = @ruby_CFLAGS@
+ruby_LIBS = @ruby_LIBS@
 runstatedir = @runstatedir@
 s_plugins = @s_plugins@
 sbindir = @sbindir@
@@ -441,6 +441,10 @@ top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
 tss2_CFLAGS = @tss2_CFLAGS@
 tss2_LIBS = @tss2_LIBS@
+tss2_socket_CFLAGS = @tss2_socket_CFLAGS@
+tss2_socket_LIBS = @tss2_socket_LIBS@
+tss2_tabrmd_CFLAGS = @tss2_tabrmd_CFLAGS@
+tss2_tabrmd_LIBS = @tss2_tabrmd_LIBS@
 urandom_device = @urandom_device@
 xml_CFLAGS = @xml_CFLAGS@
 xml_LIBS = @xml_LIBS@
diff --git a/src/libstrongswan/plugins/soup/Makefile.in b/src/libstrongswan/plugins/soup/Makefile.in
index 02e3987..ceccab7 100644
--- a/src/libstrongswan/plugins/soup/Makefile.in
+++ b/src/libstrongswan/plugins/soup/Makefile.in
@@ -311,8 +311,6 @@ RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
 RUBYGEMDIR = @RUBYGEMDIR@
-RUBYINCLUDE = @RUBYINCLUDE@
-RUBYLIB = @RUBYLIB@
 SED = @SED@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
@@ -413,6 +411,8 @@ random_device = @random_device@
 resolv_conf = @resolv_conf@
 routing_table = @routing_table@
 routing_table_prio = @routing_table_prio@
+ruby_CFLAGS = @ruby_CFLAGS@
+ruby_LIBS = @ruby_LIBS@
 runstatedir = @runstatedir@
 s_plugins = @s_plugins@
 sbindir = @sbindir@
@@ -441,6 +441,10 @@ top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
 tss2_CFLAGS = @tss2_CFLAGS@
 tss2_LIBS = @tss2_LIBS@
+tss2_socket_CFLAGS = @tss2_socket_CFLAGS@
+tss2_socket_LIBS = @tss2_socket_LIBS@
+tss2_tabrmd_CFLAGS = @tss2_tabrmd_CFLAGS@
+tss2_tabrmd_LIBS = @tss2_tabrmd_LIBS@
 urandom_device = @urandom_device@
 xml_CFLAGS = @xml_CFLAGS@
 xml_LIBS = @xml_LIBS@
diff --git a/src/libstrongswan/plugins/sqlite/Makefile.in b/src/libstrongswan/plugins/sqlite/Makefile.in
index 5e23cb9..39d7056 100644
--- a/src/libstrongswan/plugins/sqlite/Makefile.in
+++ b/src/libstrongswan/plugins/sqlite/Makefile.in
@@ -313,8 +313,6 @@ RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
 RUBYGEMDIR = @RUBYGEMDIR@
-RUBYINCLUDE = @RUBYINCLUDE@
-RUBYLIB = @RUBYLIB@
 SED = @SED@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
@@ -415,6 +413,8 @@ random_device = @random_device@
 resolv_conf = @resolv_conf@
 routing_table = @routing_table@
 routing_table_prio = @routing_table_prio@
+ruby_CFLAGS = @ruby_CFLAGS@
+ruby_LIBS = @ruby_LIBS@
 runstatedir = @runstatedir@
 s_plugins = @s_plugins@
 sbindir = @sbindir@
@@ -443,6 +443,10 @@ top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
 tss2_CFLAGS = @tss2_CFLAGS@
 tss2_LIBS = @tss2_LIBS@
+tss2_socket_CFLAGS = @tss2_socket_CFLAGS@
+tss2_socket_LIBS = @tss2_socket_LIBS@
+tss2_tabrmd_CFLAGS = @tss2_tabrmd_CFLAGS@
+tss2_tabrmd_LIBS = @tss2_tabrmd_LIBS@
 urandom_device = @urandom_device@
 xml_CFLAGS = @xml_CFLAGS@
 xml_LIBS = @xml_LIBS@
diff --git a/src/libstrongswan/plugins/sshkey/Makefile.in b/src/libstrongswan/plugins/sshkey/Makefile.in
index a666399..ded2bf8 100644
--- a/src/libstrongswan/plugins/sshkey/Makefile.in
+++ b/src/libstrongswan/plugins/sshkey/Makefile.in
@@ -313,8 +313,6 @@ RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
 RUBYGEMDIR = @RUBYGEMDIR@
-RUBYINCLUDE = @RUBYINCLUDE@
-RUBYLIB = @RUBYLIB@
 SED = @SED@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
@@ -415,6 +413,8 @@ random_device = @random_device@
 resolv_conf = @resolv_conf@
 routing_table = @routing_table@
 routing_table_prio = @routing_table_prio@
+ruby_CFLAGS = @ruby_CFLAGS@
+ruby_LIBS = @ruby_LIBS@
 runstatedir = @runstatedir@
 s_plugins = @s_plugins@
 sbindir = @sbindir@
@@ -443,6 +443,10 @@ top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
 tss2_CFLAGS = @tss2_CFLAGS@
 tss2_LIBS = @tss2_LIBS@
+tss2_socket_CFLAGS = @tss2_socket_CFLAGS@
+tss2_socket_LIBS = @tss2_socket_LIBS@
+tss2_tabrmd_CFLAGS = @tss2_tabrmd_CFLAGS@
+tss2_tabrmd_LIBS = @tss2_tabrmd_LIBS@
 urandom_device = @urandom_device@
 xml_CFLAGS = @xml_CFLAGS@
 xml_LIBS = @xml_LIBS@
diff --git a/src/libstrongswan/plugins/test_vectors/Makefile.in b/src/libstrongswan/plugins/test_vectors/Makefile.in
index 33c5720..b7332d4 100644
--- a/src/libstrongswan/plugins/test_vectors/Makefile.in
+++ b/src/libstrongswan/plugins/test_vectors/Makefile.in
@@ -331,8 +331,6 @@ RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
 RUBYGEMDIR = @RUBYGEMDIR@
-RUBYINCLUDE = @RUBYINCLUDE@
-RUBYLIB = @RUBYLIB@
 SED = @SED@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
@@ -433,6 +431,8 @@ random_device = @random_device@
 resolv_conf = @resolv_conf@
 routing_table = @routing_table@
 routing_table_prio = @routing_table_prio@
+ruby_CFLAGS = @ruby_CFLAGS@
+ruby_LIBS = @ruby_LIBS@
 runstatedir = @runstatedir@
 s_plugins = @s_plugins@
 sbindir = @sbindir@
@@ -461,6 +461,10 @@ top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
 tss2_CFLAGS = @tss2_CFLAGS@
 tss2_LIBS = @tss2_LIBS@
+tss2_socket_CFLAGS = @tss2_socket_CFLAGS@
+tss2_socket_LIBS = @tss2_socket_LIBS@
+tss2_tabrmd_CFLAGS = @tss2_tabrmd_CFLAGS@
+tss2_tabrmd_LIBS = @tss2_tabrmd_LIBS@
 urandom_device = @urandom_device@
 xml_CFLAGS = @xml_CFLAGS@
 xml_LIBS = @xml_LIBS@
diff --git a/src/libstrongswan/plugins/unbound/Makefile.in b/src/libstrongswan/plugins/unbound/Makefile.in
index 15c8c27..93159ff 100644
--- a/src/libstrongswan/plugins/unbound/Makefile.in
+++ b/src/libstrongswan/plugins/unbound/Makefile.in
@@ -313,8 +313,6 @@ RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
 RUBYGEMDIR = @RUBYGEMDIR@
-RUBYINCLUDE = @RUBYINCLUDE@
-RUBYLIB = @RUBYLIB@
 SED = @SED@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
@@ -415,6 +413,8 @@ random_device = @random_device@
 resolv_conf = @resolv_conf@
 routing_table = @routing_table@
 routing_table_prio = @routing_table_prio@
+ruby_CFLAGS = @ruby_CFLAGS@
+ruby_LIBS = @ruby_LIBS@
 runstatedir = @runstatedir@
 s_plugins = @s_plugins@
 sbindir = @sbindir@
@@ -443,6 +443,10 @@ top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
 tss2_CFLAGS = @tss2_CFLAGS@
 tss2_LIBS = @tss2_LIBS@
+tss2_socket_CFLAGS = @tss2_socket_CFLAGS@
+tss2_socket_LIBS = @tss2_socket_LIBS@
+tss2_tabrmd_CFLAGS = @tss2_tabrmd_CFLAGS@
+tss2_tabrmd_LIBS = @tss2_tabrmd_LIBS@
 urandom_device = @urandom_device@
 xml_CFLAGS = @xml_CFLAGS@
 xml_LIBS = @xml_LIBS@
diff --git a/src/libstrongswan/plugins/winhttp/Makefile.in b/src/libstrongswan/plugins/winhttp/Makefile.in
index b417d6e..9103326 100644
--- a/src/libstrongswan/plugins/winhttp/Makefile.in
+++ b/src/libstrongswan/plugins/winhttp/Makefile.in
@@ -313,8 +313,6 @@ RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
 RUBYGEMDIR = @RUBYGEMDIR@
-RUBYINCLUDE = @RUBYINCLUDE@
-RUBYLIB = @RUBYLIB@
 SED = @SED@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
@@ -415,6 +413,8 @@ random_device = @random_device@
 resolv_conf = @resolv_conf@
 routing_table = @routing_table@
 routing_table_prio = @routing_table_prio@
+ruby_CFLAGS = @ruby_CFLAGS@
+ruby_LIBS = @ruby_LIBS@
 runstatedir = @runstatedir@
 s_plugins = @s_plugins@
 sbindir = @sbindir@
@@ -443,6 +443,10 @@ top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
 tss2_CFLAGS = @tss2_CFLAGS@
 tss2_LIBS = @tss2_LIBS@
+tss2_socket_CFLAGS = @tss2_socket_CFLAGS@
+tss2_socket_LIBS = @tss2_socket_LIBS@
+tss2_tabrmd_CFLAGS = @tss2_tabrmd_CFLAGS@
+tss2_tabrmd_LIBS = @tss2_tabrmd_LIBS@
 urandom_device = @urandom_device@
 xml_CFLAGS = @xml_CFLAGS@
 xml_LIBS = @xml_LIBS@
diff --git a/src/libstrongswan/plugins/x509/Makefile.in b/src/libstrongswan/plugins/x509/Makefile.in
index e1ed6b7..3596d1f 100644
--- a/src/libstrongswan/plugins/x509/Makefile.in
+++ b/src/libstrongswan/plugins/x509/Makefile.in
@@ -312,8 +312,6 @@ RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
 RUBYGEMDIR = @RUBYGEMDIR@
-RUBYINCLUDE = @RUBYINCLUDE@
-RUBYLIB = @RUBYLIB@
 SED = @SED@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
@@ -414,6 +412,8 @@ random_device = @random_device@
 resolv_conf = @resolv_conf@
 routing_table = @routing_table@
 routing_table_prio = @routing_table_prio@
+ruby_CFLAGS = @ruby_CFLAGS@
+ruby_LIBS = @ruby_LIBS@
 runstatedir = @runstatedir@
 s_plugins = @s_plugins@
 sbindir = @sbindir@
@@ -442,6 +442,10 @@ top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
 tss2_CFLAGS = @tss2_CFLAGS@
 tss2_LIBS = @tss2_LIBS@
+tss2_socket_CFLAGS = @tss2_socket_CFLAGS@
+tss2_socket_LIBS = @tss2_socket_LIBS@
+tss2_tabrmd_CFLAGS = @tss2_tabrmd_CFLAGS@
+tss2_tabrmd_LIBS = @tss2_tabrmd_LIBS@
 urandom_device = @urandom_device@
 xml_CFLAGS = @xml_CFLAGS@
 xml_LIBS = @xml_LIBS@
diff --git a/src/libstrongswan/plugins/x509/x509_ocsp_request.c b/src/libstrongswan/plugins/x509/x509_ocsp_request.c
index e32f8ee..aef76af 100644
--- a/src/libstrongswan/plugins/x509/x509_ocsp_request.c
+++ b/src/libstrongswan/plugins/x509/x509_ocsp_request.c
@@ -209,7 +209,8 @@ static chunk_t build_nonce(private_x509_ocsp_request_t *this)
 	}
 	rng->destroy(rng);
 	return asn1_wrap(ASN1_SEQUENCE, "cm", ASN1_nonce_oid,
-				asn1_simple_object(ASN1_OCTET_STRING, this->nonce));
+				asn1_wrap(ASN1_OCTET_STRING, "m",
+					asn1_simple_object(ASN1_OCTET_STRING, this->nonce)));
 }
 
 /**
diff --git a/src/libstrongswan/plugins/xcbc/Makefile.in b/src/libstrongswan/plugins/xcbc/Makefile.in
index a231308..d5d4769 100644
--- a/src/libstrongswan/plugins/xcbc/Makefile.in
+++ b/src/libstrongswan/plugins/xcbc/Makefile.in
@@ -310,8 +310,6 @@ RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
 RUBYGEMDIR = @RUBYGEMDIR@
-RUBYINCLUDE = @RUBYINCLUDE@
-RUBYLIB = @RUBYLIB@
 SED = @SED@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
@@ -412,6 +410,8 @@ random_device = @random_device@
 resolv_conf = @resolv_conf@
 routing_table = @routing_table@
 routing_table_prio = @routing_table_prio@
+ruby_CFLAGS = @ruby_CFLAGS@
+ruby_LIBS = @ruby_LIBS@
 runstatedir = @runstatedir@
 s_plugins = @s_plugins@
 sbindir = @sbindir@
@@ -440,6 +440,10 @@ top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
 tss2_CFLAGS = @tss2_CFLAGS@
 tss2_LIBS = @tss2_LIBS@
+tss2_socket_CFLAGS = @tss2_socket_CFLAGS@
+tss2_socket_LIBS = @tss2_socket_LIBS@
+tss2_tabrmd_CFLAGS = @tss2_tabrmd_CFLAGS@
+tss2_tabrmd_LIBS = @tss2_tabrmd_LIBS@
 urandom_device = @urandom_device@
 xml_CFLAGS = @xml_CFLAGS@
 xml_LIBS = @xml_LIBS@
diff --git a/src/libstrongswan/tests/Makefile.in b/src/libstrongswan/tests/Makefile.in
index 279e179..ce0ad37 100644
--- a/src/libstrongswan/tests/Makefile.in
+++ b/src/libstrongswan/tests/Makefile.in
@@ -351,8 +351,6 @@ RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
 RUBYGEMDIR = @RUBYGEMDIR@
-RUBYINCLUDE = @RUBYINCLUDE@
-RUBYLIB = @RUBYLIB@
 SED = @SED@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
@@ -453,6 +451,8 @@ random_device = @random_device@
 resolv_conf = @resolv_conf@
 routing_table = @routing_table@
 routing_table_prio = @routing_table_prio@
+ruby_CFLAGS = @ruby_CFLAGS@
+ruby_LIBS = @ruby_LIBS@
 runstatedir = @runstatedir@
 s_plugins = @s_plugins@
 sbindir = @sbindir@
@@ -481,6 +481,10 @@ top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
 tss2_CFLAGS = @tss2_CFLAGS@
 tss2_LIBS = @tss2_LIBS@
+tss2_socket_CFLAGS = @tss2_socket_CFLAGS@
+tss2_socket_LIBS = @tss2_socket_LIBS@
+tss2_tabrmd_CFLAGS = @tss2_tabrmd_CFLAGS@
+tss2_tabrmd_LIBS = @tss2_tabrmd_LIBS@
 urandom_device = @urandom_device@
 xml_CFLAGS = @xml_CFLAGS@
 xml_LIBS = @xml_LIBS@
diff --git a/src/libstrongswan/tests/suites/test_settings.c b/src/libstrongswan/tests/suites/test_settings.c
index 5ddd0bb..9d0a6de 100644
--- a/src/libstrongswan/tests/suites/test_settings.c
+++ b/src/libstrongswan/tests/suites/test_settings.c
@@ -549,10 +549,14 @@ END_TEST
 
 #ifdef WIN32
 # define include1 "C:\\Windows\\Temp\\strongswan-settings-test-include1"
+# define include1_str "C:\\\\Windows\\\\Temp\\\\strongswan-settings-test-include1"
 # define include2 "C:\\Windows\\Temp\\strongswan-settings-test-include2"
+# define include2_str "C:\\\\Windows\\\\Temp\\\\strongswan-settings-test-include2"
 #else
 # define include1 "/tmp/strongswan-settings-test-include1"
+# define include1_str include1
 # define include2 "/tmp/strongswan-settings-test-include2"
+# define include2_str include2
 #endif
 
 static char *include_content1 =
@@ -638,10 +642,10 @@ START_TEST(test_include_string)
 		"		include this/does/not/exist.conf\n"
 		"		include = value\n"
 		"		key2 = value2\n"
-		"		include \"" include2 "\"\n"
+		"		include \"" include2_str "\"\n"
 		"	}\n"
 		"}\n"
-		"include \"" include1 "\"");
+		"include \"" include1_str "\"");
 
 	create_settings(contents);
 	verify_include();
diff --git a/src/libstrongswan/tests/test_suite.c b/src/libstrongswan/tests/test_suite.c
index 0af34c8..8541cda 100644
--- a/src/libstrongswan/tests/test_suite.c
+++ b/src/libstrongswan/tests/test_suite.c
@@ -381,7 +381,7 @@ void test_setup_handler()
 	sigaction(SIGSEGV, &action, NULL);
 	sigaction(SIGILL, &action, NULL);
 	sigaction(SIGBUS, &action, NULL);
-	/* ignore ALRM/USR1, these are catched by main thread only */
+	/* ignore ALRM/USR1, these are caught by main thread only */
 	action.sa_handler = SIG_IGN;
 	sigaction(SIGALRM, &action, NULL);
 	sigaction(SIGUSR1, &action, NULL);
diff --git a/src/libstrongswan/tests/tests.h b/src/libstrongswan/tests/tests.h
index 79a88e2..c19cac2 100644
--- a/src/libstrongswan/tests/tests.h
+++ b/src/libstrongswan/tests/tests.h
@@ -41,7 +41,7 @@ TEST_SUITE(auth_cfg_suite_create)
 TEST_SUITE(hasher_suite_create)
 TEST_SUITE(crypter_suite_create)
 TEST_SUITE(crypto_factory_suite_create)
-TEST_SUITE(iv_gen_suite_create)
+TEST_SUITE_DEPEND(iv_gen_suite_create, RNG, RNG_STRONG)
 TEST_SUITE(pen_suite_create)
 TEST_SUITE(asn1_suite_create)
 TEST_SUITE(asn1_parser_suite_create)
diff --git a/src/libstrongswan/utils/utils/memory.c b/src/libstrongswan/utils/utils/memory.c
index 30c6f54..4b4b6cc 100644
--- a/src/libstrongswan/utils/utils/memory.c
+++ b/src/libstrongswan/utils/utils/memory.c
@@ -20,7 +20,7 @@
 /**
  * Described in header.
  */
-void memxor(uint8_t dst[], uint8_t src[], size_t n)
+void memxor(uint8_t dst[], const uint8_t src[], size_t n)
 {
 	int m, i;
 
diff --git a/src/libstrongswan/utils/utils/memory.h b/src/libstrongswan/utils/utils/memory.h
index b978e7c..e840330 100644
--- a/src/libstrongswan/utils/utils/memory.h
+++ b/src/libstrongswan/utils/utils/memory.h
@@ -80,7 +80,7 @@ static inline void *memset_noop(void *s, int c, size_t n)
 /**
  * Same as memcpy, but XORs src into dst instead of copy
  */
-void memxor(uint8_t dest[], uint8_t src[], size_t n);
+void memxor(uint8_t dest[], const uint8_t src[], size_t n);
 
 /**
  * Safely overwrite n bytes of memory at ptr with zero, non-inlining variant.
diff --git a/src/libtls/Makefile.in b/src/libtls/Makefile.in
index ee1d7fc..292d10f 100644
--- a/src/libtls/Makefile.in
+++ b/src/libtls/Makefile.in
@@ -363,8 +363,6 @@ RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
 RUBYGEMDIR = @RUBYGEMDIR@
-RUBYINCLUDE = @RUBYINCLUDE@
-RUBYLIB = @RUBYLIB@
 SED = @SED@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
@@ -465,6 +463,8 @@ random_device = @random_device@
 resolv_conf = @resolv_conf@
 routing_table = @routing_table@
 routing_table_prio = @routing_table_prio@
+ruby_CFLAGS = @ruby_CFLAGS@
+ruby_LIBS = @ruby_LIBS@
 runstatedir = @runstatedir@
 s_plugins = @s_plugins@
 sbindir = @sbindir@
@@ -493,6 +493,10 @@ top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
 tss2_CFLAGS = @tss2_CFLAGS@
 tss2_LIBS = @tss2_LIBS@
+tss2_socket_CFLAGS = @tss2_socket_CFLAGS@
+tss2_socket_LIBS = @tss2_socket_LIBS@
+tss2_tabrmd_CFLAGS = @tss2_tabrmd_CFLAGS@
+tss2_tabrmd_LIBS = @tss2_tabrmd_LIBS@
 urandom_device = @urandom_device@
 xml_CFLAGS = @xml_CFLAGS@
 xml_LIBS = @xml_LIBS@
diff --git a/src/libtls/tests/Makefile.in b/src/libtls/tests/Makefile.in
index 8c87e1d..2e2c3de 100644
--- a/src/libtls/tests/Makefile.in
+++ b/src/libtls/tests/Makefile.in
@@ -307,8 +307,6 @@ RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
 RUBYGEMDIR = @RUBYGEMDIR@
-RUBYINCLUDE = @RUBYINCLUDE@
-RUBYLIB = @RUBYLIB@
 SED = @SED@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
@@ -409,6 +407,8 @@ random_device = @random_device@
 resolv_conf = @resolv_conf@
 routing_table = @routing_table@
 routing_table_prio = @routing_table_prio@
+ruby_CFLAGS = @ruby_CFLAGS@
+ruby_LIBS = @ruby_LIBS@
 runstatedir = @runstatedir@
 s_plugins = @s_plugins@
 sbindir = @sbindir@
@@ -437,6 +437,10 @@ top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
 tss2_CFLAGS = @tss2_CFLAGS@
 tss2_LIBS = @tss2_LIBS@
+tss2_socket_CFLAGS = @tss2_socket_CFLAGS@
+tss2_socket_LIBS = @tss2_socket_LIBS@
+tss2_tabrmd_CFLAGS = @tss2_tabrmd_CFLAGS@
+tss2_tabrmd_LIBS = @tss2_tabrmd_LIBS@
 urandom_device = @urandom_device@
 xml_CFLAGS = @xml_CFLAGS@
 xml_LIBS = @xml_LIBS@
diff --git a/src/libtls/tls.h b/src/libtls/tls.h
index f3dc198..f832ef5 100644
--- a/src/libtls/tls.h
+++ b/src/libtls/tls.h
@@ -169,7 +169,7 @@ struct tls_t {
 	 * Query upper layer for one or more TLS records, build fragments.
 	 *
 	 * The TLS stack automatically fragments the records to the given buffer
-	 * size. Fragmentation is indicated by the reclen ouput parameter and
+	 * size. Fragmentation is indicated by the reclen output parameter and
 	 * the return value. For the first fragment of a TLS record, a non-zero
 	 * record length is returned in reclen. If more fragments follow, NEED_MORE
 	 * is returned. A return value of ALREADY_DONE indicates that the final
diff --git a/src/libtls/tls_aead.h b/src/libtls/tls_aead.h
index 8b5cda5..389a498 100644
--- a/src/libtls/tls_aead.h
+++ b/src/libtls/tls_aead.h
@@ -75,7 +75,7 @@ struct tls_aead_t {
 	size_t (*get_mac_key_size)(tls_aead_t *this);
 
 	/**
-	 * Get the encrytion key size, if used.
+	 * Get the encryption key size, if used.
 	 *
 	 * @return		key size, in bytes, 0 if not used
 	 */
diff --git a/src/libtnccs/Android.mk b/src/libtnccs/Android.mk
index e379732..ba74965 100644
--- a/src/libtnccs/Android.mk
+++ b/src/libtnccs/Android.mk
@@ -16,7 +16,7 @@ LOCAL_SRC_FILES := $(filter %.c,$(libtnccs_la_SOURCES))
 
 LOCAL_SRC_FILES += $(call add_plugin, tnc-imc)
 ifneq ($(call plugin_enabled, tnc-imc),)
-LOCAL_SHARED_LIBRARIES += libdl
+LOCAL_LDLIBS += -ldl
 endif
 
 LOCAL_SRC_FILES += $(call add_plugin, tnc-tnccs)
diff --git a/src/libtnccs/Makefile.in b/src/libtnccs/Makefile.in
index 653d841..9a7639e 100644
--- a/src/libtnccs/Makefile.in
+++ b/src/libtnccs/Makefile.in
@@ -367,8 +367,6 @@ RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
 RUBYGEMDIR = @RUBYGEMDIR@
-RUBYINCLUDE = @RUBYINCLUDE@
-RUBYLIB = @RUBYLIB@
 SED = @SED@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
@@ -469,6 +467,8 @@ random_device = @random_device@
 resolv_conf = @resolv_conf@
 routing_table = @routing_table@
 routing_table_prio = @routing_table_prio@
+ruby_CFLAGS = @ruby_CFLAGS@
+ruby_LIBS = @ruby_LIBS@
 runstatedir = @runstatedir@
 s_plugins = @s_plugins@
 sbindir = @sbindir@
@@ -497,6 +497,10 @@ top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
 tss2_CFLAGS = @tss2_CFLAGS@
 tss2_LIBS = @tss2_LIBS@
+tss2_socket_CFLAGS = @tss2_socket_CFLAGS@
+tss2_socket_LIBS = @tss2_socket_LIBS@
+tss2_tabrmd_CFLAGS = @tss2_tabrmd_CFLAGS@
+tss2_tabrmd_LIBS = @tss2_tabrmd_LIBS@
 urandom_device = @urandom_device@
 xml_CFLAGS = @xml_CFLAGS@
 xml_LIBS = @xml_LIBS@
diff --git a/src/libtnccs/plugins/tnc_imc/Makefile.in b/src/libtnccs/plugins/tnc_imc/Makefile.in
index 84dbf14..5824c45 100644
--- a/src/libtnccs/plugins/tnc_imc/Makefile.in
+++ b/src/libtnccs/plugins/tnc_imc/Makefile.in
@@ -315,8 +315,6 @@ RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
 RUBYGEMDIR = @RUBYGEMDIR@
-RUBYINCLUDE = @RUBYINCLUDE@
-RUBYLIB = @RUBYLIB@
 SED = @SED@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
@@ -417,6 +415,8 @@ random_device = @random_device@
 resolv_conf = @resolv_conf@
 routing_table = @routing_table@
 routing_table_prio = @routing_table_prio@
+ruby_CFLAGS = @ruby_CFLAGS@
+ruby_LIBS = @ruby_LIBS@
 runstatedir = @runstatedir@
 s_plugins = @s_plugins@
 sbindir = @sbindir@
@@ -445,6 +445,10 @@ top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
 tss2_CFLAGS = @tss2_CFLAGS@
 tss2_LIBS = @tss2_LIBS@
+tss2_socket_CFLAGS = @tss2_socket_CFLAGS@
+tss2_socket_LIBS = @tss2_socket_LIBS@
+tss2_tabrmd_CFLAGS = @tss2_tabrmd_CFLAGS@
+tss2_tabrmd_LIBS = @tss2_tabrmd_LIBS@
 urandom_device = @urandom_device@
 xml_CFLAGS = @xml_CFLAGS@
 xml_LIBS = @xml_LIBS@
diff --git a/src/libtnccs/plugins/tnc_imv/Makefile.in b/src/libtnccs/plugins/tnc_imv/Makefile.in
index 5fd128f..4de4bcc 100644
--- a/src/libtnccs/plugins/tnc_imv/Makefile.in
+++ b/src/libtnccs/plugins/tnc_imv/Makefile.in
@@ -316,8 +316,6 @@ RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
 RUBYGEMDIR = @RUBYGEMDIR@
-RUBYINCLUDE = @RUBYINCLUDE@
-RUBYLIB = @RUBYLIB@
 SED = @SED@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
@@ -418,6 +416,8 @@ random_device = @random_device@
 resolv_conf = @resolv_conf@
 routing_table = @routing_table@
 routing_table_prio = @routing_table_prio@
+ruby_CFLAGS = @ruby_CFLAGS@
+ruby_LIBS = @ruby_LIBS@
 runstatedir = @runstatedir@
 s_plugins = @s_plugins@
 sbindir = @sbindir@
@@ -446,6 +446,10 @@ top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
 tss2_CFLAGS = @tss2_CFLAGS@
 tss2_LIBS = @tss2_LIBS@
+tss2_socket_CFLAGS = @tss2_socket_CFLAGS@
+tss2_socket_LIBS = @tss2_socket_LIBS@
+tss2_tabrmd_CFLAGS = @tss2_tabrmd_CFLAGS@
+tss2_tabrmd_LIBS = @tss2_tabrmd_LIBS@
 urandom_device = @urandom_device@
 xml_CFLAGS = @xml_CFLAGS@
 xml_LIBS = @xml_LIBS@
diff --git a/src/libtnccs/plugins/tnc_tnccs/Makefile.in b/src/libtnccs/plugins/tnc_tnccs/Makefile.in
index acddd84..a8607d3 100644
--- a/src/libtnccs/plugins/tnc_tnccs/Makefile.in
+++ b/src/libtnccs/plugins/tnc_tnccs/Makefile.in
@@ -315,8 +315,6 @@ RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
 RUBYGEMDIR = @RUBYGEMDIR@
-RUBYINCLUDE = @RUBYINCLUDE@
-RUBYLIB = @RUBYLIB@
 SED = @SED@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
@@ -417,6 +415,8 @@ random_device = @random_device@
 resolv_conf = @resolv_conf@
 routing_table = @routing_table@
 routing_table_prio = @routing_table_prio@
+ruby_CFLAGS = @ruby_CFLAGS@
+ruby_LIBS = @ruby_LIBS@
 runstatedir = @runstatedir@
 s_plugins = @s_plugins@
 sbindir = @sbindir@
@@ -445,6 +445,10 @@ top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
 tss2_CFLAGS = @tss2_CFLAGS@
 tss2_LIBS = @tss2_LIBS@
+tss2_socket_CFLAGS = @tss2_socket_CFLAGS@
+tss2_socket_LIBS = @tss2_socket_LIBS@
+tss2_tabrmd_CFLAGS = @tss2_tabrmd_CFLAGS@
+tss2_tabrmd_LIBS = @tss2_tabrmd_LIBS@
 urandom_device = @urandom_device@
 xml_CFLAGS = @xml_CFLAGS@
 xml_LIBS = @xml_LIBS@
diff --git a/src/libtnccs/plugins/tnccs_11/Makefile.in b/src/libtnccs/plugins/tnccs_11/Makefile.in
index b6b8074..eac0e1f 100644
--- a/src/libtnccs/plugins/tnccs_11/Makefile.in
+++ b/src/libtnccs/plugins/tnccs_11/Makefile.in
@@ -325,8 +325,6 @@ RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
 RUBYGEMDIR = @RUBYGEMDIR@
-RUBYINCLUDE = @RUBYINCLUDE@
-RUBYLIB = @RUBYLIB@
 SED = @SED@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
@@ -427,6 +425,8 @@ random_device = @random_device@
 resolv_conf = @resolv_conf@
 routing_table = @routing_table@
 routing_table_prio = @routing_table_prio@
+ruby_CFLAGS = @ruby_CFLAGS@
+ruby_LIBS = @ruby_LIBS@
 runstatedir = @runstatedir@
 s_plugins = @s_plugins@
 sbindir = @sbindir@
@@ -455,6 +455,10 @@ top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
 tss2_CFLAGS = @tss2_CFLAGS@
 tss2_LIBS = @tss2_LIBS@
+tss2_socket_CFLAGS = @tss2_socket_CFLAGS@
+tss2_socket_LIBS = @tss2_socket_LIBS@
+tss2_tabrmd_CFLAGS = @tss2_tabrmd_CFLAGS@
+tss2_tabrmd_LIBS = @tss2_tabrmd_LIBS@
 urandom_device = @urandom_device@
 xml_CFLAGS = @xml_CFLAGS@
 xml_LIBS = @xml_LIBS@
diff --git a/src/libtnccs/plugins/tnccs_20/Makefile.in b/src/libtnccs/plugins/tnccs_20/Makefile.in
index 2a1d327..0d1e73a 100644
--- a/src/libtnccs/plugins/tnccs_20/Makefile.in
+++ b/src/libtnccs/plugins/tnccs_20/Makefile.in
@@ -328,8 +328,6 @@ RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
 RUBYGEMDIR = @RUBYGEMDIR@
-RUBYINCLUDE = @RUBYINCLUDE@
-RUBYLIB = @RUBYLIB@
 SED = @SED@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
@@ -430,6 +428,8 @@ random_device = @random_device@
 resolv_conf = @resolv_conf@
 routing_table = @routing_table@
 routing_table_prio = @routing_table_prio@
+ruby_CFLAGS = @ruby_CFLAGS@
+ruby_LIBS = @ruby_LIBS@
 runstatedir = @runstatedir@
 s_plugins = @s_plugins@
 sbindir = @sbindir@
@@ -458,6 +458,10 @@ top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
 tss2_CFLAGS = @tss2_CFLAGS@
 tss2_LIBS = @tss2_LIBS@
+tss2_socket_CFLAGS = @tss2_socket_CFLAGS@
+tss2_socket_LIBS = @tss2_socket_LIBS@
+tss2_tabrmd_CFLAGS = @tss2_tabrmd_CFLAGS@
+tss2_tabrmd_LIBS = @tss2_tabrmd_LIBS@
 urandom_device = @urandom_device@
 xml_CFLAGS = @xml_CFLAGS@
 xml_LIBS = @xml_LIBS@
diff --git a/src/libtnccs/plugins/tnccs_dynamic/Makefile.in b/src/libtnccs/plugins/tnccs_dynamic/Makefile.in
index 65201dd..ebe42fe 100644
--- a/src/libtnccs/plugins/tnccs_dynamic/Makefile.in
+++ b/src/libtnccs/plugins/tnccs_dynamic/Makefile.in
@@ -315,8 +315,6 @@ RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
 RUBYGEMDIR = @RUBYGEMDIR@
-RUBYINCLUDE = @RUBYINCLUDE@
-RUBYLIB = @RUBYLIB@
 SED = @SED@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
@@ -417,6 +415,8 @@ random_device = @random_device@
 resolv_conf = @resolv_conf@
 routing_table = @routing_table@
 routing_table_prio = @routing_table_prio@
+ruby_CFLAGS = @ruby_CFLAGS@
+ruby_LIBS = @ruby_LIBS@
 runstatedir = @runstatedir@
 s_plugins = @s_plugins@
 sbindir = @sbindir@
@@ -445,6 +445,10 @@ top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
 tss2_CFLAGS = @tss2_CFLAGS@
 tss2_LIBS = @tss2_LIBS@
+tss2_socket_CFLAGS = @tss2_socket_CFLAGS@
+tss2_socket_LIBS = @tss2_socket_LIBS@
+tss2_tabrmd_CFLAGS = @tss2_tabrmd_CFLAGS@
+tss2_tabrmd_LIBS = @tss2_tabrmd_LIBS@
 urandom_device = @urandom_device@
 xml_CFLAGS = @xml_CFLAGS@
 xml_LIBS = @xml_LIBS@
diff --git a/src/libtncif/Makefile.in b/src/libtncif/Makefile.in
index 2432a70..1fc797c 100644
--- a/src/libtncif/Makefile.in
+++ b/src/libtncif/Makefile.in
@@ -277,8 +277,6 @@ RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
 RUBYGEMDIR = @RUBYGEMDIR@
-RUBYINCLUDE = @RUBYINCLUDE@
-RUBYLIB = @RUBYLIB@
 SED = @SED@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
@@ -379,6 +377,8 @@ random_device = @random_device@
 resolv_conf = @resolv_conf@
 routing_table = @routing_table@
 routing_table_prio = @routing_table_prio@
+ruby_CFLAGS = @ruby_CFLAGS@
+ruby_LIBS = @ruby_LIBS@
 runstatedir = @runstatedir@
 s_plugins = @s_plugins@
 sbindir = @sbindir@
@@ -407,6 +407,10 @@ top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
 tss2_CFLAGS = @tss2_CFLAGS@
 tss2_LIBS = @tss2_LIBS@
+tss2_socket_CFLAGS = @tss2_socket_CFLAGS@
+tss2_socket_LIBS = @tss2_socket_LIBS@
+tss2_tabrmd_CFLAGS = @tss2_tabrmd_CFLAGS@
+tss2_tabrmd_LIBS = @tss2_tabrmd_LIBS@
 urandom_device = @urandom_device@
 xml_CFLAGS = @xml_CFLAGS@
 xml_LIBS = @xml_LIBS@
diff --git a/src/libtncif/tncif_pa_subtypes.c b/src/libtncif/tncif_pa_subtypes.c
index d83c325..2789e7d 100644
--- a/src/libtncif/tncif_pa_subtypes.c
+++ b/src/libtncif/tncif_pa_subtypes.c
@@ -1,6 +1,5 @@
 /*
- * Copyright (C) 2010-2015 Andreas Steffen
- *
+ * Copyright (C) 2010-2017 Andreas Steffen
  * HSR Hochschule fuer Technik Rapperswil
  *
  * This program is free software; you can redistribute it and/or modify it
@@ -17,7 +16,7 @@
 #include "tncif_pa_subtypes.h"
 
 /* IETF PA Subtype names */
-ENUM_BEGIN(pa_subtype_ietf_names, PA_SUBTYPE_IETF_TESTING, PA_SUBTYPE_IETF_NEA_CLIENT,
+ENUM_BEGIN(pa_subtype_ietf_names, PA_SUBTYPE_IETF_TESTING, PA_SUBTYPE_IETF_SW,
 	"Testing",
 	"Operating System",
 	"Anti-Virus",
@@ -26,10 +25,11 @@ ENUM_BEGIN(pa_subtype_ietf_names, PA_SUBTYPE_IETF_TESTING, PA_SUBTYPE_IETF_NEA_C
 	"Firewall",
 	"IDPS",
 	"VPN",
-	"NEA Client"
+	"NEA Client",
+	"Software"
 );
 ENUM_NEXT(pa_subtype_ietf_names, PA_SUBTYPE_IETF_ANY, PA_SUBTYPE_IETF_ANY,
-								PA_SUBTYPE_IETF_NEA_CLIENT,
+								PA_SUBTYPE_IETF_SW,
 	"ANY"
 );
 ENUM_END(pa_subtype_ietf_names, PA_SUBTYPE_IETF_ANY);
diff --git a/src/libtncif/tncif_pa_subtypes.h b/src/libtncif/tncif_pa_subtypes.h
index d6dcad0..6964410 100644
--- a/src/libtncif/tncif_pa_subtypes.h
+++ b/src/libtncif/tncif_pa_subtypes.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2011-2015 Andreas Steffen
+ * Copyright (C) 2011-2017 Andreas Steffen
  * HSR Hochschule fuer Technik Rapperswil
  *
  * This program is free software; you can redistribute it and/or modify it
@@ -43,6 +43,7 @@ typedef enum pa_subtype_ita_t pa_subtype_ita_t;
 	PA_SUBTYPE_IETF_IDPS =				0x06,
 	PA_SUBTYPE_IETF_VPN =				0x07,
 	PA_SUBTYPE_IETF_NEA_CLIENT =		0x08,
+	PA_SUBTYPE_IETF_SW =				0x09,
 	PA_SUBTYPE_IETF_ANY =				0xff
 };
 
diff --git a/src/libtpmtss/Makefile.in b/src/libtpmtss/Makefile.in
index 405d717..90d5e54 100644
--- a/src/libtpmtss/Makefile.in
+++ b/src/libtpmtss/Makefile.in
@@ -355,8 +355,6 @@ RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
 RUBYGEMDIR = @RUBYGEMDIR@
-RUBYINCLUDE = @RUBYINCLUDE@
-RUBYLIB = @RUBYLIB@
 SED = @SED@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
@@ -457,6 +455,8 @@ random_device = @random_device@
 resolv_conf = @resolv_conf@
 routing_table = @routing_table@
 routing_table_prio = @routing_table_prio@
+ruby_CFLAGS = @ruby_CFLAGS@
+ruby_LIBS = @ruby_LIBS@
 runstatedir = @runstatedir@
 s_plugins = @s_plugins@
 sbindir = @sbindir@
@@ -485,6 +485,10 @@ top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
 tss2_CFLAGS = @tss2_CFLAGS@
 tss2_LIBS = @tss2_LIBS@
+tss2_socket_CFLAGS = @tss2_socket_CFLAGS@
+tss2_socket_LIBS = @tss2_socket_LIBS@
+tss2_tabrmd_CFLAGS = @tss2_tabrmd_CFLAGS@
+tss2_tabrmd_LIBS = @tss2_tabrmd_LIBS@
 urandom_device = @urandom_device@
 xml_CFLAGS = @xml_CFLAGS@
 xml_LIBS = @xml_LIBS@
diff --git a/src/libtpmtss/plugins/tpm/Makefile.in b/src/libtpmtss/plugins/tpm/Makefile.in
index eb9489e..f80c0f7 100644
--- a/src/libtpmtss/plugins/tpm/Makefile.in
+++ b/src/libtpmtss/plugins/tpm/Makefile.in
@@ -312,8 +312,6 @@ RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
 RUBYGEMDIR = @RUBYGEMDIR@
-RUBYINCLUDE = @RUBYINCLUDE@
-RUBYLIB = @RUBYLIB@
 SED = @SED@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
@@ -414,6 +412,8 @@ random_device = @random_device@
 resolv_conf = @resolv_conf@
 routing_table = @routing_table@
 routing_table_prio = @routing_table_prio@
+ruby_CFLAGS = @ruby_CFLAGS@
+ruby_LIBS = @ruby_LIBS@
 runstatedir = @runstatedir@
 s_plugins = @s_plugins@
 sbindir = @sbindir@
@@ -442,6 +442,10 @@ top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
 tss2_CFLAGS = @tss2_CFLAGS@
 tss2_LIBS = @tss2_LIBS@
+tss2_socket_CFLAGS = @tss2_socket_CFLAGS@
+tss2_socket_LIBS = @tss2_socket_LIBS@
+tss2_tabrmd_CFLAGS = @tss2_tabrmd_CFLAGS@
+tss2_tabrmd_LIBS = @tss2_tabrmd_LIBS@
 urandom_device = @urandom_device@
 xml_CFLAGS = @xml_CFLAGS@
 xml_LIBS = @xml_LIBS@
diff --git a/src/libtpmtss/tpm_tss_tss2.c b/src/libtpmtss/tpm_tss_tss2.c
index 9a4b9a4..dcba05c 100644
--- a/src/libtpmtss/tpm_tss_tss2.c
+++ b/src/libtpmtss/tpm_tss_tss2.c
@@ -23,8 +23,18 @@
 #include <bio/bio_reader.h>
 
 #include <tpm20.h>
+
+#ifdef TSS2_TCTI_TABRMD
+#include <tcti/tcti-tabrmd.h>
+#endif /* TSS2_TCTI_TABRMD */
+
+#ifdef TSS2_TCTI_SOCKET
 #include <tcti_socket.h>
 
+#define TCTI_SOCKET_DEFAULT_ADDRESS "127.0.0.1"
+#define TCTI_SOCKET_DEFAULT_PORT     2323
+#endif /* TSS2_TCTI_SOCKET */
+
 #define LABEL	"TPM 2.0 -"
 
 typedef struct private_tpm_tss_tss2_t private_tpm_tss_tss2_t;
@@ -209,23 +219,52 @@ static bool get_algs_capability(private_tpm_tss_tss2_t *this)
 }
 
 /**
- * Initialize TSS context
+ * Initialize TSS2 TCTI TABRMD context
  */
-static bool initialize_context(private_tpm_tss_tss2_t *this)
+static bool initialize_tcti_tabrmd_context(private_tpm_tss_tss2_t *this)
 {
+#ifdef TSS2_TCTI_TABRMD
 	size_t   tcti_context_size;
-	uint32_t sys_context_size;
 	uint32_t rval;
 
-	TCTI_SOCKET_CONF rm_if_config = { DEFAULT_HOSTNAME,
-									  DEFAULT_RESMGR_TPM_PORT
-									};
+	/* determine size of tcti context */
+	rval = tss2_tcti_tabrmd_init(NULL, &tcti_context_size);
+	if (rval != TSS2_RC_SUCCESS)
+	{
+		DBG1(DBG_PTS, "%s could not get tcti_context size: 0x%06x",
+					   LABEL, rval);
+		return FALSE;
+	}
 
-	TSS2_ABI_VERSION abi_version = { TSSWG_INTEROP,
-									 TSS_SAPI_FIRST_FAMILY,
-									 TSS_SAPI_FIRST_LEVEL,
-									 TSS_SAPI_FIRST_VERSION
-								   };
+	/* allocate memory for tcti context */
+	this->tcti_context = (TSS2_TCTI_CONTEXT*)malloc(tcti_context_size);
+
+	/* initialize tcti context */
+	rval = tss2_tcti_tabrmd_init(this->tcti_context, &tcti_context_size);
+	if (rval != TSS2_RC_SUCCESS)
+	{
+		DBG1(DBG_PTS, "%s could not get tcti_context: 0x%06x "
+					  "via tabrmd interface", LABEL, rval);
+		return FALSE;
+	}
+	return TRUE;
+#else /* TSS2_TCTI_TABRMD */
+	return FALSE;
+#endif /* TSS2_TCTI_TABRMD */
+}
+
+/**
+ * Initialize TSS2 TCTI Socket context
+ */
+static bool initialize_tcti_socket_context(private_tpm_tss_tss2_t *this)
+{
+#ifdef TSS2_TCTI_SOCKET
+	size_t   tcti_context_size;
+	uint32_t rval;
+
+	TCTI_SOCKET_CONF rm_if_config = { TCTI_SOCKET_DEFAULT_ADDRESS,
+									  TCTI_SOCKET_DEFAULT_PORT
+									};
 
 	/* determine size of tcti context */
 	rval = InitSocketTcti(NULL, &tcti_context_size, &rm_if_config, 0);
@@ -244,10 +283,29 @@ static bool initialize_context(private_tpm_tss_tss2_t *this)
 						  &rm_if_config, 0);
 	if (rval != TSS2_RC_SUCCESS)
 	{
-		DBG1(DBG_PTS, "%s could not get tcti_context: 0x%06x",
-					   LABEL, rval);
+		DBG1(DBG_PTS, "%s could not get tcti_context: 0x%06x "
+					  "via socket interface", LABEL, rval);
 		return FALSE;
 	}
+	return TRUE;
+#else /* TSS2_TCTI_SOCKET */
+	return FALSE;
+#endif /* TSS2_TCTI_SOCKET */
+}
+
+/**
+ * Initialize TSS2 Sys context
+ */
+static bool initialize_sys_context(private_tpm_tss_tss2_t *this)
+{
+	uint32_t sys_context_size;
+	uint32_t rval;
+
+	TSS2_ABI_VERSION abi_version = { TSSWG_INTEROP,
+									 TSS_SAPI_FIRST_FAMILY,
+									 TSS_SAPI_FIRST_LEVEL,
+									 TSS_SAPI_FIRST_VERSION
+								   };
 
 	/* determine size of sys context */
 	sys_context_size = Tss2_Sys_GetContextSize(0);
@@ -885,7 +943,15 @@ tpm_tss_t *tpm_tss_tss2_create()
 		},
 	);
 
-	available = initialize_context(this);
+	available = initialize_tcti_tabrmd_context(this);
+	if (!available)
+	{
+		available = initialize_tcti_socket_context(this);
+	}
+	if (available)
+	{
+		available = initialize_sys_context(this);
+	}
 	DBG1(DBG_PTS, "TPM 2.0 via TSS2 %savailable", available ? "" : "not ");
 
 	if (!available)
diff --git a/src/manager/Makefile.in b/src/manager/Makefile.in
index 58c247e..0c128c1 100644
--- a/src/manager/Makefile.in
+++ b/src/manager/Makefile.in
@@ -329,8 +329,6 @@ RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
 RUBYGEMDIR = @RUBYGEMDIR@
-RUBYINCLUDE = @RUBYINCLUDE@
-RUBYLIB = @RUBYLIB@
 SED = @SED@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
@@ -431,6 +429,8 @@ random_device = @random_device@
 resolv_conf = @resolv_conf@
 routing_table = @routing_table@
 routing_table_prio = @routing_table_prio@
+ruby_CFLAGS = @ruby_CFLAGS@
+ruby_LIBS = @ruby_LIBS@
 runstatedir = @runstatedir@
 s_plugins = @s_plugins@
 sbindir = @sbindir@
@@ -459,6 +459,10 @@ top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
 tss2_CFLAGS = @tss2_CFLAGS@
 tss2_LIBS = @tss2_LIBS@
+tss2_socket_CFLAGS = @tss2_socket_CFLAGS@
+tss2_socket_LIBS = @tss2_socket_LIBS@
+tss2_tabrmd_CFLAGS = @tss2_tabrmd_CFLAGS@
+tss2_tabrmd_LIBS = @tss2_tabrmd_LIBS@
 urandom_device = @urandom_device@
 xml_CFLAGS = @xml_CFLAGS@
 xml_LIBS = @xml_LIBS@
diff --git a/src/medsrv/Makefile.in b/src/medsrv/Makefile.in
index 7561ad9..6ebe486 100644
--- a/src/medsrv/Makefile.in
+++ b/src/medsrv/Makefile.in
@@ -318,8 +318,6 @@ RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
 RUBYGEMDIR = @RUBYGEMDIR@
-RUBYINCLUDE = @RUBYINCLUDE@
-RUBYLIB = @RUBYLIB@
 SED = @SED@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
@@ -420,6 +418,8 @@ random_device = @random_device@
 resolv_conf = @resolv_conf@
 routing_table = @routing_table@
 routing_table_prio = @routing_table_prio@
+ruby_CFLAGS = @ruby_CFLAGS@
+ruby_LIBS = @ruby_LIBS@
 runstatedir = @runstatedir@
 s_plugins = @s_plugins@
 sbindir = @sbindir@
@@ -448,6 +448,10 @@ top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
 tss2_CFLAGS = @tss2_CFLAGS@
 tss2_LIBS = @tss2_LIBS@
+tss2_socket_CFLAGS = @tss2_socket_CFLAGS@
+tss2_socket_LIBS = @tss2_socket_LIBS@
+tss2_tabrmd_CFLAGS = @tss2_tabrmd_CFLAGS@
+tss2_tabrmd_LIBS = @tss2_tabrmd_LIBS@
 urandom_device = @urandom_device@
 xml_CFLAGS = @xml_CFLAGS@
 xml_LIBS = @xml_LIBS@
diff --git a/src/pki/Makefile.in b/src/pki/Makefile.in
index ed95d81..58de24a 100644
--- a/src/pki/Makefile.in
+++ b/src/pki/Makefile.in
@@ -331,8 +331,6 @@ RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
 RUBYGEMDIR = @RUBYGEMDIR@
-RUBYINCLUDE = @RUBYINCLUDE@
-RUBYLIB = @RUBYLIB@
 SED = @SED@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
@@ -433,6 +431,8 @@ random_device = @random_device@
 resolv_conf = @resolv_conf@
 routing_table = @routing_table@
 routing_table_prio = @routing_table_prio@
+ruby_CFLAGS = @ruby_CFLAGS@
+ruby_LIBS = @ruby_LIBS@
 runstatedir = @runstatedir@
 s_plugins = @s_plugins@
 sbindir = @sbindir@
@@ -461,6 +461,10 @@ top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
 tss2_CFLAGS = @tss2_CFLAGS@
 tss2_LIBS = @tss2_LIBS@
+tss2_socket_CFLAGS = @tss2_socket_CFLAGS@
+tss2_socket_LIBS = @tss2_socket_LIBS@
+tss2_tabrmd_CFLAGS = @tss2_tabrmd_CFLAGS@
+tss2_tabrmd_LIBS = @tss2_tabrmd_LIBS@
 urandom_device = @urandom_device@
 xml_CFLAGS = @xml_CFLAGS@
 xml_LIBS = @xml_LIBS@
diff --git a/src/pki/man/Makefile.in b/src/pki/man/Makefile.in
index a469f8b..bf8092b 100644
--- a/src/pki/man/Makefile.in
+++ b/src/pki/man/Makefile.in
@@ -268,8 +268,6 @@ RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
 RUBYGEMDIR = @RUBYGEMDIR@
-RUBYINCLUDE = @RUBYINCLUDE@
-RUBYLIB = @RUBYLIB@
 SED = @SED@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
@@ -370,6 +368,8 @@ random_device = @random_device@
 resolv_conf = @resolv_conf@
 routing_table = @routing_table@
 routing_table_prio = @routing_table_prio@
+ruby_CFLAGS = @ruby_CFLAGS@
+ruby_LIBS = @ruby_LIBS@
 runstatedir = @runstatedir@
 s_plugins = @s_plugins@
 sbindir = @sbindir@
@@ -398,6 +398,10 @@ top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
 tss2_CFLAGS = @tss2_CFLAGS@
 tss2_LIBS = @tss2_LIBS@
+tss2_socket_CFLAGS = @tss2_socket_CFLAGS@
+tss2_socket_LIBS = @tss2_socket_LIBS@
+tss2_tabrmd_CFLAGS = @tss2_tabrmd_CFLAGS@
+tss2_tabrmd_LIBS = @tss2_tabrmd_LIBS@
 urandom_device = @urandom_device@
 xml_CFLAGS = @xml_CFLAGS@
 xml_LIBS = @xml_LIBS@
diff --git a/src/pki/man/pki---print.1.in b/src/pki/man/pki---print.1.in
index 65fb8bc..ad85fb3 100644
--- a/src/pki/man/pki---print.1.in
+++ b/src/pki/man/pki---print.1.in
@@ -46,9 +46,9 @@ Input file. If not given the input is read from \fISTDIN\fR.
 .BI "\-t, \-\-type " type
 Type of input. One of \fIx509\fR (X.509 certificate), \fIcrl\fR (Certificate
 Revocation List, CRL), \fIac\fR (Attribute Certificate), \fIpub\fR (public key),
-\fpriv\fR (private key), \fIrsa\fR (RSA private key), \fIecdsa\fR (ECDSA private
-key), \fIed25519\fR (Ed25519 private key), \fIbliss\fR (BLISS private key),
-\fIpriv\fR (private key), defaults to \fIx509\fR.
+\fIpriv\fR (private key), \fIrsa\fR (RSA private key), \fIecdsa\fR (ECDSA
+private key), \fIed25519\fR (Ed25519 private key), \fIbliss\fR (BLISS private
+key), defaults to \fIx509\fR.
 .
 .SH "SEE ALSO"
 .
diff --git a/src/pool/Makefile.in b/src/pool/Makefile.in
index 415de55..1da001d 100644
--- a/src/pool/Makefile.in
+++ b/src/pool/Makefile.in
@@ -313,8 +313,6 @@ RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
 RUBYGEMDIR = @RUBYGEMDIR@
-RUBYINCLUDE = @RUBYINCLUDE@
-RUBYLIB = @RUBYLIB@
 SED = @SED@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
@@ -415,6 +413,8 @@ random_device = @random_device@
 resolv_conf = @resolv_conf@
 routing_table = @routing_table@
 routing_table_prio = @routing_table_prio@
+ruby_CFLAGS = @ruby_CFLAGS@
+ruby_LIBS = @ruby_LIBS@
 runstatedir = @runstatedir@
 s_plugins = @s_plugins@
 sbindir = @sbindir@
@@ -443,6 +443,10 @@ top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
 tss2_CFLAGS = @tss2_CFLAGS@
 tss2_LIBS = @tss2_LIBS@
+tss2_socket_CFLAGS = @tss2_socket_CFLAGS@
+tss2_socket_LIBS = @tss2_socket_LIBS@
+tss2_tabrmd_CFLAGS = @tss2_tabrmd_CFLAGS@
+tss2_tabrmd_LIBS = @tss2_tabrmd_LIBS@
 urandom_device = @urandom_device@
 xml_CFLAGS = @xml_CFLAGS@
 xml_LIBS = @xml_LIBS@
diff --git a/src/pt-tls-client/Makefile.am b/src/pt-tls-client/Makefile.am
index 8d1567e..a17b5dd 100644
--- a/src/pt-tls-client/Makefile.am
+++ b/src/pt-tls-client/Makefile.am
@@ -1,4 +1,4 @@
-ipsec_PROGRAMS = pt-tls-client
+bin_PROGRAMS = pt-tls-client
 
 pt_tls_client_SOURCES = pt-tls-client.c
 
@@ -19,3 +19,7 @@ pt_tls_client_LDADD = \
 	$(top_builddir)/src/libpttls/libpttls.la \
 	$(top_builddir)/src/libtnccs/libtnccs.la
 
+man1_MANS = pt-tls-client.1
+
+CLEANFILES = $(man1_MANS)
+
diff --git a/src/pt-tls-client/Makefile.in b/src/pt-tls-client/Makefile.in
index 7912c60..820bec9 100644
--- a/src/pt-tls-client/Makefile.in
+++ b/src/pt-tls-client/Makefile.in
@@ -88,7 +88,7 @@ PRE_UNINSTALL = :
 POST_UNINSTALL = :
 build_triplet = @build@
 host_triplet = @host@
-ipsec_PROGRAMS = pt-tls-client$(EXEEXT)
+bin_PROGRAMS = pt-tls-client$(EXEEXT)
 subdir = src/pt-tls-client
 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
 am__aclocal_m4_deps = $(top_srcdir)/m4/config/libtool.m4 \
@@ -106,10 +106,10 @@ am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
 DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON)
 mkinstalldirs = $(install_sh) -d
 CONFIG_HEADER = $(top_builddir)/config.h
-CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_FILES = pt-tls-client.1
 CONFIG_CLEAN_VPATH_FILES =
-am__installdirs = "$(DESTDIR)$(ipsecdir)"
-PROGRAMS = $(ipsec_PROGRAMS)
+am__installdirs = "$(DESTDIR)$(bindir)" "$(DESTDIR)$(man1dir)"
+PROGRAMS = $(bin_PROGRAMS)
 am_pt_tls_client_OBJECTS = pt-tls-client.$(OBJEXT)
 pt_tls_client_OBJECTS = $(am_pt_tls_client_OBJECTS)
 pt_tls_client_DEPENDENCIES =  \
@@ -162,6 +162,36 @@ am__can_run_installinfo = \
     n|no|NO) false;; \
     *) (install-info --version) >/dev/null 2>&1;; \
   esac
+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__uninstall_files_from_dir = { \
+  test -z "$$files" \
+    || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \
+    || { echo " ( cd '$$dir' && rm -f" $$files ")"; \
+         $(am__cd) "$$dir" && rm -f $$files; }; \
+  }
+man1dir = $(mandir)/man1
+NROFF = nroff
+MANS = $(man1_MANS)
 am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
 # Read a list of newline-separated strings from the standard input,
 # and print each of them once, without duplicates.  Input order is
@@ -181,7 +211,8 @@ am__define_uniq_tagged_files = \
   done | $(am__uniquify_input)`
 ETAGS = etags
 CTAGS = ctags
-am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/depcomp
+am__DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/pt-tls-client.1.in \
+	$(top_srcdir)/depcomp
 DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
 ACLOCAL = @ACLOCAL@
 ALLOCA = @ALLOCA@
@@ -282,8 +313,6 @@ RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
 RUBYGEMDIR = @RUBYGEMDIR@
-RUBYINCLUDE = @RUBYINCLUDE@
-RUBYLIB = @RUBYLIB@
 SED = @SED@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
@@ -384,6 +413,8 @@ random_device = @random_device@
 resolv_conf = @resolv_conf@
 routing_table = @routing_table@
 routing_table_prio = @routing_table_prio@
+ruby_CFLAGS = @ruby_CFLAGS@
+ruby_LIBS = @ruby_LIBS@
 runstatedir = @runstatedir@
 s_plugins = @s_plugins@
 sbindir = @sbindir@
@@ -412,6 +443,10 @@ top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
 tss2_CFLAGS = @tss2_CFLAGS@
 tss2_LIBS = @tss2_LIBS@
+tss2_socket_CFLAGS = @tss2_socket_CFLAGS@
+tss2_socket_LIBS = @tss2_socket_LIBS@
+tss2_tabrmd_CFLAGS = @tss2_tabrmd_CFLAGS@
+tss2_tabrmd_LIBS = @tss2_tabrmd_LIBS@
 urandom_device = @urandom_device@
 xml_CFLAGS = @xml_CFLAGS@
 xml_LIBS = @xml_LIBS@
@@ -431,6 +466,8 @@ pt_tls_client_LDADD = \
 	$(top_builddir)/src/libpttls/libpttls.la \
 	$(top_builddir)/src/libtnccs/libtnccs.la
 
+man1_MANS = pt-tls-client.1
+CLEANFILES = $(man1_MANS)
 all: all-am
 
 .SUFFIXES:
@@ -464,12 +501,14 @@ $(top_srcdir)/configure:  $(am__configure_deps)
 $(ACLOCAL_M4):  $(am__aclocal_m4_deps)
 	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
 $(am__aclocal_m4_deps):
-install-ipsecPROGRAMS: $(ipsec_PROGRAMS)
+pt-tls-client.1: $(top_builddir)/config.status $(srcdir)/pt-tls-client.1.in
+	cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@
+install-binPROGRAMS: $(bin_PROGRAMS)
 	@$(NORMAL_INSTALL)
-	@list='$(ipsec_PROGRAMS)'; test -n "$(ipsecdir)" || list=; \
+	@list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \
 	if test -n "$$list"; then \
-	  echo " $(MKDIR_P) '$(DESTDIR)$(ipsecdir)'"; \
-	  $(MKDIR_P) "$(DESTDIR)$(ipsecdir)" || exit 1; \
+	  echo " $(MKDIR_P) '$(DESTDIR)$(bindir)'"; \
+	  $(MKDIR_P) "$(DESTDIR)$(bindir)" || exit 1; \
 	fi; \
 	for p in $$list; do echo "$$p $$p"; done | \
 	sed 's/$(EXEEXT)$$//' | \
@@ -489,24 +528,24 @@ install-ipsecPROGRAMS: $(ipsec_PROGRAMS)
 	while read type dir files; do \
 	    if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \
 	    test -z "$$files" || { \
-	    echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(ipsecdir)$$dir'"; \
-	    $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(ipsecdir)$$dir" || exit $$?; \
+	    echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(bindir)$$dir'"; \
+	    $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(bindir)$$dir" || exit $$?; \
 	    } \
 	; done
 
-uninstall-ipsecPROGRAMS:
+uninstall-binPROGRAMS:
 	@$(NORMAL_UNINSTALL)
-	@list='$(ipsec_PROGRAMS)'; test -n "$(ipsecdir)" || list=; \
+	@list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \
 	files=`for p in $$list; do echo "$$p"; done | \
 	  sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \
 	      -e 's/$$/$(EXEEXT)/' \
 	`; \
 	test -n "$$list" || exit 0; \
-	echo " ( cd '$(DESTDIR)$(ipsecdir)' && rm -f" $$files ")"; \
-	cd "$(DESTDIR)$(ipsecdir)" && rm -f $$files
+	echo " ( cd '$(DESTDIR)$(bindir)' && rm -f" $$files ")"; \
+	cd "$(DESTDIR)$(bindir)" && rm -f $$files
 
-clean-ipsecPROGRAMS:
-	@list='$(ipsec_PROGRAMS)'; test -n "$$list" || exit 0; \
+clean-binPROGRAMS:
+	@list='$(bin_PROGRAMS)'; test -n "$$list" || exit 0; \
 	echo " rm -f" $$list; \
 	rm -f $$list || exit $$?; \
 	test -n "$(EXEEXT)" || exit 0; \
@@ -555,6 +594,47 @@ mostlyclean-libtool:
 
 clean-libtool:
 	-rm -rf .libs _libs
+install-man1: $(man1_MANS)
+	@$(NORMAL_INSTALL)
+	@list1='$(man1_MANS)'; \
+	list2=''; \
+	test -n "$(man1dir)" \
+	  && test -n "`echo $$list1$$list2`" \
+	  || exit 0; \
+	echo " $(MKDIR_P) '$(DESTDIR)$(man1dir)'"; \
+	$(MKDIR_P) "$(DESTDIR)$(man1dir)" || exit 1; \
+	{ for i in $$list1; do echo "$$i"; done;  \
+	if test -n "$$list2"; then \
+	  for i in $$list2; do echo "$$i"; done \
+	    | sed -n '/\.1[a-z]*$$/p'; \
+	fi; \
+	} | while read p; do \
+	  if test -f $$p; then d=; else d="$(srcdir)/"; fi; \
+	  echo "$$d$$p"; echo "$$p"; \
+	done | \
+	sed -e 'n;s,.*/,,;p;h;s,.*\.,,;s,^[^1][0-9a-z]*$$,1,;x' \
+	      -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,' | \
+	sed 'N;N;s,\n, ,g' | { \
+	list=; while read file base inst; do \
+	  if test "$$base" = "$$inst"; then list="$$list $$file"; else \
+	    echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man1dir)/$$inst'"; \
+	    $(INSTALL_DATA) "$$file" "$(DESTDIR)$(man1dir)/$$inst" || exit $$?; \
+	  fi; \
+	done; \
+	for i in $$list; do echo "$$i"; done | $(am__base_list) | \
+	while read files; do \
+	  test -z "$$files" || { \
+	    echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(man1dir)'"; \
+	    $(INSTALL_DATA) $$files "$(DESTDIR)$(man1dir)" || exit $$?; }; \
+	done; }
+
+uninstall-man1:
+	@$(NORMAL_UNINSTALL)
+	@list='$(man1_MANS)'; test -n "$(man1dir)" || exit 0; \
+	files=`{ for i in $$list; do echo "$$i"; done; \
+	} | sed -e 's,.*/,,;h;s,.*\.,,;s,^[^1][0-9a-z]*$$,1,;x' \
+	      -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,'`; \
+	dir='$(DESTDIR)$(man1dir)'; $(am__uninstall_files_from_dir)
 
 ID: $(am__tagged_files)
 	$(am__define_uniq_tagged_files); mkid -fID $$unique
@@ -640,9 +720,9 @@ distdir: $(DISTFILES)
 	done
 check-am: all-am
 check: check-am
-all-am: Makefile $(PROGRAMS)
+all-am: Makefile $(PROGRAMS) $(MANS)
 installdirs:
-	for dir in "$(DESTDIR)$(ipsecdir)"; do \
+	for dir in "$(DESTDIR)$(bindir)" "$(DESTDIR)$(man1dir)"; do \
 	  test -z "$$dir" || $(MKDIR_P) "$$dir"; \
 	done
 install: install-am
@@ -667,6 +747,7 @@ install-strip:
 mostlyclean-generic:
 
 clean-generic:
+	-test -z "$(CLEANFILES)" || rm -f $(CLEANFILES)
 
 distclean-generic:
 	-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
@@ -677,8 +758,7 @@ maintainer-clean-generic:
 	@echo "it deletes files that may require special tools to rebuild."
 clean: clean-am
 
-clean-am: clean-generic clean-ipsecPROGRAMS clean-libtool \
-	mostlyclean-am
+clean-am: clean-binPROGRAMS clean-generic clean-libtool mostlyclean-am
 
 distclean: distclean-am
 	-rm -rf ./$(DEPDIR)
@@ -698,13 +778,13 @@ info: info-am
 
 info-am:
 
-install-data-am: install-ipsecPROGRAMS
+install-data-am: install-man
 
 install-dvi: install-dvi-am
 
 install-dvi-am:
 
-install-exec-am:
+install-exec-am: install-binPROGRAMS
 
 install-html: install-html-am
 
@@ -714,7 +794,7 @@ install-info: install-info-am
 
 install-info-am:
 
-install-man:
+install-man: install-man1
 
 install-pdf: install-pdf-am
 
@@ -744,23 +824,26 @@ ps: ps-am
 
 ps-am:
 
-uninstall-am: uninstall-ipsecPROGRAMS
+uninstall-am: uninstall-binPROGRAMS uninstall-man
+
+uninstall-man: uninstall-man1
 
 .MAKE: install-am install-strip
 
-.PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \
-	clean-ipsecPROGRAMS clean-libtool cscopelist-am ctags ctags-am \
-	distclean distclean-compile distclean-generic \
+.PHONY: CTAGS GTAGS TAGS all all-am check check-am clean \
+	clean-binPROGRAMS clean-generic clean-libtool cscopelist-am \
+	ctags ctags-am 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-ipsecPROGRAMS install-man install-pdf \
-	install-pdf-am install-ps install-ps-am install-strip \
-	installcheck installcheck-am installdirs maintainer-clean \
-	maintainer-clean-generic mostlyclean mostlyclean-compile \
-	mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
-	tags tags-am uninstall uninstall-am uninstall-ipsecPROGRAMS
+	html-am info info-am install install-am install-binPROGRAMS \
+	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-man1 \
+	install-pdf install-pdf-am install-ps install-ps-am \
+	install-strip installcheck installcheck-am installdirs \
+	maintainer-clean maintainer-clean-generic mostlyclean \
+	mostlyclean-compile mostlyclean-generic mostlyclean-libtool \
+	pdf pdf-am ps ps-am tags tags-am uninstall uninstall-am \
+	uninstall-binPROGRAMS uninstall-man uninstall-man1
 
 .PRECIOUS: Makefile
 
diff --git a/src/pt-tls-client/pt-tls-client.1.in b/src/pt-tls-client/pt-tls-client.1.in
new file mode 100644
index 0000000..d7c9dff
--- /dev/null
+++ b/src/pt-tls-client/pt-tls-client.1.in
@@ -0,0 +1,130 @@
+.TH PT-TLS-CLIENT 1 "2017-07-15" "@PACKAGE_VERSION@" "strongSwan"
+.
+.SH "NAME"
+.
+pt-tls-client \- Simple client using PT-TLS to collect integrity information
+.
+.SH "SYNOPSIS"
+.
+.SY "pt-tls-client"
+.BI \-\-connect
+.IR hostname |\fIaddress
+.OP \-\-port hex
+.RB [ \-\-cert
+.IR file ]+
+.RB [ \-\-keyid
+.IR hex |\fB\-\-key
+.IR file ]
+.RB [ \-\-key-type
+.BR rsa |\fBecdsa\fR]
+.OP \-\-client client-id
+.OP \-\-secret password
+.OP \-\-mutual
+.OP \-\-optionsfrom filename
+.OP \-\-quiet
+.OP \-\-debug level
+.YS
+.
+.SY "pt-tls-client"
+.B \-h
+|
+.B \-\-help
+.YS
+.
+.SH "DESCRIPTION"
+.
+.B pt-tls-client
+is a simple client using the PT-TLS (RFC 6876) transport protocol to collect
+integrity measurements on the client platform. PT-TLS does an initial TLS
+handshake with certificate-based server authentication and optional
+certificate-based client authentication.  Alternatively simple password-based
+SASL client authentication protected by TLS can be used.
+.P
+Attribute requests and integrity measurements are exchanged via the PA-TNC (RFC
+5792) message protocol between any number of Integrity Measurement Verifiers
+(IMVs) residing on the remote PT-TLS server and multiple Integrity Measurement
+Collectors (IMCs) loaded dynamically by the PT-TLS client according to a list
+defined by \fI/etc/tnc_config\fR. PA-TNC messages that contain one or several
+PA-TNC attributes are multiplexed into PB-TNC (RFC 5793) client or server data
+batches which in turn are transported via PT-TLS.
+.
+.SH "OPTIONS"
+.
+.TP
+.B "\-h, \-\-help"
+Prints usage information and a short summary of the available commands.
+.TP
+.BI "\-c, \-\-connect " hostname\fR|\fIaddress
+Set the hostname or IP address of the PT-TLS server.
+.TP
+.BI "\-p, \-\-port " port
+Set the port of the PT-TLS server, default: 271.
+.TP
+.BI "\-x, \-\-cert " file
+Set the path to an X.509 certificate file. This option can be repeated to load
+multiple client and CA certificates.
+.TP
+.BI "\-k, \-\-key " file
+Set the path to the client's PKCS#1 or PKCS#8 private key file
+.TP
+.BI "\-t, \-\-key\-type " type
+Define the type of the private key if stored in PKCS#1 format. Can be omitted
+with PKCS#8 keys.
+.TP
+.BI "\-x, \-\-keyid " hex
+Set the keyid of the private key stored in a smartcard or a TPM 2.0 Trusted
+Platform Module.
+.TP
+.BI "\-i, \-\-client " client-id
+Set the username or client ID of the client required for password-based SASL
+authentication.
+.TP
+.BI "\-s, \-\-secret " password
+Set the preshared secret or client password required for password-based SASL
+authentication.
+.TP
+.B "\-q, \-\-mutual
+Enable mutual attestation between PT-TLS client and PT-TLS server.
+.TP
+.BI "\-v, \-\-debug " level
+Set debug level, default: 1.
+.TP
+.B "\-q, \-\-quiet
+Disable debug output to stderr.
+.TP
+.BI "\-+, \-\-optionsfrom " file
+Read command line options from \fIfile\fR.
+.
+.SH "EXAMPLES"
+.
+Connect to a PT-TLS server using certificate-based authentication,
+storing the private ECDSA key in a file:
+.PP
+.EX
+  pt-tls-client \-\-connect pdp.example.com \-\-cert ca.crt \\
+                \-\-cert client.crt \-\-key client.key \-\-key\-type ecdsa
+.EE
+.PP
+Connect to a PT-TLS server using certificate-based authentication,
+storing the private key in a smartcard or a TPM 2.0 Trusted Platform Module:
+.PP
+.EX
+  pt-tls-client \-\-connect pdp.example.com \-\-cert ca.crt \\
+                \-\-cert client.crt \-\-keyid 0x81010002
+.EE
+.PP
+Connect to a PT-TLS server listening on port 443, using SASL password-based
+authentication:
+.PP
+.EX
+  pt-tls-client \-\-connect pdp.example.com --port 443 \-\-cert ca.crt \\
+                \-\-client jane \-\-password p2Nl9trKlb
+.EE
+.SH FILES
+.TP
+/etc/tnc_config
+.
+.SH "SEE ALSO"
+.
+.BR strongswan.conf (5)
+
diff --git a/src/pt-tls-client/pt-tls-client.c b/src/pt-tls-client/pt-tls-client.c
index 6f200c3..d7e78c4 100644
--- a/src/pt-tls-client/pt-tls-client.c
+++ b/src/pt-tls-client/pt-tls-client.c
@@ -42,9 +42,10 @@ static void usage(FILE *out)
 {
 	fprintf(out,
 		"Usage: pt-tls  --connect <hostname|address> [--port <port>]\n"
-		"              [--cert <file>]+ [--key <file>] [--key-type rsa|ecdsa]\n"
-		"              [--client <client-id>] [--secret <password>]\n"
-		"              [--optionsfrom <filename>] [--quiet] [--debug <level>]\n");
+		"              [--cert <file>]+ [--keyid <hex>|--key <file>]\n"
+		"              [--key-type rsa|ecdsa] [--client <client-id>]\n"
+		"              [--secret <password>] [--mutual] [--quiet]\n"
+		"              [--debug <level>] [--optionsfrom <filename>]\n");
 }
 
 /**
@@ -121,15 +122,26 @@ static bool load_certificate(char *filename)
 /**
  * Load private key from file
  */
-static bool load_key(char *filename, key_type_t type)
+static bool load_key(char *keyid, char *filename, key_type_t type)
 {
 	private_key_t *key;
+	chunk_t chunk;
 
-	key = lib->creds->create(lib->creds, CRED_PRIVATE_KEY, type,
-							 BUILD_FROM_FILE, filename, BUILD_END);
+	if (keyid)
+	{
+		chunk = chunk_from_hex(chunk_create(keyid, strlen(keyid)), NULL);
+		key = lib->creds->create(lib->creds, CRED_PRIVATE_KEY, KEY_ANY,
+								 BUILD_PKCS11_KEYID, chunk, BUILD_END);
+		chunk_free(&chunk);
+	}
+	else
+	{
+		key = lib->creds->create(lib->creds, CRED_PRIVATE_KEY, type,
+								 BUILD_FROM_FILE, filename, BUILD_END);
+	}
 	if (!key)
 	{
-		DBG1(DBG_TLS, "loading key from '%s' failed", filename);
+		DBG1(DBG_TLS, "loading key from '%s' failed", keyid ? keyid : filename);
 		return FALSE;
 	}
 	creds->add_key(creds, key);
@@ -255,7 +267,8 @@ static void init()
 
 int main(int argc, char *argv[])
 {
-	char *address = NULL, *identity = "%any", *secret = NULL, *key_file = NULL;
+	char *address = NULL, *identity = "%any", *secret = NULL;
+	char *keyid = NULL, *key_file = NULL;
 	key_type_t key_type = KEY_RSA;
 	int port = PT_TLS_PORT;
 
@@ -270,15 +283,17 @@ int main(int argc, char *argv[])
 			{"secret",		required_argument,		NULL,		's' },
 			{"port",		required_argument,		NULL,		'p' },
 			{"cert",		required_argument,		NULL,		'x' },
+			{"keyid",		required_argument,		NULL,		'K' },
 			{"key",			required_argument,		NULL,		'k' },
-			{"key-type",		required_argument,		NULL,		't' },
+			{"key-type",	required_argument,		NULL,		't' },
 			{"mutual",		no_argument,			NULL,		'm' },
 			{"quiet",		no_argument,			NULL,		'q' },
 			{"debug",		required_argument,		NULL,		'd' },
 			{"optionsfrom",	required_argument,		NULL,		'+' },
 			{0,0,0,0 }
 		};
-		switch (getopt_long(argc, argv, "", long_opts, NULL))
+		switch (getopt_long(argc, argv, "hc:i:s:p:x:K:k:t:mqd:+:", long_opts,
+			    NULL))
 		{
 			case EOF:
 				break;
@@ -291,6 +306,9 @@ int main(int argc, char *argv[])
 					return 1;
 				}
 				continue;
+			case 'K':			/* --keyid <hex> */
+				keyid = optarg;
+				continue;
 			case 'k':			/* --key <file> */
 				key_file = optarg;
 				continue;
@@ -352,7 +370,7 @@ int main(int argc, char *argv[])
 		usage(stderr);
 		return 1;
 	}
-	if (key_file && !load_key(key_file, key_type))
+	if ((keyid || key_file) && !load_key(keyid, key_file, key_type))
 	{
 		return 1;
 	}
diff --git a/src/scepclient/Makefile.in b/src/scepclient/Makefile.in
index 9b2023f..85522ad 100644
--- a/src/scepclient/Makefile.in
+++ b/src/scepclient/Makefile.in
@@ -310,8 +310,6 @@ RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
 RUBYGEMDIR = @RUBYGEMDIR@
-RUBYINCLUDE = @RUBYINCLUDE@
-RUBYLIB = @RUBYLIB@
 SED = @SED@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
@@ -412,6 +410,8 @@ random_device = @random_device@
 resolv_conf = @resolv_conf@
 routing_table = @routing_table@
 routing_table_prio = @routing_table_prio@
+ruby_CFLAGS = @ruby_CFLAGS@
+ruby_LIBS = @ruby_LIBS@
 runstatedir = @runstatedir@
 s_plugins = @s_plugins@
 sbindir = @sbindir@
@@ -440,6 +440,10 @@ top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
 tss2_CFLAGS = @tss2_CFLAGS@
 tss2_LIBS = @tss2_LIBS@
+tss2_socket_CFLAGS = @tss2_socket_CFLAGS@
+tss2_socket_LIBS = @tss2_socket_LIBS@
+tss2_tabrmd_CFLAGS = @tss2_tabrmd_CFLAGS@
+tss2_tabrmd_LIBS = @tss2_tabrmd_LIBS@
 urandom_device = @urandom_device@
 xml_CFLAGS = @xml_CFLAGS@
 xml_LIBS = @xml_LIBS@
diff --git a/src/starter/Makefile.in b/src/starter/Makefile.in
index 97a0713..2fa22ae 100644
--- a/src/starter/Makefile.in
+++ b/src/starter/Makefile.in
@@ -355,8 +355,6 @@ RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
 RUBYGEMDIR = @RUBYGEMDIR@
-RUBYINCLUDE = @RUBYINCLUDE@
-RUBYLIB = @RUBYLIB@
 SED = @SED@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
@@ -457,6 +455,8 @@ random_device = @random_device@
 resolv_conf = @resolv_conf@
 routing_table = @routing_table@
 routing_table_prio = @routing_table_prio@
+ruby_CFLAGS = @ruby_CFLAGS@
+ruby_LIBS = @ruby_LIBS@
 runstatedir = @runstatedir@
 s_plugins = @s_plugins@
 sbindir = @sbindir@
@@ -485,6 +485,10 @@ top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
 tss2_CFLAGS = @tss2_CFLAGS@
 tss2_LIBS = @tss2_LIBS@
+tss2_socket_CFLAGS = @tss2_socket_CFLAGS@
+tss2_socket_LIBS = @tss2_socket_LIBS@
+tss2_tabrmd_CFLAGS = @tss2_tabrmd_CFLAGS@
+tss2_tabrmd_LIBS = @tss2_tabrmd_LIBS@
 urandom_device = @urandom_device@
 xml_CFLAGS = @xml_CFLAGS@
 xml_LIBS = @xml_LIBS@
diff --git a/src/starter/tests/Makefile.in b/src/starter/tests/Makefile.in
index 6ce8bda..fc5b863 100644
--- a/src/starter/tests/Makefile.in
+++ b/src/starter/tests/Makefile.in
@@ -307,8 +307,6 @@ RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
 RUBYGEMDIR = @RUBYGEMDIR@
-RUBYINCLUDE = @RUBYINCLUDE@
-RUBYLIB = @RUBYLIB@
 SED = @SED@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
@@ -409,6 +407,8 @@ random_device = @random_device@
 resolv_conf = @resolv_conf@
 routing_table = @routing_table@
 routing_table_prio = @routing_table_prio@
+ruby_CFLAGS = @ruby_CFLAGS@
+ruby_LIBS = @ruby_LIBS@
 runstatedir = @runstatedir@
 s_plugins = @s_plugins@
 sbindir = @sbindir@
@@ -437,6 +437,10 @@ top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
 tss2_CFLAGS = @tss2_CFLAGS@
 tss2_LIBS = @tss2_LIBS@
+tss2_socket_CFLAGS = @tss2_socket_CFLAGS@
+tss2_socket_LIBS = @tss2_socket_LIBS@
+tss2_tabrmd_CFLAGS = @tss2_tabrmd_CFLAGS@
+tss2_tabrmd_LIBS = @tss2_tabrmd_LIBS@
 urandom_device = @urandom_device@
 xml_CFLAGS = @xml_CFLAGS@
 xml_LIBS = @xml_LIBS@
diff --git a/src/stroke/Makefile.in b/src/stroke/Makefile.in
index 6af83d9..9d17733 100644
--- a/src/stroke/Makefile.in
+++ b/src/stroke/Makefile.in
@@ -281,8 +281,6 @@ RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
 RUBYGEMDIR = @RUBYGEMDIR@
-RUBYINCLUDE = @RUBYINCLUDE@
-RUBYLIB = @RUBYLIB@
 SED = @SED@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
@@ -383,6 +381,8 @@ random_device = @random_device@
 resolv_conf = @resolv_conf@
 routing_table = @routing_table@
 routing_table_prio = @routing_table_prio@
+ruby_CFLAGS = @ruby_CFLAGS@
+ruby_LIBS = @ruby_LIBS@
 runstatedir = @runstatedir@
 s_plugins = @s_plugins@
 sbindir = @sbindir@
@@ -411,6 +411,10 @@ top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
 tss2_CFLAGS = @tss2_CFLAGS@
 tss2_LIBS = @tss2_LIBS@
+tss2_socket_CFLAGS = @tss2_socket_CFLAGS@
+tss2_socket_LIBS = @tss2_socket_LIBS@
+tss2_tabrmd_CFLAGS = @tss2_tabrmd_CFLAGS@
+tss2_tabrmd_LIBS = @tss2_tabrmd_LIBS@
 urandom_device = @urandom_device@
 xml_CFLAGS = @xml_CFLAGS@
 xml_LIBS = @xml_LIBS@
diff --git a/src/sw-collector/Makefile.am b/src/sw-collector/Makefile.am
new file mode 100644
index 0000000..4ed73c9
--- /dev/null
+++ b/src/sw-collector/Makefile.am
@@ -0,0 +1,32 @@
+sbin_PROGRAMS = sw-collector
+
+sw_collector_SOURCES = \
+	sw-collector.c \
+	sw_collector_db.h sw_collector_db.c \
+	sw_collector_dpkg.h sw_collector_dpkg.c \
+	sw_collector_history.h sw_collector_history.c \
+	sw_collector_rest_api.h sw_collector_rest_api.c
+
+sw-collector.o : $(top_builddir)/config.status
+
+AM_CPPFLAGS = \
+	-I$(top_srcdir)/src/libstrongswan \
+	-I$(top_srcdir)/src/libtncif \
+	-I$(top_srcdir)/src/libimcv \
+	-DPLUGINS=\""random openssl sqlite curl"\"
+
+AM_CFLAGS = $(json_CFLAGS)
+
+sw_collector_LDADD = \
+	$(top_builddir)/src/libstrongswan/libstrongswan.la \
+	$(top_builddir)/src/libimcv/libimcv.la \
+	$(json_LIBS)
+
+templatesdir = $(pkgdatadir)/templates/database/sw-collector
+dist_templates_DATA = sw_collector_tables.sql
+
+man8_MANS = sw-collector.8
+
+CLEANFILES = $(man8_MANS)
+
+
diff --git a/src/charon-cmd/Makefile.in b/src/sw-collector/Makefile.in
similarity index 85%
copy from src/charon-cmd/Makefile.in
copy to src/sw-collector/Makefile.in
index e4d057f..73016ad 100644
--- a/src/charon-cmd/Makefile.in
+++ b/src/sw-collector/Makefile.in
@@ -14,6 +14,7 @@
 
 @SET_MAKE@
 
+
 VPATH = @srcdir@
 am__is_gnu_make = { \
   if test -z '$(MAKELEVEL)'; then \
@@ -88,8 +89,8 @@ PRE_UNINSTALL = :
 POST_UNINSTALL = :
 build_triplet = @build@
 host_triplet = @host@
-sbin_PROGRAMS = charon-cmd$(EXEEXT)
-subdir = src/charon-cmd
+sbin_PROGRAMS = sw-collector$(EXEEXT)
+subdir = src/sw-collector
 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
 am__aclocal_m4_deps = $(top_srcdir)/m4/config/libtool.m4 \
 	$(top_srcdir)/m4/config/ltoptions.m4 \
@@ -103,24 +104,23 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/config/libtool.m4 \
 	$(top_srcdir)/configure.ac
 am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
 	$(ACLOCAL_M4)
-DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON)
+DIST_COMMON = $(srcdir)/Makefile.am $(dist_templates_DATA) \
+	$(am__DIST_COMMON)
 mkinstalldirs = $(install_sh) -d
 CONFIG_HEADER = $(top_builddir)/config.h
-CONFIG_CLEAN_FILES = charon-cmd.8
+CONFIG_CLEAN_FILES = sw-collector.8
 CONFIG_CLEAN_VPATH_FILES =
-am__installdirs = "$(DESTDIR)$(sbindir)" "$(DESTDIR)$(man8dir)"
+am__installdirs = "$(DESTDIR)$(sbindir)" "$(DESTDIR)$(man8dir)" \
+	"$(DESTDIR)$(templatesdir)"
 PROGRAMS = $(sbin_PROGRAMS)
-am__dirstamp = $(am__leading_dot)dirstamp
-am_charon_cmd_OBJECTS = cmd/cmd_options.$(OBJEXT) \
-	cmd/cmd_connection.$(OBJEXT) cmd/cmd_creds.$(OBJEXT) \
-	charon-cmd.$(OBJEXT)
-charon_cmd_OBJECTS = $(am_charon_cmd_OBJECTS)
+am_sw_collector_OBJECTS = sw-collector.$(OBJEXT) \
+	sw_collector_db.$(OBJEXT) sw_collector_dpkg.$(OBJEXT) \
+	sw_collector_history.$(OBJEXT) sw_collector_rest_api.$(OBJEXT)
+sw_collector_OBJECTS = $(am_sw_collector_OBJECTS)
 am__DEPENDENCIES_1 =
-charon_cmd_DEPENDENCIES =  \
+sw_collector_DEPENDENCIES =  \
 	$(top_builddir)/src/libstrongswan/libstrongswan.la \
-	$(top_builddir)/src/libcharon/libcharon.la \
-	$(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
-	$(am__DEPENDENCIES_1)
+	$(top_builddir)/src/libimcv/libimcv.la $(am__DEPENDENCIES_1)
 AM_V_lt = $(am__v_lt_ at AM_V@)
 am__v_lt_ = $(am__v_lt_ at AM_DEFAULT_V@)
 am__v_lt_0 = --silent
@@ -159,8 +159,8 @@ AM_V_CCLD = $(am__v_CCLD_ at AM_V@)
 am__v_CCLD_ = $(am__v_CCLD_ at AM_DEFAULT_V@)
 am__v_CCLD_0 = @echo "  CCLD    " $@;
 am__v_CCLD_1 = 
-SOURCES = $(charon_cmd_SOURCES)
-DIST_SOURCES = $(charon_cmd_SOURCES)
+SOURCES = $(sw_collector_SOURCES)
+DIST_SOURCES = $(sw_collector_SOURCES)
 am__can_run_installinfo = \
   case $$AM_UPDATE_INFO_DIR in \
     n|no|NO) false;; \
@@ -196,6 +196,7 @@ am__uninstall_files_from_dir = { \
 man8dir = $(mandir)/man8
 NROFF = nroff
 MANS = $(man8_MANS)
+DATA = $(dist_templates_DATA)
 am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
 # Read a list of newline-separated strings from the standard input,
 # and print each of them once, without duplicates.  Input order is
@@ -215,7 +216,7 @@ am__define_uniq_tagged_files = \
   done | $(am__uniquify_input)`
 ETAGS = etags
 CTAGS = ctags
-am__DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/charon-cmd.8.in \
+am__DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/sw-collector.8.in \
 	$(top_srcdir)/depcomp
 DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
 ACLOCAL = @ACLOCAL@
@@ -317,8 +318,6 @@ RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
 RUBYGEMDIR = @RUBYGEMDIR@
-RUBYINCLUDE = @RUBYINCLUDE@
-RUBYLIB = @RUBYLIB@
 SED = @SED@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
@@ -419,6 +418,8 @@ random_device = @random_device@
 resolv_conf = @resolv_conf@
 routing_table = @routing_table@
 routing_table_prio = @routing_table_prio@
+ruby_CFLAGS = @ruby_CFLAGS@
+ruby_LIBS = @ruby_LIBS@
 runstatedir = @runstatedir@
 s_plugins = @s_plugins@
 sbindir = @sbindir@
@@ -447,29 +448,36 @@ top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
 tss2_CFLAGS = @tss2_CFLAGS@
 tss2_LIBS = @tss2_LIBS@
+tss2_socket_CFLAGS = @tss2_socket_CFLAGS@
+tss2_socket_LIBS = @tss2_socket_LIBS@
+tss2_tabrmd_CFLAGS = @tss2_tabrmd_CFLAGS@
+tss2_tabrmd_LIBS = @tss2_tabrmd_LIBS@
 urandom_device = @urandom_device@
 xml_CFLAGS = @xml_CFLAGS@
 xml_LIBS = @xml_LIBS@
-man8_MANS = charon-cmd.8
-CLEANFILES = $(man8_MANS)
-charon_cmd_SOURCES = \
-	cmd/cmd_options.h cmd/cmd_options.c \
-	cmd/cmd_connection.h cmd/cmd_connection.c \
-	cmd/cmd_creds.h cmd/cmd_creds.c \
-	charon-cmd.c
+sw_collector_SOURCES = \
+	sw-collector.c \
+	sw_collector_db.h sw_collector_db.c \
+	sw_collector_dpkg.h sw_collector_dpkg.c \
+	sw_collector_history.h sw_collector_history.c \
+	sw_collector_rest_api.h sw_collector_rest_api.c
 
 AM_CPPFLAGS = \
 	-I$(top_srcdir)/src/libstrongswan \
-	-I$(top_srcdir)/src/libcharon \
-	-DIPSEC_DIR=\"${ipsecdir}\" \
-	-DIPSEC_PIDDIR=\"${piddir}\" \
-	-DPLUGINS=\""${cmd_plugins}\""
+	-I$(top_srcdir)/src/libtncif \
+	-I$(top_srcdir)/src/libimcv \
+	-DPLUGINS=\""random openssl sqlite curl"\"
 
-charon_cmd_LDADD = \
+AM_CFLAGS = $(json_CFLAGS)
+sw_collector_LDADD = \
 	$(top_builddir)/src/libstrongswan/libstrongswan.la \
-	$(top_builddir)/src/libcharon/libcharon.la \
-	-lm $(PTHREADLIB) $(ATOMICLIB) $(DLLIB)
+	$(top_builddir)/src/libimcv/libimcv.la \
+	$(json_LIBS)
 
+templatesdir = $(pkgdatadir)/templates/database/sw-collector
+dist_templates_DATA = sw_collector_tables.sql
+man8_MANS = sw-collector.8
+CLEANFILES = $(man8_MANS)
 all: all-am
 
 .SUFFIXES:
@@ -483,9 +491,9 @@ $(srcdir)/Makefile.in:  $(srcdir)/Makefile.am  $(am__configure_deps)
 	      exit 1;; \
 	  esac; \
 	done; \
-	echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/charon-cmd/Makefile'; \
+	echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/sw-collector/Makefile'; \
 	$(am__cd) $(top_srcdir) && \
-	  $(AUTOMAKE) --gnu src/charon-cmd/Makefile
+	  $(AUTOMAKE) --gnu src/sw-collector/Makefile
 Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
 	@case '$?' in \
 	  *config.status*) \
@@ -503,7 +511,7 @@ $(top_srcdir)/configure:  $(am__configure_deps)
 $(ACLOCAL_M4):  $(am__aclocal_m4_deps)
 	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
 $(am__aclocal_m4_deps):
-charon-cmd.8: $(top_builddir)/config.status $(srcdir)/charon-cmd.8.in
+sw-collector.8: $(top_builddir)/config.status $(srcdir)/sw-collector.8.in
 	cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@
 install-sbinPROGRAMS: $(sbin_PROGRAMS)
 	@$(NORMAL_INSTALL)
@@ -554,34 +562,22 @@ clean-sbinPROGRAMS:
 	list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \
 	echo " rm -f" $$list; \
 	rm -f $$list
-cmd/$(am__dirstamp):
-	@$(MKDIR_P) cmd
-	@: > cmd/$(am__dirstamp)
-cmd/$(DEPDIR)/$(am__dirstamp):
-	@$(MKDIR_P) cmd/$(DEPDIR)
-	@: > cmd/$(DEPDIR)/$(am__dirstamp)
-cmd/cmd_options.$(OBJEXT): cmd/$(am__dirstamp) \
-	cmd/$(DEPDIR)/$(am__dirstamp)
-cmd/cmd_connection.$(OBJEXT): cmd/$(am__dirstamp) \
-	cmd/$(DEPDIR)/$(am__dirstamp)
-cmd/cmd_creds.$(OBJEXT): cmd/$(am__dirstamp) \
-	cmd/$(DEPDIR)/$(am__dirstamp)
-
-charon-cmd$(EXEEXT): $(charon_cmd_OBJECTS) $(charon_cmd_DEPENDENCIES) $(EXTRA_charon_cmd_DEPENDENCIES) 
-	@rm -f charon-cmd$(EXEEXT)
-	$(AM_V_CCLD)$(LINK) $(charon_cmd_OBJECTS) $(charon_cmd_LDADD) $(LIBS)
+
+sw-collector$(EXEEXT): $(sw_collector_OBJECTS) $(sw_collector_DEPENDENCIES) $(EXTRA_sw_collector_DEPENDENCIES) 
+	@rm -f sw-collector$(EXEEXT)
+	$(AM_V_CCLD)$(LINK) $(sw_collector_OBJECTS) $(sw_collector_LDADD) $(LIBS)
 
 mostlyclean-compile:
 	-rm -f *.$(OBJEXT)
-	-rm -f cmd/*.$(OBJEXT)
 
 distclean-compile:
 	-rm -f *.tab.c
 
- at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/charon-cmd.Po at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at cmd/$(DEPDIR)/cmd_connection.Po at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at cmd/$(DEPDIR)/cmd_creds.Po at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at cmd/$(DEPDIR)/cmd_options.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/sw-collector.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/sw_collector_db.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/sw_collector_dpkg.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/sw_collector_history.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/sw_collector_rest_api.Po at am__quote@
 
 .c.o:
 @am__fastdepCC_TRUE@	$(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\
@@ -653,6 +649,27 @@ uninstall-man8:
 	} | sed -e 's,.*/,,;h;s,.*\.,,;s,^[^8][0-9a-z]*$$,8,;x' \
 	      -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,'`; \
 	dir='$(DESTDIR)$(man8dir)'; $(am__uninstall_files_from_dir)
+install-dist_templatesDATA: $(dist_templates_DATA)
+	@$(NORMAL_INSTALL)
+	@list='$(dist_templates_DATA)'; test -n "$(templatesdir)" || list=; \
+	if test -n "$$list"; then \
+	  echo " $(MKDIR_P) '$(DESTDIR)$(templatesdir)'"; \
+	  $(MKDIR_P) "$(DESTDIR)$(templatesdir)" || exit 1; \
+	fi; \
+	for p in $$list; do \
+	  if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+	  echo "$$d$$p"; \
+	done | $(am__base_list) | \
+	while read files; do \
+	  echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(templatesdir)'"; \
+	  $(INSTALL_DATA) $$files "$(DESTDIR)$(templatesdir)" || exit $$?; \
+	done
+
+uninstall-dist_templatesDATA:
+	@$(NORMAL_UNINSTALL)
+	@list='$(dist_templates_DATA)'; test -n "$(templatesdir)" || list=; \
+	files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
+	dir='$(DESTDIR)$(templatesdir)'; $(am__uninstall_files_from_dir)
 
 ID: $(am__tagged_files)
 	$(am__define_uniq_tagged_files); mkid -fID $$unique
@@ -738,9 +755,9 @@ distdir: $(DISTFILES)
 	done
 check-am: all-am
 check: check-am
-all-am: Makefile $(PROGRAMS) $(MANS)
+all-am: Makefile $(PROGRAMS) $(MANS) $(DATA)
 installdirs:
-	for dir in "$(DESTDIR)$(sbindir)" "$(DESTDIR)$(man8dir)"; do \
+	for dir in "$(DESTDIR)$(sbindir)" "$(DESTDIR)$(man8dir)" "$(DESTDIR)$(templatesdir)"; do \
 	  test -z "$$dir" || $(MKDIR_P) "$$dir"; \
 	done
 install: install-am
@@ -770,8 +787,6 @@ 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)
-	-rm -f cmd/$(DEPDIR)/$(am__dirstamp)
-	-rm -f cmd/$(am__dirstamp)
 
 maintainer-clean-generic:
 	@echo "This command is intended for maintainers to use"
@@ -782,7 +797,7 @@ clean-am: clean-generic clean-libtool clean-sbinPROGRAMS \
 	mostlyclean-am
 
 distclean: distclean-am
-	-rm -rf ./$(DEPDIR) cmd/$(DEPDIR)
+	-rm -rf ./$(DEPDIR)
 	-rm -f Makefile
 distclean-am: clean-am distclean-compile distclean-generic \
 	distclean-tags
@@ -799,7 +814,7 @@ info: info-am
 
 info-am:
 
-install-data-am: install-man
+install-data-am: install-dist_templatesDATA install-man
 
 install-dvi: install-dvi-am
 
@@ -828,7 +843,7 @@ install-ps-am:
 installcheck-am:
 
 maintainer-clean: maintainer-clean-am
-	-rm -rf ./$(DEPDIR) cmd/$(DEPDIR)
+	-rm -rf ./$(DEPDIR)
 	-rm -f Makefile
 maintainer-clean-am: distclean-am maintainer-clean-generic
 
@@ -845,7 +860,8 @@ ps: ps-am
 
 ps-am:
 
-uninstall-am: uninstall-man uninstall-sbinPROGRAMS
+uninstall-am: uninstall-dist_templatesDATA uninstall-man \
+	uninstall-sbinPROGRAMS
 
 uninstall-man: uninstall-man8
 
@@ -856,20 +872,22 @@ uninstall-man: uninstall-man8
 	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-man8 install-pdf \
-	install-pdf-am install-ps install-ps-am install-sbinPROGRAMS \
-	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 tags-am uninstall uninstall-am \
-	uninstall-man uninstall-man8 uninstall-sbinPROGRAMS
+	install-data-am install-dist_templatesDATA install-dvi \
+	install-dvi-am install-exec install-exec-am install-html \
+	install-html-am install-info install-info-am install-man \
+	install-man8 install-pdf install-pdf-am install-ps \
+	install-ps-am install-sbinPROGRAMS 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 tags-am uninstall uninstall-am \
+	uninstall-dist_templatesDATA uninstall-man uninstall-man8 \
+	uninstall-sbinPROGRAMS
 
 .PRECIOUS: Makefile
 
 
-charon-cmd.o :	$(top_builddir)/config.status
+sw-collector.o : $(top_builddir)/config.status
 
 # 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/sw-collector/sw-collector.8.in b/src/sw-collector/sw-collector.8.in
new file mode 100644
index 0000000..8560ba0
--- /dev/null
+++ b/src/sw-collector/sw-collector.8.in
@@ -0,0 +1,124 @@
+.TH SW-COLLECTOR 1 "2017-07-15" "@PACKAGE_VERSION@" "strongSwan"
+.
+.SH "NAME"
+.
+sw-collector \- Extracts software installation events from dpkg history log
+.
+.SH "SYNOPSIS"
+.
+.SY "sw-collector"
+.OP \-\-debug level
+.OP \-\-quiet
+.OP \-\-count event-count
+.YS
+.
+.SY "sw-collector"
+.OP \-\-debug level
+.OP \-\-quiet
+.OP \-\-installed\fR|\fB\--removed
+.BR \-\-list |\fB\-\-unregistered
+.YS
+.
+.SY "sw-collector"
+.OP \-\-debug level
+.OP \-\-quiet
+.OP \-\-installed\fR|\fB\--removed
+.OP \-\-full
+.BR \-\-generate
+.YS
+.
+.SY "sw-collector"
+.OP \-\-debug level
+.OP \-\-quiet
+.BR \-\-migrate
+.YS
+.
+.SY "sw-collector"
+.B \-h
+|
+.B \-\-help
+.YS
+.
+.SH "DESCRIPTION"
+.
+.B sw-collector
+extracts information about software package installation, update or removal
+events from the apt history log and stores the software events in an SQLite
+database. The retrieved history information is then merged and made consistent
+with the actual list of installed software packages obtained with dpkg-query.
+.
+.SH "OPTIONS"
+.
+.TP
+.B "\-h, \-\-help"
+Prints usage information and a short summary of the available commands.
+.TP
+.BI "\-v, \-\-debug " level
+Set debug level, default: 2.
+.TP
+.B "\-q, \-\-quiet
+Disable debug output to stderr.
+.TP
+.B "\-i, \-\-installed
+Apply command to installed software packages, only.
+.TP
+.B "\-r, \-\-removed
+Apply command to removed software packages, only.
+.TP
+.B "\-f, \-\-full
+Generate ISO 19770-2:2015 SWID tags with full file information (possible for
+installed software packages, only).
+.TP
+.B "\-l, \-\-list
+Lists all software packages stored in the collector database showing their
+installation status.
+.TP
+.B "\-u, \-\-unregistered
+Lists all software packages residing in the local collector database but for
+which no SWID tags exist yet in a central collector database reachable via a
+REST interface. 
+.TP
+.B "\-g, \-\-generate
+Generates ISO 19770-2:2015 SWID tags for all software packages residing in the
+local collector database but for which no SWID tags exist in a central collector
+database reachable via a REST interface.
+.TP
+.B "\-m, \-\-migrate
+Can be used to migrate collector database versions. Currently all architecture
+suffixes are removed from dpkg package names.
+.
+.SH "CONFIGURATION"
+.
+The following parameters can be configured in strongswan.conf:
+.P
+ sw-collector {
+    database = sqlite:///etc/pts/collector.db
+    history = /var/log/apt/history.log
+    first_time = 2016-04-22T20:55:14Z
+    rest_api {
+       uri = https://admin-user:ietf99hackathon@tnc.strongswan.org/api/
+       timeout = 120
+    }
+ }
+.P
+The parameters of the swid_generator used with the \-\-generate command can
+be changed in the libimcv section of strongswan.conf:
+.P
+ libimcv {
+    swid_gen {
+       command = /usr/local/bin/swid_generator
+       tag_creator {
+          name = strongSwan Project
+          regid = strongswan.org
+       }
+    }
+ }
+.
+.SH "FILES"
+.
+ at PKGDATADIR@/templates/database/sw-collector/sw_collector_tables.sql
+.
+.SH "SEE ALSO"
+.
+.BR strongswan.conf (5)
+
diff --git a/src/sw-collector/sw-collector.c b/src/sw-collector/sw-collector.c
new file mode 100644
index 0000000..e673dd6
--- /dev/null
+++ b/src/sw-collector/sw-collector.c
@@ -0,0 +1,652 @@
+/*
+ * Copyright (C) 2017 Andreas Steffen
+ * HSR Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * for more details.
+ */
+
+#define _GNU_SOURCE
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+#include <getopt.h>
+#include <unistd.h>
+#ifdef HAVE_SYSLOG
+# include <syslog.h>
+#endif
+
+#include "sw_collector_db.h"
+#include "sw_collector_history.h"
+#include "sw_collector_rest_api.h"
+#include "sw_collector_dpkg.h"
+#
+#include <library.h>
+#include <utils/debug.h>
+#include <utils/lexparser.h>
+
+#include <swid_gen/swid_gen.h>
+
+/**
+ * global debug output variables
+ */
+static int debug_level = 2;
+static bool stderr_quiet = FALSE;
+static int count = 0;
+
+typedef enum collector_op_t collector_op_t;
+
+enum collector_op_t {
+	COLLECTOR_OP_EXTRACT,
+	COLLECTOR_OP_LIST,
+	COLLECTOR_OP_UNREGISTERED,
+	COLLECTOR_OP_GENERATE,
+	COLLECTOR_OP_MIGRATE
+};
+
+/**
+ * sw_collector dbg function
+ */
+static void sw_collector_dbg(debug_t group, level_t level, char *fmt, ...)
+{
+	va_list args;
+
+	if (level <= debug_level)
+	{
+		if (!stderr_quiet)
+		{
+			va_start(args, fmt);
+			vfprintf(stderr, fmt, args);
+			fprintf(stderr, "\n");
+			va_end(args);
+		}
+
+#ifdef HAVE_SYSLOG
+		{
+			int priority = LOG_INFO;
+			char buffer[8192];
+			char *current = buffer, *next;
+
+			/* write in memory buffer first */
+			va_start(args, fmt);
+			vsnprintf(buffer, sizeof(buffer), fmt, args);
+			va_end(args);
+
+			/* do a syslog with every line */
+			while (current)
+			{
+				next = strchr(current, '\n');
+				if (next)
+				{
+					*(next++) = '\0';
+				}
+				syslog(priority, "%s\n", current);
+				current = next;
+			}
+		}
+#endif /* HAVE_SYSLOG */
+	}
+}
+
+/**
+ * atexit handler
+ */
+static void cleanup(void)
+{
+	library_deinit();
+#ifdef HAVE_SYSLOG
+	closelog();
+#endif
+}
+
+/**
+ * Display usage of sw-collector command
+ */
+static void usage(void)
+{
+	printf("\
+Usage:\n\
+  sw-collector --help\n\
+  sw-collector [--debug <level>] [--quiet] [--count <event count>]\n\
+  sw-collector [--debug <level>] [--quiet] [--installed|--removed] \
+--list|-unregistered\n\
+  sw-collector [--debug <level>] [--quiet] [--installed|--removed] \
+[--full] --generate\n\
+  sw-collector [--debug <level>] [--quiet] --migrate\n");
+}
+
+/**
+ * Parse command line options
+ */
+static collector_op_t do_args(int argc, char *argv[], bool *full_tags,
+							  sw_collector_db_query_t *query_type)
+{
+	collector_op_t op = COLLECTOR_OP_EXTRACT;
+	bool installed = FALSE, removed = FALSE, full = FALSE;
+
+	/* reinit getopt state */
+	optind = 0;
+
+	while (TRUE)
+	{
+		int c;
+
+		struct option long_opts[] = {
+			{ "help", no_argument, NULL, 'h' },
+			{ "count", required_argument, NULL, 'c' },
+			{ "debug", required_argument, NULL, 'd' },
+			{ "full", no_argument, NULL, 'f' },
+			{ "generate", no_argument, NULL, 'g' },
+			{ "installed", no_argument, NULL, 'i' },
+			{ "list", no_argument, NULL, 'l' },
+			{ "migrate", no_argument, NULL, 'm' },
+			{ "quiet", no_argument, NULL, 'q' },
+			{ "removed", no_argument, NULL, 'r' },
+			{ "unregistered", no_argument, NULL, 'u' },
+			{ 0,0,0,0 }
+		};
+
+		c = getopt_long(argc, argv, "hc:d:fgilmqru", long_opts, NULL);
+		switch (c)
+		{
+			case EOF:
+				break;
+			case 'h':
+				usage();
+				exit(SUCCESS);
+				break;
+			case 'c':
+				count = atoi(optarg);
+				continue;
+			case 'd':
+				debug_level = atoi(optarg);
+				continue;
+			case 'f':
+				full = TRUE;
+				continue;
+			case 'g':
+				op = COLLECTOR_OP_GENERATE;
+				continue;
+			case 'i':
+				installed = TRUE;
+				continue;
+			case 'l':
+				op = COLLECTOR_OP_LIST;
+				continue;
+			case 'm':
+				op = COLLECTOR_OP_MIGRATE;
+				continue;
+			case 'q':
+				stderr_quiet = TRUE;
+				continue;
+			case 'r':
+				removed = TRUE;
+				continue;
+			case 'u':
+				op = COLLECTOR_OP_UNREGISTERED;
+				continue;
+			default:
+				usage();
+				exit(EXIT_FAILURE);
+		}
+		break;
+	}
+
+	if ((!installed && !removed) || (installed && removed))
+	{
+		*query_type = SW_QUERY_ALL;
+	}
+	else if (installed)
+	{
+		*query_type = SW_QUERY_INSTALLED;
+	}
+	else
+	{
+		*query_type = SW_QUERY_REMOVED;
+	}
+	*full_tags = full;
+
+	return op;
+}
+
+/**
+ * Extract software events from apt history log files
+ */
+static int extract_history(sw_collector_db_t *db)
+{
+	sw_collector_history_t *history = NULL;
+	uint32_t epoch, last_eid, eid = 0;
+	char *history_path, *last_time = NULL, rfc_time[21];
+	chunk_t *h, history_chunk, line, cmd;
+	int status = EXIT_FAILURE;
+	bool skip = TRUE;
+
+	/* open history file for reading */
+	history_path = lib->settings->get_str(lib->settings, "%s.history", NULL,
+										  lib->ns);
+	if (!history_path)
+	{
+		fprintf(stderr, "sw-collector.history path not set.\n");
+		return EXIT_FAILURE;
+	}
+	h = chunk_map(history_path, FALSE);
+	if (!h)
+	{
+		fprintf(stderr, "opening '%s' failed: %s", history_path,
+				strerror(errno));
+		return EXIT_FAILURE;
+	}
+	history_chunk = *h;
+
+	/* Instantiate history extractor */
+	history = sw_collector_history_create(db, 1);
+	if (!history)
+	{
+		return EXIT_FAILURE;
+	}
+
+	/* retrieve last event in database */
+	if (!db->get_last_event(db, &last_eid, &epoch, &last_time) || !last_eid)
+	{
+		goto end;
+	}
+	DBG0(DBG_IMC, "Last-Event: %s, eid = %u, epoch = %u",
+				   last_time, last_eid, epoch);
+
+	/* parse history file */
+	while (fetchline(&history_chunk, &line))
+	{
+		if (line.len == 0)
+		{
+			continue;
+		}
+		if (!extract_token(&cmd, ':', &line))
+		{
+			fprintf(stderr, "terminator symbol ':' not found.\n");
+			goto end;
+		}
+		if (match("Start-Date", &cmd))
+		{
+			if (!history->extract_timestamp(history, line, rfc_time))
+			{
+				goto end;
+			}
+
+			/* have we reached new history entries? */
+			if (skip && strcmp(rfc_time, last_time) > 0)
+			{
+				skip = FALSE;
+			}
+			if (skip)
+			{
+				continue;
+			}
+
+			/* insert new event into database */
+			eid = db->add_event(db, rfc_time);
+			if (!eid)
+			{
+				goto end;
+			}
+			DBG1(DBG_IMC, "Start-Date: %s, eid = %u, epoch = %u",
+						   rfc_time, eid, epoch);
+		}
+		else if (skip)
+		{
+			/* skip old history entries which have already been processed */
+			continue;
+		}
+		else if (match("Install", &cmd))
+		{
+			DBG1(DBG_IMC, "  Install:");
+			if (!history->extract_packages(history, line, eid, SW_OP_INSTALL))
+			{
+				goto end;
+			}
+		}
+		else if (match("Upgrade", &cmd))
+		{
+			DBG1(DBG_IMC, "  Upgrade:");
+			if (!history->extract_packages(history, line, eid, SW_OP_UPGRADE))
+			{
+				goto end;
+			}
+		}
+		else if (match("Remove", &cmd))
+		{
+			DBG1(DBG_IMC, "  Remove:");
+			if (!history->extract_packages(history, line, eid, SW_OP_REMOVE))
+			{
+				goto end;
+			}
+		}
+		else if (match("Purge", &cmd))
+		{
+			DBG1(DBG_IMC, "  Purge:");
+			if (!history->extract_packages(history, line, eid, SW_OP_REMOVE))
+			{
+				goto end;
+			}
+		}
+		else if (match("End-Date", &cmd))
+		{
+			/* Process 'count' events at a time */
+			if (count > 0 && eid - last_eid == count)
+			{
+				fprintf(stderr, "added %d events\n", count);
+				goto end;
+			}
+		}
+	}
+
+	if (history->merge_installed_packages(history))
+	{
+		status = EXIT_SUCCESS;
+	}
+
+end:
+	free(last_time);
+	history->destroy(history);
+	chunk_unmap(h);
+
+	return status;
+}
+
+/**
+ * List all endpoint software identifiers stored in local collector database
+ */
+static int list_identifiers(sw_collector_db_t *db, sw_collector_db_query_t type)
+{
+	enumerator_t *e;
+	char *name, *package, *version;
+	uint32_t sw_id, count = 0, installed_count = 0, removed_count, installed;
+
+	e = db->create_sw_enumerator(db, type, NULL);
+	if (!e)
+	{
+		return EXIT_FAILURE;
+	}
+	while (e->enumerate(e, &sw_id, &name, &package, &version, &installed))
+	{
+		printf("%s,%s,%s,%d\n", name, package, version, installed);
+		if (installed)
+		{
+			installed_count++;
+		}
+		count++;
+	}
+	removed_count = count - installed_count;
+	e->destroy(e);
+
+	switch (type)
+	{
+		case SW_QUERY_ALL:
+			DBG1(DBG_IMC, "retrieved %u software identities with %u installed "
+				 "and %u removed", count, installed_count, removed_count);
+			break;
+		case SW_QUERY_INSTALLED:
+			DBG1(DBG_IMC, "retrieved %u installed software identities", count);
+			break;
+		case SW_QUERY_REMOVED:
+			DBG1(DBG_IMC, "retrieved %u removed software identities", count);
+			break;
+	}
+
+	return EXIT_SUCCESS;
+}
+
+static bool query_registry(sw_collector_rest_api_t *rest_api, bool installed)
+{
+	sw_collector_db_query_t type;
+	enumerator_t *enumerator;
+	char *sw_id;
+	int count = 0;
+
+	type = installed ? SW_QUERY_INSTALLED : SW_QUERY_REMOVED;
+	enumerator = rest_api->create_sw_enumerator(rest_api, type);
+	if (!enumerator)
+	{
+		return FALSE;
+	}
+	while (enumerator->enumerate(enumerator, &sw_id))
+	{
+		printf("%s,%s\n", sw_id, installed ? "1" : "0");
+		count++;
+	}
+	enumerator->destroy(enumerator);
+	DBG1(DBG_IMC, "%d %s software identifiers not registered", count,
+				   installed ? "installed" : "removed");
+	return TRUE;
+}
+
+
+/**
+ * List all endpoint software identifiers stored in local collector database
+ * that are not registered yet in central collelector database
+ */
+static int unregistered_identifiers(sw_collector_db_t *db,
+									sw_collector_db_query_t type)
+{
+	sw_collector_rest_api_t *rest_api;
+	int status = EXIT_SUCCESS;
+
+	rest_api = sw_collector_rest_api_create(db);
+	if (!rest_api)
+	{
+		return EXIT_FAILURE;
+	}
+
+	/* List installed software identifiers not registered centrally */
+	if (type != SW_QUERY_REMOVED && !query_registry(rest_api, TRUE))
+	{
+		status = EXIT_FAILURE;
+	}
+
+	/* List removed software identifiers not registered centrally */
+	if (type != SW_QUERY_INSTALLED && !query_registry(rest_api, FALSE))
+	{
+		status = EXIT_FAILURE;
+	}
+	rest_api->destroy(rest_api);
+
+	return status;
+}
+
+/**
+ * Generate ISO 19770-2:2015 SWID tags for [installed|removed|all]
+ * SW identifiers that are not registered centrally
+ */
+static int generate_tags(sw_collector_db_t *db, bool full_tags,
+						 sw_collector_db_query_t type)
+{
+	swid_gen_t * swid_gen;
+	sw_collector_rest_api_t *rest_api;
+	char *name, *package, *version, *tag;
+	enumerator_t *enumerator;
+	uint32_t sw_id;
+	bool installed;
+	int count = 0, installed_count = 0, status = EXIT_FAILURE;
+
+	swid_gen = swid_gen_create();
+	rest_api = sw_collector_rest_api_create(db);
+	if (!rest_api)
+	{
+		goto end;
+	}
+
+	enumerator = rest_api->create_sw_enumerator(rest_api, type);
+	if (!enumerator)
+	{
+		goto end;
+	}
+	while (enumerator->enumerate(enumerator, &name))
+	{
+		sw_id = db->get_sw_id(db, name, &package, &version, NULL, &installed);
+		if (sw_id)
+		{
+			tag = swid_gen->generate_tag(swid_gen, name, package, version,
+										 full_tags && installed, FALSE);
+			if (tag)
+			{
+				DBG2(DBG_IMC, "  creating %s", name);
+				printf("%s\n", tag);
+				free(tag);
+				count++;
+				if (installed)
+				{
+					installed_count++;
+				}
+			}
+			free(package);
+			free(version);
+		}
+	}
+	enumerator->destroy(enumerator);
+	status = EXIT_SUCCESS;
+
+	switch (type)
+	{
+		case SW_QUERY_ALL:
+			DBG1(DBG_IMC, "created %d tags for unregistered software "
+				 "identifiers with %d installed and %d removed", count,
+				 installed_count,  count - installed_count);
+			break;
+		case SW_QUERY_INSTALLED:
+			DBG1(DBG_IMC, "created %d tags for unregistered installed software "
+				 "identifiers", count);
+			break;
+		case SW_QUERY_REMOVED:
+			DBG1(DBG_IMC, "created %d tags for unregistered removed software "
+				 "identifiers", count);
+			break;
+	}
+
+end:
+	swid_gen->destroy(swid_gen);
+	DESTROY_IF(rest_api);
+
+	return status;
+}
+
+/**
+ * Append missing architecture suffix to package entries in the database
+ */
+static int migrate(sw_collector_db_t *db)
+{
+	sw_collector_dpkg_t *dpkg;
+
+	char *package, *arch, *version;
+	char package_filter[BUF_LEN];
+	int res, count = 0;
+	int status = EXIT_SUCCESS;
+	enumerator_t *enumerator;
+
+	dpkg = sw_collector_dpkg_create();
+	if (!dpkg)
+	{
+		return FAILED;
+	}
+
+	enumerator = dpkg->create_sw_enumerator(dpkg);
+	while (enumerator->enumerate(enumerator, &package, &arch, &version))
+	{
+
+		/* Look for package names with architecture suffix */
+		snprintf(package_filter, BUF_LEN, "%s:%%", package);
+
+		res = db->update_package(db, package_filter, package);
+		if (res < 0)
+		{
+				status = EXIT_FAILURE;
+				break;
+		}
+		else if (res > 0)
+		{
+			count += res;
+			DBG2(DBG_IMC, "%s: removed arch suffix %d times", package, res);
+		}
+	}
+	enumerator->destroy(enumerator);
+	dpkg->destroy(dpkg);
+
+	DBG1(DBG_IMC, "migrated %d sw identifier records", count);
+
+	return status;
+}
+
+
+int main(int argc, char *argv[])
+{
+	sw_collector_db_t *db = NULL;
+	sw_collector_db_query_t query_type;
+	collector_op_t op;
+	bool full_tags;
+	char *uri;
+	int status = EXIT_FAILURE;
+
+	op = do_args(argc, argv, &full_tags, &query_type);
+
+	/* enable sw_collector debugging hook */
+	dbg = sw_collector_dbg;
+#ifdef HAVE_SYSLOG
+	openlog("sw-collector", 0, LOG_DEBUG);
+#endif
+
+	atexit(cleanup);
+
+	/* initialize library */
+	if (!library_init(NULL, "sw-collector"))
+	{
+		exit(SS_RC_LIBSTRONGSWAN_INTEGRITY);
+	}
+
+	/* load sw-collector plugins */
+	if (!lib->plugins->load(lib->plugins,
+			lib->settings->get_str(lib->settings, "%s.load", PLUGINS, lib->ns)))
+	{
+		exit(SS_RC_INITIALIZATION_FAILED);
+	}
+
+	/* connect to sw-collector database */
+	uri = lib->settings->get_str(lib->settings, "%s.database", NULL, lib->ns);
+	if (!uri)
+	{
+		fprintf(stderr, "sw-collector.database URI not set.\n");
+		exit(EXIT_FAILURE);
+	}
+	db = sw_collector_db_create(uri);
+	if (!db)
+	{
+		fprintf(stderr, "connection to sw-collector database failed.\n");
+		exit(EXIT_FAILURE);
+	}
+
+	switch (op)
+	{
+		case COLLECTOR_OP_EXTRACT:
+			status = extract_history(db);
+			break;
+		case COLLECTOR_OP_LIST:
+			status = list_identifiers(db, query_type);
+			break;
+		case COLLECTOR_OP_UNREGISTERED:
+			status = unregistered_identifiers(db, query_type);
+			break;
+		case COLLECTOR_OP_GENERATE:
+			status = generate_tags(db, full_tags, query_type);
+			break;
+		case COLLECTOR_OP_MIGRATE:
+			status = migrate(db);
+			break;
+	}
+	db->destroy(db);
+
+	exit(status);
+}
diff --git a/src/sw-collector/sw_collector_db.c b/src/sw-collector/sw_collector_db.c
new file mode 100644
index 0000000..554c3d6
--- /dev/null
+++ b/src/sw-collector/sw_collector_db.c
@@ -0,0 +1,427 @@
+/*
+ * Copyright (C) 2017 Andreas Steffen
+ * HSR Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * for more details.
+ */
+
+#define _GNU_SOURCE
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <time.h>
+
+#include "sw_collector_db.h"
+
+#include "swima/swima_event.h"
+
+typedef struct private_sw_collector_db_t private_sw_collector_db_t;
+
+/**
+ * Private data of an sw_collector_db_t object.
+ */
+struct private_sw_collector_db_t {
+
+	/**
+	 * Public members of sw_collector_db_state_t
+	 */
+	sw_collector_db_t public;
+
+	/**
+	 * Epoch
+	 */
+	uint32_t epoch;
+
+	/**
+	 * Event ID of last event stored in database
+	 */
+	uint32_t last_eid;
+
+	/**
+	 * Software collector database
+	 */
+	database_t *db;
+
+};
+
+METHOD(sw_collector_db_t, add_event, uint32_t,
+	private_sw_collector_db_t *this, char *timestamp)
+{
+	uint32_t eid = 0;
+
+	if (this->db->execute(this->db, &eid,
+			"INSERT INTO events (epoch, timestamp) VALUES (?, ?)",
+			 DB_UINT, this->epoch, DB_TEXT, timestamp) != 1)
+	{
+		DBG1(DBG_IMC, "unable to insert event into database");
+		return 0;
+	}
+
+	return eid;
+}
+
+METHOD(sw_collector_db_t, get_last_event, bool,
+	private_sw_collector_db_t *this, uint32_t *eid, uint32_t *epoch,
+	char **last_time)
+{
+	char *timestamp;
+	enumerator_t *e;
+
+	e = this->db->query(this->db,
+			"SELECT id, epoch, timestamp FROM events ORDER BY timestamp DESC",
+			DB_UINT, DB_UINT, DB_TEXT);
+	if (!e)
+	{
+		DBG1(DBG_IMC, "database query for event failed");
+		return FALSE;
+	}
+	if (e->enumerate(e, eid, epoch, &timestamp))
+	{
+		if (last_time)
+		{
+			*last_time = strdup(timestamp);
+		}
+	}
+	else
+	{
+		*eid = 0;
+	}
+	e->destroy(e);
+
+	return TRUE;
+}
+
+METHOD(sw_collector_db_t, add_sw_event, bool,
+	private_sw_collector_db_t *this, uint32_t eid, uint32_t sw_id,
+	uint8_t action)
+{
+	if (this->db->execute(this->db, NULL,
+			"INSERT INTO sw_events (eid, sw_id, action) VALUES (?, ?, ?)",
+			 DB_UINT, eid, DB_UINT, sw_id, DB_UINT, action) != 1)
+	{
+		DBG1(DBG_IMC, "unable to insert sw_event into database");
+		return FALSE;
+	}
+
+	return TRUE;
+}
+
+METHOD(sw_collector_db_t, set_sw_id, uint32_t,
+	private_sw_collector_db_t *this, char *name,  char *package, char *version,
+	uint8_t source, bool installed)
+{
+	uint32_t sw_id;
+
+	if (this->db->execute(this->db, &sw_id,
+			"INSERT INTO sw_identifiers "
+			"(name, package, version, source, installed) VALUES (?, ?, ?, ?, ?)",
+			 DB_TEXT, name, DB_TEXT, package, DB_TEXT, version, DB_UINT, source,
+			 DB_UINT, installed) != 1)
+	{
+		DBG1(DBG_IMC, "unable to insert sw_id into database");
+		return 0;
+	}
+
+	return sw_id;
+}
+
+METHOD(sw_collector_db_t, get_sw_id, uint32_t,
+	private_sw_collector_db_t *this, char *name, char **package, char **version,
+	uint8_t *source, bool *installed)
+{
+	char *sw_package, *sw_version;
+	uint32_t sw_id = 0, sw_source, sw_installed;
+	enumerator_t *e;
+
+	/* Does software identifier already exist in database? */
+	e = this->db->query(this->db,
+			"SELECT id, package, version, source, installed "
+			"FROM sw_identifiers WHERE name = ?",
+			DB_TEXT, name, DB_UINT, DB_TEXT, DB_TEXT, DB_UINT, DB_UINT);
+	if (!e)
+	{
+		DBG1(DBG_IMC, "database query for sw_identifier failed");
+		return 0;
+	}
+	if (e->enumerate(e, &sw_id, &sw_package, &sw_version, &sw_source,
+						&sw_installed))
+	{
+		if (package)
+		{
+			*package = strdup(sw_package);
+		}
+		if (version)
+		{
+			*version = strdup(sw_version);
+		}
+		if (source)
+		{
+			*source = sw_source;
+		}
+		if (installed)
+		{
+			*installed = sw_installed;
+		}
+	}
+	e->destroy(e);
+
+	return sw_id;
+}
+
+METHOD(sw_collector_db_t, get_sw_id_count, uint32_t,
+	private_sw_collector_db_t *this, sw_collector_db_query_t type)
+{
+	uint32_t count, installed;
+	enumerator_t *e;
+
+	if (type == SW_QUERY_ALL)
+	{
+		e = this->db->query(this->db,
+			"SELECT COUNT(installed) FROM sw_identifiers", DB_UINT);
+	}
+	else
+	{
+		installed = (type == SW_QUERY_INSTALLED);
+		e = this->db->query(this->db,
+			"SELECT COUNT(installed) FROM sw_identifiers WHERE installed = ?",
+			 DB_UINT, installed, DB_UINT);
+	}
+
+	if (!e)
+	{
+		DBG1(DBG_IMC, "database query for sw_identifier count failed");
+		return 0;
+	}
+	if (!e->enumerate(e, &count))
+	{
+		count = 0;
+	}
+	e->destroy(e);
+
+	return count;
+}
+
+METHOD(sw_collector_db_t, update_sw_id, bool,
+	private_sw_collector_db_t *this, uint32_t sw_id, char *name, char *version,
+	bool installed)
+{
+	int res;
+
+	if (name && version)
+	{
+		res = this->db->execute(this->db, NULL,
+			"UPDATE sw_identifiers SET name = ?, version = ?, installed = ? "
+			"WHERE id = ?", DB_TEXT, name, DB_TEXT, version, DB_UINT, installed,
+			 DB_UINT, sw_id);
+	}
+	else
+	{
+		res = this->db->execute(this->db, NULL,
+			"UPDATE sw_identifiers SET installed = ? WHERE id = ?",
+			 DB_UINT, installed, DB_UINT, sw_id);
+	}
+	if (res != 1)
+	{
+		DBG1(DBG_IMC, "unable to update software identifier in database");
+		return FALSE;
+	}
+	return TRUE;
+}
+
+METHOD(sw_collector_db_t, update_package, int,
+	private_sw_collector_db_t *this, char *package_filter, char *package)
+{
+	int count;
+
+	count = this->db->execute(this->db, NULL,
+			"UPDATE sw_identifiers SET package = ? WHERE package LIKE ?",
+			 DB_TEXT, package, DB_TEXT, package_filter);
+	if (count < 0)
+	{
+		DBG1(DBG_IMC, "unable to update package name in database");
+	}
+
+	return count;
+}
+
+METHOD(sw_collector_db_t, create_sw_enumerator, enumerator_t*,
+	private_sw_collector_db_t *this, sw_collector_db_query_t type, char *package)
+{
+	enumerator_t *e;
+	u_int installed;
+
+	if (type == SW_QUERY_ALL)
+	{
+		if (package)
+		{
+			e = this->db->query(this->db,
+				"SELECT id, name, package, version, installed "
+				"FROM sw_identifiers WHERE package = ? ORDER BY name ASC",
+				 DB_TEXT, package, DB_UINT, DB_TEXT, DB_TEXT, DB_TEXT, DB_UINT);
+		}
+		else
+		{
+			e = this->db->query(this->db,
+				"SELECT id, name, package, version, installed "
+				"FROM sw_identifiers ORDER BY name ASC",
+				 DB_UINT, DB_TEXT, DB_TEXT, DB_TEXT, DB_UINT);
+		}
+	}
+	else
+	{
+		installed = (type == SW_QUERY_INSTALLED);
+
+		if (package)
+		{
+			e = this->db->query(this->db,
+				"SELECT id, name, package, version, installed "
+				"FROM sw_identifiers WHERE package = ? AND installed = ? "
+				"ORDER BY name ASC", DB_TEXT, package, DB_UINT, installed,
+				 DB_UINT, DB_TEXT, DB_TEXT, DB_TEXT, DB_UINT);
+		}
+		else
+		{
+			e = this->db->query(this->db,
+				"SELECT id, name, package, version, installed "
+				"FROM sw_identifiers WHERE installed = ? ORDER BY name ASC",
+				 DB_UINT, installed, DB_UINT, DB_TEXT, DB_TEXT, DB_TEXT, DB_UINT);
+		}
+	}
+	if (!e)
+	{
+		DBG1(DBG_IMC, "database query for sw_identifier count failed");
+		return NULL;
+	}
+
+	return e;
+}
+
+METHOD(sw_collector_db_t, destroy, void,
+	private_sw_collector_db_t *this)
+{
+	this->db->destroy(this->db);
+	free(this);
+}
+
+/**
+ * Determine file creation data and convert it into RFC 3339 format
+ */
+bool get_file_creation_date(char *pathname, char *timestamp)
+{
+	struct stat st;
+	struct tm ct;
+
+	if (stat(pathname, &st))
+	{
+		DBG1(DBG_IMC, "unable to obtain statistics on '%s'", pathname);
+		return FALSE;
+	}
+
+	/* Convert from local time to UTC */
+	gmtime_r(&st.st_mtime, &ct);
+	ct.tm_year += 1900;
+	ct.tm_mon += 1;
+
+	/* Form timestamp according to RFC 3339 (20 characters) */
+	snprintf(timestamp, 21, "%4d-%02d-%02dT%02d:%02d:%02dZ",
+			 ct.tm_year, ct.tm_mon, ct.tm_mday,
+			 ct.tm_hour, ct.tm_min, ct.tm_sec);
+
+	return TRUE;
+}
+
+/**
+ * Described in header.
+ */
+sw_collector_db_t *sw_collector_db_create(char *uri)
+{
+	private_sw_collector_db_t *this;
+	uint32_t first_eid, last_eid;
+	char first_time_buf[21], *first_time, *first_file;
+
+	INIT(this,
+		.public = {
+			.add_event = _add_event,
+			.get_last_event = _get_last_event,
+			.add_sw_event = _add_sw_event,
+			.set_sw_id = _set_sw_id,
+			.get_sw_id = _get_sw_id,
+			.get_sw_id_count = _get_sw_id_count,
+			.update_sw_id = _update_sw_id,
+			.update_package = _update_package,
+			.create_sw_enumerator = _create_sw_enumerator,
+			.destroy = _destroy,
+		},
+		.db = lib->db->create(lib->db, uri),
+	);
+
+	if (!this->db)
+	{
+		DBG1(DBG_IMC, "opening database URI '%s' failed", uri);
+		free(this);
+		return NULL;
+	}
+
+	/* Retrieve last event in database */
+	if (!get_last_event(this, &last_eid, &this->epoch, NULL))
+	{
+		destroy(this);
+		return NULL;
+	}
+
+	/* Create random epoch and first event if no events exist yet */
+	if (!last_eid)
+	{
+		rng_t *rng;
+
+		rng = lib->crypto->create_rng(lib->crypto, RNG_STRONG);
+		if (!rng ||
+			!rng->get_bytes(rng, sizeof(uint32_t), (uint8_t*)&this->epoch))
+		{
+			DESTROY_IF(rng);
+			destroy(this);
+			DBG1(DBG_IMC, "generating random epoch value failed");
+			return NULL;
+		}
+		rng->destroy(rng);
+
+		/* strongTNC workaround - limit epoch to 31 bit unsigned integer */
+		this->epoch &= 0x7fffffff;
+
+		/* Create first event when the OS was installed */
+		first_file = lib->settings->get_str(lib->settings,
+						"sw-collector.first_file", "/var/log/bootstrap.log");
+		first_time = lib->settings->get_str(lib->settings,
+						"sw-collector.first_time", NULL);
+		if (!first_time)
+		{
+			if (get_file_creation_date(first_file, first_time_buf))
+			{
+				first_time = first_time_buf;
+			}
+			else
+			{
+				first_time = "0000-00-00T00:00:00Z";
+			}
+		}
+		first_eid = add_event(this, first_time);
+
+		if (!first_eid)
+		{
+			destroy(this);
+			return NULL;
+		}
+		DBG0(DBG_IMC, "First-Date: %s, eid = %u, epoch = %u",
+					   first_time, first_eid, this->epoch);
+	}
+
+	return &this->public;
+}
diff --git a/src/sw-collector/sw_collector_db.h b/src/sw-collector/sw_collector_db.h
new file mode 100644
index 0000000..e3b56af
--- /dev/null
+++ b/src/sw-collector/sw_collector_db.h
@@ -0,0 +1,155 @@
+/*
+ * Copyright (C) 2017 Andreas Steffen
+ * HSR Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT 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 sw_collector_db_t sw_collector_db
+ * @{ @ingroup sw_collector
+ */
+
+#ifndef SW_COLLECTOR_DB_H_
+#define SW_COLLECTOR_DB_H_
+
+#include <library.h>
+
+typedef struct sw_collector_db_t sw_collector_db_t;
+typedef enum sw_collector_db_query_t sw_collector_db_query_t;
+
+/**
+ * Type of software identifier queries
+ */
+enum sw_collector_db_query_t {
+	SW_QUERY_ALL,
+	SW_QUERY_INSTALLED,
+	SW_QUERY_REMOVED
+};
+
+/**
+ * Software collector database object
+ */
+struct sw_collector_db_t {
+
+	/**
+	 * bAdd event to database
+	 *
+	 * @param timestamp		Timestamp in 20 octet RFC 3339 format
+	 * @return				Primary key pointing to event ID or 0 if failed
+	 */
+	uint32_t (*add_event)(sw_collector_db_t *this, char *timestamp);
+
+	/**
+	 * Get last event, zero EID if none exists
+	 *
+	 * @param eid			Primary key pointing to last event
+	 * @param epoch			Epoch
+	 * @param last_time		Timestamp in 20 octet RFC 3339 format of last event
+	 * @return
+	 */
+	bool (*get_last_event)(sw_collector_db_t *this, uint32_t *eid,
+							   uint32_t *epoch, char **last_time);
+
+	/**
+	 * Add software identifier event to database
+	 *
+	 * @param eid			Foreign key pointing to an event ID
+	 * @param sw_id			Foreign key pointing to a software identifier
+	 * @param action		1 for CREATION, 2 for deletion
+	 * @return				TRUE if successful
+	 */
+	bool (*add_sw_event)(sw_collector_db_t *this, uint32_t eid, uint32_t sw_id,
+						 uint8_t action);
+
+	/**
+	 * Set software_identifier, checking if the identifier already exists
+	 *
+	 * @param name			Software identifier
+	 * @param package		Software package
+	 * @param version		Version of software package
+	 * @param source		Source ID of the software collector
+	 * @param installed		Installation status to be set, TRUE if installed
+	 * @return				Primary key pointing to SW ID or 0 if failed
+	 */
+	uint32_t (*set_sw_id)(sw_collector_db_t *this, char *name, char *package,
+						  char *version, uint8_t source, bool installed);
+
+	/**
+	 * Get software_identifier record
+	 *
+	 * @param name			Software identifier
+	 * @param package		Software package
+	 * @param version		Version of software package
+	 * @param source		Source ID of the software collector
+	 * @param installed		Installation status
+	 * @return				Primary key pointing to SW ID or 0 if failed
+	 */
+	uint32_t (*get_sw_id)(sw_collector_db_t *this, char *name, char **package,
+						  char **version, uint8_t *source, bool *installed);
+
+	/**
+	 * Get number of installed or removed software identifiers
+	 *
+	 * @param type			Query type (ALL, INSTALLED, REMOVED)
+	 * @return				Count
+	 */
+	uint32_t (*get_sw_id_count)(sw_collector_db_t *this,
+								sw_collector_db_query_t type);
+
+	/**
+	 * Update the software identifier version
+	 *
+	 * @param sw_id			Primary key of software identifier
+	 * @param name			Software identifier
+	 * @param version		Package version
+	 * @param installed		Installation status
+	 * @return				TRUE if update successful
+	 */
+	bool (*update_sw_id)(sw_collector_db_t *this, uint32_t sw_id, char *name,
+						 char *version, bool installed);
+
+	/**
+	 * Update the package name
+	 *
+	 * @param package_filter	Package name[s] to be changed
+	 * @param package			New package name
+	 * @return					TRUE if update successful
+	 */
+	int (*update_package)(sw_collector_db_t *this, char *package_filter,
+												   char *package);
+
+	/**
+	 * Enumerate over all collected [installed] software identities
+	 *
+	 * @param type			Query type (ALL, INSTALLED, REMOVED)
+	 * @param package		If not NULL enumerate over all package versions
+	 * @return				Enumerator
+	 */
+	enumerator_t* (*create_sw_enumerator)(sw_collector_db_t *this,
+										  sw_collector_db_query_t type,
+										  char *package);
+
+	/**
+	 * Destroy sw_collector_db_t object
+	 */
+	void (*destroy)(sw_collector_db_t *this);
+
+};
+
+/**
+ * Create an sw_collector_db_t instance
+ *
+ * @param uri				database URI
+ */
+sw_collector_db_t* sw_collector_db_create(char *uri);
+
+#endif /** SW_COLLECTOR_DB_H_ @}*/
diff --git a/src/sw-collector/sw_collector_dpkg.c b/src/sw-collector/sw_collector_dpkg.c
new file mode 100644
index 0000000..b5a8582
--- /dev/null
+++ b/src/sw-collector/sw_collector_dpkg.c
@@ -0,0 +1,152 @@
+/*
+ * Copyright (C) 2017 Andreas Steffen
+ * HSR Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * for more details.
+ */
+
+#define _GNU_SOURCE
+#include <stdio.h>
+
+#include "sw_collector_dpkg.h"
+
+typedef struct private_sw_collector_dpkg_t private_sw_collector_dpkg_t;
+
+/**
+ * Private data of an sw_collector_dpkg_t object.
+ */
+struct private_sw_collector_dpkg_t {
+
+	/**
+	 * Public members of sw_collector_dpkg_state_t
+	 */
+	sw_collector_dpkg_t public;
+
+};
+
+typedef struct {
+	/** public enumerator interface */
+	enumerator_t public;
+	/** dpkg output stream */
+	FILE *file;
+	/** current dpkg output line */
+	char line[BUF_LEN];
+} dpkg_enumerator_t;
+
+METHOD(enumerator_t, enumerate, bool,
+	dpkg_enumerator_t *this, va_list args)
+{
+	char **package, **arch, **version, *state, *pos;
+
+	VA_ARGS_VGET(args, package, arch, version);
+
+	while (TRUE)
+	{
+		if (!fgets(this->line, BUF_LEN, this->file))
+		{
+			return FALSE;
+		}
+
+		*package = this->line;
+		pos = strchr(this->line, '\t');
+		if (!pos)
+		{
+			return FALSE;
+		}
+		*pos = '\0';
+
+		*arch = ++pos;
+		pos = strchr(pos, '\t');
+		if (!pos)
+		{
+			return FALSE;
+		}
+		*pos = '\0';
+
+		*version = ++pos;
+		pos = strchr(pos, '\t');
+		if (!pos)
+		{
+			return FALSE;
+		}
+		*pos = '\0';
+
+		state = ++pos;
+		pos = strchr(pos, '\n');
+		if (!pos)
+		{
+			return FALSE;
+		}
+		*pos = '\0';
+
+		if (streq(state, "install ok installed"))
+		{
+			return TRUE;
+		}
+	}
+}
+
+METHOD(enumerator_t, enumerator_destroy, void,
+	dpkg_enumerator_t *this)
+{
+	pclose(this->file);
+	free(this);	
+}
+
+METHOD(sw_collector_dpkg_t, create_sw_enumerator, enumerator_t*,
+	private_sw_collector_dpkg_t *this)
+{
+	dpkg_enumerator_t *enumerator;
+	char cmd[] = "dpkg-query -W -f="
+				 "\'${Package}\t${Architecture}\t${Version}\t${Status}\n\'";
+	FILE *file;
+
+	file = popen(cmd, "r");
+	if (!file)
+	{
+		DBG1(DBG_IMC, "failed to run dpgk-query command");
+		return NULL;
+	}
+
+	INIT(enumerator,
+		.public = {
+			.enumerate = enumerator_enumerate_default,
+			.venumerate = _enumerate,
+			.destroy = _enumerator_destroy,
+		},
+		.file = file,
+	);
+
+	return &enumerator->public;
+}
+
+METHOD(sw_collector_dpkg_t, destroy, void,
+	private_sw_collector_dpkg_t *this)
+{
+	free(this);
+}
+
+/**
+ * Described in header.
+ */
+sw_collector_dpkg_t *sw_collector_dpkg_create(void)
+{
+	private_sw_collector_dpkg_t *this;
+
+	INIT(this,
+		.public = {
+			.create_sw_enumerator = _create_sw_enumerator,
+			.destroy = _destroy,
+		},
+	);
+
+	return &this->public;
+}
diff --git a/src/sw-collector/sw_collector_dpkg.h b/src/sw-collector/sw_collector_dpkg.h
new file mode 100644
index 0000000..eab792e
--- /dev/null
+++ b/src/sw-collector/sw_collector_dpkg.h
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2017 Andreas Steffen
+ * HSR Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT 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 sw_collector_dpkg_t sw_collector_dpkg
+ * @{ @ingroup sw_collector
+ */
+
+#ifndef SW_COLLECTOR_DPKG_H_
+#define SW_COLLECTOR_DPKG_H_
+
+#include <library.h>
+
+typedef struct sw_collector_dpkg_t sw_collector_dpkg_t;
+
+/**
+ * Software collector dpkg object
+ */
+struct sw_collector_dpkg_t {
+
+	/**
+	 * List of installed software identifiers managed by the
+	 * Debian "dpkg" package manager
+	 *
+	 * @return				Enumerator
+	 */
+	enumerator_t* (*create_sw_enumerator)(sw_collector_dpkg_t *this);
+
+	/**
+	 * Destroy sw_collector_dpkg_t object
+	 */
+	void (*destroy)(sw_collector_dpkg_t *this);
+
+};
+
+/**
+ * Create an sw_collector_dpkg_t instance
+ */
+sw_collector_dpkg_t* sw_collector_dpkg_create(void);
+
+#endif /** SW_COLLECTOR_DPKG_H_ @}*/
diff --git a/src/sw-collector/sw_collector_history.c b/src/sw-collector/sw_collector_history.c
new file mode 100644
index 0000000..f1fd9f6
--- /dev/null
+++ b/src/sw-collector/sw_collector_history.c
@@ -0,0 +1,519 @@
+/*
+ * Copyright (C) 2017 Andreas Steffen
+ * HSR Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * for more details.
+ */
+
+#define _GNU_SOURCE
+#include <stdio.h>
+#include <time.h>
+
+#include "sw_collector_history.h"
+#include "sw_collector_dpkg.h"
+
+#include <swima/swima_event.h>
+#include <swid_gen/swid_gen_info.h>
+
+typedef struct private_sw_collector_history_t private_sw_collector_history_t;
+
+/**
+ * Private data of an sw_collector_history_t object.
+ */
+struct private_sw_collector_history_t {
+
+	/**
+	 * Public members of sw_collector_history_state_t
+	 */
+	sw_collector_history_t public;
+
+	/**
+	 * Software Event Source Number
+	 */
+	uint8_t source;
+
+	/**
+	 * Reference to OS info object
+	 */
+	swid_gen_info_t *info;
+
+	/**
+	 * Reference to collector database
+	 */
+	sw_collector_db_t *db;
+
+};
+
+/**
+ * Define auxiliary package_t list item object
+ */
+typedef struct package_t package_t;
+
+struct package_t {
+	char *package;
+	char *version;
+	char *old_version;
+	char *sw_id;
+	char *old_sw_id;
+};
+
+/**
+ * Create package_t list item object
+ */
+static package_t* create_package(swid_gen_info_t *info, chunk_t package,
+								 chunk_t version, chunk_t old_version)
+{
+	package_t *this;
+
+	INIT(this,
+		.package = strndup(package.ptr, package.len),
+		.version = strndup(version.ptr, version.len),
+		.old_version = strndup(old_version.ptr, old_version.len),
+	)
+
+	this->sw_id = info->create_sw_id(info, this->package, this->version);
+	if (old_version.len)
+	{
+		this->old_sw_id = info->create_sw_id(info, this->package,
+												   this->old_version);
+	}
+
+	return this;
+}
+
+/**
+ * Free package_t list item object
+ */
+static void free_package(package_t *this)
+{
+	if (this)
+	{
+		free(this->package);
+		free(this->version);
+		free(this->old_version);
+		free(this->sw_id);
+		free(this->old_sw_id);
+		free(this);
+	}
+}
+
+/**
+ * Extract and parse a single package item
+ */
+static package_t* extract_package(chunk_t item, swid_gen_info_t *info,
+												sw_collector_history_op_t op)
+{
+	chunk_t package, package_stripped, version, old_version;
+	package_t *p;
+
+	/* extract package name */
+	if (!extract_token(&package, ' ', &item))
+	{
+		fprintf(stderr, "version not found.\n");
+		return NULL;
+	}
+	item = chunk_skip(item, 1);
+
+	/* strip architecture suffix if present */
+	if (extract_token(&package_stripped, ':', &package))
+	{
+		package = package_stripped;
+	}
+
+	/* extract versions */
+	version = old_version = chunk_empty;
+
+	if (item.len > 0)
+	{
+		if (extract_token(&version, ',', &item))
+		{
+			eat_whitespace(&item);
+			if (!match("automatic", &item))
+			{
+				old_version = version;
+				version = item;
+			}
+		}
+		else
+		{
+			version = item;
+		}
+	}
+	p = create_package(info, package, version, old_version);
+
+	/* generate log entry */
+	if (op == SW_OP_UPGRADE)
+	{
+		DBG2(DBG_IMC, "    %s (%s, %s)", p->package, p->old_version, p->version);
+		DBG2(DBG_IMC, "      +%s", p->sw_id);
+		DBG2(DBG_IMC, "      -%s", p->old_sw_id);
+	}
+	else
+	{
+		DBG2(DBG_IMC, "    %s (%s)", p->package, p->version);
+		DBG2(DBG_IMC, "      %s%s", (op == SW_OP_INSTALL) ? "+" : "-", p->sw_id);
+	}
+
+	return p;
+}
+
+METHOD(sw_collector_history_t, extract_timestamp, bool,
+	private_sw_collector_history_t *this, chunk_t args, char *buf)
+{
+	struct tm loc, utc;
+	chunk_t t1, t2;
+	time_t t;
+
+	/* Break down local time with format t1 = yyyy-mm-dd and t2 = hh:mm:ss */
+	if (!eat_whitespace(&args) || !extract_token(&t1, ' ', &args) ||
+		!eat_whitespace(&args) || t1.len != 10 || args.len != 8)
+	{
+		DBG1(DBG_IMC, "unable to parse start-date");
+		return FALSE;
+	}
+	t2 = args;
+
+	if (sscanf(t1.ptr, "%4d-%2d-%2d",
+						&loc.tm_year, &loc.tm_mon, &loc.tm_mday) != 3)
+	{
+		DBG1(DBG_IMC, "unable to parse date format yyyy-mm-dd");
+		return FALSE;
+	}
+	loc.tm_year -= 1900;
+	loc.tm_mon  -= 1;
+	loc.tm_isdst = -1;
+
+	if (sscanf(t2.ptr, "%2d:%2d:%2d",
+						&loc.tm_hour, &loc.tm_min, &loc.tm_sec) != 3)
+	{
+		DBG1(DBG_IMC, "unable to parse time format hh:mm:ss");
+		return FALSE;
+	}
+
+	/* Convert from local time to UTC */
+	t = mktime(&loc);
+	gmtime_r(&t, &utc);
+	utc.tm_year += 1900;
+	utc.tm_mon  += 1;
+
+	/* Form timestamp according to RFC 3339 (20 characters) */
+	snprintf(buf, 21, "%4d-%02d-%02dT%02d:%02d:%02dZ",
+			 utc.tm_year, utc.tm_mon, utc.tm_mday,
+			 utc.tm_hour, utc.tm_min, utc.tm_sec);
+
+	return TRUE;
+}
+
+METHOD(sw_collector_history_t, extract_packages, bool,
+	private_sw_collector_history_t *this, chunk_t args, uint32_t eid,
+	sw_collector_history_op_t op)
+{
+	bool success = FALSE;
+	package_t *p = NULL;
+	chunk_t item;
+
+	eat_whitespace(&args);
+
+	while (extract_token(&item, ')', &args))
+	{
+		char *del_sw_id = NULL, *del_version = NULL;
+		char *nx, *px, *vx, *v1;
+		bool installed;
+		u_int sw_idx, ix;
+		uint32_t sw_id, sw_id_epoch_less = 0;
+		enumerator_t *e;
+
+		p = extract_package(item, this->info, op);
+		if (!p)
+		{
+			goto end;
+		}
+
+		/* packages without version information cannot be handled */
+		if (strlen(p->version) == 0)
+		{
+			free_package(p);
+			continue;
+		}
+
+		switch (op)
+		{
+			case SW_OP_REMOVE:
+				/* prepare subsequent deletion sw event */
+				del_sw_id = p->sw_id;
+				del_version = p->version;
+				break;
+			case SW_OP_UPGRADE:
+				/* prepare subsequent deletion sw event */
+				del_sw_id = p->old_sw_id;
+				del_version = p->old_version;
+				/* fall through to next case */
+			case SW_OP_INSTALL:
+				sw_id = this->db->get_sw_id(this->db, p->sw_id, NULL, NULL,
+											NULL, &installed);
+				if (sw_id)
+				{
+					/* sw identifier exists - update state to 'installed' */
+					if (installed)
+					{
+						/* this case should not occur */
+						DBG1(DBG_IMC, "  warning:  sw_id %d is already "
+									  "installed", sw_id);
+					}
+					else if (!this->db->update_sw_id(this->db, sw_id, NULL,
+													 NULL, TRUE))
+					{
+						goto end;
+					}
+				}
+				else
+				{
+					/* new sw identifier - create with state 'installed' */
+					sw_id = this->db->set_sw_id(this->db, p->sw_id, p->package,
+												p->version,	this->source, TRUE);
+					if (!sw_id)
+					{
+						goto end;
+					}
+				}
+
+				/* add creation sw event with current eid */
+				if (!this->db->add_sw_event(this->db, eid, sw_id,
+									SWIMA_EVENT_ACTION_CREATION))
+				{
+					goto end;
+				}
+				break;
+		}
+
+		if (op != SW_OP_INSTALL)
+		{
+			sw_id = 0;
+
+			/* look for existing installed package versions */
+			e = this->db->create_sw_enumerator(this->db, SW_QUERY_INSTALLED,
+											   p->package);
+			if (!e)
+			{
+				goto end;
+			}
+
+			while (e->enumerate(e, &sw_idx, &nx, &px, &vx, &ix))
+			{
+				if (streq(vx, del_version))
+				{
+					/* full match with epoch */
+					sw_id = sw_idx;
+					break;
+				}
+				v1 = strchr(vx, ':');
+				if (v1 && streq(++v1, del_version))
+				{
+					/* match with stripped epoch */
+					sw_id_epoch_less = sw_idx;
+				}
+			}
+			e->destroy(e);
+
+			if (!sw_id && sw_id_epoch_less)
+			{
+				/* no full match - fall back to epoch-less match */
+				sw_id = sw_id_epoch_less;
+			}
+			if (sw_id)
+			{
+				/* sw identifier exists - update state to 'removed' */
+				if (!this->db->update_sw_id(this->db, sw_id, NULL, NULL, FALSE))
+				{
+					goto end;
+				}
+			}
+			else
+			{
+				/* new sw identifier - create with state 'removed' */
+				sw_id = this->db->set_sw_id(this->db, del_sw_id, p->package,
+									del_version, this->source, FALSE);
+
+				/* add creation sw event with eid = 1 */
+				if (!sw_id || !this->db->add_sw_event(this->db, 1, sw_id,
+											SWIMA_EVENT_ACTION_CREATION))
+				{
+					goto end;
+				}
+			}
+
+			/* add creation sw event with current eid */
+			if (!this->db->add_sw_event(this->db, eid, sw_id,
+								SWIMA_EVENT_ACTION_DELETION))
+			{
+				goto end;
+			}
+		}
+		free_package(p);
+
+		if (args.len < 2)
+		{
+			break;
+		}
+		args = chunk_skip(args, 2);
+	}
+	p = NULL;
+	success = TRUE;
+
+end:
+	free_package(p);
+
+	return success;
+}
+
+METHOD(sw_collector_history_t, merge_installed_packages, bool,
+	private_sw_collector_history_t *this)
+{
+	uint32_t sw_id, count = 0;
+	char *package, *arch, *version, *v1, *name, *n1;
+	bool installed, success = FALSE;
+	sw_collector_dpkg_t *dpkg;
+	enumerator_t *enumerator;
+
+	DBG1(DBG_IMC, "Merging:");
+
+	dpkg = sw_collector_dpkg_create();
+	if (!dpkg)
+	{
+		return FALSE;
+	}
+
+	enumerator = dpkg->create_sw_enumerator(dpkg);
+	while (enumerator->enumerate(enumerator, &package, &arch, &version))
+	{
+		name = this->info->create_sw_id(this->info, package, version);
+		DBG3(DBG_IMC, "  %s merged", name);
+
+		sw_id = this->db->get_sw_id(this->db, name, NULL, NULL, NULL,
+									&installed);
+		if (sw_id)
+		{
+			if (!installed)
+			{
+				DBG1(DBG_IMC, "  warning: existing sw_id %u"
+							  " is not installed", sw_id);
+
+				if (!this->db->update_sw_id(this->db, sw_id, name, version,
+											TRUE))
+				{
+					free(name);
+					goto end;
+				}
+			}
+		}
+		else
+		{
+			/* check for a Debian epoch number */
+			v1 = strchr(version, ':');
+			if (v1)
+			{
+				/* check for existing and installed epoch-less version */
+				n1 = this->info->create_sw_id(this->info, package, ++v1);
+				sw_id = this->db->get_sw_id(this->db, n1, NULL, NULL, NULL,
+											&installed);
+				free(n1);
+
+				if (sw_id && installed)
+				{
+					/* add epoch to existing version */
+					if (!this->db->update_sw_id(this->db, sw_id, name, version,
+												installed))
+					{
+						free(name);
+						goto end;
+					}
+				}
+				else
+				{
+					sw_id = 0;
+				}
+			}
+		}
+
+		if (!sw_id)
+		{
+			/* new sw identifier - create with state 'installed' */
+			sw_id = this->db->set_sw_id(this->db, name, package, version,
+										this->source, TRUE);
+
+			/* add creation sw event with eid = 1 */
+			if (!sw_id || !this->db->add_sw_event(this->db, 1, sw_id,
+										SWIMA_EVENT_ACTION_CREATION))
+			{
+				free(name);
+				goto end;
+			}
+
+		}
+		free(name);
+		count++;
+	}
+	success = TRUE;
+
+	DBG1(DBG_IMC, "  merged %u installed packages, %u registered in database",
+		 count, this->db->get_sw_id_count(this->db, SW_QUERY_INSTALLED));
+
+end:
+	enumerator->destroy(enumerator);
+	dpkg->destroy(dpkg);
+
+	return success;
+}
+
+METHOD(sw_collector_history_t, destroy, void,
+	private_sw_collector_history_t *this)
+{
+	this->info->destroy(this->info);
+	free(this);
+}
+
+/**
+ * Described in header.
+ */
+sw_collector_history_t *sw_collector_history_create(sw_collector_db_t *db,
+													uint8_t source)
+{
+	private_sw_collector_history_t *this;
+	swid_gen_info_t *info;
+	os_type_t os_type;
+	char *os;
+
+	info = swid_gen_info_create();
+
+	/* check if OS supports apg/dpkg history logs */
+	info->get_os(info, &os);
+	os_type = info->get_os_type(info);
+	if (os_type != 	OS_TYPE_DEBIAN && os_type != OS_TYPE_UBUNTU)
+	{
+		DBG1(DBG_IMC, "%.*s not supported", os);
+		info->destroy(info);
+		return NULL;
+	}
+
+	INIT(this,
+		.public = {
+			.extract_timestamp = _extract_timestamp,
+			.extract_packages = _extract_packages,
+			.merge_installed_packages = _merge_installed_packages,
+			.destroy = _destroy,
+		},
+		.source = source,
+		.info = info,
+		.db = db,
+	);
+
+	return &this->public;
+}
diff --git a/src/sw-collector/sw_collector_history.h b/src/sw-collector/sw_collector_history.h
new file mode 100644
index 0000000..aa354e8
--- /dev/null
+++ b/src/sw-collector/sw_collector_history.h
@@ -0,0 +1,91 @@
+/*
+ * Copyright (C) 2017 Andreas Steffen
+ * HSR Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT 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 sw_collector_history_t sw_collector_history
+ * @{ @ingroup sw_collector
+ */
+
+#ifndef SW_COLLECTOR_HISTORY_H_
+#define SW_COLLECTOR_HISTORY_H_
+
+#include "sw_collector_db.h"
+
+#include <library.h>
+#include <utils/debug.h>
+#include <utils/lexparser.h>
+
+typedef struct sw_collector_history_t sw_collector_history_t;
+typedef enum sw_collector_history_op_t sw_collector_history_op_t;
+
+/**
+ * Define major history event operations
+ */
+enum sw_collector_history_op_t {
+	SW_OP_INSTALL,
+	SW_OP_UPGRADE,
+	SW_OP_REMOVE
+};
+
+/**
+ * Software collector history object
+ */
+struct sw_collector_history_t {
+
+	/**
+	 * Extract timestamp from event in installation history
+	 *
+	 * @param args			Arguments to be processed
+	 * @param buf			timestamp buffer for 21 byte RFC 3339 string
+	 * @return				TRUE if extraction succeeded
+	 */
+	bool (*extract_timestamp)(sw_collector_history_t *this, chunk_t args,
+							  char *buf);
+
+	/**
+	 * Extract packages from event in installation history 
+	 *
+	 * @param args			Arguments to be processed
+	 * @param eid			Primary key pointing to current event
+	 * @param op			Extraction operation 
+	 * @return				TRUE if extraction succeeded
+	 */
+	bool (*extract_packages)(sw_collector_history_t *this, chunk_t args,
+							 uint32_t eid, sw_collector_history_op_t op);
+
+	/**
+	 * Merge packages from initial installation
+	 *
+	 * @return				TRUE if merge succeeded
+	 */
+	bool (*merge_installed_packages)(sw_collector_history_t *this);
+
+	/**
+	 * Destroy sw_collector_history_t object
+	 */
+	void (*destroy)(sw_collector_history_t *this);
+
+};
+
+/**
+ * Create an sw_collector_history_t instance
+ *
+ * @param db				Internal reference to collector database
+ * @param source			Software event source number
+ */
+sw_collector_history_t* sw_collector_history_create(sw_collector_db_t *db,
+													uint8_t source);
+
+#endif /** SW_COLLECTOR_HISTORY_H_ @}*/
diff --git a/src/sw-collector/sw_collector_rest_api.c b/src/sw-collector/sw_collector_rest_api.c
new file mode 100644
index 0000000..6b9b7b9
--- /dev/null
+++ b/src/sw-collector/sw_collector_rest_api.c
@@ -0,0 +1,200 @@
+/*
+ * Copyright (C) 2017 Andreas Steffen
+ * HSR Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT 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 "sw_collector_rest_api.h"
+
+#include <rest/rest.h>
+#include <utils/debug.h>
+
+typedef struct private_sw_collector_rest_api_t private_sw_collector_rest_api_t;
+
+/**
+ * Private data of an sw_collector_rest_api_t object.
+ */
+struct private_sw_collector_rest_api_t {
+
+	/**
+	 * Public members of sw_collector_rest_api_state_t
+	 */
+	sw_collector_rest_api_t public;
+
+	/**
+	 * Software collector database
+	 */
+	sw_collector_db_t *db;
+
+	/**
+	 * REST API of central collector database
+	 */
+	rest_t *rest_api;
+
+};
+
+/**
+ * Put all locally retrieved software identifiers into a json object
+ */
+static json_object* create_rest_request(private_sw_collector_rest_api_t *this,
+										sw_collector_db_query_t type)
+{
+	json_object *jrequest, *jarray, *jstring;
+	char *name, *package, *version;
+	uint32_t sw_id, i;
+	enumerator_t *e;
+
+	jrequest = json_object_new_object();
+	jarray = json_object_new_array();
+	json_object_object_add(jrequest, "data", jarray);
+
+	e = this->db->create_sw_enumerator(this->db, type, NULL);
+	if (!e)
+	{
+		return NULL;
+	}
+	while (e->enumerate(e, &sw_id, &name, &package, &version, &i))
+	{
+		jstring = json_object_new_string(name);
+		json_object_array_add(jarray, jstring);
+	}
+	e->destroy(e);
+
+	return jrequest;
+}
+
+typedef struct {
+	/** public enumerator interface */
+	enumerator_t public;
+	/** enumerated json array */
+	json_object *jarray;
+	/** current index +1, initialized at 0 */
+	int idx;
+} json_array_enumerator_t;
+
+METHOD(enumerator_t, enumerate, bool,
+	json_array_enumerator_t *this, va_list args)
+{
+	json_object *jvalue;
+	char **out;
+
+	VA_ARGS_VGET(args, out);
+
+	if (this->idx >= json_object_array_length(this->jarray))
+	{
+		return FALSE;
+	}
+
+	jvalue = json_object_array_get_idx(this->jarray, this->idx++);
+	if (json_object_get_type(jvalue) != json_type_string)
+	{
+		DBG1(DBG_IMC, "json_string element expected in json_array");
+		return FALSE;
+	}
+	*out = (char*)json_object_get_string(jvalue);
+
+	return TRUE;
+}
+
+METHOD(enumerator_t, enumerator_destroy, void,
+	json_array_enumerator_t *this)
+{
+	json_object_put(this->jarray);
+	free(this);	
+}
+
+METHOD(sw_collector_rest_api_t, create_sw_enumerator, enumerator_t*,
+	private_sw_collector_rest_api_t *this, sw_collector_db_query_t type)
+{
+	json_array_enumerator_t *enumerator;
+	json_object *jrequest, *jresponse;
+	char cmd[BUF_LEN];
+	status_t status;
+
+	jrequest = create_rest_request(this, type);
+	if (!jrequest)
+	{
+		return NULL;
+	}
+	snprintf(cmd, BUF_LEN, "sessions/0/swid-measurement/");
+
+	status = this->rest_api->post(this->rest_api, cmd, jrequest, &jresponse);
+	json_object_put(jrequest);
+
+	switch (status)
+	{
+		case SUCCESS:
+		case NOT_FOUND:
+			jresponse = json_object_new_array();
+			break;
+		case NEED_MORE:
+			if (json_object_get_type(jresponse) != json_type_array)
+			{
+				DBG1(DBG_IMC, "REST response was not a json_array");
+				json_object_put(jresponse);
+				return NULL;
+			}
+			break;
+		case FAILED:
+		default:
+			return NULL;
+	}
+
+	INIT(enumerator,
+		.public = {
+			.enumerate = enumerator_enumerate_default,
+			.venumerate = _enumerate,
+			.destroy = _enumerator_destroy,
+		},
+		.jarray = jresponse,
+	);
+
+	return &enumerator->public;
+}
+
+METHOD(sw_collector_rest_api_t, destroy, void,
+	private_sw_collector_rest_api_t *this)
+{
+	this->rest_api->destroy(this->rest_api);
+	free(this);
+}
+
+/**
+ * Described in header.
+ */
+sw_collector_rest_api_t *sw_collector_rest_api_create(sw_collector_db_t *db)
+{
+	private_sw_collector_rest_api_t *this;
+	int timeout;
+	char *uri;
+
+	uri = lib->settings->get_str(lib->settings, "%s.rest_api.uri", NULL,
+								 lib->ns);
+	timeout = lib->settings->get_int(lib->settings, "%s.rest_api.timeout", 120,
+								 lib->ns);
+	if (!uri)
+	{
+		DBG1(DBG_IMC, "REST URI to central collector database not set");
+		return NULL;
+	}
+
+	INIT(this,
+		.public = {
+			.create_sw_enumerator = _create_sw_enumerator,
+			.destroy = _destroy,
+		},
+		.db = db,
+		.rest_api = rest_create(uri, timeout),
+	);
+
+	return &this->public;
+}
diff --git a/src/sw-collector/sw_collector_rest_api.h b/src/sw-collector/sw_collector_rest_api.h
new file mode 100644
index 0000000..fe142fc
--- /dev/null
+++ b/src/sw-collector/sw_collector_rest_api.h
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2017 Andreas Steffen
+ * HSR Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT 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 sw_collector_rest_api_t sw_collector_rest_api
+ * @{ @ingroup sw_collector
+ */
+
+#ifndef SW_COLLECTOR_REST_API_H_
+#define SW_COLLECTOR_REST_API_H_
+
+#include "sw_collector_db.h"
+
+typedef struct sw_collector_rest_api_t sw_collector_rest_api_t;
+
+/**
+ * Software collector REST API object
+ */
+struct sw_collector_rest_api_t {
+
+	/**
+	 * List of locally stored software identifiers that are not registered
+	 * in a central collector database
+	 *
+	 * @param type			Query type (ALL, INSTALLED, REMOVED)
+	 * @return				Enumerator
+	 */
+	enumerator_t* (*create_sw_enumerator)(sw_collector_rest_api_t *this,
+										  sw_collector_db_query_t type);
+
+	/**
+	 * Destroy sw_collector_rest_api_t object
+	 */
+	void (*destroy)(sw_collector_rest_api_t *this);
+
+};
+
+/**
+ * Create an sw_collector_rest_api_t instance
+ *
+ * @param db				Software collector database to be used
+ */
+sw_collector_rest_api_t* sw_collector_rest_api_create(sw_collector_db_t *db);
+
+#endif /** SW_COLLECTOR_REST_API_H_ @}*/
diff --git a/src/sw-collector/sw_collector_tables.sql b/src/sw-collector/sw_collector_tables.sql
new file mode 100644
index 0000000..b7b430b
--- /dev/null
+++ b/src/sw-collector/sw_collector_tables.sql
@@ -0,0 +1,31 @@
+/* SQLit database for an Endpoint Collector */
+
+DROP TABLE IF EXISTS "events";
+CREATE TABLE "events" (
+  "id" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
+  "epoch" INTEGER NOT NULL,
+  "timestamp" CHAR(20) NOT NULL
+);
+
+DROP TABLE IF EXISTS "sw_identifiers";
+CREATE TABLE "sw_identifiers" (
+  "id" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
+  "name" VARCHAR(255) NOT NULL,
+  "package" VARCHAR(255) NOT NULL,
+  "version" VARCHAR(255) NOT NULL,
+  "source" INTEGER DEFAULT 0,
+  "installed" INTEGER DEFAULT 1,
+  "tag" TEXT
+  );
+DROP INDEX IF EXISTS "sw_identifiers_name";
+CREATE INDEX "sw_identifiers_name" ON "sw_identifiers" (
+  "name"
+);
+
+DROP TABLE IF EXISTS "sw_events";
+CREATE TABLE "sw_events" (
+  "id" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
+  "eid" INTEGER REFERENCES "events" ("id"),
+  "sw_id" INTEGER NOT NULL REFERENCES "sw_identifiers" ("id"),
+  "action" INTEGER NOT NULL
+);
diff --git a/src/swanctl/Makefile.am b/src/swanctl/Makefile.am
index 2fc9982..19815c5 100644
--- a/src/swanctl/Makefile.am
+++ b/src/swanctl/Makefile.am
@@ -64,6 +64,7 @@ maintainer-clean-local:
 
 install-data-local: swanctl.conf
 	test -e "$(DESTDIR)$(swanctldir)" || $(INSTALL) -d "$(DESTDIR)$(swanctldir)" || true
+	test -e "$(DESTDIR)$(swanctldir)/conf.d" || $(INSTALL) -d "$(DESTDIR)$(swanctldir)/conf.d" || true
 	test -e "$(DESTDIR)$(swanctldir)/x509" || $(INSTALL) -d "$(DESTDIR)$(swanctldir)/x509" || true
 	test -e "$(DESTDIR)$(swanctldir)/x509ca" || $(INSTALL) -d "$(DESTDIR)$(swanctldir)/x509ca" || true
 	test -e "$(DESTDIR)$(swanctldir)/x509aa" || $(INSTALL) -d "$(DESTDIR)$(swanctldir)/x509aa" || true
diff --git a/src/swanctl/Makefile.in b/src/swanctl/Makefile.in
index b5313a3..6da739b 100644
--- a/src/swanctl/Makefile.in
+++ b/src/swanctl/Makefile.in
@@ -330,8 +330,6 @@ RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
 RUBYGEMDIR = @RUBYGEMDIR@
-RUBYINCLUDE = @RUBYINCLUDE@
-RUBYLIB = @RUBYLIB@
 SED = @SED@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
@@ -432,6 +430,8 @@ random_device = @random_device@
 resolv_conf = @resolv_conf@
 routing_table = @routing_table@
 routing_table_prio = @routing_table_prio@
+ruby_CFLAGS = @ruby_CFLAGS@
+ruby_LIBS = @ruby_LIBS@
 runstatedir = @runstatedir@
 s_plugins = @s_plugins@
 sbindir = @sbindir@
@@ -460,6 +460,10 @@ top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
 tss2_CFLAGS = @tss2_CFLAGS@
 tss2_LIBS = @tss2_LIBS@
+tss2_socket_CFLAGS = @tss2_socket_CFLAGS@
+tss2_socket_LIBS = @tss2_socket_LIBS@
+tss2_tabrmd_CFLAGS = @tss2_tabrmd_CFLAGS@
+tss2_tabrmd_LIBS = @tss2_tabrmd_LIBS@
 urandom_device = @urandom_device@
 xml_CFLAGS = @xml_CFLAGS@
 xml_LIBS = @xml_LIBS@
@@ -1039,6 +1043,7 @@ maintainer-clean-local:
 
 install-data-local: swanctl.conf
 	test -e "$(DESTDIR)$(swanctldir)" || $(INSTALL) -d "$(DESTDIR)$(swanctldir)" || true
+	test -e "$(DESTDIR)$(swanctldir)/conf.d" || $(INSTALL) -d "$(DESTDIR)$(swanctldir)/conf.d" || true
 	test -e "$(DESTDIR)$(swanctldir)/x509" || $(INSTALL) -d "$(DESTDIR)$(swanctldir)/x509" || true
 	test -e "$(DESTDIR)$(swanctldir)/x509ca" || $(INSTALL) -d "$(DESTDIR)$(swanctldir)/x509ca" || true
 	test -e "$(DESTDIR)$(swanctldir)/x509aa" || $(INSTALL) -d "$(DESTDIR)$(swanctldir)/x509aa" || true
diff --git a/src/swanctl/command.c b/src/swanctl/command.c
index fd9bc00..7f65d2b 100644
--- a/src/swanctl/command.c
+++ b/src/swanctl/command.c
@@ -315,6 +315,10 @@ int command_dispatch(int c, char *v[])
 {
 	int op, i;
 
+	uri = lib->settings->get_str(lib->settings, "%s.socket",
+			lib->settings->get_str(lib->settings, "%s.plugins.vici.socket",
+								   NULL, lib->ns), lib->ns);
+
 	options = options_create();
 	atexit(cleanup);
 	active = help_idx = registered;
diff --git a/src/swanctl/swanctl.conf b/src/swanctl/swanctl.conf
index b2045a3..1ff5ee8 100644
--- a/src/swanctl/swanctl.conf
+++ b/src/swanctl/swanctl.conf
@@ -151,6 +151,9 @@
             # IKE identity to expect for authentication round.
             # id = %any
 
+            # Identity to use as peer identity during EAP authentication.
+            # eap_id = id
+
             # Authorization group memberships to require.
             # groups =
 
@@ -502,3 +505,6 @@
 
 # }
 
+# Include config snippets
+include conf.d/*.conf
+
diff --git a/src/swanctl/swanctl.conf.5.main b/src/swanctl/swanctl.conf.5.main
index 9f4044d..d1aced4 100644
--- a/src/swanctl/swanctl.conf.5.main
+++ b/src/swanctl/swanctl.conf.5.main
@@ -569,6 +569,13 @@ IKE identity to expect for authentication round. Refer to the
 section for details.
 
 .TP
+.BR connections.<conn>.remote<suffix>.eap_id " [id]"
+Identity to use as peer identity during EAP authentication. If set to
+.RI "" "%any" ""
+the
+EAP\-Identity method will be used to ask the client for an identity.
+
+.TP
 .BR connections.<conn>.remote<suffix>.groups " []"
 Comma separated authorization group memberships to require. The peer must prove
 membership to at least one of the specified groups. Group membership can be
@@ -1050,9 +1057,14 @@ Netfilter mark and mask for input traffic. On Linux Netfilter may require marks
 on each packet to match an SA having that option set. This allows Netfilter
 rules to select specific tunnels for incoming traffic. The special value
 .RI "" "%unique" ""
-sets a unique mark on each CHILD_SA instance.
-
-An additional mask may be appended to the mark, separated by _/_. The default
+sets a unique mark on each CHILD_SA instance, beyond that the value
+.RI "" "%unique\-dir" ""
+assigns a different unique mark for each CHILD_SA direction
+(in/out).
+
+An additional mask may be appended to the mark, separated by
+.RI "" "/" "."
+The default
 mask if omitted is 0xffffffff.
 
 .TP
@@ -1061,9 +1073,14 @@ Netfilter mark and mask for output traffic. On Linux Netfilter may require marks
 on each packet to match a policy having that option set. This allows Netfilter
 rules to select specific tunnels for outgoing traffic. The special value
 .RI "" "%unique" ""
-sets a unique mark on each CHILD_SA instance.
-
-An additional mask may be appended to the mark, separated by _/_. The default
+sets a unique mark on each CHILD_SA instance, beyond that the value
+.RI "" "%unique\-dir" ""
+assigns a different unique mark for each CHILD_SA direction
+(in/out).
+
+An additional mask may be appended to the mark, separated by
+.RI "" "/" "."
+The default
 mask if omitted is 0xffffffff.
 
 .TP
diff --git a/src/swanctl/swanctl.opt b/src/swanctl/swanctl.opt
index 7e204db..d0a0d21 100644
--- a/src/swanctl/swanctl.opt
+++ b/src/swanctl/swanctl.opt
@@ -460,6 +460,12 @@ connections.<conn>.remote<suffix>.id = %any
 	IKE identity to expect for authentication round. Refer to the _local_ _id_
 	section for details.
 
+connections.<conn>.remote<suffix>.eap_id = id
+	Identity to use as peer identity during EAP authentication.
+
+	Identity to use as peer identity during EAP authentication. If set to _%any_
+	the EAP-Identity method will be used to ask the client for an identity.
+
 connections.<conn>.remote<suffix>.groups =
 	Authorization group memberships to require.
 
@@ -864,7 +870,9 @@ connections.<conn>.children.<child>.mark_in = 0/0x00000000
 	Netfilter mark and mask for input traffic. On Linux Netfilter may require
 	marks on each packet to match an SA having that option set. This allows
 	Netfilter rules to select specific tunnels for incoming traffic. The
-	special value _%unique_ sets a unique mark on each CHILD_SA instance.
+	special value _%unique_ sets a unique mark on each CHILD_SA instance,
+	beyond that the value _%unique-dir_ assigns a different unique mark for each
+	CHILD_SA direction (in/out).
 
 	An additional mask may be appended to the mark, separated by _/_. The
 	default mask if omitted is 0xffffffff.
@@ -875,7 +883,9 @@ connections.<conn>.children.<child>.mark_out = 0/0x00000000
 	Netfilter mark and mask for output traffic. On Linux Netfilter may require
 	marks on each packet to match a policy having that option set. This allows
 	Netfilter rules to select specific tunnels for outgoing traffic. The
-	special value _%unique_ sets a unique mark on each CHILD_SA instance.
+	special value _%unique_ sets a unique mark on each CHILD_SA instance,
+	beyond that the value _%unique-dir_ assigns a different unique mark for each
+	CHILD_SA direction (in/out).
 
 	An additional mask may be appended to the mark, separated by _/_. The
 	default mask if omitted is 0xffffffff.
@@ -1152,3 +1162,5 @@ authorities.<name>.cert_uri_base =
 	built by appending the SHA1 hash of the DER encoded certificates to this
 	base URI.
 
+include conf.d/*.conf
+	Include config snippets
diff --git a/testing/Makefile.in b/testing/Makefile.in
index af153d3..3f6f1e4 100644
--- a/testing/Makefile.in
+++ b/testing/Makefile.in
@@ -227,8 +227,6 @@ RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
 RUBYGEMDIR = @RUBYGEMDIR@
-RUBYINCLUDE = @RUBYINCLUDE@
-RUBYLIB = @RUBYLIB@
 SED = @SED@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
@@ -329,6 +327,8 @@ random_device = @random_device@
 resolv_conf = @resolv_conf@
 routing_table = @routing_table@
 routing_table_prio = @routing_table_prio@
+ruby_CFLAGS = @ruby_CFLAGS@
+ruby_LIBS = @ruby_LIBS@
 runstatedir = @runstatedir@
 s_plugins = @s_plugins@
 sbindir = @sbindir@
@@ -357,6 +357,10 @@ top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
 tss2_CFLAGS = @tss2_CFLAGS@
 tss2_LIBS = @tss2_LIBS@
+tss2_socket_CFLAGS = @tss2_socket_CFLAGS@
+tss2_socket_LIBS = @tss2_socket_LIBS@
+tss2_tabrmd_CFLAGS = @tss2_tabrmd_CFLAGS@
+tss2_tabrmd_LIBS = @tss2_tabrmd_LIBS@
 urandom_device = @urandom_device@
 xml_CFLAGS = @xml_CFLAGS@
 xml_LIBS = @xml_LIBS@
diff --git a/testing/do-tests b/testing/do-tests
index 60c34c7..e3fd9b4 100755
--- a/testing/do-tests
+++ b/testing/do-tests
@@ -49,6 +49,25 @@ passed_cnt="0"
 subdir_cnt="0"
 
 ##############################################################################
+# parse optional arguments
+#
+while getopts "v" opt
+do
+	case "$opt" in
+	v)
+		verbose=YES
+		;;
+	esac
+done
+shift $((OPTIND-1))
+
+
+function print_time()
+{
+	[ "$verbose" == "YES" ] && echo "$(date +%T.%N) ~ "
+}
+
+##############################################################################
 # copy default tests to $BUILDDIR
 #
 
@@ -207,12 +226,16 @@ for SUBDIR in $TESTS
 do
     SUBTESTS="`basename $SUBDIR`"
 
-    if [ $SUBTESTS = $SUBDIR ]
-    then
-	SUBTESTS="`ls $DEFAULTTESTSDIR/$SUBDIR`"
-    else
-	SUBDIR="`dirname $SUBDIR`"
-    fi
+	if [ $SUBTESTS = $SUBDIR ]
+	then
+		SUBTESTS="`ls $DEFAULTTESTSDIR/$SUBDIR`"
+	else
+		if [[ $SUBTESTS == *'*'* ]]
+		then
+			SUBTESTS="`basename -a $DEFAULTTESTSDIR/$SUBDIR`"
+		fi
+		SUBDIR="`dirname $SUBDIR`"
+	fi
 
     if [ ! -d $TODAYDIR/$SUBDIR ]
     then
@@ -326,7 +349,7 @@ do
 		host=`echo $host_iface | awk -F ":" '{print $1}'`
 		iface=`echo $host_iface | awk -F ":" '{if ($2 != "") { print $2 } else { printf("eth0") }}'`
 		tcpdump_cmd="tcpdump -l $TCPDUMP_IM -i $iface not port ssh and not port domain >/tmp/tcpdump.log 2>/tmp/tcpdump.err.log &"
-		echo "${host}# $tcpdump_cmd" >> $CONSOLE_LOG
+		echo "$(print_time)${host}# $tcpdump_cmd" >> $CONSOLE_LOG
 		ssh $SSHCONF root@`eval echo \\\$ipv4_$host '$tcpdump_cmd'`
 		eval TDUP_${host}="true"
 	    done
@@ -381,7 +404,7 @@ do
 	eval `awk -F "::" '{
 	    if ($1 !~ /^#.*/ && $2 != "")
 	    {
-		printf("echo \"%s# %s\"; ", $1, $2)
+		printf("echo \"$(print_time)%s# %s\"; ", $1, $2)
 		printf("ssh \044SSHCONF root@\044ipv4_%s \"%s\"; ", $1, $2)
 		printf("echo;\n")
 	    }
@@ -395,7 +418,7 @@ do
 	function stop_tcpdump {
 	    # wait for packets to get processed, but don't wait longer than 1s
 	    eval ssh $SSHCONF root@\$ipv4_${1} "\"i=100; while [ \\\$i -gt 0 ]; do pkill -USR1 tcpdump; tail -1 /tmp/tcpdump.err.log | perl -n -e '/(\\d+).*?(\\d+)/; exit (\\\$1 == \\\$2)' || break; sleep 0.01; i=\\\$((\\\$i-1)); done;\""
-	    echo "${1}# killall tcpdump" >> $CONSOLE_LOG
+	    echo "$(print_time)${1}# killall tcpdump" >> $CONSOLE_LOG
 	    eval ssh $SSHCONF root@\$ipv4_${1} "\"killall tcpdump; while true; do killall -q -0 tcpdump || break; sleep 0.01; done;\""
 	    eval TDUP_${1}="false"
 	    echo "" >> $CONSOLE_LOG
@@ -412,29 +435,50 @@ do
 	STATUS="passed"
 
 	eval `awk -F "::" '{
-	    host=$1
-	    command=$2
-	    pattern=$3
-	    hit=$4
-	    if (host !~ /^#.*/ && command != "")
-	    {
+		host=$1
+		command=$2
+		pattern=$3
+		hit=$4
+		if (host ~ /^#.*/ || command == "")
+		{
+			next
+		}
+		printf("cmd_err=\044(tempfile -p test -s err); ")
 		if (command == "tcpdump")
 		{
-		    printf("if [ \044TDUP_%s == \"true\" ]; then stop_tcpdump %s; fi; \n", host, host)
-		    printf("echo \"%s# cat /tmp/tcpdump.log | grep \047%s\047  [%s]\"; ", host, pattern, hit)
-		    printf("ssh \044SSHCONF root@\044ipv4_%s cat /tmp/tcpdump.log | grep \"%s\"; ", host, pattern)
+			printf("if [ \044TDUP_%s == \"true\" ]; then stop_tcpdump %s; fi; \n", host, host)
+			printf("cmd_out=\044(ssh \044SSHCONF root@\044ipv4_%s cat /tmp/tcpdump.log | grep \"%s\"); ", host, pattern)
 		}
 		else
 		{
-		    printf("echo \"%s# %s | grep \047%s\047  [%s]\"; ", host, command, pattern, hit)
-		    printf("ssh \044SSHCONF root@\044ipv4_%s %s | grep \"%s\"; ",  host, command, pattern)
+			printf("cmd_out=\044(ssh \044SSHCONF root@\044ipv4_%s %s 2>\044cmd_err | grep \"%s\"); ",  host, command, pattern)
 		}
 		printf("cmd_exit=\044?; ")
+		printf("cmd_fail=0; ")
+		if (hit ~ /^[0-9]+$/)
+		{
+			printf("if [ \044(echo \"\044cmd_out\" | wc -l) -ne %d ] ", hit)
+		}
+		else
+		{
+			printf("if [ \044cmd_exit -eq 0 -a \"%s\" = \"NO\"  ] ", hit)
+			printf("|| [ \044cmd_exit -ne 0 -a \"%s\" = \"YES\" ] ", hit)
+		}
+		printf("; then STATUS=\"failed\"; cmd_fail=1; fi; \n")
+
+		printf("if [ \044cmd_fail -ne 0 ]; then echo \"~~~~~~~ FAIL ~~~~~~~\"; fi; \n")
+		if (command == "tcpdump")
+		{
+			printf("echo \"$(print_time)%s# cat /tmp/tcpdump.log | grep \047%s\047  [%s]\"; ", host, pattern, hit)
+		}
+		else
+		{
+			printf("echo \"$(print_time)%s# %s | grep \047%s\047  [%s]\"; ", host, command, pattern, hit)
+		}
+		printf("if [ -n \"\044cmd_out\" ]; then echo \"\044cmd_out\"; fi; \n")
+		printf("cat \044cmd_err; rm -f -- \044cmd_err; \n")
+		printf("if [ \044cmd_fail -ne 0 ]; then echo \"~~~~~~~~~~~~~~~~~~~~\"; fi; \n")
 		printf("echo; ")
-		printf("if [ \044cmd_exit -eq 0 -a \"%s\" = \"NO\"  ] ", hit)
-		printf("|| [ \044cmd_exit -ne 0 -a \"%s\" = \"YES\" ] ", hit)
-		printf("; then STATUS=\"failed\"; fi; \n")
-	    }
 	}' $TESTDIR/evaltest.dat` >> $CONSOLE_LOG 2>&1
 
 
@@ -718,7 +762,7 @@ do
 	eval `awk -F "::" '{
 	    if ($1 !~ /^#.*/ && $2 != "")
 	    {
-		printf("echo \"%s# %s\"; ", $1, $2)
+		printf("echo \"$(print_time)%s# %s\"; ", $1, $2)
 		printf("ssh \044SSHCONF root@\044ipv4_%s \"%s\"; ", $1, $2)
 		printf("echo;\n")
 	    }
diff --git a/testing/hosts/alice/etc/strongswan.conf b/testing/hosts/alice/etc/strongswan.conf
index f7a87e9..bc0ddbf 100644
--- a/testing/hosts/alice/etc/strongswan.conf
+++ b/testing/hosts/alice/etc/strongswan.conf
@@ -1,9 +1,5 @@
 # /etc/strongswan.conf - strongSwan configuration file
 
 charon {
-  load = sha1 sha2 md5 aes des hmac pem pkcs1 x509 revocation constraints pubkey gmp random nonce curl kernel-netlink socket-default updown stroke
-}
-
-libstrongswan {
-  dh_exponent_ansi_x9_42 = no
+  load = sha1 sha2 md5 aes des hmac pem pkcs1 x509 revocation constraints curve25519 pubkey gmp random nonce curl kernel-netlink socket-default updown stroke vici
 }
diff --git a/testing/hosts/bob/etc/strongswan.conf b/testing/hosts/bob/etc/strongswan.conf
index f7a87e9..bc0ddbf 100644
--- a/testing/hosts/bob/etc/strongswan.conf
+++ b/testing/hosts/bob/etc/strongswan.conf
@@ -1,9 +1,5 @@
 # /etc/strongswan.conf - strongSwan configuration file
 
 charon {
-  load = sha1 sha2 md5 aes des hmac pem pkcs1 x509 revocation constraints pubkey gmp random nonce curl kernel-netlink socket-default updown stroke
-}
-
-libstrongswan {
-  dh_exponent_ansi_x9_42 = no
+  load = sha1 sha2 md5 aes des hmac pem pkcs1 x509 revocation constraints curve25519 pubkey gmp random nonce curl kernel-netlink socket-default updown stroke vici
 }
diff --git a/testing/hosts/carol/etc/strongswan.conf b/testing/hosts/carol/etc/strongswan.conf
index f7a87e9..bc0ddbf 100644
--- a/testing/hosts/carol/etc/strongswan.conf
+++ b/testing/hosts/carol/etc/strongswan.conf
@@ -1,9 +1,5 @@
 # /etc/strongswan.conf - strongSwan configuration file
 
 charon {
-  load = sha1 sha2 md5 aes des hmac pem pkcs1 x509 revocation constraints pubkey gmp random nonce curl kernel-netlink socket-default updown stroke
-}
-
-libstrongswan {
-  dh_exponent_ansi_x9_42 = no
+  load = sha1 sha2 md5 aes des hmac pem pkcs1 x509 revocation constraints curve25519 pubkey gmp random nonce curl kernel-netlink socket-default updown stroke vici
 }
diff --git a/testing/hosts/dave/etc/strongswan.conf b/testing/hosts/dave/etc/strongswan.conf
index f7a87e9..bc0ddbf 100644
--- a/testing/hosts/dave/etc/strongswan.conf
+++ b/testing/hosts/dave/etc/strongswan.conf
@@ -1,9 +1,5 @@
 # /etc/strongswan.conf - strongSwan configuration file
 
 charon {
-  load = sha1 sha2 md5 aes des hmac pem pkcs1 x509 revocation constraints pubkey gmp random nonce curl kernel-netlink socket-default updown stroke
-}
-
-libstrongswan {
-  dh_exponent_ansi_x9_42 = no
+  load = sha1 sha2 md5 aes des hmac pem pkcs1 x509 revocation constraints curve25519 pubkey gmp random nonce curl kernel-netlink socket-default updown stroke vici
 }
diff --git a/testing/hosts/default/usr/local/bin/init_collector b/testing/hosts/default/usr/local/bin/init_collector
new file mode 100755
index 0000000..c522de8
--- /dev/null
+++ b/testing/hosts/default/usr/local/bin/init_collector
@@ -0,0 +1,4 @@
+#! /bin/sh
+
+cat /usr/local/share/strongswan/templates/database/sw-collector/sw_collector_tables.sql | sqlite3 /etc/db.d/collector.db
+LEAK_DETECTIVE_DISABLE=1 /usr/local/sbin/sw-collector
diff --git a/testing/hosts/moon/etc/strongswan.conf b/testing/hosts/moon/etc/strongswan.conf
index f7a87e9..bc0ddbf 100644
--- a/testing/hosts/moon/etc/strongswan.conf
+++ b/testing/hosts/moon/etc/strongswan.conf
@@ -1,9 +1,5 @@
 # /etc/strongswan.conf - strongSwan configuration file
 
 charon {
-  load = sha1 sha2 md5 aes des hmac pem pkcs1 x509 revocation constraints pubkey gmp random nonce curl kernel-netlink socket-default updown stroke
-}
-
-libstrongswan {
-  dh_exponent_ansi_x9_42 = no
+  load = sha1 sha2 md5 aes des hmac pem pkcs1 x509 revocation constraints curve25519 pubkey gmp random nonce curl kernel-netlink socket-default updown stroke vici
 }
diff --git a/testing/hosts/sun/etc/strongswan.conf b/testing/hosts/sun/etc/strongswan.conf
index f7a87e9..bc0ddbf 100644
--- a/testing/hosts/sun/etc/strongswan.conf
+++ b/testing/hosts/sun/etc/strongswan.conf
@@ -1,9 +1,5 @@
 # /etc/strongswan.conf - strongSwan configuration file
 
 charon {
-  load = sha1 sha2 md5 aes des hmac pem pkcs1 x509 revocation constraints pubkey gmp random nonce curl kernel-netlink socket-default updown stroke
-}
-
-libstrongswan {
-  dh_exponent_ansi_x9_42 = no
+  load = sha1 sha2 md5 aes des hmac pem pkcs1 x509 revocation constraints curve25519 pubkey gmp random nonce curl kernel-netlink socket-default updown stroke vici
 }
diff --git a/testing/hosts/venus/etc/strongswan.conf b/testing/hosts/venus/etc/strongswan.conf
index f7a87e9..bc0ddbf 100644
--- a/testing/hosts/venus/etc/strongswan.conf
+++ b/testing/hosts/venus/etc/strongswan.conf
@@ -1,9 +1,5 @@
 # /etc/strongswan.conf - strongSwan configuration file
 
 charon {
-  load = sha1 sha2 md5 aes des hmac pem pkcs1 x509 revocation constraints pubkey gmp random nonce curl kernel-netlink socket-default updown stroke
-}
-
-libstrongswan {
-  dh_exponent_ansi_x9_42 = no
+  load = sha1 sha2 md5 aes des hmac pem pkcs1 x509 revocation constraints curve25519 pubkey gmp random nonce curl kernel-netlink socket-default updown stroke vici
 }
diff --git a/testing/scripts/build-guestimages b/testing/scripts/build-guestimages
index 43a71b9..7dd7188 100755
--- a/testing/scripts/build-guestimages
+++ b/testing/scripts/build-guestimages
@@ -48,11 +48,11 @@ do
 	execute "cp -rf $HOSTSDIR/${host}/etc $LOOPDIR" 0
 	execute "cp -rf $HOSTSDIR/default/* $LOOPDIR" 0
 	execute_chroot "ldconfig" 0
+	execute "mkdir $LOOPDIR/etc/pts" 0
 
 	if [ "$host" = "alice" ]
 	then
 		execute "mkdir $LOOPDIR/var/log/apache2/tnc" 0
-		execute "mkdir $LOOPDIR/etc/pts" 0
 		execute_chroot "chgrp www-data /etc/pts" 0
 		execute_chroot "chmod g+w /etc/pts" 0
 	fi
diff --git a/testing/scripts/build-strongswan b/testing/scripts/build-strongswan
index 8c6ecaa..d4e9e92 100755
--- a/testing/scripts/build-strongswan
+++ b/testing/scripts/build-strongswan
@@ -51,6 +51,7 @@ do_on_exit umount $LOOPDIR/root/strongswan
 
 log_action "Remove SWID tags of previous versions"
 execute_chroot 'find /usr/local/share/regid.2004-03.org.strongswan -name *.swidtag -delete'
+execute_chroot 'find /usr/local/share/strongswan -name *.swidtag -delete'
 
 echo "Building and installing strongSwan"
 
diff --git a/testing/scripts/recipes/013_strongswan.mk b/testing/scripts/recipes/013_strongswan.mk
index a5b2d80..3c5f418 100644
--- a/testing/scripts/recipes/013_strongswan.mk
+++ b/testing/scripts/recipes/013_strongswan.mk
@@ -56,6 +56,8 @@ CONFIG_OPTS = \
 	--enable-imv-attestation \
 	--enable-imc-swid \
 	--enable-imv-swid \
+	--enable-imc-swima \
+	--enable-imv-swima \
 	--enable-imc-hcd \
 	--enable-imv-hcd \
 	--enable-sql \
diff --git a/testing/testing.conf b/testing/testing.conf
index eeb69ea..e22afc3 100644
--- a/testing/testing.conf
+++ b/testing/testing.conf
@@ -31,7 +31,7 @@ fi
 : ${KERNELPATCH=ha-4.4-abicompat.patch.bz2}
 
 # strongSwan version used in tests
-: ${SWANVERSION=5.5.3}
+: ${SWANVERSION=5.6.0}
 
 # Build directory where the guest kernel and images will be built
 : ${BUILDDIR=$TESTDIR/build}
diff --git a/testing/tests/ikev2/net2net-rekey/description.txt b/testing/tests/ikev2/net2net-rekey/description.txt
new file mode 100644
index 0000000..c3122a7
--- /dev/null
+++ b/testing/tests/ikev2/net2net-rekey/description.txt
@@ -0,0 +1,10 @@
+A connection between the subnets behind the gateways <b>moon</b> and <b>sun</b> is set up.
+The authentication is based on <b>X.509 certificates</b>. Upon the successful
+establishment of the IPsec tunnel, <b>leftfirewall=yes</b> automatically
+inserts iptables-based firewall rules that let pass the tunneled traffic.
+After a while the CHILD_SA is rekeyed by <b>moon</b> (after a deliberately short
+time in this test scenario).
+In order to test both tunnel and firewall after the rekeying, client <b>alice</b>
+behind gateway <b>moon</b> pings client <b>bob</b> located behind gateway <b>sun</b>
+twice, once right after the rekeying and once after the old inbound SA has been
+deleted.
diff --git a/testing/tests/ikev2/net2net-rekey/evaltest.dat b/testing/tests/ikev2/net2net-rekey/evaltest.dat
new file mode 100644
index 0000000..0a34efe
--- /dev/null
+++ b/testing/tests/ikev2/net2net-rekey/evaltest.dat
@@ -0,0 +1,14 @@
+moon::ipsec status 2> /dev/null::net-net.*ESTABLISHED.*moon.strongswan.org.*sun.strongswan.org::YES
+sun:: ipsec status 2> /dev/null::net-net.*ESTABLISHED.*sun.strongswan.org.*moon.strongswan.org::YES
+moon::ipsec status 2> /dev/null::net-net.*INSTALLED, TUNNEL::YES
+sun:: ipsec status 2> /dev/null::net-net.*INSTALLED, TUNNEL::YES
+moon::sleep 6::wait for rekeying::NO
+moon::cat /var/log/daemon.log::creating rekey job for CHILD_SA::YES
+moon::cat /var/log/daemon.log::generating CREATE_CHILD_SA request.*REKEY_SA::YES
+moon::cat /var/log/daemon.log::deleted SAD entry with SPI::1
+alice::ping -c 1 PH_IP_BOB::64 bytes from PH_IP_BOB: icmp_.eq=1::YES
+moon::sleep 2::wait until inbound SA is deleted::NO
+moon::cat /var/log/daemon.log::deleted SAD entry with SPI::2
+alice::ping -c 1 PH_IP_BOB::64 bytes from PH_IP_BOB: icmp_.eq=1::YES
+sun::tcpdump::IP moon.strongswan.org > sun.strongswan.org: ESP::YES
+sun::tcpdump::IP sun.strongswan.org > moon.strongswan.org: ESP::YES
diff --git a/testing/tests/ikev2/net2net-rekey/hosts/moon/etc/ipsec.conf b/testing/tests/ikev2/net2net-rekey/hosts/moon/etc/ipsec.conf
new file mode 100644
index 0000000..dcd98b4
--- /dev/null
+++ b/testing/tests/ikev2/net2net-rekey/hosts/moon/etc/ipsec.conf
@@ -0,0 +1,24 @@
+# /etc/ipsec.conf - strongSwan IPsec configuration file
+
+config setup
+	charondebug="knl 2"
+
+conn %default
+	ikelifetime=60m
+	lifetime=10s
+	margintime=5s
+	rekeyfuzz=0%
+	keyingtries=1
+	keyexchange=ikev2
+	mobike=no
+
+conn net-net
+	left=PH_IP_MOON
+	leftcert=moonCert.pem
+	leftid=@moon.strongswan.org
+	leftsubnet=10.1.0.0/16
+	leftfirewall=yes
+	right=PH_IP_SUN
+	rightid=@sun.strongswan.org
+	rightsubnet=10.2.0.0/16
+	auto=add
diff --git a/testing/tests/ikev2/net2net-rekey/hosts/moon/etc/strongswan.conf b/testing/tests/ikev2/net2net-rekey/hosts/moon/etc/strongswan.conf
new file mode 100644
index 0000000..3dcbf76
--- /dev/null
+++ b/testing/tests/ikev2/net2net-rekey/hosts/moon/etc/strongswan.conf
@@ -0,0 +1,7 @@
+# /etc/strongswan.conf - strongSwan configuration file
+
+charon {
+  load = random nonce aes sha1 sha2 pem pkcs1 curve25519 gmp x509 curl revocation hmac stroke kernel-netlink socket-default updown
+  # remove rekeyed inbound SA a bit quicker for the test scenario
+  delete_rekeyed_delay = 2
+}
diff --git a/testing/tests/openssl-ikev2/rw-suite-b-192/hosts/dave/etc/ipsec.conf b/testing/tests/ikev2/net2net-rekey/hosts/sun/etc/ipsec.conf
similarity index 50%
copy from testing/tests/openssl-ikev2/rw-suite-b-192/hosts/dave/etc/ipsec.conf
copy to testing/tests/ikev2/net2net-rekey/hosts/sun/etc/ipsec.conf
index f6feda0..5b391db 100644
--- a/testing/tests/openssl-ikev2/rw-suite-b-192/hosts/dave/etc/ipsec.conf
+++ b/testing/tests/ikev2/net2net-rekey/hosts/sun/etc/ipsec.conf
@@ -8,14 +8,15 @@ conn %default
 	rekeymargin=3m
 	keyingtries=1
 	keyexchange=ikev2
-	ike=aes256gcm128-prfsha384-ecp384!
-	esp=aes256cm128-ecp384!
+	mobike=no
 
-conn peer
-	left=PH_IP_DAVE
-	leftcert=daveCert.pem
-	leftid=dave at strongswan.org
+conn net-net
+	left=PH_IP_SUN
+	leftcert=sunCert.pem
+	leftid=@sun.strongswan.org
+	leftsubnet=10.2.0.0/16
 	leftfirewall=yes
-	right=PH_IP_CAROL
-	rightid=carol at strongswan.org
+	right=PH_IP_MOON
+	rightid=@moon.strongswan.org
+	rightsubnet=10.1.0.0/16
 	auto=add
diff --git a/testing/tests/ikev2/net2net-rekey/hosts/sun/etc/strongswan.conf b/testing/tests/ikev2/net2net-rekey/hosts/sun/etc/strongswan.conf
new file mode 100644
index 0000000..93f4345
--- /dev/null
+++ b/testing/tests/ikev2/net2net-rekey/hosts/sun/etc/strongswan.conf
@@ -0,0 +1,5 @@
+# /etc/strongswan.conf - strongSwan configuration file
+
+charon {
+  load = random nonce aes sha1 sha2 pem pkcs1 curve25519 gmp x509 curl revocation hmac stroke kernel-netlink socket-default updown
+}
diff --git a/testing/tests/ikev2/net2net-rekey/posttest.dat b/testing/tests/ikev2/net2net-rekey/posttest.dat
new file mode 100644
index 0000000..837738f
--- /dev/null
+++ b/testing/tests/ikev2/net2net-rekey/posttest.dat
@@ -0,0 +1,5 @@
+moon::ipsec stop
+sun::ipsec stop
+moon::iptables-restore < /etc/iptables.flush
+sun::iptables-restore < /etc/iptables.flush
+
diff --git a/testing/tests/ikev2/net2net-rekey/pretest.dat b/testing/tests/ikev2/net2net-rekey/pretest.dat
new file mode 100644
index 0000000..bcc2cb0
--- /dev/null
+++ b/testing/tests/ikev2/net2net-rekey/pretest.dat
@@ -0,0 +1,7 @@
+moon::iptables-restore < /etc/iptables.rules
+sun::iptables-restore < /etc/iptables.rules
+sun::ipsec start
+moon::ipsec start
+sun::expect-connection net-net
+moon::expect-connection net-net
+moon::ipsec up net-net
diff --git a/testing/tests/ikev2/net2net-rekey/test.conf b/testing/tests/ikev2/net2net-rekey/test.conf
new file mode 100644
index 0000000..afa2acc
--- /dev/null
+++ b/testing/tests/ikev2/net2net-rekey/test.conf
@@ -0,0 +1,21 @@
+#!/bin/bash
+#
+# This configuration file provides information on the
+# guest instances used for this test
+
+# All guest instances that are required for this test
+#
+VIRTHOSTS="alice moon winnetou sun bob"
+
+# Corresponding block diagram
+#
+DIAGRAM="a-m-w-s-b.png"
+
+# Guest instances on which tcpdump is to be started
+#
+TCPDUMPHOSTS="sun"
+
+# Guest instances on which IPsec is started
+# Used for IPsec logging purposes
+#
+IPSECHOSTS="moon sun"
diff --git a/testing/tests/openssl-ikev2/rw-suite-b-192/hosts/dave/etc/ipsec.conf b/testing/tests/openssl-ikev2/rw-suite-b-192/hosts/dave/etc/ipsec.conf
index f6feda0..b81e9b2 100644
--- a/testing/tests/openssl-ikev2/rw-suite-b-192/hosts/dave/etc/ipsec.conf
+++ b/testing/tests/openssl-ikev2/rw-suite-b-192/hosts/dave/etc/ipsec.conf
@@ -9,7 +9,7 @@ conn %default
 	keyingtries=1
 	keyexchange=ikev2
 	ike=aes256gcm128-prfsha384-ecp384!
-	esp=aes256cm128-ecp384!
+	esp=aes256gcm128-ecp384!
 
 conn peer
 	left=PH_IP_DAVE
diff --git a/testing/tests/pfkey/net2net-rekey/description.txt b/testing/tests/pfkey/net2net-rekey/description.txt
new file mode 100644
index 0000000..c3122a7
--- /dev/null
+++ b/testing/tests/pfkey/net2net-rekey/description.txt
@@ -0,0 +1,10 @@
+A connection between the subnets behind the gateways <b>moon</b> and <b>sun</b> is set up.
+The authentication is based on <b>X.509 certificates</b>. Upon the successful
+establishment of the IPsec tunnel, <b>leftfirewall=yes</b> automatically
+inserts iptables-based firewall rules that let pass the tunneled traffic.
+After a while the CHILD_SA is rekeyed by <b>moon</b> (after a deliberately short
+time in this test scenario).
+In order to test both tunnel and firewall after the rekeying, client <b>alice</b>
+behind gateway <b>moon</b> pings client <b>bob</b> located behind gateway <b>sun</b>
+twice, once right after the rekeying and once after the old inbound SA has been
+deleted.
diff --git a/testing/tests/pfkey/net2net-rekey/evaltest.dat b/testing/tests/pfkey/net2net-rekey/evaltest.dat
new file mode 100644
index 0000000..3bf3b27
--- /dev/null
+++ b/testing/tests/pfkey/net2net-rekey/evaltest.dat
@@ -0,0 +1,16 @@
+moon::ipsec status 2> /dev/null::net-net.*ESTABLISHED.*moon.strongswan.org.*sun.strongswan.org::YES
+sun:: ipsec status 2> /dev/null::net-net.*ESTABLISHED.*sun.strongswan.org.*moon.strongswan.org::YES
+moon::ipsec status 2> /dev/null::net-net.*INSTALLED, TUNNEL::YES
+sun:: ipsec status 2> /dev/null::net-net.*INSTALLED, TUNNEL::YES
+# deleting the inbound SPI
+moon::cat /var/log/daemon.log::deleted SAD entry with SPI::1
+moon::sleep 6::wait for rekeying::NO
+moon::cat /var/log/daemon.log::creating rekey job for CHILD_SA::YES
+moon::cat /var/log/daemon.log::generating CREATE_CHILD_SA request.*REKEY_SA::YES
+moon::cat /var/log/daemon.log::deleted SAD entry with SPI::3
+alice::ping -c 1 PH_IP_BOB::64 bytes from PH_IP_BOB: icmp_.eq=1::YES
+moon::sleep 2::wait until inbound SA is deleted::NO
+moon::cat /var/log/daemon.log::deleted SAD entry with SPI::4
+alice::ping -c 1 PH_IP_BOB::64 bytes from PH_IP_BOB: icmp_.eq=1::YES
+sun::tcpdump::IP moon.strongswan.org > sun.strongswan.org: ESP::YES
+sun::tcpdump::IP sun.strongswan.org > moon.strongswan.org: ESP::YES
diff --git a/testing/tests/pfkey/net2net-rekey/hosts/moon/etc/ipsec.conf b/testing/tests/pfkey/net2net-rekey/hosts/moon/etc/ipsec.conf
new file mode 100644
index 0000000..dcd98b4
--- /dev/null
+++ b/testing/tests/pfkey/net2net-rekey/hosts/moon/etc/ipsec.conf
@@ -0,0 +1,24 @@
+# /etc/ipsec.conf - strongSwan IPsec configuration file
+
+config setup
+	charondebug="knl 2"
+
+conn %default
+	ikelifetime=60m
+	lifetime=10s
+	margintime=5s
+	rekeyfuzz=0%
+	keyingtries=1
+	keyexchange=ikev2
+	mobike=no
+
+conn net-net
+	left=PH_IP_MOON
+	leftcert=moonCert.pem
+	leftid=@moon.strongswan.org
+	leftsubnet=10.1.0.0/16
+	leftfirewall=yes
+	right=PH_IP_SUN
+	rightid=@sun.strongswan.org
+	rightsubnet=10.2.0.0/16
+	auto=add
diff --git a/testing/tests/pfkey/net2net-rekey/hosts/moon/etc/strongswan.conf b/testing/tests/pfkey/net2net-rekey/hosts/moon/etc/strongswan.conf
new file mode 100644
index 0000000..4234eb1
--- /dev/null
+++ b/testing/tests/pfkey/net2net-rekey/hosts/moon/etc/strongswan.conf
@@ -0,0 +1,7 @@
+# /etc/strongswan.conf - strongSwan configuration file
+
+charon {
+  load = random nonce aes sha1 sha2 pem pkcs1 curve25519 gmp x509 curl revocation hmac stroke kernel-pfkey kernel-netlink socket-default updown
+  # remove rekeyed inbound SA a bit quicker for the test scenario
+  delete_rekeyed_delay = 2
+}
diff --git a/testing/tests/openssl-ikev2/rw-suite-b-192/hosts/dave/etc/ipsec.conf b/testing/tests/pfkey/net2net-rekey/hosts/sun/etc/ipsec.conf
similarity index 50%
copy from testing/tests/openssl-ikev2/rw-suite-b-192/hosts/dave/etc/ipsec.conf
copy to testing/tests/pfkey/net2net-rekey/hosts/sun/etc/ipsec.conf
index f6feda0..5b391db 100644
--- a/testing/tests/openssl-ikev2/rw-suite-b-192/hosts/dave/etc/ipsec.conf
+++ b/testing/tests/pfkey/net2net-rekey/hosts/sun/etc/ipsec.conf
@@ -8,14 +8,15 @@ conn %default
 	rekeymargin=3m
 	keyingtries=1
 	keyexchange=ikev2
-	ike=aes256gcm128-prfsha384-ecp384!
-	esp=aes256cm128-ecp384!
+	mobike=no
 
-conn peer
-	left=PH_IP_DAVE
-	leftcert=daveCert.pem
-	leftid=dave at strongswan.org
+conn net-net
+	left=PH_IP_SUN
+	leftcert=sunCert.pem
+	leftid=@sun.strongswan.org
+	leftsubnet=10.2.0.0/16
 	leftfirewall=yes
-	right=PH_IP_CAROL
-	rightid=carol at strongswan.org
+	right=PH_IP_MOON
+	rightid=@moon.strongswan.org
+	rightsubnet=10.1.0.0/16
 	auto=add
diff --git a/testing/tests/pfkey/net2net-rekey/hosts/sun/etc/strongswan.conf b/testing/tests/pfkey/net2net-rekey/hosts/sun/etc/strongswan.conf
new file mode 100644
index 0000000..0ecc2f8
--- /dev/null
+++ b/testing/tests/pfkey/net2net-rekey/hosts/sun/etc/strongswan.conf
@@ -0,0 +1,5 @@
+# /etc/strongswan.conf - strongSwan configuration file
+
+charon {
+  load = random nonce aes sha1 sha2 pem pkcs1 curve25519 gmp x509 curl revocation hmac stroke kernel-pfkey kernel-netlink socket-default updown
+}
diff --git a/testing/tests/pfkey/net2net-rekey/posttest.dat b/testing/tests/pfkey/net2net-rekey/posttest.dat
new file mode 100644
index 0000000..837738f
--- /dev/null
+++ b/testing/tests/pfkey/net2net-rekey/posttest.dat
@@ -0,0 +1,5 @@
+moon::ipsec stop
+sun::ipsec stop
+moon::iptables-restore < /etc/iptables.flush
+sun::iptables-restore < /etc/iptables.flush
+
diff --git a/testing/tests/pfkey/net2net-rekey/pretest.dat b/testing/tests/pfkey/net2net-rekey/pretest.dat
new file mode 100644
index 0000000..bcc2cb0
--- /dev/null
+++ b/testing/tests/pfkey/net2net-rekey/pretest.dat
@@ -0,0 +1,7 @@
+moon::iptables-restore < /etc/iptables.rules
+sun::iptables-restore < /etc/iptables.rules
+sun::ipsec start
+moon::ipsec start
+sun::expect-connection net-net
+moon::expect-connection net-net
+moon::ipsec up net-net
diff --git a/testing/tests/pfkey/net2net-rekey/test.conf b/testing/tests/pfkey/net2net-rekey/test.conf
new file mode 100644
index 0000000..afa2acc
--- /dev/null
+++ b/testing/tests/pfkey/net2net-rekey/test.conf
@@ -0,0 +1,21 @@
+#!/bin/bash
+#
+# This configuration file provides information on the
+# guest instances used for this test
+
+# All guest instances that are required for this test
+#
+VIRTHOSTS="alice moon winnetou sun bob"
+
+# Corresponding block diagram
+#
+DIAGRAM="a-m-w-s-b.png"
+
+# Guest instances on which tcpdump is to be started
+#
+TCPDUMPHOSTS="sun"
+
+# Guest instances on which IPsec is started
+# Used for IPsec logging purposes
+#
+IPSECHOSTS="moon sun"
diff --git a/testing/tests/tkm/xfrmproxy-expire/evaltest.dat b/testing/tests/tkm/xfrmproxy-expire/evaltest.dat
index 05bf420..a3f4587 100644
--- a/testing/tests/tkm/xfrmproxy-expire/evaltest.dat
+++ b/testing/tests/tkm/xfrmproxy-expire/evaltest.dat
@@ -2,20 +2,24 @@ moon::ipsec stroke status 2> /dev/null::conn1.*ESTABLISHED.*moon.strongswan.org.
 sun::ipsec status 2> /dev/null::host-host.*ESTABLISHED.*sun.strongswan.org.*moon.strongswan.org::YES
 moon::ipsec stroke status 2> /dev/null::conn1.*INSTALLED, TRANSPORT::YES
 sun::ipsec status 2> /dev/null::host-host.*INSTALLED, TRANSPORT::YES
-moon::ping -c 1 PH_IP_SUN::64 bytes from PH_IP_SUN: icmp_.eq=1::YES
-sun::tcpdump::IP moon.strongswan.org > sun.strongswan.org: ESP::YES
-sun::tcpdump::IP sun.strongswan.org > moon.strongswan.org: ESP::YES
+moon::sleep 2::wait for rekeying::NO
 moon::cat /var/log/daemon.log::ees: acquire received for reqid 1::YES
 moon::cat /var/log/daemon.log::ees: expire received for reqid 1, spi.*, dst 192.168.0.2::YES
 moon::cat /var/log/daemon.log::creating rekey job for CHILD_SA ESP/0x.*/192.168.0.2::YES
+moon::cat /var/log/daemon.log::deleting child SA (esa: 1, spi:.*)::NO
+moon::ping -c 1 PH_IP_SUN::64 bytes from PH_IP_SUN: icmp_.eq=1::YES
+sun::tcpdump::IP moon.strongswan.org > sun.strongswan.org: ESP::YES
+sun::tcpdump::IP sun.strongswan.org > moon.strongswan.org: ESP::YES
+moon::sleep 2::wait until inbound SA is deleted::NO
 moon::cat /var/log/daemon.log::deleting child SA (esa: 1, spi:.*)::YES
+moon::ping -c 1 PH_IP_SUN::64 bytes from PH_IP_SUN: icmp_.eq=1::YES
 moon::cat /tmp/tkm.log::RSA private key '/etc/tkm/moonKey.der' loaded::YES
 moon::cat /tmp/tkm.log::Adding policy \[ 1, 192.168.0.1 <-> 192.168.0.2 \]::YES
 moon::cat /tmp/tkm.log::Checked CA certificate of CC context 1::YES
 moon::cat /tmp/tkm.log::Authentication of ISA context 1 successful::YES
 moon::cat /tmp/tkm.log::Creating first new ESA context with ID 1 (Isa 1, Sp 1, Ea 1, Initiator TRUE, spi_loc.*, spi_rem.*)::YES
 moon::cat /tmp/tkm.log::Creating ESA context with ID 2 (Isa 1, Sp 1, Ea 1, Dh_Id 1, Nc_Loc_Id 1, Initiator TRUE, spi_loc.*, spi_rem.*)::YES
-moon::cat /tmp/tkm.log | grep 'Adding ESA \[ 1, 192.168.0.1 <-> 192.168.0.2, SPI_in.*, SPI_out.*, soft 2, hard 60 \]' | wc -l::2::YES
+moon::cat /tmp/tkm.log | grep 'Adding ESA \[ 1, 192.168.0.1 <-> 192.168.0.2, SPI_in.*, SPI_out.*, soft 4, hard 60 \]' | wc -l::2::YES
 moon::cat /tmp/tkm.log::Resetting ESA context 1::YES
 moon::cat /tmp/tkm.log::Deleting ESA \[ 1, 192.168.0.1 <=> 192.168.0.2, SPI_in.*, SPI_out.* \]::YES
 moon::cat /tmp/xfrm_proxy.log::Initiating ESA acquire for reqid 1::YES
diff --git a/testing/tests/tkm/xfrmproxy-expire/hosts/moon/etc/strongswan.conf b/testing/tests/tkm/xfrmproxy-expire/hosts/moon/etc/strongswan.conf
index cc9d6e0..5b79af9 100644
--- a/testing/tests/tkm/xfrmproxy-expire/hosts/moon/etc/strongswan.conf
+++ b/testing/tests/tkm/xfrmproxy-expire/hosts/moon/etc/strongswan.conf
@@ -1,6 +1,8 @@
 # /etc/strongswan.conf - strongSwan configuration file
 
 charon-tkm {
+  # remove rekeyed inbound SA a bit quicker for the test scenario
+  delete_rekeyed_delay = 2
   dh_mapping {
     15 = 1
     16 = 2
diff --git a/testing/tests/tkm/xfrmproxy-expire/hosts/moon/etc/tkm/tkm.conf b/testing/tests/tkm/xfrmproxy-expire/hosts/moon/etc/tkm/tkm.conf
index 23e958a..62b103a 100644
--- a/testing/tests/tkm/xfrmproxy-expire/hosts/moon/etc/tkm/tkm.conf
+++ b/testing/tests/tkm/xfrmproxy-expire/hosts/moon/etc/tkm/tkm.conf
@@ -14,7 +14,7 @@
             <ip>192.168.0.2</ip>
         </remote>
         <lifetime>
-            <soft>2</soft>
+            <soft>4</soft>
             <hard>60</hard>
         </lifetime>
     </policy>
diff --git a/testing/tests/tkm/xfrmproxy-rekey/description.txt b/testing/tests/tkm/xfrmproxy-rekey/description.txt
new file mode 100644
index 0000000..648011b
--- /dev/null
+++ b/testing/tests/tkm/xfrmproxy-rekey/description.txt
@@ -0,0 +1,6 @@
+A transport connection between the hosts <b>moon</b> and <b>sun</b> is set up.
+The host <b>moon</b> starts the Trusted Key Manager (TKM) and the Ada XFRM
+proxy, which relays XFRM kernel messages to charon. The authentication is based
+on X.509 certificates. The connection is initiated by a ping from <b>moon</b>
+to <b>sun</b>. The test asserts that a rekeying initiated by <b>sun</b> works
+as expected.
diff --git a/testing/tests/tkm/xfrmproxy-expire/evaltest.dat b/testing/tests/tkm/xfrmproxy-rekey/evaltest.dat
similarity index 73%
copy from testing/tests/tkm/xfrmproxy-expire/evaltest.dat
copy to testing/tests/tkm/xfrmproxy-rekey/evaltest.dat
index 05bf420..15bdf3b 100644
--- a/testing/tests/tkm/xfrmproxy-expire/evaltest.dat
+++ b/testing/tests/tkm/xfrmproxy-rekey/evaltest.dat
@@ -2,21 +2,22 @@ moon::ipsec stroke status 2> /dev/null::conn1.*ESTABLISHED.*moon.strongswan.org.
 sun::ipsec status 2> /dev/null::host-host.*ESTABLISHED.*sun.strongswan.org.*moon.strongswan.org::YES
 moon::ipsec stroke status 2> /dev/null::conn1.*INSTALLED, TRANSPORT::YES
 sun::ipsec status 2> /dev/null::host-host.*INSTALLED, TRANSPORT::YES
+moon::sleep 2::wait for rekeying::NO
+sun::cat /var/log/daemon.log::creating rekey job for CHILD_SA ESP/0x.*/192.168.0.2::YES
 moon::ping -c 1 PH_IP_SUN::64 bytes from PH_IP_SUN: icmp_.eq=1::YES
 sun::tcpdump::IP moon.strongswan.org > sun.strongswan.org: ESP::YES
 sun::tcpdump::IP sun.strongswan.org > moon.strongswan.org: ESP::YES
-moon::cat /var/log/daemon.log::ees: acquire received for reqid 1::YES
-moon::cat /var/log/daemon.log::ees: expire received for reqid 1, spi.*, dst 192.168.0.2::YES
-moon::cat /var/log/daemon.log::creating rekey job for CHILD_SA ESP/0x.*/192.168.0.2::YES
+moon::cat /var/log/daemon.log::deleting child SA (esa: 1, spi:.*)::NO
+moon::sleep 2::wait until inbound SA is deleted::NO
 moon::cat /var/log/daemon.log::deleting child SA (esa: 1, spi:.*)::YES
+moon::ping -c 1 PH_IP_SUN::64 bytes from PH_IP_SUN: icmp_.eq=1::YES
 moon::cat /tmp/tkm.log::RSA private key '/etc/tkm/moonKey.der' loaded::YES
 moon::cat /tmp/tkm.log::Adding policy \[ 1, 192.168.0.1 <-> 192.168.0.2 \]::YES
 moon::cat /tmp/tkm.log::Checked CA certificate of CC context 1::YES
 moon::cat /tmp/tkm.log::Authentication of ISA context 1 successful::YES
 moon::cat /tmp/tkm.log::Creating first new ESA context with ID 1 (Isa 1, Sp 1, Ea 1, Initiator TRUE, spi_loc.*, spi_rem.*)::YES
-moon::cat /tmp/tkm.log::Creating ESA context with ID 2 (Isa 1, Sp 1, Ea 1, Dh_Id 1, Nc_Loc_Id 1, Initiator TRUE, spi_loc.*, spi_rem.*)::YES
-moon::cat /tmp/tkm.log | grep 'Adding ESA \[ 1, 192.168.0.1 <-> 192.168.0.2, SPI_in.*, SPI_out.*, soft 2, hard 60 \]' | wc -l::2::YES
+moon::cat /tmp/tkm.log::Creating ESA context with ID 2 (Isa 1, Sp 1, Ea 1, Dh_Id 1, Nc_Loc_Id 1, Initiator FALSE, spi_loc.*, spi_rem.*)::YES
+moon::cat /tmp/tkm.log | grep 'Adding ESA \[ 1, 192.168.0.1 <-> 192.168.0.2, SPI_in.*, SPI_out.*, soft 30, hard 60 \]' | wc -l::2::YES
 moon::cat /tmp/tkm.log::Resetting ESA context 1::YES
 moon::cat /tmp/tkm.log::Deleting ESA \[ 1, 192.168.0.1 <=> 192.168.0.2, SPI_in.*, SPI_out.* \]::YES
 moon::cat /tmp/xfrm_proxy.log::Initiating ESA acquire for reqid 1::YES
-moon::cat /tmp/xfrm_proxy.log::Initiating ESA expire (reqid 1, proto 50, SPI.*, hard FALSE)::YES
diff --git a/testing/tests/tkm/xfrmproxy-expire/hosts/moon/etc/strongswan.conf b/testing/tests/tkm/xfrmproxy-rekey/hosts/moon/etc/strongswan.conf
similarity index 54%
copy from testing/tests/tkm/xfrmproxy-expire/hosts/moon/etc/strongswan.conf
copy to testing/tests/tkm/xfrmproxy-rekey/hosts/moon/etc/strongswan.conf
index cc9d6e0..5b79af9 100644
--- a/testing/tests/tkm/xfrmproxy-expire/hosts/moon/etc/strongswan.conf
+++ b/testing/tests/tkm/xfrmproxy-rekey/hosts/moon/etc/strongswan.conf
@@ -1,6 +1,8 @@
 # /etc/strongswan.conf - strongSwan configuration file
 
 charon-tkm {
+  # remove rekeyed inbound SA a bit quicker for the test scenario
+  delete_rekeyed_delay = 2
   dh_mapping {
     15 = 1
     16 = 2
diff --git a/testing/tests/tkm/xfrmproxy-rekey/hosts/moon/etc/tkm/moonKey.der b/testing/tests/tkm/xfrmproxy-rekey/hosts/moon/etc/tkm/moonKey.der
new file mode 100644
index 0000000..d374893
Binary files /dev/null and b/testing/tests/tkm/xfrmproxy-rekey/hosts/moon/etc/tkm/moonKey.der differ
diff --git a/testing/tests/tkm/xfrmproxy-rekey/hosts/moon/etc/tkm/strongswanCert.der b/testing/tests/tkm/xfrmproxy-rekey/hosts/moon/etc/tkm/strongswanCert.der
new file mode 100644
index 0000000..a5a631f
Binary files /dev/null and b/testing/tests/tkm/xfrmproxy-rekey/hosts/moon/etc/tkm/strongswanCert.der differ
diff --git a/testing/tests/tkm/xfrmproxy-expire/hosts/moon/etc/tkm/tkm.conf b/testing/tests/tkm/xfrmproxy-rekey/hosts/moon/etc/tkm/tkm.conf
similarity index 94%
copy from testing/tests/tkm/xfrmproxy-expire/hosts/moon/etc/tkm/tkm.conf
copy to testing/tests/tkm/xfrmproxy-rekey/hosts/moon/etc/tkm/tkm.conf
index 23e958a..2619c00 100644
--- a/testing/tests/tkm/xfrmproxy-expire/hosts/moon/etc/tkm/tkm.conf
+++ b/testing/tests/tkm/xfrmproxy-rekey/hosts/moon/etc/tkm/tkm.conf
@@ -14,7 +14,7 @@
             <ip>192.168.0.2</ip>
         </remote>
         <lifetime>
-            <soft>2</soft>
+            <soft>30</soft>
             <hard>60</hard>
         </lifetime>
     </policy>
diff --git a/testing/tests/tkm/xfrmproxy-rekey/hosts/sun/etc/ipsec.conf b/testing/tests/tkm/xfrmproxy-rekey/hosts/sun/etc/ipsec.conf
new file mode 100644
index 0000000..9dc6412
--- /dev/null
+++ b/testing/tests/tkm/xfrmproxy-rekey/hosts/sun/etc/ipsec.conf
@@ -0,0 +1,22 @@
+# /etc/ipsec.conf - strongSwan IPsec configuration file
+
+config setup
+
+conn %default
+	ikelifetime=60m
+	keylife=10s
+	rekeymargin=6s
+	rekeyfuzz=0%
+	keyingtries=1
+	keyexchange=ikev2
+
+conn host-host
+	left=PH_IP_SUN
+	leftcert=sunCert.pem
+	leftid=sun.strongswan.org
+	right=PH_IP_MOON
+	rightid=moon.strongswan.org
+	ike=aes256-sha512-modp4096!
+	esp=aes256-sha512-modp4096!
+	type=transport
+	auto=add
diff --git a/testing/tests/tkm/xfrmproxy-rekey/hosts/sun/etc/strongswan.conf b/testing/tests/tkm/xfrmproxy-rekey/hosts/sun/etc/strongswan.conf
new file mode 100644
index 0000000..f585edf
--- /dev/null
+++ b/testing/tests/tkm/xfrmproxy-rekey/hosts/sun/etc/strongswan.conf
@@ -0,0 +1,5 @@
+# /etc/strongswan.conf - strongSwan configuration file
+
+charon {
+  load = aes des sha1 sha2 md5 pem pkcs1 gmp random nonce x509 curl revocation hmac xcbc stroke kernel-netlink socket-default updown
+}
diff --git a/testing/tests/tkm/xfrmproxy-rekey/posttest.dat b/testing/tests/tkm/xfrmproxy-rekey/posttest.dat
new file mode 100644
index 0000000..99efe7b
--- /dev/null
+++ b/testing/tests/tkm/xfrmproxy-rekey/posttest.dat
@@ -0,0 +1,5 @@
+moon::DAEMON_NAME=charon-tkm ipsec stop
+moon::killall xfrm_proxy
+moon::killall tkm_keymanager
+moon::rm -f /tmp/tkm.rpc.ike /tmp/tkm.rpc.ees /tmp/tkm.log /tmp/xfrm_proxy.log
+sun::ipsec stop
diff --git a/testing/tests/tkm/xfrmproxy-rekey/pretest.dat b/testing/tests/tkm/xfrmproxy-rekey/pretest.dat
new file mode 100644
index 0000000..d645ddb
--- /dev/null
+++ b/testing/tests/tkm/xfrmproxy-rekey/pretest.dat
@@ -0,0 +1,12 @@
+sun::ipsec start
+moon::rm /etc/ipsec.secrets
+moon::tkm_cfgtool -c /etc/tkm/tkm.conf -i /etc/ipsec.conf -t /etc/tkm/tkm.bin -s /usr/local/share/tkm/tkmconfig.xsd
+moon::cat /etc/ipsec.conf
+moon::tkm_keymanager -c /etc/tkm/tkm.bin -k /etc/tkm/moonKey.der -r /etc/tkm/strongswanCert.der >/tmp/tkm.log 2>&1 &
+moon::expect-file /tmp/tkm.rpc.ike
+moon::DAEMON_NAME=charon-tkm ipsec start
+moon::expect-file /tmp/tkm.rpc.ees
+moon::xfrm_proxy >/tmp/xfrm_proxy.log 2>&1 &
+moon::DAEMON_NAME=charon-tkm expect-connection conn1
+sun::expect-connection host-host
+moon::ping -c 3 192.168.0.2
diff --git a/testing/tests/tkm/xfrmproxy-rekey/test.conf b/testing/tests/tkm/xfrmproxy-rekey/test.conf
new file mode 100644
index 0000000..9647dc6
--- /dev/null
+++ b/testing/tests/tkm/xfrmproxy-rekey/test.conf
@@ -0,0 +1,21 @@
+#!/bin/bash
+#
+# This configuration file provides information on the
+# guest instances used for this test
+
+# All guest instances that are required for this test
+#
+VIRTHOSTS="moon winnetou sun"
+
+# Corresponding block diagram
+#
+DIAGRAM="m-w-s.png"
+
+# Guest instances on which tcpdump is to be started
+#
+TCPDUMPHOSTS="sun"
+
+# Guest instances on which IPsec is started
+# Used for IPsec logging purposes
+#
+IPSECHOSTS="moon sun"
diff --git a/testing/tests/tnc/tnccs-20-ev-pt-tls/description.txt b/testing/tests/tnc/tnccs-20-ev-pt-tls/description.txt
new file mode 100644
index 0000000..a4d9b4c
--- /dev/null
+++ b/testing/tests/tnc/tnccs-20-ev-pt-tls/description.txt
@@ -0,0 +1,9 @@
+The PT-TLS (RFC 6876) clients <b>carol</b> and <b>dave</b> set up a connection each to the policy decision 
+point (PDP) <b>alice</b>. Endpoint <b>carol</b> uses password-based SASL PLAIN client authentication during the
+<b>PT-TLS negotiation phase</b> whereas endpoint <b>dave</b> uses certificate-based TLS client authentication
+during the <b>TLS setup phase</b>.
+<p/>
+During the ensuing <b>PT-TLS data transport phase</b> the <b>OS</b> and <b>SWIMA</b> IMC/IMV pairs
+loaded by the PT-TLS clients and PDP, respectively, exchange PA-TNC (RFC 5792) messages
+embedded in PB-TNC (RFC 5793) batches. The <b>SWIMA</b> IMC on <b>carol</b> is requested to deliver
+all <b>Software ID Events</b> whereas <b>dave</b> must send a full <b>Software Inventory</b>.
diff --git a/testing/tests/tnc/tnccs-20-pdp-pt-tls/evaltest.dat b/testing/tests/tnc/tnccs-20-ev-pt-tls/evaltest.dat
similarity index 66%
copy from testing/tests/tnc/tnccs-20-pdp-pt-tls/evaltest.dat
copy to testing/tests/tnc/tnccs-20-ev-pt-tls/evaltest.dat
index c3409fd..2248d00 100644
--- a/testing/tests/tnc/tnccs-20-pdp-pt-tls/evaltest.dat
+++ b/testing/tests/tnc/tnccs-20-ev-pt-tls/evaltest.dat
@@ -1,23 +1,24 @@
 dave:: cat /var/log/auth.log::sending TLS CertificateVerify handshake::YES
-dave:: cat /var/log/auth.log::collected ... SWID tags::YES
+dave:: cat /var/log/auth.log::collected ... SW records::YES
+dave:: cat /var/log/auth.log::strongswan.org__strongSwan.*swidtag::YES
 carol::cat /var/log/auth.log::received SASL Success result::YES
-carol::cat /var/log/auth.log::collected ... SWID tag IDs::YES
-carol::cat /var/log/auth.log::collected 1 SWID tag::YES
+carol::cat /var/log/auth.log::collected ... SW ID events::YES
+carol::cat /var/log/auth.log::collected 3 SW records::YES
 alice::cat /var/log/daemon.log::accepting PT-TLS stream from PH_IP_DAVE::YES
 alice::cat /var/log/daemon.log::checking certificate status of.*C=CH, O=Linux strongSwan, OU=Accounting, CN=dave at strongswan.org::YES
 alice::cat /var/log/daemon.log::certificate status is good::YES
 alice::cat /var/log/daemon.log::skipping SASL, client already authenticated by TLS certificate::YES
 alice::cat /var/log/daemon.log::user AR identity.*C=CH, O=Linux strongSwan, OU=Accounting, CN=dave at strongswan.org.*authenticated by certificate::YES
-alice::cat /var/log/daemon.log::received SWID tag inventory with ... items for request 3 at eid 1 of epoch::YES
+alice::cat /var/log/daemon.log::received software inventory with ... items for request 3 at last eid 1 of epoch::YES
+alice::cat /var/log/daemon.log::role=.softwareCreator licensor tagCreator::YES
 alice::cat /var/log/daemon.log::successful system command: ssh root at moon.*logger -t charon -p auth.alert.*host with IP address 192.168.0.200 is blocked::YES
 moon:: cat /var/log/auth.log::host with IP address 192.168.0.200 is blocked::YES
 alice::cat /var/log/daemon.log::accepting PT-TLS stream from PH_IP_CAROL::YES
 alice::cat /var/log/daemon.log::SASL PLAIN authentication successful::YES
 alice::cat /var/log/daemon.log::SASL client identity is.*carol::YES
 alice::cat /var/log/daemon.log::user AR identity.*carol.*authenticated by password::YES
-alice::cat /var/log/daemon.log::received SWID tag ID inventory with ... items for request 9 at eid 1 of epoch::YES
-alice::cat /var/log/daemon.log::1 SWID tag target::YES
-alice::cat /var/log/daemon.log::received SWID tag inventory with 1 item for request 9 at eid 1 of epoch::YES
-alice::cat /var/log/daemon.log::regid.2004-03.org.strongswan_strongSwan-::YES
+alice::cat /var/log/daemon.log::received software ID events with ... items for request 9 at last eid 2 of epoch::YES
+alice::cat /var/log/daemon.log::3 SWID tag target::YES
+alice::cat /var/log/daemon.log::received software inventory with 3 items for request 9 at last eid 2 of epoch::YES
 alice::cat /var/log/daemon.log::successful system command: ssh root at moon.*logger -t charon -p auth.alert.*host with IP address 192.168.0.100 is allowed::YES
 moon::cat /var/log/auth.log::host with IP address 192.168.0.100 is allowed::YES
diff --git a/testing/tests/tnc/tnccs-20-ev-pt-tls/hosts/alice/etc/apache2/sites-available/000-default.conf b/testing/tests/tnc/tnccs-20-ev-pt-tls/hosts/alice/etc/apache2/sites-available/000-default.conf
new file mode 100644
index 0000000..4075f75
--- /dev/null
+++ b/testing/tests/tnc/tnccs-20-ev-pt-tls/hosts/alice/etc/apache2/sites-available/000-default.conf
@@ -0,0 +1,31 @@
+WSGIPythonPath /var/www/tnc
+
+<VirtualHost *:80>
+    ServerName tnc.strongswan.org
+    ServerAlias tnc
+    ServerAdmin webmaster at localhost
+
+    DocumentRoot /var/www/tnc
+
+    <Directory /var/www/tnc/config>
+        <Files wsgi.py>
+            <IfModule mod_authz_core.c>
+               Require all granted
+            </IfModule>
+            <IfModule !mod_authz_core.c>
+                Order deny,allow
+                Allow from all
+            </IfModule>
+        </Files>
+    </Directory>
+
+    WSGIScriptAlias / /var/www/tnc/config/wsgi.py
+    WSGIApplicationGroup %{GLOBAL}
+    WSGIPassAuthorization On
+
+    Alias /static/ /var/www/tnc/static/
+
+    ErrorLog ${APACHE_LOG_DIR}/tnc/error.log
+    LogLevel warn
+    CustomLog ${APACHE_LOG_DIR}/tnc/access.log combined
+</VirtualHost>
diff --git a/testing/tests/tnc/tnccs-20-ev-pt-tls/hosts/alice/etc/apache2/sites-available/default b/testing/tests/tnc/tnccs-20-ev-pt-tls/hosts/alice/etc/apache2/sites-available/default
new file mode 100644
index 0000000..1dc8b56
--- /dev/null
+++ b/testing/tests/tnc/tnccs-20-ev-pt-tls/hosts/alice/etc/apache2/sites-available/default
@@ -0,0 +1 @@
+Include sites-available/000-default.conf
\ No newline at end of file
diff --git a/testing/tests/tnc/tnccs-20-ev-pt-tls/hosts/alice/etc/iptables.rules b/testing/tests/tnc/tnccs-20-ev-pt-tls/hosts/alice/etc/iptables.rules
new file mode 100644
index 0000000..c556d94
--- /dev/null
+++ b/testing/tests/tnc/tnccs-20-ev-pt-tls/hosts/alice/etc/iptables.rules
@@ -0,0 +1,28 @@
+*filter
+
+# default policy is DROP
+-P INPUT DROP
+-P OUTPUT DROP
+-P FORWARD DROP
+
+# open loopback interface
+-A INPUT  -i lo -j ACCEPT
+-A OUTPUT -o lo -j ACCEPT
+
+# allow PT-TLS
+-A INPUT  -i eth0 -p tcp --dport 271 -j ACCEPT
+-A OUTPUT -o eth0 -p tcp --sport 271 -j ACCEPT
+
+# allow inbound ssh
+-A INPUT  -p tcp --dport 22 -j ACCEPT
+-A OUTPUT -p tcp --sport 22 -j ACCEPT
+
+# allow outbound ssh
+-A OUTPUT  -p tcp --dport 22 -j ACCEPT
+-A INPUT  -p tcp --sport 22 -j ACCEPT
+
+# allow crl fetch from winnetou
+-A INPUT  -i eth0 -p tcp --sport 80 -s 192.168.0.150 -j ACCEPT
+-A OUTPUT -o eth0 -p tcp --dport 80 -d 192.168.0.150 -j ACCEPT
+
+COMMIT
diff --git a/testing/tests/tnc/tnccs-20-ev-pt-tls/hosts/alice/etc/pts/data1.sql b/testing/tests/tnc/tnccs-20-ev-pt-tls/hosts/alice/etc/pts/data1.sql
new file mode 100644
index 0000000..16ab96d
--- /dev/null
+++ b/testing/tests/tnc/tnccs-20-ev-pt-tls/hosts/alice/etc/pts/data1.sql
@@ -0,0 +1,61 @@
+/* Devices */
+
+INSERT INTO devices (                  /*  1 */
+  value, product, created
+)
+SELECT 'aabbccddeeff11223344556677889900', id, 1372330615
+FROM products WHERE name = 'Debian DEBIAN_VERSION x86_64';
+
+/* Groups Members */
+
+INSERT INTO groups_members (
+  group_id, device_id
+) VALUES (
+  10, 1
+);
+
+/* Identities */
+
+INSERT INTO identities (
+  type, value
+) VALUES ( /* dave at strongswan.org */
+  4, X'64617665407374726f6e677377616e2e6f7267'
+);
+
+/* Sessions */
+
+INSERT INTO sessions (
+  time, connection, identity, device, product, rec
+)
+SELECT NOW, 1, 1, 1, id, 0
+FROM products WHERE name = 'Debian DEBIAN_VERSION x86_64';
+
+/* Results */
+
+INSERT INTO results (
+  session, policy, rec, result
+) VALUES (
+  1, 1, 0, 'processed 355 packages: 0 not updated, 0 blacklisted, 4 ok, 351 not found'
+);
+
+/* Enforcements */
+
+INSERT INTO enforcements (
+  policy, group_id, max_age, rec_fail, rec_noresult
+) VALUES (
+  3, 10, 0, 2, 2
+);
+
+INSERT INTO enforcements (
+  policy, group_id, max_age
+) VALUES (
+  17, 2, 86400
+);
+
+INSERT INTO enforcements (
+  policy, group_id, max_age
+) VALUES (
+  18, 10, 86400
+);
+
+DELETE FROM enforcements WHERE id = 1;
diff --git a/testing/tests/tnc/tnccs-20-ev-pt-tls/hosts/alice/etc/strongTNC/settings.ini b/testing/tests/tnc/tnccs-20-ev-pt-tls/hosts/alice/etc/strongTNC/settings.ini
new file mode 100644
index 0000000..5ae53c4
--- /dev/null
+++ b/testing/tests/tnc/tnccs-20-ev-pt-tls/hosts/alice/etc/strongTNC/settings.ini
@@ -0,0 +1,19 @@
+[debug]
+DEBUG=0
+TEMPLATE_DEBUG=0
+DEBUG_TOOLBAR=0
+
+[db]
+DJANGO_DB_URL=sqlite:////var/www/tnc/django.db
+STRONGTNC_DB_URL = sqlite:////etc/db.d/config.db
+
+[localization]
+LANGUAGE_CODE=en-us
+TIME_ZONE=Europe/Zurich
+
+[admins]
+Your Name: alice at strongswan.org
+
+[security]
+SECRET_KEY=strongSwan
+ALLOWED_HOSTS=127.0.0.1,10.1.0.10,tnc.strongswan.org,tnc
diff --git a/testing/tests/tnc/tnccs-20-ev-pt-tls/hosts/alice/etc/strongswan.conf b/testing/tests/tnc/tnccs-20-ev-pt-tls/hosts/alice/etc/strongswan.conf
new file mode 100644
index 0000000..1148b94
--- /dev/null
+++ b/testing/tests/tnc/tnccs-20-ev-pt-tls/hosts/alice/etc/strongswan.conf
@@ -0,0 +1,49 @@
+# /etc/strongswan.conf - strongSwan configuration file
+
+charon {
+  load = random nonce pem pkcs1 x509 openssl revocation constraints curl vici socket-default kernel-netlink tnc-pdp tnc-imv tnc-tnccs tnccs-20 sqlite
+
+  syslog {
+    auth {
+      default = 0
+    }
+    daemon {
+      tls = 2
+      tnc = 2 
+      imv = 3
+    }
+  }
+  plugins {
+    tnc-pdp {
+      server = aaa.strongswan.org
+      radius {
+        secret = gv6URkSs
+      }
+    }
+    tnc-imv {
+      dlclose = no
+    }
+  }
+}
+
+libtls {
+  suites = TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
+}
+
+libimcv {
+  database = sqlite:///etc/db.d/config.db
+  policy_script = /usr/local/libexec/ipsec/imv_policy_manager 
+
+  plugins {
+    imv-swima {
+      rest_api {
+        uri = http://admin-user:strongSwan@tnc.strongswan.org/api/
+      }
+    }
+  }
+}
+
+imv_policy_manager {
+  command_allow = ssh root at moon 'logger -t charon -p auth.alert "\"host with IP address %s is allowed\""'
+  command_block = ssh root at moon 'logger -t charon -p auth.alert "\"host with IP address %s is blocked\""'
+}
diff --git a/testing/tests/tnc/tnccs-20-ev-pt-tls/hosts/alice/etc/swanctl/rsa/aaaKey.pem b/testing/tests/tnc/tnccs-20-ev-pt-tls/hosts/alice/etc/swanctl/rsa/aaaKey.pem
new file mode 100644
index 0000000..adc47dd
--- /dev/null
+++ b/testing/tests/tnc/tnccs-20-ev-pt-tls/hosts/alice/etc/swanctl/rsa/aaaKey.pem
@@ -0,0 +1,27 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIIEpQIBAAKCAQEAtxfP0jM8wZqtJvNmYar+WmB5GkzZbm431C5YWpSc/4vjCMXl
+h/7VuGPkOeuEqU4KOKL3l0OQt1Exh77ii9ekg0X//4n132fI/hg0sKVRPCK8HC8l
+0LdwnLLNI7uO5ObYY1KtAVnDeI/cfFbLV0z38/X7GWCpKi7ocmVMNalpD5w7c/9a
+VgpO70O9NPr+OPhs1Lp9uJQQbQzQlhydhK3SLA1bJEcyXYMqOamJud+EcM1Hjq3S
+W5JpKhuroDSxGzMntRF0TgrGXf8ctNfz/52repoUh2GrFfOhkpXrKUErf46NNtnD
+e4FXvyprZNQO4wJBWKCSS3p16UWEL+1LFwiDPQIDAQABAoIBAQCNeNG0+rA0bF7k
+nOf8CZL1pFuOzdin8nQi+Bh/DRvufVlU+wyrM2ZSTqUXd/sOkuVk889ZyvQ0IYGj
+AQStx1cvs9Pl0OTx1ZDBfVShNWv6imBNasTObB+QhLvro037Yr/KpyRUydY2/vn/
+/VSrRSbGE8gMyNqNZKdpVQo44Ij0bJXxx7kVJ7CfftB65bujkRSK5u7eGjFVyHGs
+P9v4n72Pt0mVdC8yeiMjJAmmKLWaDf7U2SUoaxf0IRjRNPdVBuPjbYjfnJ0sGlxF
+sCQtu+3JQ4b7vyxrAyUtImbTLwvFqQHTGIahZUvhGd/1aO0Zmls1mvuZ+VhUIsek
+uBJh54jFAoGBAN7M08mBkA8oUns0IzzG+A0JYDmdbvOWbKtyQDRl7LkXOq/PckIj
+PoliI/5aNZe9+Q8kq8xnvLVcsup7EX6Ovaqc6S3ODNEjy4XEqGMM9tkrz4R4N5f5
+hLayOg3MfdJiPOn3HF+cVvHp0Vwpt8K5TgVmOWkVSKTa+6eX4mhQUuKjAoGBANJg
+Rmka90zo+7PPze4oo5ePeqwZrwQ3/6OeD/G1lqMFPOgk3MLGuv9HvtQA5gyyAH7+
+Qy/t+rdPSC7PZi29s8/cERmWTdbZ1ocuKa6xxSvktl7Ibv51d0sW1n+kfVin7cLL
+SskoK8BRXjXsZg7jjZjE5f6iqdHq+JPA2JWM10CfAoGAOXTvJScxhIcshjNS5wiU
+zZ/eXd1Y0J65VZl4L0sdujngW5iO6bl3FizmBWE0Mva99QbK+0LBarAGP+wO/elH
+xmkCxVo++exWPyARIMImIqlmsc3i4GFrtUXPLOHQjOHivZ+JhKqnzWk0IaVsi14I
+XeIX6h6gBkum3HiR3b7hMSsCgYEAtq7ftbmy8liG6hgTzTIBDUWM0xHihxlRpnVF
+hzGWw61yvGv2QDVugOt+bH7zRib0g1KsaVyQkMoJ9ownQKUxFdkWCFAa++1iezS9
+AXRhscIEE76dk93RX6VPUrw2FNyOfM8n/BIkG/cMhmroHRnBBd5Fkp8SNLWEclnO
+Od95tCUCgYEAgvohkyZAAKMRUFYEvHgwyxeXHifHVPIoK9UN022DJmIEJE2ISGtH
+yHnBKgF52tlYhC9ijKwMG43C9IvycydRUtViOxDV8AiE4BV1tXuQHLl0jD2R7yq5
+9pNtnYgXW+ZKlx9705ltHj8hhKl6r2I8oXdR9KFGO83wq8fr6tyjqHc=
+-----END RSA PRIVATE KEY-----
diff --git a/testing/tests/tnc/tnccs-20-ev-pt-tls/hosts/alice/etc/swanctl/swanctl.conf b/testing/tests/tnc/tnccs-20-ev-pt-tls/hosts/alice/etc/swanctl/swanctl.conf
new file mode 100644
index 0000000..635620b
--- /dev/null
+++ b/testing/tests/tnc/tnccs-20-ev-pt-tls/hosts/alice/etc/swanctl/swanctl.conf
@@ -0,0 +1,7 @@
+secrets {
+
+   eap-carol {
+      id = carol
+      secret = "Ar3etTnp"
+   }
+}
diff --git a/testing/tests/tnc/tnccs-20-ev-pt-tls/hosts/alice/etc/swanctl/x509/aaaCert.pem b/testing/tests/tnc/tnccs-20-ev-pt-tls/hosts/alice/etc/swanctl/x509/aaaCert.pem
new file mode 100644
index 0000000..42083c2
--- /dev/null
+++ b/testing/tests/tnc/tnccs-20-ev-pt-tls/hosts/alice/etc/swanctl/x509/aaaCert.pem
@@ -0,0 +1,25 @@
+-----BEGIN CERTIFICATE-----
+MIIEIDCCAwigAwIBAgIBMzANBgkqhkiG9w0BAQsFADBFMQswCQYDVQQGEwJDSDEZ
+MBcGA1UEChMQTGludXggc3Ryb25nU3dhbjEbMBkGA1UEAxMSc3Ryb25nU3dhbiBS
+b290IENBMB4XDTE1MDgwNDE0NTUzMVoXDTE5MDkwNjE0NTUzMVowRTELMAkGA1UE
+BhMCQ0gxGTAXBgNVBAoTEExpbnV4IHN0cm9uZ1N3YW4xGzAZBgNVBAMTEmFhYS5z
+dHJvbmdzd2FuLm9yZzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALcX
+z9IzPMGarSbzZmGq/lpgeRpM2W5uN9QuWFqUnP+L4wjF5Yf+1bhj5DnrhKlOCjii
+95dDkLdRMYe+4ovXpINF//+J9d9nyP4YNLClUTwivBwvJdC3cJyyzSO7juTm2GNS
+rQFZw3iP3HxWy1dM9/P1+xlgqSou6HJlTDWpaQ+cO3P/WlYKTu9DvTT6/jj4bNS6
+fbiUEG0M0JYcnYSt0iwNWyRHMl2DKjmpibnfhHDNR46t0luSaSobq6A0sRszJ7UR
+dE4Kxl3/HLTX8/+dq3qaFIdhqxXzoZKV6ylBK3+OjTbZw3uBV78qa2TUDuMCQVig
+kkt6delFhC/tSxcIgz0CAwEAAaOCARkwggEVMAkGA1UdEwQCMAAwCwYDVR0PBAQD
+AgOoMB0GA1UdDgQWBBRFNnP26ELy5j7KMOO+a8dh5pLe6DBtBgNVHSMEZjBkgBRd
+p91wBlEyfue2bbO15eBg6i5N76FJpEcwRTELMAkGA1UEBhMCQ0gxGTAXBgNVBAoT
+EExpbnV4IHN0cm9uZ1N3YW4xGzAZBgNVBAMTEnN0cm9uZ1N3YW4gUm9vdCBDQYIB
+ADAdBgNVHREEFjAUghJhYWEuc3Ryb25nc3dhbi5vcmcwEwYDVR0lBAwwCgYIKwYB
+BQUHAwEwOQYDVR0fBDIwMDAuoCygKoYoaHR0cDovL2NybC5zdHJvbmdzd2FuLm9y
+Zy9zdHJvbmdzd2FuLmNybDANBgkqhkiG9w0BAQsFAAOCAQEAsncNPDCCDd4mzIHs
+nHY7b6H1tVQtFSbAQntV06D4D7vOp6Y+M5S8ta50hJu4f4GEeH5c7/hm8gbRdHt/
+TcjlV/UWBfhU3c/hNJo2LpmmtdmYUABLA3rdZ+FzOnAHX9H8eI988G7eHpI9T7L2
+FY2YEnWhIUVjFrojtH2+NbuA/Ori1QwSBiVhvJQgvUPjhKkjUtC+8zIdaCmJFErQ
+GGObpAMtnTcQ74md9BQ791RPMp77tDe1fgm7m8QWIsoIyYEhvzyfk2VTBn1VlWyH
+sbT0Vb3X9ubt0KXn2Xr491WTCpc5rzDWj9CNUYUgW7RaPxgw5cj2HK6oiLnGpO73
+xyr/Qw==
+-----END CERTIFICATE-----
diff --git a/testing/tests/tnc/tnccs-20-ev-pt-tls/hosts/alice/etc/tnc_config b/testing/tests/tnc/tnccs-20-ev-pt-tls/hosts/alice/etc/tnc_config
new file mode 100644
index 0000000..1499dfc
--- /dev/null
+++ b/testing/tests/tnc/tnccs-20-ev-pt-tls/hosts/alice/etc/tnc_config
@@ -0,0 +1,4 @@
+#IMV configuration file for strongSwan client 
+
+IMV "OS"	/usr/local/lib/ipsec/imcvs/imv-os.so
+IMV "SWIMA"	/usr/local/lib/ipsec/imcvs/imv-swima.so
diff --git a/testing/tests/tnc/tnccs-20-ev-pt-tls/hosts/carol/etc/ipsec.sql b/testing/tests/tnc/tnccs-20-ev-pt-tls/hosts/carol/etc/ipsec.sql
new file mode 100644
index 0000000..805c8bf
--- /dev/null
+++ b/testing/tests/tnc/tnccs-20-ev-pt-tls/hosts/carol/etc/ipsec.sql
@@ -0,0 +1,4 @@
+/* strongSwan SQLite database */
+
+/* configuration is read from the command line */
+/* credentials are read from the command line */
diff --git a/testing/tests/tnc/tnccs-20-ev-pt-tls/hosts/carol/etc/iptables.rules b/testing/tests/tnc/tnccs-20-ev-pt-tls/hosts/carol/etc/iptables.rules
new file mode 100644
index 0000000..d01d0a3
--- /dev/null
+++ b/testing/tests/tnc/tnccs-20-ev-pt-tls/hosts/carol/etc/iptables.rules
@@ -0,0 +1,20 @@
+*filter
+
+# default policy is DROP
+-P INPUT DROP
+-P OUTPUT DROP
+-P FORWARD DROP
+
+# allow PT-TLS 
+-A INPUT  -i eth0 -s 10.1.0.10 -p tcp --sport 271 -j ACCEPT
+-A OUTPUT -o eth0 -d 10.1.0.10 -p tcp --dport 271 -j ACCEPT
+
+# allow ssh
+-A INPUT  -p tcp --dport 22 -j ACCEPT
+-A OUTPUT -p tcp --sport 22 -j ACCEPT
+
+# allow crl fetch from winnetou
+-A INPUT  -i eth0 -p tcp --sport 80 -s 192.168.0.150 -j ACCEPT
+-A OUTPUT -o eth0 -p tcp --dport 80 -d 192.168.0.150 -j ACCEPT
+
+COMMIT
diff --git a/testing/tests/tnc/tnccs-20-ev-pt-tls/hosts/carol/etc/pts/options b/testing/tests/tnc/tnccs-20-ev-pt-tls/hosts/carol/etc/pts/options
new file mode 100644
index 0000000..52a3673
--- /dev/null
+++ b/testing/tests/tnc/tnccs-20-ev-pt-tls/hosts/carol/etc/pts/options
@@ -0,0 +1,6 @@
+--connect aaa.strongswan.org
+--client carol
+--secret "Ar3etTnp"
+--cert /etc/swanctl/x509ca/strongswanCert.pem
+--quiet
+--debug 2
diff --git a/testing/tests/tnc/tnccs-20-ev-pt-tls/hosts/carol/etc/strongswan.conf b/testing/tests/tnc/tnccs-20-ev-pt-tls/hosts/carol/etc/strongswan.conf
new file mode 100644
index 0000000..87c3745
--- /dev/null
+++ b/testing/tests/tnc/tnccs-20-ev-pt-tls/hosts/carol/etc/strongswan.conf
@@ -0,0 +1,25 @@
+# /etc/strongswan.conf - strongSwan configuration file
+
+libtls {
+  suites = TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
+}
+
+libimcv {
+  plugins {
+    imc-swima {
+      swid_database = sqlite:///etc/db.d/collector.db
+    }
+  }
+}
+
+pt-tls-client {
+  load = revocation constraints pem openssl curl sqlite nonce tnc-tnccs tnc-imc tnccs-20
+}
+
+sw-collector {
+  database = sqlite:///etc/db.d/collector.db
+  history = /var/log/apt/history.log
+  rest_api {
+    uri = http://admin-user:strongSwan@tnc.strongswan.org/api/
+  }
+}
diff --git a/testing/tests/tnc/tnccs-20-ev-pt-tls/hosts/carol/etc/swanctl/swanctl.conf b/testing/tests/tnc/tnccs-20-ev-pt-tls/hosts/carol/etc/swanctl/swanctl.conf
new file mode 100644
index 0000000..28da4d4
--- /dev/null
+++ b/testing/tests/tnc/tnccs-20-ev-pt-tls/hosts/carol/etc/swanctl/swanctl.conf
@@ -0,0 +1 @@
+# the PT-TLS client reads its configuration and secrets via the command line
diff --git a/testing/tests/tnc/tnccs-20-ev-pt-tls/hosts/carol/etc/tnc_config b/testing/tests/tnc/tnccs-20-ev-pt-tls/hosts/carol/etc/tnc_config
new file mode 100644
index 0000000..3975056
--- /dev/null
+++ b/testing/tests/tnc/tnccs-20-ev-pt-tls/hosts/carol/etc/tnc_config
@@ -0,0 +1,4 @@
+#IMC configuration file for strongSwan client 
+
+IMC "OS" 	/usr/local/lib/ipsec/imcvs/imc-os.so
+IMC "SWIMA"	/usr/local/lib/ipsec/imcvs/imc-swima.so
diff --git a/testing/tests/tnc/tnccs-20-ev-pt-tls/hosts/dave/etc/ipsec.sql b/testing/tests/tnc/tnccs-20-ev-pt-tls/hosts/dave/etc/ipsec.sql
new file mode 100644
index 0000000..805c8bf
--- /dev/null
+++ b/testing/tests/tnc/tnccs-20-ev-pt-tls/hosts/dave/etc/ipsec.sql
@@ -0,0 +1,4 @@
+/* strongSwan SQLite database */
+
+/* configuration is read from the command line */
+/* credentials are read from the command line */
diff --git a/testing/tests/tnc/tnccs-20-ev-pt-tls/hosts/dave/etc/iptables.rules b/testing/tests/tnc/tnccs-20-ev-pt-tls/hosts/dave/etc/iptables.rules
new file mode 100644
index 0000000..d01d0a3
--- /dev/null
+++ b/testing/tests/tnc/tnccs-20-ev-pt-tls/hosts/dave/etc/iptables.rules
@@ -0,0 +1,20 @@
+*filter
+
+# default policy is DROP
+-P INPUT DROP
+-P OUTPUT DROP
+-P FORWARD DROP
+
+# allow PT-TLS 
+-A INPUT  -i eth0 -s 10.1.0.10 -p tcp --sport 271 -j ACCEPT
+-A OUTPUT -o eth0 -d 10.1.0.10 -p tcp --dport 271 -j ACCEPT
+
+# allow ssh
+-A INPUT  -p tcp --dport 22 -j ACCEPT
+-A OUTPUT -p tcp --sport 22 -j ACCEPT
+
+# allow crl fetch from winnetou
+-A INPUT  -i eth0 -p tcp --sport 80 -s 192.168.0.150 -j ACCEPT
+-A OUTPUT -o eth0 -p tcp --dport 80 -d 192.168.0.150 -j ACCEPT
+
+COMMIT
diff --git a/testing/tests/tnc/tnccs-20-ev-pt-tls/hosts/dave/etc/pts/options b/testing/tests/tnc/tnccs-20-ev-pt-tls/hosts/dave/etc/pts/options
new file mode 100644
index 0000000..0895314
--- /dev/null
+++ b/testing/tests/tnc/tnccs-20-ev-pt-tls/hosts/dave/etc/pts/options
@@ -0,0 +1,7 @@
+--connect aaa.strongswan.org
+--client dave at strongswan.org
+--key  /etc/swanctl/rsa/daveKey.pem
+--cert /etc/swanctl/x509/daveCert.pem
+--cert /etc/swanctl/x509ca/strongswanCert.pem
+--quiet
+--debug 2
diff --git a/testing/tests/tnc/tnccs-20-ev-pt-tls/hosts/dave/etc/strongswan.conf b/testing/tests/tnc/tnccs-20-ev-pt-tls/hosts/dave/etc/strongswan.conf
new file mode 100644
index 0000000..93cbb71
--- /dev/null
+++ b/testing/tests/tnc/tnccs-20-ev-pt-tls/hosts/dave/etc/strongswan.conf
@@ -0,0 +1,20 @@
+# /etc/strongswan.conf - strongSwan configuration file
+
+libimcv {
+  plugins {
+    imc-os {
+      push_info = no
+    }
+    imc-swima {
+      swid_pretty = yes
+    }
+  }
+}
+
+libtls {
+  suites = TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
+}
+
+pt-tls-client {
+  load = revocation constraints pem openssl curl nonce tnc-tnccs tnc-imc tnccs-20
+}
diff --git a/testing/tests/tnc/tnccs-20-ev-pt-tls/hosts/dave/etc/swanctl/swanctl.conf b/testing/tests/tnc/tnccs-20-ev-pt-tls/hosts/dave/etc/swanctl/swanctl.conf
new file mode 100644
index 0000000..28da4d4
--- /dev/null
+++ b/testing/tests/tnc/tnccs-20-ev-pt-tls/hosts/dave/etc/swanctl/swanctl.conf
@@ -0,0 +1 @@
+# the PT-TLS client reads its configuration and secrets via the command line
diff --git a/testing/tests/tnc/tnccs-20-ev-pt-tls/hosts/dave/etc/tnc_config b/testing/tests/tnc/tnccs-20-ev-pt-tls/hosts/dave/etc/tnc_config
new file mode 100644
index 0000000..3975056
--- /dev/null
+++ b/testing/tests/tnc/tnccs-20-ev-pt-tls/hosts/dave/etc/tnc_config
@@ -0,0 +1,4 @@
+#IMC configuration file for strongSwan client 
+
+IMC "OS" 	/usr/local/lib/ipsec/imcvs/imc-os.so
+IMC "SWIMA"	/usr/local/lib/ipsec/imcvs/imc-swima.so
diff --git a/testing/tests/tkm/xfrmproxy-expire/hosts/moon/etc/strongswan.conf b/testing/tests/tnc/tnccs-20-ev-pt-tls/hosts/moon/etc/strongswan.conf
similarity index 50%
copy from testing/tests/tkm/xfrmproxy-expire/hosts/moon/etc/strongswan.conf
copy to testing/tests/tnc/tnccs-20-ev-pt-tls/hosts/moon/etc/strongswan.conf
index cc9d6e0..d99a4b7 100644
--- a/testing/tests/tkm/xfrmproxy-expire/hosts/moon/etc/strongswan.conf
+++ b/testing/tests/tnc/tnccs-20-ev-pt-tls/hosts/moon/etc/strongswan.conf
@@ -1,8 +1,3 @@
 # /etc/strongswan.conf - strongSwan configuration file
 
-charon-tkm {
-  dh_mapping {
-    15 = 1
-    16 = 2
-  }
-}
+# this file is not used in this scenario 
diff --git a/testing/tests/tnc/tnccs-20-ev-pt-tls/hosts/moon/etc/swanctl/swanctl.conf b/testing/tests/tnc/tnccs-20-ev-pt-tls/hosts/moon/etc/swanctl/swanctl.conf
new file mode 100644
index 0000000..27f96a6
--- /dev/null
+++ b/testing/tests/tnc/tnccs-20-ev-pt-tls/hosts/moon/etc/swanctl/swanctl.conf
@@ -0,0 +1 @@
+# this file is not used in this scenario 
diff --git a/testing/tests/tnc/tnccs-20-ev-pt-tls/posttest.dat b/testing/tests/tnc/tnccs-20-ev-pt-tls/posttest.dat
new file mode 100644
index 0000000..09c8a6c
--- /dev/null
+++ b/testing/tests/tnc/tnccs-20-ev-pt-tls/posttest.dat
@@ -0,0 +1,10 @@
+carol::ip route del 10.1.0.0/16 via 192.168.0.1
+dave::ip route del 10.1.0.0/16 via 192.168.0.1
+winnetou::ip route del 10.1.0.0/16 via 192.168.0.1
+alice::service charon stop
+alice::service apache2 stop
+alice::rm /etc/swanctl/rsa/aaaKey.pem
+alice::rm /etc/swanctl/x509/aaaCert.pem
+alice::iptables-restore < /etc/iptables.flush
+carol::iptables-restore < /etc/iptables.flush
+dave::iptables-restore < /etc/iptables.flush
diff --git a/testing/tests/tnc/tnccs-20-pdp-pt-tls/pretest.dat b/testing/tests/tnc/tnccs-20-ev-pt-tls/pretest.dat
similarity index 86%
copy from testing/tests/tnc/tnccs-20-pdp-pt-tls/pretest.dat
copy to testing/tests/tnc/tnccs-20-ev-pt-tls/pretest.dat
index 17951e8..c0d7323 100644
--- a/testing/tests/tnc/tnccs-20-pdp-pt-tls/pretest.dat
+++ b/testing/tests/tnc/tnccs-20-ev-pt-tls/pretest.dat
@@ -19,7 +19,8 @@ alice::swanctl --load-creds
 winnetou::ip route add 10.1.0.0/16 via 192.168.0.1
 dave::ip route add 10.1.0.0/16 via 192.168.0.1
 dave::cat /etc/pts/options
-dave::ipsec pt-tls-client --optionsfrom /etc/pts/options
+dave::/usr/local/bin/pt-tls-client --optionsfrom /etc/pts/options
+carol::/usr/local/bin/init_collector
 carol::ip route add 10.1.0.0/16 via 192.168.0.1
 carol::cat /etc/pts/options
-carol::ipsec pt-tls-client --optionsfrom /etc/pts/options
+carol::/usr/local/bin/pt-tls-client --optionsfrom /etc/pts/options
diff --git a/testing/tests/tnc/tnccs-20-ev-pt-tls/test.conf b/testing/tests/tnc/tnccs-20-ev-pt-tls/test.conf
new file mode 100644
index 0000000..f434789
--- /dev/null
+++ b/testing/tests/tnc/tnccs-20-ev-pt-tls/test.conf
@@ -0,0 +1,29 @@
+#!/bin/bash
+#
+# This configuration file provides information on the
+# guest instances used for this test
+
+# All guest instances that are required for this test
+#
+VIRTHOSTS="alice moon carol winnetou dave"
+
+# Corresponding block diagram
+#
+DIAGRAM="a-m-c-w-d.png"
+
+# Guest instances on which tcpdump is to be started
+#
+TCPDUMPHOSTS="moon"
+
+# Guest instances on which IPsec is started
+# Used for IPsec logging purposes
+#
+IPSECHOSTS="carol moon dave alice"
+
+# Guest instances on which databases are used
+#
+DBHOSTS="alice carol"
+
+# charon controlled by swanctl
+#
+SWANCTL=1
diff --git a/testing/tests/tnc/tnccs-20-mutual-pt-tls/pretest.dat b/testing/tests/tnc/tnccs-20-mutual-pt-tls/pretest.dat
index af53e6c..8642292 100644
--- a/testing/tests/tnc/tnccs-20-mutual-pt-tls/pretest.dat
+++ b/testing/tests/tnc/tnccs-20-mutual-pt-tls/pretest.dat
@@ -1,4 +1,4 @@
 sun::service charon start
 moon::cat /etc/pts/options
 moon::sleep 1
-moon::ipsec pt-tls-client --optionsfrom /etc/pts/options
+moon::/usr/local/bin/pt-tls-client --optionsfrom /etc/pts/options
diff --git a/testing/tests/tnc/tnccs-20-nea-pt-tls/description.txt b/testing/tests/tnc/tnccs-20-nea-pt-tls/description.txt
new file mode 100644
index 0000000..90e8548
--- /dev/null
+++ b/testing/tests/tnc/tnccs-20-nea-pt-tls/description.txt
@@ -0,0 +1,9 @@
+The PT-TLS (RFC 6876) clients <b>carol</b> and <b>dave</b> set up a connection each to the policy decision 
+point (PDP) <b>alice</b>. Endpoint <b>carol</b> uses password-based SASL PLAIN client authentication during the
+<b>PT-TLS negotiation phase</b> whereas endpoint <b>dave</b> uses certificate-based TLS client authentication
+during the <b>TLS setup phase</b>.
+<p/>
+During the ensuing <b>PT-TLS data transport phase</b> the <b>OS</b> and <b>SWIMA</b> IMC/IMV pairs
+loaded by the PT-TLS clients and PDP, respectively, exchange PA-TNC (RFC 5792) messages
+embedded in PB-TNC (RFC 5793) batches. The <b>SWIMA</b> IMC on <b>carol</b> is requested to deliver
+a concise <b>Software ID Inventory</b> whereas <b>dave</b> must send a full <b>Software Inventory</b>.
diff --git a/testing/tests/tnc/tnccs-20-pdp-pt-tls/evaltest.dat b/testing/tests/tnc/tnccs-20-nea-pt-tls/evaltest.dat
similarity index 65%
copy from testing/tests/tnc/tnccs-20-pdp-pt-tls/evaltest.dat
copy to testing/tests/tnc/tnccs-20-nea-pt-tls/evaltest.dat
index c3409fd..198b2bd 100644
--- a/testing/tests/tnc/tnccs-20-pdp-pt-tls/evaltest.dat
+++ b/testing/tests/tnc/tnccs-20-nea-pt-tls/evaltest.dat
@@ -1,23 +1,25 @@
 dave:: cat /var/log/auth.log::sending TLS CertificateVerify handshake::YES
-dave:: cat /var/log/auth.log::collected ... SWID tags::YES
+dave:: cat /var/log/auth.log::collected ... SW records::YES
 carol::cat /var/log/auth.log::received SASL Success result::YES
-carol::cat /var/log/auth.log::collected ... SWID tag IDs::YES
-carol::cat /var/log/auth.log::collected 1 SWID tag::YES
+carol::cat /var/log/auth.log::collected ... SW ID records::YES
+carol::cat /var/log/auth.log::strongswan.org__strongSwan.*swidtag::YES
+carol::cat /var/log/auth.log::collected 1 SW record::YES
 alice::cat /var/log/daemon.log::accepting PT-TLS stream from PH_IP_DAVE::YES
 alice::cat /var/log/daemon.log::checking certificate status of.*C=CH, O=Linux strongSwan, OU=Accounting, CN=dave at strongswan.org::YES
 alice::cat /var/log/daemon.log::certificate status is good::YES
 alice::cat /var/log/daemon.log::skipping SASL, client already authenticated by TLS certificate::YES
 alice::cat /var/log/daemon.log::user AR identity.*C=CH, O=Linux strongSwan, OU=Accounting, CN=dave at strongswan.org.*authenticated by certificate::YES
-alice::cat /var/log/daemon.log::received SWID tag inventory with ... items for request 3 at eid 1 of epoch::YES
+alice::cat /var/log/daemon.log::received software inventory with ... items for request 3 at last eid 1 of epoch::YES
 alice::cat /var/log/daemon.log::successful system command: ssh root at moon.*logger -t charon -p auth.alert.*host with IP address 192.168.0.200 is blocked::YES
 moon:: cat /var/log/auth.log::host with IP address 192.168.0.200 is blocked::YES
 alice::cat /var/log/daemon.log::accepting PT-TLS stream from PH_IP_CAROL::YES
 alice::cat /var/log/daemon.log::SASL PLAIN authentication successful::YES
 alice::cat /var/log/daemon.log::SASL client identity is.*carol::YES
 alice::cat /var/log/daemon.log::user AR identity.*carol.*authenticated by password::YES
-alice::cat /var/log/daemon.log::received SWID tag ID inventory with ... items for request 9 at eid 1 of epoch::YES
+alice::cat /var/log/daemon.log::failed to collect SW ID events, fallback to SW ID inventory::YES
+alice::cat /var/log/daemon.log::received software ID inventory with ... items for request 9 at last eid 1 of epoch::YES
 alice::cat /var/log/daemon.log::1 SWID tag target::YES
-alice::cat /var/log/daemon.log::received SWID tag inventory with 1 item for request 9 at eid 1 of epoch::YES
-alice::cat /var/log/daemon.log::regid.2004-03.org.strongswan_strongSwan-::YES
+alice::cat /var/log/daemon.log::received software inventory with 1 item for request 9 at last eid 1 of epoch::YES
+alice::cat /var/log/daemon.log::strongswan.org__strongSwan.*@ /usr/local/share/strongswan::YES
 alice::cat /var/log/daemon.log::successful system command: ssh root at moon.*logger -t charon -p auth.alert.*host with IP address 192.168.0.100 is allowed::YES
 moon::cat /var/log/auth.log::host with IP address 192.168.0.100 is allowed::YES
diff --git a/testing/tests/tnc/tnccs-20-nea-pt-tls/hosts/alice/etc/apache2/sites-available/000-default.conf b/testing/tests/tnc/tnccs-20-nea-pt-tls/hosts/alice/etc/apache2/sites-available/000-default.conf
new file mode 100644
index 0000000..4075f75
--- /dev/null
+++ b/testing/tests/tnc/tnccs-20-nea-pt-tls/hosts/alice/etc/apache2/sites-available/000-default.conf
@@ -0,0 +1,31 @@
+WSGIPythonPath /var/www/tnc
+
+<VirtualHost *:80>
+    ServerName tnc.strongswan.org
+    ServerAlias tnc
+    ServerAdmin webmaster at localhost
+
+    DocumentRoot /var/www/tnc
+
+    <Directory /var/www/tnc/config>
+        <Files wsgi.py>
+            <IfModule mod_authz_core.c>
+               Require all granted
+            </IfModule>
+            <IfModule !mod_authz_core.c>
+                Order deny,allow
+                Allow from all
+            </IfModule>
+        </Files>
+    </Directory>
+
+    WSGIScriptAlias / /var/www/tnc/config/wsgi.py
+    WSGIApplicationGroup %{GLOBAL}
+    WSGIPassAuthorization On
+
+    Alias /static/ /var/www/tnc/static/
+
+    ErrorLog ${APACHE_LOG_DIR}/tnc/error.log
+    LogLevel warn
+    CustomLog ${APACHE_LOG_DIR}/tnc/access.log combined
+</VirtualHost>
diff --git a/testing/tests/tnc/tnccs-20-nea-pt-tls/hosts/alice/etc/apache2/sites-available/default b/testing/tests/tnc/tnccs-20-nea-pt-tls/hosts/alice/etc/apache2/sites-available/default
new file mode 100644
index 0000000..1dc8b56
--- /dev/null
+++ b/testing/tests/tnc/tnccs-20-nea-pt-tls/hosts/alice/etc/apache2/sites-available/default
@@ -0,0 +1 @@
+Include sites-available/000-default.conf
\ No newline at end of file
diff --git a/testing/tests/tnc/tnccs-20-nea-pt-tls/hosts/alice/etc/iptables.rules b/testing/tests/tnc/tnccs-20-nea-pt-tls/hosts/alice/etc/iptables.rules
new file mode 100644
index 0000000..c556d94
--- /dev/null
+++ b/testing/tests/tnc/tnccs-20-nea-pt-tls/hosts/alice/etc/iptables.rules
@@ -0,0 +1,28 @@
+*filter
+
+# default policy is DROP
+-P INPUT DROP
+-P OUTPUT DROP
+-P FORWARD DROP
+
+# open loopback interface
+-A INPUT  -i lo -j ACCEPT
+-A OUTPUT -o lo -j ACCEPT
+
+# allow PT-TLS
+-A INPUT  -i eth0 -p tcp --dport 271 -j ACCEPT
+-A OUTPUT -o eth0 -p tcp --sport 271 -j ACCEPT
+
+# allow inbound ssh
+-A INPUT  -p tcp --dport 22 -j ACCEPT
+-A OUTPUT -p tcp --sport 22 -j ACCEPT
+
+# allow outbound ssh
+-A OUTPUT  -p tcp --dport 22 -j ACCEPT
+-A INPUT  -p tcp --sport 22 -j ACCEPT
+
+# allow crl fetch from winnetou
+-A INPUT  -i eth0 -p tcp --sport 80 -s 192.168.0.150 -j ACCEPT
+-A OUTPUT -o eth0 -p tcp --dport 80 -d 192.168.0.150 -j ACCEPT
+
+COMMIT
diff --git a/testing/tests/tnc/tnccs-20-nea-pt-tls/hosts/alice/etc/pts/data1.sql b/testing/tests/tnc/tnccs-20-nea-pt-tls/hosts/alice/etc/pts/data1.sql
new file mode 100644
index 0000000..16ab96d
--- /dev/null
+++ b/testing/tests/tnc/tnccs-20-nea-pt-tls/hosts/alice/etc/pts/data1.sql
@@ -0,0 +1,61 @@
+/* Devices */
+
+INSERT INTO devices (                  /*  1 */
+  value, product, created
+)
+SELECT 'aabbccddeeff11223344556677889900', id, 1372330615
+FROM products WHERE name = 'Debian DEBIAN_VERSION x86_64';
+
+/* Groups Members */
+
+INSERT INTO groups_members (
+  group_id, device_id
+) VALUES (
+  10, 1
+);
+
+/* Identities */
+
+INSERT INTO identities (
+  type, value
+) VALUES ( /* dave at strongswan.org */
+  4, X'64617665407374726f6e677377616e2e6f7267'
+);
+
+/* Sessions */
+
+INSERT INTO sessions (
+  time, connection, identity, device, product, rec
+)
+SELECT NOW, 1, 1, 1, id, 0
+FROM products WHERE name = 'Debian DEBIAN_VERSION x86_64';
+
+/* Results */
+
+INSERT INTO results (
+  session, policy, rec, result
+) VALUES (
+  1, 1, 0, 'processed 355 packages: 0 not updated, 0 blacklisted, 4 ok, 351 not found'
+);
+
+/* Enforcements */
+
+INSERT INTO enforcements (
+  policy, group_id, max_age, rec_fail, rec_noresult
+) VALUES (
+  3, 10, 0, 2, 2
+);
+
+INSERT INTO enforcements (
+  policy, group_id, max_age
+) VALUES (
+  17, 2, 86400
+);
+
+INSERT INTO enforcements (
+  policy, group_id, max_age
+) VALUES (
+  18, 10, 86400
+);
+
+DELETE FROM enforcements WHERE id = 1;
diff --git a/testing/tests/tnc/tnccs-20-nea-pt-tls/hosts/alice/etc/strongTNC/settings.ini b/testing/tests/tnc/tnccs-20-nea-pt-tls/hosts/alice/etc/strongTNC/settings.ini
new file mode 100644
index 0000000..5ae53c4
--- /dev/null
+++ b/testing/tests/tnc/tnccs-20-nea-pt-tls/hosts/alice/etc/strongTNC/settings.ini
@@ -0,0 +1,19 @@
+[debug]
+DEBUG=0
+TEMPLATE_DEBUG=0
+DEBUG_TOOLBAR=0
+
+[db]
+DJANGO_DB_URL=sqlite:////var/www/tnc/django.db
+STRONGTNC_DB_URL = sqlite:////etc/db.d/config.db
+
+[localization]
+LANGUAGE_CODE=en-us
+TIME_ZONE=Europe/Zurich
+
+[admins]
+Your Name: alice at strongswan.org
+
+[security]
+SECRET_KEY=strongSwan
+ALLOWED_HOSTS=127.0.0.1,10.1.0.10,tnc.strongswan.org,tnc
diff --git a/testing/tests/tnc/tnccs-20-nea-pt-tls/hosts/alice/etc/strongswan.conf b/testing/tests/tnc/tnccs-20-nea-pt-tls/hosts/alice/etc/strongswan.conf
new file mode 100644
index 0000000..1148b94
--- /dev/null
+++ b/testing/tests/tnc/tnccs-20-nea-pt-tls/hosts/alice/etc/strongswan.conf
@@ -0,0 +1,49 @@
+# /etc/strongswan.conf - strongSwan configuration file
+
+charon {
+  load = random nonce pem pkcs1 x509 openssl revocation constraints curl vici socket-default kernel-netlink tnc-pdp tnc-imv tnc-tnccs tnccs-20 sqlite
+
+  syslog {
+    auth {
+      default = 0
+    }
+    daemon {
+      tls = 2
+      tnc = 2 
+      imv = 3
+    }
+  }
+  plugins {
+    tnc-pdp {
+      server = aaa.strongswan.org
+      radius {
+        secret = gv6URkSs
+      }
+    }
+    tnc-imv {
+      dlclose = no
+    }
+  }
+}
+
+libtls {
+  suites = TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
+}
+
+libimcv {
+  database = sqlite:///etc/db.d/config.db
+  policy_script = /usr/local/libexec/ipsec/imv_policy_manager 
+
+  plugins {
+    imv-swima {
+      rest_api {
+        uri = http://admin-user:strongSwan@tnc.strongswan.org/api/
+      }
+    }
+  }
+}
+
+imv_policy_manager {
+  command_allow = ssh root at moon 'logger -t charon -p auth.alert "\"host with IP address %s is allowed\""'
+  command_block = ssh root at moon 'logger -t charon -p auth.alert "\"host with IP address %s is blocked\""'
+}
diff --git a/testing/tests/tnc/tnccs-20-nea-pt-tls/hosts/alice/etc/swanctl/rsa/aaaKey.pem b/testing/tests/tnc/tnccs-20-nea-pt-tls/hosts/alice/etc/swanctl/rsa/aaaKey.pem
new file mode 100644
index 0000000..adc47dd
--- /dev/null
+++ b/testing/tests/tnc/tnccs-20-nea-pt-tls/hosts/alice/etc/swanctl/rsa/aaaKey.pem
@@ -0,0 +1,27 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIIEpQIBAAKCAQEAtxfP0jM8wZqtJvNmYar+WmB5GkzZbm431C5YWpSc/4vjCMXl
+h/7VuGPkOeuEqU4KOKL3l0OQt1Exh77ii9ekg0X//4n132fI/hg0sKVRPCK8HC8l
+0LdwnLLNI7uO5ObYY1KtAVnDeI/cfFbLV0z38/X7GWCpKi7ocmVMNalpD5w7c/9a
+VgpO70O9NPr+OPhs1Lp9uJQQbQzQlhydhK3SLA1bJEcyXYMqOamJud+EcM1Hjq3S
+W5JpKhuroDSxGzMntRF0TgrGXf8ctNfz/52repoUh2GrFfOhkpXrKUErf46NNtnD
+e4FXvyprZNQO4wJBWKCSS3p16UWEL+1LFwiDPQIDAQABAoIBAQCNeNG0+rA0bF7k
+nOf8CZL1pFuOzdin8nQi+Bh/DRvufVlU+wyrM2ZSTqUXd/sOkuVk889ZyvQ0IYGj
+AQStx1cvs9Pl0OTx1ZDBfVShNWv6imBNasTObB+QhLvro037Yr/KpyRUydY2/vn/
+/VSrRSbGE8gMyNqNZKdpVQo44Ij0bJXxx7kVJ7CfftB65bujkRSK5u7eGjFVyHGs
+P9v4n72Pt0mVdC8yeiMjJAmmKLWaDf7U2SUoaxf0IRjRNPdVBuPjbYjfnJ0sGlxF
+sCQtu+3JQ4b7vyxrAyUtImbTLwvFqQHTGIahZUvhGd/1aO0Zmls1mvuZ+VhUIsek
+uBJh54jFAoGBAN7M08mBkA8oUns0IzzG+A0JYDmdbvOWbKtyQDRl7LkXOq/PckIj
+PoliI/5aNZe9+Q8kq8xnvLVcsup7EX6Ovaqc6S3ODNEjy4XEqGMM9tkrz4R4N5f5
+hLayOg3MfdJiPOn3HF+cVvHp0Vwpt8K5TgVmOWkVSKTa+6eX4mhQUuKjAoGBANJg
+Rmka90zo+7PPze4oo5ePeqwZrwQ3/6OeD/G1lqMFPOgk3MLGuv9HvtQA5gyyAH7+
+Qy/t+rdPSC7PZi29s8/cERmWTdbZ1ocuKa6xxSvktl7Ibv51d0sW1n+kfVin7cLL
+SskoK8BRXjXsZg7jjZjE5f6iqdHq+JPA2JWM10CfAoGAOXTvJScxhIcshjNS5wiU
+zZ/eXd1Y0J65VZl4L0sdujngW5iO6bl3FizmBWE0Mva99QbK+0LBarAGP+wO/elH
+xmkCxVo++exWPyARIMImIqlmsc3i4GFrtUXPLOHQjOHivZ+JhKqnzWk0IaVsi14I
+XeIX6h6gBkum3HiR3b7hMSsCgYEAtq7ftbmy8liG6hgTzTIBDUWM0xHihxlRpnVF
+hzGWw61yvGv2QDVugOt+bH7zRib0g1KsaVyQkMoJ9ownQKUxFdkWCFAa++1iezS9
+AXRhscIEE76dk93RX6VPUrw2FNyOfM8n/BIkG/cMhmroHRnBBd5Fkp8SNLWEclnO
+Od95tCUCgYEAgvohkyZAAKMRUFYEvHgwyxeXHifHVPIoK9UN022DJmIEJE2ISGtH
+yHnBKgF52tlYhC9ijKwMG43C9IvycydRUtViOxDV8AiE4BV1tXuQHLl0jD2R7yq5
+9pNtnYgXW+ZKlx9705ltHj8hhKl6r2I8oXdR9KFGO83wq8fr6tyjqHc=
+-----END RSA PRIVATE KEY-----
diff --git a/testing/tests/tnc/tnccs-20-nea-pt-tls/hosts/alice/etc/swanctl/swanctl.conf b/testing/tests/tnc/tnccs-20-nea-pt-tls/hosts/alice/etc/swanctl/swanctl.conf
new file mode 100644
index 0000000..635620b
--- /dev/null
+++ b/testing/tests/tnc/tnccs-20-nea-pt-tls/hosts/alice/etc/swanctl/swanctl.conf
@@ -0,0 +1,7 @@
+secrets {
+
+   eap-carol {
+      id = carol
+      secret = "Ar3etTnp"
+   }
+}
diff --git a/testing/tests/tnc/tnccs-20-nea-pt-tls/hosts/alice/etc/swanctl/x509/aaaCert.pem b/testing/tests/tnc/tnccs-20-nea-pt-tls/hosts/alice/etc/swanctl/x509/aaaCert.pem
new file mode 100644
index 0000000..42083c2
--- /dev/null
+++ b/testing/tests/tnc/tnccs-20-nea-pt-tls/hosts/alice/etc/swanctl/x509/aaaCert.pem
@@ -0,0 +1,25 @@
+-----BEGIN CERTIFICATE-----
+MIIEIDCCAwigAwIBAgIBMzANBgkqhkiG9w0BAQsFADBFMQswCQYDVQQGEwJDSDEZ
+MBcGA1UEChMQTGludXggc3Ryb25nU3dhbjEbMBkGA1UEAxMSc3Ryb25nU3dhbiBS
+b290IENBMB4XDTE1MDgwNDE0NTUzMVoXDTE5MDkwNjE0NTUzMVowRTELMAkGA1UE
+BhMCQ0gxGTAXBgNVBAoTEExpbnV4IHN0cm9uZ1N3YW4xGzAZBgNVBAMTEmFhYS5z
+dHJvbmdzd2FuLm9yZzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALcX
+z9IzPMGarSbzZmGq/lpgeRpM2W5uN9QuWFqUnP+L4wjF5Yf+1bhj5DnrhKlOCjii
+95dDkLdRMYe+4ovXpINF//+J9d9nyP4YNLClUTwivBwvJdC3cJyyzSO7juTm2GNS
+rQFZw3iP3HxWy1dM9/P1+xlgqSou6HJlTDWpaQ+cO3P/WlYKTu9DvTT6/jj4bNS6
+fbiUEG0M0JYcnYSt0iwNWyRHMl2DKjmpibnfhHDNR46t0luSaSobq6A0sRszJ7UR
+dE4Kxl3/HLTX8/+dq3qaFIdhqxXzoZKV6ylBK3+OjTbZw3uBV78qa2TUDuMCQVig
+kkt6delFhC/tSxcIgz0CAwEAAaOCARkwggEVMAkGA1UdEwQCMAAwCwYDVR0PBAQD
+AgOoMB0GA1UdDgQWBBRFNnP26ELy5j7KMOO+a8dh5pLe6DBtBgNVHSMEZjBkgBRd
+p91wBlEyfue2bbO15eBg6i5N76FJpEcwRTELMAkGA1UEBhMCQ0gxGTAXBgNVBAoT
+EExpbnV4IHN0cm9uZ1N3YW4xGzAZBgNVBAMTEnN0cm9uZ1N3YW4gUm9vdCBDQYIB
+ADAdBgNVHREEFjAUghJhYWEuc3Ryb25nc3dhbi5vcmcwEwYDVR0lBAwwCgYIKwYB
+BQUHAwEwOQYDVR0fBDIwMDAuoCygKoYoaHR0cDovL2NybC5zdHJvbmdzd2FuLm9y
+Zy9zdHJvbmdzd2FuLmNybDANBgkqhkiG9w0BAQsFAAOCAQEAsncNPDCCDd4mzIHs
+nHY7b6H1tVQtFSbAQntV06D4D7vOp6Y+M5S8ta50hJu4f4GEeH5c7/hm8gbRdHt/
+TcjlV/UWBfhU3c/hNJo2LpmmtdmYUABLA3rdZ+FzOnAHX9H8eI988G7eHpI9T7L2
+FY2YEnWhIUVjFrojtH2+NbuA/Ori1QwSBiVhvJQgvUPjhKkjUtC+8zIdaCmJFErQ
+GGObpAMtnTcQ74md9BQ791RPMp77tDe1fgm7m8QWIsoIyYEhvzyfk2VTBn1VlWyH
+sbT0Vb3X9ubt0KXn2Xr491WTCpc5rzDWj9CNUYUgW7RaPxgw5cj2HK6oiLnGpO73
+xyr/Qw==
+-----END CERTIFICATE-----
diff --git a/testing/tests/tnc/tnccs-20-nea-pt-tls/hosts/alice/etc/tnc_config b/testing/tests/tnc/tnccs-20-nea-pt-tls/hosts/alice/etc/tnc_config
new file mode 100644
index 0000000..1499dfc
--- /dev/null
+++ b/testing/tests/tnc/tnccs-20-nea-pt-tls/hosts/alice/etc/tnc_config
@@ -0,0 +1,4 @@
+#IMV configuration file for strongSwan client 
+
+IMV "OS"	/usr/local/lib/ipsec/imcvs/imv-os.so
+IMV "SWIMA"	/usr/local/lib/ipsec/imcvs/imv-swima.so
diff --git a/testing/tests/tnc/tnccs-20-nea-pt-tls/hosts/carol/etc/ipsec.sql b/testing/tests/tnc/tnccs-20-nea-pt-tls/hosts/carol/etc/ipsec.sql
new file mode 100644
index 0000000..805c8bf
--- /dev/null
+++ b/testing/tests/tnc/tnccs-20-nea-pt-tls/hosts/carol/etc/ipsec.sql
@@ -0,0 +1,4 @@
+/* strongSwan SQLite database */
+
+/* configuration is read from the command line */
+/* credentials are read from the command line */
diff --git a/testing/tests/tnc/tnccs-20-nea-pt-tls/hosts/carol/etc/iptables.rules b/testing/tests/tnc/tnccs-20-nea-pt-tls/hosts/carol/etc/iptables.rules
new file mode 100644
index 0000000..d01d0a3
--- /dev/null
+++ b/testing/tests/tnc/tnccs-20-nea-pt-tls/hosts/carol/etc/iptables.rules
@@ -0,0 +1,20 @@
+*filter
+
+# default policy is DROP
+-P INPUT DROP
+-P OUTPUT DROP
+-P FORWARD DROP
+
+# allow PT-TLS 
+-A INPUT  -i eth0 -s 10.1.0.10 -p tcp --sport 271 -j ACCEPT
+-A OUTPUT -o eth0 -d 10.1.0.10 -p tcp --dport 271 -j ACCEPT
+
+# allow ssh
+-A INPUT  -p tcp --dport 22 -j ACCEPT
+-A OUTPUT -p tcp --sport 22 -j ACCEPT
+
+# allow crl fetch from winnetou
+-A INPUT  -i eth0 -p tcp --sport 80 -s 192.168.0.150 -j ACCEPT
+-A OUTPUT -o eth0 -p tcp --dport 80 -d 192.168.0.150 -j ACCEPT
+
+COMMIT
diff --git a/testing/tests/tnc/tnccs-20-nea-pt-tls/hosts/carol/etc/pts/options b/testing/tests/tnc/tnccs-20-nea-pt-tls/hosts/carol/etc/pts/options
new file mode 100644
index 0000000..52a3673
--- /dev/null
+++ b/testing/tests/tnc/tnccs-20-nea-pt-tls/hosts/carol/etc/pts/options
@@ -0,0 +1,6 @@
+--connect aaa.strongswan.org
+--client carol
+--secret "Ar3etTnp"
+--cert /etc/swanctl/x509ca/strongswanCert.pem
+--quiet
+--debug 2
diff --git a/testing/tests/tnc/tnccs-20-nea-pt-tls/hosts/carol/etc/strongswan.conf b/testing/tests/tnc/tnccs-20-nea-pt-tls/hosts/carol/etc/strongswan.conf
new file mode 100644
index 0000000..5aad089
--- /dev/null
+++ b/testing/tests/tnc/tnccs-20-nea-pt-tls/hosts/carol/etc/strongswan.conf
@@ -0,0 +1,18 @@
+# /etc/strongswan.conf - strongSwan configuration file
+
+libtls {
+  suites = TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
+}
+
+libimcv {
+  swid_gen {
+    tag_creator {
+      name = Debian Project
+      regid = debian.org
+    }
+  }
+}
+
+pt-tls-client {
+  load = revocation constraints pem openssl curl nonce tnc-tnccs tnc-imc tnccs-20
+}
diff --git a/testing/tests/tnc/tnccs-20-nea-pt-tls/hosts/carol/etc/swanctl/swanctl.conf b/testing/tests/tnc/tnccs-20-nea-pt-tls/hosts/carol/etc/swanctl/swanctl.conf
new file mode 100644
index 0000000..28da4d4
--- /dev/null
+++ b/testing/tests/tnc/tnccs-20-nea-pt-tls/hosts/carol/etc/swanctl/swanctl.conf
@@ -0,0 +1 @@
+# the PT-TLS client reads its configuration and secrets via the command line
diff --git a/testing/tests/tnc/tnccs-20-nea-pt-tls/hosts/carol/etc/tnc_config b/testing/tests/tnc/tnccs-20-nea-pt-tls/hosts/carol/etc/tnc_config
new file mode 100644
index 0000000..3975056
--- /dev/null
+++ b/testing/tests/tnc/tnccs-20-nea-pt-tls/hosts/carol/etc/tnc_config
@@ -0,0 +1,4 @@
+#IMC configuration file for strongSwan client 
+
+IMC "OS" 	/usr/local/lib/ipsec/imcvs/imc-os.so
+IMC "SWIMA"	/usr/local/lib/ipsec/imcvs/imc-swima.so
diff --git a/testing/tests/tnc/tnccs-20-nea-pt-tls/hosts/dave/etc/ipsec.sql b/testing/tests/tnc/tnccs-20-nea-pt-tls/hosts/dave/etc/ipsec.sql
new file mode 100644
index 0000000..805c8bf
--- /dev/null
+++ b/testing/tests/tnc/tnccs-20-nea-pt-tls/hosts/dave/etc/ipsec.sql
@@ -0,0 +1,4 @@
+/* strongSwan SQLite database */
+
+/* configuration is read from the command line */
+/* credentials are read from the command line */
diff --git a/testing/tests/tnc/tnccs-20-nea-pt-tls/hosts/dave/etc/iptables.rules b/testing/tests/tnc/tnccs-20-nea-pt-tls/hosts/dave/etc/iptables.rules
new file mode 100644
index 0000000..d01d0a3
--- /dev/null
+++ b/testing/tests/tnc/tnccs-20-nea-pt-tls/hosts/dave/etc/iptables.rules
@@ -0,0 +1,20 @@
+*filter
+
+# default policy is DROP
+-P INPUT DROP
+-P OUTPUT DROP
+-P FORWARD DROP
+
+# allow PT-TLS 
+-A INPUT  -i eth0 -s 10.1.0.10 -p tcp --sport 271 -j ACCEPT
+-A OUTPUT -o eth0 -d 10.1.0.10 -p tcp --dport 271 -j ACCEPT
+
+# allow ssh
+-A INPUT  -p tcp --dport 22 -j ACCEPT
+-A OUTPUT -p tcp --sport 22 -j ACCEPT
+
+# allow crl fetch from winnetou
+-A INPUT  -i eth0 -p tcp --sport 80 -s 192.168.0.150 -j ACCEPT
+-A OUTPUT -o eth0 -p tcp --dport 80 -d 192.168.0.150 -j ACCEPT
+
+COMMIT
diff --git a/testing/tests/tnc/tnccs-20-nea-pt-tls/hosts/dave/etc/pts/options b/testing/tests/tnc/tnccs-20-nea-pt-tls/hosts/dave/etc/pts/options
new file mode 100644
index 0000000..0895314
--- /dev/null
+++ b/testing/tests/tnc/tnccs-20-nea-pt-tls/hosts/dave/etc/pts/options
@@ -0,0 +1,7 @@
+--connect aaa.strongswan.org
+--client dave at strongswan.org
+--key  /etc/swanctl/rsa/daveKey.pem
+--cert /etc/swanctl/x509/daveCert.pem
+--cert /etc/swanctl/x509ca/strongswanCert.pem
+--quiet
+--debug 2
diff --git a/testing/tests/tnc/tnccs-20-nea-pt-tls/hosts/dave/etc/strongswan.conf b/testing/tests/tnc/tnccs-20-nea-pt-tls/hosts/dave/etc/strongswan.conf
new file mode 100644
index 0000000..cf08b96
--- /dev/null
+++ b/testing/tests/tnc/tnccs-20-nea-pt-tls/hosts/dave/etc/strongswan.conf
@@ -0,0 +1,27 @@
+# /etc/strongswan.conf - strongSwan configuration file
+
+libimcv {
+  swid_gen {
+    tag_creator {
+      name = Debian Project
+      regid = debian.org
+    }
+  }
+  plugins {
+    imc-os {
+      push_info = no
+    }
+    imc-swima {
+      swid_directory = /usr/share
+      swid_pretty = yes
+    }
+  }
+}
+
+libtls {
+  suites = TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
+}
+
+pt-tls-client {
+  load = revocation constraints pem openssl curl nonce tnc-tnccs tnc-imc tnccs-20
+}
diff --git a/testing/tests/tnc/tnccs-20-nea-pt-tls/hosts/dave/etc/swanctl/swanctl.conf b/testing/tests/tnc/tnccs-20-nea-pt-tls/hosts/dave/etc/swanctl/swanctl.conf
new file mode 100644
index 0000000..28da4d4
--- /dev/null
+++ b/testing/tests/tnc/tnccs-20-nea-pt-tls/hosts/dave/etc/swanctl/swanctl.conf
@@ -0,0 +1 @@
+# the PT-TLS client reads its configuration and secrets via the command line
diff --git a/testing/tests/tnc/tnccs-20-nea-pt-tls/hosts/dave/etc/tnc_config b/testing/tests/tnc/tnccs-20-nea-pt-tls/hosts/dave/etc/tnc_config
new file mode 100644
index 0000000..3975056
--- /dev/null
+++ b/testing/tests/tnc/tnccs-20-nea-pt-tls/hosts/dave/etc/tnc_config
@@ -0,0 +1,4 @@
+#IMC configuration file for strongSwan client 
+
+IMC "OS" 	/usr/local/lib/ipsec/imcvs/imc-os.so
+IMC "SWIMA"	/usr/local/lib/ipsec/imcvs/imc-swima.so
diff --git a/testing/tests/tkm/xfrmproxy-expire/hosts/moon/etc/strongswan.conf b/testing/tests/tnc/tnccs-20-nea-pt-tls/hosts/moon/etc/strongswan.conf
similarity index 50%
copy from testing/tests/tkm/xfrmproxy-expire/hosts/moon/etc/strongswan.conf
copy to testing/tests/tnc/tnccs-20-nea-pt-tls/hosts/moon/etc/strongswan.conf
index cc9d6e0..d99a4b7 100644
--- a/testing/tests/tkm/xfrmproxy-expire/hosts/moon/etc/strongswan.conf
+++ b/testing/tests/tnc/tnccs-20-nea-pt-tls/hosts/moon/etc/strongswan.conf
@@ -1,8 +1,3 @@
 # /etc/strongswan.conf - strongSwan configuration file
 
-charon-tkm {
-  dh_mapping {
-    15 = 1
-    16 = 2
-  }
-}
+# this file is not used in this scenario 
diff --git a/testing/tests/tnc/tnccs-20-nea-pt-tls/hosts/moon/etc/swanctl/swanctl.conf b/testing/tests/tnc/tnccs-20-nea-pt-tls/hosts/moon/etc/swanctl/swanctl.conf
new file mode 100644
index 0000000..27f96a6
--- /dev/null
+++ b/testing/tests/tnc/tnccs-20-nea-pt-tls/hosts/moon/etc/swanctl/swanctl.conf
@@ -0,0 +1 @@
+# this file is not used in this scenario 
diff --git a/testing/tests/tnc/tnccs-20-nea-pt-tls/posttest.dat b/testing/tests/tnc/tnccs-20-nea-pt-tls/posttest.dat
new file mode 100644
index 0000000..09c8a6c
--- /dev/null
+++ b/testing/tests/tnc/tnccs-20-nea-pt-tls/posttest.dat
@@ -0,0 +1,10 @@
+carol::ip route del 10.1.0.0/16 via 192.168.0.1
+dave::ip route del 10.1.0.0/16 via 192.168.0.1
+winnetou::ip route del 10.1.0.0/16 via 192.168.0.1
+alice::service charon stop
+alice::service apache2 stop
+alice::rm /etc/swanctl/rsa/aaaKey.pem
+alice::rm /etc/swanctl/x509/aaaCert.pem
+alice::iptables-restore < /etc/iptables.flush
+carol::iptables-restore < /etc/iptables.flush
+dave::iptables-restore < /etc/iptables.flush
diff --git a/testing/tests/tnc/tnccs-20-pdp-pt-tls/pretest.dat b/testing/tests/tnc/tnccs-20-nea-pt-tls/pretest.dat
similarity index 89%
copy from testing/tests/tnc/tnccs-20-pdp-pt-tls/pretest.dat
copy to testing/tests/tnc/tnccs-20-nea-pt-tls/pretest.dat
index 17951e8..d8ac3ab 100644
--- a/testing/tests/tnc/tnccs-20-pdp-pt-tls/pretest.dat
+++ b/testing/tests/tnc/tnccs-20-nea-pt-tls/pretest.dat
@@ -19,7 +19,7 @@ alice::swanctl --load-creds
 winnetou::ip route add 10.1.0.0/16 via 192.168.0.1
 dave::ip route add 10.1.0.0/16 via 192.168.0.1
 dave::cat /etc/pts/options
-dave::ipsec pt-tls-client --optionsfrom /etc/pts/options
+dave::/usr/local/bin/pt-tls-client --optionsfrom /etc/pts/options
 carol::ip route add 10.1.0.0/16 via 192.168.0.1
 carol::cat /etc/pts/options
-carol::ipsec pt-tls-client --optionsfrom /etc/pts/options
+carol::/usr/local/bin/pt-tls-client --optionsfrom /etc/pts/options
diff --git a/testing/tests/tnc/tnccs-20-nea-pt-tls/test.conf b/testing/tests/tnc/tnccs-20-nea-pt-tls/test.conf
new file mode 100644
index 0000000..08ea543
--- /dev/null
+++ b/testing/tests/tnc/tnccs-20-nea-pt-tls/test.conf
@@ -0,0 +1,29 @@
+#!/bin/bash
+#
+# This configuration file provides information on the
+# guest instances used for this test
+
+# All guest instances that are required for this test
+#
+VIRTHOSTS="alice moon carol winnetou dave"
+
+# Corresponding block diagram
+#
+DIAGRAM="a-m-c-w-d.png"
+
+# Guest instances on which tcpdump is to be started
+#
+TCPDUMPHOSTS="moon"
+
+# Guest instances on which IPsec is started
+# Used for IPsec logging purposes
+#
+IPSECHOSTS="carol moon dave alice"
+
+# Guest instances on which databases are used
+#
+DBHOSTS="alice"
+
+# charon controlled by swanctl
+#
+SWANCTL=1
diff --git a/testing/tests/tnc/tnccs-20-pdp-pt-tls/evaltest.dat b/testing/tests/tnc/tnccs-20-pdp-pt-tls/evaltest.dat
index c3409fd..fc232bf 100644
--- a/testing/tests/tnc/tnccs-20-pdp-pt-tls/evaltest.dat
+++ b/testing/tests/tnc/tnccs-20-pdp-pt-tls/evaltest.dat
@@ -18,6 +18,6 @@ alice::cat /var/log/daemon.log::user AR identity.*carol.*authenticated by passwo
 alice::cat /var/log/daemon.log::received SWID tag ID inventory with ... items for request 9 at eid 1 of epoch::YES
 alice::cat /var/log/daemon.log::1 SWID tag target::YES
 alice::cat /var/log/daemon.log::received SWID tag inventory with 1 item for request 9 at eid 1 of epoch::YES
-alice::cat /var/log/daemon.log::regid.2004-03.org.strongswan_strongSwan-::YES
+alice::cat /var/log/daemon.log::strongswan.org__strongSwan-::YES
 alice::cat /var/log/daemon.log::successful system command: ssh root at moon.*logger -t charon -p auth.alert.*host with IP address 192.168.0.100 is allowed::YES
 moon::cat /var/log/auth.log::host with IP address 192.168.0.100 is allowed::YES
diff --git a/testing/tests/tnc/tnccs-20-pdp-pt-tls/pretest.dat b/testing/tests/tnc/tnccs-20-pdp-pt-tls/pretest.dat
index 17951e8..d8ac3ab 100644
--- a/testing/tests/tnc/tnccs-20-pdp-pt-tls/pretest.dat
+++ b/testing/tests/tnc/tnccs-20-pdp-pt-tls/pretest.dat
@@ -19,7 +19,7 @@ alice::swanctl --load-creds
 winnetou::ip route add 10.1.0.0/16 via 192.168.0.1
 dave::ip route add 10.1.0.0/16 via 192.168.0.1
 dave::cat /etc/pts/options
-dave::ipsec pt-tls-client --optionsfrom /etc/pts/options
+dave::/usr/local/bin/pt-tls-client --optionsfrom /etc/pts/options
 carol::ip route add 10.1.0.0/16 via 192.168.0.1
 carol::cat /etc/pts/options
-carol::ipsec pt-tls-client --optionsfrom /etc/pts/options
+carol::/usr/local/bin/pt-tls-client --optionsfrom /etc/pts/options

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-swan/strongswan.git



More information about the Pkg-swan-devel mailing list