[Pkg-swan-devel] [strongswan] 01/01: Imported Upstream version 5.3.0

Yves-Alexis Perez corsac at moszumanska.debian.org
Thu Apr 16 06:09:23 UTC 2015


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

corsac pushed a commit to branch upstream
in repository strongswan.

commit 83b8aebb19fe6e49e13a05d4e8f5ab9a06177642
Author: Yves-Alexis Perez <corsac at debian.org>
Date:   Sat Apr 11 22:03:59 2015 +0200

    Imported Upstream version 5.3.0
---
 Android.common.mk                                  |    2 +-
 Doxyfile.in                                        |    2 +-
 Makefile.am                                        |    2 +-
 Makefile.in                                        |    7 +-
 NEWS                                               |   83 +
 conf/Makefile.am                                   |    3 +
 conf/Makefile.in                                   |    8 +
 conf/options/charon.conf                           |   13 +
 conf/options/charon.opt                            |   32 +
 conf/plugins/bliss.conf                            |   11 +
 conf/plugins/bliss.opt                             |    2 +
 conf/plugins/forecast.conf                         |   17 +
 conf/plugins/forecast.opt                          |   29 +
 conf/plugins/imc-attestation.opt                   |   18 +
 conf/plugins/imv-attestation.opt                   |   18 -
 conf/plugins/kernel-netlink.conf                   |   21 +
 conf/plugins/kernel-netlink.opt                    |   32 +
 conf/plugins/kernel-pfkey.conf                     |   11 +
 conf/plugins/kernel-pfkey.opt                      |    7 +
 conf/plugins/tnccs-20.conf                         |   13 +
 conf/plugins/tnccs-20.opt                          |    9 +
 conf/strongswan.conf.5.main                        |  125 +-
 configure                                          |  584 +++++-
 configure.ac                                       |   77 +-
 init/Makefile.in                                   |    5 +
 init/systemd-swanctl/Makefile.in                   |    5 +
 init/systemd/Makefile.in                           |    5 +
 man/Makefile.in                                    |    5 +
 man/ipsec.conf.5.in                                |  145 +-
 scripts/Makefile.in                                |    5 +
 scripts/dh_speed.c                                 |   10 +-
 src/Makefile.am                                    |    2 +-
 src/Makefile.in                                    |   13 +-
 src/_copyright/Makefile.in                         |    5 +
 src/_updown/Makefile.am                            |    1 -
 src/_updown/Makefile.in                            |   76 +-
 src/_updown/_updown.8                              |   16 -
 src/_updown/_updown.in                             |  201 +-
 src/_updown_espmark/Makefile.am                    |    2 -
 src/_updown_espmark/Makefile.in                    |  652 ------
 src/_updown_espmark/_updown_espmark                |  438 ----
 src/_updown_espmark/_updown_espmark.8              |   15 -
 src/aikgen/Makefile.in                             |    5 +
 src/charon-cmd/Makefile.in                         |    5 +
 src/charon-nm/Makefile.in                          |    5 +
 src/charon-nm/nm/nm_backend.c                      |    6 +-
 src/charon-nm/nm/nm_handler.c                      |    5 +-
 src/charon-svc/Makefile.in                         |    5 +
 src/charon-systemd/Makefile.in                     |    5 +
 src/charon-systemd/charon-systemd.c                |   28 +-
 src/charon-tkm/Makefile.in                         |    5 +
 src/charon-tkm/src/charon-tkm.c                    |    4 +
 src/charon-tkm/src/ees/ees_callbacks.c             |   22 +-
 src/charon-tkm/src/tkm/tkm.c                       |    4 +-
 src/charon-tkm/src/tkm/tkm.h                       |    8 +-
 src/charon-tkm/src/tkm/tkm_diffie_hellman.c        |   15 +-
 src/charon-tkm/src/tkm/tkm_encoder.c~              |  106 +
 src/charon-tkm/src/tkm/tkm_id_manager.c            |    2 +-
 src/charon-tkm/src/tkm/tkm_kernel_ipsec.c          |   39 +-
 src/charon-tkm/src/tkm/tkm_kernel_sad.c            |   66 +-
 src/charon-tkm/src/tkm/tkm_kernel_sad.h            |   19 +-
 src/charon-tkm/src/tkm/tkm_keymat.c                |   29 +
 src/charon-tkm/src/tkm/tkm_listener.c              |   20 +-
 src/charon-tkm/tests/diffie_hellman_tests.c        |    2 +-
 src/charon-tkm/tests/kernel_sad_tests.c            |   40 +-
 src/charon-tkm/tests/keymat_tests.c                |    4 +-
 src/charon-tkm/tests/tests.c                       |    4 +-
 src/charon/Makefile.in                             |    5 +
 src/checksum/Makefile.in                           |    5 +
 src/conftest/Makefile.in                           |    5 +
 src/conftest/actions.c                             |   16 +-
 src/dumm/Makefile.in                               |    5 +
 src/dumm/ext/dumm.c                                |    4 +-
 src/include/Makefile.in                            |    5 +
 src/ipsec/Makefile.in                              |    5 +
 src/ipsec/_ipsec.8                                 |   17 +-
 src/ipsec/_ipsec.8.in                              |   15 +-
 src/libcharon/Android.mk                           |    8 +-
 src/libcharon/Makefile.am                          |   54 +-
 src/libcharon/Makefile.in                          |  406 ++--
 src/libcharon/attributes/attribute_handler.h       |   76 +
 src/libcharon/attributes/attribute_manager.c       |  347 ++++
 src/libcharon/attributes/attribute_manager.h       |  154 ++
 src/libcharon/attributes/attribute_provider.h      |   71 +
 .../attributes/attributes.c                        |    0
 .../attributes/attributes.h                        |    0
 src/libcharon/attributes/mem_pool.c                |  735 +++++++
 src/libcharon/attributes/mem_pool.h                |  154 ++
 src/libcharon/bus/bus.c                            |   28 +
 src/libcharon/bus/bus.h                            |    9 +
 src/libcharon/bus/listeners/listener.h             |   11 +
 src/libcharon/config/ike_cfg.c                     |   17 +-
 src/libcharon/config/proposal.c                    |    2 +
 src/libcharon/control/controller.c                 |   44 +-
 src/libcharon/control/controller.h                 |    4 +-
 src/libcharon/daemon.c                             |    7 +-
 src/libcharon/daemon.h                             |   15 +
 src/libcharon/encoding/message.c                   |   16 +-
 src/libcharon/encoding/parser.c                    |   21 +-
 src/libcharon/encoding/parser.h                    |   12 +-
 src/libcharon/encoding/payloads/delete_payload.c   |   15 +
 src/libcharon/encoding/payloads/delete_payload.h   |   10 +
 .../encoding/payloads/encrypted_payload.c          |    1 +
 src/libcharon/encoding/payloads/id_payload.c       |    7 +-
 src/libcharon/encoding/payloads/ke_payload.c       |   10 +-
 src/libcharon/encoding/payloads/ke_payload.h       |    2 +-
 src/libcharon/encoding/payloads/notify_payload.c   |   22 +-
 src/libcharon/encoding/payloads/notify_payload.h   |    2 +
 src/libcharon/encoding/payloads/payload.c          |   62 +-
 src/libcharon/encoding/payloads/payload.h          |    3 +-
 .../encoding/payloads/proposal_substructure.c      |  276 ++-
 src/libcharon/kernel/kernel_handler.c              |   25 +-
 src/libcharon/plugins/addrblock/Makefile.in        |    5 +
 src/libcharon/plugins/android_dns/Makefile.in      |    5 +
 .../plugins/android_dns/android_dns_handler.c      |    7 +-
 .../plugins/android_dns/android_dns_plugin.c       |    9 +-
 src/libcharon/plugins/android_log/Makefile.in      |    5 +
 src/libcharon/plugins/attr/Makefile.am             |   19 +
 src/libcharon/plugins/attr/Makefile.in             |  777 +++++++
 src/libcharon/plugins/attr/attr_plugin.c           |  109 +
 src/libcharon/plugins/attr/attr_plugin.h           |   42 +
 src/libcharon/plugins/attr/attr_provider.c         |  329 +++
 .../plugins/attr/attr_provider.h                   |    0
 src/libcharon/plugins/attr_sql/Makefile.am         |   19 +
 src/libcharon/plugins/attr_sql/Makefile.in         |  780 +++++++
 src/libcharon/plugins/attr_sql/attr_sql_plugin.c   |  129 ++
 src/libcharon/plugins/attr_sql/attr_sql_plugin.h   |   42 +
 src/libcharon/plugins/attr_sql/attr_sql_provider.c |  478 +++++
 src/libcharon/plugins/attr_sql/attr_sql_provider.h |   50 +
 src/libcharon/plugins/certexpire/Makefile.in       |    5 +
 src/libcharon/plugins/connmark/Makefile.am         |   20 +
 src/libcharon/plugins/connmark/Makefile.in         |  782 +++++++
 src/libcharon/plugins/connmark/connmark_listener.c |  538 +++++
 src/libcharon/plugins/connmark/connmark_listener.h |   49 +
 src/libcharon/plugins/connmark/connmark_plugin.c   |  105 +
 src/libcharon/plugins/connmark/connmark_plugin.h   |   42 +
 src/libcharon/plugins/coupling/Makefile.in         |    5 +
 src/libcharon/plugins/dhcp/Makefile.in             |    5 +
 src/libcharon/plugins/dhcp/dhcp_plugin.c           |    9 +-
 src/libcharon/plugins/dhcp/dhcp_provider.c         |   12 +-
 src/libcharon/plugins/dnscert/Makefile.in          |    5 +
 src/libcharon/plugins/duplicheck/Makefile.in       |    5 +
 src/libcharon/plugins/eap_aka/Makefile.in          |    5 +
 src/libcharon/plugins/eap_aka_3gpp2/Makefile.in    |    5 +
 src/libcharon/plugins/eap_dynamic/Makefile.in      |    5 +
 src/libcharon/plugins/eap_gtc/Makefile.in          |    5 +
 src/libcharon/plugins/eap_identity/Makefile.in     |    5 +
 src/libcharon/plugins/eap_md5/Makefile.in          |    5 +
 src/libcharon/plugins/eap_mschapv2/Makefile.in     |    5 +
 src/libcharon/plugins/eap_peap/Makefile.in         |    5 +
 src/libcharon/plugins/eap_radius/Makefile.in       |    5 +
 .../plugins/eap_radius/eap_radius_accounting.c     |    2 +-
 .../plugins/eap_radius/eap_radius_plugin.c         |   23 +-
 .../plugins/eap_radius/eap_radius_provider.c       |   24 +-
 src/libcharon/plugins/eap_sim/Makefile.in          |    5 +
 src/libcharon/plugins/eap_sim_file/Makefile.in     |    5 +
 src/libcharon/plugins/eap_sim_pcsc/Makefile.in     |    5 +
 .../plugins/eap_simaka_pseudonym/Makefile.in       |    5 +
 .../plugins/eap_simaka_reauth/Makefile.in          |    5 +
 src/libcharon/plugins/eap_simaka_sql/Makefile.in   |    5 +
 src/libcharon/plugins/eap_tls/Makefile.in          |    5 +
 src/libcharon/plugins/eap_tls/eap_tls.c            |    7 +
 src/libcharon/plugins/eap_tnc/Makefile.in          |    5 +
 src/libcharon/plugins/eap_tnc/eap_tnc.c            |   27 +-
 src/libcharon/plugins/eap_ttls/Makefile.in         |    5 +
 src/libcharon/plugins/eap_ttls/eap_ttls.c          |    7 +
 src/libcharon/plugins/error_notify/Makefile.in     |    5 +
 src/libcharon/plugins/ext_auth/Makefile.in         |    5 +
 src/libcharon/plugins/farp/Makefile.in             |    5 +
 src/libcharon/plugins/forecast/Makefile.am         |   21 +
 src/libcharon/plugins/forecast/Makefile.in         |  784 +++++++
 .../plugins/forecast/forecast_forwarder.c          |  496 +++++
 .../plugins/forecast/forecast_forwarder.h          |   47 +
 src/libcharon/plugins/forecast/forecast_listener.c |  680 ++++++
 src/libcharon/plugins/forecast/forecast_listener.h |   68 +
 src/libcharon/plugins/forecast/forecast_plugin.c   |  118 ++
 src/libcharon/plugins/forecast/forecast_plugin.h   |   42 +
 src/libcharon/plugins/ha/Makefile.in               |    5 +
 src/libcharon/plugins/ha/ha_attribute.c            |    4 +-
 src/libcharon/plugins/ha/ha_cache.c                |   29 +-
 src/libcharon/plugins/ha/ha_child.c                |    4 +-
 src/libcharon/plugins/ha/ha_dispatcher.c           |   15 +-
 src/libcharon/plugins/ha/ha_ike.c                  |   10 +-
 src/libcharon/plugins/ha/ha_plugin.c               |   10 +-
 src/libcharon/plugins/ipseckey/Makefile.in         |    5 +
 src/libcharon/plugins/kernel_iph/Makefile.in       |    5 +
 src/libcharon/plugins/kernel_libipsec/Makefile.in  |    5 +
 .../kernel_libipsec/kernel_libipsec_ipsec.c        |   20 +-
 .../kernel_libipsec/kernel_libipsec_router.c       |  110 +-
 src/libcharon/plugins/kernel_wfp/Makefile.in       |    5 +
 .../plugins/kernel_wfp/kernel_wfp_compat.c         |   36 +
 .../plugins/kernel_wfp/kernel_wfp_compat.h         |   10 +
 .../plugins/kernel_wfp/kernel_wfp_ipsec.c          |  258 ++-
 src/libcharon/plugins/led/Makefile.in              |    5 +
 src/libcharon/plugins/load_tester/Makefile.in      |    5 +
 .../plugins/load_tester/load_tester_config.c       |   24 +-
 .../load_tester/load_tester_diffie_hellman.c       |   51 +-
 .../plugins/load_tester/load_tester_ipsec.c        |    8 +-
 src/libcharon/plugins/lookip/Makefile.in           |    5 +
 src/libcharon/plugins/maemo/Makefile.in            |    5 +
 src/libcharon/plugins/medcli/Makefile.in           |    5 +
 src/libcharon/plugins/medsrv/Makefile.in           |    5 +
 src/libcharon/plugins/osx_attr/Makefile.in         |    5 +
 src/libcharon/plugins/osx_attr/osx_attr_handler.c  |    6 +-
 src/libcharon/plugins/osx_attr/osx_attr_plugin.c   |    9 +-
 src/libcharon/plugins/radattr/Makefile.in          |    5 +
 src/libcharon/plugins/resolve/Makefile.am          |   20 +
 src/libcharon/plugins/resolve/Makefile.in          |  781 +++++++
 src/libcharon/plugins/resolve/resolve_handler.c    |  380 ++++
 .../plugins/resolve/resolve_handler.h              |    0
 src/libcharon/plugins/resolve/resolve_plugin.c     |  101 +
 .../plugins/resolve/resolve_plugin.h               |    0
 src/libcharon/plugins/smp/Makefile.in              |    5 +
 src/libcharon/plugins/socket_default/Makefile.in   |    5 +
 .../plugins/socket_default/socket_default_socket.c |   76 +-
 src/libcharon/plugins/socket_dynamic/Makefile.in   |    5 +
 src/libcharon/plugins/socket_win/Makefile.in       |    5 +
 src/libcharon/plugins/sql/Makefile.in              |    5 +
 src/libcharon/plugins/stroke/Makefile.in           |    5 +
 src/libcharon/plugins/stroke/stroke_attribute.c    |   27 +-
 src/libcharon/plugins/stroke/stroke_ca.c           |   81 +-
 src/libcharon/plugins/stroke/stroke_config.c       |   74 +-
 src/libcharon/plugins/stroke/stroke_control.c      |    8 +-
 src/libcharon/plugins/stroke/stroke_cred.c         |  315 +--
 src/libcharon/plugins/stroke/stroke_cred.h         |    7 +-
 src/libcharon/plugins/stroke/stroke_handler.c      |    3 +-
 src/libcharon/plugins/stroke/stroke_list.c         |   16 +-
 src/libcharon/plugins/stroke/stroke_plugin.c       |    1 +
 src/libcharon/plugins/stroke/stroke_socket.c       |   13 +-
 src/libcharon/plugins/systime_fix/Makefile.in      |    5 +
 src/libcharon/plugins/tnc_ifmap/Makefile.in        |    5 +
 src/libcharon/plugins/tnc_pdp/Makefile.in          |    5 +
 src/libcharon/plugins/tnc_pdp/tnc_pdp.c            |   25 +-
 src/libcharon/plugins/uci/Makefile.in              |    5 +
 src/libcharon/plugins/unit_tester/Makefile.am      |   26 -
 src/libcharon/plugins/unit_tester/Makefile.in      |  819 --------
 src/libcharon/plugins/unit_tester/tests.h          |   30 -
 .../plugins/unit_tester/tests/test_agent.c         |   67 -
 .../plugins/unit_tester/tests/test_auth_info.c     |  140 --
 .../plugins/unit_tester/tests/test_cert.c          |  108 -
 .../plugins/unit_tester/tests/test_curl.c          |   44 -
 .../plugins/unit_tester/tests/test_med_db.c        |   54 -
 .../plugins/unit_tester/tests/test_mysql.c         |   89 -
 .../plugins/unit_tester/tests/test_pool.c          |  100 -
 .../plugins/unit_tester/tests/test_sqlite.c        |   93 -
 src/libcharon/plugins/unit_tester/unit_tester.c    |  152 --
 src/libcharon/plugins/unit_tester/unit_tester.h    |   44 -
 src/libcharon/plugins/unity/Makefile.in            |    5 +
 src/libcharon/plugins/unity/unity_handler.c        |   29 +-
 src/libcharon/plugins/unity/unity_handler.h        |    5 +-
 src/libcharon/plugins/unity/unity_narrow.c         |   90 +-
 src/libcharon/plugins/unity/unity_plugin.c         |   17 +-
 src/libcharon/plugins/unity/unity_provider.c       |    6 +-
 src/libcharon/plugins/updown/Makefile.in           |    5 +
 src/libcharon/plugins/updown/updown_handler.c      |   57 +-
 src/libcharon/plugins/updown/updown_listener.c     |    1 +
 src/libcharon/plugins/updown/updown_plugin.c       |    9 +-
 src/libcharon/plugins/vici/Makefile.am             |    4 +
 src/libcharon/plugins/vici/Makefile.in             |   10 +-
 src/libcharon/plugins/vici/README.md               |   97 +-
 src/libcharon/plugins/vici/libvici.c               |    8 +-
 src/libcharon/plugins/vici/python/LICENSE          |   19 +
 src/libcharon/plugins/vici/python/MANIFEST.in      |    1 +
 src/libcharon/plugins/vici/python/Makefile.am      |   33 +
 src/libcharon/plugins/vici/python/Makefile.in      |  686 ++++++
 src/libcharon/plugins/vici/python/setup.py.in      |   34 +
 src/libcharon/plugins/vici/python/vici/__init__.py |    1 +
 src/libcharon/plugins/vici/python/vici/compat.py   |   14 +
 .../plugins/vici/python/vici/exception.py          |   10 +
 src/libcharon/plugins/vici/python/vici/protocol.py |  196 ++
 src/libcharon/plugins/vici/python/vici/session.py  |  327 +++
 .../plugins/vici/python/vici/test/__init__.py      |    0
 .../plugins/vici/python/vici/test/test_protocol.py |  144 ++
 src/libcharon/plugins/vici/ruby/Makefile.am        |    6 +-
 src/libcharon/plugins/vici/ruby/Makefile.in        |   11 +-
 src/libcharon/plugins/vici/ruby/lib/vici.rb        |   30 +-
 src/libcharon/plugins/vici/ruby/vici.gemspec.in    |    2 +-
 src/libcharon/plugins/vici/vici_attribute.c        |   67 +-
 src/libcharon/plugins/vici/vici_builder.c          |   79 +-
 src/libcharon/plugins/vici/vici_builder.h          |    8 +
 src/libcharon/plugins/vici/vici_config.c           |   51 +-
 src/libcharon/plugins/vici/vici_control.c          |    4 +-
 src/libcharon/plugins/vici/vici_plugin.c           |    9 +-
 src/libcharon/plugins/vici/vici_query.c            |   17 +-
 src/libcharon/plugins/whitelist/Makefile.in        |    5 +
 src/libcharon/plugins/xauth_eap/Makefile.in        |    5 +
 src/libcharon/plugins/xauth_generic/Makefile.in    |    5 +
 src/libcharon/plugins/xauth_noauth/Makefile.in     |    5 +
 src/libcharon/plugins/xauth_pam/Makefile.in        |    5 +
 src/libcharon/processing/jobs/adopt_children_job.c |   58 +-
 .../processing/jobs/delete_child_sa_job.c          |   26 +-
 .../processing/jobs/delete_child_sa_job.h          |    9 +-
 src/libcharon/processing/jobs/dpd_timeout_job.c    |    6 +
 src/libcharon/processing/jobs/inactivity_job.c     |   16 +-
 src/libcharon/processing/jobs/inactivity_job.h     |    4 +-
 src/libcharon/processing/jobs/initiate_tasks_job.c |   96 +
 src/libcharon/processing/jobs/initiate_tasks_job.h |   49 +
 src/libcharon/processing/jobs/migrate_job.c        |   62 +-
 src/libcharon/processing/jobs/migrate_job.h        |    2 +-
 src/libcharon/processing/jobs/rekey_child_sa_job.c |   27 +-
 src/libcharon/processing/jobs/rekey_child_sa_job.h |   10 +-
 src/libcharon/processing/jobs/rekey_ike_sa_job.c   |    3 +-
 src/libcharon/processing/jobs/update_sa_job.c      |   33 +-
 src/libcharon/processing/jobs/update_sa_job.h      |    8 +-
 src/libcharon/sa/authenticator.c                   |    9 +-
 src/libcharon/sa/authenticator.h                   |   10 +
 src/libcharon/sa/child_sa.c                        |  147 +-
 src/libcharon/sa/child_sa.h                        |   25 +-
 src/libcharon/sa/child_sa_manager.c                |  333 +++
 src/libcharon/sa/child_sa_manager.h                |   89 +
 src/libcharon/sa/eap/eap_method.h                  |   12 +
 src/libcharon/sa/ike_sa.c                          |   82 +-
 src/libcharon/sa/ike_sa.h                          |   10 +-
 src/libcharon/sa/ike_sa_manager.c                  |   95 +-
 src/libcharon/sa/ike_sa_manager.h                  |   10 +-
 .../sa/ikev1/authenticators/psk_v1_authenticator.c |   10 +-
 .../ikev1/authenticators/pubkey_v1_authenticator.c |   11 +-
 src/libcharon/sa/ikev1/keymat_v1.c                 |    9 +-
 src/libcharon/sa/ikev1/phase1.c                    |   14 +-
 src/libcharon/sa/ikev1/task_manager_v1.c           |    5 +-
 src/libcharon/sa/ikev1/tasks/isakmp_delete.c       |   39 +
 src/libcharon/sa/ikev1/tasks/main_mode.c           |   39 +
 src/libcharon/sa/ikev1/tasks/mode_config.c         |  137 +-
 src/libcharon/sa/ikev1/tasks/quick_delete.c        |    6 +-
 src/libcharon/sa/ikev1/tasks/quick_mode.c          |   76 +-
 src/libcharon/sa/ikev1/tasks/quick_mode.h          |    8 +
 .../sa/ikev2/authenticators/eap_authenticator.c    |    7 +
 .../sa/ikev2/authenticators/pubkey_authenticator.c |  314 ++-
 src/libcharon/sa/ikev2/keymat_v2.c                 |   35 +-
 src/libcharon/sa/ikev2/keymat_v2.h                 |   18 +-
 src/libcharon/sa/ikev2/task_manager_v2.c           |  113 +-
 src/libcharon/sa/ikev2/tasks/child_create.c        |   84 +-
 src/libcharon/sa/ikev2/tasks/child_create.h        |    8 +
 src/libcharon/sa/ikev2/tasks/child_delete.c        |    4 +-
 src/libcharon/sa/ikev2/tasks/child_rekey.c         |   10 +-
 src/libcharon/sa/ikev2/tasks/ike_cert_pre.c        |    4 +-
 src/libcharon/sa/ikev2/tasks/ike_config.c          |   19 +-
 src/libcharon/sa/ikev2/tasks/ike_init.c            |  206 +-
 src/libcharon/sa/ikev2/tasks/ike_mobike.c          |   27 +-
 src/libcharon/sa/ikev2/tasks/ike_reauth.h          |    2 +
 src/libcharon/sa/ikev2/tasks/ike_reauth_complete.c |  102 +
 src/libcharon/sa/ikev2/tasks/ike_reauth_complete.h |   56 +
 src/libcharon/sa/ikev2/tasks/ike_rekey.c           |   36 +
 src/libcharon/sa/task.c                            |    1 +
 src/libcharon/sa/task.h                            |    6 +-
 src/libcharon/sa/trap_manager.c                    |   11 +-
 src/libcharon/tests/Makefile.am                    |   21 +
 src/libcharon/tests/Makefile.in                    |  874 ++++++++
 src/libcharon/tests/libcharon_tests.c              |   56 +
 src/libcharon/tests/libcharon_tests.h              |   16 +
 src/libcharon/tests/suites/test_mem_pool.c         |  230 +++
 src/libfast/Makefile.in                            |    5 +
 src/libhydra/Android.mk                            |    7 -
 src/libhydra/Makefile.am                           |   24 +-
 src/libhydra/Makefile.in                           |   73 +-
 src/libhydra/attributes/attribute_handler.h        |   72 -
 src/libhydra/attributes/attribute_manager.c        |  348 ----
 src/libhydra/attributes/attribute_manager.h        |  153 --
 src/libhydra/attributes/attribute_provider.h       |   71 -
 src/libhydra/attributes/mem_pool.c                 |  649 ------
 src/libhydra/attributes/mem_pool.h                 |  146 --
 src/libhydra/hydra.c                               |    4 -
 src/libhydra/hydra.h                               |    9 -
 src/libhydra/kernel/kernel_interface.c             |  276 ++-
 src/libhydra/kernel/kernel_interface.h             |   76 +-
 src/libhydra/kernel/kernel_ipsec.h                 |   28 +-
 src/libhydra/kernel/kernel_listener.h              |   13 +-
 src/libhydra/plugins/attr/Makefile.am              |   18 -
 src/libhydra/plugins/attr/Makefile.in              |  771 -------
 src/libhydra/plugins/attr/attr_plugin.c            |  109 -
 src/libhydra/plugins/attr/attr_plugin.h            |   42 -
 src/libhydra/plugins/attr/attr_provider.c          |  329 ---
 src/libhydra/plugins/attr_sql/Makefile.am          |   18 -
 src/libhydra/plugins/attr_sql/Makefile.in          |  774 -------
 src/libhydra/plugins/attr_sql/attr_sql_plugin.c    |  129 --
 src/libhydra/plugins/attr_sql/attr_sql_plugin.h    |   42 -
 src/libhydra/plugins/attr_sql/sql_attribute.c      |  475 -----
 src/libhydra/plugins/attr_sql/sql_attribute.h      |   50 -
 src/libhydra/plugins/kernel_netlink/Makefile.am    |   21 +
 src/libhydra/plugins/kernel_netlink/Makefile.in    |  267 ++-
 .../plugins/kernel_netlink/kernel_netlink_ipsec.c  |  299 ++-
 .../plugins/kernel_netlink/kernel_netlink_net.c    |   46 +-
 .../plugins/kernel_netlink/kernel_netlink_shared.c |  477 ++++-
 .../plugins/kernel_netlink/kernel_netlink_shared.h |    4 +-
 .../plugins/kernel_netlink/suites/test_socket.c    |  302 +++
 src/libhydra/plugins/kernel_netlink/tests.c        |   51 +
 src/libhydra/plugins/kernel_netlink/tests.h        |   16 +
 src/libhydra/plugins/kernel_pfkey/Makefile.in      |    5 +
 .../plugins/kernel_pfkey/kernel_pfkey_ipsec.c      |  112 +-
 src/libhydra/plugins/kernel_pfroute/Makefile.in    |    5 +
 .../plugins/kernel_pfroute/kernel_pfroute_net.c    |    9 +
 src/libhydra/plugins/resolve/Makefile.am           |   19 -
 src/libhydra/plugins/resolve/Makefile.in           |  775 -------
 src/libhydra/plugins/resolve/resolve_handler.c     |  377 ----
 src/libhydra/plugins/resolve/resolve_plugin.c      |  102 -
 src/libhydra/tests/Makefile.am                     |   18 +
 src/libhydra/tests/Makefile.in                     |  839 ++++++++
 src/libhydra/tests/hydra_tests.c                   |   53 +
 src/libhydra/tests/hydra_tests.h                   |   14 +
 src/libimcv/Makefile.am                            |    3 +-
 src/libimcv/Makefile.in                            |   11 +-
 src/libimcv/imv/data.sql                           |  155 ++
 src/libimcv/imv/imv_agent.c                        |   76 +-
 src/libimcv/imv/imv_database.c                     |  111 +-
 src/libimcv/imv/imv_policy_manager.c               |   76 +-
 src/libimcv/imv/imv_session.c                      |   33 +-
 src/libimcv/imv/imv_session.h                      |   14 +-
 src/libimcv/imv/imv_session_manager.c              |   40 +-
 src/libimcv/imv/imv_session_manager.h              |    7 +-
 src/libimcv/imv/tables-mysql.sql                   |    8 +
 src/libimcv/imv/tables.sql                         |    8 +
 src/libimcv/plugins/imc_attestation/Makefile.in    |    5 +
 .../imc_attestation/imc_attestation_process.c      |   12 +-
 src/libimcv/plugins/imc_os/Makefile.in             |    5 +
 src/libimcv/plugins/imc_scanner/Makefile.in        |    5 +
 src/libimcv/plugins/imc_swid/Makefile.in           |    5 +
 src/libimcv/plugins/imc_test/Makefile.in           |    5 +
 src/libimcv/plugins/imv_attestation/Makefile.in    |    5 +
 src/libimcv/plugins/imv_attestation/attest_db.c    |   18 +-
 .../plugins/imv_attestation/build-database.sh      |    2 +-
 .../imv_attestation/imv_attestation_build.c        |    6 +-
 .../imv_attestation/imv_attestation_process.c      |    8 +-
 src/libimcv/plugins/imv_os/Makefile.in             |    5 +
 src/libimcv/plugins/imv_scanner/Makefile.in        |    5 +
 src/libimcv/plugins/imv_swid/Makefile.in           |    5 +
 src/libimcv/plugins/imv_test/Makefile.in           |    5 +
 src/libimcv/pts/components/ita/ita_comp_tboot.c    |    9 +-
 src/libimcv/pts/pts.c                              |   18 +-
 src/libimcv/pts/pts.h                              |    6 +-
 src/libimcv/seg/seg_env.c                          |    3 +-
 src/libimcv/seg/seg_env.h                          |    2 +-
 src/libimcv/suites/test_imcv_seg.c                 |   12 +-
 src/libimcv/tcg/pts/tcg_pts_attr_file_meas.c       |    3 +-
 src/libipsec/Makefile.in                           |    5 +
 src/libipsec/ip_packet.c                           |    2 +-
 src/libipsec/ipsec_event_listener.h                |    6 +-
 src/libipsec/ipsec_event_relay.c                   |   34 +-
 src/libipsec/ipsec_event_relay.h                   |    6 +-
 src/libipsec/ipsec_sa.c                            |   11 +-
 src/libipsec/ipsec_sa.h                            |    6 +-
 src/libipsec/ipsec_sa_mgr.c                        |   14 +-
 src/libipsec/ipsec_sa_mgr.h                        |    9 +-
 src/libpttls/Makefile.in                           |    5 +
 src/libradius/Makefile.in                          |    5 +
 src/libradius/radius_socket.c                      |   87 +-
 src/libsimaka/Makefile.in                          |    5 +
 src/libstrongswan/Android.mk                       |    2 +
 src/libstrongswan/Makefile.am                      |   29 +-
 src/libstrongswan/Makefile.in                      |  190 +-
 src/libstrongswan/asn1/oid.c                       |  518 ++---
 src/libstrongswan/asn1/oid.h                       |  199 +-
 src/libstrongswan/asn1/oid.txt                     |   22 +
 src/libstrongswan/credentials/auth_cfg.c           |   60 +-
 src/libstrongswan/credentials/auth_cfg.h           |    4 +-
 src/libstrongswan/credentials/cred_encoding.h      |    4 +
 src/libstrongswan/credentials/credential_manager.c |    3 +
 src/libstrongswan/credentials/keys/public_key.c    |  168 +-
 src/libstrongswan/credentials/keys/public_key.h    |   41 +-
 src/libstrongswan/credentials/sets/cert_cache.c    |   17 +-
 src/libstrongswan/credentials/sets/mem_cred.c      |   19 +
 src/libstrongswan/credentials/sets/mem_cred.h      |   12 +
 src/libstrongswan/crypto/crypters/crypter.c        |    7 +
 src/libstrongswan/crypto/crypto_tester.c           |   27 +-
 src/libstrongswan/crypto/diffie_hellman.c          |   87 +-
 src/libstrongswan/crypto/diffie_hellman.h          |   30 +-
 .../crypto/hashers/hash_algorithm_set.c            |  113 +
 .../crypto/hashers/hash_algorithm_set.h            |   76 +
 src/libstrongswan/crypto/hashers/hasher.c          |  102 +-
 src/libstrongswan/crypto/hashers/hasher.h          |   40 +-
 src/libstrongswan/crypto/mgf1/mgf1.c               |  180 ++
 src/libstrongswan/crypto/mgf1/mgf1.h               |   77 +
 src/libstrongswan/crypto/mgf1/mgf1_bitspender.c    |  208 ++
 src/libstrongswan/crypto/mgf1/mgf1_bitspender.h    |   67 +
 src/libstrongswan/crypto/pkcs5.c                   |   32 +-
 src/libstrongswan/ipsec/ipsec_types.c              |   10 +-
 src/libstrongswan/ipsec/ipsec_types.h              |    4 +-
 src/libstrongswan/library.h                        |    3 +
 src/libstrongswan/networking/host.c                |   38 +-
 src/libstrongswan/networking/host.h                |   21 +-
 src/libstrongswan/networking/host_resolver.c       |   17 +-
 src/libstrongswan/networking/tun_device.c          |   25 +-
 src/libstrongswan/networking/tun_device.h          |    4 +-
 src/libstrongswan/plugins/acert/Makefile.in        |    5 +
 src/libstrongswan/plugins/aes/Makefile.in          |    5 +
 src/libstrongswan/plugins/af_alg/Makefile.in       |    5 +
 src/libstrongswan/plugins/af_alg/af_alg_prf.c      |    1 +
 src/libstrongswan/plugins/af_alg/af_alg_signer.c   |    1 +
 src/libstrongswan/plugins/agent/Makefile.in        |    5 +
 src/libstrongswan/plugins/bliss/Makefile.am        |   54 +
 src/libstrongswan/plugins/bliss/Makefile.in        |  862 ++++++++
 src/libstrongswan/plugins/bliss/bliss_bitpacker.c  |  207 ++
 src/libstrongswan/plugins/bliss/bliss_bitpacker.h  |   85 +
 src/libstrongswan/plugins/bliss/bliss_fft.c        |  199 ++
 src/libstrongswan/plugins/bliss/bliss_fft.h        |   71 +
 src/libstrongswan/plugins/bliss/bliss_fft_params.c |  215 ++
 src/libstrongswan/plugins/bliss/bliss_fft_params.h |   75 +
 src/libstrongswan/plugins/bliss/bliss_huffman.c    |  433 ++++
 .../plugins/bliss/bliss_huffman_code.c             |   42 +
 .../plugins/bliss/bliss_huffman_code.h             |   80 +
 .../plugins/bliss/bliss_huffman_code_1.c           |  160 ++
 .../plugins/bliss/bliss_huffman_code_3.c           |  261 +++
 .../plugins/bliss/bliss_huffman_code_4.c           |  435 ++++
 .../plugins/bliss/bliss_huffman_coder.c            |  138 ++
 .../plugins/bliss/bliss_huffman_coder.h            |   77 +
 src/libstrongswan/plugins/bliss/bliss_param_set.c  |  339 +++
 src/libstrongswan/plugins/bliss/bliss_param_set.h  |  201 ++
 src/libstrongswan/plugins/bliss/bliss_plugin.c     |  101 +
 src/libstrongswan/plugins/bliss/bliss_plugin.h     |   42 +
 .../plugins/bliss/bliss_private_key.c              | 1316 ++++++++++++
 .../plugins/bliss/bliss_private_key.h              |   62 +
 src/libstrongswan/plugins/bliss/bliss_public_key.c |  515 +++++
 src/libstrongswan/plugins/bliss/bliss_public_key.h |  101 +
 src/libstrongswan/plugins/bliss/bliss_sampler.c    |  250 +++
 src/libstrongswan/plugins/bliss/bliss_sampler.h    |   94 +
 src/libstrongswan/plugins/bliss/bliss_signature.c  |  233 +++
 src/libstrongswan/plugins/bliss/bliss_signature.h  |   75 +
 src/libstrongswan/plugins/bliss/bliss_utils.c      |  167 ++
 src/libstrongswan/plugins/bliss/bliss_utils.h      |   70 +
 src/libstrongswan/plugins/bliss/tests/Makefile.am  |   27 +
 src/libstrongswan/plugins/bliss/tests/Makefile.in  |  985 +++++++++
 .../plugins/bliss/tests/bliss_tests.c              |   60 +
 .../plugins/bliss/tests/bliss_tests.h              |   23 +
 .../bliss/tests/suites/test_bliss_bitpacker.c      |  112 +
 .../plugins/bliss/tests/suites/test_bliss_fft.c    |  110 +
 .../bliss/tests/suites/test_bliss_huffman.c        |  122 ++
 .../plugins/bliss/tests/suites/test_bliss_keys.c   |  249 +++
 .../bliss/tests/suites/test_bliss_sampler.c        |   97 +
 .../plugins/bliss/tests/suites/test_bliss_sign.c   |  211 ++
 .../bliss/tests/suites/test_bliss_signature.c      |  141 ++
 src/libstrongswan/plugins/blowfish/Makefile.in     |    5 +
 src/libstrongswan/plugins/ccm/Makefile.in          |    5 +
 src/libstrongswan/plugins/cmac/Makefile.in         |    5 +
 src/libstrongswan/plugins/cmac/cmac.c              |    3 +
 src/libstrongswan/plugins/constraints/Makefile.in  |    5 +
 .../plugins/constraints/constraints_validator.c    |  217 +-
 src/libstrongswan/plugins/ctr/Makefile.in          |    5 +
 src/libstrongswan/plugins/curl/Makefile.in         |    5 +
 src/libstrongswan/plugins/des/Makefile.in          |    5 +
 src/libstrongswan/plugins/dnskey/Makefile.in       |    5 +
 src/libstrongswan/plugins/files/Makefile.am        |   16 +
 src/libstrongswan/plugins/files/Makefile.in        |  775 +++++++
 src/libstrongswan/plugins/files/files_fetcher.c    |  117 ++
 src/libstrongswan/plugins/files/files_fetcher.h    |   42 +
 src/libstrongswan/plugins/files/files_plugin.c     |   76 +
 src/libstrongswan/plugins/files/files_plugin.h     |   42 +
 src/libstrongswan/plugins/fips_prf/Makefile.in     |    5 +
 src/libstrongswan/plugins/fips_prf/fips_prf.c      |    7 +-
 src/libstrongswan/plugins/gcm/Makefile.in          |    5 +
 src/libstrongswan/plugins/gcrypt/Makefile.in       |    5 +
 src/libstrongswan/plugins/gcrypt/gcrypt_dh.c       |   21 +-
 src/libstrongswan/plugins/gmp/Makefile.in          |    5 +
 src/libstrongswan/plugins/gmp/gmp_diffie_hellman.c |   23 +-
 src/libstrongswan/plugins/hmac/Makefile.in         |    5 +
 src/libstrongswan/plugins/hmac/hmac.c              |    3 +-
 src/libstrongswan/plugins/keychain/Makefile.in     |    5 +
 src/libstrongswan/plugins/ldap/Makefile.in         |    5 +
 src/libstrongswan/plugins/md4/Makefile.in          |    5 +
 src/libstrongswan/plugins/md5/Makefile.in          |    5 +
 src/libstrongswan/plugins/mysql/Makefile.in        |    5 +
 src/libstrongswan/plugins/nonce/Makefile.in        |    5 +
 src/libstrongswan/plugins/ntru/Makefile.am         |    1 -
 src/libstrongswan/plugins/ntru/Makefile.in         |   12 +-
 src/libstrongswan/plugins/ntru/ntru_ke.c           |   38 +-
 src/libstrongswan/plugins/ntru/ntru_mgf1.c         |  182 --
 src/libstrongswan/plugins/ntru/ntru_mgf1.h         |   77 -
 src/libstrongswan/plugins/ntru/ntru_poly.c         |   62 +-
 src/libstrongswan/plugins/ntru/ntru_trits.c        |   39 +-
 src/libstrongswan/plugins/openssl/Makefile.in      |    5 +
 .../plugins/openssl/openssl_crypter.c              |    2 +-
 .../plugins/openssl/openssl_diffie_hellman.c       |   21 +-
 .../plugins/openssl/openssl_ec_diffie_hellman.c    |   23 +-
 src/libstrongswan/plugins/padlock/Makefile.in      |    5 +
 src/libstrongswan/plugins/pem/Makefile.in          |    5 +
 src/libstrongswan/plugins/pem/pem_builder.c        |   25 +-
 src/libstrongswan/plugins/pem/pem_encoder.c        |   11 +
 src/libstrongswan/plugins/pem/pem_plugin.c         |    5 +
 src/libstrongswan/plugins/pgp/Makefile.in          |    5 +
 src/libstrongswan/plugins/pkcs1/Makefile.in        |    5 +
 src/libstrongswan/plugins/pkcs1/pkcs1_builder.c    |    9 +-
 src/libstrongswan/plugins/pkcs11/Makefile.in       |    5 +
 src/libstrongswan/plugins/pkcs11/pkcs11_dh.c       |   30 +-
 src/libstrongswan/plugins/pkcs11/pkcs11_library.c  |   44 +-
 .../plugins/pkcs11/pkcs11_private_key.c            |   21 +-
 .../plugins/pkcs11/pkcs11_public_key.c             |   50 +-
 src/libstrongswan/plugins/pkcs12/Makefile.in       |    5 +
 src/libstrongswan/plugins/pkcs7/Makefile.in        |    5 +
 src/libstrongswan/plugins/pkcs8/Makefile.in        |    5 +
 src/libstrongswan/plugins/plugin_loader.c          |   16 +-
 src/libstrongswan/plugins/pubkey/Makefile.in       |    5 +
 src/libstrongswan/plugins/random/Makefile.in       |    5 +
 src/libstrongswan/plugins/rc2/Makefile.in          |    5 +
 src/libstrongswan/plugins/rdrand/Makefile.in       |    5 +
 src/libstrongswan/plugins/revocation/Makefile.in   |    5 +
 src/libstrongswan/plugins/sha1/Makefile.in         |    5 +
 src/libstrongswan/plugins/sha2/Makefile.in         |    5 +
 src/libstrongswan/plugins/soup/Makefile.in         |    5 +
 src/libstrongswan/plugins/sqlite/Makefile.in       |    5 +
 src/libstrongswan/plugins/sshkey/Makefile.in       |    5 +
 src/libstrongswan/plugins/test_vectors/Makefile.in |    5 +
 src/libstrongswan/plugins/unbound/Makefile.in      |    5 +
 src/libstrongswan/plugins/winhttp/Makefile.in      |    5 +
 src/libstrongswan/plugins/x509/Makefile.in         |    5 +
 src/libstrongswan/plugins/x509/x509_ac.c           |    4 +-
 src/libstrongswan/plugins/x509/x509_cert.c         |    2 +-
 src/libstrongswan/plugins/x509/x509_crl.c          |   25 +-
 src/libstrongswan/plugins/x509/x509_ocsp_request.c |    6 +-
 .../plugins/x509/x509_ocsp_response.c              |    4 +-
 src/libstrongswan/plugins/x509/x509_pkcs10.c       |    2 +-
 src/libstrongswan/plugins/xcbc/Makefile.in         |    5 +
 src/libstrongswan/plugins/xcbc/xcbc.c              |    4 +
 src/libstrongswan/processing/processor.h           |    2 +
 src/libstrongswan/processing/scheduler.c           |   19 +-
 src/libstrongswan/processing/scheduler.h           |    7 +-
 src/libstrongswan/processing/watcher.c             |  113 +-
 src/libstrongswan/selectors/traffic_selector.c     |  121 +-
 src/libstrongswan/selectors/traffic_selector.h     |   19 +
 src/libstrongswan/settings/settings_lexer.c        |  190 +-
 src/libstrongswan/settings/settings_lexer.l        |    5 +-
 src/libstrongswan/tests/Makefile.am                |    4 +
 src/libstrongswan/tests/Makefile.in                |   81 +
 src/libstrongswan/tests/suites/test_certnames.c    |  398 ++++
 src/libstrongswan/tests/suites/test_certpolicy.c   |  637 ++++++
 src/libstrongswan/tests/suites/test_chunk.c        |   13 +-
 src/libstrongswan/tests/suites/test_enum.c         |  166 +-
 src/libstrongswan/tests/suites/test_hasher.c       |    3 +
 src/libstrongswan/tests/suites/test_host.c         |  137 ++
 .../tests/suites/test_identification.c             |  114 +-
 src/libstrongswan/tests/suites/test_mgf1.c         |  268 +++
 src/libstrongswan/tests/suites/test_ntru.c         |  222 +-
 src/libstrongswan/tests/suites/test_settings.c     |    4 +-
 src/libstrongswan/tests/suites/test_threading.c    |  236 +++
 .../tests/suites/test_traffic_selector.c           |  284 +++
 src/libstrongswan/tests/suites/test_utils.c        |   45 +-
 src/libstrongswan/tests/tests.h                    |    5 +
 src/libstrongswan/threading/semaphore.h            |    6 +-
 src/libstrongswan/threading/thread.h               |   63 +-
 src/libstrongswan/threading/windows/rwlock.c       |    2 -
 src/libstrongswan/utils/chunk.c                    |    2 +-
 src/libstrongswan/utils/compat/apple.h             |  119 ++
 src/libstrongswan/utils/compat/windows.c           |  684 ++++++
 src/libstrongswan/utils/compat/windows.h           |  627 ++++++
 src/libstrongswan/utils/enum.c                     |   93 +-
 src/libstrongswan/utils/enum.h                     |   35 +-
 src/libstrongswan/utils/identification.c           |   87 +
 src/libstrongswan/utils/identification.h           |    9 +
 src/libstrongswan/utils/utils.h                    |    6 +-
 src/libstrongswan/utils/windows.c                  |  641 ------
 src/libstrongswan/utils/windows.h                  |  584 ------
 src/libtls/Makefile.in                             |    5 +
 src/libtls/tests/Makefile.in                       |    5 +
 src/libtls/tls.c                                   |    9 +-
 src/libtls/tls.h                                   |    7 +
 src/libtls/tls_eap.c                               |    7 +
 src/libtls/tls_eap.h                               |    7 +
 src/libtls/tls_fragmentation.c                     |   35 +-
 src/libtls/tls_fragmentation.h                     |    4 +-
 src/libtls/tls_handshake.h                         |    7 +
 src/libtls/tls_peer.c                              |   40 +-
 src/libtls/tls_protection.c                        |   11 +-
 src/libtls/tls_server.c                            |   23 +-
 src/libtls/tls_socket.c                            |   15 +-
 src/libtnccs/Android.mk                            |    2 +-
 src/libtnccs/Makefile.in                           |    5 +
 src/libtnccs/plugins/tnc_imc/Makefile.in           |    5 +
 src/libtnccs/plugins/tnc_imc/tnc_imc_plugin.c      |    1 +
 src/libtnccs/plugins/tnc_imc/tnc_imc_plugin.h      |    2 +-
 src/libtnccs/plugins/tnc_imv/Makefile.in           |    5 +
 src/libtnccs/plugins/tnc_imv/tnc_imv_plugin.h      |    2 +-
 src/libtnccs/plugins/tnc_tnccs/Makefile.in         |    5 +
 src/libtnccs/plugins/tnc_tnccs/tnc_tnccs_manager.c |   48 +-
 src/libtnccs/plugins/tnc_tnccs/tnc_tnccs_plugin.h  |    2 +-
 src/libtnccs/plugins/tnccs_11/Makefile.in          |    5 +
 src/libtnccs/plugins/tnccs_11/tnccs_11.c           |   57 +-
 src/libtnccs/plugins/tnccs_11/tnccs_11.h           |   15 +-
 src/libtnccs/plugins/tnccs_11/tnccs_11_plugin.h    |    2 +-
 src/libtnccs/plugins/tnccs_20/Makefile.am          |    4 +
 src/libtnccs/plugins/tnccs_20/Makefile.in          |   39 +-
 src/libtnccs/plugins/tnccs_20/batch/pb_tnc_batch.c |   85 +-
 src/libtnccs/plugins/tnccs_20/batch/pb_tnc_batch.h |   30 +-
 .../messages/ita/pb_mutual_capability_msg.c        |  174 ++
 .../messages/ita/pb_mutual_capability_msg.h        |   75 +
 .../tnccs_20/messages/ita/pb_noskip_test_msg.c     |   92 +
 .../tnccs_20/messages/ita/pb_noskip_test_msg.h     |   44 +
 .../plugins/tnccs_20/messages/pb_tnc_msg.c         |   22 +-
 .../plugins/tnccs_20/messages/pb_tnc_msg.h         |   20 +
 src/libtnccs/plugins/tnccs_20/tnccs_20.c           |  945 ++-------
 src/libtnccs/plugins/tnccs_20/tnccs_20.h           |   15 +-
 src/libtnccs/plugins/tnccs_20/tnccs_20_client.c    |  820 ++++++++
 src/libtnccs/plugins/tnccs_20/tnccs_20_client.h    |   65 +
 src/libtnccs/plugins/tnccs_20/tnccs_20_handler.h   |  105 +
 src/libtnccs/plugins/tnccs_20/tnccs_20_plugin.h    |    2 +-
 src/libtnccs/plugins/tnccs_20/tnccs_20_server.c    |  693 +++++++
 src/libtnccs/plugins/tnccs_20/tnccs_20_server.h    |   71 +
 src/libtnccs/plugins/tnccs_dynamic/Makefile.in     |    5 +
 src/libtnccs/plugins/tnccs_dynamic/tnccs_dynamic.c |   61 +-
 src/libtnccs/plugins/tnccs_dynamic/tnccs_dynamic.h |   15 +-
 .../plugins/tnccs_dynamic/tnccs_dynamic_plugin.h   |    2 +-
 src/libtnccs/tnc/imc/imc.h                         |    2 +-
 src/libtnccs/tnc/imv/imv.h                         |    2 +-
 src/libtnccs/tnc/tnc.h                             |    7 +-
 src/libtnccs/tnc/tnccs/tnccs.h                     |   30 +-
 src/libtnccs/tnc/tnccs/tnccs_manager.h             |   15 +-
 src/libtncif/Makefile.in                           |    5 +
 src/libtncif/tncif_names.c                         |   14 +-
 src/libtncif/tncif_names.h                         |    4 +-
 src/manager/Makefile.in                            |    5 +
 src/medsrv/Makefile.in                             |    5 +
 src/pki/Makefile.am                                |    1 +
 src/pki/Makefile.in                                |   11 +-
 src/pki/command.h                                  |    2 +-
 src/pki/commands/acert.c                           |   11 +-
 src/pki/commands/gen.c                             |   14 +-
 src/pki/commands/issue.c                           |   12 +-
 src/pki/commands/keyid.c                           |    7 +-
 src/pki/commands/pkcs12.c                          |  247 +++
 src/pki/commands/print.c                           |   34 +-
 src/pki/commands/pub.c                             |   10 +-
 src/pki/commands/req.c                             |   17 +-
 src/pki/commands/self.c                            |   20 +-
 src/pki/commands/signcrl.c                         |    8 +-
 src/pki/man/Makefile.in                            |   21 +-
 src/pki/man/pki---acert.1.in                       |    4 +-
 src/pki/man/pki---issue.1.in                       |   20 +-
 src/pki/man/pki---pkcs12.1.in                      |   62 +
 src/pki/man/pki---req.1.in                         |    4 +-
 src/pki/man/pki---self.1.in                        |   20 +-
 src/pki/man/pki---signcrl.1.in                     |    4 +-
 src/pki/pki.c                                      |   46 +-
 src/pki/pki.h                                      |    8 +
 src/pool/Makefile.am                               |    4 +-
 src/pool/Makefile.in                               |   12 +-
 src/pt-tls-client/Makefile.in                      |    5 +
 src/pt-tls-client/pt-tls-client.c                  |   43 +-
 src/scepclient/Makefile.in                         |    5 +
 src/starter/Makefile.in                            |    5 +
 src/starter/cmp.c                                  |    2 +-
 src/starter/parser/lexer.c                         |  230 ++-
 src/starter/parser/lexer.l                         |    5 +-
 src/starter/starterstroke.c                        |   14 +-
 src/starter/tests/Makefile.in                      |    5 +
 src/stroke/Makefile.in                             |    5 +
 src/stroke/stroke_msg.h                            |    2 +-
 src/swanctl/Makefile.am                            |    1 +
 src/swanctl/Makefile.in                            |    6 +
 src/swanctl/commands/list_conns.c                  |    5 +-
 src/swanctl/commands/list_sas.c                    |    6 +-
 src/swanctl/commands/load_conns.c                  |   47 +-
 src/swanctl/commands/load_creds.c                  |  290 ++-
 src/swanctl/swanctl.conf                           |   14 +-
 src/swanctl/swanctl.conf.5.main                    |   80 +-
 src/swanctl/swanctl.h                              |    5 +
 src/swanctl/swanctl.opt                            |   52 +-
 testing/Makefile.in                                |    5 +
 testing/config/kernel/config-3.18                  | 2165 +++++++++++++++++++
 testing/config/kernel/config-3.19                  | 2181 ++++++++++++++++++++
 .../etc/openssl/bliss/strongswan_blissCert.der     |  Bin 0 -> 2094 bytes
 .../etc/openssl/bliss/strongswan_blissKey.der      |  Bin 0 -> 1310 bytes
 .../0b5362afd8838bafb66c854732b490d5d8318261       |  Bin 1190 -> 0 bytes
 .../35ef6b73537e090d3b09359bfee642eafa6192eb       |  Bin 0 -> 1212 bytes
 .../533394399c61128c957881790d70511537798da1       |  Bin 1212 -> 0 bytes
 .../6645da3911d7f86e5410b698e2a441f1e2e4491a       |  Bin 0 -> 1188 bytes
 .../6b5aec8fe9dcb8d0f707490abc84ab0890a7d2da       |  Bin 1188 -> 0 bytes
 .../b8a73c3433f4e341cc7c4ae42989f0a23a956488       |  Bin 1210 -> 0 bytes
 .../e2d52f0f42f61f786f1c570a4acc8fa8d72a329f       |  Bin 0 -> 1210 bytes
 .../f22389d26d00a7ddb5ff61f3b2e66022b18b2e3d       |  Bin 0 -> 1190 bytes
 .../hosts/winnetou/etc/openssl/duck/duckCert.pem   |   36 +-
 .../hosts/winnetou/etc/openssl/duck/duckKey.pem    |   50 +-
 testing/hosts/winnetou/etc/openssl/duck/index.txt  |    2 +-
 .../winnetou/etc/openssl/duck/newcerts/01.pem      |   36 +-
 testing/hosts/winnetou/etc/openssl/generate-crl    |    4 +-
 testing/hosts/winnetou/etc/openssl/index.txt       |    3 +-
 testing/hosts/winnetou/etc/openssl/index.txt.old   |    3 +-
 testing/hosts/winnetou/etc/openssl/newcerts/32.pem |   25 +
 testing/hosts/winnetou/etc/openssl/ocspCert.pem    |   30 +-
 testing/hosts/winnetou/etc/openssl/ocspKey.pem     |   50 +-
 .../hosts/winnetou/etc/openssl/research/index.txt  |    3 +-
 .../winnetou/etc/openssl/research/index.txt.old    |    3 +-
 .../winnetou/etc/openssl/research/newcerts/0A.pem  |   23 +
 testing/hosts/winnetou/etc/openssl/research/serial |    2 +-
 .../hosts/winnetou/etc/openssl/research/serial.old |    2 +-
 testing/hosts/winnetou/etc/openssl/rfc3779/.rand   |  Bin 1024 -> 1024 bytes
 .../hosts/winnetou/etc/openssl/rfc3779/index.txt   |   12 +-
 .../winnetou/etc/openssl/rfc3779/index.txt.old     |   10 +-
 .../winnetou/etc/openssl/rfc3779/newcerts/05.pem   |   28 +
 .../winnetou/etc/openssl/rfc3779/newcerts/06.pem   |   28 +
 .../winnetou/etc/openssl/rfc3779/newcerts/07.pem   |   27 +
 .../winnetou/etc/openssl/rfc3779/newcerts/08.pem   |   27 +
 .../hosts/winnetou/etc/openssl/rfc3779/openssl.cnf |   15 +-
 testing/hosts/winnetou/etc/openssl/rfc3779/serial  |    2 +-
 .../hosts/winnetou/etc/openssl/rfc3779/serial.old  |    2 +-
 testing/hosts/winnetou/etc/openssl/serial          |    2 +-
 testing/hosts/winnetou/etc/openssl/serial.old      |    2 +-
 testing/scripts/build-baseimage                    |    2 +-
 testing/scripts/recipes/013_strongswan.mk          |    5 +-
 testing/tests/ha/both-active/description.txt       |    4 +-
 testing/tests/ikev1/double-nat-net/evaltest.dat    |    4 +-
 testing/tests/ikev1/double-nat/evaltest.dat        |    4 +-
 testing/tests/ikev1/nat-rw/evaltest.dat            |    8 +-
 .../ikev1/nat-virtual-ip/hosts/moon/etc/nat_updown |   93 +-
 .../tests/ikev1/net2net-fragmentation/evaltest.dat |    4 +-
 .../hosts/moon/etc/ipsec.d/private/moonKey.pem     |   27 +
 .../hosts/sun/etc/ipsec.d/private/sunKey.pem       |   27 +
 testing/tests/ikev2/double-nat-net/evaltest.dat    |    4 +-
 testing/tests/ikev2/double-nat/evaltest.dat        |    4 +-
 testing/tests/ikev2/forecast/description.txt       |    8 +
 testing/tests/ikev2/forecast/evaltest.dat          |   20 +
 .../ikev2/forecast/hosts/carol/etc/ipsec.conf      |   21 +
 .../ikev2/forecast/hosts/carol/etc/strongswan.conf |    5 +
 .../tests/ikev2/forecast/hosts/dave/etc/ipsec.conf |   21 +
 .../ikev2/forecast/hosts/dave/etc/strongswan.conf  |    5 +
 .../tests/ikev2/forecast/hosts/moon/etc/ipsec.conf |   22 +
 .../ikev2/forecast/hosts/moon/etc/strongswan.conf  |   16 +
 testing/tests/ikev2/forecast/posttest.dat          |    6 +
 testing/tests/ikev2/forecast/pretest.dat           |    7 +
 testing/tests/ikev2/forecast/test.conf             |   21 +
 .../host2host-transport-connmark/description.txt   |    8 +
 .../host2host-transport-connmark/evaltest.dat      |    7 +
 .../hosts/alice/etc/ipsec.conf                     |   17 +
 .../hosts/sun/etc/ipsec.conf                       |   18 +
 .../hosts/sun/etc/strongswan.conf                  |    5 +
 .../hosts/venus/etc/ipsec.conf                     |   17 +
 .../host2host-transport-connmark/posttest.dat      |    5 +
 .../ikev2/host2host-transport-connmark/pretest.dat |   11 +
 .../ikev2/host2host-transport-connmark/test.conf   |   21 +
 .../ikev2/host2host-transport-nat/description.txt  |    3 +-
 .../ikev2/host2host-transport-nat/evaltest.dat     |   13 +-
 .../ikev2/host2host-transport-nat/pretest.dat      |    1 +
 .../ikev2/mult-auth-rsa-eap-sim-id/evaltest.dat    |    8 +-
 .../hosts/carol/etc/ipsec.d/certs/carolCert.pem    |   36 +-
 .../hosts/carol/etc/ipsec.d/private/carolKey.pem   |   50 +-
 .../hosts/moon/etc/ipsec.d/cacerts/duckCert.pem    |   36 +-
 testing/tests/ikev2/nat-rw-mark/evaltest.dat       |    4 +-
 .../ikev2/nat-rw-mark/hosts/sun/etc/mark_updown    |  300 +--
 testing/tests/ikev2/nat-rw-psk/evaltest.dat        |    6 +-
 testing/tests/ikev2/nat-rw/evaltest.dat            |    8 +-
 .../ikev2/nat-virtual-ip/hosts/moon/etc/nat_updown |   94 +-
 .../tests/ikev2/net2net-cert-sha2/description.txt  |    7 +
 testing/tests/ikev2/net2net-cert-sha2/evaltest.dat |    9 +
 .../net2net-cert-sha2/hosts/moon/etc/ipsec.conf    |   23 +
 .../hosts/moon/etc/strongswan.conf                 |    5 +
 .../net2net-cert-sha2/hosts/sun/etc/ipsec.conf     |   23 +
 .../hosts/sun/etc/strongswan.conf                  |    5 +
 testing/tests/ikev2/net2net-cert-sha2/posttest.dat |    5 +
 testing/tests/ikev2/net2net-cert-sha2/pretest.dat  |    6 +
 testing/tests/ikev2/net2net-cert-sha2/test.conf    |   21 +
 .../net2net-cert/hosts/moon/etc/strongswan.conf    |    1 +
 .../net2net-cert/hosts/sun/etc/strongswan.conf     |    1 +
 .../tests/ikev2/net2net-fragmentation/evaltest.dat |    4 +-
 .../hosts/moon/etc/ipsec.d/certs/moonCert.pem      |   36 +-
 .../hosts/moon/etc/ipsec.d/private/moonKey.pem     |   50 +-
 .../hosts/sun/etc/ipsec.d/certs/sunCert.pem        |   36 +-
 .../hosts/sun/etc/ipsec.d/private/sunKey.pem       |   50 +-
 .../net2net-same-nets/hosts/sun/etc/mark_updown    |   48 +-
 .../ikev2/reauth-mbb-virtual-ip/description.txt    |    8 +
 .../tests/ikev2/reauth-mbb-virtual-ip/evaltest.dat |    7 +
 .../hosts/carol/etc/ipsec.conf                     |   22 +
 .../hosts/carol/etc/strongswan.conf                |    7 +
 .../hosts/moon/etc/ipsec.conf                      |   20 +
 .../hosts/moon/etc/strongswan.conf                 |    5 +
 .../tests/ikev2/reauth-mbb-virtual-ip/posttest.dat |    4 +
 .../tests/ikev2/reauth-mbb-virtual-ip/pretest.dat  |    6 +
 .../tests/ikev2/reauth-mbb-virtual-ip/test.conf    |   21 +
 testing/tests/ikev2/reauth-mbb/description.txt     |    7 +
 testing/tests/ikev2/reauth-mbb/evaltest.dat        |    7 +
 .../ikev2/reauth-mbb/hosts/carol/etc/ipsec.conf    |   21 +
 .../reauth-mbb/hosts/carol/etc/strongswan.conf     |    7 +
 .../ikev2/reauth-mbb/hosts/moon/etc/ipsec.conf     |   19 +
 .../reauth-mbb/hosts/moon/etc/strongswan.conf      |    5 +
 testing/tests/ikev2/reauth-mbb/posttest.dat        |    4 +
 testing/tests/ikev2/reauth-mbb/pretest.dat         |    6 +
 testing/tests/ikev2/reauth-mbb/test.conf           |   21 +
 testing/tests/ikev2/rw-eap-aka-id-rsa/evaltest.dat |    2 +-
 testing/tests/ikev2/rw-eap-aka-rsa/evaltest.dat    |    2 +-
 .../rw-eap-aka-rsa/hosts/carol/etc/ipsec.conf      |    1 -
 testing/tests/ikev2/rw-eap-dynamic/evaltest.dat    |    4 +-
 .../ikev2/rw-eap-framed-ip-radius/evaltest.dat     |    4 +-
 .../ikev2/rw-eap-md5-class-radius/evaltest.dat     |    4 +-
 .../tests/ikev2/rw-eap-md5-id-prompt/evaltest.dat  |    2 +-
 .../tests/ikev2/rw-eap-md5-id-radius/evaltest.dat  |    2 +-
 .../hosts/carol/etc/ipsec.conf                     |    1 -
 testing/tests/ikev2/rw-eap-md5-radius/evaltest.dat |    2 +-
 .../rw-eap-md5-radius/hosts/carol/etc/ipsec.conf   |    1 -
 testing/tests/ikev2/rw-eap-md5-rsa/evaltest.dat    |    2 +-
 .../rw-eap-md5-rsa/hosts/carol/etc/ipsec.conf      |    1 -
 .../ikev2/rw-eap-mschapv2-id-rsa/evaltest.dat      |    2 +-
 .../tests/ikev2/rw-eap-peap-radius/evaltest.dat    |    4 +-
 .../tests/ikev2/rw-eap-sim-id-radius/evaltest.dat  |    2 +-
 testing/tests/ikev2/rw-eap-sim-radius/evaltest.dat |    2 +-
 testing/tests/ikev2/rw-eap-sim-rsa/evaltest.dat    |    2 +-
 .../rw-eap-sim-rsa/hosts/carol/etc/ipsec.conf      |    1 -
 testing/tests/ikev2/rw-eap-tls-radius/evaltest.dat |    2 +-
 .../tests/ikev2/rw-eap-ttls-radius/evaltest.dat    |    4 +-
 .../ikev2/rw-mark-in-out/hosts/sun/etc/mark_updown |  296 +--
 testing/tests/ikev2/rw-ntru-bliss/description.txt  |   15 +
 testing/tests/ikev2/rw-ntru-bliss/evaltest.dat     |   26 +
 .../ikev2/rw-ntru-bliss/hosts/carol/etc/ipsec.conf |   25 +
 .../etc/ipsec.d/cacerts/strongswan_blissCert.der   |  Bin 0 -> 2094 bytes
 .../hosts/carol/etc/ipsec.d/certs/carolCert.der    |  Bin 0 -> 2172 bytes
 .../hosts/carol/etc/ipsec.d/private/carolKey.der   |  Bin 0 -> 1182 bytes
 .../rw-ntru-bliss/hosts/carol/etc/ipsec.secrets    |    3 +
 .../rw-ntru-bliss/hosts/carol/etc/strongswan.conf  |    7 +
 .../ikev2/rw-ntru-bliss/hosts/dave/etc/ipsec.conf  |   25 +
 .../etc/ipsec.d/cacerts/strongswan_blissCert.der   |  Bin 0 -> 2094 bytes
 .../hosts/dave/etc/ipsec.d/certs/daveCert.der      |  Bin 0 -> 2173 bytes
 .../hosts/dave/etc/ipsec.d/private/daveKey.der     |  Bin 0 -> 1310 bytes
 .../rw-ntru-bliss/hosts/dave/etc/ipsec.secrets     |    3 +
 .../rw-ntru-bliss/hosts/dave/etc/strongswan.conf   |    7 +
 .../ikev2/rw-ntru-bliss/hosts/moon/etc/ipsec.conf  |   25 +
 .../etc/ipsec.d/cacerts/strongswan_blissCert.der   |  Bin 0 -> 2094 bytes
 .../hosts/moon/etc/ipsec.d/certs/moonCert.der      |  Bin 0 -> 2190 bytes
 .../hosts/moon/etc/ipsec.d/private/moonKey.der     |  Bin 0 -> 1310 bytes
 .../rw-ntru-bliss/hosts/moon/etc/ipsec.secrets     |    3 +
 .../rw-ntru-bliss/hosts/moon/etc/strongswan.conf   |    7 +
 testing/tests/ikev2/rw-ntru-bliss/posttest.dat     |    9 +
 testing/tests/ikev2/rw-ntru-bliss/pretest.dat      |   13 +
 testing/tests/ikev2/rw-ntru-bliss/test.conf        |   21 +
 testing/tests/ikev2/rw-psk-rsa-mixed/evaltest.dat  |    4 +-
 testing/tests/ikev2/rw-psk-rsa-split/evaltest.dat  |    2 +-
 .../tests/ikev2/rw-radius-accounting/evaltest.dat  |    2 +-
 .../hosts/carol/etc/ipsec.conf                     |    1 -
 testing/tests/ikev2/rw-sig-auth/description.txt    |   10 +
 testing/tests/ikev2/rw-sig-auth/evaltest.dat       |   20 +
 .../ikev2/rw-sig-auth/hosts/carol/etc/ipsec.conf   |   29 +
 .../rw-sig-auth/hosts/carol/etc/strongswan.conf    |    5 +
 .../ikev2/rw-sig-auth/hosts/dave/etc/ipsec.conf    |   29 +
 .../rw-sig-auth/hosts/dave/etc/strongswan.conf     |    5 +
 .../ikev2/rw-sig-auth/hosts/moon/etc/ipsec.conf    |   30 +
 .../ikev2/rw-sig-auth/hosts/moon/etc/ipsec.secrets |    3 +
 .../rw-sig-auth/hosts/moon/etc/strongswan.conf     |    5 +
 testing/tests/ikev2/rw-sig-auth/posttest.dat       |    6 +
 testing/tests/ikev2/rw-sig-auth/pretest.dat        |   12 +
 testing/tests/ikev2/rw-sig-auth/test.conf          |   26 +
 testing/tests/ikev2/rw-whitelist/evaltest.dat      |    4 +-
 .../hosts/moon/etc/ipsec.d/certs/moonCert.pem      |   36 +-
 .../hosts/moon/etc/ipsec.d/private/moonKey.pem     |   50 +-
 .../hosts/sun/etc/ipsec.d/certs/sunCert.pem        |   36 +-
 .../hosts/sun/etc/ipsec.d/private/sunKey.pem       |   50 +-
 .../hosts/carol/etc/ipsec.d/certs/carolCert.pem    |   34 +-
 .../hosts/carol/etc/ipsec.d/private/carolKey.pem   |   50 +-
 .../hosts/dave/etc/ipsec.d/certs/daveCert.pem      |   34 +-
 .../hosts/dave/etc/ipsec.d/private/daveKey.pem     |   50 +-
 .../hosts/moon/etc/ipsec.d/certs/moonCert.pem      |   36 +-
 .../hosts/moon/etc/ipsec.d/private/moonKey.pem     |   50 +-
 .../libipsec/host2host-cert/hosts/moon/etc/updown  |  303 +--
 .../libipsec/host2host-cert/hosts/sun/etc/updown   |  303 +--
 .../libipsec/net2net-3des/hosts/moon/etc/updown    |  303 +--
 .../libipsec/net2net-3des/hosts/sun/etc/updown     |  303 +--
 .../libipsec/net2net-cert/hosts/moon/etc/updown    |  303 +--
 .../libipsec/net2net-cert/hosts/sun/etc/updown     |  303 +--
 testing/tests/libipsec/rw-suite-b/evaltest.dat     |    6 +-
 .../libipsec/rw-suite-b/hosts/carol/etc/updown     |  311 +--
 .../libipsec/rw-suite-b/hosts/dave/etc/updown      |  311 +--
 .../libipsec/rw-suite-b/hosts/moon/etc/updown      |  311 +--
 .../hosts/moon/etc/ipsec.d/private/moonKey.pem     |   27 +
 .../hosts/sun/etc/ipsec.d/private/sunKey.pem       |   27 +
 .../tests/openssl-ikev2/ecdsa-certs/evaltest.dat   |    4 +-
 .../ecdsa-certs/hosts/dave/etc/strongswan.conf     |    1 +
 .../tests/openssl-ikev2/ecdsa-pkcs8/evaltest.dat   |    8 +-
 .../openssl-ikev2/rw-suite-b-128/evaltest.dat      |    2 +-
 .../openssl-ikev2/rw-suite-b-192/evaltest.dat      |    2 +-
 testing/tests/sql/rw-eap-aka-rsa/evaltest.dat      |    2 +-
 testing/tests/sql/rw-psk-rsa-split/evaltest.dat    |    2 +-
 .../swanctl/net2net-cert-ipv6/description.txt      |    6 -
 .../tests/swanctl/net2net-cert-ipv6/evaltest.dat   |    5 -
 .../hosts/moon/etc/strongswan.conf                 |   15 -
 .../hosts/moon/etc/swanctl/swanctl.conf            |   35 -
 .../hosts/sun/etc/strongswan.conf                  |   15 -
 .../hosts/sun/etc/swanctl/swanctl.conf             |   35 -
 .../tests/swanctl/net2net-cert-ipv6/posttest.dat   |   11 -
 .../tests/swanctl/net2net-cert-ipv6/pretest.dat    |   16 -
 testing/tests/swanctl/net2net-cert-ipv6/test.conf  |   21 -
 testing/tests/tkm/host2host-initiator/evaltest.dat |    4 +
 testing/tests/tkm/host2host-xfrmproxy/evaltest.dat |    1 +
 testing/tests/tkm/multiple-clients/evaltest.dat    |    3 +-
 testing/tests/tkm/net2net-xfrmproxy/evaltest.dat   |    1 +
 testing/tests/tkm/xfrmproxy-expire/description.txt |    6 +
 testing/tests/tkm/xfrmproxy-expire/evaltest.dat    |   22 +
 .../hosts/moon/etc/strongswan.conf                 |    8 +
 .../hosts/moon/etc/tkm/moonKey.der                 |  Bin 0 -> 1191 bytes
 .../hosts/moon/etc/tkm/strongswanCert.der          |  Bin 0 -> 956 bytes
 .../xfrmproxy-expire/hosts/moon/etc/tkm/tkm.conf   |   21 +
 .../tkm/xfrmproxy-expire/hosts/sun/etc/ipsec.conf  |   21 +
 .../xfrmproxy-expire/hosts/sun/etc/strongswan.conf |    5 +
 testing/tests/tkm/xfrmproxy-expire/posttest.dat    |    5 +
 testing/tests/tkm/xfrmproxy-expire/pretest.dat     |   12 +
 testing/tests/tkm/xfrmproxy-expire/test.conf       |   21 +
 .../tests/tnc/tnccs-11-radius-block/evaltest.dat   |    4 +-
 testing/tests/tnc/tnccs-11-radius-pts/evaltest.dat |    4 +-
 testing/tests/tnc/tnccs-11-radius/evaltest.dat     |    4 +-
 .../tests/tnc/tnccs-20-fail-init/description.txt   |   10 +
 testing/tests/tnc/tnccs-20-fail-init/evaltest.dat  |   10 +
 .../tnccs-20-fail-init/hosts/carol/etc/ipsec.conf  |   23 +
 .../hosts/carol/etc/ipsec.secrets                  |    3 +
 .../hosts/carol/etc/strongswan.conf                |   23 +
 .../tnccs-20-fail-init/hosts/carol/etc/tnc_config  |    3 +
 .../tnccs-20-fail-init/hosts/dave/etc/ipsec.conf   |   23 +
 .../hosts/dave/etc/ipsec.secrets                   |    3 +
 .../hosts/dave/etc/strongswan.conf                 |   26 +
 .../tnccs-20-fail-init/hosts/dave/etc/tnc_config   |    3 +
 .../tnccs-20-fail-init/hosts/moon/etc/ipsec.conf   |   34 +
 .../hosts/moon/etc/ipsec.secrets                   |    6 +
 .../hosts/moon/etc/strongswan.conf                 |   23 +
 .../tnccs-20-fail-init/hosts/moon/etc/tnc_config   |    3 +
 testing/tests/tnc/tnccs-20-fail-init/posttest.dat  |    6 +
 testing/tests/tnc/tnccs-20-fail-init/pretest.dat   |   12 +
 testing/tests/tnc/tnccs-20-fail-init/test.conf     |   26 +
 .../tests/tnc/tnccs-20-fail-resp/description.txt   |    9 +
 testing/tests/tnc/tnccs-20-fail-resp/evaltest.dat  |    5 +
 .../tnccs-20-fail-resp/hosts/carol/etc/ipsec.conf  |   23 +
 .../hosts/carol/etc/ipsec.secrets                  |    3 +
 .../hosts/carol/etc/strongswan.conf                |   15 +
 .../tnccs-20-fail-resp/hosts/carol/etc/tnc_config  |    3 +
 .../tnccs-20-fail-resp/hosts/moon/etc/ipsec.conf   |   34 +
 .../hosts/moon/etc/ipsec.secrets                   |    6 +
 .../hosts/moon/etc/strongswan.conf                 |   28 +
 .../tnccs-20-fail-resp/hosts/moon/etc/tnc_config   |    3 +
 testing/tests/tnc/tnccs-20-fail-resp/posttest.dat  |    4 +
 testing/tests/tnc/tnccs-20-fail-resp/pretest.dat   |    8 +
 testing/tests/tnc/tnccs-20-fail-resp/test.conf     |   26 +
 .../tests/tnc/tnccs-20-mutual-eap/description.txt  |    3 +
 testing/tests/tnc/tnccs-20-mutual-eap/evaltest.dat |   11 +
 .../tnccs-20-mutual-eap/hosts/moon/etc/ipsec.conf  |   23 +
 .../hosts/moon/etc/strongswan.conf                 |   26 +
 .../tnccs-20-mutual-eap/hosts/moon/etc/tnc_config  |    4 +
 .../tnccs-20-mutual-eap/hosts/sun/etc/ipsec.conf   |   23 +
 .../hosts/sun/etc/strongswan.conf                  |   28 +
 .../tnccs-20-mutual-eap/hosts/sun/etc/tnc_config   |    4 +
 testing/tests/tnc/tnccs-20-mutual-eap/posttest.dat |    4 +
 testing/tests/tnc/tnccs-20-mutual-eap/pretest.dat  |    6 +
 testing/tests/tnc/tnccs-20-mutual-eap/test.conf    |   21 +
 .../tnc/tnccs-20-mutual-pt-tls/description.txt     |    3 +
 .../tests/tnc/tnccs-20-mutual-pt-tls/evaltest.dat  |    6 +
 .../hosts/moon/etc/ipsec.conf                      |    3 +
 .../hosts/moon/etc/pts/options                     |    8 +
 .../hosts/moon/etc/strongswan.conf                 |   16 +
 .../hosts/moon/etc/tnc_config                      |    4 +
 .../hosts/sun/etc/ipsec.conf                       |    9 +
 .../hosts/sun/etc/strongswan.conf                  |   28 +
 .../hosts/sun/etc/tnc_config                       |    4 +
 .../tests/tnc/tnccs-20-mutual-pt-tls/posttest.dat  |    1 +
 .../tests/tnc/tnccs-20-mutual-pt-tls/pretest.dat   |    4 +
 testing/tests/tnc/tnccs-20-mutual-pt-tls/test.conf |   21 +
 testing/tests/tnc/tnccs-20-pdp-eap/evaltest.dat    |    4 +-
 1043 files changed, 50664 insertions(+), 18236 deletions(-)

diff --git a/Android.common.mk b/Android.common.mk
index c650cb8..d33062a 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.2.1"
+strongswan_VERSION := "5.3.0"
 
diff --git a/Doxyfile.in b/Doxyfile.in
index 8adf83c..eaf02d7 100644
--- a/Doxyfile.in
+++ b/Doxyfile.in
@@ -743,7 +743,7 @@ WARN_LOGFILE           =
 # spaces.
 # Note: If this tag is empty the current directory is searched.
 
-INPUT                  = @SRC_DIR@/
+INPUT                  = @SRC_DIR@/src @SRC_DIR@/README.md
 
 # This tag can be used to specify the character encoding of the source files
 # that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses
diff --git a/Makefile.am b/Makefile.am
index 0703abc..bea4ba7 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -34,7 +34,7 @@ Doxyfile :	Doxyfile.in
 		sed \
 		-e "s:\@PACKAGE_VERSION\@:$(PACKAGE_VERSION):" \
 		-e "s:\@PACKAGE_NAME\@:$(PACKAGE_NAME):" \
-		-e "s:\@SRC_DIR\@:$(srcdir):" \
+		-e "s:\@SRC_DIR\@:$(srcdir):g" \
 		$(srcdir)/$@.in > $@
 
 apidoc :	Doxyfile
diff --git a/Makefile.in b/Makefile.in
index 8effaa3..e10818f 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -257,6 +257,7 @@ DLLIB = @DLLIB@
 DLLTOOL = @DLLTOOL@
 DSYMUTIL = @DSYMUTIL@
 DUMPBIN = @DUMPBIN@
+EASY_INSTALL = @EASY_INSTALL@
 ECHO_C = @ECHO_C@
 ECHO_N = @ECHO_N@
 ECHO_T = @ECHO_T@
@@ -317,10 +318,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
 PLUGIN_CFLAGS = @PLUGIN_CFLAGS@
 PTHREADLIB = @PTHREADLIB@
 PYTHON = @PYTHON@
+PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@
 PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
 PYTHON_PLATFORM = @PYTHON_PLATFORM@
 PYTHON_PREFIX = @PYTHON_PREFIX@
 PYTHON_VERSION = @PYTHON_VERSION@
+PY_TEST = @PY_TEST@
 RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
@@ -394,6 +397,8 @@ json_CFLAGS = @json_CFLAGS@
 json_LIBS = @json_LIBS@
 libdir = @libdir@
 libexecdir = @libexecdir@
+libiptc_CFLAGS = @libiptc_CFLAGS@
+libiptc_LIBS = @libiptc_LIBS@
 linux_headers = @linux_headers@
 localedir = @localedir@
 localstatedir = @localstatedir@
@@ -991,7 +996,7 @@ Doxyfile :	Doxyfile.in
 		sed \
 		-e "s:\@PACKAGE_VERSION\@:$(PACKAGE_VERSION):" \
 		-e "s:\@PACKAGE_NAME\@:$(PACKAGE_NAME):" \
-		-e "s:\@SRC_DIR\@:$(srcdir):" \
+		-e "s:\@SRC_DIR\@:$(srcdir):g" \
 		$(srcdir)/$@.in > $@
 
 apidoc :	Doxyfile
diff --git a/NEWS b/NEWS
index f1a4b21..81a7fc5 100644
--- a/NEWS
+++ b/NEWS
@@ -1,3 +1,86 @@
+strongswan-5.3.0
+----------------
+
+- Added support for IKEv2 make-before-break reauthentication. By using a global
+  CHILD_SA reqid allocation mechanism, charon supports overlapping CHILD_SAs.
+  This allows the use of make-before-break instead of the previously supported
+  break-before-make reauthentication, avoiding connectivity gaps during that
+  procedure. As the new mechanism may fail with peers not supporting it (such
+  as any previous strongSwan release) it must be explicitly enabled using
+  the charon.make_before_break strongswan.conf option.
+
+- Support for "Signature Authentication in IKEv2" (RFC 7427) has been added.
+  This allows the use of stronger hash algorithms for public key authentication.
+  By default, signature schemes are chosen based on the strength of the
+  signature key, but specific hash algorithms may be configured in leftauth.
+
+- Key types and hash algorithms specified in rightauth are now also checked
+  against IKEv2 signature schemes.  If such constraints are used for certificate
+  chain validation in existing configurations, in particular with peers that
+  don't support RFC 7427, it may be necessary to disable this feature with the
+  charon.signature_authentication_constraints setting, because the signature
+  scheme used in classic IKEv2 public key authentication may not be strong
+  enough.
+
+- The new connmark plugin allows a host to bind conntrack flows to a specific
+  CHILD_SA by applying and restoring the SA mark to conntrack entries. This
+  allows a peer to handle multiple transport mode connections coming over the
+  same NAT device for client-initiated flows. A common use case is to protect
+  L2TP/IPsec, as supported by some systems.
+
+- The forecast plugin can forward broadcast and multicast messages between
+  connected clients and a LAN. For CHILD_SA using unique marks, it sets up
+  the required Netfilter rules and uses a multicast/broadcast listener that
+  forwards such messages to all connected clients. This plugin is designed for
+  Windows 7 IKEv2 clients, which announces its services over the tunnel if the
+  negotiated IPsec policy allows it.
+
+- For the vici plugin a Python Egg has been added to allow Python applications
+  to control or monitor the IKE daemon using the VICI interface, similar to the
+  existing ruby gem. The Python library has been contributed by Björn Schuberg.
+
+- EAP server methods now can fulfill public key constraints, such as rightcert
+  or rightca. Additionally, public key and signature constraints can be
+  specified for EAP methods in the rightauth keyword. Currently the EAP-TLS and
+  EAP-TTLS methods provide verification details to constraints checking.
+
+- Upgrade of the BLISS post-quantum signature algorithm to the improved BLISS-B
+  variant. Can be used in conjunction with the SHA256, SHA384 and SHA512 hash
+  algorithms with SHA512 being the default.
+
+- The IF-IMV 1.4 interface now makes the IP address of the TNC access requestor
+  as seen by the TNC server available to all IMVs. This information can be
+  forwarded to policy enforcement points (e.g. firewalls or routers).
+
+- The new mutual tnccs-20 plugin parameter activates mutual TNC measurements
+  in PB-TNC half-duplex mode between two endpoints over either a PT-EAP or
+  PT-TLS transport medium.
+
+
+strongswan-5.2.2
+----------------
+
+- Fixed a denial-of-service vulnerability triggered by an IKEv2 Key Exchange
+  payload that contains the Diffie-Hellman group 1025.  This identifier was
+  used internally for DH groups with custom generator and prime.  Because
+  these arguments are missing when creating DH objects based on the KE payload
+  an invalid pointer dereference occurred.  This allowed an attacker to crash
+  the IKE daemon with a single IKE_SA_INIT message containing such a KE
+  payload.  The vulnerability has been registered as CVE-2014-9221.
+
+- The left/rightid options in ipsec.conf, or any other identity in strongSwan,
+  now accept prefixes to enforce an explicit type, such as email: or fqdn:.
+  Note that no conversion is done for the remaining string, refer to
+  ipsec.conf(5) for details.
+
+- The post-quantum Bimodal Lattice Signature Scheme (BLISS) can be used as
+  an IKEv2 public key authentication method. The pki tool offers full support
+  for the generation of BLISS key pairs and certificates.
+
+- Fixed mapping of integrity algorithms negotiated for AH via IKEv1. This could
+  cause interoperability issues when connecting to older versions of charon.
+
+
 strongswan-5.2.1
 ----------------
 
diff --git a/conf/Makefile.am b/conf/Makefile.am
index e507739..f10af25 100644
--- a/conf/Makefile.am
+++ b/conf/Makefile.am
@@ -28,6 +28,7 @@ plugins = \
 	plugins/android_log.opt \
 	plugins/attr.opt \
 	plugins/attr-sql.opt \
+	plugins/bliss.opt \
 	plugins/certexpire.opt \
 	plugins/coupling.opt \
 	plugins/dhcp.opt \
@@ -46,6 +47,7 @@ plugins = \
 	plugins/eap-ttls.opt \
 	plugins/error-notify.opt \
 	plugins/ext-auth.opt \
+	plugins/forecast.opt \
 	plugins/gcrypt.opt \
 	plugins/ha.opt \
 	plugins/imc-attestation.opt \
@@ -62,6 +64,7 @@ plugins = \
 	plugins/led.opt \
 	plugins/kernel-libipsec.opt \
 	plugins/kernel-netlink.opt \
+	plugins/kernel-pfkey.opt \
 	plugins/kernel-pfroute.opt \
 	plugins/load-tester.opt \
 	plugins/lookip.opt \
diff --git a/conf/Makefile.in b/conf/Makefile.in
index d5bb3ff..4b39140 100644
--- a/conf/Makefile.in
+++ b/conf/Makefile.in
@@ -180,6 +180,7 @@ DLLIB = @DLLIB@
 DLLTOOL = @DLLTOOL@
 DSYMUTIL = @DSYMUTIL@
 DUMPBIN = @DUMPBIN@
+EASY_INSTALL = @EASY_INSTALL@
 ECHO_C = @ECHO_C@
 ECHO_N = @ECHO_N@
 ECHO_T = @ECHO_T@
@@ -240,10 +241,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
 PLUGIN_CFLAGS = @PLUGIN_CFLAGS@
 PTHREADLIB = @PTHREADLIB@
 PYTHON = @PYTHON@
+PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@
 PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
 PYTHON_PLATFORM = @PYTHON_PLATFORM@
 PYTHON_PREFIX = @PYTHON_PREFIX@
 PYTHON_VERSION = @PYTHON_VERSION@
+PY_TEST = @PY_TEST@
 RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
@@ -317,6 +320,8 @@ json_CFLAGS = @json_CFLAGS@
 json_LIBS = @json_LIBS@
 libdir = @libdir@
 libexecdir = @libexecdir@
+libiptc_CFLAGS = @libiptc_CFLAGS@
+libiptc_LIBS = @libiptc_LIBS@
 linux_headers = @linux_headers@
 localedir = @localedir@
 localstatedir = @localstatedir@
@@ -405,6 +410,7 @@ plugins = \
 	plugins/android_log.opt \
 	plugins/attr.opt \
 	plugins/attr-sql.opt \
+	plugins/bliss.opt \
 	plugins/certexpire.opt \
 	plugins/coupling.opt \
 	plugins/dhcp.opt \
@@ -423,6 +429,7 @@ plugins = \
 	plugins/eap-ttls.opt \
 	plugins/error-notify.opt \
 	plugins/ext-auth.opt \
+	plugins/forecast.opt \
 	plugins/gcrypt.opt \
 	plugins/ha.opt \
 	plugins/imc-attestation.opt \
@@ -439,6 +446,7 @@ plugins = \
 	plugins/led.opt \
 	plugins/kernel-libipsec.opt \
 	plugins/kernel-netlink.opt \
+	plugins/kernel-pfkey.opt \
 	plugins/kernel-pfroute.opt \
 	plugins/load-tester.opt \
 	plugins/lookip.opt \
diff --git a/conf/options/charon.conf b/conf/options/charon.conf
index 0bec9bb..bd8e299 100644
--- a/conf/options/charon.conf
+++ b/conf/options/charon.conf
@@ -58,6 +58,10 @@ charon {
     # Allow IKEv1 Aggressive Mode with pre-shared keys as responder.
     # i_dont_care_about_security_and_use_aggressive_mode_psk = no
 
+    # Whether to ignore the traffic selectors from the kernel's acquire events
+    # for IKEv2 connections (they are not used for IKEv1).
+    # ignore_acquire_ts = no
+
     # A space-separated list of routing tables to be excluded from route
     # lookups.
     # ignore_routing_tables =
@@ -116,6 +120,9 @@ charon {
     # Determine plugins to load via each plugin's load option.
     # load_modular = no
 
+    # Initiate IKEv2 reauthentication with a make-before-break scheme.
+    # make_before_break = no
+
     # Maximum packet size accepted by charon.
     # max_packet = 10000
 
@@ -197,6 +204,12 @@ charon {
     # Send strongSwan vendor ID payload
     # send_vendor_id = no
 
+    # Whether to enable Signature Authentication as per RFC 7427.
+    # signature_authentication = yes
+
+    # Whether to enable constraints against IKEv2 signature schemes.
+    # signature_authentication_constraints = yes
+
     # Number of worker threads in charon.
     # threads = 16
 
diff --git a/conf/options/charon.opt b/conf/options/charon.opt
index 678aa37..bbc50ba 100644
--- a/conf/options/charon.opt
+++ b/conf/options/charon.opt
@@ -117,6 +117,17 @@ charon.i_dont_care_about_security_and_use_aggressive_mode_psk = no
 charon.ignore_routing_tables
 	A space-separated list of routing tables to be excluded from route lookups.
 
+charon.ignore_acquire_ts = no
+	Whether to ignore the traffic selectors from the kernel's acquire events for
+	IKEv2 connections (they are not used for IKEv1).
+
+	If this is disabled the traffic selectors from the kernel's acquire events,
+	which are derived from the triggering packet, are prepended to the traffic
+	selectors from the configuration for IKEv2 connection. By enabling this,
+	such specific traffic selectors will be ignored and only the ones in the
+	config will	be sent. This always happens for IKEv1 connections as the
+	protocol only supports one set of traffic selectors per CHILD_SA.
+
 charon.ikesa_limit = 0
 	Maximum number of IKE_SAs that can be established at the same time before
 	new connection attempts are blocked.
@@ -196,6 +207,16 @@ charon.load_modular = no
 charon.max_packet = 10000
 	Maximum packet size accepted by charon.
 
+charon.make_before_break = no
+	Initiate IKEv2 reauthentication with a make-before-break scheme.
+
+	Initiate IKEv2 reauthentication with a make-before-break instead of a
+	break-before-make scheme. Make-before-break uses overlapping IKE and
+	CHILD_SA during reauthentication by first recreating all new SAs before
+	deleting the old ones. This behavior can be beneficial to avoid connectivity
+	gaps during reauthentication, but requires support for overlapping SAs by
+	the peer. strongSwan can handle such overlapping SAs since version 5.3.0.
+
 charon.multiple_authentication = yes
 	Enable multiple authentication exchanges (RFC 4739).
 
@@ -277,6 +298,17 @@ charon.send_delay_type = 0
 charon.send_vendor_id = no
 	Send strongSwan vendor ID payload
 
+charon.signature_authentication = yes
+	Whether to enable Signature Authentication as per RFC 7427.
+
+charon.signature_authentication_constraints = yes
+	Whether to enable constraints against IKEv2 signature schemes.
+
+	If enabled, signature schemes configured in _rightauth_, in addition to
+	getting used as constraints against signature schemes employed in the
+	certificate chain, are also used as constraints against the signature scheme
+	used by peers during IKEv2.
+
 charon.start-scripts {}
 	Section containing a list of scripts (name = path) that are executed when
 	the daemon is started.
diff --git a/conf/plugins/bliss.conf b/conf/plugins/bliss.conf
new file mode 100644
index 0000000..e35c27d
--- /dev/null
+++ b/conf/plugins/bliss.conf
@@ -0,0 +1,11 @@
+bliss {
+
+    # Whether to load the plugin. Can also be an integer to increase the
+    # priority of this plugin.
+    load = yes
+
+    # Use the enhanced BLISS-B key generation and signature algorithm.
+    # use_bliss_b = yes
+
+}
+
diff --git a/conf/plugins/bliss.opt b/conf/plugins/bliss.opt
new file mode 100644
index 0000000..0983da0
--- /dev/null
+++ b/conf/plugins/bliss.opt
@@ -0,0 +1,2 @@
+charon.plugins.bliss.use_bliss_b = yes
+	Use the enhanced BLISS-B key generation and signature algorithm.
diff --git a/conf/plugins/forecast.conf b/conf/plugins/forecast.conf
new file mode 100644
index 0000000..79edb4b
--- /dev/null
+++ b/conf/plugins/forecast.conf
@@ -0,0 +1,17 @@
+forecast {
+
+    # Multicast groups to join locally, allowing forwarding of them.
+    # groups = 224.0.0.1,224.0.0.22,224.0.0.251,224.0.0.252,239.255.255.250
+
+    # Local interface to listen for broadcasts to forward.
+    # interface =
+
+    # Whether to load the plugin. Can also be an integer to increase the
+    # priority of this plugin.
+    load = yes
+
+    # CHILD_SA configurations names to perform multi/broadcast reinjection.
+    # reinject =
+
+}
+
diff --git a/conf/plugins/forecast.opt b/conf/plugins/forecast.opt
new file mode 100644
index 0000000..444cced
--- /dev/null
+++ b/conf/plugins/forecast.opt
@@ -0,0 +1,29 @@
+charon.plugins.forecast.interface =
+	Local interface to listen for broadcasts to forward.
+
+	Name of the local interface to listen for broadcasts messages to forward.
+	If no interface is configured, the first usable interface is used, which
+	is usually just fine for single-homed hosts. If your host has multiple
+	interfaces, set this option to the local LAN interface you want to forward
+	broadcasts from/to.
+
+charon.plugins.forecast.reinject =
+	CHILD_SA configurations names to perform multi/broadcast reinjection.
+
+	Comma separated list of CHILD_SA configuration names for which to perform
+	multi/broadcast reinjection. For clients connecting over such a
+	configuration, any multi/broadcast received over the tunnel gets reinjected
+	to all active tunnels. This makes the broadcasts visible to other peers,
+	and for examples allows clients to see others shares. If disabled,
+	multi/broadcast messages received over a tunnel are injected to the local
+	network only, but not to other IPsec clients.
+
+charon.plugins.forecast.groups = 224.0.0.1,224.0.0.22,224.0.0.251,224.0.0.252,239.255.255.250
+	Multicast groups to join locally, allowing forwarding of them.
+
+	Comma separated list of multicast groups to join locally. The local host
+	receives and forwards packets in the local LAN for joined multicast groups
+	only. Packets matching the list of multicast groups get forwarded to
+	connected clients. The default group includes host multicasts, IGMP, mDNS,
+	LLMNR and SSDP/WS-Discovery, and is usually a good choice for Windows
+	clients.
diff --git a/conf/plugins/imc-attestation.opt b/conf/plugins/imc-attestation.opt
index 9b60b9e..7a40bc9 100644
--- a/conf/plugins/imc-attestation.opt
+++ b/conf/plugins/imc-attestation.opt
@@ -18,3 +18,21 @@ libimcv.plugins.imc-attestation.use_quote2 = yes
 
 libimcv.plugins.imc-attestation.pcr_info = no
 	Whether to send pcr_before and pcr_after info.
+
+libimcv.plugins.imc-attestation.pcr17_before =
+        PCR17 value before measurement.
+
+libimcv.plugins.imc-attestation.pcr17_meas =
+        Dummy measurement value extended into PCR17 if the TBOOT log is not available.
+
+libimcv.plugins.imc-attestation.pcr17_after =
+        PCR17 value after measurement.
+
+libimcv.plugins.imc-attestation.pcr18_before =
+        PCR18 value before measurement.
+
+libimcv.plugins.imc-attestation.pcr18_meas =
+       Dummy measurement value extended into PCR17 if the TBOOT log is not available. 
+
+libimcv.plugins.imc-attestation.pcr18_after =
+        PCR18 value after measurement.
diff --git a/conf/plugins/imv-attestation.opt b/conf/plugins/imv-attestation.opt
index 3ad5162..f552250 100644
--- a/conf/plugins/imv-attestation.opt
+++ b/conf/plugins/imv-attestation.opt
@@ -12,21 +12,3 @@ libimcv.plugins.imv-attestation.hash_algorithm = sha256
 
 libimcv.plugins.imv-attestation.min_nonce_len = 0
 	DH minimum nonce length.
-
-libimcv.plugins.imc-attestation.pcr17_after
-	Dummy data if the TBOOT log is not retrieved.
-
-libimcv.plugins.imc-attestation.pcr17_before
-	Dummy data if the TBOOT log is not retrieved.
-
-libimcv.plugins.imc-attestation.pcr17_meas
-	Dummy data if the TBOOT log is not retrieved.
-
-libimcv.plugins.imc-attestation.pcr18_after
-	Dummy data if the TBOOT log is not retrieved.
-
-libimcv.plugins.imc-attestation.pcr18_before
-	Dummy data if the TBOOT log is not retrieved.
-
-libimcv.plugins.imc-attestation.pcr18_meas
-	Dummy data if the TBOOT log is not retrieved.
diff --git a/conf/plugins/kernel-netlink.conf b/conf/plugins/kernel-netlink.conf
index f05f486..723bf0a 100644
--- a/conf/plugins/kernel-netlink.conf
+++ b/conf/plugins/kernel-netlink.conf
@@ -4,6 +4,9 @@ kernel-netlink {
     # routing table.
     # fwmark =
 
+    # Whether to ignore errors potentially resulting from a retransmission.
+    # ignore_retransmit_errors = no
+
     # Whether to load the plugin. Can also be an integer to increase the
     # priority of this plugin.
     load = yes
@@ -14,6 +17,21 @@ kernel-netlink {
     # MTU to set on installed routes, 0 to disable.
     # mtu = 0
 
+    # Whether to perform concurrent Netlink ROUTE queries on a single socket.
+    # parallel_route = no
+
+    # Whether to perform concurrent Netlink XFRM queries on a single socket.
+    # parallel_xfrm = no
+
+    # Whether to always use XFRM_MSG_UPDPOLICY to install policies.
+    # policy_update = no
+
+    # Whether to use port or socket based IKE XFRM bypass policies.
+    # port_bypass = no
+
+    # Number of Netlink message retransmissions to send on timeout.
+    # retries = 0
+
     # Whether to trigger roam events when interfaces, addresses or routes
     # change.
     # roam_events = yes
@@ -22,6 +40,9 @@ kernel-netlink {
     # mode IPsec SAs in the kernel.
     # set_proto_port_transport_sa = no
 
+    # Netlink message retransmission timeout, 0 to disable retransmissions.
+    # timeout = 0
+
     # Lifetime of XFRM acquire state in kernel.
     # xfrm_acq_expires = 165
 
diff --git a/conf/plugins/kernel-netlink.opt b/conf/plugins/kernel-netlink.opt
index 7d44581..800ba20 100644
--- a/conf/plugins/kernel-netlink.opt
+++ b/conf/plugins/kernel-netlink.opt
@@ -13,6 +13,29 @@ charon.plugins.kernel-netlink.mss = 0
 charon.plugins.kernel-netlink.mtu = 0
 	MTU to set on installed routes, 0 to disable.
 
+charon.plugins.kernel-netlink.parallel_route = no
+	Whether to perform concurrent Netlink ROUTE queries on a single socket.
+
+	Whether to perform concurrent Netlink ROUTE queries on a single socket.
+	While parallel queries can improve throughput, it has more overhead. On
+	vanilla Linux, DUMP queries fail with EBUSY and must be retried, further
+	decreasing performance.
+
+charon.plugins.kernel-netlink.parallel_xfrm = no
+	Whether to perform concurrent Netlink XFRM queries on a single socket.
+
+charon.plugins.kernel-netlink.policy_update = no
+	Whether to always use XFRM_MSG_UPDPOLICY to install policies.
+
+charon.plugins.kernel-netlink.port_bypass = no
+	Whether to use port or socket based IKE XFRM bypass policies.
+
+	Whether to use port or socket based IKE XFRM bypass policies.
+	IKE bypass policies are used to exempt IKE traffic from XFRM processing.
+	The default socket based policies are directly tied to the IKE UDP sockets,
+	port based policies use global XFRM bypass policies for the used IKE UDP
+	ports.
+
 charon.plugins.kernel-netlink.roam_events = yes
 	Whether to trigger roam events when interfaces, addresses or routes change.
 
@@ -25,6 +48,15 @@ charon.plugins.kernel-netlink.set_proto_port_transport_sa = no
 	traffic, it also prevents the use of a single IPsec SA by more than one
 	traffic selector.
 
+charon.plugins.kernel-netlink.retries = 0
+	Number of Netlink message retransmissions to send on timeout.
+
+charon.plugins.kernel-netlink.timeout = 0
+	Netlink message retransmission timeout, 0 to disable retransmissions.
+
+charon.plugins.kernel-netlink.ignore_retransmit_errors = no
+	Whether to ignore errors potentially resulting from a retransmission.
+
 charon.plugins.kernel-netlink.xfrm_acq_expires = 165
 	Lifetime of XFRM acquire state in kernel.
 
diff --git a/conf/plugins/kernel-pfkey.conf b/conf/plugins/kernel-pfkey.conf
new file mode 100644
index 0000000..2d4733e
--- /dev/null
+++ b/conf/plugins/kernel-pfkey.conf
@@ -0,0 +1,11 @@
+kernel-pfkey {
+
+    # Size of the receive buffer for the event socket (0 for default size).
+    # events_buffer_size = 0
+
+    # Whether to load the plugin. Can also be an integer to increase the
+    # priority of this plugin.
+    load = yes
+
+}
+
diff --git a/conf/plugins/kernel-pfkey.opt b/conf/plugins/kernel-pfkey.opt
new file mode 100644
index 0000000..ec05215
--- /dev/null
+++ b/conf/plugins/kernel-pfkey.opt
@@ -0,0 +1,7 @@
+charon.plugins.kernel-pfkey.events_buffer_size = 0
+	Size of the receive buffer for the event socket (0 for default size).
+
+	Size of the receive buffer for the event socket (0 for default size).
+	Because events are received asynchronously installing e.g. lots of policies
+	may require a larger buffer than the default on certain platforms in order
+	to receive all messages.
diff --git a/conf/plugins/tnccs-20.conf b/conf/plugins/tnccs-20.conf
index 9a57ee1..e8c45ae 100644
--- a/conf/plugins/tnccs-20.conf
+++ b/conf/plugins/tnccs-20.conf
@@ -10,5 +10,18 @@ tnccs-20 {
     # Maximum size of a PA-TNC message (upper limit via PT-EAP = 65497).
     # max_message_size = 65490
 
+    # Enable PB-TNC mutual protocol.
+    # mutual = no
+
+    tests {
+
+        # Send an unsupported PB-TNC message type with the NOSKIP flag set.
+        # pb_tnc_noskip = no
+
+        # Send a PB-TNC batch with a modified PB-TNC version.
+        # pb_tnc_version = 2
+
+    }
+
 }
 
diff --git a/conf/plugins/tnccs-20.opt b/conf/plugins/tnccs-20.opt
index b15bc3f..8d16d1c 100644
--- a/conf/plugins/tnccs-20.opt
+++ b/conf/plugins/tnccs-20.opt
@@ -3,3 +3,12 @@ charon.plugins.tnccs-20.max_batch_size = 65522
 
 charon.plugins.tnccs-20.max_message_size = 65490
 	Maximum size of a PA-TNC message (upper limit via PT-EAP = 65497).
+
+charon.plugins.tnccs-20.mutual = no
+        Enable PB-TNC mutual protocol.
+
+charon.plugins.tnccs-20.tests.pb_tnc_noskip = no
+        Send an unsupported PB-TNC message type with the NOSKIP flag set.
+
+charon.plugins.tnccs-20.tests.pb_tnc_version = 2
+        Send a PB-TNC batch with a modified PB-TNC version.
diff --git a/conf/strongswan.conf.5.main b/conf/strongswan.conf.5.main
index 28f6b12..b6db9c9 100644
--- a/conf/strongswan.conf.5.main
+++ b/conf/strongswan.conf.5.main
@@ -198,6 +198,15 @@ keys, which is discouraged due to security concerns (offline attacks on the
 openly transmitted hash of the PSK).
 
 .TP
+.BR charon.ignore_acquire_ts " [no]"
+If this is disabled the traffic selectors from the kernel's acquire events,
+which are derived from the triggering packet, are prepended to the traffic
+selectors from the configuration for IKEv2 connection. By enabling this, such
+specific traffic selectors will be ignored and only the ones in the config will
+be sent. This always happens for IKEv1 connections as the protocol only supports
+one set of traffic selectors per CHILD_SA.
+
+.TP
 .BR charon.ignore_routing_tables " []"
 A space\-separated list of routing tables to be excluded from route lookups.
 
@@ -322,6 +331,15 @@ preserved. Enabled plugins not found in that list are ordered alphabetically
 before other plugins with the same priority.
 
 .TP
+.BR charon.make_before_break " [no]"
+Initiate IKEv2 reauthentication with a make\-before\-break instead of a
+break\-before\-make scheme. Make\-before\-break uses overlapping IKE and CHILD_SA
+during reauthentication by first recreating all new SAs before deleting the old
+ones. This behavior can be beneficial to avoid connectivity gaps during
+reauthentication, but requires support for overlapping SAs by the peer.
+strongSwan can handle such overlapping SAs since version 5.3.0.
+
+.TP
 .BR charon.max_packet " [10000]"
 Maximum packet size accepted by charon.
 
@@ -374,6 +392,10 @@ sure to adjust the permissions of the config file accordingly.
 Enable logging of SQL IP pool leases.
 
 .TP
+.BR charon.plugins.bliss.use_bliss_b " [yes]"
+Use the enhanced BLISS\-B key generation and signature algorithm.
+
+.TP
 .BR charon.plugins.certexpire.csv.cron " []"
 Cron style string specifying CSV export times.
 
@@ -762,6 +784,31 @@ Remote IKE identity.
 Remote EAP or XAuth identity, if used.
 
 .TP
+.BR charon.plugins.forecast.groups " [224.0.0.1,224.0.0.22,224.0.0.251,224.0.0.252,239.255.255.250]"
+Comma separated list of multicast groups to join locally. The local host
+receives and forwards packets in the local LAN for joined multicast groups only.
+Packets matching the list of multicast groups get forwarded to connected
+clients. The default group includes host multicasts, IGMP, mDNS, LLMNR and
+SSDP/WS\-Discovery, and is usually a good choice for Windows clients.
+
+.TP
+.BR charon.plugins.forecast.interface " []"
+Name of the local interface to listen for broadcasts messages to forward. If no
+interface is configured, the first usable interface is used, which is usually
+just fine for single\-homed hosts. If your host has multiple interfaces, set this
+option to the local LAN interface you want to forward broadcasts from/to.
+
+.TP
+.BR charon.plugins.forecast.reinject " []"
+Comma separated list of CHILD_SA configuration names for which to perform
+multi/broadcast reinjection. For clients connecting over such a configuration,
+any multi/broadcast received over the tunnel gets reinjected to all active
+tunnels. This makes the broadcasts visible to other peers, and for examples
+allows clients to see others shares. If disabled, multi/broadcast messages
+received over a tunnel are injected to the local network only, but not to other
+IPsec clients.
+
+.TP
 .BR charon.plugins.gcrypt.quick_random " [no]"
 Use faster random numbers in gcrypt; for testing only, produces weak keys!
 
@@ -812,6 +859,10 @@ table. The format is [!]mark[/mask], where the optional exclamation mark inverts
 the meaning (i.e. the rule only applies to packets that don't match the mark).
 
 .TP
+.BR charon.plugins.kernel-netlink.ignore_retransmit_errors " [no]"
+Whether to ignore errors potentially resulting from a retransmission.
+
+.TP
 .BR charon.plugins.kernel-netlink.mss " [0]"
 MSS to set on installed routes, 0 to disable.
 
@@ -820,6 +871,32 @@ MSS to set on installed routes, 0 to disable.
 MTU to set on installed routes, 0 to disable.
 
 .TP
+.BR charon.plugins.kernel-netlink.parallel_route " [no]"
+Whether to perform concurrent Netlink ROUTE queries on a single socket. While
+parallel queries can improve throughput, it has more overhead. On vanilla Linux,
+DUMP queries fail with EBUSY and must be retried, further decreasing
+performance.
+
+.TP
+.BR charon.plugins.kernel-netlink.parallel_xfrm " [no]"
+Whether to perform concurrent Netlink XFRM queries on a single socket.
+
+.TP
+.BR charon.plugins.kernel-netlink.policy_update " [no]"
+Whether to always use XFRM_MSG_UPDPOLICY to install policies.
+
+.TP
+.BR charon.plugins.kernel-netlink.port_bypass " [no]"
+Whether to use port or socket based IKE XFRM bypass policies. IKE bypass
+policies are used to exempt IKE traffic from XFRM processing. The default socket
+based policies are directly tied to the IKE UDP sockets, port based policies use
+global XFRM bypass policies for the used IKE UDP ports.
+
+.TP
+.BR charon.plugins.kernel-netlink.retries " [0]"
+Number of Netlink message retransmissions to send on timeout.
+
+.TP
 .BR charon.plugins.kernel-netlink.roam_events " [yes]"
 Whether to trigger roam events when interfaces, addresses or routes change.
 
@@ -830,12 +907,23 @@ IPsec SAs in the kernel. While doing so enforces policies for inbound traffic,
 it also prevents the use of a single IPsec SA by more than one traffic selector.
 
 .TP
+.BR charon.plugins.kernel-netlink.timeout " [0]"
+Netlink message retransmission timeout, 0 to disable retransmissions.
+
+.TP
 .BR charon.plugins.kernel-netlink.xfrm_acq_expires " [165]"
 Lifetime of XFRM acquire state in kernel. The value gets written to
 /proc/sys/net/core/xfrm_acq_expires. Indirectly controls the delay of XFRM
 acquire messages sent.
 
 .TP
+.BR charon.plugins.kernel-pfkey.events_buffer_size " [0]"
+Size of the receive buffer for the event socket (0 for default size). Because
+events are received asynchronously installing e.g. lots of policies may require
+a larger buffer than the default on certain platforms in order to receive all
+messages.
+
+.TP
 .BR charon.plugins.kernel-pfroute.vip_wait " [1000]"
 Time in ms to wait until virtual IP addresses appear/disappear before failing.
 
@@ -1291,6 +1379,18 @@ Maximum size of a PB\-TNC batch (upper limit via PT\-EAP = 65529).
 Maximum size of a PA\-TNC message (upper limit via PT\-EAP = 65497).
 
 .TP
+.BR charon.plugins.tnccs-20.mutual " [no]"
+Enable PB\-TNC mutual protocol.
+
+.TP
+.BR charon.plugins.tnccs-20.tests.pb_tnc_noskip " [no]"
+Send an unsupported PB\-TNC message type with the NOSKIP flag set.
+
+.TP
+.BR charon.plugins.tnccs-20.tests.pb_tnc_version " [2]"
+Send a PB\-TNC batch with a modified PB\-TNC version.
+
+.TP
 .BR charon.plugins.unbound.dlv_anchors " []"
 File to read trusted keys for DLV (DNSSEC Lookaside Validation) from. It uses
 the same format as
@@ -1444,6 +1544,19 @@ Specific IKEv2 message type to delay, 0 for any.
 Send strongSwan vendor ID payload
 
 .TP
+.BR charon.signature_authentication " [yes]"
+Whether to enable Signature Authentication as per RFC 7427.
+
+.TP
+.BR charon.signature_authentication_constraints " [yes]"
+If enabled, signature schemes configured in
+.RI "" "rightauth" ","
+in addition to getting
+used as constraints against signature schemes employed in the certificate chain,
+are also used as constraints against the signature scheme used by peers during
+IKEv2.
+
+.TP
 .B charon.start-scripts
 .br
 Section containing a list of scripts (name = path) that are executed when the
@@ -1581,27 +1694,27 @@ DH nonce length.
 
 .TP
 .BR libimcv.plugins.imc-attestation.pcr17_after " []"
-Dummy data if the TBOOT log is not retrieved.
+PCR17 value after measurement.
 
 .TP
 .BR libimcv.plugins.imc-attestation.pcr17_before " []"
-Dummy data if the TBOOT log is not retrieved.
+PCR17 value before measurement.
 
 .TP
 .BR libimcv.plugins.imc-attestation.pcr17_meas " []"
-Dummy data if the TBOOT log is not retrieved.
+Dummy measurement value extended into PCR17 if the TBOOT log is not available.
 
 .TP
 .BR libimcv.plugins.imc-attestation.pcr18_after " []"
-Dummy data if the TBOOT log is not retrieved.
+PCR18 value after measurement.
 
 .TP
 .BR libimcv.plugins.imc-attestation.pcr18_before " []"
-Dummy data if the TBOOT log is not retrieved.
+PCR18 value before measurement.
 
 .TP
 .BR libimcv.plugins.imc-attestation.pcr18_meas " []"
-Dummy data if the TBOOT log is not retrieved.
+Dummy measurement value extended into PCR17 if the TBOOT log is not available.
 
 .TP
 .BR libimcv.plugins.imc-attestation.pcr_info " [no]"
diff --git a/configure b/configure
index ee7d4cb..811e452 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.2.1.
+# Generated by GNU Autoconf 2.69 for strongSwan 5.3.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.2.1'
-PACKAGE_STRING='strongSwan 5.2.1'
+PACKAGE_VERSION='5.3.0'
+PACKAGE_STRING='strongSwan 5.3.0'
 PACKAGE_BUGREPORT=''
 PACKAGE_URL=''
 
@@ -633,6 +633,10 @@ am__EXEEXT_TRUE
 LTLIBOBJS
 LIBOBJS
 strongswan_options
+USE_PY_TEST_FALSE
+USE_PY_TEST_TRUE
+USE_PYTHON_EGGS_FALSE
+USE_PYTHON_EGGS_TRUE
 USE_RUBY_GEMS_FALSE
 USE_RUBY_GEMS_TRUE
 USE_LEGACY_SYSTEMD_FALSE
@@ -727,8 +731,6 @@ USE_LOCK_PROFILER_FALSE
 USE_LOCK_PROFILER_TRUE
 USE_LEAK_DETECTIVE_FALSE
 USE_LEAK_DETECTIVE_TRUE
-USE_RESOLVE_FALSE
-USE_RESOLVE_TRUE
 USE_KERNEL_PFROUTE_FALSE
 USE_KERNEL_PFROUTE_TRUE
 USE_KERNEL_PFKEY_FALSE
@@ -739,12 +741,18 @@ USE_ATTR_SQL_FALSE
 USE_ATTR_SQL_TRUE
 USE_ATTR_FALSE
 USE_ATTR_TRUE
+USE_RESOLVE_FALSE
+USE_RESOLVE_TRUE
 USE_UNITY_FALSE
 USE_UNITY_TRUE
 USE_ADDRBLOCK_FALSE
 USE_ADDRBLOCK_TRUE
 USE_FARP_FALSE
 USE_FARP_TRUE
+USE_FORECAST_FALSE
+USE_FORECAST_TRUE
+USE_CONNMARK_FALSE
+USE_CONNMARK_TRUE
 USE_SOCKET_WIN_FALSE
 USE_SOCKET_WIN_TRUE
 USE_SOCKET_DYNAMIC_FALSE
@@ -861,8 +869,6 @@ USE_HA_FALSE
 USE_HA_TRUE
 USE_LOAD_TESTER_FALSE
 USE_LOAD_TESTER_TRUE
-USE_UNIT_TESTS_FALSE
-USE_UNIT_TESTS_TRUE
 USE_DHCP_FALSE
 USE_DHCP_TRUE
 USE_UPDOWN_FALSE
@@ -893,6 +899,8 @@ USE_VICI_FALSE
 USE_VICI_TRUE
 USE_STROKE_FALSE
 USE_STROKE_TRUE
+USE_BLISS_FALSE
+USE_BLISS_TRUE
 USE_NTRU_FALSE
 USE_NTRU_TRUE
 USE_AF_ALG_FALSE
@@ -985,6 +993,8 @@ USE_UNBOUND_FALSE
 USE_UNBOUND_TRUE
 USE_WINHTTP_FALSE
 USE_WINHTTP_TRUE
+USE_FILES_FALSE
+USE_FILES_TRUE
 USE_CURL_FALSE
 USE_CURL_TRUE
 USE_TEST_VECTORS_FALSE
@@ -1005,6 +1015,9 @@ attest_plugins
 pool_plugins
 starter_plugins
 charon_plugins
+PY_TEST
+PYTHONEGGINSTALLDIR
+EASY_INSTALL
 RUBYGEMDIR
 GEM
 COVERAGE_LDFLAGS
@@ -1017,6 +1030,8 @@ USE_DEV_HEADERS_FALSE
 USE_DEV_HEADERS_TRUE
 UNWINDLIB
 BFDLIB
+libiptc_LIBS
+libiptc_CFLAGS
 nm_LIBS
 nm_CFLAGS
 pcsclite_LIBS
@@ -1238,6 +1253,7 @@ with_mpz_powm_sec
 with_dev_headers
 with_printf_hooks
 with_rubygemdir
+with_pythoneggdir
 with_systemdsystemunitdir
 with_user
 with_group
@@ -1245,6 +1261,7 @@ with_charon_udp_port
 with_charon_natt_port
 enable_aes
 enable_af_alg
+enable_bliss
 enable_blowfish
 enable_ccm
 enable_cmac
@@ -1278,6 +1295,7 @@ enable_pubkey
 enable_sshkey
 enable_x509
 enable_curl
+enable_files
 enable_ldap
 enable_soup
 enable_unbound
@@ -1358,6 +1376,8 @@ enable_tnccs_20
 enable_tnccs_dynamic
 enable_android_log
 enable_certexpire
+enable_connmark
+enable_forecast
 enable_duplicheck
 enable_error_notify
 enable_farp
@@ -1369,7 +1389,6 @@ enable_maemo
 enable_radattr
 enable_systime_fix
 enable_test_vectors
-enable_unit_tester
 enable_updown
 enable_aikgen
 enable_charon
@@ -1398,6 +1417,7 @@ enable_load_warning
 enable_mediation
 enable_unwind_backtraces
 enable_ruby_gems
+enable_python_eggs
 enable_coverage
 enable_leak_detective
 enable_lock_profiler
@@ -1446,7 +1466,9 @@ maemo_LIBS
 pcsclite_CFLAGS
 pcsclite_LIBS
 nm_CFLAGS
-nm_LIBS'
+nm_LIBS
+libiptc_CFLAGS
+libiptc_LIBS'
 
 
 # Initialize some variables set by options.
@@ -1987,7 +2009,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.2.1 to adapt to many kinds of systems.
+\`configure' configures strongSwan 5.3.0 to adapt to many kinds of systems.
 
 Usage: $0 [OPTION]... [VAR=VALUE]...
 
@@ -2057,7 +2079,7 @@ fi
 
 if test -n "$ac_init_help"; then
   case $ac_init_help in
-     short | recursive ) echo "Configuration of strongSwan 5.2.1:";;
+     short | recursive ) echo "Configuration of strongSwan 5.3.0:";;
    esac
   cat <<\_ACEOF
 
@@ -2069,6 +2091,7 @@ Optional Features:
   --disable-silent-rules  verbose build output (undo: "make V=0")
   --disable-aes           disable AES software implementation plugin.
   --enable-af-alg         enable AF_ALG crypto interface to Linux Crypto API.
+  --enable-bliss          enable BLISS software implementation plugin.
   --enable-blowfish       enable Blowfish software implementation plugin.
   --enable-ccm            enables the CCM AEAD wrapper crypto plugin.
   --disable-cmac          disable CMAC crypto implementation plugin.
@@ -2105,6 +2128,7 @@ Optional Features:
   --disable-x509          disable X509 certificate implementation plugin.
   --enable-curl           enable CURL fetcher plugin to fetch files via
                           libcurl. Requires libcurl.
+  --enable-files          enable simple file:// URI fetcher.
   --enable-ldap           enable LDAP fetching plugin to fetch files via
                           libldap. Requires openLDAP.
   --enable-soup           enable soup fetcher plugin to fetch from HTTP via
@@ -2210,6 +2234,10 @@ Optional Features:
   --enable-android-log    enable Android specific logger plugin.
   --enable-certexpire     enable CSV export of expiration dates of used
                           certificates.
+  --enable-connmark       enable connmark plugin using conntrack based marks
+                          to select return path SA.
+  --enable-forecast       enable forecast plugin forwarding
+                          broadcast/multicast messages.
   --enable-duplicheck     advanced duplicate checking plugin using liveness
                           checks.
   --enable-error-notify   enable error notification plugin.
@@ -2227,7 +2255,6 @@ Optional Features:
   --enable-systime-fix    enable plugin to handle cert lifetimes with invalid
                           system time gracefully.
   --enable-test-vectors   enable plugin providing crypto test vectors.
-  --enable-unit-tester    enable unit tests on IKEv2 daemon startup.
   --disable-updown        disable updown firewall script plugin.
   --enable-aikgen         enable AIK generator.
   --disable-charon        disable the IKEv1/IKEv2 keying daemon charon.
@@ -2267,6 +2294,7 @@ Optional Features:
                           use libunwind to create backtraces for memory leaks
                           and segfaults.
   --enable-ruby-gems      enable installation of provided ruby gems.
+  --enable-python-eggs    enable installation of provided python eggs.
   --enable-coverage       enable lcov coverage report generation.
   --enable-leak-detective enable malloc hooks to find memory leaks.
   --enable-lock-profiler  enable lock/mutex profiling code.
@@ -2343,6 +2371,8 @@ Optional Packages:
                           (default: auto).
   --with-rubygemdir=arg   path to install ruby gems to (default: "gem
                           environment gemdir").
+  --with-pythoneggdir=arg path to install python eggs to to (default: "main
+                          site-packages directory").
   --with-systemdsystemunitdir=arg
                           directory for systemd service files (default:
                           $systemdsystemunitdir_default).
@@ -2411,6 +2441,10 @@ Some influential environment variables:
               linker flags for pcsclite, overriding pkg-config
   nm_CFLAGS   C compiler flags for nm, overriding pkg-config
   nm_LIBS     linker flags for nm, overriding pkg-config
+  libiptc_CFLAGS
+              C compiler flags for libiptc, overriding pkg-config
+  libiptc_LIBS
+              linker flags for libiptc, overriding pkg-config
 
 Use these variables to override the choices made by `configure' or to help
 it to find libraries and programs with nonstandard names/locations.
@@ -2478,7 +2512,7 @@ fi
 test -n "$ac_init_help" && exit $ac_status
 if $ac_init_version; then
   cat <<\_ACEOF
-strongSwan configure 5.2.1
+strongSwan configure 5.3.0
 generated by GNU Autoconf 2.69
 
 Copyright (C) 2012 Free Software Foundation, Inc.
@@ -3000,7 +3034,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.2.1, which was
+It was created by strongSwan $as_me 5.3.0, which was
 generated by GNU Autoconf 2.69.  Invocation command line was
 
   $ $0 $@
@@ -3863,7 +3897,7 @@ fi
 
 # Define the identity of the package.
  PACKAGE='strongswan'
- VERSION='5.2.1'
+ VERSION='5.3.0'
 
 
 cat >>confdefs.h <<_ACEOF
@@ -4595,6 +4629,16 @@ fi
 
 
 
+# Check whether --with-pythoneggdir was given.
+if test "${with_pythoneggdir+set}" = set; then :
+  withval=$with_pythoneggdir; pythoneggdir="$withval"
+else
+  pythoneggdir="main site-packages directory"
+
+fi
+
+
+
 if test -n "$PKG_CONFIG"; then
 	systemdsystemunitdir_default=$($PKG_CONFIG --variable=systemdsystemunitdir systemd)
 fi
@@ -4738,6 +4782,22 @@ fi
 
 	disabled_by_default=${disabled_by_default}" af_alg"
 
+# Check whether --enable-bliss was given.
+if test "${enable_bliss+set}" = set; then :
+  enableval=$enable_bliss; bliss_given=true
+		if test x$enableval = xyes; then
+			bliss=true
+		 else
+			bliss=false
+		fi
+else
+  bliss=false
+		bliss_given=false
+
+fi
+
+	disabled_by_default=${disabled_by_default}" bliss"
+
 # Check whether --enable-blowfish was given.
 if test "${enable_blowfish+set}" = set; then :
   enableval=$enable_blowfish; blowfish_given=true
@@ -5268,6 +5328,22 @@ fi
 
 	disabled_by_default=${disabled_by_default}" curl"
 
+# Check whether --enable-files was given.
+if test "${enable_files+set}" = set; then :
+  enableval=$enable_files; files_given=true
+		if test x$enableval = xyes; then
+			files=true
+		 else
+			files=false
+		fi
+else
+  files=false
+		files_given=false
+
+fi
+
+	disabled_by_default=${disabled_by_default}" files"
+
 # Check whether --enable-ldap was given.
 if test "${enable_ldap+set}" = set; then :
   enableval=$enable_ldap; ldap_given=true
@@ -6555,6 +6631,38 @@ fi
 
 	disabled_by_default=${disabled_by_default}" certexpire"
 
+# Check whether --enable-connmark was given.
+if test "${enable_connmark+set}" = set; then :
+  enableval=$enable_connmark; connmark_given=true
+		if test x$enableval = xyes; then
+			connmark=true
+		 else
+			connmark=false
+		fi
+else
+  connmark=false
+		connmark_given=false
+
+fi
+
+	disabled_by_default=${disabled_by_default}" connmark"
+
+# Check whether --enable-forecast was given.
+if test "${enable_forecast+set}" = set; then :
+  enableval=$enable_forecast; forecast_given=true
+		if test x$enableval = xyes; then
+			forecast=true
+		 else
+			forecast=false
+		fi
+else
+  forecast=false
+		forecast_given=false
+
+fi
+
+	disabled_by_default=${disabled_by_default}" forecast"
+
 # Check whether --enable-duplicheck was given.
 if test "${enable_duplicheck+set}" = set; then :
   enableval=$enable_duplicheck; duplicheck_given=true
@@ -6731,22 +6839,6 @@ fi
 
 	disabled_by_default=${disabled_by_default}" test_vectors"
 
-# Check whether --enable-unit-tester was given.
-if test "${enable_unit_tester+set}" = set; then :
-  enableval=$enable_unit_tester; unit_tester_given=true
-		if test x$enableval = xyes; then
-			unit_tester=true
-		 else
-			unit_tester=false
-		fi
-else
-  unit_tester=false
-		unit_tester_given=false
-
-fi
-
-	disabled_by_default=${disabled_by_default}" unit_tester"
-
 # Check whether --enable-updown was given.
 if test "${enable_updown+set}" = set; then :
   enableval=$enable_updown; updown_given=true
@@ -7197,6 +7289,22 @@ fi
 
 	disabled_by_default=${disabled_by_default}" ruby_gems"
 
+# Check whether --enable-python-eggs was given.
+if test "${enable_python_eggs+set}" = set; then :
+  enableval=$enable_python_eggs; python_eggs_given=true
+		if test x$enableval = xyes; then
+			python_eggs=true
+		 else
+			python_eggs=false
+		fi
+else
+  python_eggs=false
+		python_eggs_given=false
+
+fi
+
+	disabled_by_default=${disabled_by_default}" python_eggs"
+
 # compile options
 # Check whether --enable-coverage was given.
 if test "${enable_coverage+set}" = set; then :
@@ -20878,6 +20986,102 @@ fi
 
 fi
 
+if test x$connmark = xtrue -o x$forecast = xtrue; then
+
+pkg_failed=no
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for libiptc" >&5
+$as_echo_n "checking for libiptc... " >&6; }
+
+if test -n "$libiptc_CFLAGS"; then
+    pkg_cv_libiptc_CFLAGS="$libiptc_CFLAGS"
+ elif test -n "$PKG_CONFIG"; then
+    if test -n "$PKG_CONFIG" && \
+    { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libiptc\""; } >&5
+  ($PKG_CONFIG --exists --print-errors "libiptc") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; then
+  pkg_cv_libiptc_CFLAGS=`$PKG_CONFIG --cflags "libiptc" 2>/dev/null`
+		      test "x$?" != "x0" && pkg_failed=yes
+else
+  pkg_failed=yes
+fi
+ else
+    pkg_failed=untried
+fi
+if test -n "$libiptc_LIBS"; then
+    pkg_cv_libiptc_LIBS="$libiptc_LIBS"
+ elif test -n "$PKG_CONFIG"; then
+    if test -n "$PKG_CONFIG" && \
+    { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libiptc\""; } >&5
+  ($PKG_CONFIG --exists --print-errors "libiptc") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; then
+  pkg_cv_libiptc_LIBS=`$PKG_CONFIG --libs "libiptc" 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
+	        libiptc_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "libiptc" 2>&1`
+        else
+	        libiptc_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "libiptc" 2>&1`
+        fi
+	# Put the nasty error message in config.log where it belongs
+	echo "$libiptc_PKG_ERRORS" >&5
+
+	as_fn_error $? "Package requirements (libiptc) were not met:
+
+$libiptc_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 libiptc_CFLAGS
+and libiptc_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 libiptc_CFLAGS
+and libiptc_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
+	libiptc_CFLAGS=$pkg_cv_libiptc_CFLAGS
+	libiptc_LIBS=$pkg_cv_libiptc_LIBS
+        { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+fi
+
+
+fi
+
 if test x$capabilities = xnative; then
 	{ $as_echo "$as_me:${as_lineno-$LINENO}: Usage of the native Linux capabilities interface is deprecated, use libcap instead" >&5
 $as_echo "$as_me: Usage of the native Linux capabilities interface is deprecated, use libcap instead" >&6;}
@@ -21326,6 +21530,101 @@ fi
 
 fi
 
+if test x$python_eggs = xtrue; then
+	# Extract the first word of "easy_install", so it can be a program name with args.
+set dummy easy_install; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_path_EASY_INSTALL+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  case $EASY_INSTALL in
+  [\\/]* | ?:[\\/]*)
+  ac_cv_path_EASY_INSTALL="$EASY_INSTALL" # Let the user override the test with a path.
+  ;;
+  *)
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+as_dummy="$PATH:/bin:/usr/bin:/usr/local/bin"
+for as_dir in $as_dummy
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_path_EASY_INSTALL="$as_dir/$ac_word$ac_exec_ext"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+  ;;
+esac
+fi
+EASY_INSTALL=$ac_cv_path_EASY_INSTALL
+if test -n "$EASY_INSTALL"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $EASY_INSTALL" >&5
+$as_echo "$EASY_INSTALL" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+	if test x$EASY_INSTALL = x; then
+		as_fn_error $? "Python easy_install not found" "$LINENO" 5
+	fi
+	if test "x$pythoneggdir" = "xmain site-packages directory"; then
+		PYTHONEGGINSTALLDIR=""
+
+	else
+		PYTHONEGGINSTALLDIR="--install-dir $pythoneggdir"
+
+	fi
+	# Extract the first word of "py.test", so it can be a program name with args.
+set dummy py.test; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_path_PY_TEST+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  case $PY_TEST in
+  [\\/]* | ?:[\\/]*)
+  ac_cv_path_PY_TEST="$PY_TEST" # Let the user override the test with a path.
+  ;;
+  *)
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+as_dummy="$PATH:/bin:/usr/bin:/usr/local/bin"
+for as_dir in $as_dummy
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_path_PY_TEST="$as_dir/$ac_word$ac_exec_ext"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+  ;;
+esac
+fi
+PY_TEST=$ac_cv_path_PY_TEST
+if test -n "$PY_TEST"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PY_TEST" >&5
+$as_echo "$PY_TEST" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+
 # ===============================================
 #  collect plugin list for strongSwan components
 # ===============================================
@@ -21382,26 +21681,6 @@ if test x$ldap = xtrue; then
 
 	fi
 
-if test x$mysql = xtrue; then
-		s_plugins=${s_plugins}" mysql"
-		charon_plugins=${charon_plugins}" mysql"
-		pool_plugins=${pool_plugins}" mysql"
-		manager_plugins=${manager_plugins}" mysql"
-		medsrv_plugins=${medsrv_plugins}" mysql"
-		attest_plugins=${attest_plugins}" mysql"
-
-	fi
-
-if test x$sqlite = xtrue; then
-		s_plugins=${s_plugins}" sqlite"
-		charon_plugins=${charon_plugins}" sqlite"
-		pool_plugins=${pool_plugins}" sqlite"
-		manager_plugins=${manager_plugins}" sqlite"
-		medsrv_plugins=${medsrv_plugins}" sqlite"
-		attest_plugins=${attest_plugins}" sqlite"
-
-	fi
-
 if test x$pkcs11 = xtrue; then
 		s_plugins=${s_plugins}" pkcs11"
 		charon_plugins=${charon_plugins}" pkcs11"
@@ -21794,6 +22073,7 @@ if test x$cmac = xtrue; then
 if test x$hmac = xtrue; then
 		s_plugins=${s_plugins}" hmac"
 		charon_plugins=${charon_plugins}" hmac"
+		pki_plugins=${pki_plugins}" hmac"
 		scripts_plugins=${scripts_plugins}" hmac"
 		nm_plugins=${nm_plugins}" hmac"
 		cmd_plugins=${cmd_plugins}" hmac"
@@ -21836,6 +22116,16 @@ if test x$ntru = xtrue; then
 
 	fi
 
+if test x$bliss = xtrue; then
+		s_plugins=${s_plugins}" bliss"
+		charon_plugins=${charon_plugins}" bliss"
+		pki_plugins=${pki_plugins}" bliss"
+		scripts_plugins=${scripts_plugins}" bliss"
+		nm_plugins=${nm_plugins}" bliss"
+		cmd_plugins=${cmd_plugins}" bliss"
+
+	fi
+
 if test x$curl = xtrue; then
 		s_plugins=${s_plugins}" curl"
 		charon_plugins=${charon_plugins}" curl"
@@ -21847,6 +22137,17 @@ if test x$curl = xtrue; then
 
 	fi
 
+if test x$files = xtrue; then
+		s_plugins=${s_plugins}" files"
+		charon_plugins=${charon_plugins}" files"
+		scepclient_plugins=${scepclient_plugins}" files"
+		pki_plugins=${pki_plugins}" files"
+		scripts_plugins=${scripts_plugins}" files"
+		nm_plugins=${nm_plugins}" files"
+		cmd_plugins=${cmd_plugins}" files"
+
+	fi
+
 if test x$winhttp = xtrue; then
 		s_plugins=${s_plugins}" winhttp"
 		charon_plugins=${charon_plugins}" winhttp"
@@ -21865,14 +22166,34 @@ if test x$soup = xtrue; then
 
 	fi
 
+if test x$mysql = xtrue; then
+		s_plugins=${s_plugins}" mysql"
+		charon_plugins=${charon_plugins}" mysql"
+		pool_plugins=${pool_plugins}" mysql"
+		manager_plugins=${manager_plugins}" mysql"
+		medsrv_plugins=${medsrv_plugins}" mysql"
+		attest_plugins=${attest_plugins}" mysql"
+
+	fi
+
+if test x$sqlite = xtrue; then
+		s_plugins=${s_plugins}" sqlite"
+		charon_plugins=${charon_plugins}" sqlite"
+		pool_plugins=${pool_plugins}" sqlite"
+		manager_plugins=${manager_plugins}" sqlite"
+		medsrv_plugins=${medsrv_plugins}" sqlite"
+		attest_plugins=${attest_plugins}" sqlite"
+
+	fi
+
 if test x$attr = xtrue; then
-		h_plugins=${h_plugins}" attr"
+		c_plugins=${c_plugins}" attr"
 		charon_plugins=${charon_plugins}" attr"
 
 	fi
 
 if test x$attr_sql = xtrue; then
-		h_plugins=${h_plugins}" attr-sql"
+		c_plugins=${c_plugins}" attr-sql"
 		charon_plugins=${charon_plugins}" attr-sql"
 
 	fi
@@ -21930,7 +22251,7 @@ if test x$kernel_netlink = xtrue; then
 	fi
 
 if test x$resolve = xtrue; then
-		h_plugins=${h_plugins}" resolve"
+		c_plugins=${c_plugins}" resolve"
 		charon_plugins=${charon_plugins}" resolve"
 		cmd_plugins=${cmd_plugins}" resolve"
 
@@ -21957,6 +22278,18 @@ if test x$socket_win = xtrue; then
 
 	fi
 
+if test x$connmark = xtrue; then
+		c_plugins=${c_plugins}" connmark"
+		charon_plugins=${charon_plugins}" connmark"
+
+	fi
+
+if test x$forecast = xtrue; then
+		c_plugins=${c_plugins}" forecast"
+		charon_plugins=${charon_plugins}" forecast"
+
+	fi
+
 if test x$farp = xtrue; then
 		c_plugins=${c_plugins}" farp"
 		charon_plugins=${charon_plugins}" farp"
@@ -22315,12 +22648,6 @@ if test x$unity = xtrue; then
 
 	fi
 
-if test x$unit_tester = xtrue; then
-		c_plugins=${c_plugins}" unit-tester"
-		charon_plugins=${charon_plugins}" unit-tester"
-
-	fi
-
 
 
 
@@ -22362,6 +22689,14 @@ else
   USE_CURL_FALSE=
 fi
 
+ if test x$files = xtrue; then
+  USE_FILES_TRUE=
+  USE_FILES_FALSE='#'
+else
+  USE_FILES_TRUE='#'
+  USE_FILES_FALSE=
+fi
+
  if test x$winhttp = xtrue; then
   USE_WINHTTP_TRUE=
   USE_WINHTTP_FALSE='#'
@@ -22730,6 +23065,14 @@ else
   USE_NTRU_FALSE=
 fi
 
+ if test x$bliss = xtrue; then
+  USE_BLISS_TRUE=
+  USE_BLISS_FALSE='#'
+else
+  USE_BLISS_TRUE='#'
+  USE_BLISS_FALSE=
+fi
+
 
 #  charon plugins
 # ----------------
@@ -22853,14 +23196,6 @@ else
   USE_DHCP_FALSE=
 fi
 
- if test x$unit_tester = xtrue; then
-  USE_UNIT_TESTS_TRUE=
-  USE_UNIT_TESTS_FALSE='#'
-else
-  USE_UNIT_TESTS_TRUE='#'
-  USE_UNIT_TESTS_FALSE=
-fi
-
  if test x$load_tester = xtrue; then
   USE_LOAD_TESTER_TRUE=
   USE_LOAD_TESTER_FALSE='#'
@@ -23325,6 +23660,22 @@ else
   USE_SOCKET_WIN_FALSE=
 fi
 
+ if test x$connmark = xtrue; then
+  USE_CONNMARK_TRUE=
+  USE_CONNMARK_FALSE='#'
+else
+  USE_CONNMARK_TRUE='#'
+  USE_CONNMARK_FALSE=
+fi
+
+ if test x$forecast = xtrue; then
+  USE_FORECAST_TRUE=
+  USE_FORECAST_FALSE='#'
+else
+  USE_FORECAST_TRUE='#'
+  USE_FORECAST_FALSE=
+fi
+
  if test x$farp = xtrue; then
   USE_FARP_TRUE=
   USE_FARP_FALSE='#'
@@ -23349,9 +23700,14 @@ else
   USE_UNITY_FALSE=
 fi
 
+ if test x$resolve = xtrue; then
+  USE_RESOLVE_TRUE=
+  USE_RESOLVE_FALSE='#'
+else
+  USE_RESOLVE_TRUE='#'
+  USE_RESOLVE_FALSE=
+fi
 
-#  hydra plugins
-# ---------------
  if test x$attr = xtrue; then
   USE_ATTR_TRUE=
   USE_ATTR_FALSE='#'
@@ -23368,6 +23724,9 @@ else
   USE_ATTR_SQL_FALSE=
 fi
 
+
+#  hydra plugins
+# ---------------
  if test x$kernel_netlink = xtrue; then
   USE_KERNEL_NETLINK_TRUE=
   USE_KERNEL_NETLINK_FALSE='#'
@@ -23392,14 +23751,6 @@ else
   USE_KERNEL_PFROUTE_FALSE=
 fi
 
- if test x$resolve = xtrue; then
-  USE_RESOLVE_TRUE=
-  USE_RESOLVE_FALSE='#'
-else
-  USE_RESOLVE_TRUE='#'
-  USE_RESOLVE_FALSE=
-fi
-
 
 #  other options
 # ---------------
@@ -23779,6 +24130,22 @@ else
   USE_RUBY_GEMS_FALSE=
 fi
 
+ if test x$python_eggs = xtrue; then
+  USE_PYTHON_EGGS_TRUE=
+  USE_PYTHON_EGGS_FALSE='#'
+else
+  USE_PYTHON_EGGS_TRUE='#'
+  USE_PYTHON_EGGS_FALSE=
+fi
+
+ if test "x$PY_TEST" != x; then
+  USE_PY_TEST_TRUE=
+  USE_PY_TEST_FALSE='#'
+else
+  USE_PY_TEST_TRUE='#'
+  USE_PY_TEST_FALSE=
+fi
+
 
 # ========================
 #  set global definitions
@@ -23862,14 +24229,14 @@ fi
 #  build Makefiles
 # =================
 
-ac_config_files="$ac_config_files Makefile conf/Makefile man/Makefile init/Makefile init/systemd/Makefile init/systemd-swanctl/Makefile src/Makefile src/include/Makefile src/libstrongswan/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/Makefile src/libstrongswan/plugins/md4/Makefile src/libstrongswan/plugins/md5/Makefile src/libstrongswa [...]
+ac_config_files="$ac_config_files Makefile conf/Makefile man/Makefile init/Makefile init/systemd/Makefile init/systemd-swanctl/Makefile src/Makefile src/include/Makefile src/libstrongswan/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/Makefile src/libstrongswan/plugins/md4/Makefile src/libstrongswan/plugins/md5/Makefile src/libstrongswa [...]
 
 
 # =================
 #  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---gen.1 src/pki/man/pki---issue.1 src/pki/man/pki---keyid.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/pki---acert.1 src/pki/man/pki---verify.1 src/swanctl/swanctl.8 src/swanctl/swa [...]
+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---gen.1 src/pki/man/pki---issue.1 src/pki/man/pki---keyid.1 src/pki/man/pki---pkcs7.1 src/pki/man/pki---pkcs12.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/pki---acert.1 src/pki/man/pki---verify.1 src/swanct [...]
 
 
 cat >confcache <<\_ACEOF
@@ -24026,6 +24393,10 @@ if test -z "${USE_CURL_TRUE}" && test -z "${USE_CURL_FALSE}"; then
   as_fn_error $? "conditional \"USE_CURL\" was never defined.
 Usually this means the macro was only invoked conditionally." "$LINENO" 5
 fi
+if test -z "${USE_FILES_TRUE}" && test -z "${USE_FILES_FALSE}"; then
+  as_fn_error $? "conditional \"USE_FILES\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
 if test -z "${USE_WINHTTP_TRUE}" && test -z "${USE_WINHTTP_FALSE}"; then
   as_fn_error $? "conditional \"USE_WINHTTP\" was never defined.
 Usually this means the macro was only invoked conditionally." "$LINENO" 5
@@ -24210,6 +24581,10 @@ if test -z "${USE_NTRU_TRUE}" && test -z "${USE_NTRU_FALSE}"; then
   as_fn_error $? "conditional \"USE_NTRU\" was never defined.
 Usually this means the macro was only invoked conditionally." "$LINENO" 5
 fi
+if test -z "${USE_BLISS_TRUE}" && test -z "${USE_BLISS_FALSE}"; then
+  as_fn_error $? "conditional \"USE_BLISS\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
 if test -z "${USE_STROKE_TRUE}" && test -z "${USE_STROKE_FALSE}"; then
   as_fn_error $? "conditional \"USE_STROKE\" was never defined.
 Usually this means the macro was only invoked conditionally." "$LINENO" 5
@@ -24270,10 +24645,6 @@ if test -z "${USE_DHCP_TRUE}" && test -z "${USE_DHCP_FALSE}"; then
   as_fn_error $? "conditional \"USE_DHCP\" was never defined.
 Usually this means the macro was only invoked conditionally." "$LINENO" 5
 fi
-if test -z "${USE_UNIT_TESTS_TRUE}" && test -z "${USE_UNIT_TESTS_FALSE}"; then
-  as_fn_error $? "conditional \"USE_UNIT_TESTS\" was never defined.
-Usually this means the macro was only invoked conditionally." "$LINENO" 5
-fi
 if test -z "${USE_LOAD_TESTER_TRUE}" && test -z "${USE_LOAD_TESTER_FALSE}"; then
   as_fn_error $? "conditional \"USE_LOAD_TESTER\" was never defined.
 Usually this means the macro was only invoked conditionally." "$LINENO" 5
@@ -24506,6 +24877,14 @@ if test -z "${USE_SOCKET_WIN_TRUE}" && test -z "${USE_SOCKET_WIN_FALSE}"; then
   as_fn_error $? "conditional \"USE_SOCKET_WIN\" was never defined.
 Usually this means the macro was only invoked conditionally." "$LINENO" 5
 fi
+if test -z "${USE_CONNMARK_TRUE}" && test -z "${USE_CONNMARK_FALSE}"; then
+  as_fn_error $? "conditional \"USE_CONNMARK\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${USE_FORECAST_TRUE}" && test -z "${USE_FORECAST_FALSE}"; then
+  as_fn_error $? "conditional \"USE_FORECAST\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
 if test -z "${USE_FARP_TRUE}" && test -z "${USE_FARP_FALSE}"; then
   as_fn_error $? "conditional \"USE_FARP\" was never defined.
 Usually this means the macro was only invoked conditionally." "$LINENO" 5
@@ -24518,6 +24897,10 @@ if test -z "${USE_UNITY_TRUE}" && test -z "${USE_UNITY_FALSE}"; then
   as_fn_error $? "conditional \"USE_UNITY\" was never defined.
 Usually this means the macro was only invoked conditionally." "$LINENO" 5
 fi
+if test -z "${USE_RESOLVE_TRUE}" && test -z "${USE_RESOLVE_FALSE}"; then
+  as_fn_error $? "conditional \"USE_RESOLVE\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
 if test -z "${USE_ATTR_TRUE}" && test -z "${USE_ATTR_FALSE}"; then
   as_fn_error $? "conditional \"USE_ATTR\" was never defined.
 Usually this means the macro was only invoked conditionally." "$LINENO" 5
@@ -24538,10 +24921,6 @@ if test -z "${USE_KERNEL_PFROUTE_TRUE}" && test -z "${USE_KERNEL_PFROUTE_FALSE}"
   as_fn_error $? "conditional \"USE_KERNEL_PFROUTE\" was never defined.
 Usually this means the macro was only invoked conditionally." "$LINENO" 5
 fi
-if test -z "${USE_RESOLVE_TRUE}" && test -z "${USE_RESOLVE_FALSE}"; then
-  as_fn_error $? "conditional \"USE_RESOLVE\" was never defined.
-Usually this means the macro was only invoked conditionally." "$LINENO" 5
-fi
 if test -z "${USE_LEAK_DETECTIVE_TRUE}" && test -z "${USE_LEAK_DETECTIVE_FALSE}"; then
   as_fn_error $? "conditional \"USE_LEAK_DETECTIVE\" was never defined.
 Usually this means the macro was only invoked conditionally." "$LINENO" 5
@@ -24730,6 +25109,14 @@ if test -z "${USE_RUBY_GEMS_TRUE}" && test -z "${USE_RUBY_GEMS_FALSE}"; then
   as_fn_error $? "conditional \"USE_RUBY_GEMS\" was never defined.
 Usually this means the macro was only invoked conditionally." "$LINENO" 5
 fi
+if test -z "${USE_PYTHON_EGGS_TRUE}" && test -z "${USE_PYTHON_EGGS_FALSE}"; then
+  as_fn_error $? "conditional \"USE_PYTHON_EGGS\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${USE_PY_TEST_TRUE}" && test -z "${USE_PY_TEST_FALSE}"; then
+  as_fn_error $? "conditional \"USE_PY_TEST\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
 
 : "${CONFIG_STATUS=./config.status}"
 ac_write_fail=0
@@ -25127,7 +25514,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.2.1, which was
+This file was extended by strongSwan $as_me 5.3.0, which was
 generated by GNU Autoconf 2.69.  Invocation command line was
 
   CONFIG_FILES    = $CONFIG_FILES
@@ -25193,7 +25580,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.2.1
+strongSwan config.status 5.3.0
 configured by $0, generated by GNU Autoconf 2.69,
   with options \\"\$ac_cs_config\\"
 
@@ -25641,6 +26028,7 @@ do
     "src/libstrongswan/plugins/sshkey/Makefile") CONFIG_FILES="$CONFIG_FILES src/libstrongswan/plugins/sshkey/Makefile" ;;
     "src/libstrongswan/plugins/pem/Makefile") CONFIG_FILES="$CONFIG_FILES src/libstrongswan/plugins/pem/Makefile" ;;
     "src/libstrongswan/plugins/curl/Makefile") CONFIG_FILES="$CONFIG_FILES src/libstrongswan/plugins/curl/Makefile" ;;
+    "src/libstrongswan/plugins/files/Makefile") CONFIG_FILES="$CONFIG_FILES src/libstrongswan/plugins/files/Makefile" ;;
     "src/libstrongswan/plugins/winhttp/Makefile") CONFIG_FILES="$CONFIG_FILES src/libstrongswan/plugins/winhttp/Makefile" ;;
     "src/libstrongswan/plugins/unbound/Makefile") CONFIG_FILES="$CONFIG_FILES src/libstrongswan/plugins/unbound/Makefile" ;;
     "src/libstrongswan/plugins/soup/Makefile") CONFIG_FILES="$CONFIG_FILES src/libstrongswan/plugins/soup/Makefile" ;;
@@ -25658,15 +26046,15 @@ do
     "src/libstrongswan/plugins/gcm/Makefile") CONFIG_FILES="$CONFIG_FILES src/libstrongswan/plugins/gcm/Makefile" ;;
     "src/libstrongswan/plugins/af_alg/Makefile") CONFIG_FILES="$CONFIG_FILES src/libstrongswan/plugins/af_alg/Makefile" ;;
     "src/libstrongswan/plugins/ntru/Makefile") CONFIG_FILES="$CONFIG_FILES src/libstrongswan/plugins/ntru/Makefile" ;;
+    "src/libstrongswan/plugins/bliss/Makefile") CONFIG_FILES="$CONFIG_FILES src/libstrongswan/plugins/bliss/Makefile" ;;
+    "src/libstrongswan/plugins/bliss/tests/Makefile") CONFIG_FILES="$CONFIG_FILES src/libstrongswan/plugins/bliss/tests/Makefile" ;;
     "src/libstrongswan/plugins/test_vectors/Makefile") CONFIG_FILES="$CONFIG_FILES src/libstrongswan/plugins/test_vectors/Makefile" ;;
     "src/libstrongswan/tests/Makefile") CONFIG_FILES="$CONFIG_FILES src/libstrongswan/tests/Makefile" ;;
     "src/libhydra/Makefile") CONFIG_FILES="$CONFIG_FILES src/libhydra/Makefile" ;;
-    "src/libhydra/plugins/attr/Makefile") CONFIG_FILES="$CONFIG_FILES src/libhydra/plugins/attr/Makefile" ;;
-    "src/libhydra/plugins/attr_sql/Makefile") CONFIG_FILES="$CONFIG_FILES src/libhydra/plugins/attr_sql/Makefile" ;;
     "src/libhydra/plugins/kernel_netlink/Makefile") CONFIG_FILES="$CONFIG_FILES src/libhydra/plugins/kernel_netlink/Makefile" ;;
     "src/libhydra/plugins/kernel_pfkey/Makefile") CONFIG_FILES="$CONFIG_FILES src/libhydra/plugins/kernel_pfkey/Makefile" ;;
     "src/libhydra/plugins/kernel_pfroute/Makefile") CONFIG_FILES="$CONFIG_FILES src/libhydra/plugins/kernel_pfroute/Makefile" ;;
-    "src/libhydra/plugins/resolve/Makefile") CONFIG_FILES="$CONFIG_FILES src/libhydra/plugins/resolve/Makefile" ;;
+    "src/libhydra/tests/Makefile") CONFIG_FILES="$CONFIG_FILES src/libhydra/tests/Makefile" ;;
     "src/libipsec/Makefile") CONFIG_FILES="$CONFIG_FILES src/libipsec/Makefile" ;;
     "src/libsimaka/Makefile") CONFIG_FILES="$CONFIG_FILES src/libsimaka/Makefile" ;;
     "src/libtls/Makefile") CONFIG_FILES="$CONFIG_FILES src/libtls/Makefile" ;;
@@ -25726,6 +26114,8 @@ do
     "src/libcharon/plugins/socket_default/Makefile") CONFIG_FILES="$CONFIG_FILES src/libcharon/plugins/socket_default/Makefile" ;;
     "src/libcharon/plugins/socket_dynamic/Makefile") CONFIG_FILES="$CONFIG_FILES src/libcharon/plugins/socket_dynamic/Makefile" ;;
     "src/libcharon/plugins/socket_win/Makefile") CONFIG_FILES="$CONFIG_FILES src/libcharon/plugins/socket_win/Makefile" ;;
+    "src/libcharon/plugins/connmark/Makefile") CONFIG_FILES="$CONFIG_FILES src/libcharon/plugins/connmark/Makefile" ;;
+    "src/libcharon/plugins/forecast/Makefile") CONFIG_FILES="$CONFIG_FILES src/libcharon/plugins/forecast/Makefile" ;;
     "src/libcharon/plugins/farp/Makefile") CONFIG_FILES="$CONFIG_FILES src/libcharon/plugins/farp/Makefile" ;;
     "src/libcharon/plugins/smp/Makefile") CONFIG_FILES="$CONFIG_FILES src/libcharon/plugins/smp/Makefile" ;;
     "src/libcharon/plugins/sql/Makefile") CONFIG_FILES="$CONFIG_FILES src/libcharon/plugins/sql/Makefile" ;;
@@ -25757,16 +26147,19 @@ do
     "src/libcharon/plugins/stroke/Makefile") CONFIG_FILES="$CONFIG_FILES src/libcharon/plugins/stroke/Makefile" ;;
     "src/libcharon/plugins/vici/Makefile") CONFIG_FILES="$CONFIG_FILES src/libcharon/plugins/vici/Makefile" ;;
     "src/libcharon/plugins/vici/ruby/Makefile") CONFIG_FILES="$CONFIG_FILES src/libcharon/plugins/vici/ruby/Makefile" ;;
+    "src/libcharon/plugins/vici/python/Makefile") CONFIG_FILES="$CONFIG_FILES src/libcharon/plugins/vici/python/Makefile" ;;
     "src/libcharon/plugins/updown/Makefile") CONFIG_FILES="$CONFIG_FILES src/libcharon/plugins/updown/Makefile" ;;
     "src/libcharon/plugins/dhcp/Makefile") CONFIG_FILES="$CONFIG_FILES src/libcharon/plugins/dhcp/Makefile" ;;
-    "src/libcharon/plugins/unit_tester/Makefile") CONFIG_FILES="$CONFIG_FILES src/libcharon/plugins/unit_tester/Makefile" ;;
     "src/libcharon/plugins/load_tester/Makefile") CONFIG_FILES="$CONFIG_FILES src/libcharon/plugins/load_tester/Makefile" ;;
+    "src/libcharon/plugins/resolve/Makefile") CONFIG_FILES="$CONFIG_FILES src/libcharon/plugins/resolve/Makefile" ;;
+    "src/libcharon/plugins/attr/Makefile") CONFIG_FILES="$CONFIG_FILES src/libcharon/plugins/attr/Makefile" ;;
+    "src/libcharon/plugins/attr_sql/Makefile") CONFIG_FILES="$CONFIG_FILES src/libcharon/plugins/attr_sql/Makefile" ;;
+    "src/libcharon/tests/Makefile") CONFIG_FILES="$CONFIG_FILES src/libcharon/tests/Makefile" ;;
     "src/stroke/Makefile") CONFIG_FILES="$CONFIG_FILES src/stroke/Makefile" ;;
     "src/ipsec/Makefile") CONFIG_FILES="$CONFIG_FILES src/ipsec/Makefile" ;;
     "src/starter/Makefile") CONFIG_FILES="$CONFIG_FILES src/starter/Makefile" ;;
     "src/starter/tests/Makefile") CONFIG_FILES="$CONFIG_FILES src/starter/tests/Makefile" ;;
     "src/_updown/Makefile") CONFIG_FILES="$CONFIG_FILES src/_updown/Makefile" ;;
-    "src/_updown_espmark/Makefile") CONFIG_FILES="$CONFIG_FILES src/_updown_espmark/Makefile" ;;
     "src/_copyright/Makefile") CONFIG_FILES="$CONFIG_FILES src/_copyright/Makefile" ;;
     "src/scepclient/Makefile") CONFIG_FILES="$CONFIG_FILES src/scepclient/Makefile" ;;
     "src/aikgen/Makefile") CONFIG_FILES="$CONFIG_FILES src/aikgen/Makefile" ;;
@@ -25794,6 +26187,7 @@ do
     "src/pki/man/pki---issue.1") CONFIG_FILES="$CONFIG_FILES src/pki/man/pki---issue.1" ;;
     "src/pki/man/pki---keyid.1") CONFIG_FILES="$CONFIG_FILES src/pki/man/pki---keyid.1" ;;
     "src/pki/man/pki---pkcs7.1") CONFIG_FILES="$CONFIG_FILES src/pki/man/pki---pkcs7.1" ;;
+    "src/pki/man/pki---pkcs12.1") CONFIG_FILES="$CONFIG_FILES src/pki/man/pki---pkcs12.1" ;;
     "src/pki/man/pki---print.1") CONFIG_FILES="$CONFIG_FILES src/pki/man/pki---print.1" ;;
     "src/pki/man/pki---pub.1") CONFIG_FILES="$CONFIG_FILES src/pki/man/pki---pub.1" ;;
     "src/pki/man/pki---req.1") CONFIG_FILES="$CONFIG_FILES src/pki/man/pki---req.1" ;;
diff --git a/configure.ac b/configure.ac
index 7a3c328..73c2884 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1,5 +1,5 @@
 #
-# Copyright (C) 2007-2014 Tobias Brunner
+# Copyright (C) 2007-2015 Tobias Brunner
 # Copyright (C) 2006-2014 Andreas Steffen
 # Copyright (C) 2006-2014 Martin Willi
 # Hochschule fuer Technik Rapperswil
@@ -19,7 +19,7 @@
 #  initialize & set some vars
 # ============================
 
-AC_INIT([strongSwan],[5.2.1])
+AC_INIT([strongSwan],[5.3.0])
 AM_INIT_AUTOMAKE(m4_esyscmd([
 	echo tar-ustar
 	echo subdir-objects
@@ -69,6 +69,7 @@ ARG_WITH_SET([mpz_powm_sec],         [yes], [use the more side-channel resistant
 ARG_WITH_SET([dev-headers],          [no], [install strongSwan development headers to directory.])
 ARG_WITH_SET([printf-hooks],         [auto], [force the use of a specific printf hook implementation (auto, builtin, glibc, vstr).])
 ARG_WITH_SET([rubygemdir],           ["gem environment gemdir"], [path to install ruby gems to])
+ARG_WITH_SET([pythoneggdir],         ["main site-packages directory"], [path to install python eggs to to])
 
 if test -n "$PKG_CONFIG"; then
 	systemdsystemunitdir_default=$($PKG_CONFIG --variable=systemdsystemunitdir systemd)
@@ -123,6 +124,7 @@ m4_include(m4/macros/enable-disable.m4)
 # crypto plugins
 ARG_DISBL_SET([aes],            [disable AES software implementation plugin.])
 ARG_ENABL_SET([af-alg],         [enable AF_ALG crypto interface to Linux Crypto API.])
+ARG_ENABL_SET([bliss],          [enable BLISS software implementation plugin.])
 ARG_ENABL_SET([blowfish],       [enable Blowfish software implementation plugin.])
 ARG_ENABL_SET([ccm],            [enables the CCM AEAD wrapper crypto plugin.])
 ARG_DISBL_SET([cmac],           [disable CMAC crypto implementation plugin.])
@@ -158,6 +160,7 @@ ARG_DISBL_SET([sshkey],         [disable SSH key decoding plugin.])
 ARG_DISBL_SET([x509],           [disable X509 certificate implementation plugin.])
 # fetcher/resolver plugins
 ARG_ENABL_SET([curl],           [enable CURL fetcher plugin to fetch files via libcurl. Requires libcurl.])
+ARG_ENABL_SET([files],          [enable simple file:// URI fetcher.])
 ARG_ENABL_SET([ldap],           [enable LDAP fetching plugin to fetch files via libldap. Requires openLDAP.])
 ARG_ENABL_SET([soup],           [enable soup fetcher plugin to fetch from HTTP via libsoup. Requires libsoup.])
 ARG_ENABL_SET([unbound],        [enable UNBOUND resolver plugin to perform DNS queries via libunbound. Requires libldns and libunbound.])
@@ -245,6 +248,8 @@ ARG_ENABL_SET([tnccs-dynamic],  [enable dynamic TNCCS protocol discovery module.
 # misc plugins
 ARG_ENABL_SET([android-log],    [enable Android specific logger plugin.])
 ARG_ENABL_SET([certexpire],     [enable CSV export of expiration dates of used certificates.])
+ARG_ENABL_SET([connmark],       [enable connmark plugin using conntrack based marks to select return path SA.])
+ARG_ENABL_SET([forecast],       [enable forecast plugin forwarding broadcast/multicast messages.])
 ARG_ENABL_SET([duplicheck],     [advanced duplicate checking plugin using liveness checks.])
 ARG_ENABL_SET([error-notify],   [enable error notification plugin.])
 ARG_ENABL_SET([farp],           [enable ARP faking plugin that responds to ARP requests to peers virtual IP])
@@ -256,7 +261,6 @@ ARG_ENABL_SET([maemo],          [enable Maemo specific plugin.])
 ARG_ENABL_SET([radattr],        [enable plugin to inject and process custom RADIUS attributes as IKEv2 client.])
 ARG_ENABL_SET([systime-fix],    [enable plugin to handle cert lifetimes with invalid system time gracefully.])
 ARG_ENABL_SET([test-vectors],   [enable plugin providing crypto test vectors.])
-ARG_ENABL_SET([unit-tester],    [enable unit tests on IKEv2 daemon startup.])
 ARG_DISBL_SET([updown],         [disable updown firewall script plugin.])
 # programs/components
 ARG_ENABL_SET([aikgen],         [enable AIK generator.])
@@ -287,6 +291,7 @@ ARG_DISBL_SET([load-warning],   [disable the charon plugin load option warning i
 ARG_ENABL_SET([mediation],      [enable IKEv2 Mediation Extension.])
 ARG_ENABL_SET([unwind-backtraces],[use libunwind to create backtraces for memory leaks and segfaults.])
 ARG_ENABL_SET([ruby-gems],      [enable installation of provided ruby gems.])
+ARG_ENABL_SET([python-eggs],    [enable installation of provided python eggs.])
 # compile options
 ARG_ENABL_SET([coverage],       [enable lcov coverage report generation.])
 ARG_ENABL_SET([leak-detective], [enable malloc hooks to find memory leaks.])
@@ -1076,6 +1081,12 @@ if test x$xauth_pam = xtrue; then
 	AC_CHECK_HEADER([security/pam_appl.h],,[AC_MSG_ERROR([PAM header security/pam_appl.h not found!])])
 fi
 
+if test x$connmark = xtrue -o x$forecast = xtrue; then
+	PKG_CHECK_MODULES(libiptc, [libiptc])
+	AC_SUBST(libiptc_CFLAGS)
+	AC_SUBST(libiptc_LIBS)
+fi
+
 if test x$capabilities = xnative; then
 	AC_MSG_NOTICE([Usage of the native Linux capabilities interface is deprecated, use libcap instead])
 	# Linux requires the following for capset(), Android does not have it,
@@ -1177,6 +1188,19 @@ if test x$ruby_gems = xtrue; then
 	AC_SUBST(RUBYGEMDIR, "$rubygemdir")
 fi
 
+if test x$python_eggs = xtrue; then
+	AC_PATH_PROG([EASY_INSTALL], [easy_install], [], [$PATH:/bin:/usr/bin:/usr/local/bin])
+	if test x$EASY_INSTALL = x; then
+		AC_MSG_ERROR(Python easy_install not found)
+	fi
+	if test "x$pythoneggdir" = "xmain site-packages directory"; then
+		AC_SUBST(PYTHONEGGINSTALLDIR, "")
+	else
+		AC_SUBST(PYTHONEGGINSTALLDIR, "--install-dir $pythoneggdir")
+	fi
+	AC_PATH_PROG([PY_TEST], [py.test], [], [$PATH:/bin:/usr/bin:/usr/local/bin])
+fi
+
 # ===============================================
 #  collect plugin list for strongSwan components
 # ===============================================
@@ -1207,8 +1231,6 @@ t_plugins=
 ADD_PLUGIN([test-vectors],         [s charon scepclient pki])
 ADD_PLUGIN([unbound],              [s charon scripts])
 ADD_PLUGIN([ldap],                 [s charon scepclient scripts nm cmd])
-ADD_PLUGIN([mysql],                [s charon pool manager medsrv attest])
-ADD_PLUGIN([sqlite],               [s charon pool manager medsrv attest])
 ADD_PLUGIN([pkcs11],               [s charon pki nm cmd])
 ADD_PLUGIN([aes],                  [s charon scepclient pki scripts nm cmd])
 ADD_PLUGIN([des],                  [s charon scepclient pki scripts nm cmd])
@@ -1246,16 +1268,20 @@ ADD_PLUGIN([agent],                [s charon nm cmd])
 ADD_PLUGIN([keychain],             [s charon cmd])
 ADD_PLUGIN([xcbc],                 [s charon nm cmd])
 ADD_PLUGIN([cmac],                 [s charon nm cmd])
-ADD_PLUGIN([hmac],                 [s charon scripts nm cmd])
+ADD_PLUGIN([hmac],                 [s charon pki scripts nm cmd])
 ADD_PLUGIN([ctr],                  [s charon scripts nm cmd])
 ADD_PLUGIN([ccm],                  [s charon scripts nm cmd])
 ADD_PLUGIN([gcm],                  [s charon scripts nm cmd])
 ADD_PLUGIN([ntru],                 [s charon scripts nm cmd])
+ADD_PLUGIN([bliss],                [s charon pki scripts nm cmd])
 ADD_PLUGIN([curl],                 [s charon scepclient pki scripts nm cmd])
+ADD_PLUGIN([files],                [s charon scepclient pki scripts nm cmd])
 ADD_PLUGIN([winhttp],              [s charon pki scripts])
 ADD_PLUGIN([soup],                 [s charon pki scripts nm cmd])
-ADD_PLUGIN([attr],                 [h charon])
-ADD_PLUGIN([attr-sql],             [h charon])
+ADD_PLUGIN([mysql],                [s charon pool manager medsrv attest])
+ADD_PLUGIN([sqlite],               [s charon pool manager medsrv attest])
+ADD_PLUGIN([attr],                 [c charon])
+ADD_PLUGIN([attr-sql],             [c charon])
 ADD_PLUGIN([load-tester],          [c charon])
 ADD_PLUGIN([kernel-libipsec],      [c charon cmd])
 ADD_PLUGIN([kernel-wfp],           [c charon])
@@ -1263,10 +1289,12 @@ ADD_PLUGIN([kernel-iph],           [c charon])
 ADD_PLUGIN([kernel-pfkey],         [h charon starter nm cmd])
 ADD_PLUGIN([kernel-pfroute],       [h charon starter nm cmd])
 ADD_PLUGIN([kernel-netlink],       [h charon starter nm cmd])
-ADD_PLUGIN([resolve],              [h charon cmd])
+ADD_PLUGIN([resolve],              [c charon cmd])
 ADD_PLUGIN([socket-default],       [c charon nm cmd])
 ADD_PLUGIN([socket-dynamic],       [c charon cmd])
 ADD_PLUGIN([socket-win],           [c charon])
+ADD_PLUGIN([connmark],             [c charon])
+ADD_PLUGIN([forecast],             [c charon])
 ADD_PLUGIN([farp],                 [c charon])
 ADD_PLUGIN([stroke],               [c charon])
 ADD_PLUGIN([vici],                 [c charon])
@@ -1324,7 +1352,6 @@ ADD_PLUGIN([maemo],                [c charon])
 ADD_PLUGIN([uci],                  [c charon])
 ADD_PLUGIN([addrblock],            [c charon])
 ADD_PLUGIN([unity],                [c charon])
-ADD_PLUGIN([unit-tester],          [c charon])
 
 AC_SUBST(charon_plugins)
 AC_SUBST(starter_plugins)
@@ -1352,6 +1379,7 @@ AC_SUBST(t_plugins)
 # -----------------------
 AM_CONDITIONAL(USE_TEST_VECTORS, test x$test_vectors = xtrue)
 AM_CONDITIONAL(USE_CURL, test x$curl = xtrue)
+AM_CONDITIONAL(USE_FILES, test x$files = xtrue)
 AM_CONDITIONAL(USE_WINHTTP, test x$winhttp = xtrue)
 AM_CONDITIONAL(USE_UNBOUND, test x$unbound = xtrue)
 AM_CONDITIONAL(USE_SOUP, test x$soup = xtrue)
@@ -1398,6 +1426,7 @@ AM_CONDITIONAL(USE_CCM, test x$ccm = xtrue)
 AM_CONDITIONAL(USE_GCM, test x$gcm = xtrue)
 AM_CONDITIONAL(USE_AF_ALG, test x$af_alg = xtrue)
 AM_CONDITIONAL(USE_NTRU, test x$ntru = xtrue)
+AM_CONDITIONAL(USE_BLISS, test x$bliss = xtrue)
 
 #  charon plugins
 # ----------------
@@ -1416,7 +1445,6 @@ AM_CONDITIONAL(USE_DNSCERT, test x$dnscert = xtrue)
 AM_CONDITIONAL(USE_IPSECKEY, test x$ipseckey = xtrue)
 AM_CONDITIONAL(USE_UPDOWN, test x$updown = xtrue)
 AM_CONDITIONAL(USE_DHCP, test x$dhcp = xtrue)
-AM_CONDITIONAL(USE_UNIT_TESTS, test x$unit_tester = xtrue)
 AM_CONDITIONAL(USE_LOAD_TESTER, test x$load_tester = xtrue)
 AM_CONDITIONAL(USE_HA, test x$ha = xtrue)
 AM_CONDITIONAL(USE_KERNEL_LIBIPSEC, test x$kernel_libipsec = xtrue)
@@ -1475,18 +1503,20 @@ AM_CONDITIONAL(USE_IMV_SWID, test x$imv_swid = xtrue)
 AM_CONDITIONAL(USE_SOCKET_DEFAULT, test x$socket_default = xtrue)
 AM_CONDITIONAL(USE_SOCKET_DYNAMIC, test x$socket_dynamic = xtrue)
 AM_CONDITIONAL(USE_SOCKET_WIN, test x$socket_win = xtrue)
+AM_CONDITIONAL(USE_CONNMARK, test x$connmark = xtrue)
+AM_CONDITIONAL(USE_FORECAST, test x$forecast = xtrue)
 AM_CONDITIONAL(USE_FARP, test x$farp = xtrue)
 AM_CONDITIONAL(USE_ADDRBLOCK, test x$addrblock = xtrue)
 AM_CONDITIONAL(USE_UNITY, test x$unity = xtrue)
+AM_CONDITIONAL(USE_RESOLVE, test x$resolve = xtrue)
+AM_CONDITIONAL(USE_ATTR, test x$attr = xtrue)
+AM_CONDITIONAL(USE_ATTR_SQL, test x$attr_sql = xtrue)
 
 #  hydra plugins
 # ---------------
-AM_CONDITIONAL(USE_ATTR, test x$attr = xtrue)
-AM_CONDITIONAL(USE_ATTR_SQL, test x$attr_sql = xtrue)
 AM_CONDITIONAL(USE_KERNEL_NETLINK, test x$kernel_netlink = xtrue)
 AM_CONDITIONAL(USE_KERNEL_PFKEY, test x$kernel_pfkey = xtrue)
 AM_CONDITIONAL(USE_KERNEL_PFROUTE, test x$kernel_pfroute = xtrue)
-AM_CONDITIONAL(USE_RESOLVE, test x$resolve = xtrue)
 
 #  other options
 # ---------------
@@ -1537,6 +1567,8 @@ AM_CONDITIONAL(USE_SVC, test x$svc = xtrue)
 AM_CONDITIONAL(USE_SYSTEMD, test x$systemd = xtrue)
 AM_CONDITIONAL(USE_LEGACY_SYSTEMD, test -n "$systemdsystemunitdir" -a "x$systemdsystemunitdir" != xno)
 AM_CONDITIONAL(USE_RUBY_GEMS, test x$ruby_gems = xtrue)
+AM_CONDITIONAL(USE_PYTHON_EGGS, test x$python_eggs = xtrue)
+AM_CONDITIONAL(USE_PY_TEST, test "x$PY_TEST" != x)
 
 # ========================
 #  set global definitions
@@ -1624,6 +1656,7 @@ AC_CONFIG_FILES([
 	src/libstrongswan/plugins/sshkey/Makefile
 	src/libstrongswan/plugins/pem/Makefile
 	src/libstrongswan/plugins/curl/Makefile
+	src/libstrongswan/plugins/files/Makefile
 	src/libstrongswan/plugins/winhttp/Makefile
 	src/libstrongswan/plugins/unbound/Makefile
 	src/libstrongswan/plugins/soup/Makefile
@@ -1641,15 +1674,15 @@ AC_CONFIG_FILES([
 	src/libstrongswan/plugins/gcm/Makefile
 	src/libstrongswan/plugins/af_alg/Makefile
 	src/libstrongswan/plugins/ntru/Makefile
+	src/libstrongswan/plugins/bliss/Makefile
+	src/libstrongswan/plugins/bliss/tests/Makefile
 	src/libstrongswan/plugins/test_vectors/Makefile
 	src/libstrongswan/tests/Makefile
 	src/libhydra/Makefile
-	src/libhydra/plugins/attr/Makefile
-	src/libhydra/plugins/attr_sql/Makefile
 	src/libhydra/plugins/kernel_netlink/Makefile
 	src/libhydra/plugins/kernel_pfkey/Makefile
 	src/libhydra/plugins/kernel_pfroute/Makefile
-	src/libhydra/plugins/resolve/Makefile
+	src/libhydra/tests/Makefile
 	src/libipsec/Makefile
 	src/libsimaka/Makefile
 	src/libtls/Makefile
@@ -1709,6 +1742,8 @@ AC_CONFIG_FILES([
 	src/libcharon/plugins/socket_default/Makefile
 	src/libcharon/plugins/socket_dynamic/Makefile
 	src/libcharon/plugins/socket_win/Makefile
+	src/libcharon/plugins/connmark/Makefile
+	src/libcharon/plugins/forecast/Makefile
 	src/libcharon/plugins/farp/Makefile
 	src/libcharon/plugins/smp/Makefile
 	src/libcharon/plugins/sql/Makefile
@@ -1740,16 +1775,19 @@ AC_CONFIG_FILES([
 	src/libcharon/plugins/stroke/Makefile
 	src/libcharon/plugins/vici/Makefile
 	src/libcharon/plugins/vici/ruby/Makefile
+	src/libcharon/plugins/vici/python/Makefile
 	src/libcharon/plugins/updown/Makefile
 	src/libcharon/plugins/dhcp/Makefile
-	src/libcharon/plugins/unit_tester/Makefile
 	src/libcharon/plugins/load_tester/Makefile
+	src/libcharon/plugins/resolve/Makefile
+	src/libcharon/plugins/attr/Makefile
+	src/libcharon/plugins/attr_sql/Makefile
+	src/libcharon/tests/Makefile
 	src/stroke/Makefile
 	src/ipsec/Makefile
 	src/starter/Makefile
 	src/starter/tests/Makefile
 	src/_updown/Makefile
-	src/_updown_espmark/Makefile
 	src/_copyright/Makefile
 	src/scepclient/Makefile
 	src/aikgen/Makefile
@@ -1784,6 +1822,7 @@ AC_CONFIG_FILES([
 	src/pki/man/pki---issue.1
 	src/pki/man/pki---keyid.1
 	src/pki/man/pki---pkcs7.1
+	src/pki/man/pki---pkcs12.1
 	src/pki/man/pki---print.1
 	src/pki/man/pki---pub.1
 	src/pki/man/pki---req.1
diff --git a/init/Makefile.in b/init/Makefile.in
index 3da1e65..18c69f1 100644
--- a/init/Makefile.in
+++ b/init/Makefile.in
@@ -204,6 +204,7 @@ DLLIB = @DLLIB@
 DLLTOOL = @DLLTOOL@
 DSYMUTIL = @DSYMUTIL@
 DUMPBIN = @DUMPBIN@
+EASY_INSTALL = @EASY_INSTALL@
 ECHO_C = @ECHO_C@
 ECHO_N = @ECHO_N@
 ECHO_T = @ECHO_T@
@@ -264,10 +265,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
 PLUGIN_CFLAGS = @PLUGIN_CFLAGS@
 PTHREADLIB = @PTHREADLIB@
 PYTHON = @PYTHON@
+PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@
 PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
 PYTHON_PLATFORM = @PYTHON_PLATFORM@
 PYTHON_PREFIX = @PYTHON_PREFIX@
 PYTHON_VERSION = @PYTHON_VERSION@
+PY_TEST = @PY_TEST@
 RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
@@ -341,6 +344,8 @@ json_CFLAGS = @json_CFLAGS@
 json_LIBS = @json_LIBS@
 libdir = @libdir@
 libexecdir = @libexecdir@
+libiptc_CFLAGS = @libiptc_CFLAGS@
+libiptc_LIBS = @libiptc_LIBS@
 linux_headers = @linux_headers@
 localedir = @localedir@
 localstatedir = @localstatedir@
diff --git a/init/systemd-swanctl/Makefile.in b/init/systemd-swanctl/Makefile.in
index 14089c4..28cedbd 100644
--- a/init/systemd-swanctl/Makefile.in
+++ b/init/systemd-swanctl/Makefile.in
@@ -172,6 +172,7 @@ DLLIB = @DLLIB@
 DLLTOOL = @DLLTOOL@
 DSYMUTIL = @DSYMUTIL@
 DUMPBIN = @DUMPBIN@
+EASY_INSTALL = @EASY_INSTALL@
 ECHO_C = @ECHO_C@
 ECHO_N = @ECHO_N@
 ECHO_T = @ECHO_T@
@@ -232,10 +233,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
 PLUGIN_CFLAGS = @PLUGIN_CFLAGS@
 PTHREADLIB = @PTHREADLIB@
 PYTHON = @PYTHON@
+PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@
 PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
 PYTHON_PLATFORM = @PYTHON_PLATFORM@
 PYTHON_PREFIX = @PYTHON_PREFIX@
 PYTHON_VERSION = @PYTHON_VERSION@
+PY_TEST = @PY_TEST@
 RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
@@ -309,6 +312,8 @@ json_CFLAGS = @json_CFLAGS@
 json_LIBS = @json_LIBS@
 libdir = @libdir@
 libexecdir = @libexecdir@
+libiptc_CFLAGS = @libiptc_CFLAGS@
+libiptc_LIBS = @libiptc_LIBS@
 linux_headers = @linux_headers@
 localedir = @localedir@
 localstatedir = @localstatedir@
diff --git a/init/systemd/Makefile.in b/init/systemd/Makefile.in
index a8c7af6..808023e 100644
--- a/init/systemd/Makefile.in
+++ b/init/systemd/Makefile.in
@@ -172,6 +172,7 @@ DLLIB = @DLLIB@
 DLLTOOL = @DLLTOOL@
 DSYMUTIL = @DSYMUTIL@
 DUMPBIN = @DUMPBIN@
+EASY_INSTALL = @EASY_INSTALL@
 ECHO_C = @ECHO_C@
 ECHO_N = @ECHO_N@
 ECHO_T = @ECHO_T@
@@ -232,10 +233,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
 PLUGIN_CFLAGS = @PLUGIN_CFLAGS@
 PTHREADLIB = @PTHREADLIB@
 PYTHON = @PYTHON@
+PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@
 PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
 PYTHON_PLATFORM = @PYTHON_PLATFORM@
 PYTHON_PREFIX = @PYTHON_PREFIX@
 PYTHON_VERSION = @PYTHON_VERSION@
+PY_TEST = @PY_TEST@
 RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
@@ -309,6 +312,8 @@ json_CFLAGS = @json_CFLAGS@
 json_LIBS = @json_LIBS@
 libdir = @libdir@
 libexecdir = @libexecdir@
+libiptc_CFLAGS = @libiptc_CFLAGS@
+libiptc_LIBS = @libiptc_LIBS@
 linux_headers = @linux_headers@
 localedir = @localedir@
 localstatedir = @localstatedir@
diff --git a/man/Makefile.in b/man/Makefile.in
index 08aee19..5013610 100644
--- a/man/Makefile.in
+++ b/man/Makefile.in
@@ -178,6 +178,7 @@ DLLIB = @DLLIB@
 DLLTOOL = @DLLTOOL@
 DSYMUTIL = @DSYMUTIL@
 DUMPBIN = @DUMPBIN@
+EASY_INSTALL = @EASY_INSTALL@
 ECHO_C = @ECHO_C@
 ECHO_N = @ECHO_N@
 ECHO_T = @ECHO_T@
@@ -238,10 +239,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
 PLUGIN_CFLAGS = @PLUGIN_CFLAGS@
 PTHREADLIB = @PTHREADLIB@
 PYTHON = @PYTHON@
+PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@
 PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
 PYTHON_PLATFORM = @PYTHON_PLATFORM@
 PYTHON_PREFIX = @PYTHON_PREFIX@
 PYTHON_VERSION = @PYTHON_VERSION@
+PY_TEST = @PY_TEST@
 RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
@@ -315,6 +318,8 @@ json_CFLAGS = @json_CFLAGS@
 json_LIBS = @json_LIBS@
 libdir = @libdir@
 libexecdir = @libexecdir@
+libiptc_CFLAGS = @libiptc_CFLAGS@
+libiptc_LIBS = @libiptc_LIBS@
 linux_headers = @linux_headers@
 localedir = @localedir@
 localstatedir = @localstatedir@
diff --git a/man/ipsec.conf.5.in b/man/ipsec.conf.5.in
index fe37dff..39c3b2b 100644
--- a/man/ipsec.conf.5.in
+++ b/man/ipsec.conf.5.in
@@ -23,8 +23,7 @@ as are empty lines which are not within a section.
 A line which contains
 .B include
 and a file name, separated by white space,
-is replaced by the contents of that file,
-preceded and followed by empty lines.
+is replaced by the contents of that file.
 If the file name is not a full pathname,
 it is considered to be relative to the directory containing the
 including file.
@@ -61,12 +60,9 @@ indicates what type of section follows, and
 .I name
 is an arbitrary name which distinguishes the section from others
 of the same type.
-Names must start with a letter and may contain only
-letters, digits, periods, underscores, and hyphens.
 All subsequent non-empty lines
-which begin with white space are part of the section;
-comments within a section must begin with white space too.
-There may be only one section of a given type with a given name.
+which begin with white space are part of the section.
+Sections of the same type that share the same name are merged.
 .PP
 Lines within the section are generally of the form
 .PP
@@ -75,24 +71,30 @@ Lines within the section are generally of the form
 (note the mandatory preceding white space).
 There can be white space on either side of the
 .BR = .
-Parameter names follow the same syntax as section names,
-and are specific to a section type.
-Unless otherwise explicitly specified,
-no parameter name may appear more than once in a section.
+Parameter names are specific to a section type.
 .PP
 An empty
 .I value
 stands for the system default value (if any) of the parameter,
-i.e. it is roughly equivalent to omitting the parameter line entirely.
+i.e. it is roughly equivalent to omitting the parameter line entirely. This may
+be useful to clear a setting inherited from a
+.B %default
+section or via
+.B also
+parameter (see below).
 A
 .I value
-may contain white space only if the entire
-.I value
-is enclosed in double quotes (\fB"\fR);
-a
+may contain single spaces (additional white space is reduced to one space).
+To preserve white space as written enclose the entire
 .I value
-cannot itself contain a double quote,
-nor may it be continued across more than one line.
+in double quotes (\fB"\fR); in such values double quotes themselves may be
+escaped by prefixing them with
+.B \\\\
+characters. A double-quoted string may span multiple lines by ending them with
+.B \\\\
+characters (following lines don't have to begin with white space, as that will
+be preserved). Additionally, the following control characters may be encoded in
+double-quoted strings: \\n, \\r, \\t, \\b, \\f.
 .PP
 Numeric values are specified to be either an ``integer''
 (a sequence of digits) or a ``decimal number''
@@ -102,38 +104,24 @@ There is currently one parameter which is available in any type of
 section:
 .TP
 .B also
-the value is a section name;
-the parameters of that section are appended to this section,
-as if they had been written as part of it.
-The specified section must exist, must follow the current one,
-and must have the same section type.
-(Nesting is permitted,
-and there may be more than one
+the value is a section name; the parameters of that section are inherited by
+the current section. Parameters in the current section always override inherited
+parameters, even if an
+.B also
+follows after them.
+The specified section must exist and must have the same section type; it doesn't
+if it is defined before or after the current section.
+Nesting is permitted, and there may be more than one
+.B also
+in a single section (parameters from referenced sections are inherited and
+overridden in the order of these
 .B also
-in a single section,
-although it is forbidden to append the same section more than once.)
+parameters).
 .PP
 A section with name
 .B %default
-specifies defaults for sections of the same type.
-For each parameter in it,
-any section of that type which does not have a parameter of the same name
-gets a copy of the one from the
-.B %default
-section.
-There may be multiple
-.B %default
-sections of a given type,
-but only one default may be supplied for any specific parameter name,
-and all
-.B %default
-sections of a given type must precede all non-\c
-.B %default
-sections of that type.
-.B %default
-sections may not contain the
-.B also
-parameter.
+specifies defaults for sections of the same type. All parameters in it, are
+inherited by all other sections of that type.
 .PP
 Currently there are three types of sections:
 a
@@ -446,19 +434,20 @@ This may help to surmount restrictive firewalls. In order to force the peer to
 encapsulate packets, NAT detection payloads are faked.
 .TP
 .BR fragmentation " = yes | force | " no
-whether to use IKE fragmentation (proprietary IKEv1 extension).  Acceptable
-values are
+whether to use IKE fragmentation (proprietary IKEv1 extension or IKEv2
+fragmentation as per RFC 7383).  Acceptable values are
 .BR yes ,
 .B force
 and
 .B no
-(the default). Fragmented messages sent by a peer are always accepted
+(the default). Fragmented IKE messages sent by a peer are always accepted
 irrespective of the value of this option. If set to
 .BR yes ,
 and the peer supports it, larger IKE messages will be sent in fragments.
 If set to
 .B force
-the initial IKE message will already be fragmented if required.
+(only supported for IKEv1) the initial IKE message will already be fragmented
+if required.
 .TP
 .BR ike " = <cipher suites>"
 comma-separated list of IKE/ISAKMP SA encryption/authentication algorithms
@@ -583,6 +572,7 @@ for pre-shared key authentication,
 to (require the) use of the Extensible Authentication Protocol in IKEv2, and
 .B xauth
 for IKEv1 eXtended Authentication.
+
 To require a trustchain public key strength for the remote side, specify the
 key type followed by the minimum strength in bits (for example
 .BR ecdsa-384
@@ -595,6 +585,20 @@ or a key strength definition (for example
 .BR pubkey-sha1-sha256
 or
 .BR rsa-2048-ecdsa-256-sha256-sha384-sha512 ).
+Unless disabled in
+.BR strongswan.conf (5)
+such key types and hash algorithms are also applied as constraints against IKEv2
+signature authentication schemes used by the remote side.
+
+If both peers support RFC 7427 ("Signature Authentication in IKEv2") specific
+hash algorithms to be used during IKEv2 authentication may be configured.
+The syntax is the same as above. For example, with
+.B pubkey-sha384-sha256
+a public key signature scheme with either SHA-384 or SHA-256 would get used for
+authentication, in that order and depending on the hash algorithms supported by
+the peer.  If no specific hash algorithms are configured, the default is to
+prefer an algorithm that matches or exceeds the strength of the signature key.
+
 For
 .BR eap ,
 an optional EAP method can be appended. Currently defined methods are
@@ -613,7 +617,9 @@ Alternatively, IANA assigned EAP method numbers are accepted. Vendor specific
 EAP methods are defined in the form
 .B eap-type-vendor
 .RB "(e.g. " eap-7-12345 ).
-For
+To specify signature and trust chain constraints for EAP-(T)TLS, append a colon
+to the EAP method, followed by the key type/size and hash algorithm as discussed
+above. For
 .B xauth,
 an XAuth authentication backend can be specified, such as
 .B xauth-generic
@@ -750,11 +756,36 @@ defaults to
 .B left
 or the subject of the certificate configured with
 .BR leftcert .
-Can be an IP address, a fully-qualified domain name, an email address, or
-a keyid. If
+If
 .B leftcert
 is configured the identity has to be confirmed by the certificate.
 
+Can be an IP address, a fully-qualified domain name, an email address or a
+Distinguished Name for which the ID type is determined automatically and the
+string is converted to the appropriate encoding. To enforce a specific identity
+type, a prefix may be used, followed by a colon (:). If the number sign (#)
+follows the colon, the remaining data is interpreted as hex encoding, otherwise
+the string is used as-is as the identification data. Note that this implies
+that no conversion is performed for non-string identities. For example,
+\fIipv4:10.0.0.1\fP does not create a valid ID_IPV4_ADDR IKE identity, as it
+does not get converted to binary 0x0a000001. Instead, one could use
+\fIipv4:#0a000001\fP to get a valid identity, but just using the implicit type
+with automatic conversion is usually simpler. The same applies to the ASN1
+encoded types. The following prefixes are known:
+.BR ipv4 ,
+.BR ipv6 ,
+.BR rfc822 ,
+.BR email ,
+.BR userfqdn ,
+.BR fqdn ,
+.BR dns ,
+.BR asn1dn ,
+.B asn1gn
+and
+.BR keyid .
+Custom type prefixes may be specified by surrounding the numerical type value by
+curly brackets.
+
 For IKEv2 and
 .B rightid
 the prefix
@@ -828,13 +859,15 @@ an address of the given address family will be requested explicitly.
 If an IP address is configured, it will be requested from the responder,
 which is free to respond with a different address.
 .TP
-.BR rightsourceip " = %config | <network>/<netmask> | %poolname"
+.BR rightsourceip " = %config | <network>/<netmask> | <from>-<to> | %poolname"
 Comma separated list of internal source IPs to use in a tunnel for the remote
 peer. If the value is
 .B %config
 on the responder side, the initiator must propose an address which is then
 echoed back. Also supported are address pools expressed as
 \fInetwork\fB/\fInetmask\fR
+and
+\fIfrom\fB-\fIto\fR
 or the use of an external IP address pool using %\fIpoolname\fR,
 where \fIpoolname\fR is the name of the IP address pool used for the lookup.
 .TP
@@ -959,7 +992,9 @@ sets an XFRM mark in the inbound and outbound
 IPsec SAs and policies. If the mask is missing then a default
 mask of
 .B 0xffffffff
-is assumed.
+is assumed. The special value
+.B %unique
+assigns a unique value to each newly created IPsec SA.
 .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 811dc29..d28783b 100644
--- a/scripts/Makefile.in
+++ b/scripts/Makefile.in
@@ -279,6 +279,7 @@ DLLIB = @DLLIB@
 DLLTOOL = @DLLTOOL@
 DSYMUTIL = @DSYMUTIL@
 DUMPBIN = @DUMPBIN@
+EASY_INSTALL = @EASY_INSTALL@
 ECHO_C = @ECHO_C@
 ECHO_N = @ECHO_N@
 ECHO_T = @ECHO_T@
@@ -339,10 +340,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
 PLUGIN_CFLAGS = @PLUGIN_CFLAGS@
 PTHREADLIB = @PTHREADLIB@
 PYTHON = @PYTHON@
+PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@
 PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
 PYTHON_PLATFORM = @PYTHON_PLATFORM@
 PYTHON_PREFIX = @PYTHON_PREFIX@
 PYTHON_VERSION = @PYTHON_VERSION@
+PY_TEST = @PY_TEST@
 RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
@@ -416,6 +419,8 @@ json_CFLAGS = @json_CFLAGS@
 json_LIBS = @json_LIBS@
 libdir = @libdir@
 libexecdir = @libexecdir@
+libiptc_CFLAGS = @libiptc_CFLAGS@
+libiptc_LIBS = @libiptc_LIBS@
 linux_headers = @linux_headers@
 localedir = @localedir@
 localstatedir = @localstatedir@
diff --git a/scripts/dh_speed.c b/scripts/dh_speed.c
index 8a782d8..0643ea9 100644
--- a/scripts/dh_speed.c
+++ b/scripts/dh_speed.c
@@ -15,6 +15,7 @@
 
 #include <stdio.h>
 #include <time.h>
+#include <assert.h>
 #include <library.h>
 #include <utils/debug.h>
 #include <crypto/diffie_hellman.h>
@@ -88,16 +89,16 @@ static void run_test(diffie_hellman_group_t group, int rounds)
 
 	for (round = 0; round < rounds; round++)
 	{
-		l[round]->get_my_public_value(l[round], &chunk);
-		r->set_other_public_value(r, chunk);
+		assert(l[round]->get_my_public_value(l[round], &chunk));
+		assert(r->set_other_public_value(r, chunk));
 		chunk_free(&chunk);
 	}
 
-	r->get_my_public_value(r, &chunk);
+	assert(r->get_my_public_value(r, &chunk));
 	start_timing(&timing);
 	for (round = 0; round < rounds; round++)
 	{
-		l[round]->set_other_public_value(l[round], chunk);
+		assert(l[round]->set_other_public_value(l[round], chunk));
 	}
 	printf(" | S = B^a/s: %8.1f\n", rounds / end_timing(&timing));
 	chunk_free(&chunk);
@@ -143,4 +144,3 @@ int main(int argc, char *argv[])
 	}
 	return 0;
 }
-
diff --git a/src/Makefile.am b/src/Makefile.am
index 38363d4..9608a3a 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -69,7 +69,7 @@ if USE_STROKE
 endif
 
 if USE_UPDOWN
-  SUBDIRS += _updown _updown_espmark
+  SUBDIRS += _updown
 endif
 
 if USE_SCEPCLIENT
diff --git a/src/Makefile.in b/src/Makefile.in
index 2dd0460..7596e7e 100644
--- a/src/Makefile.in
+++ b/src/Makefile.in
@@ -94,7 +94,7 @@ host_triplet = @host@
 @USE_SYSTEMD_TRUE at am__append_15 = charon-systemd
 @USE_NM_TRUE at am__append_16 = charon-nm
 @USE_STROKE_TRUE at am__append_17 = stroke
- at USE_UPDOWN_TRUE@am__append_18 = _updown _updown_espmark
+ at USE_UPDOWN_TRUE@am__append_18 = _updown
 @USE_SCEPCLIENT_TRUE at am__append_19 = scepclient
 @USE_PKI_TRUE at am__append_20 = pki
 @USE_SWANCTL_TRUE at am__append_21 = swanctl
@@ -187,9 +187,9 @@ CTAGS = ctags
 DIST_SUBDIRS = . include libstrongswan libhydra libipsec libsimaka \
 	libtls libradius libtncif libtnccs libpttls libimcv libcharon \
 	starter ipsec _copyright charon charon-systemd charon-nm \
-	stroke _updown _updown_espmark scepclient pki swanctl conftest \
-	dumm libfast manager medsrv pool charon-tkm charon-cmd \
-	charon-svc pt-tls-client checksum aikgen
+	stroke _updown scepclient pki swanctl conftest dumm libfast \
+	manager medsrv pool charon-tkm charon-cmd charon-svc \
+	pt-tls-client checksum aikgen
 DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
 am__relativize = \
   dir0=`pwd`; \
@@ -241,6 +241,7 @@ DLLIB = @DLLIB@
 DLLTOOL = @DLLTOOL@
 DSYMUTIL = @DSYMUTIL@
 DUMPBIN = @DUMPBIN@
+EASY_INSTALL = @EASY_INSTALL@
 ECHO_C = @ECHO_C@
 ECHO_N = @ECHO_N@
 ECHO_T = @ECHO_T@
@@ -301,10 +302,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
 PLUGIN_CFLAGS = @PLUGIN_CFLAGS@
 PTHREADLIB = @PTHREADLIB@
 PYTHON = @PYTHON@
+PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@
 PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
 PYTHON_PLATFORM = @PYTHON_PLATFORM@
 PYTHON_PREFIX = @PYTHON_PREFIX@
 PYTHON_VERSION = @PYTHON_VERSION@
+PY_TEST = @PY_TEST@
 RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
@@ -378,6 +381,8 @@ json_CFLAGS = @json_CFLAGS@
 json_LIBS = @json_LIBS@
 libdir = @libdir@
 libexecdir = @libexecdir@
+libiptc_CFLAGS = @libiptc_CFLAGS@
+libiptc_LIBS = @libiptc_LIBS@
 linux_headers = @linux_headers@
 localedir = @localedir@
 localstatedir = @localstatedir@
diff --git a/src/_copyright/Makefile.in b/src/_copyright/Makefile.in
index a17bbcc..2a4838c 100644
--- a/src/_copyright/Makefile.in
+++ b/src/_copyright/Makefile.in
@@ -195,6 +195,7 @@ DLLIB = @DLLIB@
 DLLTOOL = @DLLTOOL@
 DSYMUTIL = @DSYMUTIL@
 DUMPBIN = @DUMPBIN@
+EASY_INSTALL = @EASY_INSTALL@
 ECHO_C = @ECHO_C@
 ECHO_N = @ECHO_N@
 ECHO_T = @ECHO_T@
@@ -255,10 +256,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
 PLUGIN_CFLAGS = @PLUGIN_CFLAGS@
 PTHREADLIB = @PTHREADLIB@
 PYTHON = @PYTHON@
+PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@
 PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
 PYTHON_PLATFORM = @PYTHON_PLATFORM@
 PYTHON_PREFIX = @PYTHON_PREFIX@
 PYTHON_VERSION = @PYTHON_VERSION@
+PY_TEST = @PY_TEST@
 RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
@@ -332,6 +335,8 @@ json_CFLAGS = @json_CFLAGS@
 json_LIBS = @json_LIBS@
 libdir = @libdir@
 libexecdir = @libexecdir@
+libiptc_CFLAGS = @libiptc_CFLAGS@
+libiptc_LIBS = @libiptc_LIBS@
 linux_headers = @linux_headers@
 localedir = @localedir@
 localstatedir = @localstatedir@
diff --git a/src/_updown/Makefile.am b/src/_updown/Makefile.am
index b6a81f5..32fa042 100644
--- a/src/_updown/Makefile.am
+++ b/src/_updown/Makefile.am
@@ -1,6 +1,5 @@
 ipsec_SCRIPTS = _updown
 CLEANFILES = _updown
-dist_man8_MANS = _updown.8
 EXTRA_DIST = _updown.in
 
 _updown : _updown.in
diff --git a/src/_updown/Makefile.in b/src/_updown/Makefile.in
index a215a25..fe31dff 100644
--- a/src/_updown/Makefile.in
+++ b/src/_updown/Makefile.in
@@ -79,8 +79,7 @@ POST_UNINSTALL = :
 build_triplet = @build@
 host_triplet = @host@
 subdir = src/_updown
-DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
-	$(dist_man8_MANS)
+DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am
 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
 am__aclocal_m4_deps = $(top_srcdir)/m4/config/libtool.m4 \
 	$(top_srcdir)/m4/config/ltoptions.m4 \
@@ -125,7 +124,7 @@ am__uninstall_files_from_dir = { \
     || { echo " ( cd '$$dir' && rm -f" $$files ")"; \
          $(am__cd) "$$dir" && rm -f $$files; }; \
   }
-am__installdirs = "$(DESTDIR)$(ipsecdir)" "$(DESTDIR)$(man8dir)"
+am__installdirs = "$(DESTDIR)$(ipsecdir)"
 SCRIPTS = $(ipsec_SCRIPTS)
 AM_V_P = $(am__v_P_ at AM_V@)
 am__v_P_ = $(am__v_P_ at AM_DEFAULT_V@)
@@ -146,9 +145,6 @@ am__can_run_installinfo = \
     n|no|NO) false;; \
     *) (install-info --version) >/dev/null 2>&1;; \
   esac
-man8dir = $(mandir)/man8
-NROFF = nroff
-MANS = $(dist_man8_MANS)
 am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
 DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
 ACLOCAL = @ACLOCAL@
@@ -176,6 +172,7 @@ DLLIB = @DLLIB@
 DLLTOOL = @DLLTOOL@
 DSYMUTIL = @DSYMUTIL@
 DUMPBIN = @DUMPBIN@
+EASY_INSTALL = @EASY_INSTALL@
 ECHO_C = @ECHO_C@
 ECHO_N = @ECHO_N@
 ECHO_T = @ECHO_T@
@@ -236,10 +233,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
 PLUGIN_CFLAGS = @PLUGIN_CFLAGS@
 PTHREADLIB = @PTHREADLIB@
 PYTHON = @PYTHON@
+PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@
 PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
 PYTHON_PLATFORM = @PYTHON_PLATFORM@
 PYTHON_PREFIX = @PYTHON_PREFIX@
 PYTHON_VERSION = @PYTHON_VERSION@
+PY_TEST = @PY_TEST@
 RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
@@ -313,6 +312,8 @@ json_CFLAGS = @json_CFLAGS@
 json_LIBS = @json_LIBS@
 libdir = @libdir@
 libexecdir = @libexecdir@
+libiptc_CFLAGS = @libiptc_CFLAGS@
+libiptc_LIBS = @libiptc_LIBS@
 linux_headers = @linux_headers@
 localedir = @localedir@
 localstatedir = @localstatedir@
@@ -373,7 +374,6 @@ xml_CFLAGS = @xml_CFLAGS@
 xml_LIBS = @xml_LIBS@
 ipsec_SCRIPTS = _updown
 CLEANFILES = _updown
-dist_man8_MANS = _updown.8
 EXTRA_DIST = _updown.in
 all: all-am
 
@@ -449,47 +449,6 @@ mostlyclean-libtool:
 
 clean-libtool:
 	-rm -rf .libs _libs
-install-man8: $(dist_man8_MANS)
-	@$(NORMAL_INSTALL)
-	@list1='$(dist_man8_MANS)'; \
-	list2=''; \
-	test -n "$(man8dir)" \
-	  && test -n "`echo $$list1$$list2`" \
-	  || exit 0; \
-	echo " $(MKDIR_P) '$(DESTDIR)$(man8dir)'"; \
-	$(MKDIR_P) "$(DESTDIR)$(man8dir)" || 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 '/\.8[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,^[^8][0-9a-z]*$$,8,;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)$(man8dir)/$$inst'"; \
-	    $(INSTALL_DATA) "$$file" "$(DESTDIR)$(man8dir)/$$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)$(man8dir)'"; \
-	    $(INSTALL_DATA) $$files "$(DESTDIR)$(man8dir)" || exit $$?; }; \
-	done; }
-
-uninstall-man8:
-	@$(NORMAL_UNINSTALL)
-	@list='$(dist_man8_MANS)'; test -n "$(man8dir)" || exit 0; \
-	files=`{ for i in $$list; do echo "$$i"; done; \
-	} | 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)
 tags TAGS:
 
 ctags CTAGS:
@@ -529,9 +488,9 @@ distdir: $(DISTFILES)
 	done
 check-am: all-am
 check: check-am
-all-am: Makefile $(SCRIPTS) $(MANS)
+all-am: Makefile $(SCRIPTS)
 installdirs:
-	for dir in "$(DESTDIR)$(ipsecdir)" "$(DESTDIR)$(man8dir)"; do \
+	for dir in "$(DESTDIR)$(ipsecdir)"; do \
 	  test -z "$$dir" || $(MKDIR_P) "$$dir"; \
 	done
 install: install-am
@@ -585,7 +544,7 @@ info: info-am
 
 info-am:
 
-install-data-am: install-ipsecSCRIPTS install-man
+install-data-am: install-ipsecSCRIPTS
 
 install-dvi: install-dvi-am
 
@@ -601,7 +560,7 @@ install-info: install-info-am
 
 install-info-am:
 
-install-man: install-man8
+install-man:
 
 install-pdf: install-pdf-am
 
@@ -629,9 +588,7 @@ ps: ps-am
 
 ps-am:
 
-uninstall-am: uninstall-ipsecSCRIPTS uninstall-man
-
-uninstall-man: uninstall-man8
+uninstall-am: uninstall-ipsecSCRIPTS
 
 .MAKE: install-am install-strip
 
@@ -641,13 +598,12 @@ uninstall-man: uninstall-man8
 	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-ipsecSCRIPTS install-man install-man8 install-pdf \
-	install-pdf-am install-ps install-ps-am install-strip \
-	installcheck installcheck-am installdirs maintainer-clean \
+	install-ipsecSCRIPTS 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-generic \
 	mostlyclean-libtool pdf pdf-am ps ps-am tags-am uninstall \
-	uninstall-am uninstall-ipsecSCRIPTS uninstall-man \
-	uninstall-man8
+	uninstall-am uninstall-ipsecSCRIPTS
 
 
 _updown : _updown.in
diff --git a/src/_updown/_updown.8 b/src/_updown/_updown.8
deleted file mode 100644
index 8c88e5f..0000000
--- a/src/_updown/_updown.8
+++ /dev/null
@@ -1,16 +0,0 @@
-.TH _UPDOWN 8 "27 Apr 2006"
-.SH NAME
-ipsec _updown \- route and firewall manipulation script
-.SH SYNOPSIS
-.I _updown
-is invoked by pluto when it has brought up a new connection. This script
-is used to insert the appropriate routing entries for IPsec operation.
-It can also be used to insert and delete dynamic iptables firewall rules.
-The interface to the script is documented in the pluto man page.
-.SH "SEE ALSO"
-ipsec(8), ipsec_pluto(8).
-.SH HISTORY
-Man page written for the Linux FreeS/WAN project <http://www.freeswan.org/>
-by Michael Richardson. Original program written by Henry Spencer. Extended
-for the Linux strongSwan project <http://www.strongswan.org/> by Andreas
-Steffen.
diff --git a/src/_updown/_updown.in b/src/_updown/_updown.in
index 532bd24..4090fe0 100644
--- a/src/_updown/_updown.in
+++ b/src/_updown/_updown.in
@@ -1,5 +1,5 @@
-#! /bin/sh
-# iproute2 version, default updown script
+#!/bin/sh
+# default updown script
 #
 # Copyright (C) 2003-2004 Nigel Meteringham
 # Copyright (C) 2003-2004 Tuomo Soini
@@ -22,8 +22,6 @@
 # that, and use the (left/right)updown parameters in ipsec.conf to make
 # strongSwan use yours instead of this default one.
 
-# things that this script gets (from ipsec_pluto(8) man page)
-#
 #      PLUTO_VERSION
 #              indicates  what  version of this interface is being
 #              used.  This document describes version  1.1.   This
@@ -128,7 +126,7 @@
 PATH="/sbin:/bin:/usr/sbin:/usr/bin:@sbindir@"
 export PATH
 
-# uncomment to log VPN connections
+# comment to disable logging VPN connections to syslog
 VPN_LOGGING=1
 #
 # tag put in front of each log entry:
@@ -142,21 +140,11 @@ FAC_PRIO=local0.notice
 #
 # local0.notice                   -/var/log/vpn
 
-# in order to use source IP routing the Linux kernel options
-# CONFIG_IP_ADVANCED_ROUTER and CONFIG_IP_MULTIPLE_TABLES
-# must be enabled
-#
-# special routing table for sourceip routes
-SOURCEIP_ROUTING_TABLE=@routing_table@
-#
-# priority of the sourceip routing table
-SOURCEIP_ROUTING_TABLE_PRIO=@routing_table_prio@
-
 # check interface version
 case "$PLUTO_VERSION" in
-1.[0|1])	# Older Pluto?!?  Play it safe, script may be using new features.
+1.[0|1])	# Older release?!?  Play it safe, script may be using new features.
 	echo "$0: obsolete interface version \`$PLUTO_VERSION'," >&2
-	echo "$0: 	called by obsolete Pluto?" >&2
+	echo "$0: 	called by obsolete release?" >&2
 	exit 2
 	;;
 1.*)	;;
@@ -178,120 +166,9 @@ custom:*)		# custom parameters (see above CAUTION comment)
 	;;
 esac
 
-# utility functions for route manipulation
-# Meddling with this stuff should not be necessary and requires great care.
-uproute() {
-	doroute add
-	ip route flush cache
-}
-downroute() {
-	doroute delete
-	ip route flush cache
-}
-
-addsource() {
-	st=0
-	if ! ip -o route get ${PLUTO_MY_SOURCEIP%/*} | grep -q ^local
-	then
-	    it="ip addr add ${PLUTO_MY_SOURCEIP%/*}/32 dev $PLUTO_INTERFACE"
-	    oops="`eval $it 2>&1`"
-	    st=$?
-	    if test " $oops" = " " -a " $st" != " 0"
-	    then
-		oops="silent error, exit status $st"
-	    fi
-	    if test " $oops" != " " -o " $st" != " 0"
-	    then
-		echo "$0: addsource \`$it' failed ($oops)" >&2
-	    fi
-	fi
-	return $st
-}
-
-doroute() {
-	st=0
-
-	if [ -z "$PLUTO_MY_SOURCEIP" ]
-	then
-	    for dir in /etc/sysconfig /etc/conf.d; do
-		if [ -f "$dir/defaultsource" ]
-		then
-		    . "$dir/defaultsource"
-		fi
-	    done
-
-	    if [ -n "$DEFAULTSOURCE" ]
-	    then
-		PLUTO_MY_SOURCEIP=$DEFAULTSOURCE
-	    fi
-        fi
-
-	if [ -z "$KLIPS" -a -z "$PLUTO_MY_SOURCEIP" ]
-	then
-	    # leave because no route entry is required
-	    return $st
-	fi
-
-	parms1="$PLUTO_PEER_CLIENT"
-
-	if [ -n "$PLUTO_NEXT_HOP" ]
-	then
-	    parms2="via $PLUTO_NEXT_HOP"
-	else
-	    parms2="via $PLUTO_PEER"
-	fi
-	parms2="$parms2 dev $PLUTO_INTERFACE"
-
-	parms3=
-	if [ -n "$PLUTO_MY_SOURCEIP" ]
-	then
-	    if test "$1" = "add"
-	    then
-		addsource
-		if ! ip rule list | grep -q "lookup $SOURCEIP_ROUTING_TABLE"
-		then
-		    ip rule add pref $SOURCEIP_ROUTING_TABLE_PRIO table $SOURCEIP_ROUTING_TABLE
-		fi
-	    fi
-	    parms3="$parms3 src ${PLUTO_MY_SOURCEIP%/*} table $SOURCEIP_ROUTING_TABLE"
-	fi
-
-	case "$PLUTO_PEER_CLIENT_NET/$PLUTO_PEER_CLIENT_MASK" in
-	"0.0.0.0/0.0.0.0")
-		# opportunistic encryption work around
-		# need to provide route that eclipses default, without
-		# replacing it.
-		it="ip route $1 0.0.0.0/1 $parms2 $parms3 &&
-			ip route $1 128.0.0.0/1 $parms2 $parms3"
-		;;
-	*)	it="ip route $1 $parms1 $parms2 $parms3"
-		;;
-	esac
-	oops="`eval $it 2>&1`"
-	st=$?
-	if test " $oops" = " " -a " $st" != " 0"
-	then
-	    oops="silent error, exit status $st"
-	fi
-	if test " $oops" != " " -o " $st" != " 0"
-	then
-	    echo "$0: doroute \`$it' failed ($oops)" >&2
-	fi
-	return $st
-}
-
-# in the presence of KLIPS and ipsecN interfaces do not use IPSEC_POLICY
-if [ `echo "$PLUTO_INTERFACE" | grep "ipsec"` ]
-then
-	KLIPS=1
-	IPSEC_POLICY_IN=""
-	IPSEC_POLICY_OUT=""
-else
-	KLIPS=
-	IPSEC_POLICY="-m policy --pol ipsec --proto $PLUTO_PROTO --reqid $PLUTO_REQID"
-	IPSEC_POLICY_IN="$IPSEC_POLICY --dir in"
-	IPSEC_POLICY_OUT="$IPSEC_POLICY --dir out"
-fi
+IPSEC_POLICY="-m policy --pol ipsec --proto $PLUTO_PROTO --reqid $PLUTO_REQID"
+IPSEC_POLICY_IN="$IPSEC_POLICY --dir in"
+IPSEC_POLICY_OUT="$IPSEC_POLICY --dir out"
 
 # use protocol specific options to set ports
 case "$PLUTO_MY_PROTOCOL" in
@@ -334,59 +211,7 @@ fi
 PLUTO_MY_ID=`printf "$PLUTO_MY_ID"`
 PLUTO_PEER_ID=`printf "$PLUTO_PEER_ID"`
 
-# the big choice
 case "$PLUTO_VERB:$1" in
-prepare-host:*|prepare-client:*)
-	if [ -z "$KLIPS" -a -z "$PLUTO_MY_SOURCEIP" ]
-	then
-	    # exit because no route will be added,
-	    # so that existing routes can stay
-	    exit 0
-	fi
-
-	# delete possibly-existing route (preliminary to adding a route)
-	case "$PLUTO_PEER_CLIENT_NET/$PLUTO_PEER_CLIENT_MASK" in
-	"0.0.0.0/0.0.0.0")
-		# need to provide route that eclipses default, without
-		# replacing it.
-		parms1="0.0.0.0/1"
-		parms2="128.0.0.0/1"
-		it="ip route delete $parms1 2>&1 ; ip route delete $parms2 2>&1"
-		oops="`ip route delete $parms1 2>&1 ; ip route delete $parms2 2>&1`"
-		;;
-	*)
-		parms="$PLUTO_PEER_CLIENT"
-		it="ip route delete $parms 2>&1"
-		oops="`ip route delete $parms 2>&1`"
-		;;
-	esac
-	status="$?"
-	if test " $oops" = " " -a " $status" != " 0"
-	then
-		oops="silent error, exit status $status"
-	fi
-	case "$oops" in
-	*'RTNETLINK answers: No such process'*)
-		# This is what route (currently -- not documented!) gives
-		# for "could not find such a route".
-		oops=
-		status=0
-		;;
-	esac
-	if test " $oops" != " " -o " $status" != " 0"
-	then
-		echo "$0: \`$it' failed ($oops)" >&2
-	fi
-	exit $status
-	;;
-route-host:*|route-client:*)
-	# connection to me or my client subnet being routed
-	uproute
-	;;
-unroute-host:*|unroute-client:*)
-	# connection to me or my client subnet being unrouted
-	downroute
-	;;
 up-host:)
 	# connection to me coming up
 	# If you are doing a custom version, firewall commands go here.
@@ -567,16 +392,6 @@ down-client:iptables)
 #
 # IPv6
 #
-prepare-host-v6:*|prepare-client-v6:*)
-	;;
-route-host-v6:*|route-client-v6:*)
-	# connection to me or my client subnet being routed
-	#uproute_v6
-	;;
-unroute-host-v6:*|unroute-client-v6:*)
-	# connection to me or my client subnet being unrouted
-	#downroute_v6
-	;;
 up-host-v6:)
 	# connection to me coming up
 	# If you are doing a custom version, firewall commands go here.
diff --git a/src/_updown_espmark/Makefile.am b/src/_updown_espmark/Makefile.am
deleted file mode 100644
index 4567026..0000000
--- a/src/_updown_espmark/Makefile.am
+++ /dev/null
@@ -1,2 +0,0 @@
-dist_ipsec_SCRIPTS = _updown_espmark
-dist_man8_MANS = _updown_espmark.8
diff --git a/src/_updown_espmark/Makefile.in b/src/_updown_espmark/Makefile.in
deleted file mode 100644
index 51a0d9a..0000000
--- a/src/_updown_espmark/Makefile.in
+++ /dev/null
@@ -1,652 +0,0 @@
-# Makefile.in generated by automake 1.14.1 from Makefile.am.
-# @configure_input@
-
-# Copyright (C) 1994-2013 Free Software Foundation, Inc.
-
-# This Makefile.in is free software; the Free Software Foundation
-# gives unlimited permission to copy and/or distribute it,
-# with or without modifications, as long as this notice is preserved.
-
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
-# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
-# PARTICULAR PURPOSE.
-
- at SET_MAKE@
-
-VPATH = @srcdir@
-am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)'
-am__make_running_with_option = \
-  case $${target_option-} in \
-      ?) ;; \
-      *) echo "am__make_running_with_option: internal error: invalid" \
-              "target option '$${target_option-}' specified" >&2; \
-         exit 1;; \
-  esac; \
-  has_opt=no; \
-  sane_makeflags=$$MAKEFLAGS; \
-  if $(am__is_gnu_make); then \
-    sane_makeflags=$$MFLAGS; \
-  else \
-    case $$MAKEFLAGS in \
-      *\\[\ \	]*) \
-        bs=\\; \
-        sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
-          | sed "s/$$bs$$bs[$$bs $$bs	]*//g"`;; \
-    esac; \
-  fi; \
-  skip_next=no; \
-  strip_trailopt () \
-  { \
-    flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
-  }; \
-  for flg in $$sane_makeflags; do \
-    test $$skip_next = yes && { skip_next=no; continue; }; \
-    case $$flg in \
-      *=*|--*) continue;; \
-        -*I) strip_trailopt 'I'; skip_next=yes;; \
-      -*I?*) strip_trailopt 'I';; \
-        -*O) strip_trailopt 'O'; skip_next=yes;; \
-      -*O?*) strip_trailopt 'O';; \
-        -*l) strip_trailopt 'l'; skip_next=yes;; \
-      -*l?*) strip_trailopt 'l';; \
-      -[dEDm]) skip_next=yes;; \
-      -[JT]) skip_next=yes;; \
-    esac; \
-    case $$flg in \
-      *$$target_option*) has_opt=yes; break;; \
-    esac; \
-  done; \
-  test $$has_opt = yes
-am__make_dryrun = (target_option=n; $(am__make_running_with_option))
-am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
-pkgdatadir = $(datadir)/@PACKAGE@
-pkgincludedir = $(includedir)/@PACKAGE@
-pkglibdir = $(libdir)/@PACKAGE@
-pkglibexecdir = $(libexecdir)/@PACKAGE@
-am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
-install_sh_DATA = $(install_sh) -c -m 644
-install_sh_PROGRAM = $(install_sh) -c
-install_sh_SCRIPT = $(install_sh) -c
-INSTALL_HEADER = $(INSTALL_DATA)
-transform = $(program_transform_name)
-NORMAL_INSTALL = :
-PRE_INSTALL = :
-POST_INSTALL = :
-NORMAL_UNINSTALL = :
-PRE_UNINSTALL = :
-POST_UNINSTALL = :
-build_triplet = @build@
-host_triplet = @host@
-subdir = src/_updown_espmark
-DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
-	$(dist_ipsec_SCRIPTS) $(dist_man8_MANS)
-ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
-am__aclocal_m4_deps = $(top_srcdir)/m4/config/libtool.m4 \
-	$(top_srcdir)/m4/config/ltoptions.m4 \
-	$(top_srcdir)/m4/config/ltsugar.m4 \
-	$(top_srcdir)/m4/config/ltversion.m4 \
-	$(top_srcdir)/m4/config/lt~obsolete.m4 \
-	$(top_srcdir)/m4/macros/split-package-version.m4 \
-	$(top_srcdir)/m4/macros/with.m4 \
-	$(top_srcdir)/m4/macros/enable-disable.m4 \
-	$(top_srcdir)/m4/macros/add-plugin.m4 \
-	$(top_srcdir)/configure.ac
-am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
-	$(ACLOCAL_M4)
-mkinstalldirs = $(install_sh) -d
-CONFIG_HEADER = $(top_builddir)/config.h
-CONFIG_CLEAN_FILES =
-CONFIG_CLEAN_VPATH_FILES =
-am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
-am__vpath_adj = case $$p in \
-    $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
-    *) f=$$p;; \
-  esac;
-am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
-am__install_max = 40
-am__nobase_strip_setup = \
-  srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
-am__nobase_strip = \
-  for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
-am__nobase_list = $(am__nobase_strip_setup); \
-  for p in $$list; do echo "$$p $$p"; done | \
-  sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
-  $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
-    if (++n[$$2] == $(am__install_max)) \
-      { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
-    END { for (dir in files) print dir, files[dir] }'
-am__base_list = \
-  sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
-  sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
-am__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; }; \
-  }
-am__installdirs = "$(DESTDIR)$(ipsecdir)" "$(DESTDIR)$(man8dir)"
-SCRIPTS = $(dist_ipsec_SCRIPTS)
-AM_V_P = $(am__v_P_ at AM_V@)
-am__v_P_ = $(am__v_P_ at AM_DEFAULT_V@)
-am__v_P_0 = false
-am__v_P_1 = :
-AM_V_GEN = $(am__v_GEN_ at AM_V@)
-am__v_GEN_ = $(am__v_GEN_ at AM_DEFAULT_V@)
-am__v_GEN_0 = @echo "  GEN     " $@;
-am__v_GEN_1 = 
-AM_V_at = $(am__v_at_ at AM_V@)
-am__v_at_ = $(am__v_at_ at AM_DEFAULT_V@)
-am__v_at_0 = @
-am__v_at_1 = 
-SOURCES =
-DIST_SOURCES =
-am__can_run_installinfo = \
-  case $$AM_UPDATE_INFO_DIR in \
-    n|no|NO) false;; \
-    *) (install-info --version) >/dev/null 2>&1;; \
-  esac
-man8dir = $(mandir)/man8
-NROFF = nroff
-MANS = $(dist_man8_MANS)
-am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
-DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
-ACLOCAL = @ACLOCAL@
-ALLOCA = @ALLOCA@
-AMTAR = @AMTAR@
-AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
-AR = @AR@
-AUTOCONF = @AUTOCONF@
-AUTOHEADER = @AUTOHEADER@
-AUTOMAKE = @AUTOMAKE@
-AWK = @AWK@
-BFDLIB = @BFDLIB@
-BTLIB = @BTLIB@
-CC = @CC@
-CCDEPMODE = @CCDEPMODE@
-CFLAGS = @CFLAGS@
-COVERAGE_CFLAGS = @COVERAGE_CFLAGS@
-COVERAGE_LDFLAGS = @COVERAGE_LDFLAGS@
-CPP = @CPP@
-CPPFLAGS = @CPPFLAGS@
-CYGPATH_W = @CYGPATH_W@
-DEFS = @DEFS@
-DEPDIR = @DEPDIR@
-DLLIB = @DLLIB@
-DLLTOOL = @DLLTOOL@
-DSYMUTIL = @DSYMUTIL@
-DUMPBIN = @DUMPBIN@
-ECHO_C = @ECHO_C@
-ECHO_N = @ECHO_N@
-ECHO_T = @ECHO_T@
-EGREP = @EGREP@
-EXEEXT = @EXEEXT@
-FGREP = @FGREP@
-GEM = @GEM@
-GENHTML = @GENHTML@
-GPERF = @GPERF@
-GPRBUILD = @GPRBUILD@
-GREP = @GREP@
-INSTALL = @INSTALL@
-INSTALL_DATA = @INSTALL_DATA@
-INSTALL_PROGRAM = @INSTALL_PROGRAM@
-INSTALL_SCRIPT = @INSTALL_SCRIPT@
-INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
-LCOV = @LCOV@
-LD = @LD@
-LDFLAGS = @LDFLAGS@
-LEX = @LEX@
-LEXLIB = @LEXLIB@
-LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@
-LIBOBJS = @LIBOBJS@
-LIBS = @LIBS@
-LIBTOOL = @LIBTOOL@
-LIPO = @LIPO@
-LN_S = @LN_S@
-LTLIBOBJS = @LTLIBOBJS@
-MAKEINFO = @MAKEINFO@
-MANIFEST_TOOL = @MANIFEST_TOOL@
-MKDIR_P = @MKDIR_P@
-MYSQLCFLAG = @MYSQLCFLAG@
-MYSQLCONFIG = @MYSQLCONFIG@
-MYSQLLIB = @MYSQLLIB@
-NM = @NM@
-NMEDIT = @NMEDIT@
-OBJDUMP = @OBJDUMP@
-OBJEXT = @OBJEXT@
-OPENSSL_LIB = @OPENSSL_LIB@
-OTOOL = @OTOOL@
-OTOOL64 = @OTOOL64@
-PACKAGE = @PACKAGE@
-PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
-PACKAGE_NAME = @PACKAGE_NAME@
-PACKAGE_STRING = @PACKAGE_STRING@
-PACKAGE_TARNAME = @PACKAGE_TARNAME@
-PACKAGE_URL = @PACKAGE_URL@
-PACKAGE_VERSION = @PACKAGE_VERSION@
-PACKAGE_VERSION_BUILD = @PACKAGE_VERSION_BUILD@
-PACKAGE_VERSION_MAJOR = @PACKAGE_VERSION_MAJOR@
-PACKAGE_VERSION_MINOR = @PACKAGE_VERSION_MINOR@
-PACKAGE_VERSION_REVIEW = @PACKAGE_VERSION_REVIEW@
-PATH_SEPARATOR = @PATH_SEPARATOR@
-PERL = @PERL@
-PKG_CONFIG = @PKG_CONFIG@
-PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
-PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
-PLUGIN_CFLAGS = @PLUGIN_CFLAGS@
-PTHREADLIB = @PTHREADLIB@
-PYTHON = @PYTHON@
-PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
-PYTHON_PLATFORM = @PYTHON_PLATFORM@
-PYTHON_PREFIX = @PYTHON_PREFIX@
-PYTHON_VERSION = @PYTHON_VERSION@
-RANLIB = @RANLIB@
-RTLIB = @RTLIB@
-RUBY = @RUBY@
-RUBYGEMDIR = @RUBYGEMDIR@
-RUBYINCLUDE = @RUBYINCLUDE@
-RUBYLIB = @RUBYLIB@
-SED = @SED@
-SET_MAKE = @SET_MAKE@
-SHELL = @SHELL@
-SOCKLIB = @SOCKLIB@
-STRIP = @STRIP@
-UNWINDLIB = @UNWINDLIB@
-VERSION = @VERSION@
-YACC = @YACC@
-YFLAGS = @YFLAGS@
-abs_builddir = @abs_builddir@
-abs_srcdir = @abs_srcdir@
-abs_top_builddir = @abs_top_builddir@
-abs_top_srcdir = @abs_top_srcdir@
-ac_ct_AR = @ac_ct_AR@
-ac_ct_CC = @ac_ct_CC@
-ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
-aikgen_plugins = @aikgen_plugins@
-am__include = @am__include@
-am__leading_dot = @am__leading_dot@
-am__quote = @am__quote@
-am__tar = @am__tar@
-am__untar = @am__untar@
-attest_plugins = @attest_plugins@
-bindir = @bindir@
-build = @build@
-build_alias = @build_alias@
-build_cpu = @build_cpu@
-build_os = @build_os@
-build_vendor = @build_vendor@
-builddir = @builddir@
-c_plugins = @c_plugins@
-charon_natt_port = @charon_natt_port@
-charon_plugins = @charon_plugins@
-charon_udp_port = @charon_udp_port@
-clearsilver_LIBS = @clearsilver_LIBS@
-cmd_plugins = @cmd_plugins@
-datadir = @datadir@
-datarootdir = @datarootdir@
-dbusservicedir = @dbusservicedir@
-dev_headers = @dev_headers@
-docdir = @docdir@
-dvidir = @dvidir@
-exec_prefix = @exec_prefix@
-fips_mode = @fips_mode@
-gtk_CFLAGS = @gtk_CFLAGS@
-gtk_LIBS = @gtk_LIBS@
-h_plugins = @h_plugins@
-host = @host@
-host_alias = @host_alias@
-host_cpu = @host_cpu@
-host_os = @host_os@
-host_vendor = @host_vendor@
-htmldir = @htmldir@
-imcvdir = @imcvdir@
-includedir = @includedir@
-infodir = @infodir@
-install_sh = @install_sh@
-ipsec_script = @ipsec_script@
-ipsec_script_upper = @ipsec_script_upper@
-ipsecdir = @ipsecdir@
-ipsecgroup = @ipsecgroup@
-ipseclibdir = @ipseclibdir@
-ipsecuser = @ipsecuser@
-json_CFLAGS = @json_CFLAGS@
-json_LIBS = @json_LIBS@
-libdir = @libdir@
-libexecdir = @libexecdir@
-linux_headers = @linux_headers@
-localedir = @localedir@
-localstatedir = @localstatedir@
-maemo_CFLAGS = @maemo_CFLAGS@
-maemo_LIBS = @maemo_LIBS@
-manager_plugins = @manager_plugins@
-mandir = @mandir@
-medsrv_plugins = @medsrv_plugins@
-mkdir_p = @mkdir_p@
-nm_CFLAGS = @nm_CFLAGS@
-nm_LIBS = @nm_LIBS@
-nm_ca_dir = @nm_ca_dir@
-nm_plugins = @nm_plugins@
-oldincludedir = @oldincludedir@
-pcsclite_CFLAGS = @pcsclite_CFLAGS@
-pcsclite_LIBS = @pcsclite_LIBS@
-pdfdir = @pdfdir@
-piddir = @piddir@
-pkgpyexecdir = @pkgpyexecdir@
-pkgpythondir = @pkgpythondir@
-pki_plugins = @pki_plugins@
-plugindir = @plugindir@
-pool_plugins = @pool_plugins@
-prefix = @prefix@
-program_transform_name = @program_transform_name@
-psdir = @psdir@
-pyexecdir = @pyexecdir@
-pythondir = @pythondir@
-random_device = @random_device@
-resolv_conf = @resolv_conf@
-routing_table = @routing_table@
-routing_table_prio = @routing_table_prio@
-s_plugins = @s_plugins@
-sbindir = @sbindir@
-scepclient_plugins = @scepclient_plugins@
-scripts_plugins = @scripts_plugins@
-sharedstatedir = @sharedstatedir@
-soup_CFLAGS = @soup_CFLAGS@
-soup_LIBS = @soup_LIBS@
-srcdir = @srcdir@
-starter_plugins = @starter_plugins@
-strongswan_conf = @strongswan_conf@
-strongswan_options = @strongswan_options@
-swanctldir = @swanctldir@
-sysconfdir = @sysconfdir@
-systemd_daemon_CFLAGS = @systemd_daemon_CFLAGS@
-systemd_daemon_LIBS = @systemd_daemon_LIBS@
-systemd_journal_CFLAGS = @systemd_journal_CFLAGS@
-systemd_journal_LIBS = @systemd_journal_LIBS@
-systemdsystemunitdir = @systemdsystemunitdir@
-t_plugins = @t_plugins@
-target_alias = @target_alias@
-top_build_prefix = @top_build_prefix@
-top_builddir = @top_builddir@
-top_srcdir = @top_srcdir@
-urandom_device = @urandom_device@
-xml_CFLAGS = @xml_CFLAGS@
-xml_LIBS = @xml_LIBS@
-dist_ipsec_SCRIPTS = _updown_espmark
-dist_man8_MANS = _updown_espmark.8
-all: all-am
-
-.SUFFIXES:
-$(srcdir)/Makefile.in:  $(srcdir)/Makefile.am  $(am__configure_deps)
-	@for dep in $?; do \
-	  case '$(am__configure_deps)' in \
-	    *$$dep*) \
-	      ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
-	        && { if test -f $@; then exit 0; else break; fi; }; \
-	      exit 1;; \
-	  esac; \
-	done; \
-	echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/_updown_espmark/Makefile'; \
-	$(am__cd) $(top_srcdir) && \
-	  $(AUTOMAKE) --gnu src/_updown_espmark/Makefile
-.PRECIOUS: Makefile
-Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
-	@case '$?' in \
-	  *config.status*) \
-	    cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
-	  *) \
-	    echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
-	    cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
-	esac;
-
-$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
-	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
-
-$(top_srcdir)/configure:  $(am__configure_deps)
-	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
-$(ACLOCAL_M4):  $(am__aclocal_m4_deps)
-	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
-$(am__aclocal_m4_deps):
-install-dist_ipsecSCRIPTS: $(dist_ipsec_SCRIPTS)
-	@$(NORMAL_INSTALL)
-	@list='$(dist_ipsec_SCRIPTS)'; 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; \
-	  if test -f "$$d$$p"; then echo "$$d$$p"; echo "$$p"; else :; fi; \
-	done | \
-	sed -e 'p;s,.*/,,;n' \
-	    -e 'h;s|.*|.|' \
-	    -e 'p;x;s,.*/,,;$(transform)' | sed 'N;N;N;s,\n, ,g' | \
-	$(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1; } \
-	  { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \
-	    if ($$2 == $$4) { files[d] = files[d] " " $$1; \
-	      if (++n[d] == $(am__install_max)) { \
-		print "f", d, files[d]; n[d] = 0; files[d] = "" } } \
-	    else { print "f", d "/" $$4, $$1 } } \
-	  END { for (d in files) print "f", d, files[d] }' | \
-	while read type dir files; do \
-	     if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \
-	     test -z "$$files" || { \
-	       echo " $(INSTALL_SCRIPT) $$files '$(DESTDIR)$(ipsecdir)$$dir'"; \
-	       $(INSTALL_SCRIPT) $$files "$(DESTDIR)$(ipsecdir)$$dir" || exit $$?; \
-	     } \
-	; done
-
-uninstall-dist_ipsecSCRIPTS:
-	@$(NORMAL_UNINSTALL)
-	@list='$(dist_ipsec_SCRIPTS)'; test -n "$(ipsecdir)" || exit 0; \
-	files=`for p in $$list; do echo "$$p"; done | \
-	       sed -e 's,.*/,,;$(transform)'`; \
-	dir='$(DESTDIR)$(ipsecdir)'; $(am__uninstall_files_from_dir)
-
-mostlyclean-libtool:
-	-rm -f *.lo
-
-clean-libtool:
-	-rm -rf .libs _libs
-install-man8: $(dist_man8_MANS)
-	@$(NORMAL_INSTALL)
-	@list1='$(dist_man8_MANS)'; \
-	list2=''; \
-	test -n "$(man8dir)" \
-	  && test -n "`echo $$list1$$list2`" \
-	  || exit 0; \
-	echo " $(MKDIR_P) '$(DESTDIR)$(man8dir)'"; \
-	$(MKDIR_P) "$(DESTDIR)$(man8dir)" || 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 '/\.8[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,^[^8][0-9a-z]*$$,8,;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)$(man8dir)/$$inst'"; \
-	    $(INSTALL_DATA) "$$file" "$(DESTDIR)$(man8dir)/$$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)$(man8dir)'"; \
-	    $(INSTALL_DATA) $$files "$(DESTDIR)$(man8dir)" || exit $$?; }; \
-	done; }
-
-uninstall-man8:
-	@$(NORMAL_UNINSTALL)
-	@list='$(dist_man8_MANS)'; test -n "$(man8dir)" || exit 0; \
-	files=`{ for i in $$list; do echo "$$i"; done; \
-	} | 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)
-tags TAGS:
-
-ctags CTAGS:
-
-cscope cscopelist:
-
-
-distdir: $(DISTFILES)
-	@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
-	topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
-	list='$(DISTFILES)'; \
-	  dist_files=`for file in $$list; do echo $$file; done | \
-	  sed -e "s|^$$srcdirstrip/||;t" \
-	      -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
-	case $$dist_files in \
-	  */*) $(MKDIR_P) `echo "$$dist_files" | \
-			   sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
-			   sort -u` ;; \
-	esac; \
-	for file in $$dist_files; do \
-	  if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
-	  if test -d $$d/$$file; then \
-	    dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
-	    if test -d "$(distdir)/$$file"; then \
-	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
-	    fi; \
-	    if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
-	      cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
-	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
-	    fi; \
-	    cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
-	  else \
-	    test -f "$(distdir)/$$file" \
-	    || cp -p $$d/$$file "$(distdir)/$$file" \
-	    || exit 1; \
-	  fi; \
-	done
-check-am: all-am
-check: check-am
-all-am: Makefile $(SCRIPTS) $(MANS)
-installdirs:
-	for dir in "$(DESTDIR)$(ipsecdir)" "$(DESTDIR)$(man8dir)"; do \
-	  test -z "$$dir" || $(MKDIR_P) "$$dir"; \
-	done
-install: install-am
-install-exec: install-exec-am
-install-data: install-data-am
-uninstall: uninstall-am
-
-install-am: all-am
-	@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
-
-installcheck: installcheck-am
-install-strip:
-	if test -z '$(STRIP)'; then \
-	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
-	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
-	      install; \
-	else \
-	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
-	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
-	    "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
-	fi
-mostlyclean-generic:
-
-clean-generic:
-
-distclean-generic:
-	-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
-	-test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
-
-maintainer-clean-generic:
-	@echo "This command is intended for maintainers to use"
-	@echo "it deletes files that may require special tools to rebuild."
-clean: clean-am
-
-clean-am: clean-generic clean-libtool mostlyclean-am
-
-distclean: distclean-am
-	-rm -f Makefile
-distclean-am: clean-am distclean-generic
-
-dvi: dvi-am
-
-dvi-am:
-
-html: html-am
-
-html-am:
-
-info: info-am
-
-info-am:
-
-install-data-am: install-dist_ipsecSCRIPTS install-man
-
-install-dvi: install-dvi-am
-
-install-dvi-am:
-
-install-exec-am:
-
-install-html: install-html-am
-
-install-html-am:
-
-install-info: install-info-am
-
-install-info-am:
-
-install-man: install-man8
-
-install-pdf: install-pdf-am
-
-install-pdf-am:
-
-install-ps: install-ps-am
-
-install-ps-am:
-
-installcheck-am:
-
-maintainer-clean: maintainer-clean-am
-	-rm -f Makefile
-maintainer-clean-am: distclean-am maintainer-clean-generic
-
-mostlyclean: mostlyclean-am
-
-mostlyclean-am: mostlyclean-generic mostlyclean-libtool
-
-pdf: pdf-am
-
-pdf-am:
-
-ps: ps-am
-
-ps-am:
-
-uninstall-am: uninstall-dist_ipsecSCRIPTS uninstall-man
-
-uninstall-man: uninstall-man8
-
-.MAKE: install-am install-strip
-
-.PHONY: all all-am check check-am clean clean-generic clean-libtool \
-	cscopelist-am ctags-am distclean distclean-generic \
-	distclean-libtool distdir dvi dvi-am html html-am info info-am \
-	install install-am install-data install-data-am \
-	install-dist_ipsecSCRIPTS 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-strip installcheck installcheck-am installdirs \
-	maintainer-clean maintainer-clean-generic mostlyclean \
-	mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
-	tags-am uninstall uninstall-am uninstall-dist_ipsecSCRIPTS \
-	uninstall-man uninstall-man8
-
-
-# Tell versions [3.59,3.63) of GNU make to not export all variables.
-# Otherwise a system limit (for SysV at least) may be exceeded.
-.NOEXPORT:
diff --git a/src/_updown_espmark/_updown_espmark b/src/_updown_espmark/_updown_espmark
deleted file mode 100644
index 864a917..0000000
--- a/src/_updown_espmark/_updown_espmark
+++ /dev/null
@@ -1,438 +0,0 @@
-#! /bin/sh
-# iproute2 version, default updown script
-#
-# Copyright (C) 2003-2004 Nigel Meteringham
-# Copyright (C) 2003-2004 Tuomo Soini
-# Copyright (C) 2002-2004 Michael Richardson
-# Copyright (C) 2005      Andreas Steffen <andreas.steffen at strongsec.com>
-#
-# This program is free software; you can redistribute it and/or modify it
-# under the terms of the GNU General Public License as published by the
-# Free Software Foundation; either version 2 of the License, or (at your
-# option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
-#
-# This program is distributed in the hope that it will be useful, but
-# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
-# or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
-# for more details.
-
-
-
-# CAUTION:  Installing a new version of strongSwan will install a new
-# copy of this script, wiping out any custom changes you make.  If
-# you need changes, make a copy of this under another name, and customize
-# that, and use the (left/right)updown parameters in ipsec.conf to make
-# FreeS/WAN use yours instead of this default one.
-
-# things that this script gets (from ipsec_pluto(8) man page)
-#
-#
-#      PLUTO_VERSION
-#              indicates  what  version of this interface is being
-#              used.  This document describes version  1.1.   This
-#              is upwardly compatible with version 1.0.
-#
-#       PLUTO_VERB
-#              specifies the name of the operation to be performed
-#              (prepare-host, prepare-client, up-host, up-client,
-#              down-host, or down-client).  If the address family
-#              for security gateway to security gateway communica-
-#              tions is IPv6, then a suffix of -v6 is added to the
-#              verb.
-#
-#       PLUTO_CONNECTION
-#              is the name of the  connection  for  which  we  are
-#              routing.
-#
-#       PLUTO_INTERFACE
-#              is the name of the ipsec interface to be used.
-#
-#       PLUTO_ME
-#              is the IP address of our host.
-#
-#       PLUTO_MY_ID
-#              is the ID of our host.
-#
-#       PLUTO_MY_CLIENT
-#              is the IP address / count of our client subnet.  If
-#              the  client  is  just  the  host,  this will be the
-#              host's own IP address / max (where max  is  32  for
-#              IPv4 and 128 for IPv6).
-#
-#       PLUTO_MY_SOURCEIP
-#              if non-empty, then the source address for the route will be
-#              set to this IP address.
-#
-#       PLUTO_MY_PROTOCOL
-#              is the IP protocol that will be transported.
-#
-#       PLUTO_MY_PORT
-#              is  the  UDP/TCP  port  to  which  the IPsec SA  is
-#              restricted on our side.
-#
-#       PLUTO_PEER
-#              is the IP address of our peer.
-#
-#       PLUTO_PEER_ID
-#              is the ID of our peer.
-#
-#       PLUTO_PEER_CLIENT
-#              is the IP address / count of the peer's client sub-
-#              net.   If the client is just the peer, this will be
-#              the peer's own IP address / max (where  max  is  32
-#              for IPv4 and 128 for IPv6).
-#
-#       PLUTO_PEER_PROTOCOL
-#              is the IP protocol that will be transported.
-#
-#       PLUTO_PEER_PORT
-#              is  the  UDP/TCP  port  to  which  the IPsec SA  is
-#              restricted on the peer side.
-#
-#       PLUTO_XAUTH_ID
-#              is an optional user ID employed by the XAUTH protocol
-#
-#       PLUTO_MARK_IN
-#              is an optional XFRM mark set on the inbound IPsec SA
-#
-#       PLUTO_MARK_OUT
-#              is an optional XFRM mark set on the outbound IPsec SA
-#
-#       PLUTO_UDP_ENC
-#              contains the remote UDP port in the case of ESP_IN_UDP
-#              encapsulation
-#
-
-# logging of VPN connections
-#
-# tag put in front of each log entry:
-TAG=vpn
-#
-# syslog facility and priority used:
-FAC_PRIO=local0.notice
-#
-# to create a special vpn logging file, put the following line into
-# the syslog configuration file /etc/syslog.conf:
-#
-# local0.notice                   -/var/log/vpn
-#
-
-# check interface version
-case "$PLUTO_VERSION" in
-1.[0])	# Older Pluto?!?  Play it safe, script may be using new features.
-	echo "$0: obsolete interface version \`$PLUTO_VERSION'," >&2
-	echo "$0: 	called by obsolete Pluto?" >&2
-	exit 2
-	;;
-1.*)	;;
-*)	echo "$0: unknown interface version \`$PLUTO_VERSION'" >&2
-	exit 2
-	;;
-esac
-
-# check parameter(s)
-case "$1:$*" in
-':')			# no parameters
-	;;
-ipfwadm:ipfwadm)	# due to (left/right)firewall; for default script only
-	;;
-custom:*)		# custom parameters (see above CAUTION comment)
-	;;
-*)	echo "$0: unknown parameters \`$*'" >&2
-	exit 2
-	;;
-esac
-
-# utility functions for route manipulation
-# Meddling with this stuff should not be necessary and requires great care.
-uproute() {
-	doroute add
-	ip route flush cache
-}
-downroute() {
-	doroute delete
-	ip route flush cache
-}
-
-addsource() {
-	st=0
-	if ! ip -o route get ${PLUTO_MY_SOURCEIP%/*} | grep -q ^local
-	then
-	    it="ip addr add ${PLUTO_MY_SOURCEIP%/*}/32 dev $PLUTO_INTERFACE"
-	    oops="`eval $it 2>&1`"
-	    st=$?
-	    if test " $oops" = " " -a " $st" != " 0"
-	    then
-		oops="silent error, exit status $st"
-	    fi
-	    if test " $oops" != " " -o " $st" != " 0"
-	    then
-		echo "$0: addsource \`$it' failed ($oops)" >&2
-	    fi
-	fi
-	return $st
-}
-
-doroute() {
-	st=0
-	parms="$PLUTO_PEER_CLIENT"
-
-	parms2=
-	if [ -n "$PLUTO_NEXT_HOP" ]
-	then
-	   parms2="via $PLUTO_NEXT_HOP"
-	fi
-	parms2="$parms2 dev $PLUTO_INTERFACE"
-
-	if [ -z "$PLUTO_MY_SOURCEIP" ]
-	then
-            for dir in /etc/sysconfig /etc/conf.d; do
-                if [ -f "$dir/defaultsource" ]
-                then
-                    . "$dir/defaultsource"
-                fi
-            done
-
-	    if [ -n "$DEFAULTSOURCE" ]
-	    then
-		PLUTO_MY_SOURCEIP=$DEFAULTSOURCE
-	    fi
-        fi
-
-	parms3=
-	if test "$1" = "add" -a -n "$PLUTO_MY_SOURCEIP"
-	then
-	    addsource
-	    parms3="$parms3 src ${PLUTO_MY_SOURCEIP%/*}"
-	fi
-
-	case "$PLUTO_PEER_CLIENT_NET/$PLUTO_PEER_CLIENT_MASK" in
-	"0.0.0.0/0.0.0.0")
-		# opportunistic encryption work around
-		# need to provide route that eclipses default, without
-		# replacing it.
-		it="ip route $1 0.0.0.0/1 $parms2 $parms3 &&
-			ip route $1 128.0.0.0/1 $parms2 $parms3"
-		;;
-	*)	it="ip route $1 $parms $parms2 $parms3"
-		;;
-	esac
-	oops="`eval $it 2>&1`"
-	st=$?
-	if test " $oops" = " " -a " $st" != " 0"
-	then
-	    oops="silent error, exit status $st"
-	fi
-	if test " $oops" != " " -o " $st" != " 0"
-	then
-	    echo "$0: doroute \`$it' failed ($oops)" >&2
-	fi
-	return $st
-}
-
-# define ESP mark
-ESP_MARK=50
-
-# add the following static rule to the INPUT chain in the mangle table
-# iptables -t mangle -A INPUT -p 50 -j MARK --set-mark 50
-
-# NAT traversal via UDP encapsulation is supported with the rule
-# iptables -t mangle -A INPUT -p udp --dport 4500 -j MARK --set-mark 50
-
-# in the presence of KLIPS and ipsecN interfaces do not use ESP mark rules
-if [ `echo "$PLUTO_INTERFACE" | grep "ipsec"` ]
-then
-	CHECK_MARK=""
-else
-	CHECK_MARK="-m mark --mark $ESP_MARK"
-fi
-
-# are there port numbers?
-if [ "$PLUTO_MY_PORT" != 0 ]
-then
-	S_MY_PORT="--sport $PLUTO_MY_PORT"
-	D_MY_PORT="--dport $PLUTO_MY_PORT"
-fi
-if [ "$PLUTO_PEER_PORT" != 0 ]
-then
-	S_PEER_PORT="--sport $PLUTO_PEER_PORT"
-	D_PEER_PORT="--dport $PLUTO_PEER_PORT"
-fi
-
-# resolve octal escape sequences
-PLUTO_MY_ID=`printf "$PLUTO_MY_ID"`
-PLUTO_PEER_ID=`printf "$PLUTO_PEER_ID"`
-
-# the big choice
-case "$PLUTO_VERB:$1" in
-prepare-host:*|prepare-client:*)
-	# delete possibly-existing route (preliminary to adding a route)
-	case "$PLUTO_PEER_CLIENT_NET/$PLUTO_PEER_CLIENT_MASK" in
-	"0.0.0.0/0.0.0.0")
-		# need to provide route that eclipses default, without
-		# replacing it.
-		parms1="0.0.0.0/1"
-		parms2="128.0.0.0/1"
-		it="ip route delete $parms1 2>&1 ; ip route delete $parms2 2>&1"
-		oops="`ip route delete $parms1 2>&1 ; ip route delete $parms2 2>&1`"
-		;;
-	*)
-		parms="$PLUTO_PEER_CLIENT"
-		it="ip route delete $parms 2>&1"
-		oops="`ip route delete $parms 2>&1`"
-		;;
-	esac
-	status="$?"
-	if test " $oops" = " " -a " $status" != " 0"
-	then
-		oops="silent error, exit status $status"
-	fi
-	case "$oops" in
-	*'RTNETLINK answers: No such process'*)
-		# This is what route (currently -- not documented!) gives
-		# for "could not find such a route".
-		oops=
-		status=0
-		;;
-	esac
-	if test " $oops" != " " -o " $status" != " 0"
-	then
-		echo "$0: \`$it' failed ($oops)" >&2
-	fi
-	exit $status
-	;;
-route-host:*|route-client:*)
-	# connection to me or my client subnet being routed
-	uproute
-	;;
-unroute-host:*|unroute-client:*)
-	# connection to me or my client subnet being unrouted
-	downroute
-	;;
-up-host:*)
-	# connection to me coming up
-	# If you are doing a custom version, firewall commands go here.
-	iptables -I INPUT 1 -i $PLUTO_INTERFACE -p $PLUTO_MY_PROTOCOL \
-	    -s $PLUTO_PEER_CLIENT_NET/$PLUTO_PEER_CLIENT_MASK $S_PEER_PORT \
-	    -d $PLUTO_ME $D_MY_PORT $CHECK_MARK -j ACCEPT
-	iptables -I OUTPUT 1 -o $PLUTO_INTERFACE -p $PLUTO_PEER_PROTOCOL \
-	    -s $PLUTO_ME $S_MY_PORT \
-	    -d $PLUTO_PEER_CLIENT_NET/$PLUTO_PEER_CLIENT_MASK $D_PEER_PORT -j ACCEPT
-	#
-	if [ "$PLUTO_PEER_CLIENT" = "$PLUTO_PEER/32" ]
-	then
-	  logger -t $TAG -p $FAC_PRIO \
-	    "+ $PLUTO_PEER_ID $PLUTO_PEER -- $PLUTO_ME"
-	else
-	  logger -t $TAG -p $FAC_PRIO \
-	    "+ $PLUTO_PEER_ID $PLUTO_PEER_CLIENT == $PLUTO_PEER -- $PLUTO_ME"
-	fi
-	;;
-down-host:*)
-	# connection to me going down
-	# If you are doing a custom version, firewall commands go here.
-	# connection to me going down
-	# If you are doing a custom version, firewall commands go here.
-	iptables -D INPUT -i $PLUTO_INTERFACE -p $PLUTO_MY_PROTOCOL \
-	    -s $PLUTO_PEER_CLIENT_NET/$PLUTO_PEER_CLIENT_MASK $S_PEER_PORT \
-	    -d $PLUTO_ME $D_MY_PORT $CHECK_MARK -j ACCEPT
-	iptables -D OUTPUT -o $PLUTO_INTERFACE -p $PLUTO_PEER_PROTOCOL \
-	    -s $PLUTO_ME $S_MY_PORT \
-	    -d $PLUTO_PEER_CLIENT_NET/$PLUTO_PEER_CLIENT_MASK $D_PEER_PORT -j ACCEPT
-	#
-	if [ "$PLUTO_PEER_CLIENT" = "$PLUTO_PEER/32" ]
-	then
-	  logger -t $TAG -p $FAC_PRIO -- \
-	    "- $PLUTO_PEER_ID $PLUTO_PEER -- $PLUTO_ME"
-	else
-	  logger -t $TAG -p $FAC_PRIO -- \
-	  "- $PLUTO_PEER_ID $PLUTO_PEER_CLIENT == $PLUTO_PEER -- $PLUTO_ME"
-	fi
-	;;
-up-client:)
-	# connection to my client subnet coming up
-	# If you are doing a custom version, firewall commands go here.
-	iptables -I FORWARD 1 -o $PLUTO_INTERFACE -p $PLUTO_PEER_PROTOCOL \
-	    -s $PLUTO_MY_CLIENT_NET/$PLUTO_MY_CLIENT_MASK $S_MY_PORT \
-	    -d $PLUTO_PEER_CLIENT_NET/$PLUTO_PEER_CLIENT_MASK $D_PEER_PORT -j ACCEPT
-	iptables -I FORWARD 1 -i $PLUTO_INTERFACE -p $PLUTO_MY_PROTOCOL \
-	    -s $PLUTO_PEER_CLIENT_NET/$PLUTO_PEER_CLIENT_MASK $S_PEER_PORT \
-	    -d $PLUTO_MY_CLIENT_NET/$PLUTO_MY_CLIENT_MASK $D_MY_PORT \
-	       $CHECK_MARK -j ACCEPT
-	#
-	if [ "$PLUTO_PEER_CLIENT" = "$PLUTO_PEER/32" ]
-	then
-	  logger -t $TAG -p $FAC_PRIO \
-	    "+ $PLUTO_PEER_ID $PLUTO_PEER -- $PLUTO_ME == $PLUTO_MY_CLIENT"
-	else
-	  logger -t $TAG -p $FAC_PRIO \
-	    "+ $PLUTO_PEER_ID $PLUTO_PEER_CLIENT == $PLUTO_PEER -- $PLUTO_ME == $PLUTO_MY_CLIENT"
-	fi
-	;;
-down-client:)
-	# connection to my client subnet going down
-	# If you are doing a custom version, firewall commands go here.
-	iptables -D FORWARD -o $PLUTO_INTERFACE -p $PLUTO_PEER_PROTOCOL \
-	    -s $PLUTO_MY_CLIENT_NET/$PLUTO_MY_CLIENT_MASK $S_MY_PORT \
-	    -d $PLUTO_PEER_CLIENT_NET/$PLUTO_PEER_CLIENT_MASK $D_PEER_PORT -j ACCEPT
-	iptables -D FORWARD -i $PLUTO_INTERFACE -p $PLUTO_MY_PROTOCOL \
-	    -s $PLUTO_PEER_CLIENT_NET/$PLUTO_PEER_CLIENT_MASK $S_PEER_PORT \
-	    -d $PLUTO_MY_CLIENT_NET/$PLUTO_MY_CLIENT_MASK $D_MY_PORT \
-	       $CHECK_MARK -j ACCEPT
-	#
-	if [ "$PLUTO_PEER_CLIENT" = "$PLUTO_PEER/32" ]
-	then
-	  logger -t $TAG -p $FAC_PRIO -- \
-	    "- $PLUTO_PEER_ID $PLUTO_PEER -- $PLUTO_ME == $PLUTO_MY_CLIENT"
-	else
-	  logger -t $TAG -p $FAC_PRIO -- \
-	    "- $PLUTO_PEER_ID $PLUTO_PEER_CLIENT == $PLUTO_PEER -- $PLUTO_ME == $PLUTO_MY_CLIENT"
-	fi
-	;;
-up-client:ipfwadm)
-	# connection to client subnet, with (left/right)firewall=yes, coming up
-	# This is used only by the default updown script, not by your custom
-	# ones, so do not mess with it; see CAUTION comment up at top.
-	ipfwadm -F -i accept -b -S $PLUTO_MY_CLIENT_NET/$PLUTO_MY_CLIENT_MASK \
-		-D $PLUTO_PEER_CLIENT_NET/$PLUTO_PEER_CLIENT_MASK
-	;;
-down-client:ipfwadm)
-	# connection to client subnet, with (left/right)firewall=yes, going down
-	# This is used only by the default updown script, not by your custom
-	# ones, so do not mess with it; see CAUTION comment up at top.
-	ipfwadm -F -d accept -b -S $PLUTO_MY_CLIENT_NET/$PLUTO_MY_CLIENT_MASK \
-		-D $PLUTO_PEER_CLIENT_NET/$PLUTO_PEER_CLIENT_MASK
-	;;
-#
-# IPv6
-#
-prepare-host-v6:*|prepare-client-v6:*)
-	;;
-route-host-v6:*|route-client-v6:*)
-	# connection to me or my client subnet being routed
-	#uproute_v6
-	;;
-unroute-host-v6:*|unroute-client-v6:*)
-	# connection to me or my client subnet being unrouted
-	#downroute_v6
-	;;
-up-host-v6:*)
-	# connection to me coming up
-	# If you are doing a custom version, firewall commands go here.
-	;;
-down-host-v6:*)
-	# connection to me going down
-	# If you are doing a custom version, firewall commands go here.
-	;;
-up-client-v6:)
-	# connection to my client subnet coming up
-	# If you are doing a custom version, firewall commands go here.
-	;;
-down-client-v6:)
-	# connection to my client subnet going down
-	# If you are doing a custom version, firewall commands go here.
-	;;
-*)	echo "$0: unknown verb \`$PLUTO_VERB' or parameter \`$1'" >&2
-	exit 1
-	;;
-esac
diff --git a/src/_updown_espmark/_updown_espmark.8 b/src/_updown_espmark/_updown_espmark.8
deleted file mode 100644
index 34383cb..0000000
--- a/src/_updown_espmark/_updown_espmark.8
+++ /dev/null
@@ -1,15 +0,0 @@
-.TH _UPDOWN_ESPMARK 8 "7 Apr 2005"
-.SH NAME
-ipsec _updown_espmark \- manages routes and firewall rules
-.SH SYNOPSIS
-.I _updown_espmark
-is invoked by pluto when it has brought up a new connection. This script
-is used to insert the appropriate routing and iptables firewall entries for
-IPsec operation. The incoming ESP traffic must be marked by a static rule
-in the mangle table. The default value for the mark is 50.
-The interface to the script is documented in the pluto man page.
-.SH "SEE ALSO"
-ipsec(8), ipsec_pluto(8).
-.SH HISTORY
-Man page written for the Linux strongSwan project <http://www.strongswan.org/>
-by Andreas Steffen. Original program written by Henry Spencer.
diff --git a/src/aikgen/Makefile.in b/src/aikgen/Makefile.in
index 2bd5be6..33ed133 100644
--- a/src/aikgen/Makefile.in
+++ b/src/aikgen/Makefile.in
@@ -198,6 +198,7 @@ DLLIB = @DLLIB@
 DLLTOOL = @DLLTOOL@
 DSYMUTIL = @DSYMUTIL@
 DUMPBIN = @DUMPBIN@
+EASY_INSTALL = @EASY_INSTALL@
 ECHO_C = @ECHO_C@
 ECHO_N = @ECHO_N@
 ECHO_T = @ECHO_T@
@@ -258,10 +259,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
 PLUGIN_CFLAGS = @PLUGIN_CFLAGS@
 PTHREADLIB = @PTHREADLIB@
 PYTHON = @PYTHON@
+PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@
 PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
 PYTHON_PLATFORM = @PYTHON_PLATFORM@
 PYTHON_PREFIX = @PYTHON_PREFIX@
 PYTHON_VERSION = @PYTHON_VERSION@
+PY_TEST = @PY_TEST@
 RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
@@ -335,6 +338,8 @@ json_CFLAGS = @json_CFLAGS@
 json_LIBS = @json_LIBS@
 libdir = @libdir@
 libexecdir = @libexecdir@
+libiptc_CFLAGS = @libiptc_CFLAGS@
+libiptc_LIBS = @libiptc_LIBS@
 linux_headers = @linux_headers@
 localedir = @localedir@
 localstatedir = @localstatedir@
diff --git a/src/charon-cmd/Makefile.in b/src/charon-cmd/Makefile.in
index 9f67eec..64dea34 100644
--- a/src/charon-cmd/Makefile.in
+++ b/src/charon-cmd/Makefile.in
@@ -232,6 +232,7 @@ DLLIB = @DLLIB@
 DLLTOOL = @DLLTOOL@
 DSYMUTIL = @DSYMUTIL@
 DUMPBIN = @DUMPBIN@
+EASY_INSTALL = @EASY_INSTALL@
 ECHO_C = @ECHO_C@
 ECHO_N = @ECHO_N@
 ECHO_T = @ECHO_T@
@@ -292,10 +293,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
 PLUGIN_CFLAGS = @PLUGIN_CFLAGS@
 PTHREADLIB = @PTHREADLIB@
 PYTHON = @PYTHON@
+PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@
 PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
 PYTHON_PLATFORM = @PYTHON_PLATFORM@
 PYTHON_PREFIX = @PYTHON_PREFIX@
 PYTHON_VERSION = @PYTHON_VERSION@
+PY_TEST = @PY_TEST@
 RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
@@ -369,6 +372,8 @@ json_CFLAGS = @json_CFLAGS@
 json_LIBS = @json_LIBS@
 libdir = @libdir@
 libexecdir = @libexecdir@
+libiptc_CFLAGS = @libiptc_CFLAGS@
+libiptc_LIBS = @libiptc_LIBS@
 linux_headers = @linux_headers@
 localedir = @localedir@
 localstatedir = @localstatedir@
diff --git a/src/charon-nm/Makefile.in b/src/charon-nm/Makefile.in
index 69cbfe0..82f6fbc 100644
--- a/src/charon-nm/Makefile.in
+++ b/src/charon-nm/Makefile.in
@@ -203,6 +203,7 @@ DLLIB = @DLLIB@
 DLLTOOL = @DLLTOOL@
 DSYMUTIL = @DSYMUTIL@
 DUMPBIN = @DUMPBIN@
+EASY_INSTALL = @EASY_INSTALL@
 ECHO_C = @ECHO_C@
 ECHO_N = @ECHO_N@
 ECHO_T = @ECHO_T@
@@ -263,10 +264,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
 PLUGIN_CFLAGS = @PLUGIN_CFLAGS@
 PTHREADLIB = @PTHREADLIB@
 PYTHON = @PYTHON@
+PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@
 PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
 PYTHON_PLATFORM = @PYTHON_PLATFORM@
 PYTHON_PREFIX = @PYTHON_PREFIX@
 PYTHON_VERSION = @PYTHON_VERSION@
+PY_TEST = @PY_TEST@
 RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
@@ -340,6 +343,8 @@ json_CFLAGS = @json_CFLAGS@
 json_LIBS = @json_LIBS@
 libdir = @libdir@
 libexecdir = @libexecdir@
+libiptc_CFLAGS = @libiptc_CFLAGS@
+libiptc_LIBS = @libiptc_LIBS@
 linux_headers = @linux_headers@
 localedir = @localedir@
 localstatedir = @localstatedir@
diff --git a/src/charon-nm/nm/nm_backend.c b/src/charon-nm/nm/nm_backend.c
index 613c2f6..601daca 100644
--- a/src/charon-nm/nm/nm_backend.c
+++ b/src/charon-nm/nm/nm_backend.c
@@ -18,7 +18,6 @@
 #include "nm_creds.h"
 #include "nm_handler.h"
 
-#include <hydra.h>
 #include <daemon.h>
 #include <processing/jobs/callback_job.h>
 
@@ -97,7 +96,8 @@ static void nm_backend_deinit()
 		g_object_unref(this->plugin);
 	}
 	lib->credmgr->remove_set(lib->credmgr, &this->creds->set);
-	hydra->attributes->remove_handler(hydra->attributes, &this->handler->handler);
+	charon->attributes->remove_handler(charon->attributes,
+									   &this->handler->handler);
 	this->creds->destroy(this->creds);
 	this->handler->destroy(this->handler);
 	free(this);
@@ -130,7 +130,7 @@ static bool nm_backend_init()
 	this->plugin = nm_strongswan_plugin_new(this->creds, this->handler);
 	nm_backend = this;
 
-	hydra->attributes->add_handler(hydra->attributes, &this->handler->handler);
+	charon->attributes->add_handler(charon->attributes, &this->handler->handler);
 	lib->credmgr->add_set(lib->credmgr, &this->creds->set);
 	if (!this->plugin)
 	{
diff --git a/src/charon-nm/nm/nm_handler.c b/src/charon-nm/nm/nm_handler.c
index 28aa04b..bdc0667 100644
--- a/src/charon-nm/nm/nm_handler.c
+++ b/src/charon-nm/nm/nm_handler.c
@@ -41,7 +41,7 @@ struct private_nm_handler_t {
 };
 
 METHOD(attribute_handler_t, handle, bool,
-	private_nm_handler_t *this, identification_t *server,
+	private_nm_handler_t *this, ike_sa_t *ike_sa,
 	configuration_attribute_type_t type, chunk_t data)
 {
 	linked_list_t *list;
@@ -92,7 +92,7 @@ static bool enumerate_dns(enumerator_t *this,
 }
 
 METHOD(attribute_handler_t, create_attribute_enumerator, enumerator_t*,
-	private_nm_handler_t *this, identification_t *server, linked_list_t *vips)
+	private_nm_handler_t *this, ike_sa_t *ike_sa, linked_list_t *vips)
 {
 	if (vips->get_count(vips))
 	{
@@ -185,4 +185,3 @@ nm_handler_t *nm_handler_create()
 
 	return &this->public;
 }
-
diff --git a/src/charon-svc/Makefile.in b/src/charon-svc/Makefile.in
index 3783ac9..1c0a405 100644
--- a/src/charon-svc/Makefile.in
+++ b/src/charon-svc/Makefile.in
@@ -197,6 +197,7 @@ DLLIB = @DLLIB@
 DLLTOOL = @DLLTOOL@
 DSYMUTIL = @DSYMUTIL@
 DUMPBIN = @DUMPBIN@
+EASY_INSTALL = @EASY_INSTALL@
 ECHO_C = @ECHO_C@
 ECHO_N = @ECHO_N@
 ECHO_T = @ECHO_T@
@@ -257,10 +258,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
 PLUGIN_CFLAGS = @PLUGIN_CFLAGS@
 PTHREADLIB = @PTHREADLIB@
 PYTHON = @PYTHON@
+PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@
 PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
 PYTHON_PLATFORM = @PYTHON_PLATFORM@
 PYTHON_PREFIX = @PYTHON_PREFIX@
 PYTHON_VERSION = @PYTHON_VERSION@
+PY_TEST = @PY_TEST@
 RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
@@ -334,6 +337,8 @@ json_CFLAGS = @json_CFLAGS@
 json_LIBS = @json_LIBS@
 libdir = @libdir@
 libexecdir = @libexecdir@
+libiptc_CFLAGS = @libiptc_CFLAGS@
+libiptc_LIBS = @libiptc_LIBS@
 linux_headers = @linux_headers@
 localedir = @localedir@
 localstatedir = @localstatedir@
diff --git a/src/charon-systemd/Makefile.in b/src/charon-systemd/Makefile.in
index 790c8ef..d6e1c47 100644
--- a/src/charon-systemd/Makefile.in
+++ b/src/charon-systemd/Makefile.in
@@ -200,6 +200,7 @@ DLLIB = @DLLIB@
 DLLTOOL = @DLLTOOL@
 DSYMUTIL = @DSYMUTIL@
 DUMPBIN = @DUMPBIN@
+EASY_INSTALL = @EASY_INSTALL@
 ECHO_C = @ECHO_C@
 ECHO_N = @ECHO_N@
 ECHO_T = @ECHO_T@
@@ -260,10 +261,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
 PLUGIN_CFLAGS = @PLUGIN_CFLAGS@
 PTHREADLIB = @PTHREADLIB@
 PYTHON = @PYTHON@
+PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@
 PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
 PYTHON_PLATFORM = @PYTHON_PLATFORM@
 PYTHON_PREFIX = @PYTHON_PREFIX@
 PYTHON_VERSION = @PYTHON_VERSION@
+PY_TEST = @PY_TEST@
 RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
@@ -337,6 +340,8 @@ json_CFLAGS = @json_CFLAGS@
 json_LIBS = @json_LIBS@
 libdir = @libdir@
 libexecdir = @libexecdir@
+libiptc_CFLAGS = @libiptc_CFLAGS@
+libiptc_LIBS = @libiptc_LIBS@
 linux_headers = @linux_headers@
 localedir = @localedir@
 localstatedir = @localstatedir@
diff --git a/src/charon-systemd/charon-systemd.c b/src/charon-systemd/charon-systemd.c
index 4a2136f..e391a53 100644
--- a/src/charon-systemd/charon-systemd.c
+++ b/src/charon-systemd/charon-systemd.c
@@ -40,6 +40,17 @@
 #include <threading/rwlock.h>
 
 /**
+ * Default user and group
+ */
+#ifndef IPSEC_USER
+#define IPSEC_USER NULL
+#endif
+
+#ifndef IPSEC_GROUP
+#define IPSEC_GROUP NULL
+#endif
+
+/**
  * hook in library for debugging messages
  */
 extern void (*dbg) (debug_t group, level_t level, char *fmt, ...);
@@ -268,18 +279,20 @@ static int run()
  */
 static bool lookup_uid_gid()
 {
-#ifdef IPSEC_USER
-	if (!lib->caps->resolve_uid(lib->caps, IPSEC_USER))
+	char *name;
+
+	name = lib->settings->get_str(lib->settings, "%s.user", IPSEC_USER,
+								  lib->ns);
+	if (name && !lib->caps->resolve_uid(lib->caps, name))
 	{
 		return FALSE;
 	}
-#endif /* IPSEC_USER */
-#ifdef IPSEC_GROUP
-	if (!lib->caps->resolve_gid(lib->caps, IPSEC_GROUP))
+	name = lib->settings->get_str(lib->settings, "%s.group", IPSEC_GROUP,
+								  lib->ns);
+	if (name && !lib->caps->resolve_gid(lib->caps, name))
 	{
 		return FALSE;
 	}
-#endif /* IPSEC_GROUP */
 	return TRUE;
 }
 
@@ -365,7 +378,8 @@ int main(int argc, char *argv[])
 	lib->plugins->add_static_features(lib->plugins, lib->ns, features,
 							countof(features), TRUE, journal_reload, &journal);
 
-	if (!charon->initialize(charon, PLUGINS))
+	if (!charon->initialize(charon,
+			lib->settings->get_str(lib->settings, "%s.load", PLUGINS, lib->ns)))
 	{
 		sd_notifyf(0, "STATUS=charon initialization failed");
 		return SS_RC_INITIALIZATION_FAILED;
diff --git a/src/charon-tkm/Makefile.in b/src/charon-tkm/Makefile.in
index fe6606b..bff198a 100644
--- a/src/charon-tkm/Makefile.in
+++ b/src/charon-tkm/Makefile.in
@@ -142,6 +142,7 @@ DLLIB = @DLLIB@
 DLLTOOL = @DLLTOOL@
 DSYMUTIL = @DSYMUTIL@
 DUMPBIN = @DUMPBIN@
+EASY_INSTALL = @EASY_INSTALL@
 ECHO_C = @ECHO_C@
 ECHO_N = @ECHO_N@
 ECHO_T = @ECHO_T@
@@ -202,10 +203,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
 PLUGIN_CFLAGS = @PLUGIN_CFLAGS@
 PTHREADLIB = @PTHREADLIB@
 PYTHON = @PYTHON@
+PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@
 PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
 PYTHON_PLATFORM = @PYTHON_PLATFORM@
 PYTHON_PREFIX = @PYTHON_PREFIX@
 PYTHON_VERSION = @PYTHON_VERSION@
+PY_TEST = @PY_TEST@
 RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
@@ -279,6 +282,8 @@ json_CFLAGS = @json_CFLAGS@
 json_LIBS = @json_LIBS@
 libdir = @libdir@
 libexecdir = @libexecdir@
+libiptc_CFLAGS = @libiptc_CFLAGS@
+libiptc_LIBS = @libiptc_LIBS@
 linux_headers = @linux_headers@
 localedir = @localedir@
 localstatedir = @localstatedir@
diff --git a/src/charon-tkm/src/charon-tkm.c b/src/charon-tkm/src/charon-tkm.c
index a6770fc..7c60f0c 100644
--- a/src/charon-tkm/src/charon-tkm.c
+++ b/src/charon-tkm/src/charon-tkm.c
@@ -276,6 +276,10 @@ int main(int argc, char *argv[])
 		goto deinit;
 	}
 
+	/* the authorize hook currently does not support RFC 7427 signature auth */
+	lib->settings->set_bool(lib->settings, "%s.signature_authentication", FALSE,
+							dmn_name);
+
 	/* make sure we log to the DAEMON facility by default */
 	lib->settings->set_int(lib->settings, "%s.syslog.daemon.default",
 			lib->settings->get_int(lib->settings, "%s.syslog.daemon.default", 1,
diff --git a/src/charon-tkm/src/ees/ees_callbacks.c b/src/charon-tkm/src/ees/ees_callbacks.c
index 2d96538..74c0d36 100644
--- a/src/charon-tkm/src/ees/ees_callbacks.c
+++ b/src/charon-tkm/src/ees/ees_callbacks.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2012 Reto Buerki
+ * Copyright (C) 2012-2014 Reto Buerki
  * Copyright (C) 2012 Adrian-Ken Rueegsegger
  * Hochschule fuer Technik Rapperswil
  *
@@ -19,11 +19,12 @@
 #include <tkm/constants.h>
 #include <tkm/types.h>
 
+#include "tkm.h"
 #include "ees_callbacks.h"
 
 void charon_esa_acquire(result_type *res, const sp_id_type sp_id)
 {
-	DBG1(DBG_KNL, "ees: acquire received for reqid {%d}", sp_id);
+	DBG1(DBG_KNL, "ees: acquire received for reqid %u", sp_id);
 	hydra->kernel_interface->acquire(hydra->kernel_interface, sp_id, NULL,
 									 NULL);
 	*res = TKM_OK;
@@ -33,8 +34,19 @@ void charon_esa_expire(result_type *res, const sp_id_type sp_id,
 					   const esp_spi_type spi_rem, const protocol_type protocol,
 					   const expiry_flag_type hard)
 {
-	DBG1(DBG_KNL, "ees: expire received for reqid {%d}", sp_id);
-	hydra->kernel_interface->expire(hydra->kernel_interface, sp_id, protocol,
-									spi_rem, hard != 0);
+	host_t *dst;
+
+	dst = tkm->sad->get_dst_host(tkm->sad, sp_id, spi_rem, protocol);
 	*res = TKM_OK;
+	if (dst == NULL)
+	{
+		DBG3(DBG_KNL, "ees: destination host not found for reqid %u, spi %x, "
+			 "proto %u", sp_id, ntohl(spi_rem), protocol);
+		return;
+	}
+
+	DBG1(DBG_KNL, "ees: expire received for reqid %u, spi %x, dst %H", sp_id,
+		 ntohl(spi_rem), dst);
+	hydra->kernel_interface->expire(hydra->kernel_interface, protocol,
+									spi_rem, dst, hard != 0);
 }
diff --git a/src/charon-tkm/src/tkm/tkm.c b/src/charon-tkm/src/tkm/tkm.c
index 61eb605..333b699 100644
--- a/src/charon-tkm/src/tkm/tkm.c
+++ b/src/charon-tkm/src/tkm/tkm.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2012 Reto Buerki
+ * Copyright (C) 2012-2014 Reto Buerki
  * Copyright (C) 2012 Adrian-Ken Rueegsegger
  * Hochschule fuer Technik Rapperswil
  *
@@ -95,6 +95,7 @@ bool tkm_init()
 		.public = {
 			.idmgr = tkm_id_manager_create(limits),
 			.chunk_map = tkm_chunk_map_create(),
+			.sad = tkm_kernel_sad_create(),
 		},
 	);
 	tkm = &this->public;
@@ -114,6 +115,7 @@ void tkm_deinit()
 	private_tkm_t *this = (private_tkm_t*)tkm;
 	this->public.idmgr->destroy(this->public.idmgr);
 	this->public.chunk_map->destroy(this->public.chunk_map);
+	this->public.sad->destroy(this->public.sad);
 
 	ees_server_finalize();
 
diff --git a/src/charon-tkm/src/tkm/tkm.h b/src/charon-tkm/src/tkm/tkm.h
index fb5acd1..4aed086 100644
--- a/src/charon-tkm/src/tkm/tkm.h
+++ b/src/charon-tkm/src/tkm/tkm.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2012 Reto Buerki
+ * Copyright (C) 2012-2014 Reto Buerki
  * Copyright (C) 2012 Adrian-Ken Rueegsegger
  * Hochschule fuer Technik Rapperswil
  *
@@ -72,6 +72,7 @@
 
 #include "tkm_id_manager.h"
 #include "tkm_chunk_map.h"
+#include "tkm_kernel_sad.h"
 
 typedef struct tkm_t tkm_t;
 
@@ -90,6 +91,11 @@ struct tkm_t {
 	 */
 	tkm_chunk_map_t *chunk_map;
 
+	/**
+	 * CHILD/ESP SA database.
+	 */
+	tkm_kernel_sad_t *sad;
+
 };
 
 /**
diff --git a/src/charon-tkm/src/tkm/tkm_diffie_hellman.c b/src/charon-tkm/src/tkm/tkm_diffie_hellman.c
index 67db5e6..c4953b6 100644
--- a/src/charon-tkm/src/tkm/tkm_diffie_hellman.c
+++ b/src/charon-tkm/src/tkm/tkm_diffie_hellman.c
@@ -41,7 +41,7 @@ struct private_tkm_diffie_hellman_t {
 	/**
 	 * Diffie Hellman group number.
 	 */
-	u_int16_t group;
+	diffie_hellman_group_t group;
 
 	/**
 	 * Diffie Hellman public value.
@@ -55,30 +55,29 @@ struct private_tkm_diffie_hellman_t {
 
 };
 
-METHOD(diffie_hellman_t, get_my_public_value, void,
+METHOD(diffie_hellman_t, get_my_public_value, bool,
 	private_tkm_diffie_hellman_t *this, chunk_t *value)
 {
 	sequence_to_chunk(this->pubvalue.data, this->pubvalue.size, value);
+	return TRUE;
 }
 
-METHOD(diffie_hellman_t, get_shared_secret, status_t,
+METHOD(diffie_hellman_t, get_shared_secret, bool,
 	private_tkm_diffie_hellman_t *this, chunk_t *secret)
 {
 	*secret = chunk_empty;
-	return SUCCESS;
+	return TRUE;
 }
 
 
-METHOD(diffie_hellman_t, set_other_public_value, void,
+METHOD(diffie_hellman_t, set_other_public_value, bool,
 	private_tkm_diffie_hellman_t *this, chunk_t value)
 {
-	// TODO: unvoid this function
-
 	dh_pubvalue_type othervalue;
 	othervalue.size = value.len;
 	memcpy(&othervalue.data, value.ptr, value.len);
 
-	ike_dh_generate_key(this->context_id, othervalue);
+	return ike_dh_generate_key(this->context_id, othervalue) == TKM_OK;
 }
 
 METHOD(diffie_hellman_t, get_dh_group, diffie_hellman_group_t,
diff --git a/src/charon-tkm/src/tkm/tkm_encoder.c~ b/src/charon-tkm/src/tkm/tkm_encoder.c~
new file mode 100644
index 0000000..145615f
--- /dev/null
+++ b/src/charon-tkm/src/tkm/tkm_encoder.c~
@@ -0,0 +1,106 @@
+/*
+ * Copyright (C) 2013 Reto Buerki
+ * Copyright (C) 2013 Adrian-Ken Rueegsegger
+ * Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * for more details.
+ */
+
+#include <utils/debug.h>
+#include <asn1/asn1.h>
+#include <asn1/oid.h>
+
+#include "tkm_encoder.h"
+
+/**
+ * Build the SHA1 hash of pubkey(info) ASN.1 data.
+ */
+static bool hash_pubkey(chunk_t pubkey, chunk_t *hash)
+{
+	hasher_t *hasher;
+
+	hasher = lib->crypto->create_hasher(lib->crypto, HASH_SHA1);
+	if (!hasher || !hasher->allocate_hash(hasher, pubkey, hash))
+	{
+		DBG1(DBG_LIB, "SHA1 hash algorithm not supported, "
+			 "fingerprinting failed");
+		DESTROY_IF(hasher);
+		chunk_free(&pubkey);
+		return FALSE;
+	}
+	hasher->destroy(hasher);
+	chunk_free(&pubkey);
+	return TRUE;
+}
+
+/**
+ * Encode the public key blob into subjectPublicKeyInfo.
+ */
+static bool build_pub_info(chunk_t *encoding, va_list args)
+{
+	chunk_t blob;
+
+	if (cred_encoding_args(args, CRED_PART_RSA_PUB_ASN1_DER, &blob,
+						   CRED_PART_END))
+	{
+		*encoding = asn1_wrap(ASN1_SEQUENCE, "mm",
+							  asn1_algorithmIdentifier(OID_RSA_ENCRYPTION),
+							  asn1_bitstring("c", blob, 0));
+		return TRUE;
+	}
+	return FALSE;
+}
+
+/**
+ * Build the fingerprint of the subjectPublicKeyInfo object.
+ */
+static bool build_info_sha1(chunk_t *encoding, va_list args)
+{
+	chunk_t pubkey;
+
+	if (build_pub_info(&pubkey, args))
+	{
+		return hash_pubkey(pubkey, encoding);
+	}
+	return FALSE;
+}
+
+/**
+ * Build the fingerprint of the subjectPublicKey object.
+ */
+static bool build_sha1(chunk_t *encoding, va_list args)
+{
+	chunk_t blob;
+
+	if (cred_encoding_args(args, CRED_PART_RSA_PUB_ASN1_DER, &blob,
+						   CRED_PART_END))
+	{
+		return hash_pubkey(chunk_clone(blob), encoding);
+	}
+	return FALSE;
+}
+
+/**
+ * See header.
+ */
+bool tkm_encoder_encode(cred_encoding_type_t type, chunk_t *encoding,
+						va_list args)
+{
+	switch (type)
+	{
+		case KEYID_PUBKEY_INFO_SHA1:
+			return build_info_sha1(encoding, args);
+		case KEYID_PUBKEY_SHA1:
+			return build_sha1(encoding, args);
+		default:
+			return FALSE;
+	}
+}
diff --git a/src/charon-tkm/src/tkm/tkm_id_manager.c b/src/charon-tkm/src/tkm/tkm_id_manager.c
index 0fadf1a..e6d571b 100644
--- a/src/charon-tkm/src/tkm/tkm_id_manager.c
+++ b/src/charon-tkm/src/tkm/tkm_id_manager.c
@@ -24,7 +24,7 @@
 ENUM_BEGIN(tkm_context_kind_names, TKM_CTX_NONCE, TKM_CTX_ESA,
 	"NONCE_CONTEXT",
 	"DH_CONTEXT",
-	"CC_CONTEXT"
+	"CC_CONTEXT",
 	"ISA_CONTEXT",
 	"AE_CONTEXT",
 	"ESA_CONTEXT");
diff --git a/src/charon-tkm/src/tkm/tkm_kernel_ipsec.c b/src/charon-tkm/src/tkm/tkm_kernel_ipsec.c
index dbeea93..734b1ec 100644
--- a/src/charon-tkm/src/tkm/tkm_kernel_ipsec.c
+++ b/src/charon-tkm/src/tkm/tkm_kernel_ipsec.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2012 Reto Buerki
+ * Copyright (C) 2012-2014 Reto Buerki
  * Copyright (C) 2012 Adrian-Ken Rueegsegger
  * Hochschule fuer Technik Rapperswil
  *
@@ -26,7 +26,6 @@
 #include "tkm_utils.h"
 #include "tkm_types.h"
 #include "tkm_keymat.h"
-#include "tkm_kernel_sad.h"
 #include "tkm_kernel_ipsec.h"
 
 /** From linux/in.h */
@@ -51,16 +50,11 @@ struct private_tkm_kernel_ipsec_t {
 	 */
 	rng_t *rng;
 
-	/**
-	 * CHILD/ESP SA database.
-	 */
-	tkm_kernel_sad_t *sad;
-
 };
 
 METHOD(kernel_ipsec_t, get_spi, status_t,
 	private_tkm_kernel_ipsec_t *this, host_t *src, host_t *dst,
-	u_int8_t protocol, u_int32_t reqid, u_int32_t *spi)
+	u_int8_t protocol, u_int32_t *spi)
 {
 	bool result;
 
@@ -74,7 +68,6 @@ METHOD(kernel_ipsec_t, get_spi, status_t,
 		}
 	}
 
-	DBG1(DBG_KNL, "getting SPI for reqid {%u}", reqid);
 	result = this->rng->get_bytes(this->rng, sizeof(u_int32_t),
 								  (u_int8_t *)spi);
 	return result ? SUCCESS : FAILED;
@@ -82,7 +75,7 @@ METHOD(kernel_ipsec_t, get_spi, status_t,
 
 METHOD(kernel_ipsec_t, get_cpi, status_t,
 	private_tkm_kernel_ipsec_t *this, host_t *src, host_t *dst,
-	u_int32_t reqid, u_int16_t *cpi)
+	u_int16_t *cpi)
 {
 	return NOT_SUPPORTED;
 }
@@ -93,11 +86,10 @@ METHOD(kernel_ipsec_t, add_sa, status_t,
 	u_int32_t tfc, lifetime_cfg_t *lifetime, u_int16_t enc_alg, chunk_t enc_key,
 	u_int16_t int_alg, chunk_t int_key, ipsec_mode_t mode,
 	u_int16_t ipcomp, u_int16_t cpi, u_int32_t replay_window,
-	bool _initiator, bool encap, bool esn, bool inbound,
-	traffic_selector_t* src_ts, traffic_selector_t* dst_ts)
+	bool initiator, bool encap, bool esn, bool inbound, bool update,
+	linked_list_t* src_ts, linked_list_t* dst_ts)
 {
 	esa_info_t esa;
-	bool initiator;
 	esp_spi_type spi_loc, spi_rem;
 	host_t *local, *peer;
 	chunk_t *nonce_loc, *nonce_rem;
@@ -120,9 +112,6 @@ METHOD(kernel_ipsec_t, add_sa, status_t,
 		return SUCCESS;
 	}
 
-	/* Initiator if encr_r is passed as enc_key to the inbound add_sa call */
-	/* TODO: does the new _initiator parameter have the same meaning? */
-	initiator = esa.is_encr_r && inbound;
 	if (initiator)
 	{
 		spi_loc = spi;
@@ -143,7 +132,8 @@ METHOD(kernel_ipsec_t, add_sa, status_t,
 	}
 
 	esa_id = tkm->idmgr->acquire_id(tkm->idmgr, TKM_CTX_ESA);
-	if (!this->sad->insert(this->sad, esa_id, peer, local, spi_loc, protocol))
+	if (!tkm->sad->insert(tkm->sad, reqid, esa_id, local, peer, spi_rem,
+						  protocol))
 	{
 		DBG1(DBG_KNL, "unable to add entry (%llu) to SAD", esa_id);
 		goto sad_failure;
@@ -207,7 +197,7 @@ METHOD(kernel_ipsec_t, add_sa, status_t,
 	return SUCCESS;
 
 failure:
-	this->sad->remove(this->sad, esa_id);
+	tkm->sad->remove(tkm->sad, esa_id);
 sad_failure:
 	tkm->idmgr->release_id(tkm->idmgr, TKM_CTX_ESA, esa_id);
 	chunk_free(&esa.nonce_i);
@@ -229,7 +219,7 @@ METHOD(kernel_ipsec_t, del_sa, status_t,
 {
 	esa_id_type esa_id;
 
-	esa_id = this->sad->get_esa_id(this->sad, src, dst, spi, protocol);
+	esa_id = tkm->sad->get_esa_id(tkm->sad, src, dst, spi, protocol);
 	if (esa_id)
 	{
 		DBG1(DBG_KNL, "deleting child SA (esa: %llu, spi: %x)", esa_id,
@@ -239,7 +229,7 @@ METHOD(kernel_ipsec_t, del_sa, status_t,
 			DBG1(DBG_KNL, "child SA (%llu) deletion failed", esa_id);
 			return FAILED;
 		}
-		this->sad->remove(this->sad, esa_id);
+		tkm->sad->remove(tkm->sad, esa_id);
 		tkm->idmgr->release_id(tkm->idmgr, TKM_CTX_ESA, esa_id);
 	}
 	return SUCCESS;
@@ -350,7 +340,6 @@ METHOD(kernel_ipsec_t, destroy, void,
 	private_tkm_kernel_ipsec_t *this)
 {
 	DESTROY_IF(this->rng);
-	DESTROY_IF(this->sad);
 	free(this);
 }
 
@@ -380,15 +369,7 @@ tkm_kernel_ipsec_t *tkm_kernel_ipsec_create()
 				.destroy = _destroy,
 			},
 		},
-		.sad = tkm_kernel_sad_create(),
 	);
 
-	if (!this->sad)
-	{
-		DBG1(DBG_KNL, "unable to create SAD");
-		destroy(this);
-		return NULL;
-	}
-
 	return &this->public;
 }
diff --git a/src/charon-tkm/src/tkm/tkm_kernel_sad.c b/src/charon-tkm/src/tkm/tkm_kernel_sad.c
index 360a47b..3394b58 100644
--- a/src/charon-tkm/src/tkm/tkm_kernel_sad.c
+++ b/src/charon-tkm/src/tkm/tkm_kernel_sad.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2012 Reto Buerki
+ * Copyright (C) 2012-2014 Reto Buerki
  * Copyright (C) 2012 Adrian-Ken Rueegsegger
  * Hochschule fuer Technik Rapperswil
  *
@@ -57,6 +57,11 @@ struct sad_entry_t {
 	esa_id_type esa_id;
 
 	/**
+	 * Reqid.
+	 */
+	u_int32_t reqid;
+
+	/**
 	 * Source address of CHILD SA.
 	 */
 	host_t *src;
@@ -109,6 +114,19 @@ static bool sad_entry_match(sad_entry_t * const entry, const host_t * const src,
 }
 
 /**
+ * Find a list entry with given reqid, spi and proto values.
+ */
+static bool sad_entry_match_dst(sad_entry_t * const entry,
+								const u_int32_t * const reqid,
+								const u_int32_t * const spi,
+								const u_int8_t * const proto)
+{
+	return entry->reqid == *reqid &&
+		   entry->spi   == *spi &&
+		   entry->proto == *proto;
+}
+
+/**
  * Compare two SAD entries for equality.
  */
 static bool sad_entry_equal(sad_entry_t * const left, sad_entry_t * const right)
@@ -119,6 +137,7 @@ static bool sad_entry_equal(sad_entry_t * const left, sad_entry_t * const right)
 		return FALSE;
 	}
 	return left->esa_id == right->esa_id &&
+		   left->reqid == right->reqid &&
 		   left->src->ip_equals(left->src, right->src) &&
 		   left->dst->ip_equals(left->dst, right->dst) &&
 		   left->spi == right->spi && left->proto == right->proto;
@@ -126,14 +145,15 @@ static bool sad_entry_equal(sad_entry_t * const left, sad_entry_t * const right)
 
 METHOD(tkm_kernel_sad_t, insert, bool,
 	private_tkm_kernel_sad_t * const this, const esa_id_type esa_id,
-	const host_t * const src, const host_t * const dst, const u_int32_t spi,
-	const u_int8_t proto)
+	const u_int32_t reqid, const host_t * const src, const host_t * const dst,
+	const u_int32_t spi, const u_int8_t proto)
 {
 	status_t result;
 	sad_entry_t *new_entry;
 
 	INIT(new_entry,
 		 .esa_id = esa_id,
+		 .reqid = reqid,
 		 .src = (host_t *)src,
 		 .dst = (host_t *)dst,
 		 .spi = spi,
@@ -146,8 +166,9 @@ METHOD(tkm_kernel_sad_t, insert, bool,
 									new_entry);
 	if (result == NOT_FOUND)
 	{
-		DBG3(DBG_KNL, "inserting SAD entry (esa: %llu, src: %H, dst: %H, "
-			 "spi: %x, proto: %u)", esa_id, src, dst, ntohl(spi), proto);
+		DBG3(DBG_KNL, "inserting SAD entry (esa: %llu, reqid: %u, src: %H, "
+			 "dst: %H, spi: %x, proto: %u)", esa_id, reqid, src, dst,
+			 ntohl(spi), proto);
 		new_entry->src = src->clone((host_t *)src);
 		new_entry->dst = dst->clone((host_t *)dst);
 		this->data->insert_last(this->data, new_entry);
@@ -176,18 +197,44 @@ METHOD(tkm_kernel_sad_t, get_esa_id, esa_id_type,
 	if (res == SUCCESS && entry)
 	{
 		id = entry->esa_id;
-		DBG3(DBG_KNL, "getting ESA id of SAD entry (esa: %llu, src: %H, "
-			 "dst: %H, spi: %x, proto: %u)", id, src, dst, ntohl(spi),
-			 proto);
+		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");
+		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_dst_host, host_t *,
+	private_tkm_kernel_sad_t * const this, const u_int32_t reqid,
+	const u_int32_t spi, const u_int8_t proto)
+{
+	host_t *dst = NULL;
+	sad_entry_t *entry = NULL;
+
+	this->mutex->lock(this->mutex);
+	const status_t res = this->data->find_first(this->data,
+												(linked_list_match_t)sad_entry_match_dst,
+												(void**)&entry, &reqid, &spi, &proto);
+	if (res == SUCCESS && entry)
+	{
+		dst = entry->dst;
+		DBG3(DBG_KNL, "returning destination host %H of SAD entry (reqid: %u,"
+			 " spi: %x, proto: %u)", dst, reqid, ntohl(spi), proto);
+	}
+	else
+	{
+		DBG3(DBG_KNL, "no SAD entry found for reqid %u, spi %x, proto: %u",
+			 reqid, ntohl(spi), proto);
+	}
+	this->mutex->unlock(this->mutex);
+	return dst;
+}
+
 METHOD(tkm_kernel_sad_t, _remove, bool,
 	private_tkm_kernel_sad_t * const this, const esa_id_type esa_id)
 {
@@ -242,6 +289,7 @@ tkm_kernel_sad_t *tkm_kernel_sad_create()
 		.public = {
 			.insert = _insert,
 			.get_esa_id = _get_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 0194cd3..38b19dd 100644
--- a/src/charon-tkm/src/tkm/tkm_kernel_sad.h
+++ b/src/charon-tkm/src/tkm/tkm_kernel_sad.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2012 Reto Buerki
+ * Copyright (C) 2012-2014 Reto Buerki
  * Copyright (C) 2012 Adrian-Ken Rueegsegger
  * Hochschule fuer Technik Rapperswil
  *
@@ -37,6 +37,7 @@ struct tkm_kernel_sad_t {
 	 * Insert new SAD entry with specified parameters.
 	 *
 	 * @param esa_id		ESP SA context identifier
+	 * @param reqid			reqid of the SA
 	 * @param src			source address of CHILD SA
 	 * @param dst			destination address of CHILD SA
 	 * @param spi			SPI of CHILD SA
@@ -44,8 +45,9 @@ struct tkm_kernel_sad_t {
 	 * @return				TRUE if entry was inserted, FALSE otherwise
 	 */
 	bool (*insert)(tkm_kernel_sad_t * const this, const esa_id_type esa_id,
-				   const host_t * const src, const host_t * const dst,
-				   const u_int32_t spi, const u_int8_t proto);
+				   const u_int32_t reqid, const host_t * const src,
+				   const host_t * const dst, const u_int32_t spi,
+				   const u_int8_t proto);
 
 	/**
 	 * Get ESA id for entry with given parameters.
@@ -61,6 +63,17 @@ struct tkm_kernel_sad_t {
 				 const u_int32_t spi, const u_int8_t proto);
 
 	/**
+	 * Get destination host for entry with given parameters.
+	 *
+	 * @param reqid			reqid of CHILD SA
+	 * @param spi			SPI of CHILD SA
+	 * @param proto			protocol of CHILD SA (ESP/AH)
+	 * @return				destination host of entry if found, NULL otherwise
+	 */
+	host_t * (*get_dst_host)(tkm_kernel_sad_t * const this,
+			  const u_int32_t reqid, const u_int32_t spi, const u_int8_t proto);
+
+	/**
 	 * Remove entry with given ESA id from SAD.
 	 *
 	 * @param esa_id		ESA identifier of entry to remove
diff --git a/src/charon-tkm/src/tkm/tkm_keymat.c b/src/charon-tkm/src/tkm/tkm_keymat.c
index 772fac8..80721fa 100644
--- a/src/charon-tkm/src/tkm/tkm_keymat.c
+++ b/src/charon-tkm/src/tkm/tkm_keymat.c
@@ -1,4 +1,5 @@
 /*
+ * Copyright (C) 2015 Tobias Brunner
  * Copyrigth (C) 2012 Reto Buerki
  * Copyright (C) 2012 Adrian-Ken Rueegsegger
  * Hochschule fuer Technik Rapperswil
@@ -17,6 +18,7 @@
 #include <daemon.h>
 #include <tkm/constants.h>
 #include <tkm/client.h>
+#include <crypto/hashers/hash_algorithm_set.h>
 
 #include "tkm.h"
 #include "tkm_types.h"
@@ -71,6 +73,10 @@ struct private_tkm_keymat_t {
 	 */
 	chunk_t other_init_msg;
 
+	/**
+	 * Set of hash algorithms supported by peer for signature authentication
+	 */
+	hash_algorithm_set_t *hash_algorithms;
 };
 
 /**
@@ -417,6 +423,26 @@ METHOD(keymat_v2_t, get_psk_sig, bool,
 	return FALSE;
 }
 
+METHOD(keymat_v2_t, hash_algorithm_supported, bool,
+	private_tkm_keymat_t *this, hash_algorithm_t hash)
+{
+	if (!this->hash_algorithms)
+	{
+		return FALSE;
+	}
+	return this->hash_algorithms->contains(this->hash_algorithms, hash);
+}
+
+METHOD(keymat_v2_t, add_hash_algorithm, void,
+	private_tkm_keymat_t *this, hash_algorithm_t hash)
+{
+	if (!this->hash_algorithms)
+	{
+		this->hash_algorithms = hash_algorithm_set_create();
+	}
+	this->hash_algorithms->add(this->hash_algorithms, hash);
+}
+
 METHOD(keymat_t, destroy, void,
 	private_tkm_keymat_t *this)
 {
@@ -435,6 +461,7 @@ METHOD(keymat_t, destroy, void,
 		tkm->idmgr->release_id(tkm->idmgr, TKM_CTX_AE, this->ae_ctx_id);
 	}
 
+	DESTROY_IF(this->hash_algorithms);
 	DESTROY_IF(this->aead_in);
 	DESTROY_IF(this->aead_out);
 	chunk_free(&this->auth_payload);
@@ -488,6 +515,8 @@ tkm_keymat_t *tkm_keymat_create(bool initiator)
 				.get_skd = _get_skd,
 				.get_auth_octets = _get_auth_octets,
 				.get_psk_sig = _get_psk_sig,
+				.add_hash_algorithm = _add_hash_algorithm,
+				.hash_algorithm_supported = _hash_algorithm_supported,
 			},
 			.get_isa_id = _get_isa_id,
 			.set_auth_payload = _set_auth_payload,
diff --git a/src/charon-tkm/src/tkm/tkm_listener.c b/src/charon-tkm/src/tkm/tkm_listener.c
index b2692a5..bb12182 100644
--- a/src/charon-tkm/src/tkm/tkm_listener.c
+++ b/src/charon-tkm/src/tkm/tkm_listener.c
@@ -240,6 +240,8 @@ METHOD(listener_t, authorize, bool,
 		return TRUE;
 	}
 
+	*success = FALSE;
+
 	keymat = (tkm_keymat_t*)ike_sa->get_keymat(ike_sa);
 	isa_id = keymat->get_isa_id(keymat);
 	DBG1(DBG_IKE, "TKM authorize listener called for ISA context %llu", isa_id);
@@ -248,28 +250,26 @@ METHOD(listener_t, authorize, bool,
 	if (!cc_id)
 	{
 		DBG1(DBG_IKE, "unable to acquire CC context id");
-		*success = FALSE;
 		return TRUE;
 	}
 	if (!build_cert_chain(ike_sa, cc_id))
 	{
 		DBG1(DBG_IKE, "unable to build certificate chain");
-		*success = FALSE;
-		return TRUE;
+		goto cc_reset;
 	}
 
 	auth = keymat->get_auth_payload(keymat);
 	if (!auth->ptr)
 	{
 		DBG1(DBG_IKE, "no AUTHENTICATION data available");
-		*success = FALSE;
+		goto cc_reset;
 	}
 
 	other_init_msg = keymat->get_peer_init_msg(keymat);
 	if (!other_init_msg->ptr)
 	{
 		DBG1(DBG_IKE, "no peer init message available");
-		*success = FALSE;
+		goto cc_reset;
 	}
 
 	chunk_to_sequence(auth, &signature, sizeof(signature_type));
@@ -279,7 +279,7 @@ METHOD(listener_t, authorize, bool,
 	{
 		DBG1(DBG_IKE, "TKM based authentication failed"
 			 " for ISA context %llu", isa_id);
-		*success = FALSE;
+		goto cc_reset;
 	}
 	else
 	{
@@ -288,7 +288,13 @@ METHOD(listener_t, authorize, bool,
 		*success = TRUE;
 	}
 
-	return TRUE;
+cc_reset:
+	if (ike_cc_reset(cc_id) != TKM_OK)
+	{
+		DBG1(DBG_IKE, "unable to reset CC context %llu", cc_id);
+	}
+	tkm->idmgr->release_id(tkm->idmgr, TKM_CTX_CC, cc_id);
+	return TRUE; /* stay registered */
 }
 
 METHOD(listener_t, message, bool,
diff --git a/src/charon-tkm/tests/diffie_hellman_tests.c b/src/charon-tkm/tests/diffie_hellman_tests.c
index 89658a7..5ef6f41 100644
--- a/src/charon-tkm/tests/diffie_hellman_tests.c
+++ b/src/charon-tkm/tests/diffie_hellman_tests.c
@@ -40,7 +40,7 @@ START_TEST(test_dh_get_my_pubvalue)
 	fail_if(!dh, "Unable to create DH");
 
 	chunk_t value;
-	dh->dh.get_my_public_value(&dh->dh, &value);
+	ck_assert(dh->dh.get_my_public_value(&dh->dh, &value));
 	dh->dh.destroy(&dh->dh);
 
 	fail_if(value.ptr == NULL, "Pubvalue is NULL");
diff --git a/src/charon-tkm/tests/kernel_sad_tests.c b/src/charon-tkm/tests/kernel_sad_tests.c
index 6f0b396..b9ab3cb 100644
--- a/src/charon-tkm/tests/kernel_sad_tests.c
+++ b/src/charon-tkm/tests/kernel_sad_tests.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2012 Reto Buerki
+ * Copyright (C) 2012-2014 Reto Buerki
  * Copyright (C) 2012 Adrian-Ken Rueegsegger
  * Hochschule fuer Technik Rapperswil
  *
@@ -34,7 +34,7 @@ START_TEST(test_insert)
 	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, 1, addr, addr, 42, 50),
+	fail_unless(sad->insert(sad, 1, 2, addr, addr, 42, 50),
 				"Error inserting SAD entry");
 
 	sad->destroy(sad);
@@ -47,9 +47,9 @@ START_TEST(test_insert_duplicate)
 	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, 1, addr, addr, 42, 50),
+	fail_unless(sad->insert(sad, 1, 2, addr, addr, 42, 50),
 				"Error inserting SAD entry");
-	fail_if(sad->insert(sad, 1, addr, addr, 42, 50),
+	fail_if(sad->insert(sad, 1, 2, addr, addr, 42, 50),
 			"Expected error inserting duplicate entry");
 
 	sad->destroy(sad);
@@ -61,7 +61,7 @@ START_TEST(test_get_esa_id)
 {
 	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, addr, addr, 42, 50),
+	fail_unless(sad->insert(sad, 23, 54, addr, addr, 42, 50),
 				"Error inserting SAD entry");
 	fail_unless(sad->get_esa_id(sad, addr, addr, 42, 50) == 23,
 				"Error getting esa id");
@@ -81,11 +81,34 @@ START_TEST(test_get_esa_id_nonexistent)
 }
 END_TEST
 
+START_TEST(test_get_dst_host)
+{
+	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, 42, 50),
+				"Error inserting SAD entry");
+
+	host_t *dst = sad->get_dst_host(sad, 54, 42, 50);
+	fail_unless(addr->equals(addr, dst), "Error getting dst host");
+	sad->destroy(sad);
+	addr->destroy(addr);
+}
+END_TEST
+
+START_TEST(test_get_dst_host_nonexistent)
+{
+	tkm_kernel_sad_t *sad = tkm_kernel_sad_create();
+	fail_unless(sad->get_dst_host(sad, 1, 12, 50) == NULL,
+				"Got dst for nonexistent SAD entry");
+	sad->destroy(sad);
+}
+END_TEST
+
 START_TEST(test_remove)
 {
 	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, addr, addr, 42, 50),
+	fail_unless(sad->insert(sad, 23, 54, addr, addr, 42, 50),
 				"Error inserting SAD entry");
 	fail_unless(sad->get_esa_id(sad, addr, addr, 42, 50) == 23,
 				"Error getting esa id");
@@ -128,6 +151,11 @@ Suite *make_kernel_sad_tests()
 	tcase_add_test(tc, test_get_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);
+	suite_add_tcase(s, tc);
+
 	tc = tcase_create("remove");
 	tcase_add_test(tc, test_remove);
 	tcase_add_test(tc, test_remove_nonexistent);
diff --git a/src/charon-tkm/tests/keymat_tests.c b/src/charon-tkm/tests/keymat_tests.c
index 1982671..889965a 100644
--- a/src/charon-tkm/tests/keymat_tests.c
+++ b/src/charon-tkm/tests/keymat_tests.c
@@ -53,8 +53,8 @@ START_TEST(test_derive_ike_keys)
 
 	/* Use the same pubvalue for both sides */
 	chunk_t pubvalue;
-	dh->dh.get_my_public_value(&dh->dh, &pubvalue);
-	dh->dh.set_other_public_value(&dh->dh, pubvalue);
+	ck_assert(dh->dh.get_my_public_value(&dh->dh, &pubvalue));
+	ck_assert(dh->dh.set_other_public_value(&dh->dh, pubvalue));
 
 	fail_unless(keymat->keymat_v2.derive_ike_keys(&keymat->keymat_v2, proposal,
 				&dh->dh, nonce, nonce, ike_sa_id, PRF_UNDEFINED, chunk_empty),
diff --git a/src/charon-tkm/tests/tests.c b/src/charon-tkm/tests/tests.c
index 80894a1..669f4d5 100644
--- a/src/charon-tkm/tests/tests.c
+++ b/src/charon-tkm/tests/tests.c
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 2013 Tobias Brunner
- * Copyright (C) 2012 Reto Buerki
+ * Copyright (C) 2012-2014 Reto Buerki
  * Copyright (C) 2012 Adrian-Ken Rueegsegger
  * Hochschule fuer Technik Rapperswil
  *
@@ -53,7 +53,7 @@ static bool test_runner_init(bool init)
 		libhydra_init();
 		libcharon_init();
 		lib->settings->set_int(lib->settings,
-							   "test_runner.filelog.stdout.default", 0);
+							   "test-runner.filelog.stdout.default", 0);
 		charon->load_loggers(charon, NULL, FALSE);
 
 		/* Register TKM specific plugins */
diff --git a/src/charon/Makefile.in b/src/charon/Makefile.in
index f4dcf4f..e1cc5c2 100644
--- a/src/charon/Makefile.in
+++ b/src/charon/Makefile.in
@@ -199,6 +199,7 @@ DLLIB = @DLLIB@
 DLLTOOL = @DLLTOOL@
 DSYMUTIL = @DSYMUTIL@
 DUMPBIN = @DUMPBIN@
+EASY_INSTALL = @EASY_INSTALL@
 ECHO_C = @ECHO_C@
 ECHO_N = @ECHO_N@
 ECHO_T = @ECHO_T@
@@ -259,10 +260,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
 PLUGIN_CFLAGS = @PLUGIN_CFLAGS@
 PTHREADLIB = @PTHREADLIB@
 PYTHON = @PYTHON@
+PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@
 PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
 PYTHON_PLATFORM = @PYTHON_PLATFORM@
 PYTHON_PREFIX = @PYTHON_PREFIX@
 PYTHON_VERSION = @PYTHON_VERSION@
+PY_TEST = @PY_TEST@
 RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
@@ -336,6 +339,8 @@ json_CFLAGS = @json_CFLAGS@
 json_LIBS = @json_LIBS@
 libdir = @libdir@
 libexecdir = @libexecdir@
+libiptc_CFLAGS = @libiptc_CFLAGS@
+libiptc_LIBS = @libiptc_LIBS@
 linux_headers = @linux_headers@
 localedir = @localedir@
 localstatedir = @localstatedir@
diff --git a/src/checksum/Makefile.in b/src/checksum/Makefile.in
index 86e7ca6..4e41346 100644
--- a/src/checksum/Makefile.in
+++ b/src/checksum/Makefile.in
@@ -266,6 +266,7 @@ DLLIB = @DLLIB@
 DLLTOOL = @DLLTOOL@
 DSYMUTIL = @DSYMUTIL@
 DUMPBIN = @DUMPBIN@
+EASY_INSTALL = @EASY_INSTALL@
 ECHO_C = @ECHO_C@
 ECHO_N = @ECHO_N@
 ECHO_T = @ECHO_T@
@@ -326,10 +327,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
 PLUGIN_CFLAGS = @PLUGIN_CFLAGS@
 PTHREADLIB = @PTHREADLIB@
 PYTHON = @PYTHON@
+PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@
 PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
 PYTHON_PLATFORM = @PYTHON_PLATFORM@
 PYTHON_PREFIX = @PYTHON_PREFIX@
 PYTHON_VERSION = @PYTHON_VERSION@
+PY_TEST = @PY_TEST@
 RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
@@ -403,6 +406,8 @@ json_CFLAGS = @json_CFLAGS@
 json_LIBS = @json_LIBS@
 libdir = @libdir@
 libexecdir = @libexecdir@
+libiptc_CFLAGS = @libiptc_CFLAGS@
+libiptc_LIBS = @libiptc_LIBS@
 linux_headers = @linux_headers@
 localedir = @localedir@
 localstatedir = @localstatedir@
diff --git a/src/conftest/Makefile.in b/src/conftest/Makefile.in
index e3c2e43..78438d8 100644
--- a/src/conftest/Makefile.in
+++ b/src/conftest/Makefile.in
@@ -213,6 +213,7 @@ DLLIB = @DLLIB@
 DLLTOOL = @DLLTOOL@
 DSYMUTIL = @DSYMUTIL@
 DUMPBIN = @DUMPBIN@
+EASY_INSTALL = @EASY_INSTALL@
 ECHO_C = @ECHO_C@
 ECHO_N = @ECHO_N@
 ECHO_T = @ECHO_T@
@@ -273,10 +274,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
 PLUGIN_CFLAGS = @PLUGIN_CFLAGS@
 PTHREADLIB = @PTHREADLIB@
 PYTHON = @PYTHON@
+PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@
 PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
 PYTHON_PLATFORM = @PYTHON_PLATFORM@
 PYTHON_PREFIX = @PYTHON_PREFIX@
 PYTHON_VERSION = @PYTHON_VERSION@
+PY_TEST = @PY_TEST@
 RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
@@ -350,6 +353,8 @@ json_CFLAGS = @json_CFLAGS@
 json_LIBS = @json_LIBS@
 libdir = @libdir@
 libexecdir = @libexecdir@
+libiptc_CFLAGS = @libiptc_CFLAGS@
+libiptc_LIBS = @libiptc_LIBS@
 linux_headers = @linux_headers@
 localedir = @localedir@
 localstatedir = @localstatedir@
diff --git a/src/conftest/actions.c b/src/conftest/actions.c
index 7532e95..474672c 100644
--- a/src/conftest/actions.c
+++ b/src/conftest/actions.c
@@ -117,19 +117,20 @@ static job_requeue_t rekey_child(char *config)
 	enumerator_t *enumerator, *children;
 	ike_sa_t *ike_sa;
 	child_sa_t *child_sa;
-	u_int32_t reqid = 0, spi = 0;
-	protocol_id_t proto = PROTO_ESP;
+	u_int32_t spi, proto;
+	host_t *dst = NULL;
 
 	enumerator = charon->controller->create_ike_sa_enumerator(
 													charon->controller, TRUE);
 	while (enumerator->enumerate(enumerator, &ike_sa))
 	{
 		children = ike_sa->create_child_sa_enumerator(ike_sa);
-		while (children->enumerate(children, (void**)&child_sa))
+		while (children->enumerate(children, &child_sa))
 		{
 			if (streq(config, child_sa->get_name(child_sa)))
 			{
-				reqid = child_sa->get_reqid(child_sa);
+				dst = ike_sa->get_my_host(ike_sa);
+				dst = dst->clone(dst);
 				proto = child_sa->get_protocol(child_sa);
 				spi = child_sa->get_spi(child_sa, TRUE);
 				break;
@@ -138,11 +139,12 @@ static job_requeue_t rekey_child(char *config)
 		children->destroy(children);
 	}
 	enumerator->destroy(enumerator);
-	if (reqid)
+	if (dst)
 	{
 		DBG1(DBG_CFG, "starting rekey of CHILD_SA '%s'", config);
 		lib->processor->queue_job(lib->processor,
-						(job_t*)rekey_child_sa_job_create(reqid, proto, spi));
+						(job_t*)rekey_child_sa_job_create(proto, spi, dst));
+		dst->destroy(dst);
 	}
 	else
 	{
@@ -236,7 +238,7 @@ static job_requeue_t close_child(char *config)
 		{
 			if (streq(config, child_sa->get_name(child_sa)))
 			{
-				id = child_sa->get_reqid(child_sa);
+				id = child_sa->get_unique_id(child_sa);
 				break;
 			}
 		}
diff --git a/src/dumm/Makefile.in b/src/dumm/Makefile.in
index 56ac344..2ecf611 100644
--- a/src/dumm/Makefile.in
+++ b/src/dumm/Makefile.in
@@ -234,6 +234,7 @@ DLLIB = @DLLIB@
 DLLTOOL = @DLLTOOL@
 DSYMUTIL = @DSYMUTIL@
 DUMPBIN = @DUMPBIN@
+EASY_INSTALL = @EASY_INSTALL@
 ECHO_C = @ECHO_C@
 ECHO_N = @ECHO_N@
 ECHO_T = @ECHO_T@
@@ -294,10 +295,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
 PLUGIN_CFLAGS = @PLUGIN_CFLAGS@
 PTHREADLIB = @PTHREADLIB@
 PYTHON = @PYTHON@
+PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@
 PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
 PYTHON_PLATFORM = @PYTHON_PLATFORM@
 PYTHON_PREFIX = @PYTHON_PREFIX@
 PYTHON_VERSION = @PYTHON_VERSION@
+PY_TEST = @PY_TEST@
 RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
@@ -371,6 +374,8 @@ json_CFLAGS = @json_CFLAGS@
 json_LIBS = @json_LIBS@
 libdir = @libdir@
 libexecdir = @libexecdir@
+libiptc_CFLAGS = @libiptc_CFLAGS@
+libiptc_LIBS = @libiptc_LIBS@
 linux_headers = @linux_headers@
 localedir = @localedir@
 localstatedir = @localstatedir@
diff --git a/src/dumm/ext/dumm.c b/src/dumm/ext/dumm.c
index d791c08..df7ec47 100644
--- a/src/dumm/ext/dumm.c
+++ b/src/dumm/ext/dumm.c
@@ -629,7 +629,7 @@ static VALUE iface_each_addr(int argc, VALUE *argv, VALUE self)
 	linked_list_t *list;
 	iface_t *iface;
 	host_t *addr;
-	char buf[64];
+	char buf[64], *fmt = "%H";
 
 	if (!rb_block_given_p())
 	{
@@ -645,7 +645,7 @@ static VALUE iface_each_addr(int argc, VALUE *argv, VALUE self)
 	enumerator->destroy(enumerator);
 	while (list->remove_first(list, (void**)&addr) == SUCCESS)
 	{
-		snprintf(buf, sizeof(buf), "%H", addr);
+		snprintf(buf, sizeof(buf), fmt, addr);
 		addr->destroy(addr);
 		rb_yield(rb_str_new2(buf));
 	}
diff --git a/src/include/Makefile.in b/src/include/Makefile.in
index 042c46c..64be6ac 100644
--- a/src/include/Makefile.in
+++ b/src/include/Makefile.in
@@ -142,6 +142,7 @@ DLLIB = @DLLIB@
 DLLTOOL = @DLLTOOL@
 DSYMUTIL = @DSYMUTIL@
 DUMPBIN = @DUMPBIN@
+EASY_INSTALL = @EASY_INSTALL@
 ECHO_C = @ECHO_C@
 ECHO_N = @ECHO_N@
 ECHO_T = @ECHO_T@
@@ -202,10 +203,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
 PLUGIN_CFLAGS = @PLUGIN_CFLAGS@
 PTHREADLIB = @PTHREADLIB@
 PYTHON = @PYTHON@
+PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@
 PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
 PYTHON_PLATFORM = @PYTHON_PLATFORM@
 PYTHON_PREFIX = @PYTHON_PREFIX@
 PYTHON_VERSION = @PYTHON_VERSION@
+PY_TEST = @PY_TEST@
 RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
@@ -279,6 +282,8 @@ json_CFLAGS = @json_CFLAGS@
 json_LIBS = @json_LIBS@
 libdir = @libdir@
 libexecdir = @libexecdir@
+libiptc_CFLAGS = @libiptc_CFLAGS@
+libiptc_LIBS = @libiptc_LIBS@
 linux_headers = @linux_headers@
 localedir = @localedir@
 localstatedir = @localstatedir@
diff --git a/src/ipsec/Makefile.in b/src/ipsec/Makefile.in
index 526c7c4..d4dafcb 100644
--- a/src/ipsec/Makefile.in
+++ b/src/ipsec/Makefile.in
@@ -176,6 +176,7 @@ DLLIB = @DLLIB@
 DLLTOOL = @DLLTOOL@
 DSYMUTIL = @DSYMUTIL@
 DUMPBIN = @DUMPBIN@
+EASY_INSTALL = @EASY_INSTALL@
 ECHO_C = @ECHO_C@
 ECHO_N = @ECHO_N@
 ECHO_T = @ECHO_T@
@@ -236,10 +237,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
 PLUGIN_CFLAGS = @PLUGIN_CFLAGS@
 PTHREADLIB = @PTHREADLIB@
 PYTHON = @PYTHON@
+PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@
 PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
 PYTHON_PLATFORM = @PYTHON_PLATFORM@
 PYTHON_PREFIX = @PYTHON_PREFIX@
 PYTHON_VERSION = @PYTHON_VERSION@
+PY_TEST = @PY_TEST@
 RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
@@ -313,6 +316,8 @@ json_CFLAGS = @json_CFLAGS@
 json_LIBS = @json_LIBS@
 libdir = @libdir@
 libexecdir = @libexecdir@
+libiptc_CFLAGS = @libiptc_CFLAGS@
+libiptc_LIBS = @libiptc_LIBS@
 linux_headers = @linux_headers@
 localedir = @localedir@
 localstatedir = @localstatedir@
diff --git a/src/ipsec/_ipsec.8 b/src/ipsec/_ipsec.8
index 9ba9bd8..d2d0c2e 100644
--- a/src/ipsec/_ipsec.8
+++ b/src/ipsec/_ipsec.8
@@ -1,4 +1,4 @@
-.TH IPSEC 8 "2013-10-29" "5.2.1" "strongSwan"
+.TH IPSEC 8 "2013-10-29" "5.3.0" "strongSwan"
 .
 .SH NAME
 .
@@ -210,15 +210,18 @@ flushes and rereads all secrets defined in \fIipsec.secrets\fP.
 .
 .TP
 .B "rereadcacerts"
-reads all certificate files contained in the \fI/etc/ipsec.d/cacerts\fP
-directory and adds them to the list of Certification Authority (CA)
-certificates.
+removes previously loaded CA certificates, reads all certificate files
+contained in the \fI/etc/ipsec.d/cacerts\fP directory and adds them to the list
+of Certification Authority (CA) certificates. This does not affect certificates
+explicitly defined in a
+.BR ipsec.conf (5)
+ca section, which may be separately updated using the \fBupdate\fP command.
 .
 .TP
 .B "rereadaacerts"
-reads all certificate files contained in the \fI/etc/ipsec.d/aacerts\fP
-directory and adds them to the list of Authorization Authority (AA)
-certificates.
+removes previously loaded AA certificates, reads all certificate files
+contained in the \fI/etc/ipsec.d/aacerts\fP directory and adds them to the list
+of Authorization Authority (AA) certificates.
 .
 .TP
 .B "rereadocspcerts"
diff --git a/src/ipsec/_ipsec.8.in b/src/ipsec/_ipsec.8.in
index 210d74e..0aef8c0 100644
--- a/src/ipsec/_ipsec.8.in
+++ b/src/ipsec/_ipsec.8.in
@@ -210,15 +210,18 @@ flushes and rereads all secrets defined in \fIipsec.secrets\fP.
 .
 .TP
 .B "rereadcacerts"
-reads all certificate files contained in the \fI/etc/ipsec.d/cacerts\fP
-directory and adds them to the list of Certification Authority (CA)
-certificates.
+removes previously loaded CA certificates, reads all certificate files
+contained in the \fI/etc/ipsec.d/cacerts\fP directory and adds them to the list
+of Certification Authority (CA) certificates. This does not affect certificates
+explicitly defined in a
+.BR ipsec.conf (5)
+ca section, which may be separately updated using the \fBupdate\fP command.
 .
 .TP
 .B "rereadaacerts"
-reads all certificate files contained in the \fI/etc/ipsec.d/aacerts\fP
-directory and adds them to the list of Authorization Authority (AA)
-certificates.
+removes previously loaded AA certificates, reads all certificate files
+contained in the \fI/etc/ipsec.d/aacerts\fP directory and adds them to the list
+of Authorization Authority (AA) certificates.
 .
 .TP
 .B "rereadocspcerts"
diff --git a/src/libcharon/Android.mk b/src/libcharon/Android.mk
index 4212ee8..5eef6fd 100644
--- a/src/libcharon/Android.mk
+++ b/src/libcharon/Android.mk
@@ -3,6 +3,10 @@ include $(CLEAR_VARS)
 
 # copy-n-paste from Makefile.am
 libcharon_la_SOURCES := \
+attributes/attributes.c attributes/attributes.h \
+attributes/attribute_provider.h attributes/attribute_handler.h \
+attributes/attribute_manager.c attributes/attribute_manager.h \
+attributes/mem_pool.c attributes/mem_pool.h \
 bus/bus.c bus/bus.h \
 bus/listeners/listener.h \
 bus/listeners/logger.h \
@@ -62,6 +66,7 @@ processing/jobs/start_action_job.c processing/jobs/start_action_job.h \
 processing/jobs/roam_job.c processing/jobs/roam_job.h \
 processing/jobs/update_sa_job.c processing/jobs/update_sa_job.h \
 processing/jobs/inactivity_job.c processing/jobs/inactivity_job.h \
+processing/jobs/initiate_tasks_job.c processing/jobs/initiate_tasks_job.h \
 sa/eap/eap_method.c sa/eap/eap_method.h sa/eap/eap_inner_method.h \
 sa/eap/eap_manager.c sa/eap/eap_manager.h \
 sa/xauth/xauth_method.c sa/xauth/xauth_method.h \
@@ -72,6 +77,7 @@ sa/ike_sa.c sa/ike_sa.h \
 sa/ike_sa_id.c sa/ike_sa_id.h \
 sa/keymat.h sa/keymat.c \
 sa/ike_sa_manager.c sa/ike_sa_manager.h \
+sa/child_sa_manager.c sa/child_sa_manager.h \
 sa/task_manager.h sa/task_manager.c \
 sa/shunt_manager.c sa/shunt_manager.h \
 sa/trap_manager.c sa/trap_manager.h \
@@ -97,6 +103,7 @@ sa/ikev2/tasks/ike_natd.c sa/ikev2/tasks/ike_natd.h \
 sa/ikev2/tasks/ike_mobike.c sa/ikev2/tasks/ike_mobike.h \
 sa/ikev2/tasks/ike_rekey.c sa/ikev2/tasks/ike_rekey.h \
 sa/ikev2/tasks/ike_reauth.c sa/ikev2/tasks/ike_reauth.h \
+sa/ikev2/tasks/ike_reauth_complete.c sa/ikev2/tasks/ike_reauth_complete.h \
 sa/ikev2/tasks/ike_auth_lifetime.c sa/ikev2/tasks/ike_auth_lifetime.h \
 sa/ikev2/tasks/ike_vendor.c sa/ikev2/tasks/ike_vendor.h
 
@@ -238,4 +245,3 @@ LOCAL_PRELINK_MODULE := false
 LOCAL_SHARED_LIBRARIES += libstrongswan libhydra
 
 include $(BUILD_SHARED_LIBRARY)
-
diff --git a/src/libcharon/Makefile.am b/src/libcharon/Makefile.am
index e98f5e1..cd81a5e 100644
--- a/src/libcharon/Makefile.am
+++ b/src/libcharon/Makefile.am
@@ -1,6 +1,10 @@
 ipseclib_LTLIBRARIES = libcharon.la
 
 libcharon_la_SOURCES = \
+attributes/attributes.c attributes/attributes.h \
+attributes/attribute_provider.h attributes/attribute_handler.h \
+attributes/attribute_manager.c attributes/attribute_manager.h \
+attributes/mem_pool.c attributes/mem_pool.h \
 bus/bus.c bus/bus.h \
 bus/listeners/listener.h \
 bus/listeners/logger.h \
@@ -60,6 +64,7 @@ processing/jobs/start_action_job.c processing/jobs/start_action_job.h \
 processing/jobs/roam_job.c processing/jobs/roam_job.h \
 processing/jobs/update_sa_job.c processing/jobs/update_sa_job.h \
 processing/jobs/inactivity_job.c processing/jobs/inactivity_job.h \
+processing/jobs/initiate_tasks_job.c processing/jobs/initiate_tasks_job.h \
 sa/eap/eap_method.c sa/eap/eap_method.h sa/eap/eap_inner_method.h \
 sa/eap/eap_manager.c sa/eap/eap_manager.h \
 sa/xauth/xauth_method.c sa/xauth/xauth_method.h \
@@ -70,6 +75,7 @@ sa/ike_sa.c sa/ike_sa.h \
 sa/ike_sa_id.c sa/ike_sa_id.h \
 sa/keymat.h sa/keymat.c \
 sa/ike_sa_manager.c sa/ike_sa_manager.h \
+sa/child_sa_manager.c sa/child_sa_manager.h \
 sa/task_manager.h sa/task_manager.c \
 sa/shunt_manager.c sa/shunt_manager.h \
 sa/trap_manager.c sa/trap_manager.h \
@@ -96,6 +102,7 @@ sa/ikev2/tasks/ike_natd.c sa/ikev2/tasks/ike_natd.h \
 sa/ikev2/tasks/ike_mobike.c sa/ikev2/tasks/ike_mobike.h \
 sa/ikev2/tasks/ike_rekey.c sa/ikev2/tasks/ike_rekey.h \
 sa/ikev2/tasks/ike_reauth.c sa/ikev2/tasks/ike_reauth.h \
+sa/ikev2/tasks/ike_reauth_complete.c sa/ikev2/tasks/ike_reauth_complete.h \
 sa/ikev2/tasks/ike_auth_lifetime.c sa/ikev2/tasks/ike_auth_lifetime.h \
 sa/ikev2/tasks/ike_vendor.c sa/ikev2/tasks/ike_vendor.h
 endif
@@ -203,6 +210,20 @@ if MONOLITHIC
 endif
 endif
 
+if USE_CONNMARK
+  SUBDIRS += plugins/connmark
+if MONOLITHIC
+  libcharon_la_LIBADD += plugins/connmark/libstrongswan-connmark.la
+endif
+endif
+
+if USE_FORECAST
+  SUBDIRS += plugins/forecast
+if MONOLITHIC
+  libcharon_la_LIBADD += plugins/forecast/libstrongswan-forecast.la
+endif
+endif
+
 if USE_FARP
   SUBDIRS += plugins/farp
 if MONOLITHIC
@@ -595,13 +616,6 @@ if MONOLITHIC
 endif
 endif
 
-if USE_UNIT_TESTS
-  SUBDIRS += plugins/unit_tester
-if MONOLITHIC
-  libcharon_la_LIBADD += plugins/unit_tester/libstrongswan-unit-tester.la
-endif
-endif
-
 if USE_XAUTH_GENERIC
   SUBDIRS += plugins/xauth_generic
 if MONOLITHIC
@@ -629,3 +643,29 @@ if MONOLITHIC
   libcharon_la_LIBADD += plugins/xauth_noauth/libstrongswan-xauth-noauth.la
 endif
 endif
+
+if USE_RESOLVE
+  SUBDIRS += plugins/resolve
+if MONOLITHIC
+  libcharon_la_LIBADD += plugins/resolve/libstrongswan-resolve.la
+endif
+endif
+
+if USE_ATTR
+  SUBDIRS += plugins/attr
+if MONOLITHIC
+  libcharon_la_LIBADD += plugins/attr/libstrongswan-attr.la
+endif
+endif
+
+if USE_ATTR_SQL
+  SUBDIRS += plugins/attr_sql
+if MONOLITHIC
+  libcharon_la_LIBADD += plugins/attr_sql/libstrongswan-attr-sql.la
+endif
+endif
+
+if MONOLITHIC
+  SUBDIRS += .
+endif
+SUBDIRS += tests
diff --git a/src/libcharon/Makefile.in b/src/libcharon/Makefile.in
index 4d89794..3d425e0 100644
--- a/src/libcharon/Makefile.in
+++ b/src/libcharon/Makefile.in
@@ -98,6 +98,7 @@ host_triplet = @host@
 @USE_IKEV2_TRUE at sa/ikev2/tasks/ike_mobike.c sa/ikev2/tasks/ike_mobike.h \
 @USE_IKEV2_TRUE at sa/ikev2/tasks/ike_rekey.c sa/ikev2/tasks/ike_rekey.h \
 @USE_IKEV2_TRUE at sa/ikev2/tasks/ike_reauth.c sa/ikev2/tasks/ike_reauth.h \
+ at USE_IKEV2_TRUE@sa/ikev2/tasks/ike_reauth_complete.c sa/ikev2/tasks/ike_reauth_complete.h \
 @USE_IKEV2_TRUE at sa/ikev2/tasks/ike_auth_lifetime.c sa/ikev2/tasks/ike_auth_lifetime.h \
 @USE_IKEV2_TRUE at sa/ikev2/tasks/ike_vendor.c sa/ikev2/tasks/ike_vendor.h
 
@@ -146,124 +147,132 @@ host_triplet = @host@
 @MONOLITHIC_TRUE@@USE_SOCKET_DYNAMIC_TRUE at am__append_11 = plugins/socket_dynamic/libstrongswan-socket-dynamic.la
 @USE_SOCKET_WIN_TRUE at am__append_12 = plugins/socket_win
 @MONOLITHIC_TRUE@@USE_SOCKET_WIN_TRUE at am__append_13 = plugins/socket_win/libstrongswan-socket-win.la
- at USE_FARP_TRUE@am__append_14 = plugins/farp
- at MONOLITHIC_TRUE@@USE_FARP_TRUE at am__append_15 = plugins/farp/libstrongswan-farp.la
- at USE_STROKE_TRUE@am__append_16 = plugins/stroke
- at MONOLITHIC_TRUE@@USE_STROKE_TRUE at am__append_17 = plugins/stroke/libstrongswan-stroke.la
- at USE_VICI_TRUE@am__append_18 = plugins/vici
- at MONOLITHIC_TRUE@@USE_VICI_TRUE at am__append_19 = plugins/vici/libstrongswan-vici.la
- at USE_SMP_TRUE@am__append_20 = plugins/smp
- at MONOLITHIC_TRUE@@USE_SMP_TRUE at am__append_21 = plugins/smp/libstrongswan-smp.la
- at USE_SQL_TRUE@am__append_22 = plugins/sql
- at MONOLITHIC_TRUE@@USE_SQL_TRUE at am__append_23 = plugins/sql/libstrongswan-sql.la
- at USE_DNSCERT_TRUE@am__append_24 = plugins/dnscert
- at MONOLITHIC_TRUE@@USE_DNSCERT_TRUE at am__append_25 = plugins/dnscert/libstrongswan-dnscert.la
- at USE_IPSECKEY_TRUE@am__append_26 = plugins/ipseckey
- at MONOLITHIC_TRUE@@USE_IPSECKEY_TRUE at am__append_27 = plugins/ipseckey/libstrongswan-ipseckey.la
- at USE_UPDOWN_TRUE@am__append_28 = plugins/updown
- at MONOLITHIC_TRUE@@USE_UPDOWN_TRUE at am__append_29 = plugins/updown/libstrongswan-updown.la
- at USE_EXT_AUTH_TRUE@am__append_30 = plugins/ext_auth
- at MONOLITHIC_TRUE@@USE_EXT_AUTH_TRUE at am__append_31 = plugins/ext_auth/libstrongswan-ext-auth.la
- at USE_EAP_IDENTITY_TRUE@am__append_32 = plugins/eap_identity
- at MONOLITHIC_TRUE@@USE_EAP_IDENTITY_TRUE at am__append_33 = plugins/eap_identity/libstrongswan-eap-identity.la
- at USE_EAP_SIM_TRUE@am__append_34 = plugins/eap_sim
- at MONOLITHIC_TRUE@@USE_EAP_SIM_TRUE at am__append_35 = plugins/eap_sim/libstrongswan-eap-sim.la
- at USE_EAP_SIM_FILE_TRUE@am__append_36 = plugins/eap_sim_file
- at MONOLITHIC_TRUE@@USE_EAP_SIM_FILE_TRUE at am__append_37 = plugins/eap_sim_file/libstrongswan-eap-sim-file.la
- at USE_EAP_SIM_PCSC_TRUE@am__append_38 = plugins/eap_sim_pcsc
- at MONOLITHIC_TRUE@@USE_EAP_SIM_PCSC_TRUE at am__append_39 = plugins/eap_sim_pcsc/libstrongswan-eap-sim-pcsc.la
- at USE_EAP_SIMAKA_SQL_TRUE@am__append_40 = plugins/eap_simaka_sql
- at MONOLITHIC_TRUE@@USE_EAP_SIMAKA_SQL_TRUE at am__append_41 = plugins/eap_simaka_sql/libstrongswan-eap-simaka-sql.la
- at USE_EAP_SIMAKA_PSEUDONYM_TRUE@am__append_42 = plugins/eap_simaka_pseudonym
- at MONOLITHIC_TRUE@@USE_EAP_SIMAKA_PSEUDONYM_TRUE at am__append_43 = plugins/eap_simaka_pseudonym/libstrongswan-eap-simaka-pseudonym.la
- at USE_EAP_SIMAKA_REAUTH_TRUE@am__append_44 = plugins/eap_simaka_reauth
- at MONOLITHIC_TRUE@@USE_EAP_SIMAKA_REAUTH_TRUE at am__append_45 = plugins/eap_simaka_reauth/libstrongswan-eap-simaka-reauth.la
- at USE_EAP_AKA_TRUE@am__append_46 = plugins/eap_aka
- at MONOLITHIC_TRUE@@USE_EAP_AKA_TRUE at am__append_47 = plugins/eap_aka/libstrongswan-eap-aka.la
- at USE_EAP_AKA_3GPP2_TRUE@am__append_48 = plugins/eap_aka_3gpp2
- at MONOLITHIC_TRUE@@USE_EAP_AKA_3GPP2_TRUE at am__append_49 = plugins/eap_aka_3gpp2/libstrongswan-eap-aka-3gpp2.la
- at MONOLITHIC_TRUE@@USE_SIMAKA_TRUE at am__append_50 = $(top_builddir)/src/libsimaka/libsimaka.la
- at USE_EAP_MD5_TRUE@am__append_51 = plugins/eap_md5
- at MONOLITHIC_TRUE@@USE_EAP_MD5_TRUE at am__append_52 = plugins/eap_md5/libstrongswan-eap-md5.la
- at USE_EAP_GTC_TRUE@am__append_53 = plugins/eap_gtc
- at MONOLITHIC_TRUE@@USE_EAP_GTC_TRUE at am__append_54 = plugins/eap_gtc/libstrongswan-eap-gtc.la
- at USE_EAP_MSCHAPV2_TRUE@am__append_55 = plugins/eap_mschapv2
- at MONOLITHIC_TRUE@@USE_EAP_MSCHAPV2_TRUE at am__append_56 = plugins/eap_mschapv2/libstrongswan-eap-mschapv2.la
- at USE_EAP_DYNAMIC_TRUE@am__append_57 = plugins/eap_dynamic
- at MONOLITHIC_TRUE@@USE_EAP_DYNAMIC_TRUE at am__append_58 = plugins/eap_dynamic/libstrongswan-eap-dynamic.la
- at USE_EAP_RADIUS_TRUE@am__append_59 = plugins/eap_radius
- at MONOLITHIC_TRUE@@USE_EAP_RADIUS_TRUE at am__append_60 = plugins/eap_radius/libstrongswan-eap-radius.la
- at USE_EAP_TLS_TRUE@am__append_61 = plugins/eap_tls
- at MONOLITHIC_TRUE@@USE_EAP_TLS_TRUE at am__append_62 = plugins/eap_tls/libstrongswan-eap-tls.la
- at USE_EAP_TTLS_TRUE@am__append_63 = plugins/eap_ttls
- at MONOLITHIC_TRUE@@USE_EAP_TTLS_TRUE at am__append_64 = plugins/eap_ttls/libstrongswan-eap-ttls.la
- at USE_EAP_PEAP_TRUE@am__append_65 = plugins/eap_peap
- at MONOLITHIC_TRUE@@USE_EAP_PEAP_TRUE at am__append_66 = plugins/eap_peap/libstrongswan-eap-peap.la
- at USE_EAP_TNC_TRUE@am__append_67 = plugins/eap_tnc
- at MONOLITHIC_TRUE@@USE_EAP_TNC_TRUE at am__append_68 = plugins/eap_tnc/libstrongswan-eap-tnc.la
- at MONOLITHIC_TRUE@@USE_TLS_TRUE at am__append_69 = $(top_builddir)/src/libtls/libtls.la
- at MONOLITHIC_TRUE@@USE_RADIUS_TRUE at am__append_70 = $(top_builddir)/src/libradius/libradius.la
- at USE_TNC_IFMAP_TRUE@am__append_71 = plugins/tnc_ifmap
- at MONOLITHIC_TRUE@@USE_TNC_IFMAP_TRUE at am__append_72 = plugins/tnc_ifmap/libstrongswan-tnc-ifmap.la
- at USE_TNC_PDP_TRUE@am__append_73 = plugins/tnc_pdp
- at MONOLITHIC_TRUE@@USE_TNC_PDP_TRUE at am__append_74 = plugins/tnc_pdp/libstrongswan-tnc-pdp.la
- at MONOLITHIC_TRUE@@USE_LIBTNCCS_TRUE at am__append_75 = $(top_builddir)/src/libtnccs/libtnccs.la
- at USE_MEDSRV_TRUE@am__append_76 = plugins/medsrv
- at MONOLITHIC_TRUE@@USE_MEDSRV_TRUE at am__append_77 = plugins/medsrv/libstrongswan-medsrv.la
- at USE_MEDCLI_TRUE@am__append_78 = plugins/medcli
- at MONOLITHIC_TRUE@@USE_MEDCLI_TRUE at am__append_79 = plugins/medcli/libstrongswan-medcli.la
- at USE_DHCP_TRUE@am__append_80 = plugins/dhcp
- at MONOLITHIC_TRUE@@USE_DHCP_TRUE at am__append_81 = plugins/dhcp/libstrongswan-dhcp.la
- at USE_OSX_ATTR_TRUE@am__append_82 = plugins/osx_attr
- at MONOLITHIC_TRUE@@USE_OSX_ATTR_TRUE at am__append_83 = plugins/osx_attr/libstrongswan-osx-attr.la
- at USE_ANDROID_DNS_TRUE@am__append_84 = plugins/android_dns
- at MONOLITHIC_TRUE@@USE_ANDROID_DNS_TRUE at am__append_85 = plugins/android_dns/libstrongswan-android-dns.la
- at USE_ANDROID_LOG_TRUE@am__append_86 = plugins/android_log
- at MONOLITHIC_TRUE@@USE_ANDROID_LOG_TRUE at am__append_87 = plugins/android_log/libstrongswan-android-log.la
- at USE_MAEMO_TRUE@am__append_88 = plugins/maemo
- at MONOLITHIC_TRUE@@USE_MAEMO_TRUE at am__append_89 = plugins/maemo/libstrongswan-maemo.la
- at USE_HA_TRUE@am__append_90 = plugins/ha
- at MONOLITHIC_TRUE@@USE_HA_TRUE at am__append_91 = plugins/ha/libstrongswan-ha.la
- at USE_KERNEL_LIBIPSEC_TRUE@am__append_92 = plugins/kernel_libipsec
- at MONOLITHIC_TRUE@@USE_KERNEL_LIBIPSEC_TRUE at am__append_93 = plugins/kernel_libipsec/libstrongswan-kernel-libipsec.la
- at USE_KERNEL_WFP_TRUE@am__append_94 = plugins/kernel_wfp
- at MONOLITHIC_TRUE@@USE_KERNEL_WFP_TRUE at am__append_95 = plugins/kernel_wfp/libstrongswan-kernel-wfp.la
- at USE_KERNEL_IPH_TRUE@am__append_96 = plugins/kernel_iph
- at MONOLITHIC_TRUE@@USE_KERNEL_IPH_TRUE at am__append_97 = plugins/kernel_iph/libstrongswan-kernel-iph.la
- at USE_WHITELIST_TRUE@am__append_98 = plugins/whitelist
- at MONOLITHIC_TRUE@@USE_WHITELIST_TRUE at am__append_99 = plugins/whitelist/libstrongswan-whitelist.la
- at USE_LOOKIP_TRUE@am__append_100 = plugins/lookip
- at MONOLITHIC_TRUE@@USE_LOOKIP_TRUE at am__append_101 = plugins/lookip/libstrongswan-lookip.la
- at USE_ERROR_NOTIFY_TRUE@am__append_102 = plugins/error_notify
- at MONOLITHIC_TRUE@@USE_ERROR_NOTIFY_TRUE at am__append_103 = plugins/error_notify/libstrongswan-error-notify.la
- at USE_CERTEXPIRE_TRUE@am__append_104 = plugins/certexpire
- at MONOLITHIC_TRUE@@USE_CERTEXPIRE_TRUE at am__append_105 = plugins/certexpire/libstrongswan-certexpire.la
- at USE_SYSTIME_FIX_TRUE@am__append_106 = plugins/systime_fix
- at MONOLITHIC_TRUE@@USE_SYSTIME_FIX_TRUE at am__append_107 = plugins/systime_fix/libstrongswan-systime-fix.la
- at USE_LED_TRUE@am__append_108 = plugins/led
- at MONOLITHIC_TRUE@@USE_LED_TRUE at am__append_109 = plugins/led/libstrongswan-led.la
- at USE_DUPLICHECK_TRUE@am__append_110 = plugins/duplicheck
- at MONOLITHIC_TRUE@@USE_DUPLICHECK_TRUE at am__append_111 = plugins/duplicheck/libstrongswan-duplicheck.la
- at USE_COUPLING_TRUE@am__append_112 = plugins/coupling
- at MONOLITHIC_TRUE@@USE_COUPLING_TRUE at am__append_113 = plugins/coupling/libstrongswan-coupling.la
- at USE_RADATTR_TRUE@am__append_114 = plugins/radattr
- at MONOLITHIC_TRUE@@USE_RADATTR_TRUE at am__append_115 = plugins/radattr/libstrongswan-radattr.la
- at USE_UCI_TRUE@am__append_116 = plugins/uci
- at MONOLITHIC_TRUE@@USE_UCI_TRUE at am__append_117 = plugins/uci/libstrongswan-uci.la
- at USE_ADDRBLOCK_TRUE@am__append_118 = plugins/addrblock
- at MONOLITHIC_TRUE@@USE_ADDRBLOCK_TRUE at am__append_119 = plugins/addrblock/libstrongswan-addrblock.la
- at USE_UNITY_TRUE@am__append_120 = plugins/unity
- at MONOLITHIC_TRUE@@USE_UNITY_TRUE at am__append_121 = plugins/unity/libstrongswan-unity.la
- at USE_UNIT_TESTS_TRUE@am__append_122 = plugins/unit_tester
- at MONOLITHIC_TRUE@@USE_UNIT_TESTS_TRUE at am__append_123 = plugins/unit_tester/libstrongswan-unit-tester.la
- at USE_XAUTH_GENERIC_TRUE@am__append_124 = plugins/xauth_generic
- at MONOLITHIC_TRUE@@USE_XAUTH_GENERIC_TRUE at am__append_125 = plugins/xauth_generic/libstrongswan-xauth-generic.la
- at USE_XAUTH_EAP_TRUE@am__append_126 = plugins/xauth_eap
- at MONOLITHIC_TRUE@@USE_XAUTH_EAP_TRUE at am__append_127 = plugins/xauth_eap/libstrongswan-xauth-eap.la
- at USE_XAUTH_PAM_TRUE@am__append_128 = plugins/xauth_pam
- at MONOLITHIC_TRUE@@USE_XAUTH_PAM_TRUE at am__append_129 = plugins/xauth_pam/libstrongswan-xauth-pam.la
- at USE_XAUTH_NOAUTH_TRUE@am__append_130 = plugins/xauth_noauth
- at MONOLITHIC_TRUE@@USE_XAUTH_NOAUTH_TRUE at am__append_131 = plugins/xauth_noauth/libstrongswan-xauth-noauth.la
+ at USE_CONNMARK_TRUE@am__append_14 = plugins/connmark
+ at MONOLITHIC_TRUE@@USE_CONNMARK_TRUE at am__append_15 = plugins/connmark/libstrongswan-connmark.la
+ at USE_FORECAST_TRUE@am__append_16 = plugins/forecast
+ at MONOLITHIC_TRUE@@USE_FORECAST_TRUE at am__append_17 = plugins/forecast/libstrongswan-forecast.la
+ at USE_FARP_TRUE@am__append_18 = plugins/farp
+ at MONOLITHIC_TRUE@@USE_FARP_TRUE at am__append_19 = plugins/farp/libstrongswan-farp.la
+ at USE_STROKE_TRUE@am__append_20 = plugins/stroke
+ at MONOLITHIC_TRUE@@USE_STROKE_TRUE at am__append_21 = plugins/stroke/libstrongswan-stroke.la
+ at USE_VICI_TRUE@am__append_22 = plugins/vici
+ at MONOLITHIC_TRUE@@USE_VICI_TRUE at am__append_23 = plugins/vici/libstrongswan-vici.la
+ at USE_SMP_TRUE@am__append_24 = plugins/smp
+ at MONOLITHIC_TRUE@@USE_SMP_TRUE at am__append_25 = plugins/smp/libstrongswan-smp.la
+ at USE_SQL_TRUE@am__append_26 = plugins/sql
+ at MONOLITHIC_TRUE@@USE_SQL_TRUE at am__append_27 = plugins/sql/libstrongswan-sql.la
+ at USE_DNSCERT_TRUE@am__append_28 = plugins/dnscert
+ at MONOLITHIC_TRUE@@USE_DNSCERT_TRUE at am__append_29 = plugins/dnscert/libstrongswan-dnscert.la
+ at USE_IPSECKEY_TRUE@am__append_30 = plugins/ipseckey
+ at MONOLITHIC_TRUE@@USE_IPSECKEY_TRUE at am__append_31 = plugins/ipseckey/libstrongswan-ipseckey.la
+ at USE_UPDOWN_TRUE@am__append_32 = plugins/updown
+ at MONOLITHIC_TRUE@@USE_UPDOWN_TRUE at am__append_33 = plugins/updown/libstrongswan-updown.la
+ at USE_EXT_AUTH_TRUE@am__append_34 = plugins/ext_auth
+ at MONOLITHIC_TRUE@@USE_EXT_AUTH_TRUE at am__append_35 = plugins/ext_auth/libstrongswan-ext-auth.la
+ at USE_EAP_IDENTITY_TRUE@am__append_36 = plugins/eap_identity
+ at MONOLITHIC_TRUE@@USE_EAP_IDENTITY_TRUE at am__append_37 = plugins/eap_identity/libstrongswan-eap-identity.la
+ at USE_EAP_SIM_TRUE@am__append_38 = plugins/eap_sim
+ at MONOLITHIC_TRUE@@USE_EAP_SIM_TRUE at am__append_39 = plugins/eap_sim/libstrongswan-eap-sim.la
+ at USE_EAP_SIM_FILE_TRUE@am__append_40 = plugins/eap_sim_file
+ at MONOLITHIC_TRUE@@USE_EAP_SIM_FILE_TRUE at am__append_41 = plugins/eap_sim_file/libstrongswan-eap-sim-file.la
+ at USE_EAP_SIM_PCSC_TRUE@am__append_42 = plugins/eap_sim_pcsc
+ at MONOLITHIC_TRUE@@USE_EAP_SIM_PCSC_TRUE at am__append_43 = plugins/eap_sim_pcsc/libstrongswan-eap-sim-pcsc.la
+ at USE_EAP_SIMAKA_SQL_TRUE@am__append_44 = plugins/eap_simaka_sql
+ at MONOLITHIC_TRUE@@USE_EAP_SIMAKA_SQL_TRUE at am__append_45 = plugins/eap_simaka_sql/libstrongswan-eap-simaka-sql.la
+ at USE_EAP_SIMAKA_PSEUDONYM_TRUE@am__append_46 = plugins/eap_simaka_pseudonym
+ at MONOLITHIC_TRUE@@USE_EAP_SIMAKA_PSEUDONYM_TRUE at am__append_47 = plugins/eap_simaka_pseudonym/libstrongswan-eap-simaka-pseudonym.la
+ at USE_EAP_SIMAKA_REAUTH_TRUE@am__append_48 = plugins/eap_simaka_reauth
+ at MONOLITHIC_TRUE@@USE_EAP_SIMAKA_REAUTH_TRUE at am__append_49 = plugins/eap_simaka_reauth/libstrongswan-eap-simaka-reauth.la
+ at USE_EAP_AKA_TRUE@am__append_50 = plugins/eap_aka
+ at MONOLITHIC_TRUE@@USE_EAP_AKA_TRUE at am__append_51 = plugins/eap_aka/libstrongswan-eap-aka.la
+ at USE_EAP_AKA_3GPP2_TRUE@am__append_52 = plugins/eap_aka_3gpp2
+ at MONOLITHIC_TRUE@@USE_EAP_AKA_3GPP2_TRUE at am__append_53 = plugins/eap_aka_3gpp2/libstrongswan-eap-aka-3gpp2.la
+ at MONOLITHIC_TRUE@@USE_SIMAKA_TRUE at am__append_54 = $(top_builddir)/src/libsimaka/libsimaka.la
+ at USE_EAP_MD5_TRUE@am__append_55 = plugins/eap_md5
+ at MONOLITHIC_TRUE@@USE_EAP_MD5_TRUE at am__append_56 = plugins/eap_md5/libstrongswan-eap-md5.la
+ at USE_EAP_GTC_TRUE@am__append_57 = plugins/eap_gtc
+ at MONOLITHIC_TRUE@@USE_EAP_GTC_TRUE at am__append_58 = plugins/eap_gtc/libstrongswan-eap-gtc.la
+ at USE_EAP_MSCHAPV2_TRUE@am__append_59 = plugins/eap_mschapv2
+ at MONOLITHIC_TRUE@@USE_EAP_MSCHAPV2_TRUE at am__append_60 = plugins/eap_mschapv2/libstrongswan-eap-mschapv2.la
+ at USE_EAP_DYNAMIC_TRUE@am__append_61 = plugins/eap_dynamic
+ at MONOLITHIC_TRUE@@USE_EAP_DYNAMIC_TRUE at am__append_62 = plugins/eap_dynamic/libstrongswan-eap-dynamic.la
+ at USE_EAP_RADIUS_TRUE@am__append_63 = plugins/eap_radius
+ at MONOLITHIC_TRUE@@USE_EAP_RADIUS_TRUE at am__append_64 = plugins/eap_radius/libstrongswan-eap-radius.la
+ at USE_EAP_TLS_TRUE@am__append_65 = plugins/eap_tls
+ at MONOLITHIC_TRUE@@USE_EAP_TLS_TRUE at am__append_66 = plugins/eap_tls/libstrongswan-eap-tls.la
+ at USE_EAP_TTLS_TRUE@am__append_67 = plugins/eap_ttls
+ at MONOLITHIC_TRUE@@USE_EAP_TTLS_TRUE at am__append_68 = plugins/eap_ttls/libstrongswan-eap-ttls.la
+ at USE_EAP_PEAP_TRUE@am__append_69 = plugins/eap_peap
+ at MONOLITHIC_TRUE@@USE_EAP_PEAP_TRUE at am__append_70 = plugins/eap_peap/libstrongswan-eap-peap.la
+ at USE_EAP_TNC_TRUE@am__append_71 = plugins/eap_tnc
+ at MONOLITHIC_TRUE@@USE_EAP_TNC_TRUE at am__append_72 = plugins/eap_tnc/libstrongswan-eap-tnc.la
+ at MONOLITHIC_TRUE@@USE_TLS_TRUE at am__append_73 = $(top_builddir)/src/libtls/libtls.la
+ at MONOLITHIC_TRUE@@USE_RADIUS_TRUE at am__append_74 = $(top_builddir)/src/libradius/libradius.la
+ at USE_TNC_IFMAP_TRUE@am__append_75 = plugins/tnc_ifmap
+ at MONOLITHIC_TRUE@@USE_TNC_IFMAP_TRUE at am__append_76 = plugins/tnc_ifmap/libstrongswan-tnc-ifmap.la
+ at USE_TNC_PDP_TRUE@am__append_77 = plugins/tnc_pdp
+ at MONOLITHIC_TRUE@@USE_TNC_PDP_TRUE at am__append_78 = plugins/tnc_pdp/libstrongswan-tnc-pdp.la
+ at MONOLITHIC_TRUE@@USE_LIBTNCCS_TRUE at am__append_79 = $(top_builddir)/src/libtnccs/libtnccs.la
+ at USE_MEDSRV_TRUE@am__append_80 = plugins/medsrv
+ at MONOLITHIC_TRUE@@USE_MEDSRV_TRUE at am__append_81 = plugins/medsrv/libstrongswan-medsrv.la
+ at USE_MEDCLI_TRUE@am__append_82 = plugins/medcli
+ at MONOLITHIC_TRUE@@USE_MEDCLI_TRUE at am__append_83 = plugins/medcli/libstrongswan-medcli.la
+ at USE_DHCP_TRUE@am__append_84 = plugins/dhcp
+ at MONOLITHIC_TRUE@@USE_DHCP_TRUE at am__append_85 = plugins/dhcp/libstrongswan-dhcp.la
+ at USE_OSX_ATTR_TRUE@am__append_86 = plugins/osx_attr
+ at MONOLITHIC_TRUE@@USE_OSX_ATTR_TRUE at am__append_87 = plugins/osx_attr/libstrongswan-osx-attr.la
+ at USE_ANDROID_DNS_TRUE@am__append_88 = plugins/android_dns
+ at MONOLITHIC_TRUE@@USE_ANDROID_DNS_TRUE at am__append_89 = plugins/android_dns/libstrongswan-android-dns.la
+ at USE_ANDROID_LOG_TRUE@am__append_90 = plugins/android_log
+ at MONOLITHIC_TRUE@@USE_ANDROID_LOG_TRUE at am__append_91 = plugins/android_log/libstrongswan-android-log.la
+ at USE_MAEMO_TRUE@am__append_92 = plugins/maemo
+ at MONOLITHIC_TRUE@@USE_MAEMO_TRUE at am__append_93 = plugins/maemo/libstrongswan-maemo.la
+ at USE_HA_TRUE@am__append_94 = plugins/ha
+ at MONOLITHIC_TRUE@@USE_HA_TRUE at am__append_95 = plugins/ha/libstrongswan-ha.la
+ at USE_KERNEL_LIBIPSEC_TRUE@am__append_96 = plugins/kernel_libipsec
+ at MONOLITHIC_TRUE@@USE_KERNEL_LIBIPSEC_TRUE at am__append_97 = plugins/kernel_libipsec/libstrongswan-kernel-libipsec.la
+ at USE_KERNEL_WFP_TRUE@am__append_98 = plugins/kernel_wfp
+ at MONOLITHIC_TRUE@@USE_KERNEL_WFP_TRUE at am__append_99 = plugins/kernel_wfp/libstrongswan-kernel-wfp.la
+ at USE_KERNEL_IPH_TRUE@am__append_100 = plugins/kernel_iph
+ at MONOLITHIC_TRUE@@USE_KERNEL_IPH_TRUE at am__append_101 = plugins/kernel_iph/libstrongswan-kernel-iph.la
+ at USE_WHITELIST_TRUE@am__append_102 = plugins/whitelist
+ at MONOLITHIC_TRUE@@USE_WHITELIST_TRUE at am__append_103 = plugins/whitelist/libstrongswan-whitelist.la
+ at USE_LOOKIP_TRUE@am__append_104 = plugins/lookip
+ at MONOLITHIC_TRUE@@USE_LOOKIP_TRUE at am__append_105 = plugins/lookip/libstrongswan-lookip.la
+ at USE_ERROR_NOTIFY_TRUE@am__append_106 = plugins/error_notify
+ at MONOLITHIC_TRUE@@USE_ERROR_NOTIFY_TRUE at am__append_107 = plugins/error_notify/libstrongswan-error-notify.la
+ at USE_CERTEXPIRE_TRUE@am__append_108 = plugins/certexpire
+ at MONOLITHIC_TRUE@@USE_CERTEXPIRE_TRUE at am__append_109 = plugins/certexpire/libstrongswan-certexpire.la
+ at USE_SYSTIME_FIX_TRUE@am__append_110 = plugins/systime_fix
+ at MONOLITHIC_TRUE@@USE_SYSTIME_FIX_TRUE at am__append_111 = plugins/systime_fix/libstrongswan-systime-fix.la
+ at USE_LED_TRUE@am__append_112 = plugins/led
+ at MONOLITHIC_TRUE@@USE_LED_TRUE at am__append_113 = plugins/led/libstrongswan-led.la
+ at USE_DUPLICHECK_TRUE@am__append_114 = plugins/duplicheck
+ at MONOLITHIC_TRUE@@USE_DUPLICHECK_TRUE at am__append_115 = plugins/duplicheck/libstrongswan-duplicheck.la
+ at USE_COUPLING_TRUE@am__append_116 = plugins/coupling
+ at MONOLITHIC_TRUE@@USE_COUPLING_TRUE at am__append_117 = plugins/coupling/libstrongswan-coupling.la
+ at USE_RADATTR_TRUE@am__append_118 = plugins/radattr
+ at MONOLITHIC_TRUE@@USE_RADATTR_TRUE at am__append_119 = plugins/radattr/libstrongswan-radattr.la
+ at USE_UCI_TRUE@am__append_120 = plugins/uci
+ at MONOLITHIC_TRUE@@USE_UCI_TRUE at am__append_121 = plugins/uci/libstrongswan-uci.la
+ at USE_ADDRBLOCK_TRUE@am__append_122 = plugins/addrblock
+ at MONOLITHIC_TRUE@@USE_ADDRBLOCK_TRUE at am__append_123 = plugins/addrblock/libstrongswan-addrblock.la
+ at USE_UNITY_TRUE@am__append_124 = plugins/unity
+ at MONOLITHIC_TRUE@@USE_UNITY_TRUE at am__append_125 = plugins/unity/libstrongswan-unity.la
+ at USE_XAUTH_GENERIC_TRUE@am__append_126 = plugins/xauth_generic
+ at MONOLITHIC_TRUE@@USE_XAUTH_GENERIC_TRUE at am__append_127 = plugins/xauth_generic/libstrongswan-xauth-generic.la
+ at USE_XAUTH_EAP_TRUE@am__append_128 = plugins/xauth_eap
+ at MONOLITHIC_TRUE@@USE_XAUTH_EAP_TRUE at am__append_129 = plugins/xauth_eap/libstrongswan-xauth-eap.la
+ at USE_XAUTH_PAM_TRUE@am__append_130 = plugins/xauth_pam
+ at MONOLITHIC_TRUE@@USE_XAUTH_PAM_TRUE at am__append_131 = plugins/xauth_pam/libstrongswan-xauth-pam.la
+ at USE_XAUTH_NOAUTH_TRUE@am__append_132 = plugins/xauth_noauth
+ at MONOLITHIC_TRUE@@USE_XAUTH_NOAUTH_TRUE at am__append_133 = plugins/xauth_noauth/libstrongswan-xauth-noauth.la
+ at USE_RESOLVE_TRUE@am__append_134 = plugins/resolve
+ at MONOLITHIC_TRUE@@USE_RESOLVE_TRUE at am__append_135 = plugins/resolve/libstrongswan-resolve.la
+ at USE_ATTR_TRUE@am__append_136 = plugins/attr
+ at MONOLITHIC_TRUE@@USE_ATTR_TRUE at am__append_137 = plugins/attr/libstrongswan-attr.la
+ at USE_ATTR_SQL_TRUE@am__append_138 = plugins/attr_sql
+ at MONOLITHIC_TRUE@@USE_ATTR_SQL_TRUE at am__append_139 = plugins/attr_sql/libstrongswan-attr-sql.la
 subdir = src/libcharon
 DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
 	$(top_srcdir)/depcomp
@@ -325,12 +334,12 @@ libcharon_la_DEPENDENCIES =  \
 	$(am__append_29) $(am__append_31) $(am__append_33) \
 	$(am__append_35) $(am__append_37) $(am__append_39) \
 	$(am__append_41) $(am__append_43) $(am__append_45) \
-	$(am__append_47) $(am__append_49) $(am__append_50) \
-	$(am__append_52) $(am__append_54) $(am__append_56) \
+	$(am__append_47) $(am__append_49) $(am__append_51) \
+	$(am__append_53) $(am__append_54) $(am__append_56) \
 	$(am__append_58) $(am__append_60) $(am__append_62) \
 	$(am__append_64) $(am__append_66) $(am__append_68) \
-	$(am__append_69) $(am__append_70) $(am__append_72) \
-	$(am__append_74) $(am__append_75) $(am__append_77) \
+	$(am__append_70) $(am__append_72) $(am__append_73) \
+	$(am__append_74) $(am__append_76) $(am__append_78) \
 	$(am__append_79) $(am__append_81) $(am__append_83) \
 	$(am__append_85) $(am__append_87) $(am__append_89) \
 	$(am__append_91) $(am__append_93) $(am__append_95) \
@@ -339,8 +348,14 @@ libcharon_la_DEPENDENCIES =  \
 	$(am__append_109) $(am__append_111) $(am__append_113) \
 	$(am__append_115) $(am__append_117) $(am__append_119) \
 	$(am__append_121) $(am__append_123) $(am__append_125) \
-	$(am__append_127) $(am__append_129) $(am__append_131)
-am__libcharon_la_SOURCES_DIST = bus/bus.c bus/bus.h \
+	$(am__append_127) $(am__append_129) $(am__append_131) \
+	$(am__append_133) $(am__append_135) $(am__append_137) \
+	$(am__append_139)
+am__libcharon_la_SOURCES_DIST = attributes/attributes.c \
+	attributes/attributes.h attributes/attribute_provider.h \
+	attributes/attribute_handler.h attributes/attribute_manager.c \
+	attributes/attribute_manager.h attributes/mem_pool.c \
+	attributes/mem_pool.h bus/bus.c bus/bus.h \
 	bus/listeners/listener.h bus/listeners/logger.h \
 	bus/listeners/file_logger.c bus/listeners/file_logger.h \
 	config/backend_manager.c config/backend_manager.h \
@@ -421,7 +436,9 @@ am__libcharon_la_SOURCES_DIST = bus/bus.c bus/bus.h \
 	processing/jobs/roam_job.h processing/jobs/update_sa_job.c \
 	processing/jobs/update_sa_job.h \
 	processing/jobs/inactivity_job.c \
-	processing/jobs/inactivity_job.h sa/eap/eap_method.c \
+	processing/jobs/inactivity_job.h \
+	processing/jobs/initiate_tasks_job.c \
+	processing/jobs/initiate_tasks_job.h sa/eap/eap_method.c \
 	sa/eap/eap_method.h sa/eap/eap_inner_method.h \
 	sa/eap/eap_manager.c sa/eap/eap_manager.h \
 	sa/xauth/xauth_method.c sa/xauth/xauth_method.h \
@@ -429,7 +446,8 @@ am__libcharon_la_SOURCES_DIST = bus/bus.c bus/bus.h \
 	sa/authenticator.c sa/authenticator.h sa/child_sa.c \
 	sa/child_sa.h sa/ike_sa.c sa/ike_sa.h sa/ike_sa_id.c \
 	sa/ike_sa_id.h sa/keymat.h sa/keymat.c sa/ike_sa_manager.c \
-	sa/ike_sa_manager.h sa/task_manager.h sa/task_manager.c \
+	sa/ike_sa_manager.h sa/child_sa_manager.c \
+	sa/child_sa_manager.h sa/task_manager.h sa/task_manager.c \
 	sa/shunt_manager.c sa/shunt_manager.h sa/trap_manager.c \
 	sa/trap_manager.h sa/task.c sa/task.h sa/ikev2/keymat_v2.c \
 	sa/ikev2/keymat_v2.h sa/ikev2/task_manager_v2.c \
@@ -454,6 +472,8 @@ am__libcharon_la_SOURCES_DIST = bus/bus.c bus/bus.h \
 	sa/ikev2/tasks/ike_mobike.c sa/ikev2/tasks/ike_mobike.h \
 	sa/ikev2/tasks/ike_rekey.c sa/ikev2/tasks/ike_rekey.h \
 	sa/ikev2/tasks/ike_reauth.c sa/ikev2/tasks/ike_reauth.h \
+	sa/ikev2/tasks/ike_reauth_complete.c \
+	sa/ikev2/tasks/ike_reauth_complete.h \
 	sa/ikev2/tasks/ike_auth_lifetime.c \
 	sa/ikev2/tasks/ike_auth_lifetime.h sa/ikev2/tasks/ike_vendor.c \
 	sa/ikev2/tasks/ike_vendor.h sa/ikev1/keymat_v1.c \
@@ -514,6 +534,7 @@ am__dirstamp = $(am__leading_dot)dirstamp
 @USE_IKEV2_TRUE@	sa/ikev2/tasks/ike_mobike.lo \
 @USE_IKEV2_TRUE@	sa/ikev2/tasks/ike_rekey.lo \
 @USE_IKEV2_TRUE@	sa/ikev2/tasks/ike_reauth.lo \
+ at USE_IKEV2_TRUE@	sa/ikev2/tasks/ike_reauth_complete.lo \
 @USE_IKEV2_TRUE@	sa/ikev2/tasks/ike_auth_lifetime.lo \
 @USE_IKEV2_TRUE@	sa/ikev2/tasks/ike_vendor.lo
 @USE_IKEV1_TRUE at am__objects_2 = sa/ikev1/keymat_v1.lo \
@@ -543,7 +564,9 @@ am__dirstamp = $(am__leading_dot)dirstamp
 @USE_ME_TRUE@	sa/ikev2/connect_manager.lo \
 @USE_ME_TRUE@	sa/ikev2/mediation_manager.lo \
 @USE_ME_TRUE@	sa/ikev2/tasks/ike_me.lo
-am_libcharon_la_OBJECTS = bus/bus.lo bus/listeners/file_logger.lo \
+am_libcharon_la_OBJECTS = attributes/attributes.lo \
+	attributes/attribute_manager.lo attributes/mem_pool.lo \
+	bus/bus.lo bus/listeners/file_logger.lo \
 	config/backend_manager.lo config/child_cfg.lo \
 	config/ike_cfg.lo config/peer_cfg.lo config/proposal.lo \
 	control/controller.lo daemon.lo encoding/generator.lo \
@@ -587,13 +610,14 @@ am_libcharon_la_OBJECTS = bus/bus.lo bus/listeners/file_logger.lo \
 	processing/jobs/send_keepalive_job.lo \
 	processing/jobs/start_action_job.lo \
 	processing/jobs/roam_job.lo processing/jobs/update_sa_job.lo \
-	processing/jobs/inactivity_job.lo sa/eap/eap_method.lo \
+	processing/jobs/inactivity_job.lo \
+	processing/jobs/initiate_tasks_job.lo sa/eap/eap_method.lo \
 	sa/eap/eap_manager.lo sa/xauth/xauth_method.lo \
 	sa/xauth/xauth_manager.lo sa/authenticator.lo sa/child_sa.lo \
 	sa/ike_sa.lo sa/ike_sa_id.lo sa/keymat.lo sa/ike_sa_manager.lo \
-	sa/task_manager.lo sa/shunt_manager.lo sa/trap_manager.lo \
-	sa/task.lo $(am__objects_1) $(am__objects_2) $(am__objects_3) \
-	$(am__objects_4)
+	sa/child_sa_manager.lo sa/task_manager.lo sa/shunt_manager.lo \
+	sa/trap_manager.lo sa/task.lo $(am__objects_1) \
+	$(am__objects_2) $(am__objects_3) $(am__objects_4)
 libcharon_la_OBJECTS = $(am_libcharon_la_OBJECTS)
 AM_V_lt = $(am__v_lt_ at AM_V@)
 am__v_lt_ = $(am__v_lt_ at AM_DEFAULT_V@)
@@ -676,11 +700,11 @@ am__define_uniq_tagged_files = \
 ETAGS = etags
 CTAGS = ctags
 DIST_SUBDIRS = . plugins/load_tester plugins/socket_default \
-	plugins/socket_dynamic plugins/socket_win plugins/farp \
-	plugins/stroke plugins/vici plugins/smp plugins/sql \
-	plugins/dnscert plugins/ipseckey plugins/updown \
-	plugins/ext_auth plugins/eap_identity plugins/eap_sim \
-	plugins/eap_sim_file plugins/eap_sim_pcsc \
+	plugins/socket_dynamic plugins/socket_win plugins/connmark \
+	plugins/forecast plugins/farp plugins/stroke plugins/vici \
+	plugins/smp plugins/sql plugins/dnscert plugins/ipseckey \
+	plugins/updown 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_aka_3gpp2 plugins/eap_md5 plugins/eap_gtc \
@@ -694,8 +718,9 @@ DIST_SUBDIRS = . plugins/load_tester plugins/socket_default \
 	plugins/error_notify plugins/certexpire plugins/systime_fix \
 	plugins/led plugins/duplicheck plugins/coupling \
 	plugins/radattr plugins/uci plugins/addrblock plugins/unity \
-	plugins/unit_tester plugins/xauth_generic plugins/xauth_eap \
-	plugins/xauth_pam plugins/xauth_noauth
+	plugins/xauth_generic plugins/xauth_eap plugins/xauth_pam \
+	plugins/xauth_noauth plugins/resolve plugins/attr \
+	plugins/attr_sql tests
 DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
 am__relativize = \
   dir0=`pwd`; \
@@ -747,6 +772,7 @@ DLLIB = @DLLIB@
 DLLTOOL = @DLLTOOL@
 DSYMUTIL = @DSYMUTIL@
 DUMPBIN = @DUMPBIN@
+EASY_INSTALL = @EASY_INSTALL@
 ECHO_C = @ECHO_C@
 ECHO_N = @ECHO_N@
 ECHO_T = @ECHO_T@
@@ -807,10 +833,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
 PLUGIN_CFLAGS = @PLUGIN_CFLAGS@
 PTHREADLIB = @PTHREADLIB@
 PYTHON = @PYTHON@
+PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@
 PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
 PYTHON_PLATFORM = @PYTHON_PLATFORM@
 PYTHON_PREFIX = @PYTHON_PREFIX@
 PYTHON_VERSION = @PYTHON_VERSION@
+PY_TEST = @PY_TEST@
 RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
@@ -884,6 +912,8 @@ json_CFLAGS = @json_CFLAGS@
 json_LIBS = @json_LIBS@
 libdir = @libdir@
 libexecdir = @libexecdir@
+libiptc_CFLAGS = @libiptc_CFLAGS@
+libiptc_LIBS = @libiptc_LIBS@
 linux_headers = @linux_headers@
 localedir = @localedir@
 localstatedir = @localstatedir@
@@ -943,16 +973,20 @@ urandom_device = @urandom_device@
 xml_CFLAGS = @xml_CFLAGS@
 xml_LIBS = @xml_LIBS@
 ipseclib_LTLIBRARIES = libcharon.la
-libcharon_la_SOURCES = bus/bus.c bus/bus.h bus/listeners/listener.h \
-	bus/listeners/logger.h bus/listeners/file_logger.c \
-	bus/listeners/file_logger.h config/backend_manager.c \
-	config/backend_manager.h config/backend.h config/child_cfg.c \
-	config/child_cfg.h config/ike_cfg.c config/ike_cfg.h \
-	config/peer_cfg.c config/peer_cfg.h config/proposal.c \
-	config/proposal.h control/controller.c control/controller.h \
-	daemon.c daemon.h encoding/generator.c encoding/generator.h \
-	encoding/message.c encoding/message.h encoding/parser.c \
-	encoding/parser.h encoding/payloads/auth_payload.c \
+libcharon_la_SOURCES = attributes/attributes.c attributes/attributes.h \
+	attributes/attribute_provider.h attributes/attribute_handler.h \
+	attributes/attribute_manager.c attributes/attribute_manager.h \
+	attributes/mem_pool.c attributes/mem_pool.h bus/bus.c \
+	bus/bus.h bus/listeners/listener.h bus/listeners/logger.h \
+	bus/listeners/file_logger.c bus/listeners/file_logger.h \
+	config/backend_manager.c config/backend_manager.h \
+	config/backend.h config/child_cfg.c config/child_cfg.h \
+	config/ike_cfg.c config/ike_cfg.h config/peer_cfg.c \
+	config/peer_cfg.h config/proposal.c config/proposal.h \
+	control/controller.c control/controller.h daemon.c daemon.h \
+	encoding/generator.c encoding/generator.h encoding/message.c \
+	encoding/message.h encoding/parser.c encoding/parser.h \
+	encoding/payloads/auth_payload.c \
 	encoding/payloads/auth_payload.h \
 	encoding/payloads/cert_payload.c \
 	encoding/payloads/cert_payload.h \
@@ -1023,7 +1057,9 @@ libcharon_la_SOURCES = bus/bus.c bus/bus.h bus/listeners/listener.h \
 	processing/jobs/roam_job.h processing/jobs/update_sa_job.c \
 	processing/jobs/update_sa_job.h \
 	processing/jobs/inactivity_job.c \
-	processing/jobs/inactivity_job.h sa/eap/eap_method.c \
+	processing/jobs/inactivity_job.h \
+	processing/jobs/initiate_tasks_job.c \
+	processing/jobs/initiate_tasks_job.h sa/eap/eap_method.c \
 	sa/eap/eap_method.h sa/eap/eap_inner_method.h \
 	sa/eap/eap_manager.c sa/eap/eap_manager.h \
 	sa/xauth/xauth_method.c sa/xauth/xauth_method.h \
@@ -1031,7 +1067,8 @@ libcharon_la_SOURCES = bus/bus.c bus/bus.h bus/listeners/listener.h \
 	sa/authenticator.c sa/authenticator.h sa/child_sa.c \
 	sa/child_sa.h sa/ike_sa.c sa/ike_sa.h sa/ike_sa_id.c \
 	sa/ike_sa_id.h sa/keymat.h sa/keymat.c sa/ike_sa_manager.c \
-	sa/ike_sa_manager.h sa/task_manager.h sa/task_manager.c \
+	sa/ike_sa_manager.h sa/child_sa_manager.c \
+	sa/child_sa_manager.h sa/task_manager.h sa/task_manager.c \
 	sa/shunt_manager.c sa/shunt_manager.h sa/trap_manager.c \
 	sa/trap_manager.h sa/task.c sa/task.h $(am__append_1) \
 	$(am__append_2) $(am__append_3) $(am__append_5)
@@ -1057,12 +1094,12 @@ libcharon_la_LIBADD =  \
 	$(am__append_33) $(am__append_35) $(am__append_37) \
 	$(am__append_39) $(am__append_41) $(am__append_43) \
 	$(am__append_45) $(am__append_47) $(am__append_49) \
-	$(am__append_50) $(am__append_52) $(am__append_54) \
+	$(am__append_51) $(am__append_53) $(am__append_54) \
 	$(am__append_56) $(am__append_58) $(am__append_60) \
 	$(am__append_62) $(am__append_64) $(am__append_66) \
-	$(am__append_68) $(am__append_69) $(am__append_70) \
-	$(am__append_72) $(am__append_74) $(am__append_75) \
-	$(am__append_77) $(am__append_79) $(am__append_81) \
+	$(am__append_68) $(am__append_70) $(am__append_72) \
+	$(am__append_73) $(am__append_74) $(am__append_76) \
+	$(am__append_78) $(am__append_79) $(am__append_81) \
 	$(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) \
@@ -1071,7 +1108,8 @@ libcharon_la_LIBADD =  \
 	$(am__append_113) $(am__append_115) $(am__append_117) \
 	$(am__append_119) $(am__append_121) $(am__append_123) \
 	$(am__append_125) $(am__append_127) $(am__append_129) \
-	$(am__append_131)
+	$(am__append_131) $(am__append_133) $(am__append_135) \
+	$(am__append_137) $(am__append_139)
 EXTRA_DIST = Android.mk
 @MONOLITHIC_FALSE at SUBDIRS = . $(am__append_6) $(am__append_8) \
 @MONOLITHIC_FALSE@	$(am__append_10) $(am__append_12) \
@@ -1084,13 +1122,13 @@ EXTRA_DIST = Android.mk
 @MONOLITHIC_FALSE@	$(am__append_38) $(am__append_40) \
 @MONOLITHIC_FALSE@	$(am__append_42) $(am__append_44) \
 @MONOLITHIC_FALSE@	$(am__append_46) $(am__append_48) \
- at MONOLITHIC_FALSE@	$(am__append_51) $(am__append_53) \
+ at MONOLITHIC_FALSE@	$(am__append_50) $(am__append_52) \
 @MONOLITHIC_FALSE@	$(am__append_55) $(am__append_57) \
 @MONOLITHIC_FALSE@	$(am__append_59) $(am__append_61) \
 @MONOLITHIC_FALSE@	$(am__append_63) $(am__append_65) \
- at MONOLITHIC_FALSE@	$(am__append_67) $(am__append_71) \
- at MONOLITHIC_FALSE@	$(am__append_73) $(am__append_76) \
- at MONOLITHIC_FALSE@	$(am__append_78) $(am__append_80) \
+ at MONOLITHIC_FALSE@	$(am__append_67) $(am__append_69) \
+ at MONOLITHIC_FALSE@	$(am__append_71) $(am__append_75) \
+ at MONOLITHIC_FALSE@	$(am__append_77) $(am__append_80) \
 @MONOLITHIC_FALSE@	$(am__append_82) $(am__append_84) \
 @MONOLITHIC_FALSE@	$(am__append_86) $(am__append_88) \
 @MONOLITHIC_FALSE@	$(am__append_90) $(am__append_92) \
@@ -1103,7 +1141,9 @@ EXTRA_DIST = Android.mk
 @MONOLITHIC_FALSE@	$(am__append_118) $(am__append_120) \
 @MONOLITHIC_FALSE@	$(am__append_122) $(am__append_124) \
 @MONOLITHIC_FALSE@	$(am__append_126) $(am__append_128) \
- at MONOLITHIC_FALSE@	$(am__append_130)
+ at MONOLITHIC_FALSE@	$(am__append_130) $(am__append_132) \
+ at MONOLITHIC_FALSE@	$(am__append_134) $(am__append_136) \
+ at MONOLITHIC_FALSE@	$(am__append_138) tests
 
 # build optional plugins
 ########################
@@ -1118,13 +1158,13 @@ EXTRA_DIST = Android.mk
 @MONOLITHIC_TRUE@	$(am__append_38) $(am__append_40) \
 @MONOLITHIC_TRUE@	$(am__append_42) $(am__append_44) \
 @MONOLITHIC_TRUE@	$(am__append_46) $(am__append_48) \
- at MONOLITHIC_TRUE@	$(am__append_51) $(am__append_53) \
+ at MONOLITHIC_TRUE@	$(am__append_50) $(am__append_52) \
 @MONOLITHIC_TRUE@	$(am__append_55) $(am__append_57) \
 @MONOLITHIC_TRUE@	$(am__append_59) $(am__append_61) \
 @MONOLITHIC_TRUE@	$(am__append_63) $(am__append_65) \
- at MONOLITHIC_TRUE@	$(am__append_67) $(am__append_71) \
- at MONOLITHIC_TRUE@	$(am__append_73) $(am__append_76) \
- at MONOLITHIC_TRUE@	$(am__append_78) $(am__append_80) \
+ at MONOLITHIC_TRUE@	$(am__append_67) $(am__append_69) \
+ at MONOLITHIC_TRUE@	$(am__append_71) $(am__append_75) \
+ at MONOLITHIC_TRUE@	$(am__append_77) $(am__append_80) \
 @MONOLITHIC_TRUE@	$(am__append_82) $(am__append_84) \
 @MONOLITHIC_TRUE@	$(am__append_86) $(am__append_88) \
 @MONOLITHIC_TRUE@	$(am__append_90) $(am__append_92) \
@@ -1137,7 +1177,9 @@ EXTRA_DIST = Android.mk
 @MONOLITHIC_TRUE@	$(am__append_118) $(am__append_120) \
 @MONOLITHIC_TRUE@	$(am__append_122) $(am__append_124) \
 @MONOLITHIC_TRUE@	$(am__append_126) $(am__append_128) \
- at MONOLITHIC_TRUE@	$(am__append_130)
+ at MONOLITHIC_TRUE@	$(am__append_130) $(am__append_132) \
+ at MONOLITHIC_TRUE@	$(am__append_134) $(am__append_136) \
+ at MONOLITHIC_TRUE@	$(am__append_138) . tests
 all: all-recursive
 
 .SUFFIXES:
@@ -1207,6 +1249,18 @@ clean-ipseclibLTLIBRARIES:
 	  echo rm -f $${locs}; \
 	  rm -f $${locs}; \
 	}
+attributes/$(am__dirstamp):
+	@$(MKDIR_P) attributes
+	@: > attributes/$(am__dirstamp)
+attributes/$(DEPDIR)/$(am__dirstamp):
+	@$(MKDIR_P) attributes/$(DEPDIR)
+	@: > attributes/$(DEPDIR)/$(am__dirstamp)
+attributes/attributes.lo: attributes/$(am__dirstamp) \
+	attributes/$(DEPDIR)/$(am__dirstamp)
+attributes/attribute_manager.lo: attributes/$(am__dirstamp) \
+	attributes/$(DEPDIR)/$(am__dirstamp)
+attributes/mem_pool.lo: attributes/$(am__dirstamp) \
+	attributes/$(DEPDIR)/$(am__dirstamp)
 bus/$(am__dirstamp):
 	@$(MKDIR_P) bus
 	@: > bus/$(am__dirstamp)
@@ -1389,6 +1443,9 @@ processing/jobs/update_sa_job.lo: processing/jobs/$(am__dirstamp) \
 	processing/jobs/$(DEPDIR)/$(am__dirstamp)
 processing/jobs/inactivity_job.lo: processing/jobs/$(am__dirstamp) \
 	processing/jobs/$(DEPDIR)/$(am__dirstamp)
+processing/jobs/initiate_tasks_job.lo:  \
+	processing/jobs/$(am__dirstamp) \
+	processing/jobs/$(DEPDIR)/$(am__dirstamp)
 sa/eap/$(am__dirstamp):
 	@$(MKDIR_P) sa/eap
 	@: > sa/eap/$(am__dirstamp)
@@ -1421,6 +1478,8 @@ sa/ike_sa.lo: sa/$(am__dirstamp) sa/$(DEPDIR)/$(am__dirstamp)
 sa/ike_sa_id.lo: sa/$(am__dirstamp) sa/$(DEPDIR)/$(am__dirstamp)
 sa/keymat.lo: sa/$(am__dirstamp) sa/$(DEPDIR)/$(am__dirstamp)
 sa/ike_sa_manager.lo: sa/$(am__dirstamp) sa/$(DEPDIR)/$(am__dirstamp)
+sa/child_sa_manager.lo: sa/$(am__dirstamp) \
+	sa/$(DEPDIR)/$(am__dirstamp)
 sa/task_manager.lo: sa/$(am__dirstamp) sa/$(DEPDIR)/$(am__dirstamp)
 sa/shunt_manager.lo: sa/$(am__dirstamp) sa/$(DEPDIR)/$(am__dirstamp)
 sa/trap_manager.lo: sa/$(am__dirstamp) sa/$(DEPDIR)/$(am__dirstamp)
@@ -1484,6 +1543,8 @@ sa/ikev2/tasks/ike_rekey.lo: sa/ikev2/tasks/$(am__dirstamp) \
 	sa/ikev2/tasks/$(DEPDIR)/$(am__dirstamp)
 sa/ikev2/tasks/ike_reauth.lo: sa/ikev2/tasks/$(am__dirstamp) \
 	sa/ikev2/tasks/$(DEPDIR)/$(am__dirstamp)
+sa/ikev2/tasks/ike_reauth_complete.lo: sa/ikev2/tasks/$(am__dirstamp) \
+	sa/ikev2/tasks/$(DEPDIR)/$(am__dirstamp)
 sa/ikev2/tasks/ike_auth_lifetime.lo: sa/ikev2/tasks/$(am__dirstamp) \
 	sa/ikev2/tasks/$(DEPDIR)/$(am__dirstamp)
 sa/ikev2/tasks/ike_vendor.lo: sa/ikev2/tasks/$(am__dirstamp) \
@@ -1574,6 +1635,8 @@ libcharon.la: $(libcharon_la_OBJECTS) $(libcharon_la_DEPENDENCIES) $(EXTRA_libch
 
 mostlyclean-compile:
 	-rm -f *.$(OBJEXT)
+	-rm -f attributes/*.$(OBJEXT)
+	-rm -f attributes/*.lo
 	-rm -f bus/*.$(OBJEXT)
 	-rm -f bus/*.lo
 	-rm -f bus/listeners/*.$(OBJEXT)
@@ -1615,6 +1678,9 @@ distclean-compile:
 	-rm -f *.tab.c
 
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/daemon.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at attributes/$(DEPDIR)/attribute_manager.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at attributes/$(DEPDIR)/attributes.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at attributes/$(DEPDIR)/mem_pool.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at bus/$(DEPDIR)/bus.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at bus/listeners/$(DEPDIR)/file_logger.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at bus/listeners/$(DEPDIR)/sys_logger.Plo at am__quote@
@@ -1665,6 +1731,7 @@ distclean-compile:
 @AMDEP_TRUE@@am__include@ @am__quote at processing/jobs/$(DEPDIR)/dpd_timeout_job.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at processing/jobs/$(DEPDIR)/inactivity_job.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at processing/jobs/$(DEPDIR)/initiate_mediation_job.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at processing/jobs/$(DEPDIR)/initiate_tasks_job.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at processing/jobs/$(DEPDIR)/mediation_job.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at processing/jobs/$(DEPDIR)/migrate_job.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at processing/jobs/$(DEPDIR)/process_message_job.Plo at am__quote@
@@ -1679,6 +1746,7 @@ distclean-compile:
 @AMDEP_TRUE@@am__include@ @am__quote at processing/jobs/$(DEPDIR)/update_sa_job.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at sa/$(DEPDIR)/authenticator.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at sa/$(DEPDIR)/child_sa.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at sa/$(DEPDIR)/child_sa_manager.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at sa/$(DEPDIR)/ike_sa.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at sa/$(DEPDIR)/ike_sa_id.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at sa/$(DEPDIR)/ike_sa_manager.Plo at am__quote@
@@ -1730,6 +1798,7 @@ distclean-compile:
 @AMDEP_TRUE@@am__include@ @am__quote at sa/ikev2/tasks/$(DEPDIR)/ike_mobike.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at sa/ikev2/tasks/$(DEPDIR)/ike_natd.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at sa/ikev2/tasks/$(DEPDIR)/ike_reauth.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at sa/ikev2/tasks/$(DEPDIR)/ike_reauth_complete.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at sa/ikev2/tasks/$(DEPDIR)/ike_rekey.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at sa/ikev2/tasks/$(DEPDIR)/ike_vendor.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at sa/xauth/$(DEPDIR)/xauth_manager.Plo at am__quote@
@@ -1764,6 +1833,7 @@ mostlyclean-libtool:
 
 clean-libtool:
 	-rm -rf .libs _libs
+	-rm -rf attributes/.libs attributes/_libs
 	-rm -rf bus/.libs bus/_libs
 	-rm -rf bus/listeners/.libs bus/listeners/_libs
 	-rm -rf config/.libs config/_libs
@@ -1971,6 +2041,8 @@ 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 attributes/$(DEPDIR)/$(am__dirstamp)
+	-rm -f attributes/$(am__dirstamp)
 	-rm -f bus/$(DEPDIR)/$(am__dirstamp)
 	-rm -f bus/$(am__dirstamp)
 	-rm -f bus/listeners/$(DEPDIR)/$(am__dirstamp)
@@ -2017,7 +2089,7 @@ clean-am: clean-generic clean-ipseclibLTLIBRARIES clean-libtool \
 	mostlyclean-am
 
 distclean: distclean-recursive
-	-rm -rf ./$(DEPDIR) bus/$(DEPDIR) bus/listeners/$(DEPDIR) config/$(DEPDIR) control/$(DEPDIR) encoding/$(DEPDIR) encoding/payloads/$(DEPDIR) kernel/$(DEPDIR) network/$(DEPDIR) processing/jobs/$(DEPDIR) sa/$(DEPDIR) sa/eap/$(DEPDIR) sa/ikev1/$(DEPDIR) sa/ikev1/authenticators/$(DEPDIR) sa/ikev1/tasks/$(DEPDIR) sa/ikev2/$(DEPDIR) sa/ikev2/authenticators/$(DEPDIR) sa/ikev2/tasks/$(DEPDIR) sa/xauth/$(DEPDIR)
+	-rm -rf ./$(DEPDIR) attributes/$(DEPDIR) bus/$(DEPDIR) bus/listeners/$(DEPDIR) config/$(DEPDIR) control/$(DEPDIR) encoding/$(DEPDIR) encoding/payloads/$(DEPDIR) kernel/$(DEPDIR) network/$(DEPDIR) processing/jobs/$(DEPDIR) sa/$(DEPDIR) sa/eap/$(DEPDIR) sa/ikev1/$(DEPDIR) sa/ikev1/authenticators/$(DEPDIR) sa/ikev1/tasks/$(DEPDIR) sa/ikev2/$(DEPDIR) sa/ikev2/authenticators/$(DEPDIR) sa/ikev2/tasks/$(DEPDIR) sa/xauth/$(DEPDIR)
 	-rm -f Makefile
 distclean-am: clean-am distclean-compile distclean-generic \
 	distclean-tags
@@ -2063,7 +2135,7 @@ install-ps-am:
 installcheck-am:
 
 maintainer-clean: maintainer-clean-recursive
-	-rm -rf ./$(DEPDIR) bus/$(DEPDIR) bus/listeners/$(DEPDIR) config/$(DEPDIR) control/$(DEPDIR) encoding/$(DEPDIR) encoding/payloads/$(DEPDIR) kernel/$(DEPDIR) network/$(DEPDIR) processing/jobs/$(DEPDIR) sa/$(DEPDIR) sa/eap/$(DEPDIR) sa/ikev1/$(DEPDIR) sa/ikev1/authenticators/$(DEPDIR) sa/ikev1/tasks/$(DEPDIR) sa/ikev2/$(DEPDIR) sa/ikev2/authenticators/$(DEPDIR) sa/ikev2/tasks/$(DEPDIR) sa/xauth/$(DEPDIR)
+	-rm -rf ./$(DEPDIR) attributes/$(DEPDIR) bus/$(DEPDIR) bus/listeners/$(DEPDIR) config/$(DEPDIR) control/$(DEPDIR) encoding/$(DEPDIR) encoding/payloads/$(DEPDIR) kernel/$(DEPDIR) network/$(DEPDIR) processing/jobs/$(DEPDIR) sa/$(DEPDIR) sa/eap/$(DEPDIR) sa/ikev1/$(DEPDIR) sa/ikev1/authenticators/$(DEPDIR) sa/ikev1/tasks/$(DEPDIR) sa/ikev2/$(DEPDIR) sa/ikev2/authenticators/$(DEPDIR) sa/ikev2/tasks/$(DEPDIR) sa/xauth/$(DEPDIR)
 	-rm -f Makefile
 maintainer-clean-am: distclean-am maintainer-clean-generic
 
diff --git a/src/libcharon/attributes/attribute_handler.h b/src/libcharon/attributes/attribute_handler.h
new file mode 100644
index 0000000..3c14323
--- /dev/null
+++ b/src/libcharon/attributes/attribute_handler.h
@@ -0,0 +1,76 @@
+/*
+ * Copyright (C) 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.
+ */
+
+/**
+ * @defgroup attribute_handler attribute_handler
+ * @{ @ingroup attributes
+ */
+
+#ifndef ATTRIBUTE_HANDLER_H_
+#define ATTRIBUTE_HANDLER_H_
+
+typedef struct attribute_handler_t attribute_handler_t;
+
+#include <sa/ike_sa.h>
+#include <utils/chunk.h>
+#include <collections/linked_list.h>
+
+#include "attributes.h"
+
+/**
+ * Interface to handle configuration payload attributes.
+ */
+struct attribute_handler_t {
+
+	/**
+	 * Handle a configuration attribute.
+	 *
+	 * After receiving a configuration attriubte, it is passed to each
+	 * attribute handler until it is handled.
+	 *
+	 * @param ike_sa	IKE_SA under which attribute is received
+	 * @param type		type of configuration attribute to handle
+	 * @param data		associated attribute data
+	 * @return			TRUE if attribute handled
+	 */
+	bool (*handle)(attribute_handler_t *this, ike_sa_t *ike_sa,
+				   configuration_attribute_type_t type, chunk_t data);
+
+	/**
+	 * Release an attribute handled during handle().
+	 *
+	 * A handler that handle()d an attribute gets a call to release() when the
+	 * connection gets closed. Depending on the implementation, this is required
+	 * to remove the attribute.
+	 *
+	 * @param ike_sa	IKE_SA which releases attribute
+	 * @param type		type of configuration attribute to release
+	 * @param data		associated attribute data
+	 */
+	void (*release)(attribute_handler_t *this, ike_sa_t *ike_sa,
+					configuration_attribute_type_t type, chunk_t data);
+
+	/**
+	 * Enumerate attributes to request from a server.
+	 *
+	 * @param ike_sa		IKE_SA to request attributes for
+	 * @param vips			list of virtual IPs (host_t*) we are requesting
+	 * @return				enumerator (configuration_attribute_type_t, chunk_t)
+	 */
+	enumerator_t* (*create_attribute_enumerator)(attribute_handler_t *this,
+										ike_sa_t *ike_sa, linked_list_t *vips);
+};
+
+#endif /** ATTRIBUTE_HANDLER_H_ @}*/
diff --git a/src/libcharon/attributes/attribute_manager.c b/src/libcharon/attributes/attribute_manager.c
new file mode 100644
index 0000000..2ab7ed1
--- /dev/null
+++ b/src/libcharon/attributes/attribute_manager.c
@@ -0,0 +1,347 @@
+/*
+ * Copyright (C) 2008 Martin Willi
+ * Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * for more details.
+ */
+
+#include "attribute_manager.h"
+
+#include <utils/debug.h>
+#include <collections/linked_list.h>
+#include <threading/rwlock.h>
+
+typedef struct private_attribute_manager_t private_attribute_manager_t;
+
+/**
+ * private data of attribute_manager
+ */
+struct private_attribute_manager_t {
+
+	/**
+	 * public functions
+	 */
+	attribute_manager_t public;
+
+	/**
+	 * list of registered providers
+	 */
+	linked_list_t *providers;
+
+	/**
+	 * list of registered handlers
+	 */
+	linked_list_t *handlers;
+
+	/**
+	 * rwlock provider list
+	 */
+	rwlock_t *lock;
+};
+
+/**
+ * Data to pass to enumerator filters
+ */
+typedef struct {
+	/** attribute group pools */
+	linked_list_t *pools;
+	/** associated IKE_SA */
+	ike_sa_t *ike_sa;
+	/** requesting/assigned virtual IPs */
+	linked_list_t *vips;
+} enum_data_t;
+
+METHOD(attribute_manager_t, acquire_address, host_t*,
+	private_attribute_manager_t *this, linked_list_t *pools,
+	ike_sa_t *ike_sa, host_t *requested)
+{
+	enumerator_t *enumerator;
+	attribute_provider_t *current;
+	host_t *host = NULL;
+
+	this->lock->read_lock(this->lock);
+	enumerator = this->providers->create_enumerator(this->providers);
+	while (enumerator->enumerate(enumerator, &current))
+	{
+		host = current->acquire_address(current, pools, ike_sa, requested);
+		if (host)
+		{
+			break;
+		}
+	}
+	enumerator->destroy(enumerator);
+	this->lock->unlock(this->lock);
+
+	return host;
+}
+
+METHOD(attribute_manager_t, release_address, bool,
+	private_attribute_manager_t *this, linked_list_t *pools, host_t *address,
+	ike_sa_t *ike_sa)
+{
+	enumerator_t *enumerator;
+	attribute_provider_t *current;
+	bool found = FALSE;
+
+	this->lock->read_lock(this->lock);
+	enumerator = this->providers->create_enumerator(this->providers);
+	while (enumerator->enumerate(enumerator, &current))
+	{
+		if (current->release_address(current, pools, address, ike_sa))
+		{
+			found = TRUE;
+			break;
+		}
+	}
+	enumerator->destroy(enumerator);
+	this->lock->unlock(this->lock);
+
+	return found;
+}
+
+/**
+ * inner enumerator constructor for responder attributes
+ */
+static enumerator_t *responder_enum_create(attribute_provider_t *provider,
+										   enum_data_t *data)
+{
+	return provider->create_attribute_enumerator(provider, data->pools,
+												 data->ike_sa, data->vips);
+}
+
+METHOD(attribute_manager_t, create_responder_enumerator, enumerator_t*,
+	private_attribute_manager_t *this, linked_list_t *pools,
+	ike_sa_t *ike_sa, linked_list_t *vips)
+{
+	enum_data_t *data;
+
+	INIT(data,
+		.pools = pools,
+		.ike_sa = ike_sa,
+		.vips = vips,
+	);
+	this->lock->read_lock(this->lock);
+	return enumerator_create_cleaner(
+				enumerator_create_nested(
+					this->providers->create_enumerator(this->providers),
+					(void*)responder_enum_create, data, free),
+				(void*)this->lock->unlock, this->lock);
+}
+
+METHOD(attribute_manager_t, add_provider, void,
+	private_attribute_manager_t *this, attribute_provider_t *provider)
+{
+	this->lock->write_lock(this->lock);
+	this->providers->insert_last(this->providers, provider);
+	this->lock->unlock(this->lock);
+}
+
+METHOD(attribute_manager_t, remove_provider, void,
+	private_attribute_manager_t *this, attribute_provider_t *provider)
+{
+	this->lock->write_lock(this->lock);
+	this->providers->remove(this->providers, provider, NULL);
+	this->lock->unlock(this->lock);
+}
+
+METHOD(attribute_manager_t, handle, attribute_handler_t*,
+	private_attribute_manager_t *this, ike_sa_t *ike_sa,
+	attribute_handler_t *handler, configuration_attribute_type_t type,
+	chunk_t data)
+{
+	enumerator_t *enumerator;
+	attribute_handler_t *current, *handled = NULL;
+
+	this->lock->read_lock(this->lock);
+
+	/* try to find the passed handler */
+	enumerator = this->handlers->create_enumerator(this->handlers);
+	while (enumerator->enumerate(enumerator, &current))
+	{
+		if (current == handler && current->handle(current, ike_sa, type, data))
+		{
+			handled = current;
+			break;
+		}
+	}
+	enumerator->destroy(enumerator);
+	if (!handled)
+	{	/* handler requesting this attribute not found, try any other */
+		enumerator = this->handlers->create_enumerator(this->handlers);
+		while (enumerator->enumerate(enumerator, &current))
+		{
+			if (current->handle(current, ike_sa, type, data))
+			{
+				handled = current;
+				break;
+			}
+		}
+		enumerator->destroy(enumerator);
+	}
+	this->lock->unlock(this->lock);
+
+	if (!handled)
+	{
+		DBG1(DBG_CFG, "handling %N attribute failed",
+			 configuration_attribute_type_names, type);
+	}
+	return handled;
+}
+
+METHOD(attribute_manager_t, release, void,
+	private_attribute_manager_t *this, attribute_handler_t *handler,
+	ike_sa_t *ike_sa, configuration_attribute_type_t type, chunk_t data)
+{
+	enumerator_t *enumerator;
+	attribute_handler_t *current;
+
+	this->lock->read_lock(this->lock);
+	enumerator = this->handlers->create_enumerator(this->handlers);
+	while (enumerator->enumerate(enumerator, &current))
+	{
+		if (current == handler)
+		{
+			current->release(current, ike_sa, type, data);
+			break;
+		}
+	}
+	enumerator->destroy(enumerator);
+	this->lock->unlock(this->lock);
+}
+
+/**
+ * Enumerator implementation to enumerate nested initiator attributes
+ */
+typedef struct {
+	/** implements enumerator_t */
+	enumerator_t public;
+	/** back ref */
+	private_attribute_manager_t *this;
+	/** currently processing handler */
+	attribute_handler_t *handler;
+	/** outer enumerator over handlers */
+	enumerator_t *outer;
+	/** inner enumerator over current handlers attributes */
+	enumerator_t *inner;
+	/** IKE_SA to request attributes for */
+	ike_sa_t *ike_sa;
+	/** virtual IPs we are requesting along with attriubutes */
+	linked_list_t *vips;
+} initiator_enumerator_t;
+
+/**
+ * Enumerator implementation for initiator attributes
+ */
+static bool initiator_enumerate(initiator_enumerator_t *this,
+								attribute_handler_t **handler,
+								configuration_attribute_type_t *type,
+								chunk_t *value)
+{
+	/* enumerate inner attributes using outer handler enumerator */
+	while (!this->inner || !this->inner->enumerate(this->inner, type, value))
+	{
+		if (!this->outer->enumerate(this->outer, &this->handler))
+		{
+			return FALSE;
+		}
+		DESTROY_IF(this->inner);
+		this->inner = this->handler->create_attribute_enumerator(this->handler,
+													this->ike_sa, this->vips);
+	}
+	/* inject the handler as additional attribute */
+	*handler = this->handler;
+	return TRUE;
+}
+
+/**
+ * Cleanup function of initiator attribute enumerator
+ */
+static void initiator_destroy(initiator_enumerator_t *this)
+{
+	this->this->lock->unlock(this->this->lock);
+	this->outer->destroy(this->outer);
+	DESTROY_IF(this->inner);
+	free(this);
+}
+
+METHOD(attribute_manager_t, create_initiator_enumerator, enumerator_t*,
+	private_attribute_manager_t *this, ike_sa_t *ike_sa, linked_list_t *vips)
+{
+	initiator_enumerator_t *enumerator;
+
+	this->lock->read_lock(this->lock);
+
+	INIT(enumerator,
+		.public = {
+			.enumerate = (void*)initiator_enumerate,
+			.destroy = (void*)initiator_destroy,
+		},
+		.this = this,
+		.ike_sa = ike_sa,
+		.vips = vips,
+		.outer = this->handlers->create_enumerator(this->handlers),
+	);
+	return &enumerator->public;
+}
+
+METHOD(attribute_manager_t, add_handler, void,
+	private_attribute_manager_t *this, attribute_handler_t *handler)
+{
+	this->lock->write_lock(this->lock);
+	this->handlers->insert_last(this->handlers, handler);
+	this->lock->unlock(this->lock);
+}
+
+METHOD(attribute_manager_t, remove_handler, void,
+	private_attribute_manager_t *this, attribute_handler_t *handler)
+{
+	this->lock->write_lock(this->lock);
+	this->handlers->remove(this->handlers, handler, NULL);
+	this->lock->unlock(this->lock);
+}
+
+METHOD(attribute_manager_t, destroy, void,
+	private_attribute_manager_t *this)
+{
+	this->providers->destroy(this->providers);
+	this->handlers->destroy(this->handlers);
+	this->lock->destroy(this->lock);
+	free(this);
+}
+
+/*
+ * see header file
+ */
+attribute_manager_t *attribute_manager_create()
+{
+	private_attribute_manager_t *this;
+
+	INIT(this,
+		.public = {
+			.acquire_address = _acquire_address,
+			.release_address = _release_address,
+			.create_responder_enumerator = _create_responder_enumerator,
+			.add_provider = _add_provider,
+			.remove_provider = _remove_provider,
+			.handle = _handle,
+			.release = _release,
+			.create_initiator_enumerator = _create_initiator_enumerator,
+			.add_handler = _add_handler,
+			.remove_handler = _remove_handler,
+			.destroy = _destroy,
+		},
+		.providers = linked_list_create(),
+		.handlers = linked_list_create(),
+		.lock = rwlock_create(RWLOCK_TYPE_DEFAULT),
+	);
+
+	return &this->public;
+}
diff --git a/src/libcharon/attributes/attribute_manager.h b/src/libcharon/attributes/attribute_manager.h
new file mode 100644
index 0000000..6db6649
--- /dev/null
+++ b/src/libcharon/attributes/attribute_manager.h
@@ -0,0 +1,154 @@
+/*
+ * 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.
+ */
+
+/**
+ * @defgroup attribute_manager attribute_manager
+ * @{ @ingroup attributes
+ */
+
+#ifndef ATTRIBUTE_MANAGER_H_
+#define ATTRIBUTE_MANAGER_H_
+
+#include "attribute_provider.h"
+#include "attribute_handler.h"
+
+#include <sa/ike_sa.h>
+
+typedef struct attribute_manager_t attribute_manager_t;
+
+/**
+ * The attribute manager hands out attributes or handles them.
+ *
+ * The attribute manager manages both, attribute providers and attribute
+ * handlers. Attribute providers are responsible to hand out attributes if
+ * a connecting peer requests them. Handlers handle such attributes if they
+ * are received on the requesting peer.
+ */
+struct attribute_manager_t {
+
+	/**
+	 * Acquire a virtual IP address to assign to a peer.
+	 *
+	 * @param pools			list of pool names (char*) to acquire from
+	 * @param ike_sa		associated IKE_SA for which an address is requested
+	 * @param requested		IP in configuration request
+	 * @return				allocated address, NULL to serve none
+	 */
+	host_t* (*acquire_address)(attribute_manager_t *this,
+							   linked_list_t *pool, ike_sa_t *ike_sa,
+							   host_t *requested);
+
+	/**
+	 * Release a previously acquired address.
+	 *
+	 * @param pools			list of pool names (char*) to release to
+	 * @param address		address to release
+	 * @param ike_sa		associated IKE_SA for which an address is released
+	 * @return				TRUE if address released to pool
+	 */
+	bool (*release_address)(attribute_manager_t *this,
+							linked_list_t *pools, host_t *address,
+							ike_sa_t *ike_sa);
+
+	/**
+	 * Create an enumerator over attributes to hand out to a peer.
+	 *
+	 * @param pool			list of pools names (char*) to query attributes from
+	 * @param ike_sa		associated IKE_SA for which attributes are requested
+	 * @param vip			list of virtual IPs (host_t*) to assign to peer
+	 * @return				enumerator (configuration_attribute_type_t, chunk_t)
+	 */
+	enumerator_t* (*create_responder_enumerator)(attribute_manager_t *this,
+									linked_list_t *pool, ike_sa_t *ike_sa,
+									linked_list_t *vips);
+
+	/**
+	 * Register an attribute provider to the manager.
+	 *
+	 * @param provider		attribute provider to register
+	 */
+	void (*add_provider)(attribute_manager_t *this,
+						 attribute_provider_t *provider);
+	/**
+	 * Unregister an attribute provider from the manager.
+	 *
+	 * @param provider		attribute provider to unregister
+	 */
+	void (*remove_provider)(attribute_manager_t *this,
+							attribute_provider_t *provider);
+
+	/**
+	 * Handle a configuration attribute by passing them to the handlers.
+	 *
+	 * @param ike_sa		associated IKE_SA to handle an attribute for
+	 * @param handler		handler we requested the attribute for, if any
+	 * @param type			type of configuration attribute
+	 * @param data			associated attribute data
+	 * @return				handler which handled this attribute, NULL if none
+	 */
+	attribute_handler_t* (*handle)(attribute_manager_t *this,
+						ike_sa_t *ike_sa, attribute_handler_t *handler,
+						configuration_attribute_type_t type, chunk_t data);
+
+	/**
+	 * Release an attribute previously handle()d by a handler.
+	 *
+	 * @param ike_sa		associated IKE_SA to release an attribute for
+	 * @param server		server from which the attribute was received
+	 * @param type			type of attribute to release
+	 * @param data			associated attribute data
+	 */
+	void (*release)(attribute_manager_t *this, attribute_handler_t *handler,
+						ike_sa_t *ike_sa, configuration_attribute_type_t type,
+						chunk_t data);
+
+	/**
+	 * Create an enumerator over attributes to request from server.
+	 *
+	 * @param ike_sa		associated IKE_SA to request attributes for
+	 * @param vip			list of virtual IPs (host_t*) going to request
+	 * @return				enumerator (attribute_handler_t, ca_type_t, chunk_t)
+	 */
+	enumerator_t* (*create_initiator_enumerator)(attribute_manager_t *this,
+									ike_sa_t *ike_sa, linked_list_t *vips);
+
+	/**
+	 * Register an attribute handler to the manager.
+	 *
+	 * @param handler		attribute handler to register
+	 */
+	void (*add_handler)(attribute_manager_t *this,
+						attribute_handler_t *handler);
+
+	/**
+	 * Unregister an attribute handler from the manager.
+	 *
+	 * @param handler		attribute handler to unregister
+	 */
+	void (*remove_handler)(attribute_manager_t *this,
+						   attribute_handler_t *handler);
+
+	/**
+	 * Destroy a attribute_manager instance.
+	 */
+	void (*destroy)(attribute_manager_t *this);
+};
+
+/**
+ * Create a attribute_manager instance.
+ */
+attribute_manager_t *attribute_manager_create();
+
+#endif /** ATTRIBUTE_MANAGER_H_ @}*/
diff --git a/src/libcharon/attributes/attribute_provider.h b/src/libcharon/attributes/attribute_provider.h
new file mode 100644
index 0000000..57453c2
--- /dev/null
+++ b/src/libcharon/attributes/attribute_provider.h
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 2008 Martin Willi
+ * Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * for more details.
+ */
+
+/**
+ * @defgroup attribute_provider attribute_provider
+ * @{ @ingroup attributes
+ */
+
+#ifndef ATTRIBUTE_PROVIDER_H_
+#define ATTRIBUTE_PROVIDER_H_
+
+#include <sa/ike_sa.h>
+#include <networking/host.h>
+#include <collections/linked_list.h>
+
+typedef struct attribute_provider_t attribute_provider_t;
+
+/**
+ * Interface to provide attributes to peers through attribute manager.
+ */
+struct attribute_provider_t {
+
+	/**
+	 * Acquire a virtual IP address to assign to a peer.
+	 *
+	 * @param pools			list of pool names (char*) to acquire from
+	 * @param ike_sa		associated IKE_SA to assign address over
+	 * @param requested		IP in configuration request
+	 * @return				allocated address, NULL to serve none
+	 */
+	host_t* (*acquire_address)(attribute_provider_t *this,
+							   linked_list_t *pools, ike_sa_t *ike_sa,
+							   host_t *requested);
+	/**
+	 * Release a previously acquired address.
+	 *
+	 * @param pools			list of pool names (char*) to release to
+	 * @param address		address to release
+	 * @param ike_sa		IKE_SA to release address for
+	 * @return				TRUE if the address has been released by the provider
+	 */
+	bool (*release_address)(attribute_provider_t *this,
+							linked_list_t *pools, host_t *address,
+							ike_sa_t *ike_sa);
+
+	/**
+	 * Create an enumerator over attributes to hand out to a peer.
+	 *
+	 * @param pool			list of pools names (char*) to query attributes from
+	 * @param ike_sa		IKE_SA to request attributes for
+	 * @param vip			list of virtual IPs (host_t*) to assign to peer
+	 * @return				enumerator (configuration_attribute_type_t, chunk_t)
+	 */
+	enumerator_t* (*create_attribute_enumerator)(attribute_provider_t *this,
+									linked_list_t *pools, ike_sa_t *ike_sa,
+									linked_list_t *vips);
+};
+
+#endif /** ATTRIBUTE_PROVIDER_H_ @}*/
diff --git a/src/libhydra/attributes/attributes.c b/src/libcharon/attributes/attributes.c
similarity index 100%
rename from src/libhydra/attributes/attributes.c
rename to src/libcharon/attributes/attributes.c
diff --git a/src/libhydra/attributes/attributes.h b/src/libcharon/attributes/attributes.h
similarity index 100%
rename from src/libhydra/attributes/attributes.h
rename to src/libcharon/attributes/attributes.h
diff --git a/src/libcharon/attributes/mem_pool.c b/src/libcharon/attributes/mem_pool.c
new file mode 100644
index 0000000..2796682
--- /dev/null
+++ b/src/libcharon/attributes/mem_pool.c
@@ -0,0 +1,735 @@
+/*
+ * Copyright (C) 2010 Tobias Brunner
+ * Copyright (C) 2008-2010 Martin Willi
+ * Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * for more details.
+ */
+
+#include "mem_pool.h"
+
+#include <library.h>
+#include <hydra.h>
+#include <utils/debug.h>
+#include <collections/hashtable.h>
+#include <collections/array.h>
+#include <threading/mutex.h>
+
+#define POOL_LIMIT (sizeof(u_int)*8 - 1)
+
+typedef struct private_mem_pool_t private_mem_pool_t;
+
+/**
+ * private data of mem_pool_t
+ */
+struct private_mem_pool_t {
+	/**
+	 * public interface
+	 */
+	mem_pool_t public;
+
+	/**
+	 * name of the pool
+	 */
+	char *name;
+
+	/**
+	 * base address of the pool
+	 */
+	host_t *base;
+
+	/**
+	 * whether base is the network id of the subnet on which the pool is based
+	 */
+	bool base_is_network_id;
+
+	/**
+	 * size of the pool
+	 */
+	u_int size;
+
+	/**
+	 * next unused address
+	 */
+	u_int unused;
+
+	/**
+	 * lease hashtable [identity => entry]
+	 */
+	hashtable_t *leases;
+
+	/**
+	 * lock to safely access the pool
+	 */
+	mutex_t *mutex;
+};
+
+/**
+ * A unique lease address offset, with a hash of the peer host address
+ */
+typedef struct {
+	/** lease, as offset */
+	u_int offset;
+	/** hash of remote address, to allow duplicates */
+	u_int hash;
+} unique_lease_t;
+
+/**
+ * Lease entry.
+ */
+typedef struct {
+	/* identitiy reference */
+	identification_t *id;
+	/* array of online leases, as unique_lease_t */
+	array_t *online;
+	/* array of offline leases, as u_int offset */
+	array_t *offline;
+} entry_t;
+
+/**
+ * Create a new entry
+ */
+static entry_t* entry_create(identification_t *id)
+{
+	entry_t *entry;
+
+	INIT(entry,
+		.id = id->clone(id),
+		.online = array_create(sizeof(unique_lease_t), 0),
+		.offline = array_create(sizeof(u_int), 0),
+	);
+	return entry;
+}
+
+/**
+ * Destroy an entry
+ */
+static void entry_destroy(entry_t *this)
+{
+	this->id->destroy(this->id);
+	array_destroy(this->online);
+	array_destroy(this->offline);
+	free(this);
+}
+
+/**
+ * hashtable hash function for identities
+ */
+static u_int id_hash(identification_t *id)
+{
+	return chunk_hash(id->get_encoding(id));
+}
+
+/**
+ * hashtable equals function for identities
+ */
+static bool id_equals(identification_t *a, identification_t *b)
+{
+	return a->equals(a, b);
+}
+
+/**
+ * convert a pool offset to an address
+ */
+static host_t* offset2host(private_mem_pool_t *pool, int offset)
+{
+	chunk_t addr;
+	host_t *host;
+	u_int32_t *pos;
+
+	offset--;
+	if (offset > pool->size)
+	{
+		return NULL;
+	}
+
+	addr = chunk_clone(pool->base->get_address(pool->base));
+	if (pool->base->get_family(pool->base) == AF_INET6)
+	{
+		pos = (u_int32_t*)(addr.ptr + 12);
+	}
+	else
+	{
+		pos = (u_int32_t*)addr.ptr;
+	}
+	*pos = htonl(offset + ntohl(*pos));
+	host = host_create_from_chunk(pool->base->get_family(pool->base), addr, 0);
+	free(addr.ptr);
+	return host;
+}
+
+/**
+ * convert a host to a pool offset
+ */
+static int host2offset(private_mem_pool_t *pool, host_t *addr)
+{
+	chunk_t host, base;
+	u_int32_t hosti, basei;
+
+	if (addr->get_family(addr) != pool->base->get_family(pool->base))
+	{
+		return -1;
+	}
+	host = addr->get_address(addr);
+	base = pool->base->get_address(pool->base);
+	if (addr->get_family(addr) == AF_INET6)
+	{
+		/* only look at last /32 block */
+		if (!memeq(host.ptr, base.ptr, 12))
+		{
+			return -1;
+		}
+		host = chunk_skip(host, 12);
+		base = chunk_skip(base, 12);
+	}
+	hosti = ntohl(*(u_int32_t*)(host.ptr));
+	basei = ntohl(*(u_int32_t*)(base.ptr));
+	if (hosti > basei + pool->size)
+	{
+		return -1;
+	}
+	return hosti - basei + 1;
+}
+
+METHOD(mem_pool_t, get_name, const char*,
+	private_mem_pool_t *this)
+{
+	return this->name;
+}
+
+METHOD(mem_pool_t, get_base, host_t*,
+	private_mem_pool_t *this)
+{
+	return this->base;
+}
+
+METHOD(mem_pool_t, get_size, u_int,
+	private_mem_pool_t *this)
+{
+	return this->size;
+}
+
+METHOD(mem_pool_t, get_online, u_int,
+	private_mem_pool_t *this)
+{
+	enumerator_t *enumerator;
+	entry_t *entry;
+	u_int count = 0;
+
+	this->mutex->lock(this->mutex);
+	enumerator = this->leases->create_enumerator(this->leases);
+	while (enumerator->enumerate(enumerator, NULL, &entry))
+	{
+		count += array_count(entry->online);
+	}
+	enumerator->destroy(enumerator);
+	this->mutex->unlock(this->mutex);
+
+	return count;
+}
+
+METHOD(mem_pool_t, get_offline, u_int,
+	private_mem_pool_t *this)
+{
+	enumerator_t *enumerator;
+	entry_t *entry;
+	u_int count = 0;
+
+	this->mutex->lock(this->mutex);
+	enumerator = this->leases->create_enumerator(this->leases);
+	while (enumerator->enumerate(enumerator, NULL, &entry))
+	{
+		count += array_count(entry->offline);
+	}
+	enumerator->destroy(enumerator);
+	this->mutex->unlock(this->mutex);
+
+	return count;
+}
+
+/**
+ * Create a unique hash for a remote address
+ */
+static u_int hash_addr(host_t *addr)
+{
+	if (addr)
+	{
+		return chunk_hash_inc(addr->get_address(addr), addr->get_port(addr));
+	}
+	return 0;
+}
+
+/**
+ * Get an existing lease for id
+ */
+static int get_existing(private_mem_pool_t *this, identification_t *id,
+						host_t *requested, host_t *peer)
+{
+	enumerator_t *enumerator;
+	unique_lease_t *lease, reassign;
+	u_int *current;
+	entry_t *entry;
+	int offset = 0;
+
+	entry = this->leases->get(this->leases, id);
+	if (!entry)
+	{
+		return 0;
+	}
+
+	/* check for a valid offline lease, refresh */
+	enumerator = array_create_enumerator(entry->offline);
+	if (enumerator->enumerate(enumerator, &current))
+	{
+		reassign.offset = offset = *current;
+		reassign.hash = hash_addr(peer);
+		array_insert(entry->online, ARRAY_TAIL, &reassign);
+		array_remove_at(entry->offline, enumerator);
+	}
+	enumerator->destroy(enumerator);
+	if (offset)
+	{
+		DBG1(DBG_CFG, "reassigning offline lease to '%Y'", id);
+		return offset;
+	}
+	if (!peer)
+	{
+		return 0;
+	}
+	/* check for a valid online lease to reassign */
+	enumerator = array_create_enumerator(entry->online);
+	while (enumerator->enumerate(enumerator, &lease))
+	{
+		if (lease->offset == host2offset(this, requested) &&
+			lease->hash == hash_addr(peer))
+		{
+			offset = lease->offset;
+			/* add an additional "online" entry */
+			array_insert(entry->online, ARRAY_TAIL, lease);
+			break;
+		}
+	}
+	enumerator->destroy(enumerator);
+	if (offset)
+	{
+		DBG1(DBG_CFG, "reassigning online lease to '%Y'", id);
+	}
+	return offset;
+}
+
+/**
+ * Get a new lease for id
+ */
+static int get_new(private_mem_pool_t *this, identification_t *id, host_t *peer)
+{
+	entry_t *entry;
+	unique_lease_t lease = {};
+
+	if (this->unused < this->size)
+	{
+		entry = this->leases->get(this->leases, id);
+		if (!entry)
+		{
+			entry = entry_create(id);
+			this->leases->put(this->leases, entry->id, entry);
+		}
+		/* assigning offset, starting by 1 */
+		lease.offset = ++this->unused + (this->base_is_network_id ? 1 : 0);
+		lease.hash = hash_addr(peer);
+		array_insert(entry->online, ARRAY_TAIL, &lease);
+		DBG1(DBG_CFG, "assigning new lease to '%Y'", id);
+	}
+	return lease.offset;
+}
+
+/**
+ * Get a reassigned lease for id in case the pool is full
+ */
+static int get_reassigned(private_mem_pool_t *this, identification_t *id,
+						  host_t *peer)
+{
+	enumerator_t *enumerator;
+	entry_t *entry;
+	u_int current;
+	unique_lease_t lease = {};
+
+	enumerator = this->leases->create_enumerator(this->leases);
+	while (enumerator->enumerate(enumerator, NULL, &entry))
+	{
+		if (array_remove(entry->offline, ARRAY_HEAD, &current))
+		{
+			lease.offset = current;
+			DBG1(DBG_CFG, "reassigning existing offline lease by '%Y' "
+				 "to '%Y'", entry->id, id);
+		}
+		if (!array_count(entry->online) && !array_count(entry->offline))
+		{
+			this->leases->remove_at(this->leases, enumerator);
+			entry_destroy(entry);
+		}
+		if (lease.offset)
+		{
+			break;
+		}
+	}
+	enumerator->destroy(enumerator);
+
+	if (lease.offset)
+	{
+		entry = this->leases->get(this->leases, id);
+		if (!entry)
+		{
+			entry = entry_create(id);
+			this->leases->put(this->leases, entry->id, entry);
+		}
+		lease.hash = hash_addr(peer);
+		array_insert(entry->online, ARRAY_TAIL, &lease);
+	}
+	return lease.offset;
+}
+
+METHOD(mem_pool_t, acquire_address, host_t*,
+	private_mem_pool_t *this, identification_t *id, host_t *requested,
+	mem_pool_op_t operation, host_t *peer)
+{
+	int offset = 0;
+
+	/* if the pool is empty (e.g. in the %config case) we simply return the
+	 * requested address */
+	if (this->size == 0)
+	{
+		return requested->clone(requested);
+	}
+
+	if (requested->get_family(requested) !=
+		this->base->get_family(this->base))
+	{
+		return NULL;
+	}
+
+	this->mutex->lock(this->mutex);
+	switch (operation)
+	{
+		case MEM_POOL_EXISTING:
+			offset = get_existing(this, id, requested, peer);
+			break;
+		case MEM_POOL_NEW:
+			offset = get_new(this, id, peer);
+			break;
+		case MEM_POOL_REASSIGN:
+			offset = get_reassigned(this, id, peer);
+			if (!offset)
+			{
+				DBG1(DBG_CFG, "pool '%s' is full, unable to assign address",
+					 this->name);
+			}
+			break;
+		default:
+			break;
+	}
+	this->mutex->unlock(this->mutex);
+
+	if (offset)
+	{
+		return offset2host(this, offset);
+	}
+	return NULL;
+}
+
+METHOD(mem_pool_t, release_address, bool,
+	private_mem_pool_t *this, host_t *address, identification_t *id)
+{
+	enumerator_t *enumerator;
+	bool found = FALSE, more = FALSE;
+	entry_t *entry;
+	u_int offset;
+	unique_lease_t *current;
+
+	if (this->size != 0)
+	{
+		this->mutex->lock(this->mutex);
+		entry = this->leases->get(this->leases, id);
+		if (entry)
+		{
+			offset = host2offset(this, address);
+
+			enumerator = array_create_enumerator(entry->online);
+			while (enumerator->enumerate(enumerator, &current))
+			{
+				if (current->offset == offset)
+				{
+					if (!found)
+					{	/* remove the first entry only */
+						array_remove_at(entry->online, enumerator);
+						found = TRUE;
+					}
+					else
+					{	/* but check for more entries */
+						more = TRUE;
+						break;
+					}
+				}
+			}
+			enumerator->destroy(enumerator);
+
+			if (found && !more)
+			{
+				/* no tunnels are online anymore for this lease, make offline */
+				array_insert(entry->offline, ARRAY_TAIL, &offset);
+				DBG1(DBG_CFG, "lease %H by '%Y' went offline", address, id);
+			}
+		}
+		this->mutex->unlock(this->mutex);
+	}
+	return found;
+}
+
+/**
+ * lease enumerator
+ */
+typedef struct {
+	/** implemented enumerator interface */
+	enumerator_t public;
+	/** hash-table enumerator */
+	enumerator_t *entries;
+	/** online enumerator */
+	enumerator_t *online;
+	/** offline enumerator */
+	enumerator_t *offline;
+	/** enumerated pool */
+	private_mem_pool_t *pool;
+	/** currently enumerated entry */
+	entry_t *entry;
+	/** currently enumerated lease address */
+	host_t *addr;
+} lease_enumerator_t;
+
+METHOD(enumerator_t, lease_enumerate, bool,
+	lease_enumerator_t *this, identification_t **id, host_t **addr, bool *online)
+{
+	u_int *offset;
+	unique_lease_t *lease;
+
+	DESTROY_IF(this->addr);
+	this->addr = NULL;
+
+	while (TRUE)
+	{
+		if (this->entry)
+		{
+			if (this->online->enumerate(this->online, &lease))
+			{
+				*id = this->entry->id;
+				*addr = this->addr = offset2host(this->pool, lease->offset);
+				*online = TRUE;
+				return TRUE;
+			}
+			if (this->offline->enumerate(this->offline, &offset))
+			{
+				*id = this->entry->id;
+				*addr = this->addr = offset2host(this->pool, *offset);
+				*online = FALSE;
+				return TRUE;
+			}
+			this->online->destroy(this->online);
+			this->offline->destroy(this->offline);
+			this->online = this->offline = NULL;
+		}
+		if (!this->entries->enumerate(this->entries, NULL, &this->entry))
+		{
+			return FALSE;
+		}
+		this->online = array_create_enumerator(this->entry->online);
+		this->offline = array_create_enumerator(this->entry->offline);
+	}
+}
+
+METHOD(enumerator_t, lease_enumerator_destroy, void,
+	lease_enumerator_t *this)
+{
+	DESTROY_IF(this->addr);
+	DESTROY_IF(this->online);
+	DESTROY_IF(this->offline);
+	this->entries->destroy(this->entries);
+	this->pool->mutex->unlock(this->pool->mutex);
+	free(this);
+}
+
+METHOD(mem_pool_t, create_lease_enumerator, enumerator_t*,
+	   private_mem_pool_t *this)
+{
+	lease_enumerator_t *enumerator;
+
+	this->mutex->lock(this->mutex);
+	INIT(enumerator,
+		.public = {
+			.enumerate = (void*)_lease_enumerate,
+			.destroy = _lease_enumerator_destroy,
+		},
+		.pool = this,
+		.entries = this->leases->create_enumerator(this->leases),
+	);
+	return &enumerator->public;
+}
+
+METHOD(mem_pool_t, destroy, void,
+	private_mem_pool_t *this)
+{
+	enumerator_t *enumerator;
+	entry_t *entry;
+
+	enumerator = this->leases->create_enumerator(this->leases);
+	while (enumerator->enumerate(enumerator, NULL, &entry))
+	{
+		entry_destroy(entry);
+	}
+	enumerator->destroy(enumerator);
+
+	this->leases->destroy(this->leases);
+	this->mutex->destroy(this->mutex);
+	DESTROY_IF(this->base);
+	free(this->name);
+	free(this);
+}
+
+/**
+ * Generic constructor
+ */
+static private_mem_pool_t *create_generic(char *name)
+{
+	private_mem_pool_t *this;
+
+	INIT(this,
+		.public = {
+			.get_name = _get_name,
+			.get_base = _get_base,
+			.get_size = _get_size,
+			.get_online = _get_online,
+			.get_offline = _get_offline,
+			.acquire_address = _acquire_address,
+			.release_address = _release_address,
+			.create_lease_enumerator = _create_lease_enumerator,
+			.destroy = _destroy,
+		},
+		.name = strdup(name),
+		.leases = hashtable_create((hashtable_hash_t)id_hash,
+								   (hashtable_equals_t)id_equals, 16),
+		.mutex = mutex_create(MUTEX_TYPE_DEFAULT),
+	);
+
+	return this;
+}
+
+/**
+ * Check if the given host is the network ID of a subnet, that is, if hostbits
+ * are zero.  Since we limit pools to 2^31 addresses we only have to check the
+ * last 4 bytes.
+ */
+static u_int network_id_diff(host_t *host, int hostbits)
+{
+	u_int32_t last;
+	chunk_t addr;
+
+	if (!hostbits)
+	{
+		return 0;
+	}
+	addr = host->get_address(host);
+	last = untoh32(addr.ptr + addr.len - sizeof(last));
+	hostbits = sizeof(last) * 8 - hostbits;
+	return (last << hostbits) >> hostbits;
+}
+
+/**
+ * Described in header
+ */
+mem_pool_t *mem_pool_create(char *name, host_t *base, int bits)
+{
+	private_mem_pool_t *this;
+	u_int diff;
+	int addr_bits;
+
+	this = create_generic(name);
+	if (base)
+	{
+		addr_bits = base->get_family(base) == AF_INET ? 32 : 128;
+		bits = max(0, min(bits, addr_bits));
+		/* net bits -> host bits */
+		bits = addr_bits - bits;
+		if (bits > POOL_LIMIT)
+		{
+			bits = POOL_LIMIT;
+			DBG1(DBG_CFG, "virtual IP pool too large, limiting to %H/%d",
+				 base, addr_bits - bits);
+		}
+		this->size = 1 << bits;
+		this->base = base->clone(base);
+
+		if (this->size > 2)
+		{
+			/* if base is the network id we later skip the first address,
+			 * otherwise adjust the size to represent the actual number
+			 * of assignable addresses */
+			diff = network_id_diff(base, bits);
+			if (!diff)
+			{
+				this->base_is_network_id = TRUE;
+				this->size--;
+			}
+			else
+			{
+				this->size -= diff;
+			}
+			/* skip the last address (broadcast) of the subnet */
+			this->size--;
+		}
+		else if (network_id_diff(base, bits))
+		{	/* only serve the second address of the subnet */
+			this->size--;
+		}
+	}
+	return &this->public;
+}
+
+/**
+ * Described in header
+ */
+mem_pool_t *mem_pool_create_range(char *name, host_t *from, host_t *to)
+{
+	private_mem_pool_t *this;
+	chunk_t fromaddr, toaddr;
+	u_int32_t diff;
+
+	fromaddr = from->get_address(from);
+	toaddr = to->get_address(to);
+
+	if (from->get_family(from) != to->get_family(to) ||
+		fromaddr.len != toaddr.len || fromaddr.len < sizeof(diff) ||
+		memcmp(fromaddr.ptr, toaddr.ptr, toaddr.len) > 0)
+	{
+		DBG1(DBG_CFG, "invalid IP address range: %H-%H", from, to);
+		return NULL;
+	}
+	if (fromaddr.len > sizeof(diff) &&
+		!chunk_equals(chunk_create(fromaddr.ptr, fromaddr.len - sizeof(diff)),
+					  chunk_create(toaddr.ptr, toaddr.len - sizeof(diff))))
+	{
+		DBG1(DBG_CFG, "IP address range too large: %H-%H", from, to);
+		return NULL;
+	}
+	this = create_generic(name);
+	this->base = from->clone(from);
+	diff = untoh32(toaddr.ptr + toaddr.len - sizeof(diff)) -
+		   untoh32(fromaddr.ptr + fromaddr.len - sizeof(diff));
+	this->size = diff + 1;
+
+	return &this->public;
+}
diff --git a/src/libcharon/attributes/mem_pool.h b/src/libcharon/attributes/mem_pool.h
new file mode 100644
index 0000000..3ee1dd3
--- /dev/null
+++ b/src/libcharon/attributes/mem_pool.h
@@ -0,0 +1,154 @@
+/*
+ * Copyright (C) 2010 Tobias Brunner
+ * Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * for more details.
+ */
+
+/**
+ * @defgroup mem_pool mem_pool
+ * @{ @ingroup attributes
+ */
+
+#ifndef MEM_POOL_H
+#define MEM_POOL_H
+
+typedef struct mem_pool_t mem_pool_t;
+typedef enum mem_pool_op_t mem_pool_op_t;
+
+#include <networking/host.h>
+#include <utils/identification.h>
+
+/**
+ * In-memory IP pool acquire operation.
+ */
+enum mem_pool_op_t {
+	/** Check for an exsiting lease */
+	MEM_POOL_EXISTING,
+	/** Get a new lease */
+	MEM_POOL_NEW,
+	/** Replace an existing offline lease of another ID */
+	MEM_POOL_REASSIGN,
+};
+
+/**
+ * An in-memory IP address pool.
+ */
+struct mem_pool_t {
+
+	/**
+	 * Get the name of this pool.
+	 *
+	 * @return			the name of this pool
+	 */
+	const char* (*get_name)(mem_pool_t *this);
+
+	/**
+	 * Get the base (first) address of this pool.
+	 *
+	 * @return			base address, internal host
+	 */
+	host_t* (*get_base)(mem_pool_t *this);
+
+	/**
+	 * Get the size (i.e. number of addresses) of this pool.
+	 *
+	 * @return			the size of this pool
+	 */
+	u_int (*get_size)(mem_pool_t *this);
+
+	/**
+	 * Get the number of online leases.
+	 *
+	 * @return			the number of offline leases
+	 */
+	u_int (*get_online)(mem_pool_t *this);
+
+	/**
+	 * Get the number of offline leases.
+	 *
+	 * @return			the number of online leases
+	 */
+	u_int (*get_offline)(mem_pool_t *this);
+
+	/**
+	 * Acquire an address for the given id from this pool.
+	 *
+	 * This call is usually invoked several times: The first time to find an
+	 * existing lease (MEM_POOL_EXISTING), if none found a second time to
+	 * acquire a new lease (MEM_POOL_NEW), and if the pool is full once again
+	 * to assign an existing offline lease (MEM_POOL_REASSIGN).
+	 *
+	 * If the same identity requests a virtual IP that is already assigned to
+	 * it, the peer address and port is used to check if it is the same client
+	 * instance that is connecting. If this is true, the request is considered
+	 * a request for a reauthentication attempt, and the same virtual IP gets
+	 * assigned to the peer.
+	 *
+	 * @param id		the id to acquire an address for
+	 * @param requested	acquire this address, if possible
+	 * @param operation	acquire operation to perform, see above
+	 * @param peer		optional remote IKE address and port
+	 * @return			the acquired address
+	 */
+	host_t* (*acquire_address)(mem_pool_t *this, identification_t *id,
+							   host_t *requested, mem_pool_op_t operation,
+							   host_t *peer);
+
+	/**
+	 * Release a previously acquired address.
+	 *
+	 * @param address	the address to release
+	 * @param id		the id the address was assigned to
+	 * @return			TRUE, if the lease was found
+	 */
+	bool (*release_address)(mem_pool_t *this, host_t *address,
+							identification_t *id);
+
+	/**
+	 * Create an enumerator over the leases of this pool.
+	 *
+	 * Enumerator enumerates over
+	 * identification_t *id, host_t *address, bool online
+	 *
+	 * @return			enumerator
+	 */
+	enumerator_t* (*create_lease_enumerator)(mem_pool_t *this);
+
+	/**
+	 * Destroy a mem_pool_t instance.
+	 */
+	void (*destroy)(mem_pool_t *this);
+};
+
+/**
+ * Create an in-memory IP address pool.
+ *
+ * An empty pool just returns the requested address.
+ *
+ * @param name		name of this pool
+ * @param base		base address of this pool, NULL to create an empty pool
+ * @param bits		number of non-network bits in base, as in CIDR notation
+ * @return			memory pool instance
+ */
+mem_pool_t *mem_pool_create(char *name, host_t *base, int bits);
+
+/**
+ * Create an in-memory IP address from a range.
+ *
+ * @param name		name of this pool
+ * @param from		start of ranged pool
+ * @param to		end of ranged pool
+ * @return			memory pool instance, NULL if range invalid
+ */
+mem_pool_t *mem_pool_create_range(char *name, host_t *from, host_t *to);
+
+#endif /** MEM_POOL_H_ @} */
diff --git a/src/libcharon/bus/bus.c b/src/libcharon/bus/bus.c
index cb59f97..7938f46 100644
--- a/src/libcharon/bus/bus.c
+++ b/src/libcharon/bus/bus.c
@@ -755,6 +755,33 @@ METHOD(bus_t, ike_rekey, void,
 	this->mutex->unlock(this->mutex);
 }
 
+METHOD(bus_t, ike_update, void,
+	private_bus_t *this, ike_sa_t *ike_sa, bool local, host_t *new)
+{
+	enumerator_t *enumerator;
+	entry_t *entry;
+	bool keep;
+
+	this->mutex->lock(this->mutex);
+	enumerator = this->listeners->create_enumerator(this->listeners);
+	while (enumerator->enumerate(enumerator, &entry))
+	{
+		if (entry->calling || !entry->listener->ike_update)
+		{
+			continue;
+		}
+		entry->calling++;
+		keep = entry->listener->ike_update(entry->listener, ike_sa, local, new);
+		entry->calling--;
+		if (!keep)
+		{
+			unregister_listener(this, entry, enumerator);
+		}
+	}
+	enumerator->destroy(enumerator);
+	this->mutex->unlock(this->mutex);
+}
+
 METHOD(bus_t, ike_reestablish_pre, void,
 	private_bus_t *this, ike_sa_t *old, ike_sa_t *new)
 {
@@ -1006,6 +1033,7 @@ bus_t *bus_create()
 			.child_keys = _child_keys,
 			.ike_updown = _ike_updown,
 			.ike_rekey = _ike_rekey,
+			.ike_update = _ike_update,
 			.ike_reestablish_pre = _ike_reestablish_pre,
 			.ike_reestablish_post = _ike_reestablish_post,
 			.child_updown = _child_updown,
diff --git a/src/libcharon/bus/bus.h b/src/libcharon/bus/bus.h
index e1d221c..051c429 100644
--- a/src/libcharon/bus/bus.h
+++ b/src/libcharon/bus/bus.h
@@ -382,6 +382,15 @@ struct bus_t {
 	void (*ike_rekey)(bus_t *this, ike_sa_t *old, ike_sa_t *new);
 
 	/**
+	 * IKE_SA peer endpoint update hook.
+	 *
+	 * @param ike_sa	updated IKE_SA, having old endpoints set
+	 * @param local		TRUE if local endpoint gets updated, FALSE for remote
+	 * @param new		new endpoint address and port
+	 */
+	void (*ike_update)(bus_t *this, ike_sa_t *ike_sa, bool local, host_t *new);
+
+	/**
 	 * IKE_SA reestablishing hook (before resolving hosts).
 	 *
 	 * @param old		reestablished and obsolete IKE_SA
diff --git a/src/libcharon/bus/listeners/listener.h b/src/libcharon/bus/listeners/listener.h
index 0910cb3..3447d8f 100644
--- a/src/libcharon/bus/listeners/listener.h
+++ b/src/libcharon/bus/listeners/listener.h
@@ -128,6 +128,17 @@ struct listener_t {
 	bool (*ike_rekey)(listener_t *this, ike_sa_t *old, ike_sa_t *new);
 
 	/**
+	 * Hook called for IKE_SA peer endpoint updates.
+	 *
+	 * @param ike_sa	updated IKE_SA, having old endpoints set
+	 * @param local		TRUE if local endpoint gets updated, FALSE for remote
+	 * @param new		new endpoint address and port
+	 * @return			TRUE to stay registered, FALSE to unregister
+	 */
+	bool (*ike_update)(listener_t *this, ike_sa_t *ike_sa,
+					   bool local, host_t *new);
+
+	/**
 	 * Hook called when an initiator reestablishes an IKE_SA.
 	 *
 	 * This is invoked right after creating the new IKE_SA and setting the
diff --git a/src/libcharon/config/ike_cfg.c b/src/libcharon/config/ike_cfg.c
index 42a3e90..9464ceb 100644
--- a/src/libcharon/config/ike_cfg.c
+++ b/src/libcharon/config/ike_cfg.c
@@ -459,25 +459,10 @@ static traffic_selector_t* make_range(char *str)
 {
 	traffic_selector_t *ts;
 	ts_type_t type;
-	char *pos;
 	host_t *from, *to;
 
-	pos = strchr(str, '-');
-	if (!pos)
-	{
-		return NULL;
-	}
-	to = host_create_from_string(pos + 1, 0);
-	if (!to)
-	{
-		return NULL;
-	}
-	str = strndup(str, pos - str);
-	from = host_create_from_string_and_family(str, to->get_family(to), 0);
-	free(str);
-	if (!from)
+	if (!host_create_from_range(str, &from, &to))
 	{
-		to->destroy(to);
 		return NULL;
 	}
 	if (to->get_family(to) == AF_INET)
diff --git a/src/libcharon/config/proposal.c b/src/libcharon/config/proposal.c
index 50d3c6f..e59dcd9 100644
--- a/src/libcharon/config/proposal.c
+++ b/src/libcharon/config/proposal.c
@@ -399,10 +399,12 @@ static const struct {
 	pseudo_random_function_t prf;
 } integ_prf_map[] = {
 	{AUTH_HMAC_SHA1_96,					PRF_HMAC_SHA1					},
+	{AUTH_HMAC_SHA1_160,				PRF_HMAC_SHA1					},
 	{AUTH_HMAC_SHA2_256_128,			PRF_HMAC_SHA2_256				},
 	{AUTH_HMAC_SHA2_384_192,			PRF_HMAC_SHA2_384				},
 	{AUTH_HMAC_SHA2_512_256,			PRF_HMAC_SHA2_512				},
 	{AUTH_HMAC_MD5_96,					PRF_HMAC_MD5					},
+	{AUTH_HMAC_MD5_128,					PRF_HMAC_MD5					},
 	{AUTH_AES_XCBC_96,					PRF_AES128_XCBC					},
 	{AUTH_CAMELLIA_XCBC_96,				PRF_CAMELLIA128_XCBC			},
 	{AUTH_AES_CMAC_96,					PRF_AES128_CMAC					},
diff --git a/src/libcharon/control/controller.c b/src/libcharon/control/controller.c
index 25667e5..fd8349e 100644
--- a/src/libcharon/control/controller.c
+++ b/src/libcharon/control/controller.c
@@ -303,6 +303,18 @@ METHOD(listener_t, child_state_change, bool,
 						/* proper delete */
 						this->status = SUCCESS;
 						break;
+					case CHILD_RETRYING:
+						/* retrying with a different DH group; survive another
+						 * initiation round */
+						this->status = NEED_MORE;
+						return TRUE;
+					case CHILD_CREATED:
+						if (this->status == NEED_MORE)
+						{
+							this->status = FAILED;
+							return TRUE;
+						}
+						break;
 					default:
 						break;
 				}
@@ -437,7 +449,7 @@ METHOD(job_t, terminate_ike_execute, job_requeue_t,
 	ike_sa_t *ike_sa;
 
 	ike_sa = charon->ike_sa_manager->checkout_by_id(charon->ike_sa_manager,
-													unique_id, FALSE);
+													unique_id);
 	if (!ike_sa)
 	{
 		DBG1(DBG_IKE, "unable to terminate IKE_SA: ID %d not found", unique_id);
@@ -522,17 +534,15 @@ METHOD(job_t, terminate_child_execute, job_requeue_t,
 	interface_job_t *job)
 {
 	interface_listener_t *listener = &job->listener;
-	u_int32_t reqid = listener->id;
-	enumerator_t *enumerator;
+	u_int32_t id = listener->id;
 	child_sa_t *child_sa;
 	ike_sa_t *ike_sa;
 
-	ike_sa = charon->ike_sa_manager->checkout_by_id(charon->ike_sa_manager,
-													reqid, TRUE);
+	ike_sa = charon->child_sa_manager->checkout_by_id(charon->child_sa_manager,
+													  id, &child_sa);
 	if (!ike_sa)
 	{
-		DBG1(DBG_IKE, "unable to terminate, CHILD_SA with ID %d not found",
-			 reqid);
+		DBG1(DBG_IKE, "unable to terminate, CHILD_SA with ID %d not found", id);
 		listener->status = NOT_FOUND;
 		/* release listener */
 		listener_done(listener);
@@ -542,22 +552,10 @@ METHOD(job_t, terminate_child_execute, job_requeue_t,
 	listener->ike_sa = ike_sa;
 	listener->lock->unlock(listener->lock);
 
-	enumerator = ike_sa->create_child_sa_enumerator(ike_sa);
-	while (enumerator->enumerate(enumerator, (void**)&child_sa))
-	{
-		if (child_sa->get_state(child_sa) != CHILD_ROUTED &&
-			child_sa->get_reqid(child_sa) == reqid)
-		{
-			break;
-		}
-		child_sa = NULL;
-	}
-	enumerator->destroy(enumerator);
-
-	if (!child_sa)
+	if (child_sa->get_state(child_sa) == CHILD_ROUTED)
 	{
 		DBG1(DBG_IKE, "unable to terminate, established "
-			 "CHILD_SA with ID %d not found", reqid);
+			 "CHILD_SA with ID %d not found", id);
 		charon->ike_sa_manager->checkin(charon->ike_sa_manager, ike_sa);
 		listener->status = NOT_FOUND;
 		/* release listener */
@@ -584,7 +582,7 @@ METHOD(job_t, terminate_child_execute, job_requeue_t,
 }
 
 METHOD(controller_t, terminate_child, status_t,
-	controller_t *this, u_int32_t reqid,
+	controller_t *this, u_int32_t unique_id,
 	controller_cb_t callback, void *param, u_int timeout)
 {
 	interface_job_t *job;
@@ -605,7 +603,7 @@ METHOD(controller_t, terminate_child, status_t,
 				.param = param,
 			},
 			.status = FAILED,
-			.id = reqid,
+			.id = unique_id,
 			.lock = spinlock_create(),
 		},
 		.public = {
diff --git a/src/libcharon/control/controller.h b/src/libcharon/control/controller.h
index 222285c..02f4ebb 100644
--- a/src/libcharon/control/controller.h
+++ b/src/libcharon/control/controller.h
@@ -118,7 +118,7 @@ struct controller_t {
 	 * If a callback is provided the function is synchronous and thus blocks
 	 * until the CHILD_SA is properly deleted, or the call timed out.
 	 *
-	 * @param reqid			reqid of the CHILD_SA to terminate
+	 * @param unique_id		CHILD_SA unique ID to terminate
 	 * @param cb			logging callback
 	 * @param param			parameter to include in each call of cb
 	 * @param timeout		timeout in ms to wait for callbacks, 0 to disable
@@ -128,7 +128,7 @@ struct controller_t {
 	 *						- NEED_MORE, if callback returned FALSE
 	 *						- OUT_OF_RES if timed out
 	 */
-	status_t (*terminate_child)(controller_t *this, u_int32_t reqid,
+	status_t (*terminate_child)(controller_t *this, u_int32_t unique_id,
 								controller_cb_t callback, void *param,
 								u_int timeout);
 
diff --git a/src/libcharon/daemon.c b/src/libcharon/daemon.c
index 3ae7c4e..b1b8f57 100644
--- a/src/libcharon/daemon.c
+++ b/src/libcharon/daemon.c
@@ -474,12 +474,15 @@ static void destroy(private_daemon_t *this)
 	DESTROY_IF(this->public.connect_manager);
 	DESTROY_IF(this->public.mediation_manager);
 #endif /* ME */
-	/* make sure the cache is clear before unloading plugins */
+	/* make sure the cache and scheduler are clear before unloading plugins */
 	lib->credmgr->flush_cache(lib->credmgr, CERT_ANY);
+	lib->scheduler->flush(lib->scheduler);
 	lib->plugins->unload(lib->plugins);
+	DESTROY_IF(this->public.attributes);
 	DESTROY_IF(this->kernel_handler);
 	DESTROY_IF(this->public.traps);
 	DESTROY_IF(this->public.shunts);
+	DESTROY_IF(this->public.child_sa_manager);
 	DESTROY_IF(this->public.ike_sa_manager);
 	DESTROY_IF(this->public.controller);
 	DESTROY_IF(this->public.eap);
@@ -606,6 +609,7 @@ METHOD(daemon_t, initialize, bool,
 	{
 		return FALSE;
 	}
+	this->public.child_sa_manager = child_sa_manager_create();
 
 	/* Queue start_action job */
 	lib->processor->queue_job(lib->processor, (job_t*)start_action_job_create());
@@ -642,6 +646,7 @@ private_daemon_t *daemon_create()
 		.ref = 1,
 	);
 	charon = &this->public;
+	this->public.attributes = attribute_manager_create();
 	this->public.controller = controller_create();
 	this->public.eap = eap_manager_create();
 	this->public.xauth = xauth_manager_create();
diff --git a/src/libcharon/daemon.h b/src/libcharon/daemon.h
index 36242bb..d16bf1d 100644
--- a/src/libcharon/daemon.h
+++ b/src/libcharon/daemon.h
@@ -19,6 +19,9 @@
 /**
  * @defgroup libcharon libcharon
  *
+ * @defgroup attributes attributes
+ * @ingroup libcharon
+ *
  * @defgroup bus bus
  * @ingroup libcharon
  *
@@ -152,12 +155,14 @@
 
 typedef struct daemon_t daemon_t;
 
+#include <attributes/attribute_manager.h>
 #include <network/sender.h>
 #include <network/receiver.h>
 #include <network/socket_manager.h>
 #include <control/controller.h>
 #include <bus/bus.h>
 #include <sa/ike_sa_manager.h>
+#include <sa/child_sa_manager.h>
 #include <sa/trap_manager.h>
 #include <sa/shunt_manager.h>
 #include <config/backend_manager.h>
@@ -215,6 +220,11 @@ struct daemon_t {
 	ike_sa_manager_t *ike_sa_manager;
 
 	/**
+	 * A child_sa_manager_t instance.
+	 */
+	child_sa_manager_t *child_sa_manager;
+
+	/**
 	 * Manager for triggering policies, called traps
 	 */
 	trap_manager_t *traps;
@@ -240,6 +250,11 @@ struct daemon_t {
 	receiver_t *receiver;
 
 	/**
+	 * Manager for IKE configuration attributes
+	 */
+	attribute_manager_t *attributes;
+
+	/**
 	 * The signaling bus.
 	 */
 	bus_t *bus;
diff --git a/src/libcharon/encoding/message.c b/src/libcharon/encoding/message.c
index cb6c97f..0a596ff 100644
--- a/src/libcharon/encoding/message.c
+++ b/src/libcharon/encoding/message.c
@@ -180,6 +180,7 @@ static payload_order_t ike_sa_init_r_order[] = {
  */
 static payload_rule_t ike_auth_i_rules[] = {
 /*	payload type					min	max						encr	suff */
+	{PLV2_FRAGMENT,					0,	1,						TRUE,	TRUE},
 	{PLV2_NOTIFY,					0,	MAX_NOTIFY_PAYLOADS,	TRUE,	FALSE},
 	{PLV2_EAP,						0,	1,						TRUE,	TRUE},
 	{PLV2_AUTH,						0,	1,						TRUE,	TRUE},
@@ -227,6 +228,7 @@ static payload_order_t ike_auth_i_order[] = {
 	{PLV2_NOTIFY,					NO_ADDITIONAL_ADDRESSES},
 	{PLV2_NOTIFY,					0},
 	{PLV2_VENDOR_ID,				0},
+	{PLV2_FRAGMENT,					0},
 };
 
 /**
@@ -234,6 +236,7 @@ static payload_order_t ike_auth_i_order[] = {
  */
 static payload_rule_t ike_auth_r_rules[] = {
 /*	payload type					min	max						encr	suff */
+	{PLV2_FRAGMENT,					0,	1,						TRUE,	TRUE},
 	{PLV2_NOTIFY,					0,	MAX_NOTIFY_PAYLOADS,	TRUE,	TRUE},
 	{PLV2_EAP,						0,	1,						TRUE,	TRUE},
 	{PLV2_AUTH,						0,	1,						TRUE,	TRUE},
@@ -270,6 +273,7 @@ static payload_order_t ike_auth_r_order[] = {
 	{PLV2_NOTIFY,					NO_ADDITIONAL_ADDRESSES},
 	{PLV2_NOTIFY,					0},
 	{PLV2_VENDOR_ID,				0},
+	{PLV2_FRAGMENT,					0},
 };
 
 /**
@@ -277,6 +281,7 @@ static payload_order_t ike_auth_r_order[] = {
  */
 static payload_rule_t informational_i_rules[] = {
 /*	payload type					min	max						encr	suff */
+	{PLV2_FRAGMENT,					0,	1,						TRUE,	TRUE},
 	{PLV2_NOTIFY,					0,	MAX_NOTIFY_PAYLOADS,	TRUE,	FALSE},
 	{PLV2_CONFIGURATION,			0,	1,						TRUE,	FALSE},
 	{PLV2_DELETE,					0,	MAX_DELETE_PAYLOADS,	TRUE,	FALSE},
@@ -295,6 +300,7 @@ static payload_order_t informational_i_order[] = {
 	{PLV2_NOTIFY,					0},
 	{PLV2_DELETE,					0},
 	{PLV2_CONFIGURATION,			0},
+	{PLV2_FRAGMENT,					0},
 };
 
 /**
@@ -302,6 +308,7 @@ static payload_order_t informational_i_order[] = {
  */
 static payload_rule_t informational_r_rules[] = {
 /*	payload type					min	max						encr	suff */
+	{PLV2_FRAGMENT,					0,	1,						TRUE,	TRUE},
 	{PLV2_NOTIFY,					0,	MAX_NOTIFY_PAYLOADS,	TRUE,	FALSE},
 	{PLV2_CONFIGURATION,			0,	1,						TRUE,	FALSE},
 	{PLV2_DELETE,					0,	MAX_DELETE_PAYLOADS,	TRUE,	FALSE},
@@ -320,6 +327,7 @@ static payload_order_t informational_r_order[] = {
 	{PLV2_NOTIFY,					0},
 	{PLV2_DELETE,					0},
 	{PLV2_CONFIGURATION,			0},
+	{PLV2_FRAGMENT,					0},
 };
 
 /**
@@ -327,6 +335,7 @@ static payload_order_t informational_r_order[] = {
  */
 static payload_rule_t create_child_sa_i_rules[] = {
 /*	payload type					min	max						encr	suff */
+	{PLV2_FRAGMENT,					0,	1,						TRUE,	TRUE},
 	{PLV2_NOTIFY,					0,	MAX_NOTIFY_PAYLOADS,	TRUE,	FALSE},
 	{PLV2_SECURITY_ASSOCIATION,		1,	1,						TRUE,	FALSE},
 	{PLV2_NONCE,					1,	1,						TRUE,	FALSE},
@@ -353,6 +362,7 @@ static payload_order_t create_child_sa_i_order[] = {
 	{PLV2_TS_INITIATOR,				0},
 	{PLV2_TS_RESPONDER,				0},
 	{PLV2_NOTIFY,					0},
+	{PLV2_FRAGMENT,					0},
 };
 
 /**
@@ -360,6 +370,7 @@ static payload_order_t create_child_sa_i_order[] = {
  */
 static payload_rule_t create_child_sa_r_rules[] = {
 /*	payload type					min	max						encr	suff */
+	{PLV2_FRAGMENT,					0,	1,						TRUE,	TRUE},
 	{PLV2_NOTIFY,					0,	MAX_NOTIFY_PAYLOADS,	TRUE,	TRUE},
 	{PLV2_SECURITY_ASSOCIATION,		1,	1,						TRUE,	FALSE},
 	{PLV2_NONCE,					1,	1,						TRUE,	FALSE},
@@ -386,6 +397,7 @@ static payload_order_t create_child_sa_r_order[] = {
 	{PLV2_TS_RESPONDER,				0},
 	{PLV2_NOTIFY,					ADDITIONAL_TS_POSSIBLE},
 	{PLV2_NOTIFY,					0},
+	{PLV2_FRAGMENT,					0},
 };
 
 #ifdef ME
@@ -2143,6 +2155,8 @@ METHOD(message_t, parse_header, status_t,
 	}
 	ike_header->destroy(ike_header);
 
+	this->parser->set_major_version(this->parser, this->major_version);
+
 	DBG2(DBG_ENC, "parsed a %N %s header", exchange_type_names,
 		 this->exchange_type, this->major_version == IKEV1_MAJOR_VERSION ?
 		 "message" : (this->is_request ? "request" : "response"));
@@ -2463,7 +2477,7 @@ static status_t decrypt_payloads(private_message_t *this, keymat_t *keymat)
 			was_encrypted = "encrypted fragment payload";
 		}
 
-		if (payload_is_known(type) && !was_encrypted &&
+		if (payload_is_known(type, this->major_version) && !was_encrypted &&
 			!is_connectivity_check(this, payload) &&
 			this->exchange_type != AGGRESSIVE)
 		{
diff --git a/src/libcharon/encoding/parser.c b/src/libcharon/encoding/parser.c
index d6240fd..f834036 100644
--- a/src/libcharon/encoding/parser.c
+++ b/src/libcharon/encoding/parser.c
@@ -59,6 +59,11 @@ struct private_parser_t {
 	parser_t public;
 
 	/**
+	 * major IKE version
+	 */
+	u_int8_t major_version;
+
+	/**
 	 * Current bit for reading in input data.
 	 */
 	u_int8_t bit_pos;
@@ -369,7 +374,14 @@ METHOD(parser_t, parse_payload, status_t,
 	encoding_rule_t *rule;
 
 	/* create instance of the payload to parse */
-	pld = payload_create(payload_type);
+	if (payload_is_known(payload_type, this->major_version))
+	{
+		pld = payload_create(payload_type);
+	}
+	else
+	{
+		pld = (payload_t*)unknown_payload_create(payload_type);
+	}
 
 	DBG2(DBG_ENC, "parsing %N payload, %d bytes left",
 		 payload_type_names, payload_type, this->input_roof - this->byte_pos);
@@ -629,6 +641,12 @@ METHOD(parser_t, reset_context, void,
 	this->bit_pos = 0;
 }
 
+METHOD(parser_t, set_major_version, void,
+	private_parser_t *this, u_int8_t major_version)
+{
+	this->major_version = major_version;
+}
+
 METHOD(parser_t, destroy, void,
 	private_parser_t *this)
 {
@@ -646,6 +664,7 @@ parser_t *parser_create(chunk_t data)
 		.public = {
 			.parse_payload = _parse_payload,
 			.reset_context = _reset_context,
+			.set_major_version = _set_major_version,
 			.get_remaining_byte_count = _get_remaining_byte_count,
 			.destroy = _destroy,
 		},
diff --git a/src/libcharon/encoding/parser.h b/src/libcharon/encoding/parser.h
index 27c5f03..5fd3e86 100644
--- a/src/libcharon/encoding/parser.h
+++ b/src/libcharon/encoding/parser.h
@@ -29,7 +29,7 @@ typedef struct parser_t parser_t;
 #include <encoding/payloads/payload.h>
 
 /**
- * A parser_t class to parse IKEv2 payloads.
+ * A parser_t class to parse IKE payloads.
  *
  * A parser is used for parsing one chunk of data. Multiple
  * payloads can be parsed out of the chunk using parse_payload.
@@ -50,7 +50,8 @@ struct parser_t {
 	 * 						- SUCCESSFUL if succeeded,
 	 * 						- PARSE_ERROR if corrupted/invalid data found
 	 */
-	status_t (*parse_payload) (parser_t *this, payload_type_t payload_type, payload_t **payload);
+	status_t (*parse_payload) (parser_t *this, payload_type_t payload_type,
+							   payload_t **payload);
 
 	/**
 	 * Gets the remaining byte count which is not currently parsed.
@@ -63,6 +64,13 @@ struct parser_t {
 	void (*reset_context) (parser_t *this);
 
 	/**
+	 * Set the major IKE version.
+	 *
+	 * @param major_version	the major IKE version
+	 */
+	void (*set_major_version) (parser_t *this, u_int8_t major_version);
+
+	/**
 	 * Destroys a parser_t object.
 	 */
 	void (*destroy) (parser_t *this);
diff --git a/src/libcharon/encoding/payloads/delete_payload.c b/src/libcharon/encoding/payloads/delete_payload.c
index c2ab3b9..f11ea48 100644
--- a/src/libcharon/encoding/payloads/delete_payload.c
+++ b/src/libcharon/encoding/payloads/delete_payload.c
@@ -1,4 +1,5 @@
 /*
+ * Copyright (C) 2015 Tobias Brunner
  * Copyright (C) 2005-2010 Martin Willi
  * Copyright (C) 2010 revosec AG
  * Copyright (C) 2005 Jan Hutter
@@ -281,6 +282,19 @@ METHOD(delete_payload_t, set_ike_spi, void,
 	this->payload_length = get_header_length(this) + this->spi_size;
 }
 
+METHOD(delete_payload_t, get_ike_spi, bool,
+	private_delete_payload_t *this, u_int64_t *spi_i, u_int64_t *spi_r)
+{
+	if (this->protocol_id != PROTO_IKE ||
+		this->spis.len < 2 * sizeof(u_int64_t))
+	{
+		return FALSE;
+	}
+	memcpy(spi_i, this->spis.ptr, sizeof(u_int64_t));
+	memcpy(spi_r, this->spis.ptr + sizeof(u_int64_t), sizeof(u_int64_t));
+	return TRUE;
+}
+
 /**
  * SPI enumerator implementation
  */
@@ -352,6 +366,7 @@ delete_payload_t *delete_payload_create(payload_type_t type,
 			.get_protocol_id = _get_protocol_id,
 			.add_spi = _add_spi,
 			.set_ike_spi = _set_ike_spi,
+			.get_ike_spi = _get_ike_spi,
 			.create_spi_enumerator = _create_spi_enumerator,
 			.destroy = _destroy,
 		},
diff --git a/src/libcharon/encoding/payloads/delete_payload.h b/src/libcharon/encoding/payloads/delete_payload.h
index 46a89ea..6728718 100644
--- a/src/libcharon/encoding/payloads/delete_payload.h
+++ b/src/libcharon/encoding/payloads/delete_payload.h
@@ -1,4 +1,5 @@
 /*
+ * Copyright (C) 2015 Tobias Brunner
  * Copyright (C) 2005-2006 Martin Willi
  * Copyright (C) 2005 Jan Hutter
  * Hochschule fuer Technik Rapperswil
@@ -61,6 +62,15 @@ struct delete_payload_t {
 	void (*set_ike_spi)(delete_payload_t *this, u_int64_t spi_i, u_int64_t spi_r);
 
 	/**
+	 * Get the IKE SPIs from an IKEv1 delete.
+	 *
+	 * @param spi_i			initiator SPI
+	 * @param spi_r			responder SPI
+	 * @return				TRUE if SPIs extracted successfully
+	 */
+	bool (*get_ike_spi)(delete_payload_t *this, u_int64_t *spi_i, u_int64_t *spi_r);
+
+	/**
 	 * Get an enumerator over the SPIs in network order.
 	 *
 	 * @return				enumerator over SPIs, u_int32_t
diff --git a/src/libcharon/encoding/payloads/encrypted_payload.c b/src/libcharon/encoding/payloads/encrypted_payload.c
index 5c574c3..04372fd 100644
--- a/src/libcharon/encoding/payloads/encrypted_payload.c
+++ b/src/libcharon/encoding/payloads/encrypted_payload.c
@@ -561,6 +561,7 @@ static status_t parse(private_encrypted_payload_t *this, chunk_t plain)
 	payload_type_t type;
 
 	parser = parser_create(plain);
+	parser->set_major_version(parser, this->type == PLV1_ENCRYPTED ? 1 : 2);
 	type = this->next_payload;
 	while (type != PL_NONE)
 	{
diff --git a/src/libcharon/encoding/payloads/id_payload.c b/src/libcharon/encoding/payloads/id_payload.c
index a002a8f..bb8aab7 100644
--- a/src/libcharon/encoding/payloads/id_payload.c
+++ b/src/libcharon/encoding/payloads/id_payload.c
@@ -258,17 +258,20 @@ static traffic_selector_t *get_ts_from_range(private_id_payload_t *this,
 static traffic_selector_t *get_ts_from_subnet(private_id_payload_t *this,
 											  ts_type_t type)
 {
+	traffic_selector_t *ts;
 	chunk_t net, netmask;
 	int i;
 
 	net = chunk_create(this->id_data.ptr, this->id_data.len / 2);
-	netmask = chunk_skip(this->id_data, this->id_data.len / 2);
+	netmask = chunk_clone(chunk_skip(this->id_data, this->id_data.len / 2));
 	for (i = 0; i < net.len; i++)
 	{
 		netmask.ptr[i] = (netmask.ptr[i] ^ 0xFF) | net.ptr[i];
 	}
-	return traffic_selector_create_from_bytes(this->protocol_id, type,
+	ts = traffic_selector_create_from_bytes(this->protocol_id, type,
 								net, this->port, netmask, this->port ?: 65535);
+	chunk_free(&netmask);
+	return ts;
 }
 
 /**
diff --git a/src/libcharon/encoding/payloads/ke_payload.c b/src/libcharon/encoding/payloads/ke_payload.c
index 4f552d6..50fd73f 100644
--- a/src/libcharon/encoding/payloads/ke_payload.c
+++ b/src/libcharon/encoding/payloads/ke_payload.c
@@ -247,9 +247,15 @@ ke_payload_t *ke_payload_create(payload_type_t type)
 ke_payload_t *ke_payload_create_from_diffie_hellman(payload_type_t type,
 													diffie_hellman_t *dh)
 {
-	private_ke_payload_t *this = (private_ke_payload_t*)ke_payload_create(type);
+	private_ke_payload_t *this;
+	chunk_t value;
 
-	dh->get_my_public_value(dh, &this->key_exchange_data);
+	if (!dh->get_my_public_value(dh, &value))
+	{
+		return NULL;
+	}
+	this = (private_ke_payload_t*)ke_payload_create(type);
+	this->key_exchange_data = value;
 	this->dh_group_number = dh->get_dh_group(dh);
 	this->payload_length += this->key_exchange_data.len;
 
diff --git a/src/libcharon/encoding/payloads/ke_payload.h b/src/libcharon/encoding/payloads/ke_payload.h
index dfc6308..96c5096 100644
--- a/src/libcharon/encoding/payloads/ke_payload.h
+++ b/src/libcharon/encoding/payloads/ke_payload.h
@@ -73,7 +73,7 @@ ke_payload_t *ke_payload_create(payload_type_t type);
  *
  * @param type		PLV2_KEY_EXCHANGE or PLV1_KEY_EXCHANGE
  * @param dh		diffie hellman object containing group and key
- * @return 			ke_payload_t object
+ * @return 			ke_payload_t object, NULL on error
  */
 ke_payload_t *ke_payload_create_from_diffie_hellman(payload_type_t type,
 													diffie_hellman_t *dh);
diff --git a/src/libcharon/encoding/payloads/notify_payload.c b/src/libcharon/encoding/payloads/notify_payload.c
index 94723dd..f32a127 100644
--- a/src/libcharon/encoding/payloads/notify_payload.c
+++ b/src/libcharon/encoding/payloads/notify_payload.c
@@ -65,7 +65,7 @@ ENUM_NEXT(notify_type_names, ME_CONNECT_FAILED, ME_CONNECT_FAILED, CHILD_SA_NOT_
 	"ME_CONNECT_FAILED");
 ENUM_NEXT(notify_type_names, MS_NOTIFY_STATUS, MS_NOTIFY_STATUS, ME_CONNECT_FAILED,
 	"MS_NOTIFY_STATUS");
-ENUM_NEXT(notify_type_names, INITIAL_CONTACT, FRAGMENTATION_SUPPORTED, MS_NOTIFY_STATUS,
+ENUM_NEXT(notify_type_names, INITIAL_CONTACT, SIGNATURE_HASH_ALGORITHMS, MS_NOTIFY_STATUS,
 	"INITIAL_CONTACT",
 	"SET_WINDOW_SIZE",
 	"ADDITIONAL_TS_POSSIBLE",
@@ -112,8 +112,9 @@ ENUM_NEXT(notify_type_names, INITIAL_CONTACT, FRAGMENTATION_SUPPORTED, MS_NOTIFY
 	"ERX_SUPPORTED",
 	"IFOM_CAPABILITY",
 	"SENDER_REQUEST_ID",
-	"FRAGMENTATION_SUPPORTED");
-ENUM_NEXT(notify_type_names, INITIAL_CONTACT_IKEV1, INITIAL_CONTACT_IKEV1, FRAGMENTATION_SUPPORTED,
+	"FRAGMENTATION_SUPPORTED",
+	"SIGNATURE_HASH_ALGORITHMS");
+ENUM_NEXT(notify_type_names, INITIAL_CONTACT_IKEV1, INITIAL_CONTACT_IKEV1, SIGNATURE_HASH_ALGORITHMS,
 	"INITIAL_CONTACT");
 ENUM_NEXT(notify_type_names, DPD_R_U_THERE, DPD_R_U_THERE_ACK, INITIAL_CONTACT_IKEV1,
 	"DPD_R_U_THERE",
@@ -174,7 +175,7 @@ ENUM_NEXT(notify_type_short_names, ME_CONNECT_FAILED, ME_CONNECT_FAILED, CHILD_S
 	"ME_CONN_FAIL");
 ENUM_NEXT(notify_type_short_names, MS_NOTIFY_STATUS, MS_NOTIFY_STATUS, ME_CONNECT_FAILED,
 	"MS_STATUS");
-ENUM_NEXT(notify_type_short_names, INITIAL_CONTACT, FRAGMENTATION_SUPPORTED, MS_NOTIFY_STATUS,
+ENUM_NEXT(notify_type_short_names, INITIAL_CONTACT, SIGNATURE_HASH_ALGORITHMS, MS_NOTIFY_STATUS,
 	"INIT_CONTACT",
 	"SET_WINSIZE",
 	"ADD_TS_POSS",
@@ -221,8 +222,9 @@ ENUM_NEXT(notify_type_short_names, INITIAL_CONTACT, FRAGMENTATION_SUPPORTED, MS_
 	"ERX_SUP",
 	"IFOM_CAP",
 	"SENDER_REQ_ID",
-	"FRAG_SUP");
-ENUM_NEXT(notify_type_short_names, INITIAL_CONTACT_IKEV1, INITIAL_CONTACT_IKEV1, FRAGMENTATION_SUPPORTED,
+	"FRAG_SUP",
+	"HASH_ALG");
+ENUM_NEXT(notify_type_short_names, INITIAL_CONTACT_IKEV1, INITIAL_CONTACT_IKEV1, SIGNATURE_HASH_ALGORITHMS,
 	"INITIAL_CONTACT");
 ENUM_NEXT(notify_type_short_names, DPD_R_U_THERE, DPD_R_U_THERE_ACK, INITIAL_CONTACT_IKEV1,
 	"DPD",
@@ -473,6 +475,14 @@ METHOD(payload_t, verify, status_t,
 			}
 			break;
 		}
+		case SIGNATURE_HASH_ALGORITHMS:
+		{
+			if (this->notify_data.len % 2)
+			{
+				bad_length = TRUE;
+			}
+			break;
+		}
 		case AUTH_LIFETIME:
 		{
 			if (this->notify_data.len != 4)
diff --git a/src/libcharon/encoding/payloads/notify_payload.h b/src/libcharon/encoding/payloads/notify_payload.h
index 25521c2..6907573 100644
--- a/src/libcharon/encoding/payloads/notify_payload.h
+++ b/src/libcharon/encoding/payloads/notify_payload.h
@@ -151,6 +151,8 @@ enum notify_type_t {
 	SENDER_REQUEST_ID = 16429,
 	/* IKEv2 fragmentation supported, RFC 7383 */
 	FRAGMENTATION_SUPPORTED = 16430,
+	/* Signature Hash Algorithms, RFC 7427 */
+	SIGNATURE_HASH_ALGORITHMS = 16431,
 	/* IKEv1 initial contact */
 	INITIAL_CONTACT_IKEV1 = 24578,
 	/* IKEv1 DPD */
diff --git a/src/libcharon/encoding/payloads/payload.c b/src/libcharon/encoding/payloads/payload.c
index 600b6dd..a1cd2f9 100644
--- a/src/libcharon/encoding/payloads/payload.c
+++ b/src/libcharon/encoding/payloads/payload.c
@@ -266,37 +266,51 @@ payload_t *payload_create(payload_type_t type)
 /**
  * See header.
  */
-bool payload_is_known(payload_type_t type)
+bool payload_is_known(payload_type_t type, u_int8_t maj_ver)
 {
-	if (type == PL_HEADER)
+	if (type >= PL_HEADER)
 	{
 		return TRUE;
 	}
-	if (type >= PLV1_SECURITY_ASSOCIATION && type <= PLV1_CONFIGURATION)
+	switch (maj_ver)
 	{
-		return TRUE;
-	}
-	if (type >= PLV1_NAT_D && type <= PLV1_NAT_OA)
-	{
-		return TRUE;
-	}
-	if (type >= PLV2_SECURITY_ASSOCIATION && type <= PLV2_EAP)
-	{
-		return TRUE;
-	}
-	if (type == PLV2_FRAGMENT)
-	{
-		return TRUE;
-	}
+		case 0:
+		case IKEV1_MAJOR_VERSION:
+			if (type >= PLV1_SECURITY_ASSOCIATION && type <= PLV1_CONFIGURATION)
+			{
+				return TRUE;
+			}
+			if (type >= PLV1_NAT_D && type <= PLV1_NAT_OA)
+			{
+				return TRUE;
+			}
+			if (type >= PLV1_NAT_D_DRAFT_00_03 && type <= PLV1_FRAGMENT)
+			{
+				return TRUE;
+			}
+			if (maj_ver)
+			{
+				break;
+			}
+			/* fall-through */
+		case IKEV2_MAJOR_VERSION:
+			if (type >= PLV2_SECURITY_ASSOCIATION && type <= PLV2_EAP)
+			{
+				return TRUE;
+			}
+			if (type == PLV2_FRAGMENT)
+			{
+				return TRUE;
+			}
 #ifdef ME
-	if (type == PLV2_ID_PEER)
-	{
-		return TRUE;
-	}
+			if (type == PLV2_ID_PEER)
+			{
+				return TRUE;
+			}
 #endif
-	if (type >= PLV1_NAT_D_DRAFT_00_03 && type <= PLV1_FRAGMENT)
-	{
-		return TRUE;
+			break;
+		default:
+			break;
 	}
 	return FALSE;
 }
diff --git a/src/libcharon/encoding/payloads/payload.h b/src/libcharon/encoding/payloads/payload.h
index 036cd42..920779b 100644
--- a/src/libcharon/encoding/payloads/payload.h
+++ b/src/libcharon/encoding/payloads/payload.h
@@ -405,9 +405,10 @@ payload_t *payload_create(payload_type_t type);
  * Check if a specific payload is implemented, or handled as unknown payload.
  *
  * @param type		type of the payload to check
+ * @param maj_ver	major IKE version (use 0 to skip version check)
  * @return			FALSE if payload type handled as unknown payload
  */
-bool payload_is_known(payload_type_t type);
+bool payload_is_known(payload_type_t type, u_int8_t maj_ver);
 
 /**
  * Get the value field in a payload using encoding rules.
diff --git a/src/libcharon/encoding/payloads/proposal_substructure.c b/src/libcharon/encoding/payloads/proposal_substructure.c
index 53e8cf3..48dcfeb 100644
--- a/src/libcharon/encoding/payloads/proposal_substructure.c
+++ b/src/libcharon/encoding/payloads/proposal_substructure.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2012 Tobias Brunner
+ * Copyright (C) 2012-2014 Tobias Brunner
  * Copyright (C) 2005-2010 Martin Willi
  * Copyright (C) 2005 Jan Hutter
  * Hochschule fuer Technik Rapperswil
@@ -224,26 +224,7 @@ typedef enum {
 	/* FreeS/WAN proprietary */
 	IKEV1_ESP_ENCR_SERPENT = 252,
 	IKEV1_ESP_ENCR_TWOFISH = 253,
-} ikev1_esp_encr_transid_t;
-
-/**
- * IKEv1 Transform ID ESP authentication algorithm.
- */
-typedef enum {
-	IKEV1_ESP_AUTH_HMAC_MD5 = 1,
-	IKEV1_ESP_AUTH_HMAC_SHA = 2,
-	IKEV1_ESP_AUTH_DES_MAC = 3,
-	IKEV1_ESP_AUTH_KPDK = 4,
-	IKEV1_ESP_AUTH_HMAC_SHA2_256 = 5,
-	IKEV1_ESP_AUTH_HMAC_SHA2_384 = 6,
-	IKEV1_ESP_AUTH_HMAC_SHA2_512 = 7,
-	IKEV1_ESP_AUTH_HMAC_RIPEMD = 8,
-	IKEV1_ESP_AUTH_AES_XCBC_MAC = 9,
-	IKEV1_ESP_AUTH_SIG_RSA = 10,
-	IKEV1_ESP_AUTH_AES_128_GMAC = 11,
-	IKEV1_ESP_AUTH_AES_192_GMAC = 12,
-	IKEV1_ESP_AUTH_AES_256_GMAC = 13,
-} ikev1_esp_auth_transid_it;
+} ikev1_esp_transid_t;
 
 /**
  * IKEv1 Transform ID AH authentication algorithm.
@@ -264,6 +245,25 @@ typedef enum {
 } ikev1_ah_transid_t;
 
 /**
+ * IKEv1 authentication algorithm.
+ */
+typedef enum {
+	IKEV1_AUTH_HMAC_MD5 = 1,
+	IKEV1_AUTH_HMAC_SHA = 2,
+	IKEV1_AUTH_DES_MAC = 3,
+	IKEV1_AUTH_KPDK = 4,
+	IKEV1_AUTH_HMAC_SHA2_256 = 5,
+	IKEV1_AUTH_HMAC_SHA2_384 = 6,
+	IKEV1_AUTH_HMAC_SHA2_512 = 7,
+	IKEV1_AUTH_HMAC_RIPEMD = 8,
+	IKEV1_AUTH_AES_XCBC_MAC = 9,
+	IKEV1_AUTH_SIG_RSA = 10,
+	IKEV1_AUTH_AES_128_GMAC = 11,
+	IKEV1_AUTH_AES_192_GMAC = 12,
+	IKEV1_AUTH_AES_256_GMAC = 13,
+} ikev1_auth_algo_t;
+
+/**
  * IKEv1 ESP Encapsulation mode.
  */
 typedef enum {
@@ -345,7 +345,7 @@ METHOD(payload_t, verify, status_t,
 	switch (this->protocol_id)
 	{
 		case PROTO_IPCOMP:
-			if (this->spi.len != 2)
+			if (this->spi.len != 2 && this->spi.len != 4)
 			{
 				DBG1(DBG_ENC, "invalid CPI length in IPCOMP proposal");
 				return FAILED;
@@ -536,7 +536,7 @@ METHOD(proposal_substructure_t, get_cpi, bool,
 		{
 			if (cpi)
 			{
-				*cpi = *((u_int16_t*)this->spi.ptr);
+				*cpi = htons(untoh16(this->spi.ptr + this->spi.len - 2));
 			}
 			enumerator->destroy(enumerator);
 			return TRUE;
@@ -620,7 +620,7 @@ static algo_map_t map_prf[] = {
 /**
  * ESP encryption algorithm mapping
  */
-static algo_map_t map_esp_encr[] = {
+static algo_map_t map_esp[] = {
 	{ IKEV1_ESP_ENCR_DES_IV64,				ENCR_DES_IV64 },
 	{ IKEV1_ESP_ENCR_DES,					ENCR_DES },
 	{ IKEV1_ESP_ENCR_3DES,					ENCR_3DES },
@@ -646,23 +646,6 @@ static algo_map_t map_esp_encr[] = {
 };
 
 /**
- * ESP authentication algorithm mapping
- */
-static algo_map_t map_esp_auth[] = {
-	{ IKEV1_ESP_AUTH_HMAC_MD5,			AUTH_HMAC_MD5_96 },
-	{ IKEV1_ESP_AUTH_HMAC_SHA,			AUTH_HMAC_SHA1_96 },
-	{ IKEV1_ESP_AUTH_DES_MAC,			AUTH_DES_MAC },
-	{ IKEV1_ESP_AUTH_KPDK,				AUTH_KPDK_MD5 },
-	{ IKEV1_ESP_AUTH_HMAC_SHA2_256,		AUTH_HMAC_SHA2_256_128 },
-	{ IKEV1_ESP_AUTH_HMAC_SHA2_384,		AUTH_HMAC_SHA2_384_192 },
-	{ IKEV1_ESP_AUTH_HMAC_SHA2_512,		AUTH_HMAC_SHA2_512_256 },
-	{ IKEV1_ESP_AUTH_AES_XCBC_MAC,		AUTH_AES_XCBC_96 },
-	{ IKEV1_ESP_AUTH_AES_128_GMAC,		AUTH_AES_128_GMAC },
-	{ IKEV1_ESP_AUTH_AES_192_GMAC,		AUTH_AES_192_GMAC },
-	{ IKEV1_ESP_AUTH_AES_256_GMAC,		AUTH_AES_256_GMAC },
-};
-
-/**
  * AH authentication algorithm mapping
  */
 static algo_map_t map_ah[] = {
@@ -679,34 +662,30 @@ static algo_map_t map_ah[] = {
 };
 
 /**
- * Get IKEv2 algorithm from IKEv1 identifier
+ * ESP/AH authentication algorithm mapping
  */
-static u_int16_t get_alg_from_ikev1(transform_type_t type, u_int16_t value)
+static algo_map_t map_auth[] = {
+	{ IKEV1_AUTH_HMAC_MD5,			AUTH_HMAC_MD5_96 },
+	{ IKEV1_AUTH_HMAC_SHA,			AUTH_HMAC_SHA1_96 },
+	{ IKEV1_AUTH_DES_MAC,			AUTH_DES_MAC },
+	{ IKEV1_AUTH_KPDK,				AUTH_KPDK_MD5 },
+	{ IKEV1_AUTH_HMAC_SHA2_256,		AUTH_HMAC_SHA2_256_128 },
+	{ IKEV1_AUTH_HMAC_SHA2_384,		AUTH_HMAC_SHA2_384_192 },
+	{ IKEV1_AUTH_HMAC_SHA2_512,		AUTH_HMAC_SHA2_512_256 },
+	{ IKEV1_AUTH_AES_XCBC_MAC,		AUTH_AES_XCBC_96 },
+	{ IKEV1_AUTH_AES_128_GMAC,		AUTH_AES_128_GMAC },
+	{ IKEV1_AUTH_AES_192_GMAC,		AUTH_AES_192_GMAC },
+	{ IKEV1_AUTH_AES_256_GMAC,		AUTH_AES_256_GMAC },
+};
+
+/**
+ * Map an IKEv1 to an IKEv2 identifier
+ */
+static u_int16_t ikev2_from_ikev1(algo_map_t *map, int count, u_int16_t def,
+								  u_int16_t value)
 {
-	algo_map_t *map;
-	u_int16_t def;
-	int i, count;
+	int i;
 
-	switch (type)
-	{
-		case ENCRYPTION_ALGORITHM:
-			map = map_encr;
-			count = countof(map_encr);
-			def = ENCR_UNDEFINED;
-			break;
-		case INTEGRITY_ALGORITHM:
-			map = map_integ;
-			count = countof(map_integ);
-			def = AUTH_UNDEFINED;
-			break;
-		case PSEUDO_RANDOM_FUNCTION:
-			map = map_prf;
-			count = countof(map_prf);
-			def = PRF_UNDEFINED;
-			break;
-		default:
-			return 0;
-	}
 	for (i = 0; i < count; i++)
 	{
 		if (map[i].ikev1 == value)
@@ -718,30 +697,12 @@ static u_int16_t get_alg_from_ikev1(transform_type_t type, u_int16_t value)
 }
 
 /**
- * Get IKEv1 algorithm from IKEv2 identifier
+ * Map an IKEv2 to an IKEv1 identifier
  */
-static u_int16_t get_ikev1_from_alg(transform_type_t type, u_int16_t value)
+static u_int16_t ikev1_from_ikev2(algo_map_t *map, int count, u_int16_t value)
 {
-	algo_map_t *map;
-	int i, count;
+	int i;
 
-	switch (type)
-	{
-		case ENCRYPTION_ALGORITHM:
-			map = map_encr;
-			count = countof(map_encr);
-			break;
-		case INTEGRITY_ALGORITHM:
-			map = map_integ;
-			count = countof(map_integ);
-			break;
-		case PSEUDO_RANDOM_FUNCTION:
-			map = map_prf;
-			count = countof(map_prf);
-			break;
-		default:
-			return 0;
-	}
 	for (i = 0; i < count; i++)
 	{
 		if (map[i].ikev2 == value)
@@ -753,87 +714,96 @@ static u_int16_t get_ikev1_from_alg(transform_type_t type, u_int16_t value)
 }
 
 /**
- * Get IKEv2 algorithm from IKEv1 ESP transaction ID
+ * Get IKEv2 algorithm from IKEv1 identifier
  */
-static u_int16_t get_alg_from_ikev1_transid(protocol_id_t proto,
-										transform_type_t type, u_int16_t value)
+static u_int16_t get_alg_from_ikev1(transform_type_t type, u_int16_t value)
 {
-	algo_map_t *map;
-	u_int16_t def;
-	int i, count;
-
 	switch (type)
 	{
 		case ENCRYPTION_ALGORITHM:
-			map = map_esp_encr;
-			count = countof(map_esp_encr);
-			def = ENCR_UNDEFINED;
-			break;
+			return ikev2_from_ikev1(map_encr, countof(map_encr),
+									ENCR_UNDEFINED, value);
 		case INTEGRITY_ALGORITHM:
-			if (proto == PROTO_ESP)
-			{
-				map = map_esp_auth;
-				count = countof(map_esp_auth);
-			}
-			else
-			{
-				map = map_ah;
-				count = countof(map_ah);
-			}
-			def = AUTH_UNDEFINED;
-			break;
+			return ikev2_from_ikev1(map_integ, countof(map_integ),
+									AUTH_UNDEFINED, value);
+		case PSEUDO_RANDOM_FUNCTION:
+			return ikev2_from_ikev1(map_prf, countof(map_prf),
+									PRF_UNDEFINED, value);
 		default:
 			return 0;
 	}
-	for (i = 0; i < count; i++)
+}
+
+/**
+ * Get IKEv1 algorithm from IKEv2 identifier
+ */
+static u_int16_t get_ikev1_from_alg(transform_type_t type, u_int16_t value)
+{
+	switch (type)
 	{
-		if (map[i].ikev1 == value)
-		{
-			return map[i].ikev2;
-		}
+		case ENCRYPTION_ALGORITHM:
+			return ikev1_from_ikev2(map_encr, countof(map_encr), value);
+		case INTEGRITY_ALGORITHM:
+			return ikev1_from_ikev2(map_integ, countof(map_integ), value);
+		case PSEUDO_RANDOM_FUNCTION:
+			return ikev1_from_ikev2(map_prf, countof(map_prf), value);
+		default:
+			return 0;
 	}
-	return def;
 }
 
 /**
- * Get IKEv1 ESP/AH transaction ID from IKEv2 identifier
+ * Get IKEv2 algorithm from IKEv1 ESP/AH transform ID
  */
-static u_int16_t get_ikev1_transid_from_alg(protocol_id_t proto,
-										transform_type_t type, u_int16_t value)
+static u_int16_t get_alg_from_ikev1_transid(transform_type_t type,
+											u_int16_t value)
 {
-	algo_map_t *map;
-	int i, count;
-
 	switch (type)
 	{
 		case ENCRYPTION_ALGORITHM:
-			map = map_esp_encr;
-			count = countof(map_esp_encr);
-			break;
+			return ikev2_from_ikev1(map_esp, countof(map_esp),
+									ENCR_UNDEFINED, value);
 		case INTEGRITY_ALGORITHM:
-			if (proto == PROTO_ESP)
-			{
-				map = map_esp_auth;
-				count = countof(map_esp_auth);
-			}
-			else
-			{
-				map = map_ah;
-				count = countof(map_ah);
-			}
-			break;
+			return ikev2_from_ikev1(map_ah, countof(map_ah),
+									AUTH_UNDEFINED, value);
 		default:
 			return 0;
 	}
-	for (i = 0; i < count; i++)
+}
+
+/**
+ * Get IKEv1 ESP/AH transform ID from IKEv2 identifier
+ */
+static u_int16_t get_ikev1_transid_from_alg(transform_type_t type,
+											u_int16_t value)
+{
+	switch (type)
 	{
-		if (map[i].ikev2 == value)
-		{
-			return map[i].ikev1;
-		}
+		case ENCRYPTION_ALGORITHM:
+			return ikev1_from_ikev2(map_esp, countof(map_esp), value);
+		case INTEGRITY_ALGORITHM:
+			return ikev1_from_ikev2(map_ah, countof(map_ah), value);
+		default:
+			return 0;
 	}
-	return 0;
 }
+
+/**
+ * Get IKEv1 authentication algorithm from IKEv2 identifier
+ */
+static u_int16_t get_alg_from_ikev1_auth(u_int16_t value)
+{
+	return ikev2_from_ikev1(map_auth, countof(map_auth), AUTH_UNDEFINED, value);
+}
+
+/**
+ * Get IKEv1 authentication algorithm from IKEv2 identifier
+ */
+static u_int16_t get_ikev1_auth_from_alg(u_int16_t value)
+{
+	return ikev1_from_ikev2(map_auth, countof(map_auth), value);
+}
+
 /**
  * Get IKEv1 authentication attribute from auth_method_t
  */
@@ -971,8 +941,7 @@ static void add_to_proposal_v1(proposal_t *proposal,
 				break;
 			case TATTR_PH2_AUTH_ALGORITHM:
 				proposal->add_algorithm(proposal, INTEGRITY_ALGORITHM,
-						get_alg_from_ikev1_transid(proto, INTEGRITY_ALGORITHM,
-												   value), 0);
+										get_alg_from_ikev1_auth(value), 0);
 				break;
 			case TATTR_PH2_GROUP:
 				proposal->add_algorithm(proposal, DIFFIE_HELLMAN_GROUP,
@@ -989,7 +958,7 @@ static void add_to_proposal_v1(proposal_t *proposal,
 							NO_EXT_SEQ_NUMBERS, 0);
 	if (proto == PROTO_ESP)
 	{
-		encr = get_alg_from_ikev1_transid(proto, ENCRYPTION_ALGORITHM,
+		encr = get_alg_from_ikev1_transid(ENCRYPTION_ALGORITHM,
 									transform->get_transform_id(transform));
 		if (encr)
 		{
@@ -1354,19 +1323,17 @@ static void set_from_proposal_v1(private_proposal_substructure_t *this,
 				ipsec_mode_t mode, encap_t udp, int number)
 {
 	transform_substructure_t *transform = NULL;
-	u_int16_t alg, key_size;
+	u_int16_t alg, transid, key_size;
 	enumerator_t *enumerator;
-	protocol_id_t proto;
 
-	proto = proposal->get_protocol(proposal);
 	enumerator = proposal->create_enumerator(proposal, ENCRYPTION_ALGORITHM);
 	if (enumerator->enumerate(enumerator, &alg, &key_size))
 	{
-		alg = get_ikev1_transid_from_alg(proto, ENCRYPTION_ALGORITHM, alg);
-		if (alg)
+		transid = get_ikev1_transid_from_alg(ENCRYPTION_ALGORITHM, alg);
+		if (transid)
 		{
 			transform = transform_substructure_create_type(
-									PLV1_TRANSFORM_SUBSTRUCTURE, number, alg);
+								PLV1_TRANSFORM_SUBSTRUCTURE, number, transid);
 			if (key_size)
 			{
 				transform->add_transform_attribute(transform,
@@ -1380,13 +1347,14 @@ 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))
 	{
-		alg = get_ikev1_transid_from_alg(proto, INTEGRITY_ALGORITHM, alg);
-		if (alg)
+		transid = get_ikev1_transid_from_alg(INTEGRITY_ALGORITHM, alg);
+		alg = get_ikev1_auth_from_alg(alg);
+		if (transid && alg)
 		{
 			if (!transform)
 			{
 				transform = transform_substructure_create_type(
-									PLV1_TRANSFORM_SUBSTRUCTURE, number, alg);
+								PLV1_TRANSFORM_SUBSTRUCTURE, number, transid);
 			}
 			transform->add_transform_attribute(transform,
 				transform_attribute_create_value(PLV1_TRANSFORM_ATTRIBUTE,
diff --git a/src/libcharon/kernel/kernel_handler.c b/src/libcharon/kernel/kernel_handler.c
index 059124e..9c0e260 100644
--- a/src/libcharon/kernel/kernel_handler.c
+++ b/src/libcharon/kernel/kernel_handler.c
@@ -72,36 +72,39 @@ METHOD(kernel_listener_t, acquire, bool,
 }
 
 METHOD(kernel_listener_t, expire, bool,
-	private_kernel_handler_t *this, u_int32_t reqid, u_int8_t protocol,
-	u_int32_t spi, bool hard)
+	private_kernel_handler_t *this, u_int8_t protocol, u_int32_t spi,
+	host_t *dst, bool hard)
 {
 	protocol_id_t proto = proto_ip2ike(protocol);
 
-	DBG1(DBG_KNL, "creating %s job for %N CHILD_SA with SPI %.8x and reqid {%u}",
-		 hard ? "delete" : "rekey", protocol_id_names, proto, ntohl(spi), reqid);
+	DBG1(DBG_KNL, "creating %s job for CHILD_SA %N/0x%08x/%H",
+		 hard ? "delete" : "rekey", protocol_id_names, proto, ntohl(spi), dst);
 
 	if (hard)
 	{
 		lib->processor->queue_job(lib->processor,
-				(job_t*)delete_child_sa_job_create(reqid, proto, spi, hard));
+				(job_t*)delete_child_sa_job_create(proto, spi, dst, hard));
 	}
 	else
 	{
 		lib->processor->queue_job(lib->processor,
-				(job_t*)rekey_child_sa_job_create(reqid, proto, spi));
+				(job_t*)rekey_child_sa_job_create(proto, spi, dst));
 	}
 	return TRUE;
 }
 
 METHOD(kernel_listener_t, mapping, bool,
-	private_kernel_handler_t *this, u_int32_t reqid, u_int32_t spi,
-	host_t *remote)
+	private_kernel_handler_t *this, u_int8_t protocol, u_int32_t spi,
+	host_t *dst, host_t *remote)
 {
-	DBG1(DBG_KNL, "NAT mappings of ESP CHILD_SA with SPI %.8x and reqid {%u} "
-		 "changed, queuing update job", ntohl(spi), reqid);
+	protocol_id_t proto = proto_ip2ike(protocol);
+
+	DBG1(DBG_KNL, "NAT mappings of CHILD_SA %N/0x%08x/%H changed to %#H, "
+		 "queuing update job", protocol_id_names, proto, ntohl(spi), dst,
+		 remote);
 
 	lib->processor->queue_job(lib->processor,
-							  (job_t*)update_sa_job_create(reqid, remote));
+						(job_t*)update_sa_job_create(proto, spi, dst, remote));
 	return TRUE;
 }
 
diff --git a/src/libcharon/plugins/addrblock/Makefile.in b/src/libcharon/plugins/addrblock/Makefile.in
index c3b014c..0554465 100644
--- a/src/libcharon/plugins/addrblock/Makefile.in
+++ b/src/libcharon/plugins/addrblock/Makefile.in
@@ -229,6 +229,7 @@ DLLIB = @DLLIB@
 DLLTOOL = @DLLTOOL@
 DSYMUTIL = @DSYMUTIL@
 DUMPBIN = @DUMPBIN@
+EASY_INSTALL = @EASY_INSTALL@
 ECHO_C = @ECHO_C@
 ECHO_N = @ECHO_N@
 ECHO_T = @ECHO_T@
@@ -289,10 +290,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
 PLUGIN_CFLAGS = @PLUGIN_CFLAGS@
 PTHREADLIB = @PTHREADLIB@
 PYTHON = @PYTHON@
+PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@
 PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
 PYTHON_PLATFORM = @PYTHON_PLATFORM@
 PYTHON_PREFIX = @PYTHON_PREFIX@
 PYTHON_VERSION = @PYTHON_VERSION@
+PY_TEST = @PY_TEST@
 RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
@@ -366,6 +369,8 @@ json_CFLAGS = @json_CFLAGS@
 json_LIBS = @json_LIBS@
 libdir = @libdir@
 libexecdir = @libexecdir@
+libiptc_CFLAGS = @libiptc_CFLAGS@
+libiptc_LIBS = @libiptc_LIBS@
 linux_headers = @linux_headers@
 localedir = @localedir@
 localstatedir = @localstatedir@
diff --git a/src/libcharon/plugins/android_dns/Makefile.in b/src/libcharon/plugins/android_dns/Makefile.in
index 50594a4..58cf97b 100644
--- a/src/libcharon/plugins/android_dns/Makefile.in
+++ b/src/libcharon/plugins/android_dns/Makefile.in
@@ -229,6 +229,7 @@ DLLIB = @DLLIB@
 DLLTOOL = @DLLTOOL@
 DSYMUTIL = @DSYMUTIL@
 DUMPBIN = @DUMPBIN@
+EASY_INSTALL = @EASY_INSTALL@
 ECHO_C = @ECHO_C@
 ECHO_N = @ECHO_N@
 ECHO_T = @ECHO_T@
@@ -289,10 +290,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
 PLUGIN_CFLAGS = @PLUGIN_CFLAGS@
 PTHREADLIB = @PTHREADLIB@
 PYTHON = @PYTHON@
+PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@
 PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
 PYTHON_PLATFORM = @PYTHON_PLATFORM@
 PYTHON_PREFIX = @PYTHON_PREFIX@
 PYTHON_VERSION = @PYTHON_VERSION@
+PY_TEST = @PY_TEST@
 RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
@@ -366,6 +369,8 @@ json_CFLAGS = @json_CFLAGS@
 json_LIBS = @json_LIBS@
 libdir = @libdir@
 libexecdir = @libexecdir@
+libiptc_CFLAGS = @libiptc_CFLAGS@
+libiptc_LIBS = @libiptc_LIBS@
 linux_headers = @linux_headers@
 localedir = @localedir@
 localstatedir = @localstatedir@
diff --git a/src/libcharon/plugins/android_dns/android_dns_handler.c b/src/libcharon/plugins/android_dns/android_dns_handler.c
index 5268103..160a145 100644
--- a/src/libcharon/plugins/android_dns/android_dns_handler.c
+++ b/src/libcharon/plugins/android_dns/android_dns_handler.c
@@ -128,7 +128,7 @@ static bool set_dns_server(private_android_dns_handler_t *this, int index,
 }
 
 METHOD(attribute_handler_t, handle, bool,
-	private_android_dns_handler_t *this, identification_t *id,
+	private_android_dns_handler_t *this, ike_sa_t *ike_sa,
 	configuration_attribute_type_t type, chunk_t data)
 {
 	switch (type)
@@ -158,7 +158,7 @@ METHOD(attribute_handler_t, handle, bool,
 }
 
 METHOD(attribute_handler_t, release, void,
-	private_android_dns_handler_t *this, identification_t *server,
+	private_android_dns_handler_t *this, ike_sa_t *ike_sa,
 	configuration_attribute_type_t type, chunk_t data)
 {
 	if (type == INTERNAL_IP4_DNS)
@@ -192,7 +192,7 @@ METHOD(enumerator_t, enumerate_dns, bool,
 }
 
 METHOD(attribute_handler_t, create_attribute_enumerator, enumerator_t *,
-	private_android_dns_handler_t *this, identification_t *id,
+	private_android_dns_handler_t *this, ike_sa_t *ike_sa,
 	linked_list_t *vips)
 {
 	enumerator_t *enumerator;
@@ -232,4 +232,3 @@ android_dns_handler_t *android_dns_handler_create()
 
 	return &this->public;
 }
-
diff --git a/src/libcharon/plugins/android_dns/android_dns_plugin.c b/src/libcharon/plugins/android_dns/android_dns_plugin.c
index b8eb11b..9b6ec0d 100644
--- a/src/libcharon/plugins/android_dns/android_dns_plugin.c
+++ b/src/libcharon/plugins/android_dns/android_dns_plugin.c
@@ -16,7 +16,6 @@
 #include "android_dns_plugin.h"
 #include "android_dns_handler.h"
 
-#include <hydra.h>
 #include <daemon.h>
 
 typedef struct private_android_dns_plugin_t private_android_dns_plugin_t;
@@ -51,13 +50,13 @@ static bool plugin_cb(private_android_dns_plugin_t *this,
 {
 	if (reg)
 	{
-		hydra->attributes->add_handler(hydra->attributes,
-									   &this->handler->handler);
+		charon->attributes->add_handler(charon->attributes,
+										&this->handler->handler);
 	}
 	else
 	{
-		hydra->attributes->remove_handler(hydra->attributes,
-										  &this->handler->handler);
+		charon->attributes->remove_handler(charon->attributes,
+										   &this->handler->handler);
 	}
 	return TRUE;
 }
diff --git a/src/libcharon/plugins/android_log/Makefile.in b/src/libcharon/plugins/android_log/Makefile.in
index 700a421..8ce92e5 100644
--- a/src/libcharon/plugins/android_log/Makefile.in
+++ b/src/libcharon/plugins/android_log/Makefile.in
@@ -229,6 +229,7 @@ DLLIB = @DLLIB@
 DLLTOOL = @DLLTOOL@
 DSYMUTIL = @DSYMUTIL@
 DUMPBIN = @DUMPBIN@
+EASY_INSTALL = @EASY_INSTALL@
 ECHO_C = @ECHO_C@
 ECHO_N = @ECHO_N@
 ECHO_T = @ECHO_T@
@@ -289,10 +290,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
 PLUGIN_CFLAGS = @PLUGIN_CFLAGS@
 PTHREADLIB = @PTHREADLIB@
 PYTHON = @PYTHON@
+PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@
 PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
 PYTHON_PLATFORM = @PYTHON_PLATFORM@
 PYTHON_PREFIX = @PYTHON_PREFIX@
 PYTHON_VERSION = @PYTHON_VERSION@
+PY_TEST = @PY_TEST@
 RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
@@ -366,6 +369,8 @@ json_CFLAGS = @json_CFLAGS@
 json_LIBS = @json_LIBS@
 libdir = @libdir@
 libexecdir = @libexecdir@
+libiptc_CFLAGS = @libiptc_CFLAGS@
+libiptc_LIBS = @libiptc_LIBS@
 linux_headers = @linux_headers@
 localedir = @localedir@
 localstatedir = @localstatedir@
diff --git a/src/libcharon/plugins/attr/Makefile.am b/src/libcharon/plugins/attr/Makefile.am
new file mode 100644
index 0000000..6bc7e77
--- /dev/null
+++ b/src/libcharon/plugins/attr/Makefile.am
@@ -0,0 +1,19 @@
+AM_CPPFLAGS = \
+	-I$(top_srcdir)/src/libstrongswan \
+	-I$(top_srcdir)/src/libhydra \
+	-I$(top_srcdir)/src/libcharon
+
+AM_CFLAGS = \
+	$(PLUGIN_CFLAGS)
+
+if MONOLITHIC
+noinst_LTLIBRARIES = libstrongswan-attr.la
+else
+plugin_LTLIBRARIES = libstrongswan-attr.la
+endif
+
+libstrongswan_attr_la_SOURCES = \
+	attr_plugin.h attr_plugin.c \
+	attr_provider.h attr_provider.c
+
+libstrongswan_attr_la_LDFLAGS = -module -avoid-version
diff --git a/src/libcharon/plugins/attr/Makefile.in b/src/libcharon/plugins/attr/Makefile.in
new file mode 100644
index 0000000..486b3c0
--- /dev/null
+++ b/src/libcharon/plugins/attr/Makefile.in
@@ -0,0 +1,777 @@
+# Makefile.in generated by automake 1.14.1 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994-2013 Free Software Foundation, Inc.
+
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+ at SET_MAKE@
+
+VPATH = @srcdir@
+am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)'
+am__make_running_with_option = \
+  case $${target_option-} in \
+      ?) ;; \
+      *) echo "am__make_running_with_option: internal error: invalid" \
+              "target option '$${target_option-}' specified" >&2; \
+         exit 1;; \
+  esac; \
+  has_opt=no; \
+  sane_makeflags=$$MAKEFLAGS; \
+  if $(am__is_gnu_make); then \
+    sane_makeflags=$$MFLAGS; \
+  else \
+    case $$MAKEFLAGS in \
+      *\\[\ \	]*) \
+        bs=\\; \
+        sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
+          | sed "s/$$bs$$bs[$$bs $$bs	]*//g"`;; \
+    esac; \
+  fi; \
+  skip_next=no; \
+  strip_trailopt () \
+  { \
+    flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
+  }; \
+  for flg in $$sane_makeflags; do \
+    test $$skip_next = yes && { skip_next=no; continue; }; \
+    case $$flg in \
+      *=*|--*) continue;; \
+        -*I) strip_trailopt 'I'; skip_next=yes;; \
+      -*I?*) strip_trailopt 'I';; \
+        -*O) strip_trailopt 'O'; skip_next=yes;; \
+      -*O?*) strip_trailopt 'O';; \
+        -*l) strip_trailopt 'l'; skip_next=yes;; \
+      -*l?*) strip_trailopt 'l';; \
+      -[dEDm]) skip_next=yes;; \
+      -[JT]) skip_next=yes;; \
+    esac; \
+    case $$flg in \
+      *$$target_option*) has_opt=yes; break;; \
+    esac; \
+  done; \
+  test $$has_opt = yes
+am__make_dryrun = (target_option=n; $(am__make_running_with_option))
+am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+subdir = src/libcharon/plugins/attr
+DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
+	$(top_srcdir)/depcomp
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/m4/config/libtool.m4 \
+	$(top_srcdir)/m4/config/ltoptions.m4 \
+	$(top_srcdir)/m4/config/ltsugar.m4 \
+	$(top_srcdir)/m4/config/ltversion.m4 \
+	$(top_srcdir)/m4/config/lt~obsolete.m4 \
+	$(top_srcdir)/m4/macros/split-package-version.m4 \
+	$(top_srcdir)/m4/macros/with.m4 \
+	$(top_srcdir)/m4/macros/enable-disable.m4 \
+	$(top_srcdir)/m4/macros/add-plugin.m4 \
+	$(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+	$(ACLOCAL_M4)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
+am__vpath_adj = case $$p in \
+    $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
+    *) f=$$p;; \
+  esac;
+am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
+am__install_max = 40
+am__nobase_strip_setup = \
+  srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
+am__nobase_strip = \
+  for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
+am__nobase_list = $(am__nobase_strip_setup); \
+  for p in $$list; do echo "$$p $$p"; done | \
+  sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
+  $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
+    if (++n[$$2] == $(am__install_max)) \
+      { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
+    END { for (dir in files) print dir, files[dir] }'
+am__base_list = \
+  sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
+  sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
+am__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; }; \
+  }
+am__installdirs = "$(DESTDIR)$(plugindir)"
+LTLIBRARIES = $(noinst_LTLIBRARIES) $(plugin_LTLIBRARIES)
+libstrongswan_attr_la_LIBADD =
+am_libstrongswan_attr_la_OBJECTS = attr_plugin.lo attr_provider.lo
+libstrongswan_attr_la_OBJECTS = $(am_libstrongswan_attr_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_attr_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \
+	$(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \
+	$(AM_CFLAGS) $(CFLAGS) $(libstrongswan_attr_la_LDFLAGS) \
+	$(LDFLAGS) -o $@
+ at MONOLITHIC_FALSE@am_libstrongswan_attr_la_rpath = -rpath $(plugindir)
+ at MONOLITHIC_TRUE@am_libstrongswan_attr_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
+am__v_P_1 = :
+AM_V_GEN = $(am__v_GEN_ at AM_V@)
+am__v_GEN_ = $(am__v_GEN_ at AM_DEFAULT_V@)
+am__v_GEN_0 = @echo "  GEN     " $@;
+am__v_GEN_1 = 
+AM_V_at = $(am__v_at_ at AM_V@)
+am__v_at_ = $(am__v_at_ at AM_DEFAULT_V@)
+am__v_at_0 = @
+am__v_at_1 = 
+DEFAULT_INCLUDES = -I. at am__isrc@ -I$(top_builddir)
+depcomp = $(SHELL) $(top_srcdir)/depcomp
+am__depfiles_maybe = depfiles
+am__mv = mv -f
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+	$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+	$(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \
+	$(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
+	$(AM_CFLAGS) $(CFLAGS)
+AM_V_CC = $(am__v_CC_ at AM_V@)
+am__v_CC_ = $(am__v_CC_ at AM_DEFAULT_V@)
+am__v_CC_0 = @echo "  CC      " $@;
+am__v_CC_1 = 
+CCLD = $(CC)
+LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+	$(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+	$(AM_LDFLAGS) $(LDFLAGS) -o $@
+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_attr_la_SOURCES)
+DIST_SOURCES = $(libstrongswan_attr_la_SOURCES)
+am__can_run_installinfo = \
+  case $$AM_UPDATE_INFO_DIR in \
+    n|no|NO) false;; \
+    *) (install-info --version) >/dev/null 2>&1;; \
+  esac
+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
+# *not* preserved.
+am__uniquify_input = $(AWK) '\
+  BEGIN { nonempty = 0; } \
+  { items[$$0] = 1; nonempty = 1; } \
+  END { if (nonempty) { for (i in items) print i; }; } \
+'
+# Make sure the list of sources is unique.  This is necessary because,
+# e.g., the same source file might be shared among _SOURCES variables
+# for different programs/libraries.
+am__define_uniq_tagged_files = \
+  list='$(am__tagged_files)'; \
+  unique=`for i in $$list; do \
+    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+  done | $(am__uniquify_input)`
+ETAGS = etags
+CTAGS = ctags
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+ALLOCA = @ALLOCA@
+AMTAR = @AMTAR@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+BFDLIB = @BFDLIB@
+BTLIB = @BTLIB@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+COVERAGE_CFLAGS = @COVERAGE_CFLAGS@
+COVERAGE_LDFLAGS = @COVERAGE_LDFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DLLIB = @DLLIB@
+DLLTOOL = @DLLTOOL@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+EASY_INSTALL = @EASY_INSTALL@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+FGREP = @FGREP@
+GEM = @GEM@
+GENHTML = @GENHTML@
+GPERF = @GPERF@
+GPRBUILD = @GPRBUILD@
+GREP = @GREP@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+LCOV = @LCOV@
+LD = @LD@
+LDFLAGS = @LDFLAGS@
+LEX = @LEX@
+LEXLIB = @LEXLIB@
+LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LIPO = @LIPO@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+MAKEINFO = @MAKEINFO@
+MANIFEST_TOOL = @MANIFEST_TOOL@
+MKDIR_P = @MKDIR_P@
+MYSQLCFLAG = @MYSQLCFLAG@
+MYSQLCONFIG = @MYSQLCONFIG@
+MYSQLLIB = @MYSQLLIB@
+NM = @NM@
+NMEDIT = @NMEDIT@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OPENSSL_LIB = @OPENSSL_LIB@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PACKAGE_VERSION_BUILD = @PACKAGE_VERSION_BUILD@
+PACKAGE_VERSION_MAJOR = @PACKAGE_VERSION_MAJOR@
+PACKAGE_VERSION_MINOR = @PACKAGE_VERSION_MINOR@
+PACKAGE_VERSION_REVIEW = @PACKAGE_VERSION_REVIEW@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PERL = @PERL@
+PKG_CONFIG = @PKG_CONFIG@
+PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
+PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
+PLUGIN_CFLAGS = @PLUGIN_CFLAGS@
+PTHREADLIB = @PTHREADLIB@
+PYTHON = @PYTHON@
+PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@
+PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
+PYTHON_PLATFORM = @PYTHON_PLATFORM@
+PYTHON_PREFIX = @PYTHON_PREFIX@
+PYTHON_VERSION = @PYTHON_VERSION@
+PY_TEST = @PY_TEST@
+RANLIB = @RANLIB@
+RTLIB = @RTLIB@
+RUBY = @RUBY@
+RUBYGEMDIR = @RUBYGEMDIR@
+RUBYINCLUDE = @RUBYINCLUDE@
+RUBYLIB = @RUBYLIB@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+SOCKLIB = @SOCKLIB@
+STRIP = @STRIP@
+UNWINDLIB = @UNWINDLIB@
+VERSION = @VERSION@
+YACC = @YACC@
+YFLAGS = @YFLAGS@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+aikgen_plugins = @aikgen_plugins@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+attest_plugins = @attest_plugins@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+c_plugins = @c_plugins@
+charon_natt_port = @charon_natt_port@
+charon_plugins = @charon_plugins@
+charon_udp_port = @charon_udp_port@
+clearsilver_LIBS = @clearsilver_LIBS@
+cmd_plugins = @cmd_plugins@
+datadir = @datadir@
+datarootdir = @datarootdir@
+dbusservicedir = @dbusservicedir@
+dev_headers = @dev_headers@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+fips_mode = @fips_mode@
+gtk_CFLAGS = @gtk_CFLAGS@
+gtk_LIBS = @gtk_LIBS@
+h_plugins = @h_plugins@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+imcvdir = @imcvdir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+ipsec_script = @ipsec_script@
+ipsec_script_upper = @ipsec_script_upper@
+ipsecdir = @ipsecdir@
+ipsecgroup = @ipsecgroup@
+ipseclibdir = @ipseclibdir@
+ipsecuser = @ipsecuser@
+json_CFLAGS = @json_CFLAGS@
+json_LIBS = @json_LIBS@
+libdir = @libdir@
+libexecdir = @libexecdir@
+libiptc_CFLAGS = @libiptc_CFLAGS@
+libiptc_LIBS = @libiptc_LIBS@
+linux_headers = @linux_headers@
+localedir = @localedir@
+localstatedir = @localstatedir@
+maemo_CFLAGS = @maemo_CFLAGS@
+maemo_LIBS = @maemo_LIBS@
+manager_plugins = @manager_plugins@
+mandir = @mandir@
+medsrv_plugins = @medsrv_plugins@
+mkdir_p = @mkdir_p@
+nm_CFLAGS = @nm_CFLAGS@
+nm_LIBS = @nm_LIBS@
+nm_ca_dir = @nm_ca_dir@
+nm_plugins = @nm_plugins@
+oldincludedir = @oldincludedir@
+pcsclite_CFLAGS = @pcsclite_CFLAGS@
+pcsclite_LIBS = @pcsclite_LIBS@
+pdfdir = @pdfdir@
+piddir = @piddir@
+pkgpyexecdir = @pkgpyexecdir@
+pkgpythondir = @pkgpythondir@
+pki_plugins = @pki_plugins@
+plugindir = @plugindir@
+pool_plugins = @pool_plugins@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+pyexecdir = @pyexecdir@
+pythondir = @pythondir@
+random_device = @random_device@
+resolv_conf = @resolv_conf@
+routing_table = @routing_table@
+routing_table_prio = @routing_table_prio@
+s_plugins = @s_plugins@
+sbindir = @sbindir@
+scepclient_plugins = @scepclient_plugins@
+scripts_plugins = @scripts_plugins@
+sharedstatedir = @sharedstatedir@
+soup_CFLAGS = @soup_CFLAGS@
+soup_LIBS = @soup_LIBS@
+srcdir = @srcdir@
+starter_plugins = @starter_plugins@
+strongswan_conf = @strongswan_conf@
+strongswan_options = @strongswan_options@
+swanctldir = @swanctldir@
+sysconfdir = @sysconfdir@
+systemd_daemon_CFLAGS = @systemd_daemon_CFLAGS@
+systemd_daemon_LIBS = @systemd_daemon_LIBS@
+systemd_journal_CFLAGS = @systemd_journal_CFLAGS@
+systemd_journal_LIBS = @systemd_journal_LIBS@
+systemdsystemunitdir = @systemdsystemunitdir@
+t_plugins = @t_plugins@
+target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+urandom_device = @urandom_device@
+xml_CFLAGS = @xml_CFLAGS@
+xml_LIBS = @xml_LIBS@
+AM_CPPFLAGS = \
+	-I$(top_srcdir)/src/libstrongswan \
+	-I$(top_srcdir)/src/libhydra \
+	-I$(top_srcdir)/src/libcharon
+
+AM_CFLAGS = \
+	$(PLUGIN_CFLAGS)
+
+ at MONOLITHIC_TRUE@noinst_LTLIBRARIES = libstrongswan-attr.la
+ at MONOLITHIC_FALSE@plugin_LTLIBRARIES = libstrongswan-attr.la
+libstrongswan_attr_la_SOURCES = \
+	attr_plugin.h attr_plugin.c \
+	attr_provider.h attr_provider.c
+
+libstrongswan_attr_la_LDFLAGS = -module -avoid-version
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .c .lo .o .obj
+$(srcdir)/Makefile.in:  $(srcdir)/Makefile.am  $(am__configure_deps)
+	@for dep in $?; do \
+	  case '$(am__configure_deps)' in \
+	    *$$dep*) \
+	      ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+	        && { if test -f $@; then exit 0; else break; fi; }; \
+	      exit 1;; \
+	  esac; \
+	done; \
+	echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/libcharon/plugins/attr/Makefile'; \
+	$(am__cd) $(top_srcdir) && \
+	  $(AUTOMAKE) --gnu src/libcharon/plugins/attr/Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+	@case '$?' in \
+	  *config.status*) \
+	    cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+	  *) \
+	    echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+	    cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+	esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure:  $(am__configure_deps)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4):  $(am__aclocal_m4_deps)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+
+clean-noinstLTLIBRARIES:
+	-test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES)
+	@list='$(noinst_LTLIBRARIES)'; \
+	locs=`for p in $$list; do echo $$p; done | \
+	      sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \
+	      sort -u`; \
+	test -z "$$locs" || { \
+	  echo rm -f $${locs}; \
+	  rm -f $${locs}; \
+	}
+
+install-pluginLTLIBRARIES: $(plugin_LTLIBRARIES)
+	@$(NORMAL_INSTALL)
+	@list='$(plugin_LTLIBRARIES)'; test -n "$(plugindir)" || list=; \
+	list2=; for p in $$list; do \
+	  if test -f $$p; then \
+	    list2="$$list2 $$p"; \
+	  else :; fi; \
+	done; \
+	test -z "$$list2" || { \
+	  echo " $(MKDIR_P) '$(DESTDIR)$(plugindir)'"; \
+	  $(MKDIR_P) "$(DESTDIR)$(plugindir)" || exit 1; \
+	  echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(plugindir)'"; \
+	  $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(plugindir)"; \
+	}
+
+uninstall-pluginLTLIBRARIES:
+	@$(NORMAL_UNINSTALL)
+	@list='$(plugin_LTLIBRARIES)'; test -n "$(plugindir)" || list=; \
+	for p in $$list; do \
+	  $(am__strip_dir) \
+	  echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(plugindir)/$$f'"; \
+	  $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(plugindir)/$$f"; \
+	done
+
+clean-pluginLTLIBRARIES:
+	-test -z "$(plugin_LTLIBRARIES)" || rm -f $(plugin_LTLIBRARIES)
+	@list='$(plugin_LTLIBRARIES)'; \
+	locs=`for p in $$list; do echo $$p; done | \
+	      sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \
+	      sort -u`; \
+	test -z "$$locs" || { \
+	  echo rm -f $${locs}; \
+	  rm -f $${locs}; \
+	}
+
+libstrongswan-attr.la: $(libstrongswan_attr_la_OBJECTS) $(libstrongswan_attr_la_DEPENDENCIES) $(EXTRA_libstrongswan_attr_la_DEPENDENCIES) 
+	$(AM_V_CCLD)$(libstrongswan_attr_la_LINK) $(am_libstrongswan_attr_la_rpath) $(libstrongswan_attr_la_OBJECTS) $(libstrongswan_attr_la_LIBADD) $(LIBS)
+
+mostlyclean-compile:
+	-rm -f *.$(OBJEXT)
+
+distclean-compile:
+	-rm -f *.tab.c
+
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/attr_plugin.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/attr_provider.Plo at am__quote@
+
+.c.o:
+ at am__fastdepCC_TRUE@	$(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\
+ at am__fastdepCC_TRUE@	$(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\
+ at am__fastdepCC_TRUE@	$(am__mv) $$depbase.Tpo $$depbase.Po
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(COMPILE) -c -o $@ $<
+
+.c.obj:
+ at am__fastdepCC_TRUE@	$(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\
+ at am__fastdepCC_TRUE@	$(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\
+ at am__fastdepCC_TRUE@	$(am__mv) $$depbase.Tpo $$depbase.Po
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
+
+.c.lo:
+ at am__fastdepCC_TRUE@	$(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\
+ at am__fastdepCC_TRUE@	$(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\
+ at am__fastdepCC_TRUE@	$(am__mv) $$depbase.Tpo $$depbase.Plo
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(LTCOMPILE) -c -o $@ $<
+
+mostlyclean-libtool:
+	-rm -f *.lo
+
+clean-libtool:
+	-rm -rf .libs _libs
+
+ID: $(am__tagged_files)
+	$(am__define_uniq_tagged_files); mkid -fID $$unique
+tags: tags-am
+TAGS: tags
+
+tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+	set x; \
+	here=`pwd`; \
+	$(am__define_uniq_tagged_files); \
+	shift; \
+	if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
+	  test -n "$$unique" || unique=$$empty_fix; \
+	  if test $$# -gt 0; then \
+	    $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+	      "$$@" $$unique; \
+	  else \
+	    $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+	      $$unique; \
+	  fi; \
+	fi
+ctags: ctags-am
+
+CTAGS: ctags
+ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+	$(am__define_uniq_tagged_files); \
+	test -z "$(CTAGS_ARGS)$$unique" \
+	  || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+	     $$unique
+
+GTAGS:
+	here=`$(am__cd) $(top_builddir) && pwd` \
+	  && $(am__cd) $(top_srcdir) \
+	  && gtags -i $(GTAGS_ARGS) "$$here"
+cscopelist: cscopelist-am
+
+cscopelist-am: $(am__tagged_files)
+	list='$(am__tagged_files)'; \
+	case "$(srcdir)" in \
+	  [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
+	  *) sdir=$(subdir)/$(srcdir) ;; \
+	esac; \
+	for i in $$list; do \
+	  if test -f "$$i"; then \
+	    echo "$(subdir)/$$i"; \
+	  else \
+	    echo "$$sdir/$$i"; \
+	  fi; \
+	done >> $(top_builddir)/cscope.files
+
+distclean-tags:
+	-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+distdir: $(DISTFILES)
+	@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+	topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+	list='$(DISTFILES)'; \
+	  dist_files=`for file in $$list; do echo $$file; done | \
+	  sed -e "s|^$$srcdirstrip/||;t" \
+	      -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+	case $$dist_files in \
+	  */*) $(MKDIR_P) `echo "$$dist_files" | \
+			   sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+			   sort -u` ;; \
+	esac; \
+	for file in $$dist_files; do \
+	  if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+	  if test -d $$d/$$file; then \
+	    dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+	    if test -d "$(distdir)/$$file"; then \
+	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+	    fi; \
+	    if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+	      cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+	    fi; \
+	    cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+	  else \
+	    test -f "$(distdir)/$$file" \
+	    || cp -p $$d/$$file "$(distdir)/$$file" \
+	    || exit 1; \
+	  fi; \
+	done
+check-am: all-am
+check: check-am
+all-am: Makefile $(LTLIBRARIES)
+installdirs:
+	for dir in "$(DESTDIR)$(plugindir)"; do \
+	  test -z "$$dir" || $(MKDIR_P) "$$dir"; \
+	done
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+	@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+	if test -z '$(STRIP)'; then \
+	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	      install; \
+	else \
+	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	    "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+	fi
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+	-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+	-test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+
+maintainer-clean-generic:
+	@echo "This command is intended for maintainers to use"
+	@echo "it deletes files that may require special tools to rebuild."
+clean: clean-am
+
+clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \
+	clean-pluginLTLIBRARIES mostlyclean-am
+
+distclean: distclean-am
+	-rm -rf ./$(DEPDIR)
+	-rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+	distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+html-am:
+
+info: info-am
+
+info-am:
+
+install-data-am: install-pluginLTLIBRARIES
+
+install-dvi: install-dvi-am
+
+install-dvi-am:
+
+install-exec-am:
+
+install-html: install-html-am
+
+install-html-am:
+
+install-info: install-info-am
+
+install-info-am:
+
+install-man:
+
+install-pdf: install-pdf-am
+
+install-pdf-am:
+
+install-ps: install-ps-am
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+	-rm -rf ./$(DEPDIR)
+	-rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic \
+	mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am: uninstall-pluginLTLIBRARIES
+
+.MAKE: install-am install-strip
+
+.PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \
+	clean-libtool clean-noinstLTLIBRARIES clean-pluginLTLIBRARIES \
+	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-man install-pdf \
+	install-pdf-am install-pluginLTLIBRARIES install-ps \
+	install-ps-am install-strip installcheck installcheck-am \
+	installdirs maintainer-clean maintainer-clean-generic \
+	mostlyclean mostlyclean-compile mostlyclean-generic \
+	mostlyclean-libtool pdf pdf-am ps ps-am tags tags-am uninstall \
+	uninstall-am uninstall-pluginLTLIBRARIES
+
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/src/libcharon/plugins/attr/attr_plugin.c b/src/libcharon/plugins/attr/attr_plugin.c
new file mode 100644
index 0000000..9b15c3c
--- /dev/null
+++ b/src/libcharon/plugins/attr/attr_plugin.c
@@ -0,0 +1,109 @@
+/*
+ * Copyright (C) 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.
+ */
+
+#include "attr_plugin.h"
+#include "attr_provider.h"
+
+#include <daemon.h>
+
+typedef struct private_attr_plugin_t private_attr_plugin_t;
+
+/**
+ * private data of attr plugin
+ */
+struct private_attr_plugin_t {
+
+	/**
+	 * implements plugin interface
+	 */
+	attr_plugin_t public;
+
+	/**
+	 * CFG attributes provider
+	 */
+	attr_provider_t *provider;
+};
+
+METHOD(plugin_t, get_name, char*,
+	private_attr_plugin_t *this)
+{
+	return "attr";
+}
+
+/**
+ * Register provider
+ */
+static bool plugin_cb(private_attr_plugin_t *this,
+					  plugin_feature_t *feature, bool reg, void *cb_data)
+{
+	if (reg)
+	{
+		charon->attributes->add_provider(charon->attributes,
+										 &this->provider->provider);
+	}
+	else
+	{
+		charon->attributes->remove_provider(charon->attributes,
+										    &this->provider->provider);
+	}
+	return TRUE;
+}
+
+METHOD(plugin_t, get_features, int,
+	private_attr_plugin_t *this, plugin_feature_t *features[])
+{
+	static plugin_feature_t f[] = {
+		PLUGIN_CALLBACK((plugin_feature_callback_t)plugin_cb, NULL),
+			PLUGIN_PROVIDE(CUSTOM, "attr"),
+	};
+	*features = f;
+	return countof(f);
+}
+
+METHOD(plugin_t, reload, bool,
+	private_attr_plugin_t *this)
+{
+	this->provider->reload(this->provider);
+	return TRUE;
+}
+
+METHOD(plugin_t, destroy, void,
+	private_attr_plugin_t *this)
+{
+	this->provider->destroy(this->provider);
+	free(this);
+}
+
+/*
+ * see header file
+ */
+plugin_t *attr_plugin_create()
+{
+	private_attr_plugin_t *this;
+
+	INIT(this,
+		.public = {
+			.plugin = {
+				.get_name = _get_name,
+				.get_features = _get_features,
+				.reload = _reload,
+				.destroy = _destroy,
+			},
+		},
+		.provider = attr_provider_create(),
+	);
+
+	return &this->public.plugin;
+}
diff --git a/src/libcharon/plugins/attr/attr_plugin.h b/src/libcharon/plugins/attr/attr_plugin.h
new file mode 100644
index 0000000..0c6eebf
--- /dev/null
+++ b/src/libcharon/plugins/attr/attr_plugin.h
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 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.
+ */
+
+/**
+ * @defgroup attr attr
+ * @ingroup cplugins
+ *
+ * @defgroup attr_plugin attr_plugin
+ * @{ @ingroup attr
+ */
+
+#ifndef ATTR_PLUGIN_H_
+#define ATTR_PLUGIN_H_
+
+#include <plugins/plugin.h>
+
+typedef struct attr_plugin_t attr_plugin_t;
+
+/**
+ * Plugin providing configuration attribute through strongswan.conf.
+ */
+struct attr_plugin_t {
+
+	/**
+	 * implements plugin interface
+	 */
+	plugin_t plugin;
+};
+
+#endif /** ATTR_PLUGIN_H_ @}*/
diff --git a/src/libcharon/plugins/attr/attr_provider.c b/src/libcharon/plugins/attr/attr_provider.c
new file mode 100644
index 0000000..cac0ae4
--- /dev/null
+++ b/src/libcharon/plugins/attr/attr_provider.c
@@ -0,0 +1,329 @@
+/*
+ * Copyright (C) 2010 Tobias Brunner
+ * Copyright (C) 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.
+ */
+
+#include "attr_provider.h"
+
+#include <time.h>
+
+#include <daemon.h>
+#include <utils/debug.h>
+#include <collections/linked_list.h>
+#include <threading/rwlock.h>
+
+#define SERVER_MAX		2
+
+typedef struct private_attr_provider_t private_attr_provider_t;
+typedef struct attribute_entry_t attribute_entry_t;
+
+/**
+ * private data of attr_provider
+ */
+struct private_attr_provider_t {
+
+	/**
+	 * public functions
+	 */
+	attr_provider_t public;
+
+	/**
+	 * List of attributes, attribute_entry_t
+	 */
+	linked_list_t *attributes;
+
+	/**
+	 * Lock for attribute list
+	 */
+	rwlock_t *lock;
+};
+
+struct attribute_entry_t {
+	/** type of attribute */
+	configuration_attribute_type_t type;
+	/** attribute value */
+	chunk_t value;
+};
+
+/**
+ * Destroy an entry
+ */
+static void attribute_destroy(attribute_entry_t *this)
+{
+	free(this->value.ptr);
+	free(this);
+}
+
+/**
+ * convert enumerator value from attribute_entry
+ */
+static bool attr_enum_filter(void *null, attribute_entry_t **in,
+			configuration_attribute_type_t *type, void* none, chunk_t *value)
+{
+	*type = (*in)->type;
+	*value = (*in)->value;
+	return TRUE;
+}
+
+METHOD(attribute_provider_t, create_attribute_enumerator, enumerator_t*,
+	private_attr_provider_t *this, linked_list_t *pools,
+	ike_sa_t *ike_sa, linked_list_t *vips)
+{
+	if (vips->get_count(vips))
+	{
+		this->lock->read_lock(this->lock);
+		return enumerator_create_filter(
+				this->attributes->create_enumerator(this->attributes),
+				(void*)attr_enum_filter, this->lock, (void*)this->lock->unlock);
+	}
+	return enumerator_create_empty();
+}
+
+METHOD(attr_provider_t, destroy, void,
+	private_attr_provider_t *this)
+{
+	this->attributes->destroy_function(this->attributes,
+									   (void*)attribute_destroy);
+	this->lock->destroy(this->lock);
+	free(this);
+}
+
+/**
+ * Add an attribute entry to the list
+ */
+static void add_legacy_entry(private_attr_provider_t *this, char *key, int nr,
+							 configuration_attribute_type_t type)
+{
+	attribute_entry_t *entry;
+	host_t *host;
+	char *str;
+
+	str = lib->settings->get_str(lib->settings, "%s.%s%d", NULL, lib->ns,
+								 key, nr);
+	if (str)
+	{
+		host = host_create_from_string(str, 0);
+		if (host)
+		{
+			entry = malloc_thing(attribute_entry_t);
+
+			if (host->get_family(host) == AF_INET6)
+			{
+				switch (type)
+				{
+					case INTERNAL_IP4_DNS:
+						type = INTERNAL_IP6_DNS;
+						break;
+					case INTERNAL_IP4_NBNS:
+						type = INTERNAL_IP6_NBNS;
+						break;
+					default:
+						break;
+				}
+			}
+			entry->type = type;
+			entry->value = chunk_clone(host->get_address(host));
+			host->destroy(host);
+			DBG2(DBG_CFG, "loaded legacy entry attribute %N: %#B",
+				 configuration_attribute_type_names, entry->type, &entry->value);
+			this->attributes->insert_last(this->attributes, entry);
+		}
+	}
+}
+
+/**
+ * Key to attribute type mappings, for v4 and v6 attributes
+ */
+typedef struct {
+	char *name;
+	configuration_attribute_type_t v4;
+	configuration_attribute_type_t v6;
+} attribute_type_key_t;
+
+static attribute_type_key_t keys[] = {
+	{"address",			INTERNAL_IP4_ADDRESS,	INTERNAL_IP6_ADDRESS},
+	{"dns",				INTERNAL_IP4_DNS,		INTERNAL_IP6_DNS},
+	{"nbns",			INTERNAL_IP4_NBNS,		INTERNAL_IP6_NBNS},
+	{"dhcp",			INTERNAL_IP4_DHCP,		INTERNAL_IP6_DHCP},
+	{"netmask",			INTERNAL_IP4_NETMASK,	INTERNAL_IP6_NETMASK},
+	{"server",			INTERNAL_IP4_SERVER,	INTERNAL_IP6_SERVER},
+	{"subnet",			INTERNAL_IP4_SUBNET,	INTERNAL_IP6_SUBNET},
+	{"split-include",	UNITY_SPLIT_INCLUDE,	UNITY_SPLIT_INCLUDE},
+	{"split-exclude",	UNITY_LOCAL_LAN,		UNITY_LOCAL_LAN},
+};
+
+/**
+ * Load (numerical) entries from the plugins.attr namespace
+ */
+static void load_entries(private_attr_provider_t *this)
+{
+	enumerator_t *enumerator, *tokens;
+	char *key, *value, *token;
+	int i;
+
+	for (i = 1; i <= SERVER_MAX; i++)
+	{
+		add_legacy_entry(this, "dns", i, INTERNAL_IP4_DNS);
+		add_legacy_entry(this, "nbns", i, INTERNAL_IP4_NBNS);
+	}
+
+	enumerator = lib->settings->create_key_value_enumerator(lib->settings,
+													"%s.plugins.attr", lib->ns);
+	while (enumerator->enumerate(enumerator, &key, &value))
+	{
+		configuration_attribute_type_t type;
+		attribute_type_key_t *mapped = NULL;
+		attribute_entry_t *entry;
+		chunk_t data;
+		host_t *host;
+		char *pos;
+		int i, mask = -1, family;
+
+		if (streq(key, "load"))
+		{
+			continue;
+		}
+		type = atoi(key);
+		if (!type)
+		{
+			for (i = 0; i < countof(keys); i++)
+			{
+				if (streq(key, keys[i].name))
+				{
+					mapped = &keys[i];
+					break;
+				}
+			}
+			if (!mapped)
+			{
+				DBG1(DBG_CFG, "mapping attribute type %s failed", key);
+				continue;
+			}
+		}
+		tokens = enumerator_create_token(value, ",", " ");
+		while (tokens->enumerate(tokens, &token))
+		{
+			pos = strchr(token, '/');
+			if (pos)
+			{
+				*(pos++) = '\0';
+				mask = atoi(pos);
+			}
+			host = host_create_from_string(token, 0);
+			if (!host)
+			{
+				if (mapped)
+				{
+					DBG1(DBG_CFG, "invalid host in key %s: %s", key, token);
+					continue;
+				}
+				/* store numeric attributes that are no IP addresses as strings */
+				data = chunk_clone(chunk_from_str(token));
+			}
+			else
+			{
+				family = host->get_family(host);
+				if (mask == -1)
+				{
+					data = chunk_clone(host->get_address(host));
+				}
+				else
+				{
+					if (family == AF_INET)
+					{	/* IPv4 attributes contain a subnet mask */
+						u_int32_t netmask = 0;
+
+						if (mask)
+						{	/* shifting u_int32_t by 32 or more is undefined */
+							mask = 32 - mask;
+							netmask = htonl((0xFFFFFFFF >> mask) << mask);
+						}
+						data = chunk_cat("cc", host->get_address(host),
+										 chunk_from_thing(netmask));
+					}
+					else
+					{	/* IPv6 addresses the prefix only */
+						data = chunk_cat("cc", host->get_address(host),
+										 chunk_from_chars(mask));
+					}
+				}
+				host->destroy(host);
+				if (mapped)
+				{
+					switch (family)
+					{
+						case AF_INET:
+							type = mapped->v4;
+							break;
+						case AF_INET6:
+							type = mapped->v6;
+							break;
+					}
+				}
+			}
+			INIT(entry,
+				.type = type,
+				.value = data,
+			);
+			DBG2(DBG_CFG, "loaded attribute %N: %#B",
+				 configuration_attribute_type_names, entry->type, &entry->value);
+			this->attributes->insert_last(this->attributes, entry);
+		}
+		tokens->destroy(tokens);
+	}
+	enumerator->destroy(enumerator);
+}
+
+METHOD(attr_provider_t, reload, void,
+	private_attr_provider_t *this)
+{
+	this->lock->write_lock(this->lock);
+
+	this->attributes->destroy_function(this->attributes, (void*)attribute_destroy);
+	this->attributes = linked_list_create();
+
+	load_entries(this);
+
+	DBG1(DBG_CFG, "loaded %d entr%s for attr plugin configuration",
+		 this->attributes->get_count(this->attributes),
+		 this->attributes->get_count(this->attributes) == 1 ? "y" : "ies");
+
+	this->lock->unlock(this->lock);
+}
+
+/*
+ * see header file
+ */
+attr_provider_t *attr_provider_create(database_t *db)
+{
+	private_attr_provider_t *this;
+
+	INIT(this,
+		.public = {
+			.provider = {
+				.acquire_address = (void*)return_null,
+				.release_address = (void*)return_false,
+				.create_attribute_enumerator = _create_attribute_enumerator,
+			},
+			.reload = _reload,
+			.destroy = _destroy,
+		},
+		.attributes = linked_list_create(),
+		.lock = rwlock_create(RWLOCK_TYPE_DEFAULT),
+	);
+
+	load_entries(this);
+
+	return &this->public;
+}
diff --git a/src/libhydra/plugins/attr/attr_provider.h b/src/libcharon/plugins/attr/attr_provider.h
similarity index 100%
rename from src/libhydra/plugins/attr/attr_provider.h
rename to src/libcharon/plugins/attr/attr_provider.h
diff --git a/src/libcharon/plugins/attr_sql/Makefile.am b/src/libcharon/plugins/attr_sql/Makefile.am
new file mode 100644
index 0000000..366c902
--- /dev/null
+++ b/src/libcharon/plugins/attr_sql/Makefile.am
@@ -0,0 +1,19 @@
+AM_CPPFLAGS = \
+	-I$(top_srcdir)/src/libstrongswan \
+	-I$(top_srcdir)/src/libhydra \
+	-I$(top_srcdir)/src/libcharon
+
+AM_CFLAGS = \
+	$(PLUGIN_CFLAGS)
+
+if MONOLITHIC
+noinst_LTLIBRARIES = libstrongswan-attr-sql.la
+else
+plugin_LTLIBRARIES = libstrongswan-attr-sql.la
+endif
+
+libstrongswan_attr_sql_la_SOURCES = \
+	attr_sql_plugin.h attr_sql_plugin.c \
+	attr_sql_provider.h attr_sql_provider.c
+
+libstrongswan_attr_sql_la_LDFLAGS = -module -avoid-version
diff --git a/src/libcharon/plugins/attr_sql/Makefile.in b/src/libcharon/plugins/attr_sql/Makefile.in
new file mode 100644
index 0000000..8f1b3c0
--- /dev/null
+++ b/src/libcharon/plugins/attr_sql/Makefile.in
@@ -0,0 +1,780 @@
+# Makefile.in generated by automake 1.14.1 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994-2013 Free Software Foundation, Inc.
+
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+ at SET_MAKE@
+
+VPATH = @srcdir@
+am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)'
+am__make_running_with_option = \
+  case $${target_option-} in \
+      ?) ;; \
+      *) echo "am__make_running_with_option: internal error: invalid" \
+              "target option '$${target_option-}' specified" >&2; \
+         exit 1;; \
+  esac; \
+  has_opt=no; \
+  sane_makeflags=$$MAKEFLAGS; \
+  if $(am__is_gnu_make); then \
+    sane_makeflags=$$MFLAGS; \
+  else \
+    case $$MAKEFLAGS in \
+      *\\[\ \	]*) \
+        bs=\\; \
+        sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
+          | sed "s/$$bs$$bs[$$bs $$bs	]*//g"`;; \
+    esac; \
+  fi; \
+  skip_next=no; \
+  strip_trailopt () \
+  { \
+    flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
+  }; \
+  for flg in $$sane_makeflags; do \
+    test $$skip_next = yes && { skip_next=no; continue; }; \
+    case $$flg in \
+      *=*|--*) continue;; \
+        -*I) strip_trailopt 'I'; skip_next=yes;; \
+      -*I?*) strip_trailopt 'I';; \
+        -*O) strip_trailopt 'O'; skip_next=yes;; \
+      -*O?*) strip_trailopt 'O';; \
+        -*l) strip_trailopt 'l'; skip_next=yes;; \
+      -*l?*) strip_trailopt 'l';; \
+      -[dEDm]) skip_next=yes;; \
+      -[JT]) skip_next=yes;; \
+    esac; \
+    case $$flg in \
+      *$$target_option*) has_opt=yes; break;; \
+    esac; \
+  done; \
+  test $$has_opt = yes
+am__make_dryrun = (target_option=n; $(am__make_running_with_option))
+am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+subdir = src/libcharon/plugins/attr_sql
+DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
+	$(top_srcdir)/depcomp
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/m4/config/libtool.m4 \
+	$(top_srcdir)/m4/config/ltoptions.m4 \
+	$(top_srcdir)/m4/config/ltsugar.m4 \
+	$(top_srcdir)/m4/config/ltversion.m4 \
+	$(top_srcdir)/m4/config/lt~obsolete.m4 \
+	$(top_srcdir)/m4/macros/split-package-version.m4 \
+	$(top_srcdir)/m4/macros/with.m4 \
+	$(top_srcdir)/m4/macros/enable-disable.m4 \
+	$(top_srcdir)/m4/macros/add-plugin.m4 \
+	$(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+	$(ACLOCAL_M4)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
+am__vpath_adj = case $$p in \
+    $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
+    *) f=$$p;; \
+  esac;
+am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
+am__install_max = 40
+am__nobase_strip_setup = \
+  srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
+am__nobase_strip = \
+  for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
+am__nobase_list = $(am__nobase_strip_setup); \
+  for p in $$list; do echo "$$p $$p"; done | \
+  sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
+  $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
+    if (++n[$$2] == $(am__install_max)) \
+      { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
+    END { for (dir in files) print dir, files[dir] }'
+am__base_list = \
+  sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
+  sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
+am__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; }; \
+  }
+am__installdirs = "$(DESTDIR)$(plugindir)"
+LTLIBRARIES = $(noinst_LTLIBRARIES) $(plugin_LTLIBRARIES)
+libstrongswan_attr_sql_la_LIBADD =
+am_libstrongswan_attr_sql_la_OBJECTS = attr_sql_plugin.lo \
+	attr_sql_provider.lo
+libstrongswan_attr_sql_la_OBJECTS =  \
+	$(am_libstrongswan_attr_sql_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_attr_sql_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \
+	$(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \
+	$(AM_CFLAGS) $(CFLAGS) $(libstrongswan_attr_sql_la_LDFLAGS) \
+	$(LDFLAGS) -o $@
+ at MONOLITHIC_FALSE@am_libstrongswan_attr_sql_la_rpath = -rpath \
+ at MONOLITHIC_FALSE@	$(plugindir)
+ at MONOLITHIC_TRUE@am_libstrongswan_attr_sql_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
+am__v_P_1 = :
+AM_V_GEN = $(am__v_GEN_ at AM_V@)
+am__v_GEN_ = $(am__v_GEN_ at AM_DEFAULT_V@)
+am__v_GEN_0 = @echo "  GEN     " $@;
+am__v_GEN_1 = 
+AM_V_at = $(am__v_at_ at AM_V@)
+am__v_at_ = $(am__v_at_ at AM_DEFAULT_V@)
+am__v_at_0 = @
+am__v_at_1 = 
+DEFAULT_INCLUDES = -I. at am__isrc@ -I$(top_builddir)
+depcomp = $(SHELL) $(top_srcdir)/depcomp
+am__depfiles_maybe = depfiles
+am__mv = mv -f
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+	$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+	$(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \
+	$(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
+	$(AM_CFLAGS) $(CFLAGS)
+AM_V_CC = $(am__v_CC_ at AM_V@)
+am__v_CC_ = $(am__v_CC_ at AM_DEFAULT_V@)
+am__v_CC_0 = @echo "  CC      " $@;
+am__v_CC_1 = 
+CCLD = $(CC)
+LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+	$(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+	$(AM_LDFLAGS) $(LDFLAGS) -o $@
+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_attr_sql_la_SOURCES)
+DIST_SOURCES = $(libstrongswan_attr_sql_la_SOURCES)
+am__can_run_installinfo = \
+  case $$AM_UPDATE_INFO_DIR in \
+    n|no|NO) false;; \
+    *) (install-info --version) >/dev/null 2>&1;; \
+  esac
+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
+# *not* preserved.
+am__uniquify_input = $(AWK) '\
+  BEGIN { nonempty = 0; } \
+  { items[$$0] = 1; nonempty = 1; } \
+  END { if (nonempty) { for (i in items) print i; }; } \
+'
+# Make sure the list of sources is unique.  This is necessary because,
+# e.g., the same source file might be shared among _SOURCES variables
+# for different programs/libraries.
+am__define_uniq_tagged_files = \
+  list='$(am__tagged_files)'; \
+  unique=`for i in $$list; do \
+    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+  done | $(am__uniquify_input)`
+ETAGS = etags
+CTAGS = ctags
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+ALLOCA = @ALLOCA@
+AMTAR = @AMTAR@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+BFDLIB = @BFDLIB@
+BTLIB = @BTLIB@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+COVERAGE_CFLAGS = @COVERAGE_CFLAGS@
+COVERAGE_LDFLAGS = @COVERAGE_LDFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DLLIB = @DLLIB@
+DLLTOOL = @DLLTOOL@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+EASY_INSTALL = @EASY_INSTALL@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+FGREP = @FGREP@
+GEM = @GEM@
+GENHTML = @GENHTML@
+GPERF = @GPERF@
+GPRBUILD = @GPRBUILD@
+GREP = @GREP@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+LCOV = @LCOV@
+LD = @LD@
+LDFLAGS = @LDFLAGS@
+LEX = @LEX@
+LEXLIB = @LEXLIB@
+LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LIPO = @LIPO@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+MAKEINFO = @MAKEINFO@
+MANIFEST_TOOL = @MANIFEST_TOOL@
+MKDIR_P = @MKDIR_P@
+MYSQLCFLAG = @MYSQLCFLAG@
+MYSQLCONFIG = @MYSQLCONFIG@
+MYSQLLIB = @MYSQLLIB@
+NM = @NM@
+NMEDIT = @NMEDIT@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OPENSSL_LIB = @OPENSSL_LIB@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PACKAGE_VERSION_BUILD = @PACKAGE_VERSION_BUILD@
+PACKAGE_VERSION_MAJOR = @PACKAGE_VERSION_MAJOR@
+PACKAGE_VERSION_MINOR = @PACKAGE_VERSION_MINOR@
+PACKAGE_VERSION_REVIEW = @PACKAGE_VERSION_REVIEW@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PERL = @PERL@
+PKG_CONFIG = @PKG_CONFIG@
+PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
+PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
+PLUGIN_CFLAGS = @PLUGIN_CFLAGS@
+PTHREADLIB = @PTHREADLIB@
+PYTHON = @PYTHON@
+PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@
+PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
+PYTHON_PLATFORM = @PYTHON_PLATFORM@
+PYTHON_PREFIX = @PYTHON_PREFIX@
+PYTHON_VERSION = @PYTHON_VERSION@
+PY_TEST = @PY_TEST@
+RANLIB = @RANLIB@
+RTLIB = @RTLIB@
+RUBY = @RUBY@
+RUBYGEMDIR = @RUBYGEMDIR@
+RUBYINCLUDE = @RUBYINCLUDE@
+RUBYLIB = @RUBYLIB@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+SOCKLIB = @SOCKLIB@
+STRIP = @STRIP@
+UNWINDLIB = @UNWINDLIB@
+VERSION = @VERSION@
+YACC = @YACC@
+YFLAGS = @YFLAGS@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+aikgen_plugins = @aikgen_plugins@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+attest_plugins = @attest_plugins@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+c_plugins = @c_plugins@
+charon_natt_port = @charon_natt_port@
+charon_plugins = @charon_plugins@
+charon_udp_port = @charon_udp_port@
+clearsilver_LIBS = @clearsilver_LIBS@
+cmd_plugins = @cmd_plugins@
+datadir = @datadir@
+datarootdir = @datarootdir@
+dbusservicedir = @dbusservicedir@
+dev_headers = @dev_headers@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+fips_mode = @fips_mode@
+gtk_CFLAGS = @gtk_CFLAGS@
+gtk_LIBS = @gtk_LIBS@
+h_plugins = @h_plugins@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+imcvdir = @imcvdir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+ipsec_script = @ipsec_script@
+ipsec_script_upper = @ipsec_script_upper@
+ipsecdir = @ipsecdir@
+ipsecgroup = @ipsecgroup@
+ipseclibdir = @ipseclibdir@
+ipsecuser = @ipsecuser@
+json_CFLAGS = @json_CFLAGS@
+json_LIBS = @json_LIBS@
+libdir = @libdir@
+libexecdir = @libexecdir@
+libiptc_CFLAGS = @libiptc_CFLAGS@
+libiptc_LIBS = @libiptc_LIBS@
+linux_headers = @linux_headers@
+localedir = @localedir@
+localstatedir = @localstatedir@
+maemo_CFLAGS = @maemo_CFLAGS@
+maemo_LIBS = @maemo_LIBS@
+manager_plugins = @manager_plugins@
+mandir = @mandir@
+medsrv_plugins = @medsrv_plugins@
+mkdir_p = @mkdir_p@
+nm_CFLAGS = @nm_CFLAGS@
+nm_LIBS = @nm_LIBS@
+nm_ca_dir = @nm_ca_dir@
+nm_plugins = @nm_plugins@
+oldincludedir = @oldincludedir@
+pcsclite_CFLAGS = @pcsclite_CFLAGS@
+pcsclite_LIBS = @pcsclite_LIBS@
+pdfdir = @pdfdir@
+piddir = @piddir@
+pkgpyexecdir = @pkgpyexecdir@
+pkgpythondir = @pkgpythondir@
+pki_plugins = @pki_plugins@
+plugindir = @plugindir@
+pool_plugins = @pool_plugins@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+pyexecdir = @pyexecdir@
+pythondir = @pythondir@
+random_device = @random_device@
+resolv_conf = @resolv_conf@
+routing_table = @routing_table@
+routing_table_prio = @routing_table_prio@
+s_plugins = @s_plugins@
+sbindir = @sbindir@
+scepclient_plugins = @scepclient_plugins@
+scripts_plugins = @scripts_plugins@
+sharedstatedir = @sharedstatedir@
+soup_CFLAGS = @soup_CFLAGS@
+soup_LIBS = @soup_LIBS@
+srcdir = @srcdir@
+starter_plugins = @starter_plugins@
+strongswan_conf = @strongswan_conf@
+strongswan_options = @strongswan_options@
+swanctldir = @swanctldir@
+sysconfdir = @sysconfdir@
+systemd_daemon_CFLAGS = @systemd_daemon_CFLAGS@
+systemd_daemon_LIBS = @systemd_daemon_LIBS@
+systemd_journal_CFLAGS = @systemd_journal_CFLAGS@
+systemd_journal_LIBS = @systemd_journal_LIBS@
+systemdsystemunitdir = @systemdsystemunitdir@
+t_plugins = @t_plugins@
+target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+urandom_device = @urandom_device@
+xml_CFLAGS = @xml_CFLAGS@
+xml_LIBS = @xml_LIBS@
+AM_CPPFLAGS = \
+	-I$(top_srcdir)/src/libstrongswan \
+	-I$(top_srcdir)/src/libhydra \
+	-I$(top_srcdir)/src/libcharon
+
+AM_CFLAGS = \
+	$(PLUGIN_CFLAGS)
+
+ at MONOLITHIC_TRUE@noinst_LTLIBRARIES = libstrongswan-attr-sql.la
+ at MONOLITHIC_FALSE@plugin_LTLIBRARIES = libstrongswan-attr-sql.la
+libstrongswan_attr_sql_la_SOURCES = \
+	attr_sql_plugin.h attr_sql_plugin.c \
+	attr_sql_provider.h attr_sql_provider.c
+
+libstrongswan_attr_sql_la_LDFLAGS = -module -avoid-version
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .c .lo .o .obj
+$(srcdir)/Makefile.in:  $(srcdir)/Makefile.am  $(am__configure_deps)
+	@for dep in $?; do \
+	  case '$(am__configure_deps)' in \
+	    *$$dep*) \
+	      ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+	        && { if test -f $@; then exit 0; else break; fi; }; \
+	      exit 1;; \
+	  esac; \
+	done; \
+	echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/libcharon/plugins/attr_sql/Makefile'; \
+	$(am__cd) $(top_srcdir) && \
+	  $(AUTOMAKE) --gnu src/libcharon/plugins/attr_sql/Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+	@case '$?' in \
+	  *config.status*) \
+	    cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+	  *) \
+	    echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+	    cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+	esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure:  $(am__configure_deps)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4):  $(am__aclocal_m4_deps)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+
+clean-noinstLTLIBRARIES:
+	-test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES)
+	@list='$(noinst_LTLIBRARIES)'; \
+	locs=`for p in $$list; do echo $$p; done | \
+	      sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \
+	      sort -u`; \
+	test -z "$$locs" || { \
+	  echo rm -f $${locs}; \
+	  rm -f $${locs}; \
+	}
+
+install-pluginLTLIBRARIES: $(plugin_LTLIBRARIES)
+	@$(NORMAL_INSTALL)
+	@list='$(plugin_LTLIBRARIES)'; test -n "$(plugindir)" || list=; \
+	list2=; for p in $$list; do \
+	  if test -f $$p; then \
+	    list2="$$list2 $$p"; \
+	  else :; fi; \
+	done; \
+	test -z "$$list2" || { \
+	  echo " $(MKDIR_P) '$(DESTDIR)$(plugindir)'"; \
+	  $(MKDIR_P) "$(DESTDIR)$(plugindir)" || exit 1; \
+	  echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(plugindir)'"; \
+	  $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(plugindir)"; \
+	}
+
+uninstall-pluginLTLIBRARIES:
+	@$(NORMAL_UNINSTALL)
+	@list='$(plugin_LTLIBRARIES)'; test -n "$(plugindir)" || list=; \
+	for p in $$list; do \
+	  $(am__strip_dir) \
+	  echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(plugindir)/$$f'"; \
+	  $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(plugindir)/$$f"; \
+	done
+
+clean-pluginLTLIBRARIES:
+	-test -z "$(plugin_LTLIBRARIES)" || rm -f $(plugin_LTLIBRARIES)
+	@list='$(plugin_LTLIBRARIES)'; \
+	locs=`for p in $$list; do echo $$p; done | \
+	      sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \
+	      sort -u`; \
+	test -z "$$locs" || { \
+	  echo rm -f $${locs}; \
+	  rm -f $${locs}; \
+	}
+
+libstrongswan-attr-sql.la: $(libstrongswan_attr_sql_la_OBJECTS) $(libstrongswan_attr_sql_la_DEPENDENCIES) $(EXTRA_libstrongswan_attr_sql_la_DEPENDENCIES) 
+	$(AM_V_CCLD)$(libstrongswan_attr_sql_la_LINK) $(am_libstrongswan_attr_sql_la_rpath) $(libstrongswan_attr_sql_la_OBJECTS) $(libstrongswan_attr_sql_la_LIBADD) $(LIBS)
+
+mostlyclean-compile:
+	-rm -f *.$(OBJEXT)
+
+distclean-compile:
+	-rm -f *.tab.c
+
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/attr_sql_plugin.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/attr_sql_provider.Plo at am__quote@
+
+.c.o:
+ at am__fastdepCC_TRUE@	$(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\
+ at am__fastdepCC_TRUE@	$(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\
+ at am__fastdepCC_TRUE@	$(am__mv) $$depbase.Tpo $$depbase.Po
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(COMPILE) -c -o $@ $<
+
+.c.obj:
+ at am__fastdepCC_TRUE@	$(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\
+ at am__fastdepCC_TRUE@	$(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\
+ at am__fastdepCC_TRUE@	$(am__mv) $$depbase.Tpo $$depbase.Po
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
+
+.c.lo:
+ at am__fastdepCC_TRUE@	$(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\
+ at am__fastdepCC_TRUE@	$(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\
+ at am__fastdepCC_TRUE@	$(am__mv) $$depbase.Tpo $$depbase.Plo
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(LTCOMPILE) -c -o $@ $<
+
+mostlyclean-libtool:
+	-rm -f *.lo
+
+clean-libtool:
+	-rm -rf .libs _libs
+
+ID: $(am__tagged_files)
+	$(am__define_uniq_tagged_files); mkid -fID $$unique
+tags: tags-am
+TAGS: tags
+
+tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+	set x; \
+	here=`pwd`; \
+	$(am__define_uniq_tagged_files); \
+	shift; \
+	if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
+	  test -n "$$unique" || unique=$$empty_fix; \
+	  if test $$# -gt 0; then \
+	    $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+	      "$$@" $$unique; \
+	  else \
+	    $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+	      $$unique; \
+	  fi; \
+	fi
+ctags: ctags-am
+
+CTAGS: ctags
+ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+	$(am__define_uniq_tagged_files); \
+	test -z "$(CTAGS_ARGS)$$unique" \
+	  || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+	     $$unique
+
+GTAGS:
+	here=`$(am__cd) $(top_builddir) && pwd` \
+	  && $(am__cd) $(top_srcdir) \
+	  && gtags -i $(GTAGS_ARGS) "$$here"
+cscopelist: cscopelist-am
+
+cscopelist-am: $(am__tagged_files)
+	list='$(am__tagged_files)'; \
+	case "$(srcdir)" in \
+	  [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
+	  *) sdir=$(subdir)/$(srcdir) ;; \
+	esac; \
+	for i in $$list; do \
+	  if test -f "$$i"; then \
+	    echo "$(subdir)/$$i"; \
+	  else \
+	    echo "$$sdir/$$i"; \
+	  fi; \
+	done >> $(top_builddir)/cscope.files
+
+distclean-tags:
+	-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+distdir: $(DISTFILES)
+	@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+	topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+	list='$(DISTFILES)'; \
+	  dist_files=`for file in $$list; do echo $$file; done | \
+	  sed -e "s|^$$srcdirstrip/||;t" \
+	      -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+	case $$dist_files in \
+	  */*) $(MKDIR_P) `echo "$$dist_files" | \
+			   sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+			   sort -u` ;; \
+	esac; \
+	for file in $$dist_files; do \
+	  if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+	  if test -d $$d/$$file; then \
+	    dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+	    if test -d "$(distdir)/$$file"; then \
+	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+	    fi; \
+	    if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+	      cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+	    fi; \
+	    cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+	  else \
+	    test -f "$(distdir)/$$file" \
+	    || cp -p $$d/$$file "$(distdir)/$$file" \
+	    || exit 1; \
+	  fi; \
+	done
+check-am: all-am
+check: check-am
+all-am: Makefile $(LTLIBRARIES)
+installdirs:
+	for dir in "$(DESTDIR)$(plugindir)"; do \
+	  test -z "$$dir" || $(MKDIR_P) "$$dir"; \
+	done
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+	@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+	if test -z '$(STRIP)'; then \
+	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	      install; \
+	else \
+	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	    "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+	fi
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+	-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+	-test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+
+maintainer-clean-generic:
+	@echo "This command is intended for maintainers to use"
+	@echo "it deletes files that may require special tools to rebuild."
+clean: clean-am
+
+clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \
+	clean-pluginLTLIBRARIES mostlyclean-am
+
+distclean: distclean-am
+	-rm -rf ./$(DEPDIR)
+	-rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+	distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+html-am:
+
+info: info-am
+
+info-am:
+
+install-data-am: install-pluginLTLIBRARIES
+
+install-dvi: install-dvi-am
+
+install-dvi-am:
+
+install-exec-am:
+
+install-html: install-html-am
+
+install-html-am:
+
+install-info: install-info-am
+
+install-info-am:
+
+install-man:
+
+install-pdf: install-pdf-am
+
+install-pdf-am:
+
+install-ps: install-ps-am
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+	-rm -rf ./$(DEPDIR)
+	-rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic \
+	mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am: uninstall-pluginLTLIBRARIES
+
+.MAKE: install-am install-strip
+
+.PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \
+	clean-libtool clean-noinstLTLIBRARIES clean-pluginLTLIBRARIES \
+	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-man install-pdf \
+	install-pdf-am install-pluginLTLIBRARIES install-ps \
+	install-ps-am install-strip installcheck installcheck-am \
+	installdirs maintainer-clean maintainer-clean-generic \
+	mostlyclean mostlyclean-compile mostlyclean-generic \
+	mostlyclean-libtool pdf pdf-am ps ps-am tags tags-am uninstall \
+	uninstall-am uninstall-pluginLTLIBRARIES
+
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/src/libcharon/plugins/attr_sql/attr_sql_plugin.c b/src/libcharon/plugins/attr_sql/attr_sql_plugin.c
new file mode 100644
index 0000000..9088775
--- /dev/null
+++ b/src/libcharon/plugins/attr_sql/attr_sql_plugin.c
@@ -0,0 +1,129 @@
+/*
+ * Copyright (C) 2013 Tobias Brunner
+ * Copyright (C) 2008 Martin Willi
+ * Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * for more details.
+ */
+
+#include <daemon.h>
+#include <utils/debug.h>
+#include <plugins/plugin_feature.h>
+
+#include "attr_sql_plugin.h"
+#include "attr_sql_provider.h"
+
+typedef struct private_attr_sql_plugin_t private_attr_sql_plugin_t;
+
+/**
+ * private data of attr_sql plugin
+ */
+struct private_attr_sql_plugin_t {
+
+	/**
+	 * implements plugin interface
+	 */
+	attr_sql_plugin_t public;
+
+	/**
+	 * database connection instance
+	 */
+	database_t *db;
+
+	/**
+	 * configuration attributes
+	 */
+	attr_sql_provider_t *attribute;
+};
+
+METHOD(plugin_t, get_name, char*,
+	private_attr_sql_plugin_t *this)
+{
+	return "attr-sql";
+}
+
+/**
+ * Connect to database
+ */
+static bool open_database(private_attr_sql_plugin_t *this,
+						  plugin_feature_t *feature, bool reg, void *cb_data)
+{
+	if (reg)
+	{
+		char *uri;
+
+		uri = lib->settings->get_str(lib->settings,
+								"%s.plugins.attr-sql.database", NULL, lib->ns);
+		if (!uri)
+		{
+			DBG1(DBG_CFG, "attr-sql plugin: database URI not set");
+			return FALSE;
+		}
+
+		this->db = lib->db->create(lib->db, uri);
+		if (!this->db)
+		{
+			DBG1(DBG_CFG, "attr-sql plugin failed to connect to database");
+			return FALSE;
+		}
+		this->attribute = attr_sql_provider_create(this->db);
+		charon->attributes->add_provider(charon->attributes,
+										 &this->attribute->provider);
+	}
+	else
+	{
+		charon->attributes->remove_provider(charon->attributes,
+											&this->attribute->provider);
+		this->attribute->destroy(this->attribute);
+		this->db->destroy(this->db);
+	}
+	return TRUE;
+}
+
+METHOD(plugin_t, get_features, int,
+	private_attr_sql_plugin_t *this, plugin_feature_t *features[])
+{
+	static plugin_feature_t f[] = {
+		PLUGIN_CALLBACK((plugin_feature_callback_t)open_database, NULL),
+			PLUGIN_PROVIDE(CUSTOM, "attr-sql"),
+				PLUGIN_DEPENDS(DATABASE, DB_ANY),
+	};
+	*features = f;
+	return countof(f);
+}
+
+METHOD(plugin_t, destroy, void,
+	private_attr_sql_plugin_t *this)
+{
+	free(this);
+}
+
+/*
+ * see header file
+ */
+plugin_t *attr_sql_plugin_create()
+{
+	private_attr_sql_plugin_t *this;
+
+	INIT(this,
+		.public = {
+			.plugin = {
+				.get_name = _get_name,
+				.get_features = _get_features,
+				.destroy = _destroy,
+			},
+		},
+	);
+	lib->settings->add_fallback(lib->settings, "%s.plugins.attr-sql",
+								"libhydra.plugins.attr-sql", lib->ns);
+
+	return &this->public.plugin;
+}
diff --git a/src/libcharon/plugins/attr_sql/attr_sql_plugin.h b/src/libcharon/plugins/attr_sql/attr_sql_plugin.h
new file mode 100644
index 0000000..b6b04cc
--- /dev/null
+++ b/src/libcharon/plugins/attr_sql/attr_sql_plugin.h
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2008 Martin Willi
+ * Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * for more details.
+ */
+
+/**
+ * @defgroup attr_sql attr_sql
+ * @ingroup cplugins
+ *
+ * @defgroup attr_sql_plugin attr_sql_plugin
+ * @{ @ingroup attr_sql
+ */
+
+#ifndef ATTR_SQL_PLUGIN_H_
+#define ATTR_SQL_PLUGIN_H_
+
+#include <plugins/plugin.h>
+
+typedef struct attr_sql_plugin_t attr_sql_plugin_t;
+
+/**
+ * SQL database attribute configuration plugin
+ */
+struct attr_sql_plugin_t {
+
+	/**
+	 * implements plugin interface
+	 */
+	plugin_t plugin;
+};
+
+#endif /** ATTR_SQL_PLUGIN_H_ @}*/
diff --git a/src/libcharon/plugins/attr_sql/attr_sql_provider.c b/src/libcharon/plugins/attr_sql/attr_sql_provider.c
new file mode 100644
index 0000000..c241070
--- /dev/null
+++ b/src/libcharon/plugins/attr_sql/attr_sql_provider.c
@@ -0,0 +1,478 @@
+/*
+ * Copyright (C) 2008 Martin Willi
+ * Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * for more details.
+ */
+
+#include <time.h>
+
+#include <utils/debug.h>
+#include <library.h>
+
+#include "attr_sql_provider.h"
+
+typedef struct private_attr_sql_provider_t private_attr_sql_provider_t;
+
+/**
+ * private data of attr_sql_provider
+ */
+struct private_attr_sql_provider_t {
+
+	/**
+	 * public functions
+	 */
+	attr_sql_provider_t public;
+
+	/**
+	 * database connection
+	 */
+	database_t *db;
+
+	/**
+	 * whether to record lease history in lease table
+	 */
+	bool history;
+};
+
+/**
+ * lookup/insert an identity
+ */
+static u_int get_identity(private_attr_sql_provider_t *this, ike_sa_t *ike_sa)
+{
+	identification_t *id;
+	enumerator_t *e;
+	u_int row;
+
+	id = ike_sa->get_other_eap_id(ike_sa);
+
+	this->db->transaction(this->db, TRUE);
+	/* look for peer identity in the identities table */
+	e = this->db->query(this->db,
+						"SELECT id FROM identities WHERE type = ? AND data = ?",
+						DB_INT, id->get_type(id), DB_BLOB, id->get_encoding(id),
+						DB_UINT);
+	if (e && e->enumerate(e, &row))
+	{
+		e->destroy(e);
+		this->db->commit(this->db);
+		return row;
+	}
+	DESTROY_IF(e);
+	/* not found, insert new one */
+	if (this->db->execute(this->db, &row,
+				  "INSERT INTO identities (type, data) VALUES (?, ?)",
+				  DB_INT, id->get_type(id), DB_BLOB, id->get_encoding(id)) == 1)
+	{
+		this->db->commit(this->db);
+		return row;
+	}
+	this->db->rollback(this->db);
+	return 0;
+}
+
+/**
+ * Lookup an attribute pool by name
+ */
+static u_int get_attr_pool(private_attr_sql_provider_t *this, char *name)
+{
+	enumerator_t *e;
+	u_int row = 0;
+
+	e = this->db->query(this->db,
+						"SELECT id FROM attribute_pools WHERE name = ?",
+						DB_TEXT, name, DB_UINT);
+	if (e)
+	{
+		e->enumerate(e, &row);
+	}
+	DESTROY_IF(e);
+
+	return row;
+}
+
+/**
+ * Lookup pool by name and address family
+ */
+static u_int get_pool(private_attr_sql_provider_t *this, char *name, int family,
+					  u_int *timeout)
+{
+	enumerator_t *e;
+	chunk_t start;
+	u_int pool;
+
+	e = this->db->query(this->db,
+						"SELECT id, start, timeout FROM pools WHERE name = ?",
+						DB_TEXT, name, DB_UINT, DB_BLOB, DB_UINT);
+	if (e && e->enumerate(e, &pool, &start, timeout))
+	{
+		if ((family == AF_INET  && start.len == 4) ||
+			(family == AF_INET6 && start.len == 16))
+		{
+			e->destroy(e);
+			return pool;
+		}
+	}
+	DESTROY_IF(e);
+	return 0;
+}
+
+/**
+ * Look up an existing lease
+ */
+static host_t* check_lease(private_attr_sql_provider_t *this, char *name,
+						   u_int pool, u_int identity)
+{
+	while (TRUE)
+	{
+		u_int id;
+		chunk_t address;
+		enumerator_t *e;
+		time_t now = time(NULL);
+
+		e = this->db->query(this->db,
+				"SELECT id, address FROM addresses "
+				"WHERE pool = ? AND identity = ? AND released != 0 LIMIT 1",
+				DB_UINT, pool, DB_UINT, identity, DB_UINT, DB_BLOB);
+		if (!e || !e->enumerate(e, &id, &address))
+		{
+			DESTROY_IF(e);
+			break;
+		}
+		address = chunk_clonea(address);
+		e->destroy(e);
+
+		if (this->db->execute(this->db, NULL,
+				"UPDATE addresses SET acquired = ?, released = 0 "
+				"WHERE id = ? AND identity = ? AND released != 0",
+				DB_UINT, now, DB_UINT, id, DB_UINT, identity) > 0)
+		{
+			host_t *host;
+
+			host = host_create_from_chunk(AF_UNSPEC, address, 0);
+			if (host)
+			{
+				DBG1(DBG_CFG, "acquired existing lease for address %H in"
+					 " pool '%s'", host, name);
+				return host;
+			}
+		}
+	}
+	return NULL;
+}
+
+/**
+ * We check for unallocated addresses or expired leases. First we select an
+ * address as a candidate, but double check later on if it is still available
+ * during the update operation. This allows us to work without locking.
+ */
+static host_t* get_lease(private_attr_sql_provider_t *this, char *name,
+						 u_int pool, u_int timeout, u_int identity)
+{
+	while (TRUE)
+	{
+		u_int id;
+		chunk_t address;
+		enumerator_t *e;
+		time_t now = time(NULL);
+		int hits;
+
+		if (timeout)
+		{
+			/* check for an expired lease */
+			e = this->db->query(this->db,
+				"SELECT id, address FROM addresses "
+				"WHERE pool = ? AND released != 0 AND released < ? LIMIT 1",
+				DB_UINT, pool, DB_UINT, now - timeout, DB_UINT, DB_BLOB);
+		}
+		else
+		{
+			/* with static leases, check for an unallocated address */
+			e = this->db->query(this->db,
+				"SELECT id, address FROM addresses "
+				"WHERE pool = ? AND identity = 0 LIMIT 1",
+				DB_UINT, pool, DB_UINT, DB_BLOB);
+
+		}
+
+		if (!e || !e->enumerate(e, &id, &address))
+		{
+			DESTROY_IF(e);
+			break;
+		}
+		address = chunk_clonea(address);
+		e->destroy(e);
+
+		if (timeout)
+		{
+			hits = this->db->execute(this->db, NULL,
+						"UPDATE addresses SET "
+						"acquired = ?, released = 0, identity = ? "
+						"WHERE id = ? AND released != 0 AND released < ?",
+						DB_UINT, now, DB_UINT, identity,
+						DB_UINT, id, DB_UINT, now - timeout);
+		}
+		else
+		{
+			hits = this->db->execute(this->db, NULL,
+						"UPDATE addresses SET "
+						"acquired = ?, released = 0, identity = ? "
+						"WHERE id = ? AND identity = 0",
+						DB_UINT, now, DB_UINT, identity, DB_UINT, id);
+		}
+		if (hits > 0)
+		{
+			host_t *host;
+
+			host = host_create_from_chunk(AF_UNSPEC, address, 0);
+			if (host)
+			{
+				DBG1(DBG_CFG, "acquired new lease for address %H in pool '%s'",
+					 host, name);
+				return host;
+			}
+		}
+	}
+	DBG1(DBG_CFG, "no available address found in pool '%s'", name);
+	return NULL;
+}
+
+METHOD(attribute_provider_t, acquire_address, host_t*,
+	private_attr_sql_provider_t *this, linked_list_t *pools, ike_sa_t *ike_sa,
+	host_t *requested)
+{
+	enumerator_t *enumerator;
+	host_t *address = NULL;
+	u_int identity, pool, timeout;
+	char *name;
+	int family;
+
+	identity = get_identity(this, ike_sa);
+	if (identity)
+	{
+		family = requested->get_family(requested);
+		/* check for an existing lease in all pools */
+		enumerator = pools->create_enumerator(pools);
+		while (enumerator->enumerate(enumerator, &name))
+		{
+			pool = get_pool(this, name, family, &timeout);
+			if (pool)
+			{
+				address = check_lease(this, name, pool, identity);
+				if (address)
+				{
+					break;
+				}
+			}
+		}
+		enumerator->destroy(enumerator);
+
+		if (!address)
+		{
+			/* get an unallocated address or expired lease */
+			enumerator = pools->create_enumerator(pools);
+			while (enumerator->enumerate(enumerator, &name))
+			{
+				pool = get_pool(this, name, family, &timeout);
+				if (pool)
+				{
+					address = get_lease(this, name, pool, timeout, identity);
+					if (address)
+					{
+						break;
+					}
+				}
+			}
+			enumerator->destroy(enumerator);
+		}
+	}
+	return address;
+}
+
+METHOD(attribute_provider_t, release_address, bool,
+	private_attr_sql_provider_t *this, linked_list_t *pools, host_t *address,
+	ike_sa_t *ike_sa)
+{
+	enumerator_t *enumerator;
+	u_int pool, timeout;
+	time_t now = time(NULL);
+	bool found = FALSE;
+	char *name;
+	int family;
+
+	family = address->get_family(address);
+	enumerator = pools->create_enumerator(pools);
+	while (enumerator->enumerate(enumerator, &name))
+	{
+		pool = get_pool(this, name, family, &timeout);
+		if (!pool)
+		{
+			continue;
+		}
+		if (this->db->execute(this->db, NULL,
+				"UPDATE addresses SET released = ? WHERE "
+				"pool = ? AND address = ?", DB_UINT, time(NULL),
+				DB_UINT, pool, DB_BLOB, address->get_address(address)) > 0)
+		{
+			if (this->history)
+			{
+				this->db->execute(this->db, NULL,
+					"INSERT INTO leases (address, identity, acquired, released)"
+					" SELECT id, identity, acquired, ? FROM addresses "
+					" WHERE pool = ? AND address = ?",
+					DB_UINT, now, DB_UINT, pool,
+					DB_BLOB, address->get_address(address));
+			}
+			found = TRUE;
+			break;
+		}
+	}
+	enumerator->destroy(enumerator);
+
+	return found;
+}
+
+METHOD(attribute_provider_t, create_attribute_enumerator, enumerator_t*,
+	private_attr_sql_provider_t *this, linked_list_t *pools, ike_sa_t *ike_sa,
+	linked_list_t *vips)
+{
+	enumerator_t *attr_enumerator = NULL;
+
+	if (vips->get_count(vips))
+	{
+		enumerator_t *pool_enumerator;
+		u_int count;
+		char *name;
+
+		/* in a first step check for attributes that match name and id */
+		if (ike_sa)
+		{
+			u_int identity = get_identity(this, ike_sa);
+
+			pool_enumerator = pools->create_enumerator(pools);
+			while (pool_enumerator->enumerate(pool_enumerator, &name))
+			{
+				u_int attr_pool = get_attr_pool(this, name);
+				if (!attr_pool)
+				{
+					continue;
+				}
+
+				attr_enumerator = this->db->query(this->db,
+								"SELECT count(*) FROM attributes "
+								"WHERE pool = ? AND identity = ?",
+								DB_UINT, attr_pool, DB_UINT, identity, DB_UINT);
+
+				if (attr_enumerator &&
+					attr_enumerator->enumerate(attr_enumerator, &count) &&
+					count != 0)
+				{
+					attr_enumerator->destroy(attr_enumerator);
+					attr_enumerator = this->db->query(this->db,
+								"SELECT type, value FROM attributes "
+								"WHERE pool = ? AND identity = ?", DB_UINT,
+								attr_pool, DB_UINT, identity, DB_INT, DB_BLOB);
+					break;
+				}
+				DESTROY_IF(attr_enumerator);
+				attr_enumerator = NULL;
+			}
+			pool_enumerator->destroy(pool_enumerator);
+		}
+
+		/* in a second step check for attributes that match name */
+		if (!attr_enumerator)
+		{
+			pool_enumerator = pools->create_enumerator(pools);
+			while (pool_enumerator->enumerate(pool_enumerator, &name))
+			{
+				u_int attr_pool = get_attr_pool(this, name);
+				if (!attr_pool)
+				{
+					continue;
+				}
+
+				attr_enumerator = this->db->query(this->db,
+									"SELECT count(*) FROM attributes "
+									"WHERE pool = ? AND identity = 0",
+									DB_UINT, attr_pool, DB_UINT);
+
+				if (attr_enumerator &&
+					attr_enumerator->enumerate(attr_enumerator, &count) &&
+					count != 0)
+				{
+					attr_enumerator->destroy(attr_enumerator);
+					attr_enumerator = this->db->query(this->db,
+									"SELECT type, value FROM attributes "
+									"WHERE pool = ? AND identity = 0",
+									DB_UINT, attr_pool, DB_INT, DB_BLOB);
+					break;
+				}
+				DESTROY_IF(attr_enumerator);
+				attr_enumerator = NULL;
+			}
+			pool_enumerator->destroy(pool_enumerator);
+		}
+
+		/* lastly try to find global attributes */
+		if (!attr_enumerator)
+		{
+			attr_enumerator = this->db->query(this->db,
+									"SELECT type, value FROM attributes "
+									"WHERE pool = 0 AND identity = 0",
+									DB_INT, DB_BLOB);
+		}
+	}
+
+	return (attr_enumerator ? attr_enumerator : enumerator_create_empty());
+}
+
+METHOD(attr_sql_provider_t, destroy, void,
+	private_attr_sql_provider_t *this)
+{
+	free(this);
+}
+
+/*
+ * see header file
+ */
+attr_sql_provider_t *attr_sql_provider_create(database_t *db)
+{
+	private_attr_sql_provider_t *this;
+	time_t now = time(NULL);
+
+	INIT(this,
+		.public = {
+			.provider = {
+				.acquire_address = _acquire_address,
+				.release_address = _release_address,
+				.create_attribute_enumerator = _create_attribute_enumerator,
+			},
+			.destroy = _destroy,
+		},
+		.db = db,
+		.history = lib->settings->get_bool(lib->settings,
+							"%s.plugins.attr-sql.lease_history", TRUE, lib->ns),
+	);
+
+	/* close any "online" leases in the case we crashed */
+	if (this->history)
+	{
+		this->db->execute(this->db, NULL,
+					"INSERT INTO leases (address, identity, acquired, released)"
+					" SELECT id, identity, acquired, ? FROM addresses "
+					" WHERE released = 0", DB_UINT, now);
+	}
+	this->db->execute(this->db, NULL,
+					  "UPDATE addresses SET released = ? WHERE released = 0",
+					  DB_UINT, now);
+	return &this->public;
+}
diff --git a/src/libcharon/plugins/attr_sql/attr_sql_provider.h b/src/libcharon/plugins/attr_sql/attr_sql_provider.h
new file mode 100644
index 0000000..a9b037b
--- /dev/null
+++ b/src/libcharon/plugins/attr_sql/attr_sql_provider.h
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2008 Martin Willi
+ * Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * for more details.
+ */
+
+/**
+ * @defgroup attr_sql_provider attr_sql_provider
+ * @{ @ingroup attr_sql
+ */
+
+#ifndef ATTR_SQL_PROVIDER_H_
+#define ATTR_SQL_PROVIDER_H_
+
+#include <attributes/attribute_provider.h>
+#include <database/database.h>
+
+typedef struct attr_sql_provider_t attr_sql_provider_t;
+
+/**
+ * SQL database based IKEv2 cfg attribute provider.
+ */
+struct attr_sql_provider_t {
+
+	/**
+	 * Implements attribute provider interface
+	 */
+	attribute_provider_t provider;
+
+	/**
+	 * Destroy a attr_sql_provider instance.
+	 */
+	void (*destroy)(attr_sql_provider_t *this);
+};
+
+/**
+ * Create a attr_sql_provider instance.
+ */
+attr_sql_provider_t *attr_sql_provider_create(database_t *db);
+
+#endif /** ATTR_SQL_PROVIDER_H_ @}*/
diff --git a/src/libcharon/plugins/certexpire/Makefile.in b/src/libcharon/plugins/certexpire/Makefile.in
index 08101d5..f946d73 100644
--- a/src/libcharon/plugins/certexpire/Makefile.in
+++ b/src/libcharon/plugins/certexpire/Makefile.in
@@ -229,6 +229,7 @@ DLLIB = @DLLIB@
 DLLTOOL = @DLLTOOL@
 DSYMUTIL = @DSYMUTIL@
 DUMPBIN = @DUMPBIN@
+EASY_INSTALL = @EASY_INSTALL@
 ECHO_C = @ECHO_C@
 ECHO_N = @ECHO_N@
 ECHO_T = @ECHO_T@
@@ -289,10 +290,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
 PLUGIN_CFLAGS = @PLUGIN_CFLAGS@
 PTHREADLIB = @PTHREADLIB@
 PYTHON = @PYTHON@
+PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@
 PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
 PYTHON_PLATFORM = @PYTHON_PLATFORM@
 PYTHON_PREFIX = @PYTHON_PREFIX@
 PYTHON_VERSION = @PYTHON_VERSION@
+PY_TEST = @PY_TEST@
 RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
@@ -366,6 +369,8 @@ json_CFLAGS = @json_CFLAGS@
 json_LIBS = @json_LIBS@
 libdir = @libdir@
 libexecdir = @libexecdir@
+libiptc_CFLAGS = @libiptc_CFLAGS@
+libiptc_LIBS = @libiptc_LIBS@
 linux_headers = @linux_headers@
 localedir = @localedir@
 localstatedir = @localstatedir@
diff --git a/src/libcharon/plugins/connmark/Makefile.am b/src/libcharon/plugins/connmark/Makefile.am
new file mode 100644
index 0000000..cc4d0ec
--- /dev/null
+++ b/src/libcharon/plugins/connmark/Makefile.am
@@ -0,0 +1,20 @@
+AM_CPPFLAGS = \
+	-I$(top_srcdir)/src/libstrongswan \
+	-I$(top_srcdir)/src/libhydra \
+	-I$(top_srcdir)/src/libcharon
+
+AM_CFLAGS = \
+	$(PLUGIN_CFLAGS) $(libiptc_CFLAGS)
+
+if MONOLITHIC
+noinst_LTLIBRARIES = libstrongswan-connmark.la
+else
+plugin_LTLIBRARIES = libstrongswan-connmark.la
+endif
+
+libstrongswan_connmark_la_SOURCES = \
+	connmark_listener.h connmark_listener.c \
+	connmark_plugin.h connmark_plugin.c
+
+libstrongswan_connmark_la_LDFLAGS = -module -avoid-version
+libstrongswan_connmark_la_LIBADD = $(libiptc_LIBS)
diff --git a/src/libcharon/plugins/connmark/Makefile.in b/src/libcharon/plugins/connmark/Makefile.in
new file mode 100644
index 0000000..65f53fd
--- /dev/null
+++ b/src/libcharon/plugins/connmark/Makefile.in
@@ -0,0 +1,782 @@
+# Makefile.in generated by automake 1.14.1 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994-2013 Free Software Foundation, Inc.
+
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+ at SET_MAKE@
+
+VPATH = @srcdir@
+am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)'
+am__make_running_with_option = \
+  case $${target_option-} in \
+      ?) ;; \
+      *) echo "am__make_running_with_option: internal error: invalid" \
+              "target option '$${target_option-}' specified" >&2; \
+         exit 1;; \
+  esac; \
+  has_opt=no; \
+  sane_makeflags=$$MAKEFLAGS; \
+  if $(am__is_gnu_make); then \
+    sane_makeflags=$$MFLAGS; \
+  else \
+    case $$MAKEFLAGS in \
+      *\\[\ \	]*) \
+        bs=\\; \
+        sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
+          | sed "s/$$bs$$bs[$$bs $$bs	]*//g"`;; \
+    esac; \
+  fi; \
+  skip_next=no; \
+  strip_trailopt () \
+  { \
+    flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
+  }; \
+  for flg in $$sane_makeflags; do \
+    test $$skip_next = yes && { skip_next=no; continue; }; \
+    case $$flg in \
+      *=*|--*) continue;; \
+        -*I) strip_trailopt 'I'; skip_next=yes;; \
+      -*I?*) strip_trailopt 'I';; \
+        -*O) strip_trailopt 'O'; skip_next=yes;; \
+      -*O?*) strip_trailopt 'O';; \
+        -*l) strip_trailopt 'l'; skip_next=yes;; \
+      -*l?*) strip_trailopt 'l';; \
+      -[dEDm]) skip_next=yes;; \
+      -[JT]) skip_next=yes;; \
+    esac; \
+    case $$flg in \
+      *$$target_option*) has_opt=yes; break;; \
+    esac; \
+  done; \
+  test $$has_opt = yes
+am__make_dryrun = (target_option=n; $(am__make_running_with_option))
+am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+subdir = src/libcharon/plugins/connmark
+DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
+	$(top_srcdir)/depcomp
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/m4/config/libtool.m4 \
+	$(top_srcdir)/m4/config/ltoptions.m4 \
+	$(top_srcdir)/m4/config/ltsugar.m4 \
+	$(top_srcdir)/m4/config/ltversion.m4 \
+	$(top_srcdir)/m4/config/lt~obsolete.m4 \
+	$(top_srcdir)/m4/macros/split-package-version.m4 \
+	$(top_srcdir)/m4/macros/with.m4 \
+	$(top_srcdir)/m4/macros/enable-disable.m4 \
+	$(top_srcdir)/m4/macros/add-plugin.m4 \
+	$(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+	$(ACLOCAL_M4)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
+am__vpath_adj = case $$p in \
+    $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
+    *) f=$$p;; \
+  esac;
+am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
+am__install_max = 40
+am__nobase_strip_setup = \
+  srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
+am__nobase_strip = \
+  for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
+am__nobase_list = $(am__nobase_strip_setup); \
+  for p in $$list; do echo "$$p $$p"; done | \
+  sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
+  $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
+    if (++n[$$2] == $(am__install_max)) \
+      { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
+    END { for (dir in files) print dir, files[dir] }'
+am__base_list = \
+  sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
+  sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
+am__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; }; \
+  }
+am__installdirs = "$(DESTDIR)$(plugindir)"
+LTLIBRARIES = $(noinst_LTLIBRARIES) $(plugin_LTLIBRARIES)
+am__DEPENDENCIES_1 =
+libstrongswan_connmark_la_DEPENDENCIES = $(am__DEPENDENCIES_1)
+am_libstrongswan_connmark_la_OBJECTS = connmark_listener.lo \
+	connmark_plugin.lo
+libstrongswan_connmark_la_OBJECTS =  \
+	$(am_libstrongswan_connmark_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_connmark_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \
+	$(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \
+	$(AM_CFLAGS) $(CFLAGS) $(libstrongswan_connmark_la_LDFLAGS) \
+	$(LDFLAGS) -o $@
+ at MONOLITHIC_FALSE@am_libstrongswan_connmark_la_rpath = -rpath \
+ at MONOLITHIC_FALSE@	$(plugindir)
+ at MONOLITHIC_TRUE@am_libstrongswan_connmark_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
+am__v_P_1 = :
+AM_V_GEN = $(am__v_GEN_ at AM_V@)
+am__v_GEN_ = $(am__v_GEN_ at AM_DEFAULT_V@)
+am__v_GEN_0 = @echo "  GEN     " $@;
+am__v_GEN_1 = 
+AM_V_at = $(am__v_at_ at AM_V@)
+am__v_at_ = $(am__v_at_ at AM_DEFAULT_V@)
+am__v_at_0 = @
+am__v_at_1 = 
+DEFAULT_INCLUDES = -I. at am__isrc@ -I$(top_builddir)
+depcomp = $(SHELL) $(top_srcdir)/depcomp
+am__depfiles_maybe = depfiles
+am__mv = mv -f
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+	$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+	$(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \
+	$(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
+	$(AM_CFLAGS) $(CFLAGS)
+AM_V_CC = $(am__v_CC_ at AM_V@)
+am__v_CC_ = $(am__v_CC_ at AM_DEFAULT_V@)
+am__v_CC_0 = @echo "  CC      " $@;
+am__v_CC_1 = 
+CCLD = $(CC)
+LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+	$(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+	$(AM_LDFLAGS) $(LDFLAGS) -o $@
+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_connmark_la_SOURCES)
+DIST_SOURCES = $(libstrongswan_connmark_la_SOURCES)
+am__can_run_installinfo = \
+  case $$AM_UPDATE_INFO_DIR in \
+    n|no|NO) false;; \
+    *) (install-info --version) >/dev/null 2>&1;; \
+  esac
+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
+# *not* preserved.
+am__uniquify_input = $(AWK) '\
+  BEGIN { nonempty = 0; } \
+  { items[$$0] = 1; nonempty = 1; } \
+  END { if (nonempty) { for (i in items) print i; }; } \
+'
+# Make sure the list of sources is unique.  This is necessary because,
+# e.g., the same source file might be shared among _SOURCES variables
+# for different programs/libraries.
+am__define_uniq_tagged_files = \
+  list='$(am__tagged_files)'; \
+  unique=`for i in $$list; do \
+    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+  done | $(am__uniquify_input)`
+ETAGS = etags
+CTAGS = ctags
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+ALLOCA = @ALLOCA@
+AMTAR = @AMTAR@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+BFDLIB = @BFDLIB@
+BTLIB = @BTLIB@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+COVERAGE_CFLAGS = @COVERAGE_CFLAGS@
+COVERAGE_LDFLAGS = @COVERAGE_LDFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DLLIB = @DLLIB@
+DLLTOOL = @DLLTOOL@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+EASY_INSTALL = @EASY_INSTALL@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+FGREP = @FGREP@
+GEM = @GEM@
+GENHTML = @GENHTML@
+GPERF = @GPERF@
+GPRBUILD = @GPRBUILD@
+GREP = @GREP@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+LCOV = @LCOV@
+LD = @LD@
+LDFLAGS = @LDFLAGS@
+LEX = @LEX@
+LEXLIB = @LEXLIB@
+LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LIPO = @LIPO@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+MAKEINFO = @MAKEINFO@
+MANIFEST_TOOL = @MANIFEST_TOOL@
+MKDIR_P = @MKDIR_P@
+MYSQLCFLAG = @MYSQLCFLAG@
+MYSQLCONFIG = @MYSQLCONFIG@
+MYSQLLIB = @MYSQLLIB@
+NM = @NM@
+NMEDIT = @NMEDIT@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OPENSSL_LIB = @OPENSSL_LIB@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PACKAGE_VERSION_BUILD = @PACKAGE_VERSION_BUILD@
+PACKAGE_VERSION_MAJOR = @PACKAGE_VERSION_MAJOR@
+PACKAGE_VERSION_MINOR = @PACKAGE_VERSION_MINOR@
+PACKAGE_VERSION_REVIEW = @PACKAGE_VERSION_REVIEW@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PERL = @PERL@
+PKG_CONFIG = @PKG_CONFIG@
+PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
+PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
+PLUGIN_CFLAGS = @PLUGIN_CFLAGS@
+PTHREADLIB = @PTHREADLIB@
+PYTHON = @PYTHON@
+PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@
+PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
+PYTHON_PLATFORM = @PYTHON_PLATFORM@
+PYTHON_PREFIX = @PYTHON_PREFIX@
+PYTHON_VERSION = @PYTHON_VERSION@
+PY_TEST = @PY_TEST@
+RANLIB = @RANLIB@
+RTLIB = @RTLIB@
+RUBY = @RUBY@
+RUBYGEMDIR = @RUBYGEMDIR@
+RUBYINCLUDE = @RUBYINCLUDE@
+RUBYLIB = @RUBYLIB@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+SOCKLIB = @SOCKLIB@
+STRIP = @STRIP@
+UNWINDLIB = @UNWINDLIB@
+VERSION = @VERSION@
+YACC = @YACC@
+YFLAGS = @YFLAGS@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+aikgen_plugins = @aikgen_plugins@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+attest_plugins = @attest_plugins@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+c_plugins = @c_plugins@
+charon_natt_port = @charon_natt_port@
+charon_plugins = @charon_plugins@
+charon_udp_port = @charon_udp_port@
+clearsilver_LIBS = @clearsilver_LIBS@
+cmd_plugins = @cmd_plugins@
+datadir = @datadir@
+datarootdir = @datarootdir@
+dbusservicedir = @dbusservicedir@
+dev_headers = @dev_headers@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+fips_mode = @fips_mode@
+gtk_CFLAGS = @gtk_CFLAGS@
+gtk_LIBS = @gtk_LIBS@
+h_plugins = @h_plugins@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+imcvdir = @imcvdir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+ipsec_script = @ipsec_script@
+ipsec_script_upper = @ipsec_script_upper@
+ipsecdir = @ipsecdir@
+ipsecgroup = @ipsecgroup@
+ipseclibdir = @ipseclibdir@
+ipsecuser = @ipsecuser@
+json_CFLAGS = @json_CFLAGS@
+json_LIBS = @json_LIBS@
+libdir = @libdir@
+libexecdir = @libexecdir@
+libiptc_CFLAGS = @libiptc_CFLAGS@
+libiptc_LIBS = @libiptc_LIBS@
+linux_headers = @linux_headers@
+localedir = @localedir@
+localstatedir = @localstatedir@
+maemo_CFLAGS = @maemo_CFLAGS@
+maemo_LIBS = @maemo_LIBS@
+manager_plugins = @manager_plugins@
+mandir = @mandir@
+medsrv_plugins = @medsrv_plugins@
+mkdir_p = @mkdir_p@
+nm_CFLAGS = @nm_CFLAGS@
+nm_LIBS = @nm_LIBS@
+nm_ca_dir = @nm_ca_dir@
+nm_plugins = @nm_plugins@
+oldincludedir = @oldincludedir@
+pcsclite_CFLAGS = @pcsclite_CFLAGS@
+pcsclite_LIBS = @pcsclite_LIBS@
+pdfdir = @pdfdir@
+piddir = @piddir@
+pkgpyexecdir = @pkgpyexecdir@
+pkgpythondir = @pkgpythondir@
+pki_plugins = @pki_plugins@
+plugindir = @plugindir@
+pool_plugins = @pool_plugins@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+pyexecdir = @pyexecdir@
+pythondir = @pythondir@
+random_device = @random_device@
+resolv_conf = @resolv_conf@
+routing_table = @routing_table@
+routing_table_prio = @routing_table_prio@
+s_plugins = @s_plugins@
+sbindir = @sbindir@
+scepclient_plugins = @scepclient_plugins@
+scripts_plugins = @scripts_plugins@
+sharedstatedir = @sharedstatedir@
+soup_CFLAGS = @soup_CFLAGS@
+soup_LIBS = @soup_LIBS@
+srcdir = @srcdir@
+starter_plugins = @starter_plugins@
+strongswan_conf = @strongswan_conf@
+strongswan_options = @strongswan_options@
+swanctldir = @swanctldir@
+sysconfdir = @sysconfdir@
+systemd_daemon_CFLAGS = @systemd_daemon_CFLAGS@
+systemd_daemon_LIBS = @systemd_daemon_LIBS@
+systemd_journal_CFLAGS = @systemd_journal_CFLAGS@
+systemd_journal_LIBS = @systemd_journal_LIBS@
+systemdsystemunitdir = @systemdsystemunitdir@
+t_plugins = @t_plugins@
+target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+urandom_device = @urandom_device@
+xml_CFLAGS = @xml_CFLAGS@
+xml_LIBS = @xml_LIBS@
+AM_CPPFLAGS = \
+	-I$(top_srcdir)/src/libstrongswan \
+	-I$(top_srcdir)/src/libhydra \
+	-I$(top_srcdir)/src/libcharon
+
+AM_CFLAGS = \
+	$(PLUGIN_CFLAGS) $(libiptc_CFLAGS)
+
+ at MONOLITHIC_TRUE@noinst_LTLIBRARIES = libstrongswan-connmark.la
+ at MONOLITHIC_FALSE@plugin_LTLIBRARIES = libstrongswan-connmark.la
+libstrongswan_connmark_la_SOURCES = \
+	connmark_listener.h connmark_listener.c \
+	connmark_plugin.h connmark_plugin.c
+
+libstrongswan_connmark_la_LDFLAGS = -module -avoid-version
+libstrongswan_connmark_la_LIBADD = $(libiptc_LIBS)
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .c .lo .o .obj
+$(srcdir)/Makefile.in:  $(srcdir)/Makefile.am  $(am__configure_deps)
+	@for dep in $?; do \
+	  case '$(am__configure_deps)' in \
+	    *$$dep*) \
+	      ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+	        && { if test -f $@; then exit 0; else break; fi; }; \
+	      exit 1;; \
+	  esac; \
+	done; \
+	echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/libcharon/plugins/connmark/Makefile'; \
+	$(am__cd) $(top_srcdir) && \
+	  $(AUTOMAKE) --gnu src/libcharon/plugins/connmark/Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+	@case '$?' in \
+	  *config.status*) \
+	    cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+	  *) \
+	    echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+	    cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+	esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure:  $(am__configure_deps)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4):  $(am__aclocal_m4_deps)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+
+clean-noinstLTLIBRARIES:
+	-test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES)
+	@list='$(noinst_LTLIBRARIES)'; \
+	locs=`for p in $$list; do echo $$p; done | \
+	      sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \
+	      sort -u`; \
+	test -z "$$locs" || { \
+	  echo rm -f $${locs}; \
+	  rm -f $${locs}; \
+	}
+
+install-pluginLTLIBRARIES: $(plugin_LTLIBRARIES)
+	@$(NORMAL_INSTALL)
+	@list='$(plugin_LTLIBRARIES)'; test -n "$(plugindir)" || list=; \
+	list2=; for p in $$list; do \
+	  if test -f $$p; then \
+	    list2="$$list2 $$p"; \
+	  else :; fi; \
+	done; \
+	test -z "$$list2" || { \
+	  echo " $(MKDIR_P) '$(DESTDIR)$(plugindir)'"; \
+	  $(MKDIR_P) "$(DESTDIR)$(plugindir)" || exit 1; \
+	  echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(plugindir)'"; \
+	  $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(plugindir)"; \
+	}
+
+uninstall-pluginLTLIBRARIES:
+	@$(NORMAL_UNINSTALL)
+	@list='$(plugin_LTLIBRARIES)'; test -n "$(plugindir)" || list=; \
+	for p in $$list; do \
+	  $(am__strip_dir) \
+	  echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(plugindir)/$$f'"; \
+	  $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(plugindir)/$$f"; \
+	done
+
+clean-pluginLTLIBRARIES:
+	-test -z "$(plugin_LTLIBRARIES)" || rm -f $(plugin_LTLIBRARIES)
+	@list='$(plugin_LTLIBRARIES)'; \
+	locs=`for p in $$list; do echo $$p; done | \
+	      sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \
+	      sort -u`; \
+	test -z "$$locs" || { \
+	  echo rm -f $${locs}; \
+	  rm -f $${locs}; \
+	}
+
+libstrongswan-connmark.la: $(libstrongswan_connmark_la_OBJECTS) $(libstrongswan_connmark_la_DEPENDENCIES) $(EXTRA_libstrongswan_connmark_la_DEPENDENCIES) 
+	$(AM_V_CCLD)$(libstrongswan_connmark_la_LINK) $(am_libstrongswan_connmark_la_rpath) $(libstrongswan_connmark_la_OBJECTS) $(libstrongswan_connmark_la_LIBADD) $(LIBS)
+
+mostlyclean-compile:
+	-rm -f *.$(OBJEXT)
+
+distclean-compile:
+	-rm -f *.tab.c
+
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/connmark_listener.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/connmark_plugin.Plo at am__quote@
+
+.c.o:
+ at am__fastdepCC_TRUE@	$(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\
+ at am__fastdepCC_TRUE@	$(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\
+ at am__fastdepCC_TRUE@	$(am__mv) $$depbase.Tpo $$depbase.Po
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(COMPILE) -c -o $@ $<
+
+.c.obj:
+ at am__fastdepCC_TRUE@	$(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\
+ at am__fastdepCC_TRUE@	$(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\
+ at am__fastdepCC_TRUE@	$(am__mv) $$depbase.Tpo $$depbase.Po
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
+
+.c.lo:
+ at am__fastdepCC_TRUE@	$(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\
+ at am__fastdepCC_TRUE@	$(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\
+ at am__fastdepCC_TRUE@	$(am__mv) $$depbase.Tpo $$depbase.Plo
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(LTCOMPILE) -c -o $@ $<
+
+mostlyclean-libtool:
+	-rm -f *.lo
+
+clean-libtool:
+	-rm -rf .libs _libs
+
+ID: $(am__tagged_files)
+	$(am__define_uniq_tagged_files); mkid -fID $$unique
+tags: tags-am
+TAGS: tags
+
+tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+	set x; \
+	here=`pwd`; \
+	$(am__define_uniq_tagged_files); \
+	shift; \
+	if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
+	  test -n "$$unique" || unique=$$empty_fix; \
+	  if test $$# -gt 0; then \
+	    $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+	      "$$@" $$unique; \
+	  else \
+	    $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+	      $$unique; \
+	  fi; \
+	fi
+ctags: ctags-am
+
+CTAGS: ctags
+ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+	$(am__define_uniq_tagged_files); \
+	test -z "$(CTAGS_ARGS)$$unique" \
+	  || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+	     $$unique
+
+GTAGS:
+	here=`$(am__cd) $(top_builddir) && pwd` \
+	  && $(am__cd) $(top_srcdir) \
+	  && gtags -i $(GTAGS_ARGS) "$$here"
+cscopelist: cscopelist-am
+
+cscopelist-am: $(am__tagged_files)
+	list='$(am__tagged_files)'; \
+	case "$(srcdir)" in \
+	  [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
+	  *) sdir=$(subdir)/$(srcdir) ;; \
+	esac; \
+	for i in $$list; do \
+	  if test -f "$$i"; then \
+	    echo "$(subdir)/$$i"; \
+	  else \
+	    echo "$$sdir/$$i"; \
+	  fi; \
+	done >> $(top_builddir)/cscope.files
+
+distclean-tags:
+	-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+distdir: $(DISTFILES)
+	@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+	topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+	list='$(DISTFILES)'; \
+	  dist_files=`for file in $$list; do echo $$file; done | \
+	  sed -e "s|^$$srcdirstrip/||;t" \
+	      -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+	case $$dist_files in \
+	  */*) $(MKDIR_P) `echo "$$dist_files" | \
+			   sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+			   sort -u` ;; \
+	esac; \
+	for file in $$dist_files; do \
+	  if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+	  if test -d $$d/$$file; then \
+	    dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+	    if test -d "$(distdir)/$$file"; then \
+	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+	    fi; \
+	    if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+	      cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+	    fi; \
+	    cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+	  else \
+	    test -f "$(distdir)/$$file" \
+	    || cp -p $$d/$$file "$(distdir)/$$file" \
+	    || exit 1; \
+	  fi; \
+	done
+check-am: all-am
+check: check-am
+all-am: Makefile $(LTLIBRARIES)
+installdirs:
+	for dir in "$(DESTDIR)$(plugindir)"; do \
+	  test -z "$$dir" || $(MKDIR_P) "$$dir"; \
+	done
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+	@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+	if test -z '$(STRIP)'; then \
+	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	      install; \
+	else \
+	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	    "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+	fi
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+	-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+	-test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+
+maintainer-clean-generic:
+	@echo "This command is intended for maintainers to use"
+	@echo "it deletes files that may require special tools to rebuild."
+clean: clean-am
+
+clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \
+	clean-pluginLTLIBRARIES mostlyclean-am
+
+distclean: distclean-am
+	-rm -rf ./$(DEPDIR)
+	-rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+	distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+html-am:
+
+info: info-am
+
+info-am:
+
+install-data-am: install-pluginLTLIBRARIES
+
+install-dvi: install-dvi-am
+
+install-dvi-am:
+
+install-exec-am:
+
+install-html: install-html-am
+
+install-html-am:
+
+install-info: install-info-am
+
+install-info-am:
+
+install-man:
+
+install-pdf: install-pdf-am
+
+install-pdf-am:
+
+install-ps: install-ps-am
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+	-rm -rf ./$(DEPDIR)
+	-rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic \
+	mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am: uninstall-pluginLTLIBRARIES
+
+.MAKE: install-am install-strip
+
+.PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \
+	clean-libtool clean-noinstLTLIBRARIES clean-pluginLTLIBRARIES \
+	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-man install-pdf \
+	install-pdf-am install-pluginLTLIBRARIES install-ps \
+	install-ps-am install-strip installcheck installcheck-am \
+	installdirs maintainer-clean maintainer-clean-generic \
+	mostlyclean mostlyclean-compile mostlyclean-generic \
+	mostlyclean-libtool pdf pdf-am ps ps-am tags tags-am uninstall \
+	uninstall-am uninstall-pluginLTLIBRARIES
+
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/src/libcharon/plugins/connmark/connmark_listener.c b/src/libcharon/plugins/connmark/connmark_listener.c
new file mode 100644
index 0000000..23df690
--- /dev/null
+++ b/src/libcharon/plugins/connmark/connmark_listener.c
@@ -0,0 +1,538 @@
+/*
+ * Copyright (C) 2014 Martin Willi
+ * Copyright (C) 2014 revosec AG
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * for more details.
+ */
+
+#include "connmark_listener.h"
+
+#include <daemon.h>
+
+#include <errno.h>
+#include <libiptc/libiptc.h>
+#include <linux/netfilter/xt_esp.h>
+#include <linux/netfilter/xt_tcpudp.h>
+#include <linux/netfilter/xt_MARK.h>
+#include <linux/netfilter/xt_policy.h>
+#include <linux/netfilter/xt_CONNMARK.h>
+
+
+typedef struct private_connmark_listener_t private_connmark_listener_t;
+
+/**
+ * Private data of an connmark_listener_t object.
+ */
+struct private_connmark_listener_t {
+
+	/**
+	 * Public connmark_listener_t interface.
+	 */
+	connmark_listener_t public;
+};
+
+/**
+ * Convert an (IPv4) traffic selector to an address and mask
+ */
+static bool ts2in(traffic_selector_t *ts,
+				  struct in_addr *addr, struct in_addr *mask)
+{
+	u_int8_t bits;
+	host_t *net;
+
+	if (ts->get_type(ts) == TS_IPV4_ADDR_RANGE &&
+		ts->to_subnet(ts, &net, &bits))
+	{
+		memcpy(&addr->s_addr, net->get_address(net).ptr, 4);
+		net->destroy(net);
+		mask->s_addr = htonl(0xffffffffU << (32 - bits));
+		return TRUE;
+	}
+	return FALSE;
+}
+
+/**
+ * Convert an (IPv4) host to an address with mask
+ */
+static bool host2in(host_t *host, struct in_addr *addr, struct in_addr *mask)
+{
+	if (host->get_family(host) == AF_INET)
+	{
+		memcpy(&addr->s_addr, host->get_address(host).ptr, 4);
+		mask->s_addr = ~0;
+		return TRUE;
+	}
+	return FALSE;
+}
+
+/**
+ * Add or remove a rule to/from the specified chain
+ */
+static bool manage_rule(struct iptc_handle *ipth, const char *chain,
+						bool add, struct ipt_entry *e)
+{
+	if (add)
+	{
+		if (!iptc_insert_entry(chain, e, 0, ipth))
+		{
+			DBG1(DBG_CFG, "appending %s rule failed: %s",
+				 chain, iptc_strerror(errno));
+			return FALSE;
+		}
+	}
+	else
+	{
+		if (!iptc_delete_entry(chain, e, "", ipth))
+		{
+			DBG1(DBG_CFG, "deleting %s rule failed: %s",
+				 chain, iptc_strerror(errno));
+			return FALSE;
+		}
+	}
+	return TRUE;
+}
+
+/**
+ * Add rule marking UDP-encapsulated ESP packets to match the correct policy
+ */
+static bool manage_pre_esp_in_udp(private_connmark_listener_t *this,
+								  struct iptc_handle *ipth, bool add,
+								  u_int mark, u_int32_t spi,
+								  host_t *dst, host_t *src)
+{
+	struct {
+		struct ipt_entry e;
+		struct ipt_entry_match m;
+		struct xt_udp udp;
+		struct ipt_entry_target t;
+		struct xt_mark_tginfo2 tm;
+	} ipt = {
+		.e  = {
+			.target_offset = XT_ALIGN(sizeof(ipt.e) + sizeof(ipt.m) +
+									  sizeof(ipt.udp)),
+			.next_offset = sizeof(ipt),
+			.ip = {
+				.proto = IPPROTO_UDP,
+			},
+		},
+		.m = {
+			.u = {
+				.user = {
+					.match_size = XT_ALIGN(sizeof(ipt.m) + sizeof(ipt.udp)),
+					.name = "udp",
+				},
+			},
+		},
+		.udp = {
+			.spts = { src->get_port(src), src->get_port(src) },
+			.dpts = { dst->get_port(dst), dst->get_port(dst) },
+		},
+		.t = {
+			.u = {
+				.user = {
+					.target_size = XT_ALIGN(sizeof(ipt.t) + sizeof(ipt.tm)),
+					.name = "MARK",
+					.revision = 2,
+				},
+			},
+		},
+		.tm = {
+			.mark = mark,
+			.mask = ~0,
+		},
+	};
+
+	if (!host2in(dst, &ipt.e.ip.dst, &ipt.e.ip.dmsk) ||
+		!host2in(src, &ipt.e.ip.src, &ipt.e.ip.smsk))
+	{
+		return FALSE;
+	}
+	return manage_rule(ipth, "PREROUTING", add, &ipt.e);
+}
+
+/**
+ * Add rule marking non-encapsulated ESP packets to match the correct policy
+ */
+static bool manage_pre_esp(private_connmark_listener_t *this,
+						   struct iptc_handle *ipth, bool add,
+						   u_int mark, u_int32_t spi,
+						   host_t *dst, host_t *src)
+{
+	struct {
+		struct ipt_entry e;
+		struct ipt_entry_match m;
+		struct xt_esp esp;
+		struct ipt_entry_target t;
+		struct xt_mark_tginfo2 tm;
+	} ipt = {
+		.e  = {
+			.target_offset = XT_ALIGN(sizeof(ipt.e) + sizeof(ipt.m) +
+									  sizeof(ipt.esp)),
+			.next_offset = sizeof(ipt),
+			.ip = {
+				.proto = IPPROTO_ESP,
+			},
+		},
+		.m = {
+			.u = {
+				.user = {
+					.match_size = XT_ALIGN(sizeof(ipt.m) + sizeof(ipt.esp)),
+					.name = "esp",
+				},
+			},
+		},
+		.esp = {
+			.spis = { htonl(spi), htonl(spi) },
+		},
+		.t = {
+			.u = {
+				.user = {
+					.target_size = XT_ALIGN(sizeof(ipt.t) + sizeof(ipt.tm)),
+					.name = "MARK",
+					.revision = 2,
+				},
+			},
+		},
+		.tm = {
+			.mark = mark,
+			.mask = ~0,
+		},
+	};
+
+	if (!host2in(dst, &ipt.e.ip.dst, &ipt.e.ip.dmsk) ||
+		!host2in(src, &ipt.e.ip.src, &ipt.e.ip.smsk))
+	{
+		return FALSE;
+	}
+	return manage_rule(ipth, "PREROUTING", add, &ipt.e);
+}
+
+/**
+ * Add rule marking ESP packets to match the correct policy
+ */
+static bool manage_pre(private_connmark_listener_t *this,
+					   struct iptc_handle *ipth, bool add,
+					   u_int mark, u_int32_t spi, bool encap,
+					   host_t *dst, host_t *src)
+{
+	if (encap)
+	{
+		return manage_pre_esp_in_udp(this, ipth, add, mark, spi, dst, src);
+	}
+	return manage_pre_esp(this, ipth, add, mark, spi, dst, src);
+}
+
+/**
+ * Add inbound rule applying CONNMARK to matching traffic
+ */
+static bool manage_in(private_connmark_listener_t *this,
+					  struct iptc_handle *ipth, bool add,
+					  u_int mark, u_int32_t spi,
+					  traffic_selector_t *dst, traffic_selector_t *src)
+{
+	struct {
+		struct ipt_entry e;
+		struct ipt_entry_match m;
+		struct xt_policy_info p;
+		struct ipt_entry_target t;
+		struct xt_connmark_tginfo1 cm;
+	} ipt = {
+		.e  = {
+			.target_offset = XT_ALIGN(sizeof(ipt.e) + sizeof(ipt.m) +
+									  sizeof(ipt.p)),
+			.next_offset = sizeof(ipt),
+		},
+		.m = {
+			.u = {
+				.user = {
+					.match_size = XT_ALIGN(sizeof(ipt.m) + sizeof(ipt.p)),
+					.name = "policy",
+				},
+			},
+		},
+		.p = {
+			.pol = {
+				{
+					.spi = spi,
+					.match.spi = 1,
+				},
+			},
+			.len = 1,
+			.flags = XT_POLICY_MATCH_IN,
+		},
+		.t = {
+			.u = {
+				.user = {
+					.target_size = XT_ALIGN(sizeof(ipt.t) + sizeof(ipt.cm)),
+					.name = "CONNMARK",
+					.revision = 1,
+				},
+			},
+		},
+		.cm = {
+			.ctmark = mark,
+			.ctmask = ~0,
+			.nfmask = ~0,
+			.mode = XT_CONNMARK_SET,
+		},
+	};
+
+	if (!ts2in(dst, &ipt.e.ip.dst, &ipt.e.ip.dmsk) ||
+		!ts2in(src, &ipt.e.ip.src, &ipt.e.ip.smsk))
+	{
+		return FALSE;
+	}
+	return manage_rule(ipth, "INPUT", add, &ipt.e);
+}
+
+/**
+ * Add outbund rule restoring CONNMARK on matching traffic
+ */
+static bool manage_out(private_connmark_listener_t *this,
+					   struct iptc_handle *ipth, bool add,
+					   traffic_selector_t *dst, traffic_selector_t *src)
+{
+	struct {
+		struct ipt_entry e;
+		struct ipt_entry_target t;
+		struct xt_connmark_tginfo1 cm;
+	} ipt = {
+		.e  = {
+			.target_offset = XT_ALIGN(sizeof(ipt.e)),
+			.next_offset = sizeof(ipt),
+		},
+		.t = {
+			.u = {
+				.user = {
+					.target_size = XT_ALIGN(sizeof(ipt.t) + sizeof(ipt.cm)),
+					.name = "CONNMARK",
+					.revision = 1,
+				},
+			},
+		},
+		.cm = {
+			.ctmask = ~0,
+			.nfmask = ~0,
+			.mode = XT_CONNMARK_RESTORE,
+		},
+	};
+
+	if (!ts2in(dst, &ipt.e.ip.dst, &ipt.e.ip.dmsk) ||
+		!ts2in(src, &ipt.e.ip.src, &ipt.e.ip.smsk))
+	{
+		return FALSE;
+	}
+	return manage_rule(ipth, "OUTPUT", add, &ipt.e);
+}
+
+/**
+ * Initialize iptables handle, log error
+ */
+static struct iptc_handle* init_handle()
+{
+	struct iptc_handle *ipth;
+
+	ipth = iptc_init("mangle");
+	if (ipth)
+	{
+		return ipth;
+	}
+	DBG1(DBG_CFG, "initializing iptables failed: %s", iptc_strerror(errno));
+	return NULL;
+}
+
+/**
+ * Commit iptables rules, log error
+ */
+static bool commit_handle(struct iptc_handle *ipth)
+{
+	if (iptc_commit(ipth))
+	{
+		return TRUE;
+	}
+	DBG1(DBG_CFG, "forecast iptables commit failed: %s", iptc_strerror(errno));
+	return FALSE;
+}
+
+/**
+ * Add/Remove policies for a CHILD_SA using a iptables handle
+ */
+static bool manage_policies(private_connmark_listener_t *this,
+						struct iptc_handle *ipth, host_t *dst, host_t *src,
+						bool encap, child_sa_t *child_sa, bool add)
+{
+	traffic_selector_t *local, *remote;
+	enumerator_t *enumerator;
+	u_int32_t spi;
+	u_int mark;
+	bool done = TRUE;
+
+	spi = child_sa->get_spi(child_sa, TRUE);
+	mark = child_sa->get_mark(child_sa, TRUE).value;
+
+	enumerator = child_sa->create_policy_enumerator(child_sa);
+	while (enumerator->enumerate(enumerator, &local, &remote))
+	{
+		if (!manage_pre(this, ipth, add, mark, spi, encap, dst, src) ||
+			!manage_in(this, ipth, add, mark, spi, local, remote) ||
+			!manage_out(this, ipth, add, remote, local))
+		{
+			done = FALSE;
+			break;
+		}
+	}
+	enumerator->destroy(enumerator);
+
+	return done;
+}
+
+/**
+ * Check if rules should be installed for given CHILD_SA
+ */
+static bool handle_sa(child_sa_t *child_sa)
+{
+	return child_sa->get_mark(child_sa, TRUE).value &&
+		   child_sa->get_mark(child_sa, FALSE).value &&
+		   child_sa->get_mode(child_sa) == MODE_TRANSPORT &&
+		   child_sa->get_protocol(child_sa) == PROTO_ESP;
+}
+
+METHOD(listener_t, child_updown, bool,
+	private_connmark_listener_t *this, ike_sa_t *ike_sa, child_sa_t *child_sa,
+	bool up)
+{
+	struct iptc_handle *ipth;
+	host_t *dst, *src;
+	bool encap;
+
+	dst = ike_sa->get_my_host(ike_sa);
+	src = ike_sa->get_other_host(ike_sa);
+	encap = child_sa->has_encap(child_sa);
+
+	if (handle_sa(child_sa))
+	{
+		ipth = init_handle();
+		if (ipth)
+		{
+			if (manage_policies(this, ipth, dst, src, encap, child_sa, up))
+			{
+				commit_handle(ipth);
+			}
+			iptc_free(ipth);
+		}
+	}
+	return TRUE;
+}
+
+METHOD(listener_t, child_rekey, bool,
+	private_connmark_listener_t *this, ike_sa_t *ike_sa,
+	child_sa_t *old, child_sa_t *new)
+{
+	struct iptc_handle *ipth;
+	host_t *dst, *src;
+	bool oldencap, newencap;
+
+	dst = ike_sa->get_my_host(ike_sa);
+	src = ike_sa->get_other_host(ike_sa);
+	oldencap = old->has_encap(old);
+	newencap = new->has_encap(new);
+
+	if (handle_sa(old))
+	{
+		ipth = init_handle();
+		if (ipth)
+		{
+			if (manage_policies(this, ipth, dst, src, oldencap, old, FALSE) &&
+				manage_policies(this, ipth, dst, src, newencap, new, TRUE))
+			{
+				commit_handle(ipth);
+			}
+			iptc_free(ipth);
+		}
+	}
+	return TRUE;
+}
+
+METHOD(listener_t, ike_update, bool,
+	private_connmark_listener_t *this, ike_sa_t *ike_sa,
+	bool local, host_t *new)
+{
+	struct iptc_handle *ipth;
+	enumerator_t *enumerator;
+	child_sa_t *child_sa;
+	host_t *dst, *src;
+	bool oldencap, newencap;
+
+	if (local)
+	{
+		dst = new;
+		src = ike_sa->get_other_host(ike_sa);
+	}
+	else
+	{
+		dst = ike_sa->get_my_host(ike_sa);
+		src = new;
+	}
+	/* during ike_update(), has_encap() on the CHILD_SA has not yet been
+	 * updated, but shows the old state. */
+	newencap = ike_sa->has_condition(ike_sa, COND_NAT_ANY);
+
+	enumerator = ike_sa->create_child_sa_enumerator(ike_sa);
+	while (enumerator->enumerate(enumerator, &child_sa))
+	{
+		if (handle_sa(child_sa))
+		{
+			oldencap = child_sa->has_encap(child_sa);
+			ipth = init_handle();
+			if (ipth)
+			{
+				if (manage_policies(this, ipth, dst, src, oldencap,
+									child_sa, FALSE) &&
+					manage_policies(this, ipth, dst, src, newencap,
+									child_sa, TRUE))
+				{
+					commit_handle(ipth);
+				}
+				iptc_free(ipth);
+			}
+		}
+	}
+	enumerator->destroy(enumerator);
+
+	return TRUE;
+}
+
+METHOD(connmark_listener_t, destroy, void,
+	private_connmark_listener_t *this)
+{
+	free(this);
+}
+
+/**
+ * See header
+ */
+connmark_listener_t *connmark_listener_create()
+{
+	private_connmark_listener_t *this;
+
+	INIT(this,
+		.public = {
+			.listener = {
+				.ike_update = _ike_update,
+				.child_updown = _child_updown,
+				.child_rekey = _child_rekey,
+			},
+			.destroy = _destroy,
+		},
+	);
+
+	return &this->public;
+}
diff --git a/src/libcharon/plugins/connmark/connmark_listener.h b/src/libcharon/plugins/connmark/connmark_listener.h
new file mode 100644
index 0000000..2d4098f
--- /dev/null
+++ b/src/libcharon/plugins/connmark/connmark_listener.h
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2014 Martin Willi
+ * Copyright (C) 2014 revosec AG
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * for more details.
+ */
+
+/**
+ * @defgroup connmark_listener connmark_listener
+ * @{ @ingroup connmark
+ */
+
+#ifndef CONNMARK_LISTENER_H_
+#define CONNMARK_LISTENER_H_
+
+#include <bus/listeners/listener.h>
+
+typedef struct connmark_listener_t connmark_listener_t;
+
+/**
+ * Listener to install Netfilter rules
+ */
+struct connmark_listener_t {
+
+	/**
+	 * Implements listener_t interface.
+	 */
+	listener_t listener;
+
+	/**
+	 * Destroy a connmark_listener_t.
+	 */
+	void (*destroy)(connmark_listener_t *this);
+};
+
+/**
+ * Create a connmark_listener instance.
+ */
+connmark_listener_t *connmark_listener_create();
+
+#endif /** CONNMARK_LISTENER_H_ @}*/
diff --git a/src/libcharon/plugins/connmark/connmark_plugin.c b/src/libcharon/plugins/connmark/connmark_plugin.c
new file mode 100644
index 0000000..3f276f9
--- /dev/null
+++ b/src/libcharon/plugins/connmark/connmark_plugin.c
@@ -0,0 +1,105 @@
+/*
+ * Copyright (C) 2014 Martin Willi
+ * Copyright (C) 2014 revosec AG
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * for more details.
+ */
+
+#include "connmark_plugin.h"
+#include "connmark_listener.h"
+
+#include <daemon.h>
+
+typedef struct private_connmark_plugin_t private_connmark_plugin_t;
+
+/**
+ * private data of connmark plugin
+ */
+struct private_connmark_plugin_t {
+
+	/**
+	 * implements plugin interface
+	 */
+	connmark_plugin_t public;
+
+	/**
+	 * Listener installing netfilter rules
+	 */
+	connmark_listener_t *listener;
+};
+
+METHOD(plugin_t, get_name, char*,
+	private_connmark_plugin_t *this)
+{
+	return "connmark";
+}
+
+/**
+ * Register listener
+ */
+static bool plugin_cb(private_connmark_plugin_t *this,
+					  plugin_feature_t *feature, bool reg, void *cb_data)
+{
+	if (reg)
+	{
+		charon->bus->add_listener(charon->bus, &this->listener->listener);
+	}
+	else
+	{
+		charon->bus->remove_listener(charon->bus, &this->listener->listener);
+	}
+	return TRUE;
+}
+
+METHOD(plugin_t, get_features, int,
+	private_connmark_plugin_t *this, plugin_feature_t *features[])
+{
+	static plugin_feature_t f[] = {
+		PLUGIN_CALLBACK((plugin_feature_callback_t)plugin_cb, NULL),
+			PLUGIN_PROVIDE(CUSTOM, "connmark"),
+	};
+	*features = f;
+	return countof(f);
+}
+
+METHOD(plugin_t, destroy, void,
+	private_connmark_plugin_t *this)
+{
+	this->listener->destroy(this->listener);
+	free(this);
+}
+
+/**
+ * Plugin constructor
+ */
+plugin_t *connmark_plugin_create()
+{
+	private_connmark_plugin_t *this;
+
+	if (!lib->caps->keep(lib->caps, CAP_NET_ADMIN))
+	{
+		DBG1(DBG_NET, "connmark plugin requires CAP_NET_ADMIN capability");
+		return NULL;
+	}
+
+	INIT(this,
+		.public = {
+			.plugin = {
+				.get_name = _get_name,
+				.get_features = _get_features,
+				.destroy = _destroy,
+			},
+		},
+		.listener = connmark_listener_create(),
+	);
+
+	return &this->public.plugin;
+}
diff --git a/src/libcharon/plugins/connmark/connmark_plugin.h b/src/libcharon/plugins/connmark/connmark_plugin.h
new file mode 100644
index 0000000..5b4cceb
--- /dev/null
+++ b/src/libcharon/plugins/connmark/connmark_plugin.h
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2014 Martin Willi
+ * Copyright (C) 2014 revosec AG
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * for more details.
+ */
+
+/**
+ * @defgroup connmark connmark
+ * @ingroup cplugins
+ *
+ * @defgroup connmark_plugin connmark_plugin
+ * @{ @ingroup connmark
+ */
+
+#ifndef CONNMARK_PLUGIN_H_
+#define CONNMARK_PLUGIN_H_
+
+#include <plugins/plugin.h>
+
+typedef struct connmark_plugin_t connmark_plugin_t;
+
+/**
+ * Plugin using marks to select return path SA based on conntrack.
+ */
+struct connmark_plugin_t {
+
+	/**
+	 * implements plugin interface
+	 */
+	plugin_t plugin;
+};
+
+#endif /** CONNMARK_PLUGIN_H_ @}*/
diff --git a/src/libcharon/plugins/coupling/Makefile.in b/src/libcharon/plugins/coupling/Makefile.in
index 679d2da..dff80c3 100644
--- a/src/libcharon/plugins/coupling/Makefile.in
+++ b/src/libcharon/plugins/coupling/Makefile.in
@@ -229,6 +229,7 @@ DLLIB = @DLLIB@
 DLLTOOL = @DLLTOOL@
 DSYMUTIL = @DSYMUTIL@
 DUMPBIN = @DUMPBIN@
+EASY_INSTALL = @EASY_INSTALL@
 ECHO_C = @ECHO_C@
 ECHO_N = @ECHO_N@
 ECHO_T = @ECHO_T@
@@ -289,10 +290,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
 PLUGIN_CFLAGS = @PLUGIN_CFLAGS@
 PTHREADLIB = @PTHREADLIB@
 PYTHON = @PYTHON@
+PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@
 PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
 PYTHON_PLATFORM = @PYTHON_PLATFORM@
 PYTHON_PREFIX = @PYTHON_PREFIX@
 PYTHON_VERSION = @PYTHON_VERSION@
+PY_TEST = @PY_TEST@
 RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
@@ -366,6 +369,8 @@ json_CFLAGS = @json_CFLAGS@
 json_LIBS = @json_LIBS@
 libdir = @libdir@
 libexecdir = @libexecdir@
+libiptc_CFLAGS = @libiptc_CFLAGS@
+libiptc_LIBS = @libiptc_LIBS@
 linux_headers = @linux_headers@
 localedir = @localedir@
 localstatedir = @localstatedir@
diff --git a/src/libcharon/plugins/dhcp/Makefile.in b/src/libcharon/plugins/dhcp/Makefile.in
index 768c2b3..1e84f04 100644
--- a/src/libcharon/plugins/dhcp/Makefile.in
+++ b/src/libcharon/plugins/dhcp/Makefile.in
@@ -227,6 +227,7 @@ DLLIB = @DLLIB@
 DLLTOOL = @DLLTOOL@
 DSYMUTIL = @DSYMUTIL@
 DUMPBIN = @DUMPBIN@
+EASY_INSTALL = @EASY_INSTALL@
 ECHO_C = @ECHO_C@
 ECHO_N = @ECHO_N@
 ECHO_T = @ECHO_T@
@@ -287,10 +288,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
 PLUGIN_CFLAGS = @PLUGIN_CFLAGS@
 PTHREADLIB = @PTHREADLIB@
 PYTHON = @PYTHON@
+PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@
 PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
 PYTHON_PLATFORM = @PYTHON_PLATFORM@
 PYTHON_PREFIX = @PYTHON_PREFIX@
 PYTHON_VERSION = @PYTHON_VERSION@
+PY_TEST = @PY_TEST@
 RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
@@ -364,6 +367,8 @@ json_CFLAGS = @json_CFLAGS@
 json_LIBS = @json_LIBS@
 libdir = @libdir@
 libexecdir = @libexecdir@
+libiptc_CFLAGS = @libiptc_CFLAGS@
+libiptc_LIBS = @libiptc_LIBS@
 linux_headers = @linux_headers@
 localedir = @localedir@
 localstatedir = @localstatedir@
diff --git a/src/libcharon/plugins/dhcp/dhcp_plugin.c b/src/libcharon/plugins/dhcp/dhcp_plugin.c
index c36c60d..642e28a 100644
--- a/src/libcharon/plugins/dhcp/dhcp_plugin.c
+++ b/src/libcharon/plugins/dhcp/dhcp_plugin.c
@@ -18,7 +18,6 @@
 
 #include "dhcp_plugin.h"
 
-#include <hydra.h>
 #include <daemon.h>
 #include <plugins/plugin_feature.h>
 
@@ -69,13 +68,13 @@ static bool plugin_cb(private_dhcp_plugin_t *this,
 			return FALSE;
 		}
 		this->provider = dhcp_provider_create(this->socket);
-		hydra->attributes->add_provider(hydra->attributes,
-										&this->provider->provider);
+		charon->attributes->add_provider(charon->attributes,
+										 &this->provider->provider);
 	}
 	else
 	{
-		hydra->attributes->remove_provider(hydra->attributes,
-										   &this->provider->provider);
+		charon->attributes->remove_provider(charon->attributes,
+											&this->provider->provider);
 		this->provider->destroy(this->provider);
 		this->socket->destroy(this->socket);
 	}
diff --git a/src/libcharon/plugins/dhcp/dhcp_provider.c b/src/libcharon/plugins/dhcp/dhcp_provider.c
index f5325b5..f0681b1 100644
--- a/src/libcharon/plugins/dhcp/dhcp_provider.c
+++ b/src/libcharon/plugins/dhcp/dhcp_provider.c
@@ -66,10 +66,11 @@ static uintptr_t hash_transaction(dhcp_transaction_t *transaction)
 
 METHOD(attribute_provider_t, acquire_address, host_t*,
 	private_dhcp_provider_t *this, linked_list_t *pools,
-	identification_t *id, host_t *requested)
+	ike_sa_t *ike_sa, host_t *requested)
 {
 	dhcp_transaction_t *transaction, *old;
 	enumerator_t *enumerator;
+	identification_t *id;
 	char *pool;
 	host_t *vip = NULL;
 
@@ -77,6 +78,7 @@ METHOD(attribute_provider_t, acquire_address, host_t*,
 	{
 		return NULL;
 	}
+	id = ike_sa->get_other_eap_id(ike_sa);
 	enumerator = pools->create_enumerator(pools);
 	while (enumerator->enumerate(enumerator, &pool))
 	{
@@ -104,10 +106,11 @@ METHOD(attribute_provider_t, acquire_address, host_t*,
 
 METHOD(attribute_provider_t, release_address, bool,
 	private_dhcp_provider_t *this, linked_list_t *pools,
-	host_t *address, identification_t *id)
+	host_t *address, ike_sa_t *ike_sa)
 {
 	dhcp_transaction_t *transaction;
 	enumerator_t *enumerator;
+	identification_t *id;
 	bool found = FALSE;
 	char *pool;
 
@@ -115,6 +118,7 @@ METHOD(attribute_provider_t, release_address, bool,
 	{
 		return FALSE;
 	}
+	id = ike_sa->get_other_eap_id(ike_sa);
 	enumerator = pools->create_enumerator(pools);
 	while (enumerator->enumerate(enumerator, &pool))
 	{
@@ -139,11 +143,12 @@ METHOD(attribute_provider_t, release_address, bool,
 }
 
 METHOD(attribute_provider_t, create_attribute_enumerator, enumerator_t*,
-	private_dhcp_provider_t *this, linked_list_t *pools, identification_t *id,
+	private_dhcp_provider_t *this, linked_list_t *pools, ike_sa_t *ike_sa,
 	linked_list_t *vips)
 {
 	dhcp_transaction_t *transaction = NULL;
 	enumerator_t *enumerator;
+	identification_t *id;
 	host_t *vip;
 
 	if (pools->find_first(pools, (linked_list_match_t)streq,
@@ -152,6 +157,7 @@ METHOD(attribute_provider_t, create_attribute_enumerator, enumerator_t*,
 		return NULL;
 	}
 
+	id = ike_sa->get_other_eap_id(ike_sa);
 	this->mutex->lock(this->mutex);
 	enumerator = vips->create_enumerator(vips);
 	while (enumerator->enumerate(enumerator, &vip))
diff --git a/src/libcharon/plugins/dnscert/Makefile.in b/src/libcharon/plugins/dnscert/Makefile.in
index 3484e08..ed873b3 100644
--- a/src/libcharon/plugins/dnscert/Makefile.in
+++ b/src/libcharon/plugins/dnscert/Makefile.in
@@ -229,6 +229,7 @@ DLLIB = @DLLIB@
 DLLTOOL = @DLLTOOL@
 DSYMUTIL = @DSYMUTIL@
 DUMPBIN = @DUMPBIN@
+EASY_INSTALL = @EASY_INSTALL@
 ECHO_C = @ECHO_C@
 ECHO_N = @ECHO_N@
 ECHO_T = @ECHO_T@
@@ -289,10 +290,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
 PLUGIN_CFLAGS = @PLUGIN_CFLAGS@
 PTHREADLIB = @PTHREADLIB@
 PYTHON = @PYTHON@
+PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@
 PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
 PYTHON_PLATFORM = @PYTHON_PLATFORM@
 PYTHON_PREFIX = @PYTHON_PREFIX@
 PYTHON_VERSION = @PYTHON_VERSION@
+PY_TEST = @PY_TEST@
 RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
@@ -366,6 +369,8 @@ json_CFLAGS = @json_CFLAGS@
 json_LIBS = @json_LIBS@
 libdir = @libdir@
 libexecdir = @libexecdir@
+libiptc_CFLAGS = @libiptc_CFLAGS@
+libiptc_LIBS = @libiptc_LIBS@
 linux_headers = @linux_headers@
 localedir = @localedir@
 localstatedir = @localstatedir@
diff --git a/src/libcharon/plugins/duplicheck/Makefile.in b/src/libcharon/plugins/duplicheck/Makefile.in
index 381d7a1..41862cb 100644
--- a/src/libcharon/plugins/duplicheck/Makefile.in
+++ b/src/libcharon/plugins/duplicheck/Makefile.in
@@ -236,6 +236,7 @@ DLLIB = @DLLIB@
 DLLTOOL = @DLLTOOL@
 DSYMUTIL = @DSYMUTIL@
 DUMPBIN = @DUMPBIN@
+EASY_INSTALL = @EASY_INSTALL@
 ECHO_C = @ECHO_C@
 ECHO_N = @ECHO_N@
 ECHO_T = @ECHO_T@
@@ -296,10 +297,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
 PLUGIN_CFLAGS = @PLUGIN_CFLAGS@
 PTHREADLIB = @PTHREADLIB@
 PYTHON = @PYTHON@
+PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@
 PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
 PYTHON_PLATFORM = @PYTHON_PLATFORM@
 PYTHON_PREFIX = @PYTHON_PREFIX@
 PYTHON_VERSION = @PYTHON_VERSION@
+PY_TEST = @PY_TEST@
 RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
@@ -373,6 +376,8 @@ json_CFLAGS = @json_CFLAGS@
 json_LIBS = @json_LIBS@
 libdir = @libdir@
 libexecdir = @libexecdir@
+libiptc_CFLAGS = @libiptc_CFLAGS@
+libiptc_LIBS = @libiptc_LIBS@
 linux_headers = @linux_headers@
 localedir = @localedir@
 localstatedir = @localstatedir@
diff --git a/src/libcharon/plugins/eap_aka/Makefile.in b/src/libcharon/plugins/eap_aka/Makefile.in
index 3b0f876..dacddfb 100644
--- a/src/libcharon/plugins/eap_aka/Makefile.in
+++ b/src/libcharon/plugins/eap_aka/Makefile.in
@@ -230,6 +230,7 @@ DLLIB = @DLLIB@
 DLLTOOL = @DLLTOOL@
 DSYMUTIL = @DSYMUTIL@
 DUMPBIN = @DUMPBIN@
+EASY_INSTALL = @EASY_INSTALL@
 ECHO_C = @ECHO_C@
 ECHO_N = @ECHO_N@
 ECHO_T = @ECHO_T@
@@ -290,10 +291,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
 PLUGIN_CFLAGS = @PLUGIN_CFLAGS@
 PTHREADLIB = @PTHREADLIB@
 PYTHON = @PYTHON@
+PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@
 PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
 PYTHON_PLATFORM = @PYTHON_PLATFORM@
 PYTHON_PREFIX = @PYTHON_PREFIX@
 PYTHON_VERSION = @PYTHON_VERSION@
+PY_TEST = @PY_TEST@
 RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
@@ -367,6 +370,8 @@ json_CFLAGS = @json_CFLAGS@
 json_LIBS = @json_LIBS@
 libdir = @libdir@
 libexecdir = @libexecdir@
+libiptc_CFLAGS = @libiptc_CFLAGS@
+libiptc_LIBS = @libiptc_LIBS@
 linux_headers = @linux_headers@
 localedir = @localedir@
 localstatedir = @localstatedir@
diff --git a/src/libcharon/plugins/eap_aka_3gpp2/Makefile.in b/src/libcharon/plugins/eap_aka_3gpp2/Makefile.in
index 839a379..3c26b85 100644
--- a/src/libcharon/plugins/eap_aka_3gpp2/Makefile.in
+++ b/src/libcharon/plugins/eap_aka_3gpp2/Makefile.in
@@ -231,6 +231,7 @@ DLLIB = @DLLIB@
 DLLTOOL = @DLLTOOL@
 DSYMUTIL = @DSYMUTIL@
 DUMPBIN = @DUMPBIN@
+EASY_INSTALL = @EASY_INSTALL@
 ECHO_C = @ECHO_C@
 ECHO_N = @ECHO_N@
 ECHO_T = @ECHO_T@
@@ -291,10 +292,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
 PLUGIN_CFLAGS = @PLUGIN_CFLAGS@
 PTHREADLIB = @PTHREADLIB@
 PYTHON = @PYTHON@
+PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@
 PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
 PYTHON_PLATFORM = @PYTHON_PLATFORM@
 PYTHON_PREFIX = @PYTHON_PREFIX@
 PYTHON_VERSION = @PYTHON_VERSION@
+PY_TEST = @PY_TEST@
 RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
@@ -368,6 +371,8 @@ json_CFLAGS = @json_CFLAGS@
 json_LIBS = @json_LIBS@
 libdir = @libdir@
 libexecdir = @libexecdir@
+libiptc_CFLAGS = @libiptc_CFLAGS@
+libiptc_LIBS = @libiptc_LIBS@
 linux_headers = @linux_headers@
 localedir = @localedir@
 localstatedir = @localstatedir@
diff --git a/src/libcharon/plugins/eap_dynamic/Makefile.in b/src/libcharon/plugins/eap_dynamic/Makefile.in
index fdbad62..402c7ca 100644
--- a/src/libcharon/plugins/eap_dynamic/Makefile.in
+++ b/src/libcharon/plugins/eap_dynamic/Makefile.in
@@ -229,6 +229,7 @@ DLLIB = @DLLIB@
 DLLTOOL = @DLLTOOL@
 DSYMUTIL = @DSYMUTIL@
 DUMPBIN = @DUMPBIN@
+EASY_INSTALL = @EASY_INSTALL@
 ECHO_C = @ECHO_C@
 ECHO_N = @ECHO_N@
 ECHO_T = @ECHO_T@
@@ -289,10 +290,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
 PLUGIN_CFLAGS = @PLUGIN_CFLAGS@
 PTHREADLIB = @PTHREADLIB@
 PYTHON = @PYTHON@
+PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@
 PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
 PYTHON_PLATFORM = @PYTHON_PLATFORM@
 PYTHON_PREFIX = @PYTHON_PREFIX@
 PYTHON_VERSION = @PYTHON_VERSION@
+PY_TEST = @PY_TEST@
 RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
@@ -366,6 +369,8 @@ json_CFLAGS = @json_CFLAGS@
 json_LIBS = @json_LIBS@
 libdir = @libdir@
 libexecdir = @libexecdir@
+libiptc_CFLAGS = @libiptc_CFLAGS@
+libiptc_LIBS = @libiptc_LIBS@
 linux_headers = @linux_headers@
 localedir = @localedir@
 localstatedir = @localstatedir@
diff --git a/src/libcharon/plugins/eap_gtc/Makefile.in b/src/libcharon/plugins/eap_gtc/Makefile.in
index 9675104..2279b25 100644
--- a/src/libcharon/plugins/eap_gtc/Makefile.in
+++ b/src/libcharon/plugins/eap_gtc/Makefile.in
@@ -228,6 +228,7 @@ DLLIB = @DLLIB@
 DLLTOOL = @DLLTOOL@
 DSYMUTIL = @DSYMUTIL@
 DUMPBIN = @DUMPBIN@
+EASY_INSTALL = @EASY_INSTALL@
 ECHO_C = @ECHO_C@
 ECHO_N = @ECHO_N@
 ECHO_T = @ECHO_T@
@@ -288,10 +289,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
 PLUGIN_CFLAGS = @PLUGIN_CFLAGS@
 PTHREADLIB = @PTHREADLIB@
 PYTHON = @PYTHON@
+PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@
 PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
 PYTHON_PLATFORM = @PYTHON_PLATFORM@
 PYTHON_PREFIX = @PYTHON_PREFIX@
 PYTHON_VERSION = @PYTHON_VERSION@
+PY_TEST = @PY_TEST@
 RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
@@ -365,6 +368,8 @@ json_CFLAGS = @json_CFLAGS@
 json_LIBS = @json_LIBS@
 libdir = @libdir@
 libexecdir = @libexecdir@
+libiptc_CFLAGS = @libiptc_CFLAGS@
+libiptc_LIBS = @libiptc_LIBS@
 linux_headers = @linux_headers@
 localedir = @localedir@
 localstatedir = @localstatedir@
diff --git a/src/libcharon/plugins/eap_identity/Makefile.in b/src/libcharon/plugins/eap_identity/Makefile.in
index 0610b58..30d2c88 100644
--- a/src/libcharon/plugins/eap_identity/Makefile.in
+++ b/src/libcharon/plugins/eap_identity/Makefile.in
@@ -229,6 +229,7 @@ DLLIB = @DLLIB@
 DLLTOOL = @DLLTOOL@
 DSYMUTIL = @DSYMUTIL@
 DUMPBIN = @DUMPBIN@
+EASY_INSTALL = @EASY_INSTALL@
 ECHO_C = @ECHO_C@
 ECHO_N = @ECHO_N@
 ECHO_T = @ECHO_T@
@@ -289,10 +290,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
 PLUGIN_CFLAGS = @PLUGIN_CFLAGS@
 PTHREADLIB = @PTHREADLIB@
 PYTHON = @PYTHON@
+PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@
 PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
 PYTHON_PLATFORM = @PYTHON_PLATFORM@
 PYTHON_PREFIX = @PYTHON_PREFIX@
 PYTHON_VERSION = @PYTHON_VERSION@
+PY_TEST = @PY_TEST@
 RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
@@ -366,6 +369,8 @@ json_CFLAGS = @json_CFLAGS@
 json_LIBS = @json_LIBS@
 libdir = @libdir@
 libexecdir = @libexecdir@
+libiptc_CFLAGS = @libiptc_CFLAGS@
+libiptc_LIBS = @libiptc_LIBS@
 linux_headers = @linux_headers@
 localedir = @localedir@
 localstatedir = @localstatedir@
diff --git a/src/libcharon/plugins/eap_md5/Makefile.in b/src/libcharon/plugins/eap_md5/Makefile.in
index 38c9d0b..14616c2 100644
--- a/src/libcharon/plugins/eap_md5/Makefile.in
+++ b/src/libcharon/plugins/eap_md5/Makefile.in
@@ -228,6 +228,7 @@ DLLIB = @DLLIB@
 DLLTOOL = @DLLTOOL@
 DSYMUTIL = @DSYMUTIL@
 DUMPBIN = @DUMPBIN@
+EASY_INSTALL = @EASY_INSTALL@
 ECHO_C = @ECHO_C@
 ECHO_N = @ECHO_N@
 ECHO_T = @ECHO_T@
@@ -288,10 +289,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
 PLUGIN_CFLAGS = @PLUGIN_CFLAGS@
 PTHREADLIB = @PTHREADLIB@
 PYTHON = @PYTHON@
+PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@
 PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
 PYTHON_PLATFORM = @PYTHON_PLATFORM@
 PYTHON_PREFIX = @PYTHON_PREFIX@
 PYTHON_VERSION = @PYTHON_VERSION@
+PY_TEST = @PY_TEST@
 RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
@@ -365,6 +368,8 @@ json_CFLAGS = @json_CFLAGS@
 json_LIBS = @json_LIBS@
 libdir = @libdir@
 libexecdir = @libexecdir@
+libiptc_CFLAGS = @libiptc_CFLAGS@
+libiptc_LIBS = @libiptc_LIBS@
 linux_headers = @linux_headers@
 localedir = @localedir@
 localstatedir = @localstatedir@
diff --git a/src/libcharon/plugins/eap_mschapv2/Makefile.in b/src/libcharon/plugins/eap_mschapv2/Makefile.in
index f5dfd68..78dfd29 100644
--- a/src/libcharon/plugins/eap_mschapv2/Makefile.in
+++ b/src/libcharon/plugins/eap_mschapv2/Makefile.in
@@ -229,6 +229,7 @@ DLLIB = @DLLIB@
 DLLTOOL = @DLLTOOL@
 DSYMUTIL = @DSYMUTIL@
 DUMPBIN = @DUMPBIN@
+EASY_INSTALL = @EASY_INSTALL@
 ECHO_C = @ECHO_C@
 ECHO_N = @ECHO_N@
 ECHO_T = @ECHO_T@
@@ -289,10 +290,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
 PLUGIN_CFLAGS = @PLUGIN_CFLAGS@
 PTHREADLIB = @PTHREADLIB@
 PYTHON = @PYTHON@
+PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@
 PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
 PYTHON_PLATFORM = @PYTHON_PLATFORM@
 PYTHON_PREFIX = @PYTHON_PREFIX@
 PYTHON_VERSION = @PYTHON_VERSION@
+PY_TEST = @PY_TEST@
 RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
@@ -366,6 +369,8 @@ json_CFLAGS = @json_CFLAGS@
 json_LIBS = @json_LIBS@
 libdir = @libdir@
 libexecdir = @libexecdir@
+libiptc_CFLAGS = @libiptc_CFLAGS@
+libiptc_LIBS = @libiptc_LIBS@
 linux_headers = @linux_headers@
 localedir = @localedir@
 localstatedir = @localstatedir@
diff --git a/src/libcharon/plugins/eap_peap/Makefile.in b/src/libcharon/plugins/eap_peap/Makefile.in
index 5ccd581..2f0d65d 100644
--- a/src/libcharon/plugins/eap_peap/Makefile.in
+++ b/src/libcharon/plugins/eap_peap/Makefile.in
@@ -230,6 +230,7 @@ DLLIB = @DLLIB@
 DLLTOOL = @DLLTOOL@
 DSYMUTIL = @DSYMUTIL@
 DUMPBIN = @DUMPBIN@
+EASY_INSTALL = @EASY_INSTALL@
 ECHO_C = @ECHO_C@
 ECHO_N = @ECHO_N@
 ECHO_T = @ECHO_T@
@@ -290,10 +291,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
 PLUGIN_CFLAGS = @PLUGIN_CFLAGS@
 PTHREADLIB = @PTHREADLIB@
 PYTHON = @PYTHON@
+PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@
 PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
 PYTHON_PLATFORM = @PYTHON_PLATFORM@
 PYTHON_PREFIX = @PYTHON_PREFIX@
 PYTHON_VERSION = @PYTHON_VERSION@
+PY_TEST = @PY_TEST@
 RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
@@ -367,6 +370,8 @@ json_CFLAGS = @json_CFLAGS@
 json_LIBS = @json_LIBS@
 libdir = @libdir@
 libexecdir = @libexecdir@
+libiptc_CFLAGS = @libiptc_CFLAGS@
+libiptc_LIBS = @libiptc_LIBS@
 linux_headers = @linux_headers@
 localedir = @localedir@
 localstatedir = @localstatedir@
diff --git a/src/libcharon/plugins/eap_radius/Makefile.in b/src/libcharon/plugins/eap_radius/Makefile.in
index 04cc422..4753437 100644
--- a/src/libcharon/plugins/eap_radius/Makefile.in
+++ b/src/libcharon/plugins/eap_radius/Makefile.in
@@ -231,6 +231,7 @@ DLLIB = @DLLIB@
 DLLTOOL = @DLLTOOL@
 DSYMUTIL = @DSYMUTIL@
 DUMPBIN = @DUMPBIN@
+EASY_INSTALL = @EASY_INSTALL@
 ECHO_C = @ECHO_C@
 ECHO_N = @ECHO_N@
 ECHO_T = @ECHO_T@
@@ -291,10 +292,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
 PLUGIN_CFLAGS = @PLUGIN_CFLAGS@
 PTHREADLIB = @PTHREADLIB@
 PYTHON = @PYTHON@
+PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@
 PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
 PYTHON_PLATFORM = @PYTHON_PLATFORM@
 PYTHON_PREFIX = @PYTHON_PREFIX@
 PYTHON_VERSION = @PYTHON_VERSION@
+PY_TEST = @PY_TEST@
 RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
@@ -368,6 +371,8 @@ json_CFLAGS = @json_CFLAGS@
 json_LIBS = @json_LIBS@
 libdir = @libdir@
 libexecdir = @libexecdir@
+libiptc_CFLAGS = @libiptc_CFLAGS@
+libiptc_LIBS = @libiptc_LIBS@
 linux_headers = @linux_headers@
 localedir = @localedir@
 localstatedir = @localstatedir@
diff --git a/src/libcharon/plugins/eap_radius/eap_radius_accounting.c b/src/libcharon/plugins/eap_radius/eap_radius_accounting.c
index 31c96d2..ac4ecfc 100644
--- a/src/libcharon/plugins/eap_radius/eap_radius_accounting.c
+++ b/src/libcharon/plugins/eap_radius/eap_radius_accounting.c
@@ -99,7 +99,7 @@ typedef struct {
 	/** IKE_SA identifier this entry is stored under */
 	ike_sa_id_t *id;
 	/** RADIUS accounting session ID */
-	char sid[16];
+	char sid[24];
 	/** number of sent/received octets/packets */
 	struct {
 		u_int64_t sent;
diff --git a/src/libcharon/plugins/eap_radius/eap_radius_plugin.c b/src/libcharon/plugins/eap_radius/eap_radius_plugin.c
index 1a48c07..6a4a038 100644
--- a/src/libcharon/plugins/eap_radius/eap_radius_plugin.c
+++ b/src/libcharon/plugins/eap_radius/eap_radius_plugin.c
@@ -26,7 +26,7 @@
 #include <radius_client.h>
 #include <radius_config.h>
 
-#include <hydra.h>
+#include <daemon.h>
 #include <threading/rwlock.h>
 #include <processing/jobs/callback_job.h>
 #include <processing/jobs/delete_ike_sa_job.h>
@@ -149,19 +149,26 @@ static void load_configs(private_eap_radius_plugin_t *this)
 			continue;
 		}
 		nas_identifier = lib->settings->get_str(lib->settings,
-				"%s.plugins.eap-radius.servers.%s.nas_identifier", "strongSwan",
+				"%s.plugins.eap-radius.servers.%s.nas_identifier",
+					lib->settings->get_str(lib->settings,
+						"%s.plugins.eap-radius.nas_identifier", "strongSwan",
+						lib->ns),
 				lib->ns, section);
 		auth_port = lib->settings->get_int(lib->settings,
 			"%s.plugins.eap-radius.servers.%s.auth_port",
 				lib->settings->get_int(lib->settings,
 					"%s.plugins.eap-radius.servers.%s.port",
-					AUTH_PORT, lib->ns, section),
+						lib->settings->get_int(lib->settings,
+							"%s.plugins.eap-radius.port", AUTH_PORT, lib->ns),
+					lib->ns, section),
 			lib->ns, section);
 		acct_port = lib->settings->get_int(lib->settings,
 				"%s.plugins.eap-radius.servers.%s.acct_port", ACCT_PORT,
 				lib->ns, section);
 		sockets = lib->settings->get_int(lib->settings,
-				"%s.plugins.eap-radius.servers.%s.sockets", 1,
+				"%s.plugins.eap-radius.servers.%s.sockets",
+					lib->settings->get_int(lib->settings,
+						"%s.plugins.eap-radius.sockets", 1, lib->ns),
 				lib->ns, section);
 		preference = lib->settings->get_int(lib->settings,
 				"%s.plugins.eap-radius.servers.%s.preference", 0,
@@ -211,13 +218,13 @@ static bool plugin_cb(private_eap_radius_plugin_t *this,
 		{
 			charon->bus->add_listener(charon->bus, &this->forward->listener);
 		}
-		hydra->attributes->add_provider(hydra->attributes,
-										&this->provider->provider);
+		charon->attributes->add_provider(charon->attributes,
+										 &this->provider->provider);
 	}
 	else
 	{
-		hydra->attributes->remove_provider(hydra->attributes,
-										   &this->provider->provider);
+		charon->attributes->remove_provider(charon->attributes,
+											&this->provider->provider);
 		if (this->forward)
 		{
 			charon->bus->remove_listener(charon->bus, &this->forward->listener);
diff --git a/src/libcharon/plugins/eap_radius/eap_radius_provider.c b/src/libcharon/plugins/eap_radius/eap_radius_provider.c
index 7c79461..0cf7237 100644
--- a/src/libcharon/plugins/eap_radius/eap_radius_provider.c
+++ b/src/libcharon/plugins/eap_radius/eap_radius_provider.c
@@ -311,19 +311,13 @@ METHOD(listener_t, ike_rekey, bool,
 
 METHOD(attribute_provider_t, acquire_address, host_t*,
 	private_eap_radius_provider_t *this, linked_list_t *pools,
-	identification_t *id, host_t *requested)
+	ike_sa_t *ike_sa, host_t *requested)
 {
 	enumerator_t *enumerator;
 	host_t *addr = NULL;
-	ike_sa_t *ike_sa;
 	uintptr_t sa;
 	char *name;
 
-	ike_sa = charon->bus->get_sa(charon->bus);
-	if (!ike_sa)
-	{
-		return NULL;
-	}
 	sa = ike_sa->get_unique_id(ike_sa);
 
 	enumerator = pools->create_enumerator(pools);
@@ -348,19 +342,13 @@ METHOD(attribute_provider_t, acquire_address, host_t*,
 
 METHOD(attribute_provider_t, release_address, bool,
 	private_eap_radius_provider_t *this, linked_list_t *pools, host_t *address,
-	identification_t *id)
+	ike_sa_t *ike_sa)
 {
 	enumerator_t *enumerator;
 	host_t *found = NULL;
-	ike_sa_t *ike_sa;
 	uintptr_t sa;
 	char *name;
 
-	ike_sa = charon->bus->get_sa(charon->bus);
-	if (!ike_sa)
-	{
-		return FALSE;
-	}
 	sa = ike_sa->get_unique_id(ike_sa);
 
 	enumerator = pools->create_enumerator(pools);
@@ -428,18 +416,12 @@ METHOD(enumerator_t, attribute_destroy, void,
 
 METHOD(attribute_provider_t, create_attribute_enumerator, enumerator_t*,
 	private_eap_radius_provider_t *this, linked_list_t *pools,
-	identification_t *id, linked_list_t *vips)
+	ike_sa_t *ike_sa, linked_list_t *vips)
 {
 	attribute_enumerator_t *enumerator;
 	attr_t *attr;
-	ike_sa_t *ike_sa;
 	uintptr_t sa;
 
-	ike_sa = charon->bus->get_sa(charon->bus);
-	if (!ike_sa)
-	{
-		return NULL;
-	}
 	sa = ike_sa->get_unique_id(ike_sa);
 
 	INIT(enumerator,
diff --git a/src/libcharon/plugins/eap_sim/Makefile.in b/src/libcharon/plugins/eap_sim/Makefile.in
index 6a00ea7..251eeee 100644
--- a/src/libcharon/plugins/eap_sim/Makefile.in
+++ b/src/libcharon/plugins/eap_sim/Makefile.in
@@ -230,6 +230,7 @@ DLLIB = @DLLIB@
 DLLTOOL = @DLLTOOL@
 DSYMUTIL = @DSYMUTIL@
 DUMPBIN = @DUMPBIN@
+EASY_INSTALL = @EASY_INSTALL@
 ECHO_C = @ECHO_C@
 ECHO_N = @ECHO_N@
 ECHO_T = @ECHO_T@
@@ -290,10 +291,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
 PLUGIN_CFLAGS = @PLUGIN_CFLAGS@
 PTHREADLIB = @PTHREADLIB@
 PYTHON = @PYTHON@
+PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@
 PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
 PYTHON_PLATFORM = @PYTHON_PLATFORM@
 PYTHON_PREFIX = @PYTHON_PREFIX@
 PYTHON_VERSION = @PYTHON_VERSION@
+PY_TEST = @PY_TEST@
 RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
@@ -367,6 +370,8 @@ json_CFLAGS = @json_CFLAGS@
 json_LIBS = @json_LIBS@
 libdir = @libdir@
 libexecdir = @libexecdir@
+libiptc_CFLAGS = @libiptc_CFLAGS@
+libiptc_LIBS = @libiptc_LIBS@
 linux_headers = @linux_headers@
 localedir = @localedir@
 localstatedir = @localstatedir@
diff --git a/src/libcharon/plugins/eap_sim_file/Makefile.in b/src/libcharon/plugins/eap_sim_file/Makefile.in
index 7a08f4e..bffcbc0 100644
--- a/src/libcharon/plugins/eap_sim_file/Makefile.in
+++ b/src/libcharon/plugins/eap_sim_file/Makefile.in
@@ -231,6 +231,7 @@ DLLIB = @DLLIB@
 DLLTOOL = @DLLTOOL@
 DSYMUTIL = @DSYMUTIL@
 DUMPBIN = @DUMPBIN@
+EASY_INSTALL = @EASY_INSTALL@
 ECHO_C = @ECHO_C@
 ECHO_N = @ECHO_N@
 ECHO_T = @ECHO_T@
@@ -291,10 +292,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
 PLUGIN_CFLAGS = @PLUGIN_CFLAGS@
 PTHREADLIB = @PTHREADLIB@
 PYTHON = @PYTHON@
+PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@
 PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
 PYTHON_PLATFORM = @PYTHON_PLATFORM@
 PYTHON_PREFIX = @PYTHON_PREFIX@
 PYTHON_VERSION = @PYTHON_VERSION@
+PY_TEST = @PY_TEST@
 RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
@@ -368,6 +371,8 @@ json_CFLAGS = @json_CFLAGS@
 json_LIBS = @json_LIBS@
 libdir = @libdir@
 libexecdir = @libexecdir@
+libiptc_CFLAGS = @libiptc_CFLAGS@
+libiptc_LIBS = @libiptc_LIBS@
 linux_headers = @linux_headers@
 localedir = @localedir@
 localstatedir = @localstatedir@
diff --git a/src/libcharon/plugins/eap_sim_pcsc/Makefile.in b/src/libcharon/plugins/eap_sim_pcsc/Makefile.in
index a1ec7ad..78682ce 100644
--- a/src/libcharon/plugins/eap_sim_pcsc/Makefile.in
+++ b/src/libcharon/plugins/eap_sim_pcsc/Makefile.in
@@ -232,6 +232,7 @@ DLLIB = @DLLIB@
 DLLTOOL = @DLLTOOL@
 DSYMUTIL = @DSYMUTIL@
 DUMPBIN = @DUMPBIN@
+EASY_INSTALL = @EASY_INSTALL@
 ECHO_C = @ECHO_C@
 ECHO_N = @ECHO_N@
 ECHO_T = @ECHO_T@
@@ -292,10 +293,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
 PLUGIN_CFLAGS = @PLUGIN_CFLAGS@
 PTHREADLIB = @PTHREADLIB@
 PYTHON = @PYTHON@
+PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@
 PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
 PYTHON_PLATFORM = @PYTHON_PLATFORM@
 PYTHON_PREFIX = @PYTHON_PREFIX@
 PYTHON_VERSION = @PYTHON_VERSION@
+PY_TEST = @PY_TEST@
 RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
@@ -369,6 +372,8 @@ json_CFLAGS = @json_CFLAGS@
 json_LIBS = @json_LIBS@
 libdir = @libdir@
 libexecdir = @libexecdir@
+libiptc_CFLAGS = @libiptc_CFLAGS@
+libiptc_LIBS = @libiptc_LIBS@
 linux_headers = @linux_headers@
 localedir = @localedir@
 localstatedir = @localstatedir@
diff --git a/src/libcharon/plugins/eap_simaka_pseudonym/Makefile.in b/src/libcharon/plugins/eap_simaka_pseudonym/Makefile.in
index bf99ab0..2a6be5f 100644
--- a/src/libcharon/plugins/eap_simaka_pseudonym/Makefile.in
+++ b/src/libcharon/plugins/eap_simaka_pseudonym/Makefile.in
@@ -232,6 +232,7 @@ DLLIB = @DLLIB@
 DLLTOOL = @DLLTOOL@
 DSYMUTIL = @DSYMUTIL@
 DUMPBIN = @DUMPBIN@
+EASY_INSTALL = @EASY_INSTALL@
 ECHO_C = @ECHO_C@
 ECHO_N = @ECHO_N@
 ECHO_T = @ECHO_T@
@@ -292,10 +293,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
 PLUGIN_CFLAGS = @PLUGIN_CFLAGS@
 PTHREADLIB = @PTHREADLIB@
 PYTHON = @PYTHON@
+PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@
 PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
 PYTHON_PLATFORM = @PYTHON_PLATFORM@
 PYTHON_PREFIX = @PYTHON_PREFIX@
 PYTHON_VERSION = @PYTHON_VERSION@
+PY_TEST = @PY_TEST@
 RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
@@ -369,6 +372,8 @@ json_CFLAGS = @json_CFLAGS@
 json_LIBS = @json_LIBS@
 libdir = @libdir@
 libexecdir = @libexecdir@
+libiptc_CFLAGS = @libiptc_CFLAGS@
+libiptc_LIBS = @libiptc_LIBS@
 linux_headers = @linux_headers@
 localedir = @localedir@
 localstatedir = @localstatedir@
diff --git a/src/libcharon/plugins/eap_simaka_reauth/Makefile.in b/src/libcharon/plugins/eap_simaka_reauth/Makefile.in
index ce46023..de504d4 100644
--- a/src/libcharon/plugins/eap_simaka_reauth/Makefile.in
+++ b/src/libcharon/plugins/eap_simaka_reauth/Makefile.in
@@ -231,6 +231,7 @@ DLLIB = @DLLIB@
 DLLTOOL = @DLLTOOL@
 DSYMUTIL = @DSYMUTIL@
 DUMPBIN = @DUMPBIN@
+EASY_INSTALL = @EASY_INSTALL@
 ECHO_C = @ECHO_C@
 ECHO_N = @ECHO_N@
 ECHO_T = @ECHO_T@
@@ -291,10 +292,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
 PLUGIN_CFLAGS = @PLUGIN_CFLAGS@
 PTHREADLIB = @PTHREADLIB@
 PYTHON = @PYTHON@
+PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@
 PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
 PYTHON_PLATFORM = @PYTHON_PLATFORM@
 PYTHON_PREFIX = @PYTHON_PREFIX@
 PYTHON_VERSION = @PYTHON_VERSION@
+PY_TEST = @PY_TEST@
 RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
@@ -368,6 +371,8 @@ json_CFLAGS = @json_CFLAGS@
 json_LIBS = @json_LIBS@
 libdir = @libdir@
 libexecdir = @libexecdir@
+libiptc_CFLAGS = @libiptc_CFLAGS@
+libiptc_LIBS = @libiptc_LIBS@
 linux_headers = @linux_headers@
 localedir = @localedir@
 localstatedir = @localstatedir@
diff --git a/src/libcharon/plugins/eap_simaka_sql/Makefile.in b/src/libcharon/plugins/eap_simaka_sql/Makefile.in
index 0c0b7fd..de3508a 100644
--- a/src/libcharon/plugins/eap_simaka_sql/Makefile.in
+++ b/src/libcharon/plugins/eap_simaka_sql/Makefile.in
@@ -230,6 +230,7 @@ DLLIB = @DLLIB@
 DLLTOOL = @DLLTOOL@
 DSYMUTIL = @DSYMUTIL@
 DUMPBIN = @DUMPBIN@
+EASY_INSTALL = @EASY_INSTALL@
 ECHO_C = @ECHO_C@
 ECHO_N = @ECHO_N@
 ECHO_T = @ECHO_T@
@@ -290,10 +291,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
 PLUGIN_CFLAGS = @PLUGIN_CFLAGS@
 PTHREADLIB = @PTHREADLIB@
 PYTHON = @PYTHON@
+PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@
 PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
 PYTHON_PLATFORM = @PYTHON_PLATFORM@
 PYTHON_PREFIX = @PYTHON_PREFIX@
 PYTHON_VERSION = @PYTHON_VERSION@
+PY_TEST = @PY_TEST@
 RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
@@ -367,6 +370,8 @@ json_CFLAGS = @json_CFLAGS@
 json_LIBS = @json_LIBS@
 libdir = @libdir@
 libexecdir = @libexecdir@
+libiptc_CFLAGS = @libiptc_CFLAGS@
+libiptc_LIBS = @libiptc_LIBS@
 linux_headers = @linux_headers@
 localedir = @localedir@
 localstatedir = @localstatedir@
diff --git a/src/libcharon/plugins/eap_tls/Makefile.in b/src/libcharon/plugins/eap_tls/Makefile.in
index 25696f5..d4219b8 100644
--- a/src/libcharon/plugins/eap_tls/Makefile.in
+++ b/src/libcharon/plugins/eap_tls/Makefile.in
@@ -229,6 +229,7 @@ DLLIB = @DLLIB@
 DLLTOOL = @DLLTOOL@
 DSYMUTIL = @DSYMUTIL@
 DUMPBIN = @DUMPBIN@
+EASY_INSTALL = @EASY_INSTALL@
 ECHO_C = @ECHO_C@
 ECHO_N = @ECHO_N@
 ECHO_T = @ECHO_T@
@@ -289,10 +290,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
 PLUGIN_CFLAGS = @PLUGIN_CFLAGS@
 PTHREADLIB = @PTHREADLIB@
 PYTHON = @PYTHON@
+PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@
 PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
 PYTHON_PLATFORM = @PYTHON_PLATFORM@
 PYTHON_PREFIX = @PYTHON_PREFIX@
 PYTHON_VERSION = @PYTHON_VERSION@
+PY_TEST = @PY_TEST@
 RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
@@ -366,6 +369,8 @@ json_CFLAGS = @json_CFLAGS@
 json_LIBS = @json_LIBS@
 libdir = @libdir@
 libexecdir = @libexecdir@
+libiptc_CFLAGS = @libiptc_CFLAGS@
+libiptc_LIBS = @libiptc_LIBS@
 linux_headers = @linux_headers@
 localedir = @localedir@
 localstatedir = @localstatedir@
diff --git a/src/libcharon/plugins/eap_tls/eap_tls.c b/src/libcharon/plugins/eap_tls/eap_tls.c
index dffbaf2..bc01ba5 100644
--- a/src/libcharon/plugins/eap_tls/eap_tls.c
+++ b/src/libcharon/plugins/eap_tls/eap_tls.c
@@ -109,6 +109,12 @@ METHOD(eap_method_t, is_mutual, bool,
 	return TRUE;
 }
 
+METHOD(eap_method_t, get_auth, auth_cfg_t*,
+	private_eap_tls_t *this)
+{
+	return this->tls_eap->get_auth(this->tls_eap);
+}
+
 METHOD(eap_method_t, destroy, void,
 	private_eap_tls_t *this)
 {
@@ -138,6 +144,7 @@ static eap_tls_t *eap_tls_create(identification_t *server,
 				.get_msk = _get_msk,
 				.get_identifier = _get_identifier,
 				.set_identifier = _set_identifier,
+				.get_auth = _get_auth,
 				.destroy = _destroy,
 			},
 		},
diff --git a/src/libcharon/plugins/eap_tnc/Makefile.in b/src/libcharon/plugins/eap_tnc/Makefile.in
index 2d5d658..6c34ed0 100644
--- a/src/libcharon/plugins/eap_tnc/Makefile.in
+++ b/src/libcharon/plugins/eap_tnc/Makefile.in
@@ -230,6 +230,7 @@ DLLIB = @DLLIB@
 DLLTOOL = @DLLTOOL@
 DSYMUTIL = @DSYMUTIL@
 DUMPBIN = @DUMPBIN@
+EASY_INSTALL = @EASY_INSTALL@
 ECHO_C = @ECHO_C@
 ECHO_N = @ECHO_N@
 ECHO_T = @ECHO_T@
@@ -290,10 +291,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
 PLUGIN_CFLAGS = @PLUGIN_CFLAGS@
 PTHREADLIB = @PTHREADLIB@
 PYTHON = @PYTHON@
+PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@
 PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
 PYTHON_PLATFORM = @PYTHON_PLATFORM@
 PYTHON_PREFIX = @PYTHON_PREFIX@
 PYTHON_VERSION = @PYTHON_VERSION@
+PY_TEST = @PY_TEST@
 RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
@@ -367,6 +370,8 @@ json_CFLAGS = @json_CFLAGS@
 json_LIBS = @json_LIBS@
 libdir = @libdir@
 libexecdir = @libexecdir@
+libiptc_CFLAGS = @libiptc_CFLAGS@
+libiptc_LIBS = @libiptc_LIBS@
 linux_headers = @linux_headers@
 localedir = @localedir@
 localstatedir = @localstatedir@
diff --git a/src/libcharon/plugins/eap_tnc/eap_tnc.c b/src/libcharon/plugins/eap_tnc/eap_tnc.c
index 62d23d0..f70f47e 100644
--- a/src/libcharon/plugins/eap_tnc/eap_tnc.c
+++ b/src/libcharon/plugins/eap_tnc/eap_tnc.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2010-2013 Andreas Steffen
+ * Copyright (C) 2010-2015 Andreas Steffen
  * HSR Hochschule fuer Technik Rapperswil
  *
  * This program is free software; you can redistribute it and/or modify it
@@ -256,6 +256,8 @@ static eap_tnc_t *eap_tnc_create(identification_t *server,
 	private_eap_tnc_t *this;
 	int max_msg_count;
 	char* protocol;
+	ike_sa_t *ike_sa;
+	host_t *server_ip, *peer_ip;
 	tnccs_t *tnccs;
 	tnccs_type_t tnccs_type;
 
@@ -302,8 +304,29 @@ static eap_tnc_t *eap_tnc_create(identification_t *server,
 		free(this);
 		return NULL;
 	}
+
+	/* Determine IP addresses of server and peer */
+	ike_sa = charon->bus->get_sa(charon->bus);
+	if (!ike_sa)
+	{
+		DBG1(DBG_TNC, "%N constructor did not find IKE_SA",
+					   eap_type_names, type);
+		free(this);
+		return NULL;
+	}
+	if (is_server)
+	{
+		server_ip = ike_sa->get_my_host(ike_sa);
+		peer_ip = ike_sa->get_other_host(ike_sa);
+	}
+	else
+	{
+		peer_ip = ike_sa->get_my_host(ike_sa);
+		server_ip = ike_sa->get_other_host(ike_sa);
+	}
+
 	tnccs = tnc->tnccs->create_instance(tnc->tnccs, tnccs_type,
-						is_server, server, peer,
+						is_server, server, peer, server_ip, peer_ip,
 						(type == EAP_TNC) ? TNC_IFT_EAP_1_1 : TNC_IFT_EAP_2_0,
 						is_server ? enforce_recommendation : NULL);
 	if (!tnccs)
diff --git a/src/libcharon/plugins/eap_ttls/Makefile.in b/src/libcharon/plugins/eap_ttls/Makefile.in
index 38c7632..0babf17 100644
--- a/src/libcharon/plugins/eap_ttls/Makefile.in
+++ b/src/libcharon/plugins/eap_ttls/Makefile.in
@@ -231,6 +231,7 @@ DLLIB = @DLLIB@
 DLLTOOL = @DLLTOOL@
 DSYMUTIL = @DSYMUTIL@
 DUMPBIN = @DUMPBIN@
+EASY_INSTALL = @EASY_INSTALL@
 ECHO_C = @ECHO_C@
 ECHO_N = @ECHO_N@
 ECHO_T = @ECHO_T@
@@ -291,10 +292,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
 PLUGIN_CFLAGS = @PLUGIN_CFLAGS@
 PTHREADLIB = @PTHREADLIB@
 PYTHON = @PYTHON@
+PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@
 PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
 PYTHON_PLATFORM = @PYTHON_PLATFORM@
 PYTHON_PREFIX = @PYTHON_PREFIX@
 PYTHON_VERSION = @PYTHON_VERSION@
+PY_TEST = @PY_TEST@
 RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
@@ -368,6 +371,8 @@ json_CFLAGS = @json_CFLAGS@
 json_LIBS = @json_LIBS@
 libdir = @libdir@
 libexecdir = @libexecdir@
+libiptc_CFLAGS = @libiptc_CFLAGS@
+libiptc_LIBS = @libiptc_LIBS@
 linux_headers = @linux_headers@
 localedir = @localedir@
 localstatedir = @localstatedir@
diff --git a/src/libcharon/plugins/eap_ttls/eap_ttls.c b/src/libcharon/plugins/eap_ttls/eap_ttls.c
index 703cd3f..c99d47f 100644
--- a/src/libcharon/plugins/eap_ttls/eap_ttls.c
+++ b/src/libcharon/plugins/eap_ttls/eap_ttls.c
@@ -111,6 +111,12 @@ METHOD(eap_method_t, is_mutual, bool,
 	return TRUE;
 }
 
+METHOD(eap_method_t, get_auth, auth_cfg_t*,
+	private_eap_ttls_t *this)
+{
+	return this->tls_eap->get_auth(this->tls_eap);
+}
+
 METHOD(eap_method_t, destroy, void,
 	private_eap_ttls_t *this)
 {
@@ -141,6 +147,7 @@ static eap_ttls_t *eap_ttls_create(identification_t *server,
 				.get_identifier = _get_identifier,
 				.set_identifier = _set_identifier,
 				.get_msk = _get_msk,
+				.get_auth = _get_auth,
 				.destroy = _destroy,
 			},
 		},
diff --git a/src/libcharon/plugins/error_notify/Makefile.in b/src/libcharon/plugins/error_notify/Makefile.in
index d9fa454..0a07aa7 100644
--- a/src/libcharon/plugins/error_notify/Makefile.in
+++ b/src/libcharon/plugins/error_notify/Makefile.in
@@ -237,6 +237,7 @@ DLLIB = @DLLIB@
 DLLTOOL = @DLLTOOL@
 DSYMUTIL = @DSYMUTIL@
 DUMPBIN = @DUMPBIN@
+EASY_INSTALL = @EASY_INSTALL@
 ECHO_C = @ECHO_C@
 ECHO_N = @ECHO_N@
 ECHO_T = @ECHO_T@
@@ -297,10 +298,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
 PLUGIN_CFLAGS = @PLUGIN_CFLAGS@
 PTHREADLIB = @PTHREADLIB@
 PYTHON = @PYTHON@
+PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@
 PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
 PYTHON_PLATFORM = @PYTHON_PLATFORM@
 PYTHON_PREFIX = @PYTHON_PREFIX@
 PYTHON_VERSION = @PYTHON_VERSION@
+PY_TEST = @PY_TEST@
 RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
@@ -374,6 +377,8 @@ json_CFLAGS = @json_CFLAGS@
 json_LIBS = @json_LIBS@
 libdir = @libdir@
 libexecdir = @libexecdir@
+libiptc_CFLAGS = @libiptc_CFLAGS@
+libiptc_LIBS = @libiptc_LIBS@
 linux_headers = @linux_headers@
 localedir = @localedir@
 localstatedir = @localstatedir@
diff --git a/src/libcharon/plugins/ext_auth/Makefile.in b/src/libcharon/plugins/ext_auth/Makefile.in
index a1b47dd..d23e680 100644
--- a/src/libcharon/plugins/ext_auth/Makefile.in
+++ b/src/libcharon/plugins/ext_auth/Makefile.in
@@ -229,6 +229,7 @@ DLLIB = @DLLIB@
 DLLTOOL = @DLLTOOL@
 DSYMUTIL = @DSYMUTIL@
 DUMPBIN = @DUMPBIN@
+EASY_INSTALL = @EASY_INSTALL@
 ECHO_C = @ECHO_C@
 ECHO_N = @ECHO_N@
 ECHO_T = @ECHO_T@
@@ -289,10 +290,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
 PLUGIN_CFLAGS = @PLUGIN_CFLAGS@
 PTHREADLIB = @PTHREADLIB@
 PYTHON = @PYTHON@
+PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@
 PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
 PYTHON_PLATFORM = @PYTHON_PLATFORM@
 PYTHON_PREFIX = @PYTHON_PREFIX@
 PYTHON_VERSION = @PYTHON_VERSION@
+PY_TEST = @PY_TEST@
 RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
@@ -366,6 +369,8 @@ json_CFLAGS = @json_CFLAGS@
 json_LIBS = @json_LIBS@
 libdir = @libdir@
 libexecdir = @libexecdir@
+libiptc_CFLAGS = @libiptc_CFLAGS@
+libiptc_LIBS = @libiptc_LIBS@
 linux_headers = @linux_headers@
 localedir = @localedir@
 localstatedir = @localstatedir@
diff --git a/src/libcharon/plugins/farp/Makefile.in b/src/libcharon/plugins/farp/Makefile.in
index 2bfd38b..318400f 100644
--- a/src/libcharon/plugins/farp/Makefile.in
+++ b/src/libcharon/plugins/farp/Makefile.in
@@ -227,6 +227,7 @@ DLLIB = @DLLIB@
 DLLTOOL = @DLLTOOL@
 DSYMUTIL = @DSYMUTIL@
 DUMPBIN = @DUMPBIN@
+EASY_INSTALL = @EASY_INSTALL@
 ECHO_C = @ECHO_C@
 ECHO_N = @ECHO_N@
 ECHO_T = @ECHO_T@
@@ -287,10 +288,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
 PLUGIN_CFLAGS = @PLUGIN_CFLAGS@
 PTHREADLIB = @PTHREADLIB@
 PYTHON = @PYTHON@
+PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@
 PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
 PYTHON_PLATFORM = @PYTHON_PLATFORM@
 PYTHON_PREFIX = @PYTHON_PREFIX@
 PYTHON_VERSION = @PYTHON_VERSION@
+PY_TEST = @PY_TEST@
 RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
@@ -364,6 +367,8 @@ json_CFLAGS = @json_CFLAGS@
 json_LIBS = @json_LIBS@
 libdir = @libdir@
 libexecdir = @libexecdir@
+libiptc_CFLAGS = @libiptc_CFLAGS@
+libiptc_LIBS = @libiptc_LIBS@
 linux_headers = @linux_headers@
 localedir = @localedir@
 localstatedir = @localstatedir@
diff --git a/src/libcharon/plugins/forecast/Makefile.am b/src/libcharon/plugins/forecast/Makefile.am
new file mode 100644
index 0000000..ce57313
--- /dev/null
+++ b/src/libcharon/plugins/forecast/Makefile.am
@@ -0,0 +1,21 @@
+AM_CPPFLAGS = \
+	-I$(top_srcdir)/src/libstrongswan \
+	-I$(top_srcdir)/src/libhydra \
+	-I$(top_srcdir)/src/libcharon
+
+AM_CFLAGS = \
+	$(PLUGIN_CFLAGS) $(libiptc_CFLAGS)
+
+if MONOLITHIC
+noinst_LTLIBRARIES = libstrongswan-forecast.la
+else
+plugin_LTLIBRARIES = libstrongswan-forecast.la
+endif
+
+libstrongswan_forecast_la_SOURCES = \
+	forecast_listener.h forecast_listener.c \
+	forecast_forwarder.h forecast_forwarder.c \
+	forecast_plugin.h forecast_plugin.c
+
+libstrongswan_forecast_la_LDFLAGS = -module -avoid-version
+libstrongswan_forecast_la_LIBADD = $(libiptc_LIBS)
diff --git a/src/libcharon/plugins/forecast/Makefile.in b/src/libcharon/plugins/forecast/Makefile.in
new file mode 100644
index 0000000..7b190ca
--- /dev/null
+++ b/src/libcharon/plugins/forecast/Makefile.in
@@ -0,0 +1,784 @@
+# Makefile.in generated by automake 1.14.1 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994-2013 Free Software Foundation, Inc.
+
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+ at SET_MAKE@
+
+VPATH = @srcdir@
+am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)'
+am__make_running_with_option = \
+  case $${target_option-} in \
+      ?) ;; \
+      *) echo "am__make_running_with_option: internal error: invalid" \
+              "target option '$${target_option-}' specified" >&2; \
+         exit 1;; \
+  esac; \
+  has_opt=no; \
+  sane_makeflags=$$MAKEFLAGS; \
+  if $(am__is_gnu_make); then \
+    sane_makeflags=$$MFLAGS; \
+  else \
+    case $$MAKEFLAGS in \
+      *\\[\ \	]*) \
+        bs=\\; \
+        sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
+          | sed "s/$$bs$$bs[$$bs $$bs	]*//g"`;; \
+    esac; \
+  fi; \
+  skip_next=no; \
+  strip_trailopt () \
+  { \
+    flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
+  }; \
+  for flg in $$sane_makeflags; do \
+    test $$skip_next = yes && { skip_next=no; continue; }; \
+    case $$flg in \
+      *=*|--*) continue;; \
+        -*I) strip_trailopt 'I'; skip_next=yes;; \
+      -*I?*) strip_trailopt 'I';; \
+        -*O) strip_trailopt 'O'; skip_next=yes;; \
+      -*O?*) strip_trailopt 'O';; \
+        -*l) strip_trailopt 'l'; skip_next=yes;; \
+      -*l?*) strip_trailopt 'l';; \
+      -[dEDm]) skip_next=yes;; \
+      -[JT]) skip_next=yes;; \
+    esac; \
+    case $$flg in \
+      *$$target_option*) has_opt=yes; break;; \
+    esac; \
+  done; \
+  test $$has_opt = yes
+am__make_dryrun = (target_option=n; $(am__make_running_with_option))
+am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+subdir = src/libcharon/plugins/forecast
+DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
+	$(top_srcdir)/depcomp
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/m4/config/libtool.m4 \
+	$(top_srcdir)/m4/config/ltoptions.m4 \
+	$(top_srcdir)/m4/config/ltsugar.m4 \
+	$(top_srcdir)/m4/config/ltversion.m4 \
+	$(top_srcdir)/m4/config/lt~obsolete.m4 \
+	$(top_srcdir)/m4/macros/split-package-version.m4 \
+	$(top_srcdir)/m4/macros/with.m4 \
+	$(top_srcdir)/m4/macros/enable-disable.m4 \
+	$(top_srcdir)/m4/macros/add-plugin.m4 \
+	$(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+	$(ACLOCAL_M4)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
+am__vpath_adj = case $$p in \
+    $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
+    *) f=$$p;; \
+  esac;
+am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
+am__install_max = 40
+am__nobase_strip_setup = \
+  srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
+am__nobase_strip = \
+  for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
+am__nobase_list = $(am__nobase_strip_setup); \
+  for p in $$list; do echo "$$p $$p"; done | \
+  sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
+  $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
+    if (++n[$$2] == $(am__install_max)) \
+      { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
+    END { for (dir in files) print dir, files[dir] }'
+am__base_list = \
+  sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
+  sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
+am__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; }; \
+  }
+am__installdirs = "$(DESTDIR)$(plugindir)"
+LTLIBRARIES = $(noinst_LTLIBRARIES) $(plugin_LTLIBRARIES)
+am__DEPENDENCIES_1 =
+libstrongswan_forecast_la_DEPENDENCIES = $(am__DEPENDENCIES_1)
+am_libstrongswan_forecast_la_OBJECTS = forecast_listener.lo \
+	forecast_forwarder.lo forecast_plugin.lo
+libstrongswan_forecast_la_OBJECTS =  \
+	$(am_libstrongswan_forecast_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_forecast_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \
+	$(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \
+	$(AM_CFLAGS) $(CFLAGS) $(libstrongswan_forecast_la_LDFLAGS) \
+	$(LDFLAGS) -o $@
+ at MONOLITHIC_FALSE@am_libstrongswan_forecast_la_rpath = -rpath \
+ at MONOLITHIC_FALSE@	$(plugindir)
+ at MONOLITHIC_TRUE@am_libstrongswan_forecast_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
+am__v_P_1 = :
+AM_V_GEN = $(am__v_GEN_ at AM_V@)
+am__v_GEN_ = $(am__v_GEN_ at AM_DEFAULT_V@)
+am__v_GEN_0 = @echo "  GEN     " $@;
+am__v_GEN_1 = 
+AM_V_at = $(am__v_at_ at AM_V@)
+am__v_at_ = $(am__v_at_ at AM_DEFAULT_V@)
+am__v_at_0 = @
+am__v_at_1 = 
+DEFAULT_INCLUDES = -I. at am__isrc@ -I$(top_builddir)
+depcomp = $(SHELL) $(top_srcdir)/depcomp
+am__depfiles_maybe = depfiles
+am__mv = mv -f
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+	$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+	$(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \
+	$(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
+	$(AM_CFLAGS) $(CFLAGS)
+AM_V_CC = $(am__v_CC_ at AM_V@)
+am__v_CC_ = $(am__v_CC_ at AM_DEFAULT_V@)
+am__v_CC_0 = @echo "  CC      " $@;
+am__v_CC_1 = 
+CCLD = $(CC)
+LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+	$(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+	$(AM_LDFLAGS) $(LDFLAGS) -o $@
+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_forecast_la_SOURCES)
+DIST_SOURCES = $(libstrongswan_forecast_la_SOURCES)
+am__can_run_installinfo = \
+  case $$AM_UPDATE_INFO_DIR in \
+    n|no|NO) false;; \
+    *) (install-info --version) >/dev/null 2>&1;; \
+  esac
+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
+# *not* preserved.
+am__uniquify_input = $(AWK) '\
+  BEGIN { nonempty = 0; } \
+  { items[$$0] = 1; nonempty = 1; } \
+  END { if (nonempty) { for (i in items) print i; }; } \
+'
+# Make sure the list of sources is unique.  This is necessary because,
+# e.g., the same source file might be shared among _SOURCES variables
+# for different programs/libraries.
+am__define_uniq_tagged_files = \
+  list='$(am__tagged_files)'; \
+  unique=`for i in $$list; do \
+    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+  done | $(am__uniquify_input)`
+ETAGS = etags
+CTAGS = ctags
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+ALLOCA = @ALLOCA@
+AMTAR = @AMTAR@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+BFDLIB = @BFDLIB@
+BTLIB = @BTLIB@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+COVERAGE_CFLAGS = @COVERAGE_CFLAGS@
+COVERAGE_LDFLAGS = @COVERAGE_LDFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DLLIB = @DLLIB@
+DLLTOOL = @DLLTOOL@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+EASY_INSTALL = @EASY_INSTALL@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+FGREP = @FGREP@
+GEM = @GEM@
+GENHTML = @GENHTML@
+GPERF = @GPERF@
+GPRBUILD = @GPRBUILD@
+GREP = @GREP@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+LCOV = @LCOV@
+LD = @LD@
+LDFLAGS = @LDFLAGS@
+LEX = @LEX@
+LEXLIB = @LEXLIB@
+LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LIPO = @LIPO@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+MAKEINFO = @MAKEINFO@
+MANIFEST_TOOL = @MANIFEST_TOOL@
+MKDIR_P = @MKDIR_P@
+MYSQLCFLAG = @MYSQLCFLAG@
+MYSQLCONFIG = @MYSQLCONFIG@
+MYSQLLIB = @MYSQLLIB@
+NM = @NM@
+NMEDIT = @NMEDIT@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OPENSSL_LIB = @OPENSSL_LIB@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PACKAGE_VERSION_BUILD = @PACKAGE_VERSION_BUILD@
+PACKAGE_VERSION_MAJOR = @PACKAGE_VERSION_MAJOR@
+PACKAGE_VERSION_MINOR = @PACKAGE_VERSION_MINOR@
+PACKAGE_VERSION_REVIEW = @PACKAGE_VERSION_REVIEW@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PERL = @PERL@
+PKG_CONFIG = @PKG_CONFIG@
+PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
+PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
+PLUGIN_CFLAGS = @PLUGIN_CFLAGS@
+PTHREADLIB = @PTHREADLIB@
+PYTHON = @PYTHON@
+PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@
+PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
+PYTHON_PLATFORM = @PYTHON_PLATFORM@
+PYTHON_PREFIX = @PYTHON_PREFIX@
+PYTHON_VERSION = @PYTHON_VERSION@
+PY_TEST = @PY_TEST@
+RANLIB = @RANLIB@
+RTLIB = @RTLIB@
+RUBY = @RUBY@
+RUBYGEMDIR = @RUBYGEMDIR@
+RUBYINCLUDE = @RUBYINCLUDE@
+RUBYLIB = @RUBYLIB@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+SOCKLIB = @SOCKLIB@
+STRIP = @STRIP@
+UNWINDLIB = @UNWINDLIB@
+VERSION = @VERSION@
+YACC = @YACC@
+YFLAGS = @YFLAGS@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+aikgen_plugins = @aikgen_plugins@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+attest_plugins = @attest_plugins@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+c_plugins = @c_plugins@
+charon_natt_port = @charon_natt_port@
+charon_plugins = @charon_plugins@
+charon_udp_port = @charon_udp_port@
+clearsilver_LIBS = @clearsilver_LIBS@
+cmd_plugins = @cmd_plugins@
+datadir = @datadir@
+datarootdir = @datarootdir@
+dbusservicedir = @dbusservicedir@
+dev_headers = @dev_headers@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+fips_mode = @fips_mode@
+gtk_CFLAGS = @gtk_CFLAGS@
+gtk_LIBS = @gtk_LIBS@
+h_plugins = @h_plugins@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+imcvdir = @imcvdir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+ipsec_script = @ipsec_script@
+ipsec_script_upper = @ipsec_script_upper@
+ipsecdir = @ipsecdir@
+ipsecgroup = @ipsecgroup@
+ipseclibdir = @ipseclibdir@
+ipsecuser = @ipsecuser@
+json_CFLAGS = @json_CFLAGS@
+json_LIBS = @json_LIBS@
+libdir = @libdir@
+libexecdir = @libexecdir@
+libiptc_CFLAGS = @libiptc_CFLAGS@
+libiptc_LIBS = @libiptc_LIBS@
+linux_headers = @linux_headers@
+localedir = @localedir@
+localstatedir = @localstatedir@
+maemo_CFLAGS = @maemo_CFLAGS@
+maemo_LIBS = @maemo_LIBS@
+manager_plugins = @manager_plugins@
+mandir = @mandir@
+medsrv_plugins = @medsrv_plugins@
+mkdir_p = @mkdir_p@
+nm_CFLAGS = @nm_CFLAGS@
+nm_LIBS = @nm_LIBS@
+nm_ca_dir = @nm_ca_dir@
+nm_plugins = @nm_plugins@
+oldincludedir = @oldincludedir@
+pcsclite_CFLAGS = @pcsclite_CFLAGS@
+pcsclite_LIBS = @pcsclite_LIBS@
+pdfdir = @pdfdir@
+piddir = @piddir@
+pkgpyexecdir = @pkgpyexecdir@
+pkgpythondir = @pkgpythondir@
+pki_plugins = @pki_plugins@
+plugindir = @plugindir@
+pool_plugins = @pool_plugins@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+pyexecdir = @pyexecdir@
+pythondir = @pythondir@
+random_device = @random_device@
+resolv_conf = @resolv_conf@
+routing_table = @routing_table@
+routing_table_prio = @routing_table_prio@
+s_plugins = @s_plugins@
+sbindir = @sbindir@
+scepclient_plugins = @scepclient_plugins@
+scripts_plugins = @scripts_plugins@
+sharedstatedir = @sharedstatedir@
+soup_CFLAGS = @soup_CFLAGS@
+soup_LIBS = @soup_LIBS@
+srcdir = @srcdir@
+starter_plugins = @starter_plugins@
+strongswan_conf = @strongswan_conf@
+strongswan_options = @strongswan_options@
+swanctldir = @swanctldir@
+sysconfdir = @sysconfdir@
+systemd_daemon_CFLAGS = @systemd_daemon_CFLAGS@
+systemd_daemon_LIBS = @systemd_daemon_LIBS@
+systemd_journal_CFLAGS = @systemd_journal_CFLAGS@
+systemd_journal_LIBS = @systemd_journal_LIBS@
+systemdsystemunitdir = @systemdsystemunitdir@
+t_plugins = @t_plugins@
+target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+urandom_device = @urandom_device@
+xml_CFLAGS = @xml_CFLAGS@
+xml_LIBS = @xml_LIBS@
+AM_CPPFLAGS = \
+	-I$(top_srcdir)/src/libstrongswan \
+	-I$(top_srcdir)/src/libhydra \
+	-I$(top_srcdir)/src/libcharon
+
+AM_CFLAGS = \
+	$(PLUGIN_CFLAGS) $(libiptc_CFLAGS)
+
+ at MONOLITHIC_TRUE@noinst_LTLIBRARIES = libstrongswan-forecast.la
+ at MONOLITHIC_FALSE@plugin_LTLIBRARIES = libstrongswan-forecast.la
+libstrongswan_forecast_la_SOURCES = \
+	forecast_listener.h forecast_listener.c \
+	forecast_forwarder.h forecast_forwarder.c \
+	forecast_plugin.h forecast_plugin.c
+
+libstrongswan_forecast_la_LDFLAGS = -module -avoid-version
+libstrongswan_forecast_la_LIBADD = $(libiptc_LIBS)
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .c .lo .o .obj
+$(srcdir)/Makefile.in:  $(srcdir)/Makefile.am  $(am__configure_deps)
+	@for dep in $?; do \
+	  case '$(am__configure_deps)' in \
+	    *$$dep*) \
+	      ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+	        && { if test -f $@; then exit 0; else break; fi; }; \
+	      exit 1;; \
+	  esac; \
+	done; \
+	echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/libcharon/plugins/forecast/Makefile'; \
+	$(am__cd) $(top_srcdir) && \
+	  $(AUTOMAKE) --gnu src/libcharon/plugins/forecast/Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+	@case '$?' in \
+	  *config.status*) \
+	    cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+	  *) \
+	    echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+	    cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+	esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure:  $(am__configure_deps)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4):  $(am__aclocal_m4_deps)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+
+clean-noinstLTLIBRARIES:
+	-test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES)
+	@list='$(noinst_LTLIBRARIES)'; \
+	locs=`for p in $$list; do echo $$p; done | \
+	      sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \
+	      sort -u`; \
+	test -z "$$locs" || { \
+	  echo rm -f $${locs}; \
+	  rm -f $${locs}; \
+	}
+
+install-pluginLTLIBRARIES: $(plugin_LTLIBRARIES)
+	@$(NORMAL_INSTALL)
+	@list='$(plugin_LTLIBRARIES)'; test -n "$(plugindir)" || list=; \
+	list2=; for p in $$list; do \
+	  if test -f $$p; then \
+	    list2="$$list2 $$p"; \
+	  else :; fi; \
+	done; \
+	test -z "$$list2" || { \
+	  echo " $(MKDIR_P) '$(DESTDIR)$(plugindir)'"; \
+	  $(MKDIR_P) "$(DESTDIR)$(plugindir)" || exit 1; \
+	  echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(plugindir)'"; \
+	  $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(plugindir)"; \
+	}
+
+uninstall-pluginLTLIBRARIES:
+	@$(NORMAL_UNINSTALL)
+	@list='$(plugin_LTLIBRARIES)'; test -n "$(plugindir)" || list=; \
+	for p in $$list; do \
+	  $(am__strip_dir) \
+	  echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(plugindir)/$$f'"; \
+	  $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(plugindir)/$$f"; \
+	done
+
+clean-pluginLTLIBRARIES:
+	-test -z "$(plugin_LTLIBRARIES)" || rm -f $(plugin_LTLIBRARIES)
+	@list='$(plugin_LTLIBRARIES)'; \
+	locs=`for p in $$list; do echo $$p; done | \
+	      sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \
+	      sort -u`; \
+	test -z "$$locs" || { \
+	  echo rm -f $${locs}; \
+	  rm -f $${locs}; \
+	}
+
+libstrongswan-forecast.la: $(libstrongswan_forecast_la_OBJECTS) $(libstrongswan_forecast_la_DEPENDENCIES) $(EXTRA_libstrongswan_forecast_la_DEPENDENCIES) 
+	$(AM_V_CCLD)$(libstrongswan_forecast_la_LINK) $(am_libstrongswan_forecast_la_rpath) $(libstrongswan_forecast_la_OBJECTS) $(libstrongswan_forecast_la_LIBADD) $(LIBS)
+
+mostlyclean-compile:
+	-rm -f *.$(OBJEXT)
+
+distclean-compile:
+	-rm -f *.tab.c
+
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/forecast_forwarder.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/forecast_listener.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/forecast_plugin.Plo at am__quote@
+
+.c.o:
+ at am__fastdepCC_TRUE@	$(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\
+ at am__fastdepCC_TRUE@	$(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\
+ at am__fastdepCC_TRUE@	$(am__mv) $$depbase.Tpo $$depbase.Po
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(COMPILE) -c -o $@ $<
+
+.c.obj:
+ at am__fastdepCC_TRUE@	$(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\
+ at am__fastdepCC_TRUE@	$(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\
+ at am__fastdepCC_TRUE@	$(am__mv) $$depbase.Tpo $$depbase.Po
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
+
+.c.lo:
+ at am__fastdepCC_TRUE@	$(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\
+ at am__fastdepCC_TRUE@	$(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\
+ at am__fastdepCC_TRUE@	$(am__mv) $$depbase.Tpo $$depbase.Plo
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(LTCOMPILE) -c -o $@ $<
+
+mostlyclean-libtool:
+	-rm -f *.lo
+
+clean-libtool:
+	-rm -rf .libs _libs
+
+ID: $(am__tagged_files)
+	$(am__define_uniq_tagged_files); mkid -fID $$unique
+tags: tags-am
+TAGS: tags
+
+tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+	set x; \
+	here=`pwd`; \
+	$(am__define_uniq_tagged_files); \
+	shift; \
+	if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
+	  test -n "$$unique" || unique=$$empty_fix; \
+	  if test $$# -gt 0; then \
+	    $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+	      "$$@" $$unique; \
+	  else \
+	    $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+	      $$unique; \
+	  fi; \
+	fi
+ctags: ctags-am
+
+CTAGS: ctags
+ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+	$(am__define_uniq_tagged_files); \
+	test -z "$(CTAGS_ARGS)$$unique" \
+	  || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+	     $$unique
+
+GTAGS:
+	here=`$(am__cd) $(top_builddir) && pwd` \
+	  && $(am__cd) $(top_srcdir) \
+	  && gtags -i $(GTAGS_ARGS) "$$here"
+cscopelist: cscopelist-am
+
+cscopelist-am: $(am__tagged_files)
+	list='$(am__tagged_files)'; \
+	case "$(srcdir)" in \
+	  [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
+	  *) sdir=$(subdir)/$(srcdir) ;; \
+	esac; \
+	for i in $$list; do \
+	  if test -f "$$i"; then \
+	    echo "$(subdir)/$$i"; \
+	  else \
+	    echo "$$sdir/$$i"; \
+	  fi; \
+	done >> $(top_builddir)/cscope.files
+
+distclean-tags:
+	-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+distdir: $(DISTFILES)
+	@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+	topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+	list='$(DISTFILES)'; \
+	  dist_files=`for file in $$list; do echo $$file; done | \
+	  sed -e "s|^$$srcdirstrip/||;t" \
+	      -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+	case $$dist_files in \
+	  */*) $(MKDIR_P) `echo "$$dist_files" | \
+			   sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+			   sort -u` ;; \
+	esac; \
+	for file in $$dist_files; do \
+	  if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+	  if test -d $$d/$$file; then \
+	    dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+	    if test -d "$(distdir)/$$file"; then \
+	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+	    fi; \
+	    if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+	      cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+	    fi; \
+	    cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+	  else \
+	    test -f "$(distdir)/$$file" \
+	    || cp -p $$d/$$file "$(distdir)/$$file" \
+	    || exit 1; \
+	  fi; \
+	done
+check-am: all-am
+check: check-am
+all-am: Makefile $(LTLIBRARIES)
+installdirs:
+	for dir in "$(DESTDIR)$(plugindir)"; do \
+	  test -z "$$dir" || $(MKDIR_P) "$$dir"; \
+	done
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+	@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+	if test -z '$(STRIP)'; then \
+	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	      install; \
+	else \
+	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	    "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+	fi
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+	-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+	-test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+
+maintainer-clean-generic:
+	@echo "This command is intended for maintainers to use"
+	@echo "it deletes files that may require special tools to rebuild."
+clean: clean-am
+
+clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \
+	clean-pluginLTLIBRARIES mostlyclean-am
+
+distclean: distclean-am
+	-rm -rf ./$(DEPDIR)
+	-rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+	distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+html-am:
+
+info: info-am
+
+info-am:
+
+install-data-am: install-pluginLTLIBRARIES
+
+install-dvi: install-dvi-am
+
+install-dvi-am:
+
+install-exec-am:
+
+install-html: install-html-am
+
+install-html-am:
+
+install-info: install-info-am
+
+install-info-am:
+
+install-man:
+
+install-pdf: install-pdf-am
+
+install-pdf-am:
+
+install-ps: install-ps-am
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+	-rm -rf ./$(DEPDIR)
+	-rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic \
+	mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am: uninstall-pluginLTLIBRARIES
+
+.MAKE: install-am install-strip
+
+.PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \
+	clean-libtool clean-noinstLTLIBRARIES clean-pluginLTLIBRARIES \
+	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-man install-pdf \
+	install-pdf-am install-pluginLTLIBRARIES install-ps \
+	install-ps-am install-strip installcheck installcheck-am \
+	installdirs maintainer-clean maintainer-clean-generic \
+	mostlyclean mostlyclean-compile mostlyclean-generic \
+	mostlyclean-libtool pdf pdf-am ps ps-am tags tags-am uninstall \
+	uninstall-am uninstall-pluginLTLIBRARIES
+
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/src/libcharon/plugins/forecast/forecast_forwarder.c b/src/libcharon/plugins/forecast/forecast_forwarder.c
new file mode 100644
index 0000000..07a3d49
--- /dev/null
+++ b/src/libcharon/plugins/forecast/forecast_forwarder.c
@@ -0,0 +1,496 @@
+/*
+ * Copyright (C) 2010-2014 Martin Willi
+ * Copyright (C) 2010-2014 revosec AG
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * for more details.
+ */
+
+#include "forecast_forwarder.h"
+
+#include <errno.h>
+#include <unistd.h>
+#include <netinet/ip.h>
+#include <netinet/udp.h>
+#include <linux/socket.h>
+#include <netinet/if_ether.h>
+#include <linux/if_packet.h>
+#include <linux/filter.h>
+#include <sys/ioctl.h>
+#include <ifaddrs.h>
+#include <net/if.h>
+
+#include <hydra.h>
+#include <daemon.h>
+#include <threading/thread.h>
+#include <processing/jobs/callback_job.h>
+
+#define BOOTP_SERVER_PORT 67
+#define BOOTP_CLIENT_PORT 68
+
+typedef struct private_forecast_forwarder_t private_forecast_forwarder_t;
+typedef struct private_kernel_listener_t private_kernel_listener_t;
+
+/**
+ * Private data of registered kernel listener
+ */
+struct private_kernel_listener_t {
+
+	/**
+	 * Implements kernel_listener_t
+	 */
+	kernel_listener_t listener;
+
+	/**
+	 * Listener that knows active addresses
+	 */
+	forecast_listener_t *fc;
+
+	/**
+	 * current broadcast address of internal network
+	 */
+	u_int32_t broadcast;
+
+	/**
+	 * LAN interface index
+	 */
+	int ifindex;
+
+	/**
+	 * Packet socket
+	 */
+	int pkt;
+
+	/**
+	 * RAW socket
+	 */
+	int raw;
+};
+
+/**
+ * Private data of an forecast_forwarder_t object.
+ */
+struct private_forecast_forwarder_t {
+
+	/**
+	 * Public forecast_forwarder_t interface.
+	 */
+	forecast_forwarder_t public;
+
+	/**
+	 * Public kernel_listener_t interface.
+	 */
+	private_kernel_listener_t kernel;
+};
+
+/**
+ * Send a broadcast/multicast packet to a network
+ */
+static void send_net(private_forecast_forwarder_t *this,
+					 struct sockaddr_ll *addr, void *buf, size_t len)
+{
+	if (sendto(this->kernel.pkt, buf, len, 0,
+			   (struct sockaddr*)addr, sizeof(*addr)) != len)
+	{
+		DBG1(DBG_NET, "forecast send_net() failed: %s", strerror(errno));
+	}
+}
+
+/**
+ * Send a broadcast/multicast packet to a peer
+ */
+static void send_peer(private_forecast_forwarder_t *this, u_int32_t dst,
+					  void *buf, size_t len, int mark)
+{
+	struct sockaddr_in addr = {
+		.sin_family = AF_INET,
+		.sin_addr.s_addr = dst,
+	};
+
+	if (setsockopt(this->kernel.raw, SOL_SOCKET, SO_MARK,
+				   &mark, sizeof(mark)) != 0)
+	{
+		DBG1(DBG_NET, "forecast setting SO_MARK failed: %s", strerror(errno));
+	}
+	if (sendto(this->kernel.raw, buf, len, 0,
+			   (struct sockaddr*)&addr, sizeof(addr)) != len)
+	{
+		DBG1(DBG_NET, "forecast send_peer() failed: %s", strerror(errno));
+	}
+}
+
+/**
+ * Check if an IP packet is BOOTP/DHCP
+ */
+static bool is_bootp(void *buf, size_t len)
+{
+	struct __attribute__((__packed__)) {
+		struct iphdr ip;
+		struct udphdr udp;
+	} *pkt = buf;
+
+	if (len > sizeof(*pkt))
+	{
+		if (ntohs(pkt->udp.source) == BOOTP_CLIENT_PORT &&
+			ntohs(pkt->udp.dest) == BOOTP_SERVER_PORT)
+		{
+			return TRUE;
+		}
+		if (ntohs(pkt->udp.source) == BOOTP_SERVER_PORT &&
+			ntohs(pkt->udp.dest) == BOOTP_CLIENT_PORT)
+		{
+			return TRUE;
+		}
+	}
+	return FALSE;
+}
+
+/**
+ * Broadcast/Multicast receiver
+ */
+static bool receive_casts(private_forecast_forwarder_t *this)
+{
+	struct __attribute__((packed)) {
+		struct iphdr hdr;
+		char data[2048];
+	} buf;
+	char *type;
+	ssize_t len;
+	u_int mark, origin = 0;
+	host_t *src, *dst;
+	traffic_selector_t *ts;
+	enumerator_t *enumerator;
+	struct sockaddr_ll addr;
+	socklen_t alen = sizeof(addr);
+	bool reinject;
+
+	len = recvfrom(this->kernel.pkt, &buf, sizeof(buf), MSG_DONTWAIT,
+				   (struct sockaddr*)&addr, &alen);
+	if (len < 0)
+	{
+		if (errno != EAGAIN && errno != EWOULDBLOCK)
+		{
+			DBG1(DBG_NET, "receiving from forecast socket failed: %s",
+				 strerror(errno));
+		}
+		return TRUE;
+	}
+	else if (len < sizeof(struct iphdr))
+	{
+		DBG1(DBG_NET, "received short forecast packet: %zd bytes", len);
+		return TRUE;
+	}
+	if (is_bootp(&buf, len))
+	{	/* don't forward DHCP broadcasts */
+		return TRUE;
+	}
+
+	src = host_create_from_chunk(AF_INET, chunk_from_thing(buf.hdr.saddr), 0);
+	dst = host_create_from_chunk(AF_INET, chunk_from_thing(buf.hdr.daddr), 0);
+
+	/* create valid broadcast/multicast MAC to send out */
+	if (IN_MULTICAST(ntohl(buf.hdr.daddr)))
+	{
+		type = "multi";
+		ETHER_MAP_IP_MULTICAST(&buf.hdr.daddr, addr.sll_addr);
+	}
+	else
+	{
+		type = "broad";
+		memset(&addr.sll_addr, 0xFF, sizeof(addr.sll_addr));
+	}
+	DBG2(DBG_NET, "forecast intercepted packet: %H to %H", src, dst);
+
+	/* find mark of originating tunnel */
+	enumerator = this->kernel.fc->create_enumerator(this->kernel.fc, FALSE);
+	while (enumerator->enumerate(enumerator, &ts, &mark, &reinject))
+	{
+		if (ts->includes(ts, src))
+		{
+			origin = mark;
+			break;
+		}
+	}
+	enumerator->destroy(enumerator);
+
+	/* send packet over all tunnels, but not the packets origin */
+	enumerator = this->kernel.fc->create_enumerator(this->kernel.fc, FALSE);
+	while (enumerator->enumerate(enumerator, &ts, &mark, &reinject))
+	{
+		if (ts->includes(ts, dst))
+		{
+			if ((reinject && origin != mark) || origin == 0)
+			{
+				DBG2(DBG_NET, "forwarding a %H %scast from %H to peer %R (%u)",
+					 dst, type, src, ts, mark);
+				send_peer(this, buf.hdr.daddr, &buf, len, mark);
+			}
+		}
+	}
+	enumerator->destroy(enumerator);
+
+	if (origin)
+	{
+		/* forward broadcast/multicast from client to network */
+		DBG2(DBG_NET, "forwarding a %H %scast from peer %H to internal network",
+			 dst, type, src);
+		addr.sll_ifindex = this->kernel.ifindex;
+		send_net(this, &addr, &buf, len);
+	}
+
+	dst->destroy(dst);
+	src->destroy(src);
+
+	return TRUE;
+}
+
+/**
+ * Join a multicast group
+ */
+static void join_group(private_kernel_listener_t *this, char *group,
+					   struct sockaddr *addr)
+{
+	struct sockaddr_in *in;
+	struct ip_mreqn mreq;
+	host_t *host;
+
+	host = host_create_from_string(group, 0);
+	if (host)
+	{
+		memset(&mreq, 0, sizeof(mreq));
+		memcpy(&mreq.imr_multiaddr.s_addr, host->get_address(host).ptr, 4);
+		if (addr->sa_family == AF_INET)
+		{
+			in = (struct sockaddr_in*)addr;
+			memcpy(&mreq.imr_address, &in->sin_addr.s_addr,
+				   sizeof(in->sin_addr.s_addr));
+		}
+		mreq.imr_ifindex = this->ifindex;
+		if (setsockopt(this->raw, IPPROTO_IP, IP_ADD_MEMBERSHIP,
+					   &mreq, sizeof(mreq)) == -1)
+		{
+			if (errno != EADDRINUSE)
+			{
+				DBG1(DBG_NET, "forecast multicast join to %s failed: %s",
+					 group, strerror(errno));
+			}
+		}
+		else
+		{
+			DBG2(DBG_NET, "forwarding multicast group %s", group);
+		}
+		host->destroy(host);
+	}
+}
+
+/**
+ * (Re-)Join all multicast groups we want to forward
+ */
+static void join_groups(private_kernel_listener_t *this, struct sockaddr *addr)
+{
+	enumerator_t *enumerator;
+	char *groups, *group;
+	static char *def =
+		"224.0.0.1,"		/* host multicast */
+		"224.0.0.22,"		/* IGMP */
+		"224.0.0.251,"		/* mDNS */
+		"224.0.0.252,"		/* LLMNR */
+		"239.255.255.250";	/* SSDP/WS-discovery */
+
+	groups = lib->settings->get_str(lib->settings,
+									"%s.plugins.forecast.groups", def, lib->ns);
+	DBG1(DBG_CFG, "joining forecast multicast groups: %s", groups);
+	enumerator = enumerator_create_token(groups, ",", " ");
+	while (enumerator->enumerate(enumerator, &group))
+	{
+		join_group(this, group, addr);
+	}
+	enumerator->destroy(enumerator);
+}
+
+/**
+ * Attach the socket filter to the socket
+ */
+static bool attach_filter(int fd, u_int32_t broadcast)
+{
+	struct sock_filter filter_code[] = {
+		/* destination address: is ... */
+		BPF_STMT(BPF_LD+BPF_W+BPF_ABS, offsetof(struct iphdr, daddr)),
+		/* broadcast, as received from the local network */
+		BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, ntohl(broadcast), 4, 0),
+		/* broadcast, as Win7 sends them */
+		BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0xFFFFFFFF, 3, 0),
+		/* any multicast, 224.0.0.0/4 */
+		BPF_STMT(BPF_ALU+BPF_AND+BPF_K, 0xF0000000),
+		BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0xE0000000, 1, 0),
+		BPF_STMT(BPF_RET+BPF_K, 0),
+		BPF_STMT(BPF_LD+BPF_W+BPF_LEN, 0),
+		BPF_STMT(BPF_RET+BPF_A, 0),
+	};
+	struct sock_fprog filter = {
+		sizeof(filter_code) / sizeof(struct sock_filter),
+		filter_code,
+	};
+
+	if (setsockopt(fd, SOL_SOCKET, SO_ATTACH_FILTER,
+				   &filter, sizeof(filter)) < 0)
+	{
+		DBG1(DBG_NET, "installing forecast PACKET socket filter failed: %s",
+			 strerror(errno));
+		return FALSE;
+	}
+	return TRUE;
+}
+
+/**
+ * Get the interface index of an interface name
+ */
+static int get_ifindex(private_kernel_listener_t *this, char *ifname)
+{
+	struct ifreq ifr = {};
+
+	strncpy(ifr.ifr_name, ifname, IFNAMSIZ);
+	if (ioctl(this->raw, SIOCGIFINDEX, &ifr) == 0)
+	{
+		return ifr.ifr_ifindex;
+	}
+	return 0;
+}
+
+/**
+ * Set up the interface for broad/multicast forwarding
+ */
+static void setup_interface(private_kernel_listener_t *this)
+{
+	struct ifaddrs *addrs, *current;
+	struct sockaddr_in *in;
+	host_t *host;
+	char *name;
+
+	name = lib->settings->get_str(lib->settings,
+							"%s.plugins.forecast.interface", NULL, lib->ns);
+	if (getifaddrs(&addrs) == 0)
+	{
+		for (current = addrs; current; current = current->ifa_next)
+		{
+			if (name && !streq(name, current->ifa_name))
+			{
+				continue;
+			}
+			if (current->ifa_flags & IFF_BROADCAST &&
+				current->ifa_broadaddr &&
+				current->ifa_broadaddr->sa_family == AF_INET)
+			{
+				DBG1(DBG_NET, "using forecast interface %s", current->ifa_name);
+				this->ifindex = get_ifindex(this, current->ifa_name);
+				in = (struct sockaddr_in*)current->ifa_broadaddr;
+				attach_filter(this->pkt, in->sin_addr.s_addr);
+				join_groups(this, current->ifa_addr);
+				host = host_create_from_sockaddr(current->ifa_broadaddr);
+				if (host)
+				{
+					this->fc->set_broadcast(this->fc, host);
+					host->destroy(host);
+				}
+				break;
+			}
+		}
+	}
+	freeifaddrs(addrs);
+}
+
+METHOD(kernel_listener_t, roam, bool,
+	private_kernel_listener_t *this, bool address)
+{
+	if (address)
+	{
+		setup_interface(this);
+	}
+	return TRUE;
+}
+
+METHOD(forecast_forwarder_t, destroy, void,
+	private_forecast_forwarder_t *this)
+{
+	if (this->kernel.raw != -1)
+	{
+		close(this->kernel.raw);
+	}
+	if (this->kernel.pkt != -1)
+	{
+		lib->watcher->remove(lib->watcher, this->kernel.pkt);
+		close(this->kernel.pkt);
+	}
+	hydra->kernel_interface->remove_listener(hydra->kernel_interface,
+											 &this->kernel.listener);
+	free(this);
+}
+
+/**
+ * See header
+ */
+forecast_forwarder_t *forecast_forwarder_create(forecast_listener_t *listener)
+{
+	private_forecast_forwarder_t *this;
+	int on = 1;
+
+	INIT(this,
+		.public = {
+			.destroy = _destroy,
+		},
+		.kernel = {
+			.listener = {
+				.roam = _roam,
+			},
+			.raw = -1,
+			.pkt = -1,
+			.fc = listener,
+		},
+	);
+
+	this->kernel.pkt = socket(AF_PACKET, SOCK_DGRAM, htons(ETH_P_IP));
+	if (this->kernel.pkt == -1)
+	{
+		DBG1(DBG_NET, "opening PACKET socket failed: %s", strerror(errno));
+		destroy(this);
+		return NULL;
+	}
+	this->kernel.raw = socket(AF_INET, SOCK_RAW, IPPROTO_UDP);
+	if (this->kernel.raw == -1)
+	{
+		DBG1(DBG_NET, "opening RAW socket failed: %s", strerror(errno));
+		destroy(this);
+		return NULL;
+	}
+	if (setsockopt(this->kernel.raw, IPPROTO_IP, IP_HDRINCL,
+				   &on, sizeof(on)) == -1)
+	{
+		DBG1(DBG_NET, "forecast socket HDRINCL failed: %s", strerror(errno));
+		destroy(this);
+		return NULL;
+	}
+	if (setsockopt(this->kernel.raw, SOL_SOCKET, SO_BROADCAST,
+				   &on, sizeof(on)) == -1)
+	{
+		DBG1(DBG_NET, "forecast socket BROADCAST failed: %s", strerror(errno));
+		destroy(this);
+		return NULL;
+	}
+
+	setup_interface(&this->kernel);
+
+	hydra->kernel_interface->add_listener(hydra->kernel_interface,
+										  &this->kernel.listener);
+
+	lib->watcher->add(lib->watcher, this->kernel.pkt, WATCHER_READ,
+					  (watcher_cb_t)receive_casts, this);
+
+	return &this->public;
+}
diff --git a/src/libcharon/plugins/forecast/forecast_forwarder.h b/src/libcharon/plugins/forecast/forecast_forwarder.h
new file mode 100644
index 0000000..14d1073
--- /dev/null
+++ b/src/libcharon/plugins/forecast/forecast_forwarder.h
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2010-2014 Martin Willi
+ * Copyright (C) 2010-2014 revosec AG
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * for more details.
+ */
+
+/**
+ * @defgroup forecast_forwarder forecast_forwarder
+ * @{ @ingroup forecast
+ */
+
+#ifndef FORECAST_FORWARDER_H_
+#define FORECAST_FORWARDER_H_
+
+#include "forecast_listener.h"
+
+typedef struct forecast_forwarder_t forecast_forwarder_t;
+
+/**
+ * Broadcast/Multicast sniffer and forwarder.
+ */
+struct forecast_forwarder_t {
+
+	/**
+	 * Destroy a forecast_forwarder_t.
+	 */
+	void (*destroy)(forecast_forwarder_t *this);
+};
+
+/**
+ * Create a forecast_forwarder instance.
+ *
+ * @param listener		listener to check for addresses to forward to
+ * @return				forwarder instance
+ */
+forecast_forwarder_t *forecast_forwarder_create(forecast_listener_t *listener);
+
+#endif /** FORECAST_FORWARDER_H_ @}*/
diff --git a/src/libcharon/plugins/forecast/forecast_listener.c b/src/libcharon/plugins/forecast/forecast_listener.c
new file mode 100644
index 0000000..63a8cb1
--- /dev/null
+++ b/src/libcharon/plugins/forecast/forecast_listener.c
@@ -0,0 +1,680 @@
+/*
+ * Copyright (C) 2010-2014 Martin Willi
+ * Copyright (C) 2010-2014 revosec AG
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * for more details.
+ */
+
+#include "forecast_listener.h"
+
+#include <errno.h>
+#include <libiptc/libiptc.h>
+#include <linux/netfilter/xt_MARK.h>
+#include <linux/netfilter/xt_esp.h>
+
+#include <daemon.h>
+#include <collections/array.h>
+#include <collections/hashtable.h>
+#include <threading/rwlock.h>
+
+typedef struct private_forecast_listener_t private_forecast_listener_t;
+
+/**
+ * Private data of an forecast_listener_t object.
+ */
+struct private_forecast_listener_t {
+
+	/**
+	 * Public forecast_listener_t interface.
+	 */
+	forecast_listener_t public;
+
+	/**
+	 * List of entries
+	 */
+	linked_list_t *entries;
+
+	/**
+	 * RWlock for IP list
+	 */
+	rwlock_t *lock;
+
+	/**
+	 * Configs we do reinjection
+	 */
+	char *reinject_configs;
+
+	/**
+	 * Broadcast address on LAN interface, network order
+	 */
+	u_int32_t broadcast;
+};
+
+/**
+ * Hashtable entry
+ */
+typedef struct {
+	/** local traffic selectors */
+	array_t *lts;
+	/** remote traffic selectors */
+	array_t *rts;
+	/** firewall mark used by CHILD_SA */
+	u_int mark;
+	/** local IKE_SA endpoint */
+	host_t *lhost;
+	/** remote IKE_SA endpoint */
+	host_t *rhost;
+	/** inbound SPI */
+	u_int32_t spi;
+	/** use UDP encapsulation */
+	bool encap;
+	/** whether we should allow reencapsulation of IPsec received forecasts */
+	bool reinject;
+	/** broadcast address used for that entry */
+	u_int32_t broadcast;
+} entry_t;
+
+/**
+ * Destroy an entry
+ */
+static void entry_destroy(entry_t *entry)
+{
+	if (entry)
+	{
+		entry->lhost->destroy(entry->lhost);
+		entry->rhost->destroy(entry->rhost);
+		array_destroy_offset(entry->lts, offsetof(traffic_selector_t, destroy));
+		array_destroy_offset(entry->rts, offsetof(traffic_selector_t, destroy));
+		free(entry);
+	}
+}
+
+/**
+ * Convert an (IPv4) traffic selector to an address and mask
+ */
+static bool ts2in(traffic_selector_t *ts,
+				  struct in_addr *addr, struct in_addr *mask)
+{
+	u_int8_t bits;
+	host_t *net;
+
+	if (ts->get_type(ts) == TS_IPV4_ADDR_RANGE &&
+		ts->to_subnet(ts, &net, &bits))
+	{
+		memcpy(&addr->s_addr, net->get_address(net).ptr, 4);
+		net->destroy(net);
+		mask->s_addr = htonl(0xffffffffU << (32 - bits));
+		return TRUE;
+	}
+	return FALSE;
+}
+
+/**
+ * Convert an (IPv4) host to an address with mask
+ */
+static bool host2in(host_t *host, struct in_addr *addr, struct in_addr *mask)
+{
+	if (host->get_family(host) == AF_INET)
+	{
+		memcpy(&addr->s_addr, host->get_address(host).ptr, 4);
+		mask->s_addr = ~0;
+		return TRUE;
+	}
+	return FALSE;
+}
+
+/**
+ * Add or remove a rule to/from the specified chain
+ */
+static bool manage_rule(struct iptc_handle *ipth, const char *chain,
+						bool add, struct ipt_entry *e)
+{
+	if (add)
+	{
+		if (!iptc_insert_entry(chain, e, 0, ipth))
+		{
+			DBG1(DBG_CFG, "appending %s rule failed: %s",
+				 chain, iptc_strerror(errno));
+			return FALSE;
+		}
+	}
+	else
+	{
+		if (!iptc_delete_entry(chain, e, "", ipth))
+		{
+			DBG1(DBG_CFG, "deleting %s rule failed: %s",
+				 chain, iptc_strerror(errno));
+			return FALSE;
+		}
+	}
+	return TRUE;
+}
+
+/**
+ * Add rule marking UDP-encapsulated ESP packets to match the correct policy
+ */
+static bool manage_pre_esp_in_udp(struct iptc_handle *ipth,
+								  entry_t *entry, bool add)
+{
+	struct {
+		struct ipt_entry e;
+		struct ipt_entry_match m;
+		struct xt_udp udp;
+		struct ipt_entry_target t;
+		struct xt_mark_tginfo2 tm;
+	} ipt = {
+		.e  = {
+			.target_offset = XT_ALIGN(sizeof(ipt.e) + sizeof(ipt.m) +
+									  sizeof(ipt.udp)),
+			.next_offset = sizeof(ipt),
+			.ip = {
+				.proto = IPPROTO_UDP,
+			},
+		},
+		.m = {
+			.u = {
+				.user = {
+					.match_size = XT_ALIGN(sizeof(ipt.m) + sizeof(ipt.udp)),
+					.name = "udp",
+				},
+			},
+		},
+		.udp = {
+			.spts = {
+				entry->rhost->get_port(entry->rhost),
+				entry->rhost->get_port(entry->lhost)
+			},
+			.dpts = {
+				entry->lhost->get_port(entry->lhost),
+				entry->lhost->get_port(entry->lhost)
+			},
+		},
+		.t = {
+			.u = {
+				.user = {
+					.target_size = XT_ALIGN(sizeof(ipt.t) + sizeof(ipt.tm)),
+					.name = "MARK",
+					.revision = 2,
+				},
+			},
+		},
+		.tm = {
+			.mark = entry->mark,
+			.mask = ~0,
+		},
+	};
+
+	if (!host2in(entry->lhost, &ipt.e.ip.dst, &ipt.e.ip.dmsk) ||
+		!host2in(entry->rhost, &ipt.e.ip.src, &ipt.e.ip.smsk))
+	{
+		return FALSE;
+	}
+	return manage_rule(ipth, "PREROUTING", add, &ipt.e);
+}
+
+/**
+ * Add rule marking non-encapsulated ESP packets to match the correct policy
+ */
+static bool manage_pre_esp(struct iptc_handle *ipth, entry_t *entry, bool add)
+{
+	struct {
+		struct ipt_entry e;
+		struct ipt_entry_match m;
+		struct xt_esp esp;
+		struct ipt_entry_target t;
+		struct xt_mark_tginfo2 tm;
+	} ipt = {
+		.e  = {
+			.target_offset = XT_ALIGN(sizeof(ipt.e) + sizeof(ipt.m) +
+									  sizeof(ipt.esp)),
+			.next_offset = sizeof(ipt),
+			.ip = {
+				.proto = IPPROTO_ESP,
+			},
+		},
+		.m = {
+			.u = {
+				.user = {
+					.match_size = XT_ALIGN(sizeof(ipt.m) + sizeof(ipt.esp)),
+					.name = "esp",
+				},
+			},
+		},
+		.esp = {
+			.spis = { htonl(entry->spi), htonl(entry->spi) },
+		},
+		.t = {
+			.u = {
+				.user = {
+					.target_size = XT_ALIGN(sizeof(ipt.t) + sizeof(ipt.tm)),
+					.name = "MARK",
+					.revision = 2,
+				},
+			},
+		},
+		.tm = {
+			.mark = entry->mark,
+			.mask = ~0,
+		},
+	};
+
+	if (!host2in(entry->lhost, &ipt.e.ip.dst, &ipt.e.ip.dmsk) ||
+		!host2in(entry->rhost, &ipt.e.ip.src, &ipt.e.ip.smsk))
+	{
+		return FALSE;
+	}
+	return manage_rule(ipth, "PREROUTING", add, &ipt.e);
+}
+
+/**
+ * Add rule marking ESP packets to match the correct policy
+ */
+static bool manage_pre(struct iptc_handle *ipth, entry_t *entry, bool add)
+{
+	if (entry->encap)
+	{
+		return manage_pre_esp_in_udp(ipth, entry, add);
+	}
+	return manage_pre_esp(ipth, entry, add);
+}
+
+/**
+ * Add rule handling outbound traffic to use correct mark
+ */
+static bool manage_out(struct iptc_handle *ipth, entry_t *entry, bool add)
+{
+	struct {
+		struct ipt_entry e;
+		struct ipt_entry_target t;
+		struct xt_mark_tginfo2 m;
+	} ipt = {
+		.e  = {
+			.target_offset = XT_ALIGN(sizeof(ipt.e)),
+			.next_offset = sizeof(ipt),
+		},
+		.t = {
+			.u.user.target_size = XT_ALIGN(sizeof(ipt.t) + sizeof(ipt.m)),
+			.u.user.name = "MARK",
+			.u.user.revision = 2,
+		},
+		.m = {
+			.mark = entry->mark,
+			.mask = ~0,
+		},
+	};
+	enumerator_t *enumerator;
+	traffic_selector_t *ts;
+
+	enumerator = array_create_enumerator(entry->rts);
+	while (enumerator->enumerate(enumerator, &ts))
+	{
+		if (!ts2in(ts, &ipt.e.ip.dst, &ipt.e.ip.dmsk))
+		{
+			continue;
+		}
+		if (ipt.e.ip.dst.s_addr == 0xffffffff ||
+			ipt.e.ip.dst.s_addr == entry->broadcast ||
+			memeq(&ipt.e.ip.dst.s_addr, "\xe0", 1))
+		{
+			/* skip broadcast/multicast selectors, they are shared and the mark
+			 * is set by the socket we use for reinjection */
+			continue;
+		}
+		if (!manage_rule(ipth, "PREROUTING", add, &ipt.e) ||
+			!manage_rule(ipth, "OUTPUT", add, &ipt.e))
+		{
+			enumerator->destroy(enumerator);
+			return FALSE;
+		}
+	}
+	enumerator->destroy(enumerator);
+
+	return TRUE;
+}
+
+/**
+ * Check if config is whitelisted to reinject traffic
+ */
+static bool is_reinject_config(private_forecast_listener_t *this, char *name)
+{
+	enumerator_t *enumerator;
+	bool reinject = FALSE;
+	char *token;
+
+	enumerator = enumerator_create_token(this->reinject_configs, ",", " ");
+	while (enumerator->enumerate(enumerator, &token))
+	{
+		if (streq(token, name))
+		{
+			reinject = TRUE;
+			break;
+		}
+	}
+	enumerator->destroy(enumerator);
+
+	return reinject;
+}
+
+/**
+ * Add rules and entry for given CHILD_SA
+ */
+static bool add_entry(private_forecast_listener_t *this,
+					  struct iptc_handle *ipth, host_t *lhost, host_t *rhost,
+					  child_sa_t *child_sa, bool encap)
+{
+	enumerator_t *enumerator;
+	traffic_selector_t *ts;
+	entry_t *entry;
+
+	INIT(entry,
+		.lts = array_create(0, 0),
+		.rts = array_create(0, 0),
+		.lhost = lhost->clone(lhost),
+		.rhost = rhost->clone(rhost),
+		.spi = child_sa->get_spi(child_sa, TRUE),
+		.encap = encap,
+		.mark = child_sa->get_mark(child_sa, TRUE).value,
+		.reinject = is_reinject_config(this, child_sa->get_name(child_sa)),
+		.broadcast = this->broadcast,
+	);
+
+	enumerator = child_sa->create_ts_enumerator(child_sa, TRUE);
+	while (enumerator->enumerate(enumerator, &ts))
+	{
+		array_insert(entry->lts, ARRAY_TAIL, ts->clone(ts));
+	}
+	enumerator->destroy(enumerator);
+
+	enumerator = child_sa->create_ts_enumerator(child_sa, FALSE);
+	while (enumerator->enumerate(enumerator, &ts))
+	{
+		array_insert(entry->rts, ARRAY_TAIL, ts->clone(ts));
+	}
+	enumerator->destroy(enumerator);
+
+	if (manage_pre(ipth, entry, TRUE) &&
+		manage_out(ipth, entry, TRUE))
+	{
+		this->lock->write_lock(this->lock);
+		this->entries->insert_last(this->entries, entry);
+		this->lock->unlock(this->lock);
+		return TRUE;
+	}
+	entry_destroy(entry);
+	return FALSE;
+}
+
+/**
+ * Remove an entry and rules for a given mark
+ */
+static bool remove_entry(private_forecast_listener_t *this,
+						 struct iptc_handle *ipth, child_sa_t *child_sa)
+{
+	enumerator_t *enumerator;
+	entry_t *entry;
+	bool done = FALSE;
+
+	this->lock->write_lock(this->lock);
+	enumerator = this->entries->create_enumerator(this->entries);
+	while (enumerator->enumerate(enumerator, &entry))
+	{
+		if (entry->mark == child_sa->get_mark(child_sa, TRUE).value)
+		{
+			this->entries->remove_at(this->entries, enumerator);
+			if (manage_pre(ipth, entry, FALSE) &&
+				manage_out(ipth, entry, FALSE))
+			{
+				done = TRUE;
+			}
+			entry_destroy(entry);
+			break;
+		}
+	}
+	enumerator->destroy(enumerator);
+	this->lock->unlock(this->lock);
+
+	return done;
+}
+
+/**
+ * Initialize iptables handle, log error
+ */
+static struct iptc_handle* init_handle()
+{
+	struct iptc_handle *ipth;
+
+	ipth = iptc_init("mangle");
+	if (ipth)
+	{
+		return ipth;
+	}
+	DBG1(DBG_CFG, "initializing iptables failed: %s", iptc_strerror(errno));
+	return NULL;
+}
+
+/**
+ * Commit iptables rules, log error
+ */
+static bool commit_handle(struct iptc_handle *ipth)
+{
+	if (iptc_commit(ipth))
+	{
+		return TRUE;
+	}
+	DBG1(DBG_CFG, "forecast iptables commit failed: %s", iptc_strerror(errno));
+	return FALSE;
+}
+
+/**
+ * Check if we should handle the given CHILD_SA
+ */
+static bool handle_sa(child_sa_t *child_sa)
+{
+	return child_sa->get_mark(child_sa, TRUE).value &&
+		   child_sa->get_mark(child_sa, FALSE).value;
+}
+
+METHOD(listener_t, child_updown, bool,
+	private_forecast_listener_t *this, ike_sa_t *ike_sa, child_sa_t *child_sa,
+	bool up)
+{
+	struct iptc_handle *ipth;
+	host_t *lhost, *rhost;
+	bool encap;
+
+	lhost = ike_sa->get_my_host(ike_sa);
+	rhost = ike_sa->get_other_host(ike_sa);
+	encap = child_sa->has_encap(child_sa);
+
+	if (handle_sa(child_sa))
+	{
+		ipth = init_handle();
+		if (ipth)
+		{
+			if (up)
+			{
+				if (add_entry(this, ipth, lhost, rhost, child_sa, encap))
+				{
+					commit_handle(ipth);
+				}
+			}
+			else
+			{
+				if (remove_entry(this, ipth, child_sa))
+				{
+					commit_handle(ipth);
+				}
+			}
+			iptc_free(ipth);
+		}
+	}
+	return TRUE;
+}
+
+METHOD(listener_t, child_rekey, bool,
+	private_forecast_listener_t *this, ike_sa_t *ike_sa,
+	child_sa_t *old, child_sa_t *new)
+{
+	struct iptc_handle *ipth;;
+	host_t *lhost, *rhost;
+
+	lhost = ike_sa->get_my_host(ike_sa);
+	rhost = ike_sa->get_other_host(ike_sa);
+
+	if (handle_sa(old))
+	{
+		ipth = init_handle();
+		if (ipth)
+		{
+			if (remove_entry(this, ipth, old) &&
+				add_entry(this, ipth, lhost, rhost, new, new->has_encap(new)))
+			{
+				commit_handle(ipth);
+			}
+			iptc_free(ipth);
+		}
+	}
+	return TRUE;
+}
+
+METHOD(listener_t, ike_update, bool,
+	private_forecast_listener_t *this, ike_sa_t *ike_sa,
+	bool local, host_t *new)
+{
+	struct iptc_handle *ipth;
+	enumerator_t *enumerator;
+	child_sa_t *child_sa;
+	host_t *lhost, *rhost;
+	bool encap;
+
+	if (local)
+	{
+		lhost = new;
+		rhost = ike_sa->get_other_host(ike_sa);
+	}
+	else
+	{
+		lhost = ike_sa->get_my_host(ike_sa);
+		rhost = new;
+	}
+	/* during ike_update(), has_encap() on the CHILD_SA has not yet been
+	 * updated, but shows the old state. */
+	encap = ike_sa->has_condition(ike_sa, COND_NAT_ANY);
+
+	enumerator = ike_sa->create_child_sa_enumerator(ike_sa);
+	while (enumerator->enumerate(enumerator, &child_sa))
+	{
+		if (handle_sa(child_sa))
+		{
+			ipth = init_handle();
+			if (ipth)
+			{
+				if (remove_entry(this, ipth, child_sa) &&
+					add_entry(this, ipth, lhost, rhost, child_sa, encap))
+				{
+					commit_handle(ipth);
+				}
+				iptc_free(ipth);
+			}
+		}
+	}
+	enumerator->destroy(enumerator);
+
+	return TRUE;
+}
+
+/**
+ * Filter to map entries to ts/mark
+ */
+static bool ts_filter(entry_t *entry, traffic_selector_t **ts,
+					  traffic_selector_t **out, void *dummy, u_int32_t *mark,
+					  void *dummy2, bool *reinject)
+{
+	*out = *ts;
+	*mark = entry->mark;
+	*reinject = entry->reinject;
+	return TRUE;
+}
+
+/**
+ * Create inner enumerator over local traffic selectors
+ */
+static enumerator_t* create_inner_local(entry_t *entry, rwlock_t *lock)
+{
+	return enumerator_create_filter(array_create_enumerator(entry->lts),
+									(void*)ts_filter, entry, NULL);
+}
+
+/**
+ * Create inner enumerator over remote traffic selectors
+ */
+static enumerator_t* create_inner_remote(entry_t *entry, rwlock_t *lock)
+{
+	return enumerator_create_filter(array_create_enumerator(entry->rts),
+									(void*)ts_filter, entry, NULL);
+}
+
+METHOD(forecast_listener_t, create_enumerator, enumerator_t*,
+	private_forecast_listener_t *this, bool local)
+{
+	this->lock->read_lock(this->lock);
+	return enumerator_create_nested(
+					this->entries->create_enumerator(this->entries),
+					(void*)(local ? create_inner_local : create_inner_remote),
+					this->lock, (void*)this->lock->unlock);
+}
+
+METHOD(forecast_listener_t, set_broadcast, void,
+	private_forecast_listener_t *this, host_t *bcast)
+{
+	if (bcast->get_family(bcast) == AF_INET)
+	{
+		struct sockaddr_in *in;
+
+		in = (struct sockaddr_in*)bcast->get_sockaddr(bcast);
+		this->broadcast = in->sin_addr.s_addr;
+	}
+}
+
+METHOD(forecast_listener_t, destroy, void,
+	private_forecast_listener_t *this)
+{
+	this->entries->destroy(this->entries);
+	this->lock->destroy(this->lock);
+	free(this);
+}
+
+/**
+ * See header
+ */
+forecast_listener_t *forecast_listener_create()
+{
+	private_forecast_listener_t *this;
+
+	INIT(this,
+		.public = {
+			.listener = {
+				.ike_update = _ike_update,
+				.child_updown = _child_updown,
+				.child_rekey = _child_rekey,
+			},
+			.create_enumerator = _create_enumerator,
+			.set_broadcast = _set_broadcast,
+			.destroy = _destroy,
+		},
+		.entries = linked_list_create(),
+		.lock = rwlock_create(RWLOCK_TYPE_DEFAULT),
+		.reinject_configs = lib->settings->get_str(lib->settings,
+								"%s.plugins.forecast.reinject", "", lib->ns),
+	);
+
+	return &this->public;
+}
diff --git a/src/libcharon/plugins/forecast/forecast_listener.h b/src/libcharon/plugins/forecast/forecast_listener.h
new file mode 100644
index 0000000..49827ec
--- /dev/null
+++ b/src/libcharon/plugins/forecast/forecast_listener.h
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 2010-2014 Martin Willi
+ * Copyright (C) 2010-2014 revosec AG
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * for more details.
+ */
+
+/**
+ * @defgroup forecast_listener forecast_listener
+ * @{ @ingroup forecast
+ */
+
+#ifndef FORECAST_LISTENER_H_
+#define FORECAST_LISTENER_H_
+
+#include <bus/listeners/listener.h>
+
+typedef struct forecast_listener_t forecast_listener_t;
+
+/**
+ * Listener to register the set of IPs we forward received multi/broadcasts to.
+ */
+struct forecast_listener_t {
+
+	/**
+	 * Implements listener_t interface.
+	 */
+	listener_t listener;
+
+	/**
+	 * Create an enumerator over active tunnels.
+	 *
+	 * The enumerator enumerates over local or remote traffic selectors,
+	 * associated firewall marks and if decasulated packets should get
+	 * reinjected into other tunnels.
+	 *
+	 * @param local		TRUE to enumerate local, FALSE to enumerate remote TS
+	 * @return			enumerator over (traffic_selector_t*, u_int, bool)
+	 */
+	enumerator_t* (*create_enumerator)(forecast_listener_t *this, bool local);
+
+	/**
+	 * Set the broadcast address of the LAN interface.
+	 *
+	 * @param bcast		broadcast address
+	 */
+	void (*set_broadcast)(forecast_listener_t *this, host_t *bcast);
+
+	/**
+	 * Destroy a forecast_listener_t.
+	 */
+	void (*destroy)(forecast_listener_t *this);
+};
+
+/**
+ * Create a forecast_listener instance.
+ */
+forecast_listener_t *forecast_listener_create();
+
+#endif /** FORECAST_LISTENER_H_ @}*/
diff --git a/src/libcharon/plugins/forecast/forecast_plugin.c b/src/libcharon/plugins/forecast/forecast_plugin.c
new file mode 100644
index 0000000..a129b76
--- /dev/null
+++ b/src/libcharon/plugins/forecast/forecast_plugin.c
@@ -0,0 +1,118 @@
+/*
+ * Copyright (C) 2010-2014 Martin Willi
+ * Copyright (C) 2010-2014 revosec AG
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * for more details.
+ */
+
+#include "forecast_plugin.h"
+#include "forecast_listener.h"
+#include "forecast_forwarder.h"
+
+#include <daemon.h>
+
+typedef struct private_forecast_plugin_t private_forecast_plugin_t;
+
+/**
+ * Private data of forecast plugin
+ */
+struct private_forecast_plugin_t {
+
+	/**
+	 * implements plugin interface
+	 */
+	forecast_plugin_t public;
+
+	/**
+	 * Listener registering active tunnels
+	 */
+	forecast_listener_t *listener;
+
+	/**
+	 * Broadcast/Multicast sniffer and forwarder
+	 */
+	forecast_forwarder_t *forwarder;
+};
+
+METHOD(plugin_t, get_name, char*,
+	private_forecast_plugin_t *this)
+{
+	return "forecast";
+}
+
+/**
+ * Register plugin features
+ */
+static bool register_forecast(private_forecast_plugin_t *this,
+							  plugin_feature_t *feature, bool reg, void *data)
+{
+	if (reg)
+	{
+		this->forwarder = forecast_forwarder_create(this->listener);
+		if (!this->forwarder)
+		{
+			return FALSE;
+		}
+		charon->bus->add_listener(charon->bus, &this->listener->listener);
+	}
+	else
+	{
+		charon->bus->remove_listener(charon->bus, &this->listener->listener);
+		this->forwarder->destroy(this->forwarder);
+	}
+	return TRUE;
+}
+
+METHOD(plugin_t, get_features, int,
+	private_forecast_plugin_t *this, plugin_feature_t *features[])
+{
+	static plugin_feature_t f[] = {
+		PLUGIN_CALLBACK((plugin_feature_callback_t)register_forecast, NULL),
+			PLUGIN_PROVIDE(CUSTOM, "forecast"),
+	};
+	*features = f;
+	return countof(f);
+}
+
+METHOD(plugin_t, destroy, void,
+	private_forecast_plugin_t *this)
+{
+	this->listener->destroy(this->listener);
+	free(this);
+}
+
+/**
+ * Plugin constructor
+ */
+plugin_t *forecast_plugin_create()
+{
+	private_forecast_plugin_t *this;
+
+	if (!lib->caps->keep(lib->caps, CAP_NET_RAW))
+	{
+		DBG1(DBG_NET, "forecast plugin requires CAP_NET_RAW capability");
+		return NULL;
+	}
+
+	INIT(this,
+		.public = {
+			.plugin = {
+				.get_name = _get_name,
+				.get_features = _get_features,
+				.reload = (void*)return_false,
+				.destroy = _destroy,
+			},
+		},
+		.listener = forecast_listener_create(),
+	);
+
+	return &this->public.plugin;
+}
diff --git a/src/libcharon/plugins/forecast/forecast_plugin.h b/src/libcharon/plugins/forecast/forecast_plugin.h
new file mode 100644
index 0000000..739ca4d
--- /dev/null
+++ b/src/libcharon/plugins/forecast/forecast_plugin.h
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2010-2014 Martin Willi
+ * Copyright (C) 2010-2014 revosec AG
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * for more details.
+ */
+
+/**
+ * @defgroup forecast forecast
+ * @ingroup cplugins
+ *
+ * @defgroup forecast_plugin forecast_plugin
+ * @{ @ingroup forecast
+ */
+
+#ifndef FORECAST_PLUGIN_H_
+#define FORECAST_PLUGIN_H_
+
+#include <plugins/plugin.h>
+
+typedef struct forecast_plugin_t forecast_plugin_t;
+
+/**
+ * Broadcast/Multicast forwarding plugin.
+ */
+struct forecast_plugin_t {
+
+	/**
+	 * Implements plugin interface.
+	 */
+	plugin_t plugin;
+};
+
+#endif /** FORECAST_PLUGIN_H_ @}*/
diff --git a/src/libcharon/plugins/ha/Makefile.in b/src/libcharon/plugins/ha/Makefile.in
index aa5bdb7..de74f88 100644
--- a/src/libcharon/plugins/ha/Makefile.in
+++ b/src/libcharon/plugins/ha/Makefile.in
@@ -229,6 +229,7 @@ DLLIB = @DLLIB@
 DLLTOOL = @DLLTOOL@
 DSYMUTIL = @DSYMUTIL@
 DUMPBIN = @DUMPBIN@
+EASY_INSTALL = @EASY_INSTALL@
 ECHO_C = @ECHO_C@
 ECHO_N = @ECHO_N@
 ECHO_T = @ECHO_T@
@@ -289,10 +290,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
 PLUGIN_CFLAGS = @PLUGIN_CFLAGS@
 PTHREADLIB = @PTHREADLIB@
 PYTHON = @PYTHON@
+PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@
 PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
 PYTHON_PLATFORM = @PYTHON_PLATFORM@
 PYTHON_PREFIX = @PYTHON_PREFIX@
 PYTHON_VERSION = @PYTHON_VERSION@
+PY_TEST = @PY_TEST@
 RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
@@ -366,6 +369,8 @@ json_CFLAGS = @json_CFLAGS@
 json_LIBS = @json_LIBS@
 libdir = @libdir@
 libexecdir = @libexecdir@
+libiptc_CFLAGS = @libiptc_CFLAGS@
+libiptc_LIBS = @libiptc_LIBS@
 linux_headers = @linux_headers@
 localedir = @localedir@
 localstatedir = @localstatedir@
diff --git a/src/libcharon/plugins/ha/ha_attribute.c b/src/libcharon/plugins/ha/ha_attribute.c
index dd55fae..2b271a8 100644
--- a/src/libcharon/plugins/ha/ha_attribute.c
+++ b/src/libcharon/plugins/ha/ha_attribute.c
@@ -170,7 +170,7 @@ static bool responsible_for(private_ha_attribute_t *this, int bit)
 }
 
 METHOD(attribute_provider_t, acquire_address, host_t*,
-	private_ha_attribute_t *this, linked_list_t *pools, identification_t *id,
+	private_ha_attribute_t *this, linked_list_t *pools, ike_sa_t *ike_sa,
 	host_t *requested)
 {
 	enumerator_t *enumerator;
@@ -233,7 +233,7 @@ METHOD(attribute_provider_t, acquire_address, host_t*,
 
 METHOD(attribute_provider_t, release_address, bool,
 	private_ha_attribute_t *this, linked_list_t *pools, host_t *address,
-	identification_t *id)
+	ike_sa_t *ike_sa)
 {
 	enumerator_t *enumerator;
 	pool_t *pool;
diff --git a/src/libcharon/plugins/ha/ha_cache.c b/src/libcharon/plugins/ha/ha_cache.c
index 60e75fc..6c1b347 100644
--- a/src/libcharon/plugins/ha/ha_cache.c
+++ b/src/libcharon/plugins/ha/ha_cache.c
@@ -196,9 +196,26 @@ static status_t rekey_children(ike_sa_t *ike_sa)
 	enumerator_t *enumerator;
 	child_sa_t *child_sa;
 	status_t status = SUCCESS;
+	linked_list_t *children;
+	struct {
+		protocol_id_t protocol;
+		u_int32_t spi;
+	} *info;
 
+	children = linked_list_create();
 	enumerator = ike_sa->create_child_sa_enumerator(ike_sa);
-	while (enumerator->enumerate(enumerator, (void**)&child_sa))
+	while (enumerator->enumerate(enumerator, &child_sa))
+	{
+		INIT(info,
+			.protocol = child_sa->get_protocol(child_sa),
+			.spi = child_sa->get_spi(child_sa, TRUE),
+		);
+		children->insert_last(children, info);
+	}
+	enumerator->destroy(enumerator);
+
+	enumerator = children->create_enumerator(children);
+	while (enumerator->enumerate(enumerator, &info))
 	{
 		if (ike_sa->supports_extension(ike_sa, EXT_MS_WINDOWS) &&
 			ike_sa->has_condition(ike_sa, COND_NAT_THERE))
@@ -207,17 +224,13 @@ static status_t rekey_children(ike_sa_t *ike_sa)
 			 * with an "invalid situation" error. We just close the CHILD_SA,
 			 * Windows will reestablish it immediately if required. */
 			DBG1(DBG_CFG, "resyncing CHILD_SA using a delete");
-			status = ike_sa->delete_child_sa(ike_sa,
-											 child_sa->get_protocol(child_sa),
-											 child_sa->get_spi(child_sa, TRUE),
+			status = ike_sa->delete_child_sa(ike_sa, info->protocol, info->spi,
 											 FALSE);
 		}
 		else
 		{
 			DBG1(DBG_CFG, "resyncing CHILD_SA using a rekey");
-			status = ike_sa->rekey_child_sa(ike_sa,
-											child_sa->get_protocol(child_sa),
-											child_sa->get_spi(child_sa, TRUE));
+			status = ike_sa->rekey_child_sa(ike_sa, info->protocol, info->spi);
 		}
 		if (status == DESTROY_ME)
 		{
@@ -225,6 +238,8 @@ static status_t rekey_children(ike_sa_t *ike_sa)
 		}
 	}
 	enumerator->destroy(enumerator);
+	children->destroy_function(children, free);
+
 	return status;
 }
 
diff --git a/src/libcharon/plugins/ha/ha_child.c b/src/libcharon/plugins/ha/ha_child.c
index c166d72..17f2d50 100644
--- a/src/libcharon/plugins/ha/ha_child.c
+++ b/src/libcharon/plugins/ha/ha_child.c
@@ -97,7 +97,7 @@ METHOD(listener_t, child_keys, bool,
 	}
 	m->add_attribute(m, HA_NONCE_I, nonce_i);
 	m->add_attribute(m, HA_NONCE_R, nonce_r);
-	if (dh && dh->get_shared_secret(dh, &secret) == SUCCESS)
+	if (dh && dh->get_shared_secret(dh, &secret))
 	{
 		m->add_attribute(m, HA_SECRET, secret);
 		chunk_clear(&secret);
@@ -128,7 +128,7 @@ METHOD(listener_t, child_keys, bool,
 			ike_sa->get_other_host(ike_sa), child_sa->get_spi(child_sa, FALSE));
 	DBG1(DBG_CFG, "handling HA CHILD_SA %s{%d} %#R=== %#R "
 		"(segment in: %d%s, out: %d%s)", child_sa->get_name(child_sa),
-		child_sa->get_reqid(child_sa), local_ts, remote_ts,
+		child_sa->get_unique_id(child_sa), local_ts, remote_ts,
 		seg_i, this->segments->is_active(this->segments, seg_i) ? "*" : "",
 		seg_o, this->segments->is_active(this->segments, seg_o) ? "*" : "");
 
diff --git a/src/libcharon/plugins/ha/ha_dispatcher.c b/src/libcharon/plugins/ha/ha_dispatcher.c
index e20e872..31eeb93 100644
--- a/src/libcharon/plugins/ha/ha_dispatcher.c
+++ b/src/libcharon/plugins/ha/ha_dispatcher.c
@@ -81,17 +81,18 @@ struct ha_diffie_hellman_t {
 	chunk_t pub;
 };
 
-METHOD(diffie_hellman_t, dh_get_shared_secret, status_t,
+METHOD(diffie_hellman_t, dh_get_shared_secret, bool,
 	ha_diffie_hellman_t *this, chunk_t *secret)
 {
 	*secret = chunk_clone(this->secret);
-	return SUCCESS;
+	return TRUE;
 }
 
-METHOD(diffie_hellman_t, dh_get_my_public_value, void,
+METHOD(diffie_hellman_t, dh_get_my_public_value, bool,
 	ha_diffie_hellman_t *this, chunk_t *value)
 {
 	*value = chunk_clone(this->pub);
+	return TRUE;
 }
 
 METHOD(diffie_hellman_t, dh_destroy, void,
@@ -373,6 +374,9 @@ static void process_ike_update(private_ha_dispatcher_t *this,
 				else
 				{
 					DBG1(DBG_IKE, "HA is missing nodes peer configuration");
+					charon->ike_sa_manager->checkin_and_destroy(
+												charon->ike_sa_manager, ike_sa);
+					ike_sa = NULL;
 				}
 				break;
 			case HA_EXTENSIONS:
@@ -718,7 +722,8 @@ static void process_child_add(private_ha_dispatcher_t *this,
 
 	child_sa = child_sa_create(ike_sa->get_my_host(ike_sa),
 							   ike_sa->get_other_host(ike_sa), config, 0,
-							   ike_sa->has_condition(ike_sa, COND_NAT_ANY));
+							   ike_sa->has_condition(ike_sa, COND_NAT_ANY),
+							   0, 0);
 	child_sa->set_mode(child_sa, mode);
 	child_sa->set_protocol(child_sa, PROTO_ESP);
 	child_sa->set_ipcomp(child_sa, ipcomp);
@@ -835,7 +840,7 @@ static void process_child_add(private_ha_dispatcher_t *this,
 
 	DBG1(DBG_CFG, "installed HA CHILD_SA %s{%d} %#R=== %#R "
 		"(segment in: %d%s, out: %d%s)", child_sa->get_name(child_sa),
-		child_sa->get_reqid(child_sa), local_ts, remote_ts,
+		child_sa->get_unique_id(child_sa), local_ts, remote_ts,
 		seg_i, this->segments->is_active(this->segments, seg_i) ? "*" : "",
 		seg_o, this->segments->is_active(this->segments, seg_o) ? "*" : "");
 	child_sa->add_policies(child_sa, local_ts, remote_ts);
diff --git a/src/libcharon/plugins/ha/ha_ike.c b/src/libcharon/plugins/ha/ha_ike.c
index 442a3a2..6b4b53c 100644
--- a/src/libcharon/plugins/ha/ha_ike.c
+++ b/src/libcharon/plugins/ha/ha_ike.c
@@ -84,7 +84,7 @@ METHOD(listener_t, ike_keys, bool,
 	{	/* do not sync SA between nodes */
 		return TRUE;
 	}
-	if (dh->get_shared_secret(dh, &secret) != SUCCESS)
+	if (!dh->get_shared_secret(dh, &secret))
 	{
 		return TRUE;
 	}
@@ -127,9 +127,11 @@ METHOD(listener_t, ike_keys, bool,
 	chunk_clear(&secret);
 	if (ike_sa->get_version(ike_sa) == IKEV1)
 	{
-		dh->get_my_public_value(dh, &secret);
-		m->add_attribute(m, HA_LOCAL_DH, secret);
-		chunk_free(&secret);
+		if (dh->get_my_public_value(dh, &secret))
+		{
+			m->add_attribute(m, HA_LOCAL_DH, secret);
+			chunk_free(&secret);
+		}
 		m->add_attribute(m, HA_REMOTE_DH, dh_other);
 		if (shared)
 		{
diff --git a/src/libcharon/plugins/ha/ha_plugin.c b/src/libcharon/plugins/ha/ha_plugin.c
index 493cad5..a58377b 100644
--- a/src/libcharon/plugins/ha/ha_plugin.c
+++ b/src/libcharon/plugins/ha/ha_plugin.c
@@ -25,7 +25,6 @@
 #include "ha_attribute.h"
 
 #include <daemon.h>
-#include <hydra.h>
 #include <config/child_cfg.h>
 
 typedef struct private_ha_plugin_t private_ha_plugin_t;
@@ -108,13 +107,13 @@ static bool plugin_cb(private_ha_plugin_t *this,
 		charon->bus->add_listener(charon->bus, &this->segments->listener);
 		charon->bus->add_listener(charon->bus, &this->ike->listener);
 		charon->bus->add_listener(charon->bus, &this->child->listener);
-		hydra->attributes->add_provider(hydra->attributes,
-										&this->attr->provider);
+		charon->attributes->add_provider(charon->attributes,
+										 &this->attr->provider);
 	}
 	else
 	{
-		hydra->attributes->remove_provider(hydra->attributes,
-										   &this->attr->provider);
+		charon->attributes->remove_provider(charon->attributes,
+											&this->attr->provider);
 		charon->bus->remove_listener(charon->bus, &this->segments->listener);
 		charon->bus->remove_listener(charon->bus, &this->ike->listener);
 		charon->bus->remove_listener(charon->bus, &this->child->listener);
@@ -224,4 +223,3 @@ plugin_t *ha_plugin_create()
 
 	return &this->public.plugin;
 }
-
diff --git a/src/libcharon/plugins/ipseckey/Makefile.in b/src/libcharon/plugins/ipseckey/Makefile.in
index bd3fd63..f98e78f 100644
--- a/src/libcharon/plugins/ipseckey/Makefile.in
+++ b/src/libcharon/plugins/ipseckey/Makefile.in
@@ -229,6 +229,7 @@ DLLIB = @DLLIB@
 DLLTOOL = @DLLTOOL@
 DSYMUTIL = @DSYMUTIL@
 DUMPBIN = @DUMPBIN@
+EASY_INSTALL = @EASY_INSTALL@
 ECHO_C = @ECHO_C@
 ECHO_N = @ECHO_N@
 ECHO_T = @ECHO_T@
@@ -289,10 +290,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
 PLUGIN_CFLAGS = @PLUGIN_CFLAGS@
 PTHREADLIB = @PTHREADLIB@
 PYTHON = @PYTHON@
+PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@
 PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
 PYTHON_PLATFORM = @PYTHON_PLATFORM@
 PYTHON_PREFIX = @PYTHON_PREFIX@
 PYTHON_VERSION = @PYTHON_VERSION@
+PY_TEST = @PY_TEST@
 RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
@@ -366,6 +369,8 @@ json_CFLAGS = @json_CFLAGS@
 json_LIBS = @json_LIBS@
 libdir = @libdir@
 libexecdir = @libexecdir@
+libiptc_CFLAGS = @libiptc_CFLAGS@
+libiptc_LIBS = @libiptc_LIBS@
 linux_headers = @linux_headers@
 localedir = @localedir@
 localstatedir = @localstatedir@
diff --git a/src/libcharon/plugins/kernel_iph/Makefile.in b/src/libcharon/plugins/kernel_iph/Makefile.in
index 7e1f79b..7a2583d 100644
--- a/src/libcharon/plugins/kernel_iph/Makefile.in
+++ b/src/libcharon/plugins/kernel_iph/Makefile.in
@@ -229,6 +229,7 @@ DLLIB = @DLLIB@
 DLLTOOL = @DLLTOOL@
 DSYMUTIL = @DSYMUTIL@
 DUMPBIN = @DUMPBIN@
+EASY_INSTALL = @EASY_INSTALL@
 ECHO_C = @ECHO_C@
 ECHO_N = @ECHO_N@
 ECHO_T = @ECHO_T@
@@ -289,10 +290,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
 PLUGIN_CFLAGS = @PLUGIN_CFLAGS@
 PTHREADLIB = @PTHREADLIB@
 PYTHON = @PYTHON@
+PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@
 PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
 PYTHON_PLATFORM = @PYTHON_PLATFORM@
 PYTHON_PREFIX = @PYTHON_PREFIX@
 PYTHON_VERSION = @PYTHON_VERSION@
+PY_TEST = @PY_TEST@
 RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
@@ -366,6 +369,8 @@ json_CFLAGS = @json_CFLAGS@
 json_LIBS = @json_LIBS@
 libdir = @libdir@
 libexecdir = @libexecdir@
+libiptc_CFLAGS = @libiptc_CFLAGS@
+libiptc_LIBS = @libiptc_LIBS@
 linux_headers = @linux_headers@
 localedir = @localedir@
 localstatedir = @localstatedir@
diff --git a/src/libcharon/plugins/kernel_libipsec/Makefile.in b/src/libcharon/plugins/kernel_libipsec/Makefile.in
index c961c0b..6b6c956 100644
--- a/src/libcharon/plugins/kernel_libipsec/Makefile.in
+++ b/src/libcharon/plugins/kernel_libipsec/Makefile.in
@@ -231,6 +231,7 @@ DLLIB = @DLLIB@
 DLLTOOL = @DLLTOOL@
 DSYMUTIL = @DSYMUTIL@
 DUMPBIN = @DUMPBIN@
+EASY_INSTALL = @EASY_INSTALL@
 ECHO_C = @ECHO_C@
 ECHO_N = @ECHO_N@
 ECHO_T = @ECHO_T@
@@ -291,10 +292,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
 PLUGIN_CFLAGS = @PLUGIN_CFLAGS@
 PTHREADLIB = @PTHREADLIB@
 PYTHON = @PYTHON@
+PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@
 PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
 PYTHON_PLATFORM = @PYTHON_PLATFORM@
 PYTHON_PREFIX = @PYTHON_PREFIX@
 PYTHON_VERSION = @PYTHON_VERSION@
+PY_TEST = @PY_TEST@
 RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
@@ -368,6 +371,8 @@ json_CFLAGS = @json_CFLAGS@
 json_LIBS = @json_LIBS@
 libdir = @libdir@
 libexecdir = @libexecdir@
+libiptc_CFLAGS = @libiptc_CFLAGS@
+libiptc_LIBS = @libiptc_LIBS@
 linux_headers = @linux_headers@
 localedir = @localedir@
 localstatedir = @localstatedir@
diff --git a/src/libcharon/plugins/kernel_libipsec/kernel_libipsec_ipsec.c b/src/libcharon/plugins/kernel_libipsec/kernel_libipsec_ipsec.c
index bd07a67..6246dc5 100644
--- a/src/libcharon/plugins/kernel_libipsec/kernel_libipsec_ipsec.c
+++ b/src/libcharon/plugins/kernel_libipsec/kernel_libipsec_ipsec.c
@@ -222,10 +222,10 @@ static inline bool policy_entry_equals(policy_entry_t *a,
 /**
  * Expiration callback
  */
-static void expire(u_int32_t reqid, u_int8_t protocol, u_int32_t spi, bool hard)
+static void expire(u_int8_t protocol, u_int32_t spi, host_t *dst, bool hard)
 {
-	hydra->kernel_interface->expire(hydra->kernel_interface, reqid, protocol,
-									spi, hard);
+	hydra->kernel_interface->expire(hydra->kernel_interface, protocol,
+									spi, dst, hard);
 }
 
 METHOD(kernel_ipsec_t, get_features, kernel_feature_t,
@@ -236,14 +236,14 @@ METHOD(kernel_ipsec_t, get_features, kernel_feature_t,
 
 METHOD(kernel_ipsec_t, get_spi, status_t,
 	private_kernel_libipsec_ipsec_t *this, host_t *src, host_t *dst,
-	u_int8_t protocol, u_int32_t reqid, u_int32_t *spi)
+	u_int8_t protocol, u_int32_t *spi)
 {
-	return ipsec->sas->get_spi(ipsec->sas, src, dst, protocol, reqid, spi);
+	return ipsec->sas->get_spi(ipsec->sas, src, dst, protocol, spi);
 }
 
 METHOD(kernel_ipsec_t, get_cpi, status_t,
 	private_kernel_libipsec_ipsec_t *this, host_t *src, host_t *dst,
-	u_int32_t reqid, u_int16_t *cpi)
+	u_int16_t *cpi)
 {
 	return NOT_SUPPORTED;
 }
@@ -254,13 +254,13 @@ METHOD(kernel_ipsec_t, add_sa, status_t,
 	u_int32_t tfc, lifetime_cfg_t *lifetime, u_int16_t enc_alg, chunk_t enc_key,
 	u_int16_t int_alg, chunk_t int_key, ipsec_mode_t mode,
 	u_int16_t ipcomp, u_int16_t cpi, u_int32_t replay_window,
-	bool initiator, bool encap, bool esn, bool inbound,
-	traffic_selector_t *src_ts, traffic_selector_t *dst_ts)
+	bool initiator, bool encap, bool esn, bool inbound, bool update,
+	linked_list_t *src_ts, linked_list_t *dst_ts)
 {
 	return ipsec->sas->add_sa(ipsec->sas, src, dst, spi, protocol, reqid, mark,
 							  tfc, lifetime, enc_alg, enc_key, int_alg, int_key,
-							  mode, ipcomp, cpi, initiator, encap, esn, inbound,
-							  src_ts, dst_ts);
+							  mode, ipcomp, cpi, initiator, encap, esn,
+							  inbound, update);
 }
 
 METHOD(kernel_ipsec_t, update_sa, status_t,
diff --git a/src/libcharon/plugins/kernel_libipsec/kernel_libipsec_router.c b/src/libcharon/plugins/kernel_libipsec/kernel_libipsec_router.c
index 6ce1d4e..830954e 100644
--- a/src/libcharon/plugins/kernel_libipsec/kernel_libipsec_router.c
+++ b/src/libcharon/plugins/kernel_libipsec/kernel_libipsec_router.c
@@ -131,35 +131,6 @@ static void deliver_plain(private_kernel_libipsec_router_t *this,
 }
 
 /**
- * Create an FD set covering all TUN devices and the read end of the notify pipe
- */
-static int collect_fds(private_kernel_libipsec_router_t *this, fd_set *fds)
-{
-	enumerator_t *enumerator;
-	tun_entry_t *entry;
-	int maxfd;
-
-	FD_ZERO(fds);
-	FD_SET(this->notify[0], fds);
-	maxfd = this->notify[0];
-
-	FD_SET(this->tun.fd, fds);
-	maxfd = max(maxfd, this->tun.fd);
-
-	this->lock->read_lock(this->lock);
-	enumerator = this->tuns->create_enumerator(this->tuns);
-	while (enumerator->enumerate(enumerator, NULL, &entry))
-	{
-		FD_SET(entry->fd, fds);
-		maxfd = max(maxfd, entry->fd);
-	}
-	enumerator->destroy(enumerator);
-	this->lock->unlock(this->lock);
-
-	return maxfd + 1;
-}
-
-/**
  * Read and process outbound plaintext packet for the given TUN device
  */
 static void process_plain(tun_device_t *tun)
@@ -183,29 +154,20 @@ static void process_plain(tun_device_t *tun)
 }
 
 /**
- * Handle waiting data for any TUN device
+ * Find flagged revents in a pollfd set by fd
  */
-static void handle_tuns(private_kernel_libipsec_router_t *this, fd_set *fds)
+static int find_revents(struct pollfd *pfd, int count, int fd)
 {
-	enumerator_t *enumerator;
-	tun_entry_t *entry;
+	int i;
 
-	if (FD_ISSET(this->tun.fd, fds))
+	for (i = 0; i < count; i++)
 	{
-		process_plain(this->tun.tun);
-	}
-
-	this->lock->read_lock(this->lock);
-	enumerator = this->tuns->create_enumerator(this->tuns);
-	while (enumerator->enumerate(enumerator, NULL, &entry))
-	{
-		if (FD_ISSET(entry->fd, fds))
+		if (pfd[i].fd == fd)
 		{
-			process_plain(entry->tun);
+			return pfd[i].revents;
 		}
 	}
-	enumerator->destroy(enumerator);
-	this->lock->unlock(this->lock);
+	return 0;
 }
 
 /**
@@ -213,28 +175,68 @@ static void handle_tuns(private_kernel_libipsec_router_t *this, fd_set *fds)
  */
 static job_requeue_t handle_plain(private_kernel_libipsec_router_t *this)
 {
+	enumerator_t *enumerator;
+	tun_entry_t *entry;
 	bool oldstate;
-	fd_set fds;
-	int maxfd;
+	int count = 0;
+	char buf[1];
+	struct pollfd *pfd;
+
+	this->lock->read_lock(this->lock);
 
-	maxfd = collect_fds(this, &fds);
+	pfd = alloca(sizeof(*pfd) * (this->tuns->get_count(this->tuns) + 2));
+	pfd[count].fd = this->notify[0];
+	pfd[count].events = POLLIN;
+	count++;
+	pfd[count].fd = this->tun.fd;
+	pfd[count].events = POLLIN;
+	count++;
+
+	enumerator = this->tuns->create_enumerator(this->tuns);
+	while (enumerator->enumerate(enumerator, NULL, &entry))
+	{
+		pfd[count].fd = entry->fd;
+		pfd[count].events = POLLIN;
+		count++;
+	}
+	enumerator->destroy(enumerator);
+	this->lock->unlock(this->lock);
 
 	oldstate = thread_cancelability(TRUE);
-	if (select(maxfd, &fds, NULL, NULL, NULL) <= 0)
+	if (poll(pfd, count, -1) <= 0)
 	{
 		thread_cancelability(oldstate);
 		return JOB_REQUEUE_FAIR;
 	}
 	thread_cancelability(oldstate);
 
-	if (FD_ISSET(this->notify[0], &fds))
-	{	/* list of TUN devices changed, read notification data, rebuild FDs */
-		char buf[1];
-		while (read(this->notify[0], &buf, sizeof(buf)) == sizeof(buf));
+	if (pfd[0].revents & POLLIN)
+	{
+		/* list of TUN devices changed, read notification data, rebuild FDs */
+		while (read(this->notify[0], &buf, sizeof(buf)) == sizeof(buf))
+		{
+			/* nop */
+		}
 		return JOB_REQUEUE_DIRECT;
 	}
 
-	handle_tuns(this, &fds);
+	if (pfd[1].revents & POLLIN)
+	{
+		process_plain(this->tun.tun);
+	}
+
+	this->lock->read_lock(this->lock);
+	enumerator = this->tuns->create_enumerator(this->tuns);
+	while (enumerator->enumerate(enumerator, NULL, &entry))
+	{
+		if (find_revents(pfd, count, entry->fd) & POLLIN)
+		{
+			process_plain(entry->tun);
+		}
+	}
+	enumerator->destroy(enumerator);
+	this->lock->unlock(this->lock);
+
 	return JOB_REQUEUE_DIRECT;
 }
 
diff --git a/src/libcharon/plugins/kernel_wfp/Makefile.in b/src/libcharon/plugins/kernel_wfp/Makefile.in
index 1c92e30..efb214b 100644
--- a/src/libcharon/plugins/kernel_wfp/Makefile.in
+++ b/src/libcharon/plugins/kernel_wfp/Makefile.in
@@ -237,6 +237,7 @@ DLLIB = @DLLIB@
 DLLTOOL = @DLLTOOL@
 DSYMUTIL = @DSYMUTIL@
 DUMPBIN = @DUMPBIN@
+EASY_INSTALL = @EASY_INSTALL@
 ECHO_C = @ECHO_C@
 ECHO_N = @ECHO_N@
 ECHO_T = @ECHO_T@
@@ -297,10 +298,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
 PLUGIN_CFLAGS = @PLUGIN_CFLAGS@
 PTHREADLIB = @PTHREADLIB@
 PYTHON = @PYTHON@
+PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@
 PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
 PYTHON_PLATFORM = @PYTHON_PLATFORM@
 PYTHON_PREFIX = @PYTHON_PREFIX@
 PYTHON_VERSION = @PYTHON_VERSION@
+PY_TEST = @PY_TEST@
 RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
@@ -374,6 +377,8 @@ json_CFLAGS = @json_CFLAGS@
 json_LIBS = @json_LIBS@
 libdir = @libdir@
 libexecdir = @libexecdir@
+libiptc_CFLAGS = @libiptc_CFLAGS@
+libiptc_LIBS = @libiptc_LIBS@
 linux_headers = @linux_headers@
 localedir = @localedir@
 localstatedir = @localstatedir@
diff --git a/src/libcharon/plugins/kernel_wfp/kernel_wfp_compat.c b/src/libcharon/plugins/kernel_wfp/kernel_wfp_compat.c
index 41f85ba..2e31aa1 100644
--- a/src/libcharon/plugins/kernel_wfp/kernel_wfp_compat.c
+++ b/src/libcharon/plugins/kernel_wfp/kernel_wfp_compat.c
@@ -54,6 +54,24 @@ const GUID FWPM_LAYER_IPFORWARD_V4 = {
 const GUID FWPM_LAYER_IPFORWARD_V6 = {
 	0x7b964818, 0x19c7, 0x493a, { 0xb7,0x1f,0x83,0x2c,0x36,0x84,0xd2,0x8c }
 };
+const GUID FWPM_LAYER_ALE_AUTH_CONNECT_V4 = {
+	0xc38d57d1, 0x05a7, 0x4c33, { 0x90,0x4f,0x7f,0xbc,0xee,0xe6,0x0e,0x82 }
+};
+const GUID FWPM_LAYER_ALE_AUTH_CONNECT_V6 = {
+	0x4a72393b, 0x319f, 0x44bc, { 0x84,0xc3,0xba,0x54,0xdc,0xb3,0xb6,0xb4 }
+};
+const GUID FWPM_LAYER_ALE_AUTH_RECV_ACCEPT_V4 = {
+	0xe1cd9fe7, 0xf4b5, 0x4273, { 0x96,0xc0,0x59,0x2e,0x48,0x7b,0x86,0x50 }
+};
+const GUID FWPM_LAYER_ALE_AUTH_RECV_ACCEPT_V6 = {
+	0xa3b42c97, 0x9f04, 0x4672, { 0xb8,0x7e,0xce,0xe9,0xc4,0x83,0x25,0x7f }
+};
+const GUID FWPM_SUBLAYER_IPSEC_TUNNEL = {
+	0x83f299ed, 0x9ff4, 0x4967, { 0xaf,0xf4,0xc3,0x09,0xf4,0xda,0xb8,0x27 }
+};
+const GUID FWPM_SUBLAYER_IPSEC_FORWARD_OUTBOUND_TUNNEL = {
+	0xa5082e73, 0x8f71, 0x4559, { 0x8a,0x9a,0x10,0x1c,0xea,0x04,0xef,0x87 }
+};
 const GUID FWPM_CALLOUT_IPSEC_INBOUND_TRANSPORT_V4 = {
 	0x5132900d, 0x5e84, 0x4b5f, { 0x80,0xe4,0x01,0x74,0x1e,0x81,0xff,0x10 }
 };
@@ -90,6 +108,24 @@ const GUID FWPM_CALLOUT_IPSEC_FORWARD_OUTBOUND_TUNNEL_V4 = {
 const GUID FWPM_CALLOUT_IPSEC_FORWARD_OUTBOUND_TUNNEL_V6 = {
 	0xdae640cc, 0xe021, 0x4bee, { 0x9e,0xb6,0xa4,0x8b,0x27,0x5c,0x8c,0x1d }
 };
+const GUID FWPM_CALLOUT_IPSEC_ALE_CONNECT_V4 = {
+	0x6ac141fc, 0xf75d, 0x4203, { 0xb9,0xc8,0x48,0xe6,0x14,0x9c,0x27,0x12 }
+};
+const GUID FWPM_CALLOUT_IPSEC_ALE_CONNECT_V6 = {
+	0x4c0dda05, 0xe31f, 0x4666, { 0x90,0xb0,0xb3,0xdf,0xad,0x34,0x12,0x9a  }
+};
+const GUID FWPM_CALLOUT_IPSEC_INBOUND_TUNNEL_ALE_ACCEPT_V4 = {
+	0x3df6e7de, 0xfd20, 0x48f2, { 0x9f,0x26,0xf8,0x54,0x44,0x4c,0xba,0x79 }
+};
+const GUID FWPM_CALLOUT_IPSEC_INBOUND_TUNNEL_ALE_ACCEPT_V6 = {
+	0xa1e392d3, 0x72ac, 0x47bb, { 0x87,0xa7,0x01,0x22,0xc6,0x94,0x34,0xab }
+};
+const GUID FWPM_CALLOUT_IPSEC_INBOUND_INITIATE_SECURE_V4 = {
+	0x7dff309b, 0xba7d, 0x4aba, { 0x91,0xaa,0xae,0x5c,0x66,0x40,0xc9,0x44 }
+};
+const GUID FWPM_CALLOUT_IPSEC_INBOUND_INITIATE_SECURE_V6 = {
+	0xa9a0d6d9, 0xc58c, 0x474e, { 0x8a,0xeb,0x3c,0xfe,0x99,0xd6,0xd5,0x3d }
+};
 
 /**
  * Load a function symbol from a loaded dll
diff --git a/src/libcharon/plugins/kernel_wfp/kernel_wfp_compat.h b/src/libcharon/plugins/kernel_wfp/kernel_wfp_compat.h
index 50a89a0..a553a09 100644
--- a/src/libcharon/plugins/kernel_wfp/kernel_wfp_compat.h
+++ b/src/libcharon/plugins/kernel_wfp/kernel_wfp_compat.h
@@ -127,6 +127,10 @@ const GUID FWPM_LAYER_OUTBOUND_TRANSPORT_V4;
 const GUID FWPM_LAYER_OUTBOUND_TRANSPORT_V6;
 const GUID FWPM_LAYER_IPFORWARD_V4;
 const GUID FWPM_LAYER_IPFORWARD_V6;
+const GUID FWPM_LAYER_ALE_AUTH_CONNECT_V4;
+const GUID FWPM_LAYER_ALE_AUTH_CONNECT_V6;
+const GUID FWPM_LAYER_ALE_AUTH_RECV_ACCEPT_V4;
+const GUID FWPM_LAYER_ALE_AUTH_RECV_ACCEPT_V6;
 const GUID FWPM_SUBLAYER_IPSEC_TUNNEL;
 const GUID FWPM_SUBLAYER_IPSEC_FORWARD_OUTBOUND_TUNNEL;
 const GUID FWPM_CALLOUT_IPSEC_INBOUND_TRANSPORT_V4;
@@ -141,6 +145,12 @@ const GUID FWPM_CALLOUT_IPSEC_FORWARD_INBOUND_TUNNEL_V4;
 const GUID FWPM_CALLOUT_IPSEC_FORWARD_INBOUND_TUNNEL_V6;
 const GUID FWPM_CALLOUT_IPSEC_FORWARD_OUTBOUND_TUNNEL_V4;
 const GUID FWPM_CALLOUT_IPSEC_FORWARD_OUTBOUND_TUNNEL_V6;
+const GUID FWPM_CALLOUT_IPSEC_ALE_CONNECT_V4;
+const GUID FWPM_CALLOUT_IPSEC_ALE_CONNECT_V6;
+const GUID FWPM_CALLOUT_IPSEC_INBOUND_TUNNEL_ALE_ACCEPT_V4;
+const GUID FWPM_CALLOUT_IPSEC_INBOUND_TUNNEL_ALE_ACCEPT_V6;
+const GUID FWPM_CALLOUT_IPSEC_INBOUND_INITIATE_SECURE_V4;
+const GUID FWPM_CALLOUT_IPSEC_INBOUND_INITIATE_SECURE_V6;
 
 /* integrity config, missing in some MinGW versions */
 #ifndef IPSEC_AUTH_CONFIG_HMAC_MD5_96
diff --git a/src/libcharon/plugins/kernel_wfp/kernel_wfp_ipsec.c b/src/libcharon/plugins/kernel_wfp/kernel_wfp_ipsec.c
index c788bfb..b38ded8 100644
--- a/src/libcharon/plugins/kernel_wfp/kernel_wfp_ipsec.c
+++ b/src/libcharon/plugins/kernel_wfp/kernel_wfp_ipsec.c
@@ -26,6 +26,8 @@
 #include <collections/hashtable.h>
 #include <processing/jobs/callback_job.h>
 
+#define IPPROTO_IPIP 4
+#define IPPROTO_IPV6 41
 
 typedef struct private_kernel_wfp_ipsec_t private_kernel_wfp_ipsec_t;
 
@@ -188,6 +190,14 @@ typedef struct {
 	u_int64_t provider;
 	/** WFP allocated LUID for SA context */
 	u_int64_t sa_id;
+	/** WFP allocated LUID for tunnel mode IP-IPv4 inbound filter */
+	u_int64_t ip_ipv4_in;
+	/** WFP allocated LUID for tunnel mode IP-IPv4 outbound filter */
+	u_int64_t ip_ipv4_out;
+	/** WFP allocated LUID for tunnel mode IP-IPv6 inbound filter */
+	u_int64_t ip_ipv6_in;
+	/** WFP allocated LUID for tunnel mode IP-IPv6 outbound filter */
+	u_int64_t ip_ipv6_out;
 } entry_t;
 
 /**
@@ -285,6 +295,22 @@ static void cleanup_policies(private_kernel_wfp_ipsec_t *this, entry_t *entry)
  */
 static void entry_destroy(private_kernel_wfp_ipsec_t *this, entry_t *entry)
 {
+	if (entry->ip_ipv4_in)
+	{
+		FwpmFilterDeleteById0(this->handle, entry->ip_ipv4_in);
+	}
+	if (entry->ip_ipv4_out)
+	{
+		FwpmFilterDeleteById0(this->handle, entry->ip_ipv4_out);
+	}
+	if (entry->ip_ipv6_in)
+	{
+		FwpmFilterDeleteById0(this->handle, entry->ip_ipv6_in);
+	}
+	if (entry->ip_ipv6_out)
+	{
+		FwpmFilterDeleteById0(this->handle, entry->ip_ipv6_out);
+	}
 	if (entry->sa_id)
 	{
 		IPsecSaContextDeleteById0(this->handle, entry->sa_id);
@@ -553,49 +579,58 @@ static void free_conditions(FWPM_FILTER_CONDITION0 *conds, int count)
  * Find the callout GUID for given parameters
  */
 static bool find_callout(bool tunnel, bool v6, bool inbound, bool forward,
-						 GUID *layer, GUID *sublayer, GUID *callout)
+						 bool ale, GUID *layer, GUID *sublayer, GUID *callout)
 {
 	struct {
 		bool tunnel;
 		bool v6;
 		bool inbound;
 		bool forward;
+		bool ale;
 		const GUID *layer;
 		const GUID *sublayer;
 		const GUID *callout;
 	} map[] = {
-		{ 0, 0, 0, 0, 	&FWPM_LAYER_OUTBOUND_TRANSPORT_V4, NULL,
-						&FWPM_CALLOUT_IPSEC_OUTBOUND_TRANSPORT_V4			},
-		{ 0, 0, 1, 0,	&FWPM_LAYER_INBOUND_TRANSPORT_V4, NULL,
-						&FWPM_CALLOUT_IPSEC_INBOUND_TRANSPORT_V4			},
-		{ 0, 1, 0, 0,	&FWPM_LAYER_OUTBOUND_TRANSPORT_V6, NULL,
-						&FWPM_CALLOUT_IPSEC_OUTBOUND_TRANSPORT_V6			},
-		{ 0, 1, 1, 0,	&FWPM_LAYER_INBOUND_TRANSPORT_V6, NULL,
-						&FWPM_CALLOUT_IPSEC_INBOUND_TRANSPORT_V6			},
-		{ 1, 0, 0, 0,	&FWPM_LAYER_OUTBOUND_TRANSPORT_V4,
-						&FWPM_SUBLAYER_IPSEC_TUNNEL,
-						&FWPM_CALLOUT_IPSEC_OUTBOUND_TUNNEL_V4				},
-		{ 1, 0, 0, 1,	&FWPM_LAYER_IPFORWARD_V4,
-						&FWPM_SUBLAYER_IPSEC_FORWARD_OUTBOUND_TUNNEL,
-						&FWPM_CALLOUT_IPSEC_FORWARD_OUTBOUND_TUNNEL_V4		},
-		{ 1, 0, 1, 0,	&FWPM_LAYER_INBOUND_TRANSPORT_V4,
-						&FWPM_SUBLAYER_IPSEC_TUNNEL,
-						&FWPM_CALLOUT_IPSEC_INBOUND_TUNNEL_V4				},
-		{ 1, 0, 1, 1,	&FWPM_LAYER_IPFORWARD_V4,
-						&FWPM_SUBLAYER_IPSEC_TUNNEL,
-						&FWPM_CALLOUT_IPSEC_FORWARD_INBOUND_TUNNEL_V4		},
-		{ 1, 1, 0, 0,	&FWPM_LAYER_OUTBOUND_TRANSPORT_V6,
-						&FWPM_SUBLAYER_IPSEC_TUNNEL,
-						&FWPM_CALLOUT_IPSEC_OUTBOUND_TUNNEL_V6				},
-		{ 1, 1, 0, 1,	&FWPM_LAYER_IPFORWARD_V6,
-						&FWPM_SUBLAYER_IPSEC_TUNNEL,
-						&FWPM_CALLOUT_IPSEC_FORWARD_OUTBOUND_TUNNEL_V6		},
-		{ 1, 1, 1, 0,	&FWPM_LAYER_INBOUND_TRANSPORT_V6,
-						&FWPM_SUBLAYER_IPSEC_TUNNEL,
-						&FWPM_CALLOUT_IPSEC_INBOUND_TUNNEL_V6				},
-		{ 1, 1, 1, 1,	&FWPM_LAYER_IPFORWARD_V6,
-						&FWPM_SUBLAYER_IPSEC_TUNNEL,
-						&FWPM_CALLOUT_IPSEC_FORWARD_INBOUND_TUNNEL_V6		},
+		{ 0, 0, 0, 0, 0,	&FWPM_LAYER_OUTBOUND_TRANSPORT_V4, NULL,
+							&FWPM_CALLOUT_IPSEC_OUTBOUND_TRANSPORT_V4		},
+		{ 0, 0, 1, 0, 0,	&FWPM_LAYER_INBOUND_TRANSPORT_V4, NULL,
+							&FWPM_CALLOUT_IPSEC_INBOUND_TRANSPORT_V4		},
+		{ 0, 1, 0, 0, 0,	&FWPM_LAYER_OUTBOUND_TRANSPORT_V6, NULL,
+							&FWPM_CALLOUT_IPSEC_OUTBOUND_TRANSPORT_V6		},
+		{ 0, 1, 1, 0, 0,	&FWPM_LAYER_INBOUND_TRANSPORT_V6, NULL,
+							&FWPM_CALLOUT_IPSEC_INBOUND_TRANSPORT_V6		},
+		{ 1, 0, 0, 0, 0,	&FWPM_LAYER_OUTBOUND_TRANSPORT_V4,
+							&FWPM_SUBLAYER_IPSEC_TUNNEL,
+							&FWPM_CALLOUT_IPSEC_OUTBOUND_TUNNEL_V4			},
+		{ 1, 0, 0, 1, 0,	&FWPM_LAYER_IPFORWARD_V4,
+							&FWPM_SUBLAYER_IPSEC_FORWARD_OUTBOUND_TUNNEL,
+							&FWPM_CALLOUT_IPSEC_FORWARD_OUTBOUND_TUNNEL_V4	},
+		{ 1, 0, 1, 0, 0,	&FWPM_LAYER_INBOUND_TRANSPORT_V4,
+							&FWPM_SUBLAYER_IPSEC_TUNNEL,
+							&FWPM_CALLOUT_IPSEC_INBOUND_TUNNEL_V4			},
+		{ 1, 0, 1, 1, 0,	&FWPM_LAYER_IPFORWARD_V4,
+							&FWPM_SUBLAYER_IPSEC_TUNNEL,
+							&FWPM_CALLOUT_IPSEC_FORWARD_INBOUND_TUNNEL_V4	},
+		{ 1, 0, 0, 0, 1,	&FWPM_LAYER_ALE_AUTH_CONNECT_V4, NULL,
+							&FWPM_CALLOUT_IPSEC_ALE_CONNECT_V4				},
+		{ 1, 0, 1, 0, 1,	&FWPM_LAYER_ALE_AUTH_RECV_ACCEPT_V4, NULL,
+							&FWPM_CALLOUT_IPSEC_INBOUND_TUNNEL_ALE_ACCEPT_V4},
+		{ 1, 1, 0, 0, 0,	&FWPM_LAYER_OUTBOUND_TRANSPORT_V6,
+							&FWPM_SUBLAYER_IPSEC_TUNNEL,
+							&FWPM_CALLOUT_IPSEC_OUTBOUND_TUNNEL_V6			},
+		{ 1, 1, 0, 1, 0,	&FWPM_LAYER_IPFORWARD_V6,
+							&FWPM_SUBLAYER_IPSEC_FORWARD_OUTBOUND_TUNNEL,
+							&FWPM_CALLOUT_IPSEC_FORWARD_OUTBOUND_TUNNEL_V6	},
+		{ 1, 1, 1, 0, 0,	&FWPM_LAYER_INBOUND_TRANSPORT_V6,
+							&FWPM_SUBLAYER_IPSEC_TUNNEL,
+							&FWPM_CALLOUT_IPSEC_INBOUND_TUNNEL_V6			},
+		{ 1, 1, 1, 1, 0,	&FWPM_LAYER_IPFORWARD_V6,
+							&FWPM_SUBLAYER_IPSEC_TUNNEL,
+							&FWPM_CALLOUT_IPSEC_FORWARD_INBOUND_TUNNEL_V6	},
+		{ 1, 1, 0, 0, 1,	&FWPM_LAYER_ALE_AUTH_CONNECT_V6, NULL,
+							&FWPM_CALLOUT_IPSEC_ALE_CONNECT_V6				},
+		{ 1, 1, 1, 0, 1,	&FWPM_LAYER_ALE_AUTH_RECV_ACCEPT_V6, NULL,
+							&FWPM_CALLOUT_IPSEC_INBOUND_TUNNEL_ALE_ACCEPT_V6},
 	};
 	int i;
 
@@ -604,7 +639,8 @@ static bool find_callout(bool tunnel, bool v6, bool inbound, bool forward,
 		if (tunnel == map[i].tunnel &&
 			v6 == map[i].v6 &&
 			inbound == map[i].inbound &&
-			forward == map[i].forward)
+			forward == map[i].forward &&
+			ale == map[i].ale)
 		{
 			*callout = *map[i].callout;
 			*layer = *map[i].layer;
@@ -647,7 +683,7 @@ static bool install_sp(private_kernel_wfp_ipsec_t *this, sp_entry_t *sp,
 	}
 
 	v6 = sp->src->get_type(sp->src) == TS_IPV6_ADDR_RANGE;
-	if (!find_callout(context != NULL, v6, inbound, fwd,
+	if (!find_callout(context != NULL, v6, inbound, fwd, FALSE,
 					  &filter.layerKey, &filter.subLayerKey,
 					  &filter.action.calloutKey))
 	{
@@ -688,8 +724,73 @@ static bool install_sp(private_kernel_wfp_ipsec_t *this, sp_entry_t *sp,
 	free_conditions(conds, count);
 	if (res != ERROR_SUCCESS)
 	{
-		DBG1(DBG_KNL, "installing %s%sbound WFP filter failed: 0x%08x",
-			 fwd ? "forward " : "", inbound ? "in" : "out", res);
+		DBG1(DBG_KNL, "installing IPv%d %s%sbound %s WFP filter failed: 0x%08x",
+			 v6 ? 6 : 4, fwd ? "forward " : "", inbound ? "in" : "out",
+			 context ? "tunnel" : "transport", res);
+		return FALSE;
+	}
+	return TRUE;
+}
+
+/**
+ * Install an IP-IP allow filter for SA specific hosts
+ */
+static bool install_ipip_ale(private_kernel_wfp_ipsec_t *this,
+							 host_t *local, host_t *remote, GUID *context,
+							 bool inbound, int proto, u_int64_t *filter_id)
+{
+	traffic_selector_t *lts, *rts;
+	FWPM_FILTER_CONDITION0 *conds = NULL;
+	int count = 0;
+	bool v6;
+	DWORD res;
+	FWPM_FILTER0 filter = {
+		.displayData = {
+			.name = L"charon IPsec IP-in-IP ALE policy",
+		},
+		.action = {
+			.type = FWP_ACTION_CALLOUT_TERMINATING,
+		},
+	};
+
+	if (context)
+	{
+		filter.flags |= FWPM_FILTER_FLAG_HAS_PROVIDER_CONTEXT;
+		filter.providerKey = (GUID*)&this->provider.providerKey;
+		filter.providerContextKey = *context;
+	}
+
+	v6 = local->get_family(local) == AF_INET6;
+	if (!find_callout(TRUE, v6, inbound, FALSE, TRUE, &filter.layerKey,
+					  &filter.subLayerKey, &filter.action.calloutKey))
+	{
+		return FALSE;
+	}
+
+	lts = traffic_selector_create_from_subnet(local->clone(local),
+											v6 ? 128 : 32 , proto, 0, 65535);
+	rts = traffic_selector_create_from_subnet(remote->clone(remote),
+											v6 ? 128 : 32 , proto, 0, 65535);
+	if (!ts2condition(lts, &FWPM_CONDITION_IP_LOCAL_ADDRESS, &conds, &count) ||
+		!ts2condition(rts, &FWPM_CONDITION_IP_REMOTE_ADDRESS, &conds, &count))
+	{
+		free_conditions(conds, count);
+		lts->destroy(lts);
+		rts->destroy(rts);
+		return FALSE;
+	}
+	lts->destroy(lts);
+	rts->destroy(rts);
+
+	filter.numFilterConditions = count;
+	filter.filterCondition = conds;
+
+	res = FwpmFilterAdd0(this->handle, &filter, NULL, filter_id);
+	free_conditions(conds, count);
+	if (res != ERROR_SUCCESS)
+	{
+		DBG1(DBG_KNL, "installing IP-IPv%d %s ALE WFP filter failed: 0x%08x",
+			 v6 ? 6 : 4, inbound ? "inbound" : "outbound", res);
 		return FALSE;
 	}
 	return TRUE;
@@ -703,10 +804,21 @@ static bool install_sps(private_kernel_wfp_ipsec_t *this,
 {
 	enumerator_t *enumerator;
 	sp_entry_t *sp;
+	bool has_v4 = FALSE, has_v6 = FALSE;
 
 	enumerator = array_create_enumerator(entry->sps);
 	while (enumerator->enumerate(enumerator, &sp))
 	{
+		switch (sp->src->get_type(sp->src))
+		{
+			case TS_IPV4_ADDR_RANGE:
+				has_v4 = TRUE;
+				break;
+			case TS_IPV6_ADDR_RANGE:
+				has_v6 = TRUE;
+				break;
+		}
+
 		/* inbound policy */
 		if (!install_sp(this, sp, context, TRUE, FALSE, &sp->policy_in))
 		{
@@ -719,21 +831,22 @@ static bool install_sps(private_kernel_wfp_ipsec_t *this,
 			enumerator->destroy(enumerator);
 			return FALSE;
 		}
+
 		if (context)
 		{
 			if (!sp->src->is_host(sp->src, entry->local) ||
 				!sp->dst->is_host(sp->dst, entry->remote))
 			{
 				/* inbound forward policy, from decapsulation */
-				if (!install_sp(this, sp, context,
-								TRUE, TRUE, &sp->policy_fwd_in))
+				if (!install_sp(this, sp, context, TRUE, TRUE,
+								&sp->policy_fwd_in))
 				{
 					enumerator->destroy(enumerator);
 					return FALSE;
 				}
 				/* outbound forward policy, to encapsulate */
-				if (!install_sp(this, sp, context,
-								FALSE, TRUE, &sp->policy_fwd_out))
+				if (!install_sp(this, sp, context, FALSE, TRUE,
+								&sp->policy_fwd_out))
 				{
 					enumerator->destroy(enumerator);
 					return FALSE;
@@ -743,6 +856,38 @@ static bool install_sps(private_kernel_wfp_ipsec_t *this,
 	}
 	enumerator->destroy(enumerator);
 
+	if (context)
+	{
+		/* In tunnel mode, Windows does firewall filtering on decrypted but
+		 * non-unwrapped packets: It sees them as IP-in-IP packets. When using
+		 * a default-drop policy, we need to allow such packets explicitly. */
+		if (has_v4)
+		{
+			if (!install_ipip_ale(this, entry->local, entry->remote, context,
+								  TRUE, IPPROTO_IPIP, &entry->ip_ipv4_in))
+			{
+				return FALSE;
+			}
+			if (!install_ipip_ale(this, entry->local, entry->remote, NULL,
+								  FALSE, IPPROTO_IPIP, &entry->ip_ipv4_out))
+			{
+				return FALSE;
+			}
+		}
+		if (has_v6)
+		{
+			if (!install_ipip_ale(this, entry->local, entry->remote, context,
+								  TRUE, IPPROTO_IPV6, &entry->ip_ipv6_in))
+			{
+				return FALSE;
+			}
+			if (!install_ipip_ale(this, entry->local, entry->remote, NULL,
+								  FALSE, IPPROTO_IPV6, &entry->ip_ipv6_out))
+			{
+				return FALSE;
+			}
+		}
+	}
 	return TRUE;
 }
 
@@ -1583,8 +1728,20 @@ static void WINAPI event_callback(void *user, const FWPM_NET_EVENT1 *event)
 			acquire(this, event->classifyDrop->filterId, local, remote);
 			break;
 		case FWPM_NET_EVENT_TYPE_IKEEXT_MM_FAILURE:
+			DBG1(DBG_KNL, "WFP MM failure: %R === %R, 0x%08x, filterId %llu",
+				 local, remote, event->ikeMmFailure->failureErrorCode,
+				 event->ikeMmFailure->mmFilterId);
+			break;
 		case FWPM_NET_EVENT_TYPE_IKEEXT_QM_FAILURE:
+			DBG1(DBG_KNL, "WFP QM failure: %R === %R, 0x%08x, filterId %llu",
+				 local, remote, event->ikeQmFailure->failureErrorCode,
+				 event->ikeQmFailure->qmFilterId);
+			break;
 		case FWPM_NET_EVENT_TYPE_IKEEXT_EM_FAILURE:
+			DBG1(DBG_KNL, "WFP EM failure: %R === %R, 0x%08x, filterId %llu",
+				 local, remote, event->ikeEmFailure->failureErrorCode,
+				 event->ikeEmFailure->qmFilterId);
+			break;
 		case FWPM_NET_EVENT_TYPE_IPSEC_KERNEL_DROP:
 			DBG1(DBG_KNL, "IPsec kernel drop: %R === %R, error 0x%08x, "
 				 "SPI 0x%08x, %s filterId %llu", local, remote,
@@ -1824,7 +1981,7 @@ static u_int permute(u_int x, u_int p)
 
 METHOD(kernel_ipsec_t, get_spi, status_t,
 	private_kernel_wfp_ipsec_t *this, host_t *src, host_t *dst,
-	u_int8_t protocol, u_int32_t reqid, u_int32_t *spi)
+	u_int8_t protocol, u_int32_t *spi)
 {
 	/* To avoid sequencial SPIs, we use a one-to-one permuation function on
 	 * an incrementing counter, that is a full period PRNG for the range we
@@ -1841,7 +1998,7 @@ METHOD(kernel_ipsec_t, get_spi, status_t,
 
 METHOD(kernel_ipsec_t, get_cpi, status_t,
 	private_kernel_wfp_ipsec_t *this, host_t *src, host_t *dst,
-	u_int32_t reqid, u_int16_t *cpi)
+	u_int16_t *cpi)
 {
 	return NOT_SUPPORTED;
 }
@@ -1875,9 +2032,8 @@ static void expire_data_destroy(expire_data_t *data)
 static job_requeue_t expire_job(expire_data_t *data)
 {
 	private_kernel_wfp_ipsec_t *this = data->this;
-	u_int32_t reqid = 0;
 	u_int8_t protocol;
-	entry_t *entry;
+	entry_t *entry = NULL;
 	sa_entry_t key = {
 		.spi = data->spi,
 		.dst = data->dst,
@@ -1891,7 +2047,6 @@ static job_requeue_t expire_job(expire_data_t *data)
 		if (entry)
 		{
 			protocol = entry->isa.protocol;
-			reqid = entry->reqid;
 			if (entry->osa.dst)
 			{
 				key.dst = entry->osa.dst;
@@ -1908,15 +2063,14 @@ static job_requeue_t expire_job(expire_data_t *data)
 		if (entry)
 		{
 			protocol = entry->isa.protocol;
-			reqid = entry->reqid;
 		}
 		this->mutex->unlock(this->mutex);
 	}
 
-	if (reqid)
+	if (entry)
 	{
-		hydra->kernel_interface->expire(hydra->kernel_interface,
-										reqid, protocol, data->spi, data->hard);
+		hydra->kernel_interface->expire(hydra->kernel_interface, protocol,
+										data->spi, data->dst, data->hard);
 	}
 
 	return JOB_REQUEUE_NONE;
@@ -1949,8 +2103,8 @@ METHOD(kernel_ipsec_t, add_sa, status_t,
 	u_int32_t tfc, lifetime_cfg_t *lifetime, u_int16_t enc_alg, chunk_t enc_key,
 	u_int16_t int_alg, chunk_t int_key, ipsec_mode_t mode,
 	u_int16_t ipcomp, u_int16_t cpi, u_int32_t replay_window,
-	bool initiator, bool encap, bool esn, bool inbound,
-	traffic_selector_t *src_ts, traffic_selector_t *dst_ts)
+	bool initiator, bool encap, bool esn, bool inbound, bool update,
+	linked_list_t *src_ts, linked_list_t *dst_ts)
 {
 	host_t *local, *remote;
 	entry_t *entry;
diff --git a/src/libcharon/plugins/led/Makefile.in b/src/libcharon/plugins/led/Makefile.in
index db4552d..7942868 100644
--- a/src/libcharon/plugins/led/Makefile.in
+++ b/src/libcharon/plugins/led/Makefile.in
@@ -226,6 +226,7 @@ DLLIB = @DLLIB@
 DLLTOOL = @DLLTOOL@
 DSYMUTIL = @DSYMUTIL@
 DUMPBIN = @DUMPBIN@
+EASY_INSTALL = @EASY_INSTALL@
 ECHO_C = @ECHO_C@
 ECHO_N = @ECHO_N@
 ECHO_T = @ECHO_T@
@@ -286,10 +287,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
 PLUGIN_CFLAGS = @PLUGIN_CFLAGS@
 PTHREADLIB = @PTHREADLIB@
 PYTHON = @PYTHON@
+PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@
 PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
 PYTHON_PLATFORM = @PYTHON_PLATFORM@
 PYTHON_PREFIX = @PYTHON_PREFIX@
 PYTHON_VERSION = @PYTHON_VERSION@
+PY_TEST = @PY_TEST@
 RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
@@ -363,6 +366,8 @@ json_CFLAGS = @json_CFLAGS@
 json_LIBS = @json_LIBS@
 libdir = @libdir@
 libexecdir = @libexecdir@
+libiptc_CFLAGS = @libiptc_CFLAGS@
+libiptc_LIBS = @libiptc_LIBS@
 linux_headers = @linux_headers@
 localedir = @localedir@
 localstatedir = @localstatedir@
diff --git a/src/libcharon/plugins/load_tester/Makefile.in b/src/libcharon/plugins/load_tester/Makefile.in
index 418dccb..52dbec5 100644
--- a/src/libcharon/plugins/load_tester/Makefile.in
+++ b/src/libcharon/plugins/load_tester/Makefile.in
@@ -239,6 +239,7 @@ DLLIB = @DLLIB@
 DLLTOOL = @DLLTOOL@
 DSYMUTIL = @DSYMUTIL@
 DUMPBIN = @DUMPBIN@
+EASY_INSTALL = @EASY_INSTALL@
 ECHO_C = @ECHO_C@
 ECHO_N = @ECHO_N@
 ECHO_T = @ECHO_T@
@@ -299,10 +300,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
 PLUGIN_CFLAGS = @PLUGIN_CFLAGS@
 PTHREADLIB = @PTHREADLIB@
 PYTHON = @PYTHON@
+PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@
 PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
 PYTHON_PLATFORM = @PYTHON_PLATFORM@
 PYTHON_PREFIX = @PYTHON_PREFIX@
 PYTHON_VERSION = @PYTHON_VERSION@
+PY_TEST = @PY_TEST@
 RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
@@ -376,6 +379,8 @@ json_CFLAGS = @json_CFLAGS@
 json_LIBS = @json_LIBS@
 libdir = @libdir@
 libexecdir = @libexecdir@
+libiptc_CFLAGS = @libiptc_CFLAGS@
+libiptc_LIBS = @libiptc_LIBS@
 linux_headers = @linux_headers@
 localedir = @localedir@
 localstatedir = @localstatedir@
diff --git a/src/libcharon/plugins/load_tester/load_tester_config.c b/src/libcharon/plugins/load_tester/load_tester_config.c
index bc7c0ff..8a50063 100644
--- a/src/libcharon/plugins/load_tester/load_tester_config.c
+++ b/src/libcharon/plugins/load_tester/load_tester_config.c
@@ -394,6 +394,28 @@ static void generate_auth_cfg(private_load_tester_config_t *this, char *str,
 				}
 			}
 		}
+		else if (strpfx(str, "xauth"))
+		{	/* XAuth, use a username */
+			class = AUTH_CLASS_XAUTH;
+			if (*(str + strlen("xauth")) == '-')
+			{
+				auth->add(auth, AUTH_RULE_XAUTH_BACKEND, str + strlen("xauth-"));
+			}
+			if (!id)
+			{
+				if (local && num)
+				{
+					snprintf(buf, sizeof(buf), "cli-%.6d-%.2d", num, rnd);
+					id = identification_create_from_string(buf);
+				}
+				else
+				{
+					id = identification_create_from_encoding(ID_ANY, chunk_empty);
+				}
+			}
+			/* additionally set the ID as XAuth identity */
+			auth->add(auth, AUTH_RULE_XAUTH_IDENTITY, id->clone(id));
+		}
 		else
 		{
 			if (!streq(str, "pubkey"))
@@ -618,7 +640,7 @@ static host_t *allocate_addr(private_load_tester_config_t *this, uint num)
 	enumerator = this->pools->create_enumerator(this->pools);
 	while (enumerator->enumerate(enumerator, &pool))
 	{
-		found = pool->acquire_address(pool, id, requested, MEM_POOL_NEW);
+		found = pool->acquire_address(pool, id, requested, MEM_POOL_NEW, NULL);
 		if (found)
 		{
 			iface = (char*)pool->get_name(pool);
diff --git a/src/libcharon/plugins/load_tester/load_tester_diffie_hellman.c b/src/libcharon/plugins/load_tester/load_tester_diffie_hellman.c
index d5ec359..e1c7c0e 100644
--- a/src/libcharon/plugins/load_tester/load_tester_diffie_hellman.c
+++ b/src/libcharon/plugins/load_tester/load_tester_diffie_hellman.c
@@ -15,33 +15,38 @@
 
 #include "load_tester_diffie_hellman.h"
 
-/**
- * Implementation of gmp_diffie_hellman_t.get_my_public_value.
- */
-static void get_my_public_value(load_tester_diffie_hellman_t *this,
-								chunk_t *value)
+METHOD(diffie_hellman_t, get_my_public_value, bool,
+	load_tester_diffie_hellman_t *this, chunk_t *value)
 {
 	*value = chunk_empty;
+	return TRUE;
 }
 
-/**
- * Implementation of gmp_diffie_hellman_t.get_shared_secret.
- */
-static status_t get_shared_secret(load_tester_diffie_hellman_t *this,
-								  chunk_t *secret)
+METHOD(diffie_hellman_t, set_other_public_value, bool,
+	load_tester_diffie_hellman_t *this, chunk_t value)
+{
+	return TRUE;
+}
+
+METHOD(diffie_hellman_t, get_shared_secret, bool,
+	load_tester_diffie_hellman_t *this, chunk_t *secret)
 {
 	*secret = chunk_empty;
-	return SUCCESS;
+	return TRUE;
 }
 
-/**
- * Implementation of gmp_diffie_hellman_t.get_dh_group.
- */
-static diffie_hellman_group_t get_dh_group(load_tester_diffie_hellman_t *this)
+METHOD(diffie_hellman_t, get_dh_group, diffie_hellman_group_t,
+	load_tester_diffie_hellman_t *this)
 {
 	return MODP_NULL;
 }
 
+METHOD(diffie_hellman_t, destroy, void,
+	load_tester_diffie_hellman_t *this)
+{
+	free(this);
+}
+
 /**
  * See header
  */
@@ -55,13 +60,15 @@ load_tester_diffie_hellman_t *load_tester_diffie_hellman_create(
 		return NULL;
 	}
 
-	this = malloc_thing(load_tester_diffie_hellman_t);
-
-	this->dh.get_shared_secret = (status_t (*)(diffie_hellman_t *, chunk_t *))get_shared_secret;
-	this->dh.set_other_public_value = (void (*)(diffie_hellman_t *, chunk_t ))nop;
-	this->dh.get_my_public_value = (void (*)(diffie_hellman_t *, chunk_t *))get_my_public_value;
-	this->dh.get_dh_group = (diffie_hellman_group_t (*)(diffie_hellman_t *))get_dh_group;
-	this->dh.destroy = (void (*)(diffie_hellman_t *))free;
+	INIT(this,
+		.dh = {
+			.get_shared_secret = _get_shared_secret,
+			.set_other_public_value = _set_other_public_value,
+			.get_my_public_value = _get_my_public_value,
+			.get_dh_group = _get_dh_group,
+			.destroy = _destroy,
+		}
+	);
 
 	return this;
 }
diff --git a/src/libcharon/plugins/load_tester/load_tester_ipsec.c b/src/libcharon/plugins/load_tester/load_tester_ipsec.c
index 3f256dd..62d43e3 100644
--- a/src/libcharon/plugins/load_tester/load_tester_ipsec.c
+++ b/src/libcharon/plugins/load_tester/load_tester_ipsec.c
@@ -36,7 +36,7 @@ struct private_load_tester_ipsec_t {
 
 METHOD(kernel_ipsec_t, get_spi, status_t,
 	private_load_tester_ipsec_t *this, host_t *src, host_t *dst,
-	u_int8_t protocol, u_int32_t reqid, u_int32_t *spi)
+	u_int8_t protocol, u_int32_t *spi)
 {
 	*spi = (uint32_t)ref_get(&this->spi);
 	return SUCCESS;
@@ -44,7 +44,7 @@ METHOD(kernel_ipsec_t, get_spi, status_t,
 
 METHOD(kernel_ipsec_t, get_cpi, status_t,
 	private_load_tester_ipsec_t *this, host_t *src, host_t *dst,
-	u_int32_t reqid, u_int16_t *cpi)
+	u_int16_t *cpi)
 {
 	return FAILED;
 }
@@ -55,8 +55,8 @@ METHOD(kernel_ipsec_t, add_sa, status_t,
 	u_int32_t tfc, lifetime_cfg_t *lifetime, u_int16_t enc_alg, chunk_t enc_key,
 	u_int16_t int_alg, chunk_t int_key, ipsec_mode_t mode,
 	u_int16_t ipcomp, u_int16_t cpi, u_int32_t replay_window,
-	bool initiator, bool encap, bool esn, bool inbound,
-	traffic_selector_t *src_ts, traffic_selector_t *dst_ts)
+	bool initiator, bool encap, bool esn, bool inbound, bool update,
+	linked_list_t *src_ts, linked_list_t *dst_ts)
 {
 	return SUCCESS;
 }
diff --git a/src/libcharon/plugins/lookip/Makefile.in b/src/libcharon/plugins/lookip/Makefile.in
index f0f2c75..264c58f 100644
--- a/src/libcharon/plugins/lookip/Makefile.in
+++ b/src/libcharon/plugins/lookip/Makefile.in
@@ -235,6 +235,7 @@ DLLIB = @DLLIB@
 DLLTOOL = @DLLTOOL@
 DSYMUTIL = @DSYMUTIL@
 DUMPBIN = @DUMPBIN@
+EASY_INSTALL = @EASY_INSTALL@
 ECHO_C = @ECHO_C@
 ECHO_N = @ECHO_N@
 ECHO_T = @ECHO_T@
@@ -295,10 +296,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
 PLUGIN_CFLAGS = @PLUGIN_CFLAGS@
 PTHREADLIB = @PTHREADLIB@
 PYTHON = @PYTHON@
+PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@
 PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
 PYTHON_PLATFORM = @PYTHON_PLATFORM@
 PYTHON_PREFIX = @PYTHON_PREFIX@
 PYTHON_VERSION = @PYTHON_VERSION@
+PY_TEST = @PY_TEST@
 RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
@@ -372,6 +375,8 @@ json_CFLAGS = @json_CFLAGS@
 json_LIBS = @json_LIBS@
 libdir = @libdir@
 libexecdir = @libexecdir@
+libiptc_CFLAGS = @libiptc_CFLAGS@
+libiptc_LIBS = @libiptc_LIBS@
 linux_headers = @linux_headers@
 localedir = @localedir@
 localstatedir = @localstatedir@
diff --git a/src/libcharon/plugins/maemo/Makefile.in b/src/libcharon/plugins/maemo/Makefile.in
index 3a866e9..76c9012 100644
--- a/src/libcharon/plugins/maemo/Makefile.in
+++ b/src/libcharon/plugins/maemo/Makefile.in
@@ -231,6 +231,7 @@ DLLIB = @DLLIB@
 DLLTOOL = @DLLTOOL@
 DSYMUTIL = @DSYMUTIL@
 DUMPBIN = @DUMPBIN@
+EASY_INSTALL = @EASY_INSTALL@
 ECHO_C = @ECHO_C@
 ECHO_N = @ECHO_N@
 ECHO_T = @ECHO_T@
@@ -291,10 +292,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
 PLUGIN_CFLAGS = @PLUGIN_CFLAGS@
 PTHREADLIB = @PTHREADLIB@
 PYTHON = @PYTHON@
+PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@
 PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
 PYTHON_PLATFORM = @PYTHON_PLATFORM@
 PYTHON_PREFIX = @PYTHON_PREFIX@
 PYTHON_VERSION = @PYTHON_VERSION@
+PY_TEST = @PY_TEST@
 RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
@@ -368,6 +371,8 @@ json_CFLAGS = @json_CFLAGS@
 json_LIBS = @json_LIBS@
 libdir = @libdir@
 libexecdir = @libexecdir@
+libiptc_CFLAGS = @libiptc_CFLAGS@
+libiptc_LIBS = @libiptc_LIBS@
 linux_headers = @linux_headers@
 localedir = @localedir@
 localstatedir = @localstatedir@
diff --git a/src/libcharon/plugins/medcli/Makefile.in b/src/libcharon/plugins/medcli/Makefile.in
index e0f70ce..35740c3 100644
--- a/src/libcharon/plugins/medcli/Makefile.in
+++ b/src/libcharon/plugins/medcli/Makefile.in
@@ -229,6 +229,7 @@ DLLIB = @DLLIB@
 DLLTOOL = @DLLTOOL@
 DSYMUTIL = @DSYMUTIL@
 DUMPBIN = @DUMPBIN@
+EASY_INSTALL = @EASY_INSTALL@
 ECHO_C = @ECHO_C@
 ECHO_N = @ECHO_N@
 ECHO_T = @ECHO_T@
@@ -289,10 +290,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
 PLUGIN_CFLAGS = @PLUGIN_CFLAGS@
 PTHREADLIB = @PTHREADLIB@
 PYTHON = @PYTHON@
+PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@
 PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
 PYTHON_PLATFORM = @PYTHON_PLATFORM@
 PYTHON_PREFIX = @PYTHON_PREFIX@
 PYTHON_VERSION = @PYTHON_VERSION@
+PY_TEST = @PY_TEST@
 RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
@@ -366,6 +369,8 @@ json_CFLAGS = @json_CFLAGS@
 json_LIBS = @json_LIBS@
 libdir = @libdir@
 libexecdir = @libexecdir@
+libiptc_CFLAGS = @libiptc_CFLAGS@
+libiptc_LIBS = @libiptc_LIBS@
 linux_headers = @linux_headers@
 localedir = @localedir@
 localstatedir = @localstatedir@
diff --git a/src/libcharon/plugins/medsrv/Makefile.in b/src/libcharon/plugins/medsrv/Makefile.in
index adb61e8..8fe160e 100644
--- a/src/libcharon/plugins/medsrv/Makefile.in
+++ b/src/libcharon/plugins/medsrv/Makefile.in
@@ -229,6 +229,7 @@ DLLIB = @DLLIB@
 DLLTOOL = @DLLTOOL@
 DSYMUTIL = @DSYMUTIL@
 DUMPBIN = @DUMPBIN@
+EASY_INSTALL = @EASY_INSTALL@
 ECHO_C = @ECHO_C@
 ECHO_N = @ECHO_N@
 ECHO_T = @ECHO_T@
@@ -289,10 +290,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
 PLUGIN_CFLAGS = @PLUGIN_CFLAGS@
 PTHREADLIB = @PTHREADLIB@
 PYTHON = @PYTHON@
+PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@
 PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
 PYTHON_PLATFORM = @PYTHON_PLATFORM@
 PYTHON_PREFIX = @PYTHON_PREFIX@
 PYTHON_VERSION = @PYTHON_VERSION@
+PY_TEST = @PY_TEST@
 RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
@@ -366,6 +369,8 @@ json_CFLAGS = @json_CFLAGS@
 json_LIBS = @json_LIBS@
 libdir = @libdir@
 libexecdir = @libexecdir@
+libiptc_CFLAGS = @libiptc_CFLAGS@
+libiptc_LIBS = @libiptc_LIBS@
 linux_headers = @linux_headers@
 localedir = @localedir@
 localstatedir = @localstatedir@
diff --git a/src/libcharon/plugins/osx_attr/Makefile.in b/src/libcharon/plugins/osx_attr/Makefile.in
index a0c21c4..9a5e438 100644
--- a/src/libcharon/plugins/osx_attr/Makefile.in
+++ b/src/libcharon/plugins/osx_attr/Makefile.in
@@ -229,6 +229,7 @@ DLLIB = @DLLIB@
 DLLTOOL = @DLLTOOL@
 DSYMUTIL = @DSYMUTIL@
 DUMPBIN = @DUMPBIN@
+EASY_INSTALL = @EASY_INSTALL@
 ECHO_C = @ECHO_C@
 ECHO_N = @ECHO_N@
 ECHO_T = @ECHO_T@
@@ -289,10 +290,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
 PLUGIN_CFLAGS = @PLUGIN_CFLAGS@
 PTHREADLIB = @PTHREADLIB@
 PYTHON = @PYTHON@
+PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@
 PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
 PYTHON_PLATFORM = @PYTHON_PLATFORM@
 PYTHON_PREFIX = @PYTHON_PREFIX@
 PYTHON_VERSION = @PYTHON_VERSION@
+PY_TEST = @PY_TEST@
 RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
@@ -366,6 +369,8 @@ json_CFLAGS = @json_CFLAGS@
 json_LIBS = @json_LIBS@
 libdir = @libdir@
 libexecdir = @libexecdir@
+libiptc_CFLAGS = @libiptc_CFLAGS@
+libiptc_LIBS = @libiptc_LIBS@
 linux_headers = @linux_headers@
 localedir = @localedir@
 localstatedir = @localstatedir@
diff --git a/src/libcharon/plugins/osx_attr/osx_attr_handler.c b/src/libcharon/plugins/osx_attr/osx_attr_handler.c
index 9a3b270..d974b57 100644
--- a/src/libcharon/plugins/osx_attr/osx_attr_handler.c
+++ b/src/libcharon/plugins/osx_attr/osx_attr_handler.c
@@ -169,7 +169,7 @@ static bool manage_dns(int family, chunk_t data, bool add)
 }
 
 METHOD(attribute_handler_t, handle, bool,
-	private_osx_attr_handler_t *this, identification_t *id,
+	private_osx_attr_handler_t *this, ike_sa_t *ike_sa,
 	configuration_attribute_type_t type, chunk_t data)
 {
 	switch (type)
@@ -182,7 +182,7 @@ METHOD(attribute_handler_t, handle, bool,
 }
 
 METHOD(attribute_handler_t, release, void,
-	private_osx_attr_handler_t *this, identification_t *server,
+	private_osx_attr_handler_t *this, ike_sa_t *ike_sa,
 	configuration_attribute_type_t type, chunk_t data)
 {
 	switch (type)
@@ -206,7 +206,7 @@ METHOD(enumerator_t, enumerate_dns, bool,
 }
 
 METHOD(attribute_handler_t, create_attribute_enumerator, enumerator_t *,
-	private_osx_attr_handler_t *this, identification_t *id,
+	private_osx_attr_handler_t *this, ike_sa_t *ike_sa,
 	linked_list_t *vips)
 {
 	enumerator_t *enumerator;
diff --git a/src/libcharon/plugins/osx_attr/osx_attr_plugin.c b/src/libcharon/plugins/osx_attr/osx_attr_plugin.c
index 380483c..4be9eda 100644
--- a/src/libcharon/plugins/osx_attr/osx_attr_plugin.c
+++ b/src/libcharon/plugins/osx_attr/osx_attr_plugin.c
@@ -16,7 +16,6 @@
 #include "osx_attr_plugin.h"
 #include "osx_attr_handler.h"
 
-#include <hydra.h>
 #include <daemon.h>
 
 typedef struct private_osx_attr_plugin_t private_osx_attr_plugin_t;
@@ -51,13 +50,13 @@ static bool plugin_cb(private_osx_attr_plugin_t *this,
 {
 	if (reg)
 	{
-		hydra->attributes->add_handler(hydra->attributes,
-									   &this->handler->handler);
+		charon->attributes->add_handler(charon->attributes,
+										&this->handler->handler);
 	}
 	else
 	{
-		hydra->attributes->remove_handler(hydra->attributes,
-										  &this->handler->handler);
+		charon->attributes->remove_handler(charon->attributes,
+										   &this->handler->handler);
 	}
 	return TRUE;
 }
diff --git a/src/libcharon/plugins/radattr/Makefile.in b/src/libcharon/plugins/radattr/Makefile.in
index 14abba9..baff3fc 100644
--- a/src/libcharon/plugins/radattr/Makefile.in
+++ b/src/libcharon/plugins/radattr/Makefile.in
@@ -230,6 +230,7 @@ DLLIB = @DLLIB@
 DLLTOOL = @DLLTOOL@
 DSYMUTIL = @DSYMUTIL@
 DUMPBIN = @DUMPBIN@
+EASY_INSTALL = @EASY_INSTALL@
 ECHO_C = @ECHO_C@
 ECHO_N = @ECHO_N@
 ECHO_T = @ECHO_T@
@@ -290,10 +291,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
 PLUGIN_CFLAGS = @PLUGIN_CFLAGS@
 PTHREADLIB = @PTHREADLIB@
 PYTHON = @PYTHON@
+PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@
 PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
 PYTHON_PLATFORM = @PYTHON_PLATFORM@
 PYTHON_PREFIX = @PYTHON_PREFIX@
 PYTHON_VERSION = @PYTHON_VERSION@
+PY_TEST = @PY_TEST@
 RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
@@ -367,6 +370,8 @@ json_CFLAGS = @json_CFLAGS@
 json_LIBS = @json_LIBS@
 libdir = @libdir@
 libexecdir = @libexecdir@
+libiptc_CFLAGS = @libiptc_CFLAGS@
+libiptc_LIBS = @libiptc_LIBS@
 linux_headers = @linux_headers@
 localedir = @localedir@
 localstatedir = @localstatedir@
diff --git a/src/libcharon/plugins/resolve/Makefile.am b/src/libcharon/plugins/resolve/Makefile.am
new file mode 100644
index 0000000..9cfc370
--- /dev/null
+++ b/src/libcharon/plugins/resolve/Makefile.am
@@ -0,0 +1,20 @@
+AM_CPPFLAGS = \
+	-I$(top_srcdir)/src/libstrongswan \
+	-I$(top_srcdir)/src/libhydra \
+	-I$(top_srcdir)/src/libcharon \
+	-DRESOLV_CONF=\"${resolv_conf}\"
+
+AM_CFLAGS = \
+	$(PLUGIN_CFLAGS)
+
+if MONOLITHIC
+noinst_LTLIBRARIES = libstrongswan-resolve.la
+else
+plugin_LTLIBRARIES = libstrongswan-resolve.la
+endif
+
+libstrongswan_resolve_la_SOURCES = \
+	resolve_plugin.h resolve_plugin.c \
+	resolve_handler.h resolve_handler.c
+
+libstrongswan_resolve_la_LDFLAGS = -module -avoid-version
diff --git a/src/libcharon/plugins/resolve/Makefile.in b/src/libcharon/plugins/resolve/Makefile.in
new file mode 100644
index 0000000..91479bf
--- /dev/null
+++ b/src/libcharon/plugins/resolve/Makefile.in
@@ -0,0 +1,781 @@
+# Makefile.in generated by automake 1.14.1 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994-2013 Free Software Foundation, Inc.
+
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+ at SET_MAKE@
+
+VPATH = @srcdir@
+am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)'
+am__make_running_with_option = \
+  case $${target_option-} in \
+      ?) ;; \
+      *) echo "am__make_running_with_option: internal error: invalid" \
+              "target option '$${target_option-}' specified" >&2; \
+         exit 1;; \
+  esac; \
+  has_opt=no; \
+  sane_makeflags=$$MAKEFLAGS; \
+  if $(am__is_gnu_make); then \
+    sane_makeflags=$$MFLAGS; \
+  else \
+    case $$MAKEFLAGS in \
+      *\\[\ \	]*) \
+        bs=\\; \
+        sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
+          | sed "s/$$bs$$bs[$$bs $$bs	]*//g"`;; \
+    esac; \
+  fi; \
+  skip_next=no; \
+  strip_trailopt () \
+  { \
+    flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
+  }; \
+  for flg in $$sane_makeflags; do \
+    test $$skip_next = yes && { skip_next=no; continue; }; \
+    case $$flg in \
+      *=*|--*) continue;; \
+        -*I) strip_trailopt 'I'; skip_next=yes;; \
+      -*I?*) strip_trailopt 'I';; \
+        -*O) strip_trailopt 'O'; skip_next=yes;; \
+      -*O?*) strip_trailopt 'O';; \
+        -*l) strip_trailopt 'l'; skip_next=yes;; \
+      -*l?*) strip_trailopt 'l';; \
+      -[dEDm]) skip_next=yes;; \
+      -[JT]) skip_next=yes;; \
+    esac; \
+    case $$flg in \
+      *$$target_option*) has_opt=yes; break;; \
+    esac; \
+  done; \
+  test $$has_opt = yes
+am__make_dryrun = (target_option=n; $(am__make_running_with_option))
+am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+subdir = src/libcharon/plugins/resolve
+DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
+	$(top_srcdir)/depcomp
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/m4/config/libtool.m4 \
+	$(top_srcdir)/m4/config/ltoptions.m4 \
+	$(top_srcdir)/m4/config/ltsugar.m4 \
+	$(top_srcdir)/m4/config/ltversion.m4 \
+	$(top_srcdir)/m4/config/lt~obsolete.m4 \
+	$(top_srcdir)/m4/macros/split-package-version.m4 \
+	$(top_srcdir)/m4/macros/with.m4 \
+	$(top_srcdir)/m4/macros/enable-disable.m4 \
+	$(top_srcdir)/m4/macros/add-plugin.m4 \
+	$(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+	$(ACLOCAL_M4)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
+am__vpath_adj = case $$p in \
+    $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
+    *) f=$$p;; \
+  esac;
+am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
+am__install_max = 40
+am__nobase_strip_setup = \
+  srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
+am__nobase_strip = \
+  for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
+am__nobase_list = $(am__nobase_strip_setup); \
+  for p in $$list; do echo "$$p $$p"; done | \
+  sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
+  $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
+    if (++n[$$2] == $(am__install_max)) \
+      { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
+    END { for (dir in files) print dir, files[dir] }'
+am__base_list = \
+  sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
+  sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
+am__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; }; \
+  }
+am__installdirs = "$(DESTDIR)$(plugindir)"
+LTLIBRARIES = $(noinst_LTLIBRARIES) $(plugin_LTLIBRARIES)
+libstrongswan_resolve_la_LIBADD =
+am_libstrongswan_resolve_la_OBJECTS = resolve_plugin.lo \
+	resolve_handler.lo
+libstrongswan_resolve_la_OBJECTS =  \
+	$(am_libstrongswan_resolve_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_resolve_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \
+	$(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \
+	$(AM_CFLAGS) $(CFLAGS) $(libstrongswan_resolve_la_LDFLAGS) \
+	$(LDFLAGS) -o $@
+ at MONOLITHIC_FALSE@am_libstrongswan_resolve_la_rpath = -rpath \
+ at MONOLITHIC_FALSE@	$(plugindir)
+ at MONOLITHIC_TRUE@am_libstrongswan_resolve_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
+am__v_P_1 = :
+AM_V_GEN = $(am__v_GEN_ at AM_V@)
+am__v_GEN_ = $(am__v_GEN_ at AM_DEFAULT_V@)
+am__v_GEN_0 = @echo "  GEN     " $@;
+am__v_GEN_1 = 
+AM_V_at = $(am__v_at_ at AM_V@)
+am__v_at_ = $(am__v_at_ at AM_DEFAULT_V@)
+am__v_at_0 = @
+am__v_at_1 = 
+DEFAULT_INCLUDES = -I. at am__isrc@ -I$(top_builddir)
+depcomp = $(SHELL) $(top_srcdir)/depcomp
+am__depfiles_maybe = depfiles
+am__mv = mv -f
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+	$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+	$(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \
+	$(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
+	$(AM_CFLAGS) $(CFLAGS)
+AM_V_CC = $(am__v_CC_ at AM_V@)
+am__v_CC_ = $(am__v_CC_ at AM_DEFAULT_V@)
+am__v_CC_0 = @echo "  CC      " $@;
+am__v_CC_1 = 
+CCLD = $(CC)
+LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+	$(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+	$(AM_LDFLAGS) $(LDFLAGS) -o $@
+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_resolve_la_SOURCES)
+DIST_SOURCES = $(libstrongswan_resolve_la_SOURCES)
+am__can_run_installinfo = \
+  case $$AM_UPDATE_INFO_DIR in \
+    n|no|NO) false;; \
+    *) (install-info --version) >/dev/null 2>&1;; \
+  esac
+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
+# *not* preserved.
+am__uniquify_input = $(AWK) '\
+  BEGIN { nonempty = 0; } \
+  { items[$$0] = 1; nonempty = 1; } \
+  END { if (nonempty) { for (i in items) print i; }; } \
+'
+# Make sure the list of sources is unique.  This is necessary because,
+# e.g., the same source file might be shared among _SOURCES variables
+# for different programs/libraries.
+am__define_uniq_tagged_files = \
+  list='$(am__tagged_files)'; \
+  unique=`for i in $$list; do \
+    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+  done | $(am__uniquify_input)`
+ETAGS = etags
+CTAGS = ctags
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+ALLOCA = @ALLOCA@
+AMTAR = @AMTAR@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+BFDLIB = @BFDLIB@
+BTLIB = @BTLIB@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+COVERAGE_CFLAGS = @COVERAGE_CFLAGS@
+COVERAGE_LDFLAGS = @COVERAGE_LDFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DLLIB = @DLLIB@
+DLLTOOL = @DLLTOOL@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+EASY_INSTALL = @EASY_INSTALL@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+FGREP = @FGREP@
+GEM = @GEM@
+GENHTML = @GENHTML@
+GPERF = @GPERF@
+GPRBUILD = @GPRBUILD@
+GREP = @GREP@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+LCOV = @LCOV@
+LD = @LD@
+LDFLAGS = @LDFLAGS@
+LEX = @LEX@
+LEXLIB = @LEXLIB@
+LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LIPO = @LIPO@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+MAKEINFO = @MAKEINFO@
+MANIFEST_TOOL = @MANIFEST_TOOL@
+MKDIR_P = @MKDIR_P@
+MYSQLCFLAG = @MYSQLCFLAG@
+MYSQLCONFIG = @MYSQLCONFIG@
+MYSQLLIB = @MYSQLLIB@
+NM = @NM@
+NMEDIT = @NMEDIT@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OPENSSL_LIB = @OPENSSL_LIB@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PACKAGE_VERSION_BUILD = @PACKAGE_VERSION_BUILD@
+PACKAGE_VERSION_MAJOR = @PACKAGE_VERSION_MAJOR@
+PACKAGE_VERSION_MINOR = @PACKAGE_VERSION_MINOR@
+PACKAGE_VERSION_REVIEW = @PACKAGE_VERSION_REVIEW@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PERL = @PERL@
+PKG_CONFIG = @PKG_CONFIG@
+PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
+PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
+PLUGIN_CFLAGS = @PLUGIN_CFLAGS@
+PTHREADLIB = @PTHREADLIB@
+PYTHON = @PYTHON@
+PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@
+PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
+PYTHON_PLATFORM = @PYTHON_PLATFORM@
+PYTHON_PREFIX = @PYTHON_PREFIX@
+PYTHON_VERSION = @PYTHON_VERSION@
+PY_TEST = @PY_TEST@
+RANLIB = @RANLIB@
+RTLIB = @RTLIB@
+RUBY = @RUBY@
+RUBYGEMDIR = @RUBYGEMDIR@
+RUBYINCLUDE = @RUBYINCLUDE@
+RUBYLIB = @RUBYLIB@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+SOCKLIB = @SOCKLIB@
+STRIP = @STRIP@
+UNWINDLIB = @UNWINDLIB@
+VERSION = @VERSION@
+YACC = @YACC@
+YFLAGS = @YFLAGS@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+aikgen_plugins = @aikgen_plugins@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+attest_plugins = @attest_plugins@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+c_plugins = @c_plugins@
+charon_natt_port = @charon_natt_port@
+charon_plugins = @charon_plugins@
+charon_udp_port = @charon_udp_port@
+clearsilver_LIBS = @clearsilver_LIBS@
+cmd_plugins = @cmd_plugins@
+datadir = @datadir@
+datarootdir = @datarootdir@
+dbusservicedir = @dbusservicedir@
+dev_headers = @dev_headers@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+fips_mode = @fips_mode@
+gtk_CFLAGS = @gtk_CFLAGS@
+gtk_LIBS = @gtk_LIBS@
+h_plugins = @h_plugins@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+imcvdir = @imcvdir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+ipsec_script = @ipsec_script@
+ipsec_script_upper = @ipsec_script_upper@
+ipsecdir = @ipsecdir@
+ipsecgroup = @ipsecgroup@
+ipseclibdir = @ipseclibdir@
+ipsecuser = @ipsecuser@
+json_CFLAGS = @json_CFLAGS@
+json_LIBS = @json_LIBS@
+libdir = @libdir@
+libexecdir = @libexecdir@
+libiptc_CFLAGS = @libiptc_CFLAGS@
+libiptc_LIBS = @libiptc_LIBS@
+linux_headers = @linux_headers@
+localedir = @localedir@
+localstatedir = @localstatedir@
+maemo_CFLAGS = @maemo_CFLAGS@
+maemo_LIBS = @maemo_LIBS@
+manager_plugins = @manager_plugins@
+mandir = @mandir@
+medsrv_plugins = @medsrv_plugins@
+mkdir_p = @mkdir_p@
+nm_CFLAGS = @nm_CFLAGS@
+nm_LIBS = @nm_LIBS@
+nm_ca_dir = @nm_ca_dir@
+nm_plugins = @nm_plugins@
+oldincludedir = @oldincludedir@
+pcsclite_CFLAGS = @pcsclite_CFLAGS@
+pcsclite_LIBS = @pcsclite_LIBS@
+pdfdir = @pdfdir@
+piddir = @piddir@
+pkgpyexecdir = @pkgpyexecdir@
+pkgpythondir = @pkgpythondir@
+pki_plugins = @pki_plugins@
+plugindir = @plugindir@
+pool_plugins = @pool_plugins@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+pyexecdir = @pyexecdir@
+pythondir = @pythondir@
+random_device = @random_device@
+resolv_conf = @resolv_conf@
+routing_table = @routing_table@
+routing_table_prio = @routing_table_prio@
+s_plugins = @s_plugins@
+sbindir = @sbindir@
+scepclient_plugins = @scepclient_plugins@
+scripts_plugins = @scripts_plugins@
+sharedstatedir = @sharedstatedir@
+soup_CFLAGS = @soup_CFLAGS@
+soup_LIBS = @soup_LIBS@
+srcdir = @srcdir@
+starter_plugins = @starter_plugins@
+strongswan_conf = @strongswan_conf@
+strongswan_options = @strongswan_options@
+swanctldir = @swanctldir@
+sysconfdir = @sysconfdir@
+systemd_daemon_CFLAGS = @systemd_daemon_CFLAGS@
+systemd_daemon_LIBS = @systemd_daemon_LIBS@
+systemd_journal_CFLAGS = @systemd_journal_CFLAGS@
+systemd_journal_LIBS = @systemd_journal_LIBS@
+systemdsystemunitdir = @systemdsystemunitdir@
+t_plugins = @t_plugins@
+target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+urandom_device = @urandom_device@
+xml_CFLAGS = @xml_CFLAGS@
+xml_LIBS = @xml_LIBS@
+AM_CPPFLAGS = \
+	-I$(top_srcdir)/src/libstrongswan \
+	-I$(top_srcdir)/src/libhydra \
+	-I$(top_srcdir)/src/libcharon \
+	-DRESOLV_CONF=\"${resolv_conf}\"
+
+AM_CFLAGS = \
+	$(PLUGIN_CFLAGS)
+
+ at MONOLITHIC_TRUE@noinst_LTLIBRARIES = libstrongswan-resolve.la
+ at MONOLITHIC_FALSE@plugin_LTLIBRARIES = libstrongswan-resolve.la
+libstrongswan_resolve_la_SOURCES = \
+	resolve_plugin.h resolve_plugin.c \
+	resolve_handler.h resolve_handler.c
+
+libstrongswan_resolve_la_LDFLAGS = -module -avoid-version
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .c .lo .o .obj
+$(srcdir)/Makefile.in:  $(srcdir)/Makefile.am  $(am__configure_deps)
+	@for dep in $?; do \
+	  case '$(am__configure_deps)' in \
+	    *$$dep*) \
+	      ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+	        && { if test -f $@; then exit 0; else break; fi; }; \
+	      exit 1;; \
+	  esac; \
+	done; \
+	echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/libcharon/plugins/resolve/Makefile'; \
+	$(am__cd) $(top_srcdir) && \
+	  $(AUTOMAKE) --gnu src/libcharon/plugins/resolve/Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+	@case '$?' in \
+	  *config.status*) \
+	    cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+	  *) \
+	    echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+	    cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+	esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure:  $(am__configure_deps)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4):  $(am__aclocal_m4_deps)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+
+clean-noinstLTLIBRARIES:
+	-test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES)
+	@list='$(noinst_LTLIBRARIES)'; \
+	locs=`for p in $$list; do echo $$p; done | \
+	      sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \
+	      sort -u`; \
+	test -z "$$locs" || { \
+	  echo rm -f $${locs}; \
+	  rm -f $${locs}; \
+	}
+
+install-pluginLTLIBRARIES: $(plugin_LTLIBRARIES)
+	@$(NORMAL_INSTALL)
+	@list='$(plugin_LTLIBRARIES)'; test -n "$(plugindir)" || list=; \
+	list2=; for p in $$list; do \
+	  if test -f $$p; then \
+	    list2="$$list2 $$p"; \
+	  else :; fi; \
+	done; \
+	test -z "$$list2" || { \
+	  echo " $(MKDIR_P) '$(DESTDIR)$(plugindir)'"; \
+	  $(MKDIR_P) "$(DESTDIR)$(plugindir)" || exit 1; \
+	  echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(plugindir)'"; \
+	  $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(plugindir)"; \
+	}
+
+uninstall-pluginLTLIBRARIES:
+	@$(NORMAL_UNINSTALL)
+	@list='$(plugin_LTLIBRARIES)'; test -n "$(plugindir)" || list=; \
+	for p in $$list; do \
+	  $(am__strip_dir) \
+	  echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(plugindir)/$$f'"; \
+	  $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(plugindir)/$$f"; \
+	done
+
+clean-pluginLTLIBRARIES:
+	-test -z "$(plugin_LTLIBRARIES)" || rm -f $(plugin_LTLIBRARIES)
+	@list='$(plugin_LTLIBRARIES)'; \
+	locs=`for p in $$list; do echo $$p; done | \
+	      sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \
+	      sort -u`; \
+	test -z "$$locs" || { \
+	  echo rm -f $${locs}; \
+	  rm -f $${locs}; \
+	}
+
+libstrongswan-resolve.la: $(libstrongswan_resolve_la_OBJECTS) $(libstrongswan_resolve_la_DEPENDENCIES) $(EXTRA_libstrongswan_resolve_la_DEPENDENCIES) 
+	$(AM_V_CCLD)$(libstrongswan_resolve_la_LINK) $(am_libstrongswan_resolve_la_rpath) $(libstrongswan_resolve_la_OBJECTS) $(libstrongswan_resolve_la_LIBADD) $(LIBS)
+
+mostlyclean-compile:
+	-rm -f *.$(OBJEXT)
+
+distclean-compile:
+	-rm -f *.tab.c
+
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/resolve_handler.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/resolve_plugin.Plo at am__quote@
+
+.c.o:
+ at am__fastdepCC_TRUE@	$(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\
+ at am__fastdepCC_TRUE@	$(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\
+ at am__fastdepCC_TRUE@	$(am__mv) $$depbase.Tpo $$depbase.Po
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(COMPILE) -c -o $@ $<
+
+.c.obj:
+ at am__fastdepCC_TRUE@	$(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\
+ at am__fastdepCC_TRUE@	$(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\
+ at am__fastdepCC_TRUE@	$(am__mv) $$depbase.Tpo $$depbase.Po
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
+
+.c.lo:
+ at am__fastdepCC_TRUE@	$(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\
+ at am__fastdepCC_TRUE@	$(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\
+ at am__fastdepCC_TRUE@	$(am__mv) $$depbase.Tpo $$depbase.Plo
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(LTCOMPILE) -c -o $@ $<
+
+mostlyclean-libtool:
+	-rm -f *.lo
+
+clean-libtool:
+	-rm -rf .libs _libs
+
+ID: $(am__tagged_files)
+	$(am__define_uniq_tagged_files); mkid -fID $$unique
+tags: tags-am
+TAGS: tags
+
+tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+	set x; \
+	here=`pwd`; \
+	$(am__define_uniq_tagged_files); \
+	shift; \
+	if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
+	  test -n "$$unique" || unique=$$empty_fix; \
+	  if test $$# -gt 0; then \
+	    $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+	      "$$@" $$unique; \
+	  else \
+	    $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+	      $$unique; \
+	  fi; \
+	fi
+ctags: ctags-am
+
+CTAGS: ctags
+ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+	$(am__define_uniq_tagged_files); \
+	test -z "$(CTAGS_ARGS)$$unique" \
+	  || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+	     $$unique
+
+GTAGS:
+	here=`$(am__cd) $(top_builddir) && pwd` \
+	  && $(am__cd) $(top_srcdir) \
+	  && gtags -i $(GTAGS_ARGS) "$$here"
+cscopelist: cscopelist-am
+
+cscopelist-am: $(am__tagged_files)
+	list='$(am__tagged_files)'; \
+	case "$(srcdir)" in \
+	  [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
+	  *) sdir=$(subdir)/$(srcdir) ;; \
+	esac; \
+	for i in $$list; do \
+	  if test -f "$$i"; then \
+	    echo "$(subdir)/$$i"; \
+	  else \
+	    echo "$$sdir/$$i"; \
+	  fi; \
+	done >> $(top_builddir)/cscope.files
+
+distclean-tags:
+	-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+distdir: $(DISTFILES)
+	@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+	topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+	list='$(DISTFILES)'; \
+	  dist_files=`for file in $$list; do echo $$file; done | \
+	  sed -e "s|^$$srcdirstrip/||;t" \
+	      -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+	case $$dist_files in \
+	  */*) $(MKDIR_P) `echo "$$dist_files" | \
+			   sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+			   sort -u` ;; \
+	esac; \
+	for file in $$dist_files; do \
+	  if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+	  if test -d $$d/$$file; then \
+	    dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+	    if test -d "$(distdir)/$$file"; then \
+	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+	    fi; \
+	    if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+	      cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+	    fi; \
+	    cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+	  else \
+	    test -f "$(distdir)/$$file" \
+	    || cp -p $$d/$$file "$(distdir)/$$file" \
+	    || exit 1; \
+	  fi; \
+	done
+check-am: all-am
+check: check-am
+all-am: Makefile $(LTLIBRARIES)
+installdirs:
+	for dir in "$(DESTDIR)$(plugindir)"; do \
+	  test -z "$$dir" || $(MKDIR_P) "$$dir"; \
+	done
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+	@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+	if test -z '$(STRIP)'; then \
+	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	      install; \
+	else \
+	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	    "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+	fi
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+	-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+	-test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+
+maintainer-clean-generic:
+	@echo "This command is intended for maintainers to use"
+	@echo "it deletes files that may require special tools to rebuild."
+clean: clean-am
+
+clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \
+	clean-pluginLTLIBRARIES mostlyclean-am
+
+distclean: distclean-am
+	-rm -rf ./$(DEPDIR)
+	-rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+	distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+html-am:
+
+info: info-am
+
+info-am:
+
+install-data-am: install-pluginLTLIBRARIES
+
+install-dvi: install-dvi-am
+
+install-dvi-am:
+
+install-exec-am:
+
+install-html: install-html-am
+
+install-html-am:
+
+install-info: install-info-am
+
+install-info-am:
+
+install-man:
+
+install-pdf: install-pdf-am
+
+install-pdf-am:
+
+install-ps: install-ps-am
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+	-rm -rf ./$(DEPDIR)
+	-rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic \
+	mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am: uninstall-pluginLTLIBRARIES
+
+.MAKE: install-am install-strip
+
+.PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \
+	clean-libtool clean-noinstLTLIBRARIES clean-pluginLTLIBRARIES \
+	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-man install-pdf \
+	install-pdf-am install-pluginLTLIBRARIES install-ps \
+	install-ps-am install-strip installcheck installcheck-am \
+	installdirs maintainer-clean maintainer-clean-generic \
+	mostlyclean mostlyclean-compile mostlyclean-generic \
+	mostlyclean-libtool pdf pdf-am ps ps-am tags tags-am uninstall \
+	uninstall-am uninstall-pluginLTLIBRARIES
+
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/src/libcharon/plugins/resolve/resolve_handler.c b/src/libcharon/plugins/resolve/resolve_handler.c
new file mode 100644
index 0000000..74c3960
--- /dev/null
+++ b/src/libcharon/plugins/resolve/resolve_handler.c
@@ -0,0 +1,380 @@
+/*
+ * Copyright (C) 2012 Tobias Brunner
+ * Copyright (C) 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.
+ */
+
+#include "resolve_handler.h"
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+
+#include <hydra.h>
+#include <utils/debug.h>
+#include <threading/mutex.h>
+
+/* path to resolvconf executable */
+#define RESOLVCONF_EXEC "/sbin/resolvconf"
+
+/* default prefix used for resolvconf interfaces (should have high prio) */
+#define RESOLVCONF_PREFIX "lo.inet.ipsec."
+
+typedef struct private_resolve_handler_t private_resolve_handler_t;
+
+/**
+ * Private data of an resolve_handler_t object.
+ */
+struct private_resolve_handler_t {
+
+	/**
+	 * Public resolve_handler_t interface.
+	 */
+	resolve_handler_t public;
+
+	/**
+	 * resolv.conf file to use
+	 */
+	char *file;
+
+	/**
+	 * use resolvconf instead of writing directly to resolv.conf
+	 */
+	bool use_resolvconf;
+
+	/**
+	 * prefix to be used for interface names sent to resolvconf
+	 */
+	char *iface_prefix;
+
+	/**
+	 * Mutex to access file exclusively
+	 */
+	mutex_t *mutex;
+};
+
+/**
+ * Writes the given nameserver to resolv.conf
+ */
+static bool write_nameserver(private_resolve_handler_t *this,
+							 identification_t *server, host_t *addr)
+{
+	FILE *in, *out;
+	char buf[1024];
+	size_t len;
+	bool handled = FALSE;
+
+	in = fopen(this->file, "r");
+	/* allows us to stream from in to out */
+	unlink(this->file);
+	out = fopen(this->file, "w");
+	if (out)
+	{
+		fprintf(out, "nameserver %H   # by strongSwan, from %Y\n", addr,
+				server);
+		DBG1(DBG_IKE, "installing DNS server %H to %s", addr, this->file);
+		handled = TRUE;
+
+		/* copy rest of the file */
+		if (in)
+		{
+			while ((len = fread(buf, 1, sizeof(buf), in)))
+			{
+				ignore_result(fwrite(buf, 1, len, out));
+			}
+		}
+		fclose(out);
+	}
+	if (in)
+	{
+		fclose(in);
+	}
+	return handled;
+}
+
+/**
+ * Removes the given nameserver from resolv.conf
+ */
+static void remove_nameserver(private_resolve_handler_t *this,
+							  identification_t *server, host_t *addr)
+{
+	FILE *in, *out;
+	char line[1024], matcher[512];
+
+	in = fopen(this->file, "r");
+	if (in)
+	{
+		/* allows us to stream from in to out */
+		unlink(this->file);
+		out = fopen(this->file, "w");
+		if (out)
+		{
+			snprintf(matcher, sizeof(matcher),
+					 "nameserver %H   # by strongSwan, from %Y\n",
+					 addr, server);
+
+			/* copy all, but matching line */
+			while (fgets(line, sizeof(line), in))
+			{
+				if (strpfx(line, matcher))
+				{
+					DBG1(DBG_IKE, "removing DNS server %H from %s",
+						 addr, this->file);
+				}
+				else
+				{
+					fputs(line, out);
+				}
+			}
+			fclose(out);
+		}
+		fclose(in);
+	}
+}
+
+/**
+ * Add or remove the given nameserver by invoking resolvconf.
+ */
+static bool invoke_resolvconf(private_resolve_handler_t *this,
+							  identification_t *server, host_t *addr,
+							  bool install)
+{
+	char cmd[128];
+	bool success = TRUE;
+
+	/* we use the nameserver's IP address as part of the interface name to
+	 * make them unique */
+	if (snprintf(cmd, sizeof(cmd), "%s %s %s%H", RESOLVCONF_EXEC,
+				install ? "-a" : "-d", this->iface_prefix, addr) >= sizeof(cmd))
+	{
+		return FALSE;
+	}
+
+	if (install)
+	{
+		FILE *out;
+
+		out = popen(cmd, "w");
+		if (!out)
+		{
+			return FALSE;
+		}
+		DBG1(DBG_IKE, "installing DNS server %H via resolvconf", addr);
+		fprintf(out, "nameserver %H\n", addr);
+		success = !ferror(out);
+		if (pclose(out))
+		{
+			return FALSE;
+		}
+	}
+	else
+	{
+		ignore_result(system(cmd));
+	}
+	return success;
+}
+
+METHOD(attribute_handler_t, handle, bool,
+	private_resolve_handler_t *this, ike_sa_t *ike_sa,
+	configuration_attribute_type_t type, chunk_t data)
+{
+	identification_t *server;
+	host_t *addr;
+	bool handled;
+
+	switch (type)
+	{
+		case INTERNAL_IP4_DNS:
+			addr = host_create_from_chunk(AF_INET, data, 0);
+			break;
+		case INTERNAL_IP6_DNS:
+			addr = host_create_from_chunk(AF_INET6, data, 0);
+			break;
+		default:
+			return FALSE;
+	}
+
+	if (!addr || addr->is_anyaddr(addr))
+	{
+		DESTROY_IF(addr);
+		return FALSE;
+	}
+	server = ike_sa->get_other_id(ike_sa);
+
+	this->mutex->lock(this->mutex);
+	if (this->use_resolvconf)
+	{
+		handled = invoke_resolvconf(this, server, addr, TRUE);
+	}
+	else
+	{
+		handled = write_nameserver(this, server, addr);
+	}
+	this->mutex->unlock(this->mutex);
+	addr->destroy(addr);
+
+	if (!handled)
+	{
+		DBG1(DBG_IKE, "adding DNS server failed");
+	}
+	return handled;
+}
+
+METHOD(attribute_handler_t, release, void,
+	private_resolve_handler_t *this, ike_sa_t *ike_sa,
+	configuration_attribute_type_t type, chunk_t data)
+{
+	identification_t *server;
+	host_t *addr;
+	int family;
+
+	switch (type)
+	{
+		case INTERNAL_IP4_DNS:
+			family = AF_INET;
+			break;
+		case INTERNAL_IP6_DNS:
+			family = AF_INET6;
+			break;
+		default:
+			return;
+	}
+	addr = host_create_from_chunk(family, data, 0);
+	server = ike_sa->get_other_id(ike_sa);
+
+	this->mutex->lock(this->mutex);
+	if (this->use_resolvconf)
+	{
+		invoke_resolvconf(this, server, addr, FALSE);
+	}
+	else
+	{
+		remove_nameserver(this, server, addr);
+	}
+	this->mutex->unlock(this->mutex);
+
+	addr->destroy(addr);
+}
+
+/**
+ * Attribute enumerator implementation
+ */
+typedef struct {
+	/** implements enumerator_t interface */
+	enumerator_t public;
+	/** request IPv4 DNS? */
+	bool v4;
+	/** request IPv6 DNS? */
+	bool v6;
+} attribute_enumerator_t;
+
+static bool attribute_enumerate(attribute_enumerator_t *this,
+								configuration_attribute_type_t *type,
+								chunk_t *data)
+{
+	if (this->v4)
+	{
+		*type = INTERNAL_IP4_DNS;
+		*data = chunk_empty;
+		this->v4 = FALSE;
+		return TRUE;
+	}
+	if (this->v6)
+	{
+		*type = INTERNAL_IP6_DNS;
+		*data = chunk_empty;
+		this->v6 = FALSE;
+		return TRUE;
+	}
+	return FALSE;
+}
+
+/**
+ * Check if a list has a host of given family
+ */
+static bool has_host_family(linked_list_t *list, int family)
+{
+	enumerator_t *enumerator;
+	host_t *host;
+	bool found = FALSE;
+
+	enumerator = list->create_enumerator(list);
+	while (enumerator->enumerate(enumerator, &host))
+	{
+		if (host->get_family(host) == family)
+		{
+			found = TRUE;
+			break;
+		}
+	}
+	enumerator->destroy(enumerator);
+
+	return found;
+}
+
+METHOD(attribute_handler_t, create_attribute_enumerator, enumerator_t*,
+	private_resolve_handler_t *this, ike_sa_t *ike_sa,
+	linked_list_t *vips)
+{
+	attribute_enumerator_t *enumerator;
+
+	INIT(enumerator,
+		.public = {
+			.enumerate = (void*)attribute_enumerate,
+			.destroy = (void*)free,
+		},
+		.v4 = has_host_family(vips, AF_INET),
+		.v6 = has_host_family(vips, AF_INET6),
+	);
+	return &enumerator->public;
+}
+
+METHOD(resolve_handler_t, destroy, void,
+	private_resolve_handler_t *this)
+{
+	this->mutex->destroy(this->mutex);
+	free(this);
+}
+
+/**
+ * See header
+ */
+resolve_handler_t *resolve_handler_create()
+{
+	private_resolve_handler_t *this;
+	struct stat st;
+
+	INIT(this,
+		.public = {
+			.handler = {
+				.handle = _handle,
+				.release = _release,
+				.create_attribute_enumerator = _create_attribute_enumerator,
+			},
+			.destroy = _destroy,
+		},
+		.mutex = mutex_create(MUTEX_TYPE_DEFAULT),
+		.file = lib->settings->get_str(lib->settings, "%s.plugins.resolve.file",
+									   RESOLV_CONF, lib->ns),
+	);
+
+	if (stat(RESOLVCONF_EXEC, &st) == 0)
+	{
+		this->use_resolvconf = TRUE;
+		this->iface_prefix = lib->settings->get_str(lib->settings,
+								"%s.plugins.resolve.resolvconf.iface_prefix",
+								RESOLVCONF_PREFIX, lib->ns);
+	}
+
+	return &this->public;
+}
diff --git a/src/libhydra/plugins/resolve/resolve_handler.h b/src/libcharon/plugins/resolve/resolve_handler.h
similarity index 100%
rename from src/libhydra/plugins/resolve/resolve_handler.h
rename to src/libcharon/plugins/resolve/resolve_handler.h
diff --git a/src/libcharon/plugins/resolve/resolve_plugin.c b/src/libcharon/plugins/resolve/resolve_plugin.c
new file mode 100644
index 0000000..193c5b6
--- /dev/null
+++ b/src/libcharon/plugins/resolve/resolve_plugin.c
@@ -0,0 +1,101 @@
+/*
+ * Copyright (C) 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.
+ */
+
+#include "resolve_plugin.h"
+#include "resolve_handler.h"
+
+#include <daemon.h>
+
+typedef struct private_resolve_plugin_t private_resolve_plugin_t;
+
+/**
+ * private data of resolve plugin
+ */
+struct private_resolve_plugin_t {
+
+	/**
+	 * implements plugin interface
+	 */
+	resolve_plugin_t public;
+
+	/**
+	 * The registered DNS attribute handler
+	 */
+	resolve_handler_t *handler;
+};
+
+METHOD(plugin_t, get_name, char*,
+	private_resolve_plugin_t *this)
+{
+	return "resolve";
+}
+
+/**
+ * Register handler
+ */
+static bool plugin_cb(private_resolve_plugin_t *this,
+					  plugin_feature_t *feature, bool reg, void *cb_data)
+{
+	if (reg)
+	{
+		charon->attributes->add_handler(charon->attributes,
+										&this->handler->handler);
+	}
+	else
+	{
+		charon->attributes->remove_handler(charon->attributes,
+										   &this->handler->handler);
+	}
+	return TRUE;
+}
+
+METHOD(plugin_t, get_features, int,
+	private_resolve_plugin_t *this, plugin_feature_t *features[])
+{
+	static plugin_feature_t f[] = {
+		PLUGIN_CALLBACK((plugin_feature_callback_t)plugin_cb, NULL),
+			PLUGIN_PROVIDE(CUSTOM, "resolve"),
+	};
+	*features = f;
+	return countof(f);
+}
+
+METHOD(plugin_t, destroy, void,
+	private_resolve_plugin_t *this)
+{
+	this->handler->destroy(this->handler);
+	free(this);
+}
+
+/*
+ * see header file
+ */
+plugin_t *resolve_plugin_create()
+{
+	private_resolve_plugin_t *this;
+
+	INIT(this,
+		.public = {
+			.plugin = {
+				.get_name = _get_name,
+				.get_features = _get_features,
+				.destroy = _destroy,
+			},
+		},
+		.handler = resolve_handler_create(),
+	);
+
+	return &this->public.plugin;
+}
diff --git a/src/libhydra/plugins/resolve/resolve_plugin.h b/src/libcharon/plugins/resolve/resolve_plugin.h
similarity index 100%
rename from src/libhydra/plugins/resolve/resolve_plugin.h
rename to src/libcharon/plugins/resolve/resolve_plugin.h
diff --git a/src/libcharon/plugins/smp/Makefile.in b/src/libcharon/plugins/smp/Makefile.in
index 7c5b030..572e7fc 100644
--- a/src/libcharon/plugins/smp/Makefile.in
+++ b/src/libcharon/plugins/smp/Makefile.in
@@ -227,6 +227,7 @@ DLLIB = @DLLIB@
 DLLTOOL = @DLLTOOL@
 DSYMUTIL = @DSYMUTIL@
 DUMPBIN = @DUMPBIN@
+EASY_INSTALL = @EASY_INSTALL@
 ECHO_C = @ECHO_C@
 ECHO_N = @ECHO_N@
 ECHO_T = @ECHO_T@
@@ -287,10 +288,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
 PLUGIN_CFLAGS = @PLUGIN_CFLAGS@
 PTHREADLIB = @PTHREADLIB@
 PYTHON = @PYTHON@
+PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@
 PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
 PYTHON_PLATFORM = @PYTHON_PLATFORM@
 PYTHON_PREFIX = @PYTHON_PREFIX@
 PYTHON_VERSION = @PYTHON_VERSION@
+PY_TEST = @PY_TEST@
 RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
@@ -364,6 +367,8 @@ json_CFLAGS = @json_CFLAGS@
 json_LIBS = @json_LIBS@
 libdir = @libdir@
 libexecdir = @libexecdir@
+libiptc_CFLAGS = @libiptc_CFLAGS@
+libiptc_LIBS = @libiptc_LIBS@
 linux_headers = @linux_headers@
 localedir = @localedir@
 localstatedir = @localstatedir@
diff --git a/src/libcharon/plugins/socket_default/Makefile.in b/src/libcharon/plugins/socket_default/Makefile.in
index 548524a..25b4099 100644
--- a/src/libcharon/plugins/socket_default/Makefile.in
+++ b/src/libcharon/plugins/socket_default/Makefile.in
@@ -229,6 +229,7 @@ DLLIB = @DLLIB@
 DLLTOOL = @DLLTOOL@
 DSYMUTIL = @DSYMUTIL@
 DUMPBIN = @DUMPBIN@
+EASY_INSTALL = @EASY_INSTALL@
 ECHO_C = @ECHO_C@
 ECHO_N = @ECHO_N@
 ECHO_T = @ECHO_T@
@@ -289,10 +290,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
 PLUGIN_CFLAGS = @PLUGIN_CFLAGS@
 PTHREADLIB = @PTHREADLIB@
 PYTHON = @PYTHON@
+PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@
 PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
 PYTHON_PLATFORM = @PYTHON_PLATFORM@
 PYTHON_PREFIX = @PYTHON_PREFIX@
 PYTHON_VERSION = @PYTHON_VERSION@
+PY_TEST = @PY_TEST@
 RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
@@ -366,6 +369,8 @@ json_CFLAGS = @json_CFLAGS@
 json_LIBS = @json_LIBS@
 libdir = @libdir@
 libexecdir = @libexecdir@
+libiptc_CFLAGS = @libiptc_CFLAGS@
+libiptc_LIBS = @libiptc_LIBS@
 linux_headers = @linux_headers@
 localedir = @localedir@
 localstatedir = @localstatedir@
diff --git a/src/libcharon/plugins/socket_default/socket_default_socket.c b/src/libcharon/plugins/socket_default/socket_default_socket.c
index 9cc3995..dbfddbb 100644
--- a/src/libcharon/plugins/socket_default/socket_default_socket.c
+++ b/src/libcharon/plugins/socket_default/socket_default_socket.c
@@ -141,6 +141,11 @@ struct private_socket_default_socket_t {
 	 * TRUE if the source address should be set on outbound packets
 	 */
 	bool set_source;
+
+	/**
+	 * A counter to implement round-robin selection of read sockets
+	 */
+	u_int rr_counter;
 };
 
 METHOD(socket_t, receiver, status_t,
@@ -150,66 +155,43 @@ METHOD(socket_t, receiver, status_t,
 	chunk_t data;
 	packet_t *pkt;
 	host_t *source = NULL, *dest = NULL;
-	int bytes_read = 0;
+	int i, rr, index, bytes_read = 0, selected = -1;
 	bool oldstate;
-
-	fd_set rfds;
-	int max_fd = 0, selected = 0;
 	u_int16_t port = 0;
-
-	FD_ZERO(&rfds);
-
-	if (this->ipv4 != -1)
-	{
-		FD_SET(this->ipv4, &rfds);
-		max_fd = max(max_fd, this->ipv4);
-	}
-	if (this->ipv4_natt != -1)
-	{
-		FD_SET(this->ipv4_natt, &rfds);
-		max_fd = max(max_fd, this->ipv4_natt);
-	}
-	if (this->ipv6 != -1)
-	{
-		FD_SET(this->ipv6, &rfds);
-		max_fd = max(max_fd, this->ipv6);
-	}
-	if (this->ipv6_natt != -1)
-	{
-		FD_SET(this->ipv6_natt, &rfds);
-		max_fd = max(max_fd, this->ipv6_natt);
-	}
+	struct pollfd pfd[] = {
+		{ .fd = this->ipv4,			.events = POLLIN },
+		{ .fd = this->ipv4_natt,	.events = POLLIN },
+		{ .fd = this->ipv6,			.events = POLLIN },
+		{ .fd = this->ipv6_natt,	.events = POLLIN },
+	};
+	int ports[] = {
+		/* port numbers associated to pollfds */
+		this->port, this->natt, this->port, this->natt,
+	};
 
 	DBG2(DBG_NET, "waiting for data on sockets");
 	oldstate = thread_cancelability(TRUE);
-	if (select(max_fd + 1, &rfds, NULL, NULL, NULL) <= 0)
+	if (poll(pfd, countof(pfd), -1) <= 0)
 	{
 		thread_cancelability(oldstate);
 		return FAILED;
 	}
 	thread_cancelability(oldstate);
 
-	if (this->ipv4 != -1 && FD_ISSET(this->ipv4, &rfds))
+	rr = this->rr_counter++;
+	for (i = 0; i < countof(pfd); i++)
 	{
-		port = this->port;
-		selected = this->ipv4;
-	}
-	if (this->ipv4_natt != -1 && FD_ISSET(this->ipv4_natt, &rfds))
-	{
-		port = this->natt;
-		selected = this->ipv4_natt;
-	}
-	if (this->ipv6 != -1 && FD_ISSET(this->ipv6, &rfds))
-	{
-		port = this->port;
-		selected = this->ipv6;
-	}
-	if (this->ipv6_natt != -1 && FD_ISSET(this->ipv6_natt, &rfds))
-	{
-		port = this->natt;
-		selected = this->ipv6_natt;
+		/* To serve all ports with equal priority, we use a round-robin
+		 * scheme to choose the one to process in this invocation */
+		index = (rr + i) % countof(pfd);
+		if (pfd[index].revents & POLLIN)
+		{
+			selected = pfd[index].fd;
+			port = ports[index];
+			break;
+		}
 	}
-	if (selected)
+	if (selected != -1)
 	{
 		struct msghdr msg;
 		struct cmsghdr *cmsgptr;
diff --git a/src/libcharon/plugins/socket_dynamic/Makefile.in b/src/libcharon/plugins/socket_dynamic/Makefile.in
index 892549c..5c010a5 100644
--- a/src/libcharon/plugins/socket_dynamic/Makefile.in
+++ b/src/libcharon/plugins/socket_dynamic/Makefile.in
@@ -229,6 +229,7 @@ DLLIB = @DLLIB@
 DLLTOOL = @DLLTOOL@
 DSYMUTIL = @DSYMUTIL@
 DUMPBIN = @DUMPBIN@
+EASY_INSTALL = @EASY_INSTALL@
 ECHO_C = @ECHO_C@
 ECHO_N = @ECHO_N@
 ECHO_T = @ECHO_T@
@@ -289,10 +290,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
 PLUGIN_CFLAGS = @PLUGIN_CFLAGS@
 PTHREADLIB = @PTHREADLIB@
 PYTHON = @PYTHON@
+PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@
 PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
 PYTHON_PLATFORM = @PYTHON_PLATFORM@
 PYTHON_PREFIX = @PYTHON_PREFIX@
 PYTHON_VERSION = @PYTHON_VERSION@
+PY_TEST = @PY_TEST@
 RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
@@ -366,6 +369,8 @@ json_CFLAGS = @json_CFLAGS@
 json_LIBS = @json_LIBS@
 libdir = @libdir@
 libexecdir = @libexecdir@
+libiptc_CFLAGS = @libiptc_CFLAGS@
+libiptc_LIBS = @libiptc_LIBS@
 linux_headers = @linux_headers@
 localedir = @localedir@
 localstatedir = @localstatedir@
diff --git a/src/libcharon/plugins/socket_win/Makefile.in b/src/libcharon/plugins/socket_win/Makefile.in
index 88b2ac3..0c3bf31 100644
--- a/src/libcharon/plugins/socket_win/Makefile.in
+++ b/src/libcharon/plugins/socket_win/Makefile.in
@@ -229,6 +229,7 @@ DLLIB = @DLLIB@
 DLLTOOL = @DLLTOOL@
 DSYMUTIL = @DSYMUTIL@
 DUMPBIN = @DUMPBIN@
+EASY_INSTALL = @EASY_INSTALL@
 ECHO_C = @ECHO_C@
 ECHO_N = @ECHO_N@
 ECHO_T = @ECHO_T@
@@ -289,10 +290,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
 PLUGIN_CFLAGS = @PLUGIN_CFLAGS@
 PTHREADLIB = @PTHREADLIB@
 PYTHON = @PYTHON@
+PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@
 PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
 PYTHON_PLATFORM = @PYTHON_PLATFORM@
 PYTHON_PREFIX = @PYTHON_PREFIX@
 PYTHON_VERSION = @PYTHON_VERSION@
+PY_TEST = @PY_TEST@
 RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
@@ -366,6 +369,8 @@ json_CFLAGS = @json_CFLAGS@
 json_LIBS = @json_LIBS@
 libdir = @libdir@
 libexecdir = @libexecdir@
+libiptc_CFLAGS = @libiptc_CFLAGS@
+libiptc_LIBS = @libiptc_LIBS@
 linux_headers = @linux_headers@
 localedir = @localedir@
 localstatedir = @localstatedir@
diff --git a/src/libcharon/plugins/sql/Makefile.in b/src/libcharon/plugins/sql/Makefile.in
index 3c13245..f74257a 100644
--- a/src/libcharon/plugins/sql/Makefile.in
+++ b/src/libcharon/plugins/sql/Makefile.in
@@ -227,6 +227,7 @@ DLLIB = @DLLIB@
 DLLTOOL = @DLLTOOL@
 DSYMUTIL = @DSYMUTIL@
 DUMPBIN = @DUMPBIN@
+EASY_INSTALL = @EASY_INSTALL@
 ECHO_C = @ECHO_C@
 ECHO_N = @ECHO_N@
 ECHO_T = @ECHO_T@
@@ -287,10 +288,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
 PLUGIN_CFLAGS = @PLUGIN_CFLAGS@
 PTHREADLIB = @PTHREADLIB@
 PYTHON = @PYTHON@
+PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@
 PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
 PYTHON_PLATFORM = @PYTHON_PLATFORM@
 PYTHON_PREFIX = @PYTHON_PREFIX@
 PYTHON_VERSION = @PYTHON_VERSION@
+PY_TEST = @PY_TEST@
 RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
@@ -364,6 +367,8 @@ json_CFLAGS = @json_CFLAGS@
 json_LIBS = @json_LIBS@
 libdir = @libdir@
 libexecdir = @libexecdir@
+libiptc_CFLAGS = @libiptc_CFLAGS@
+libiptc_LIBS = @libiptc_LIBS@
 linux_headers = @linux_headers@
 localedir = @localedir@
 localstatedir = @localstatedir@
diff --git a/src/libcharon/plugins/stroke/Makefile.in b/src/libcharon/plugins/stroke/Makefile.in
index d468018..a316f5c 100644
--- a/src/libcharon/plugins/stroke/Makefile.in
+++ b/src/libcharon/plugins/stroke/Makefile.in
@@ -231,6 +231,7 @@ DLLIB = @DLLIB@
 DLLTOOL = @DLLTOOL@
 DSYMUTIL = @DSYMUTIL@
 DUMPBIN = @DUMPBIN@
+EASY_INSTALL = @EASY_INSTALL@
 ECHO_C = @ECHO_C@
 ECHO_N = @ECHO_N@
 ECHO_T = @ECHO_T@
@@ -291,10 +292,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
 PLUGIN_CFLAGS = @PLUGIN_CFLAGS@
 PTHREADLIB = @PTHREADLIB@
 PYTHON = @PYTHON@
+PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@
 PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
 PYTHON_PLATFORM = @PYTHON_PLATFORM@
 PYTHON_PREFIX = @PYTHON_PREFIX@
 PYTHON_VERSION = @PYTHON_VERSION@
+PY_TEST = @PY_TEST@
 RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
@@ -368,6 +371,8 @@ json_CFLAGS = @json_CFLAGS@
 json_LIBS = @json_LIBS@
 libdir = @libdir@
 libexecdir = @libexecdir@
+libiptc_CFLAGS = @libiptc_CFLAGS@
+libiptc_LIBS = @libiptc_LIBS@
 linux_headers = @linux_headers@
 localedir = @localedir@
 localstatedir = @localstatedir@
diff --git a/src/libcharon/plugins/stroke/stroke_attribute.c b/src/libcharon/plugins/stroke/stroke_attribute.c
index 0f3c389..cd1b4d0 100644
--- a/src/libcharon/plugins/stroke/stroke_attribute.c
+++ b/src/libcharon/plugins/stroke/stroke_attribute.c
@@ -94,7 +94,7 @@ static mem_pool_t *find_pool(private_stroke_attribute_t *this, char *name)
  */
 static host_t *find_addr(private_stroke_attribute_t *this, linked_list_t *pools,
 						 identification_t *id, host_t *requested,
-						 mem_pool_op_t operation)
+						 mem_pool_op_t operation, host_t *peer)
 {
 	host_t *addr = NULL;
 	enumerator_t *enumerator;
@@ -107,7 +107,7 @@ static host_t *find_addr(private_stroke_attribute_t *this, linked_list_t *pools,
 		pool = find_pool(this, name);
 		if (pool)
 		{
-			addr = pool->acquire_address(pool, id, requested, operation);
+			addr = pool->acquire_address(pool, id, requested, operation, peer);
 			if (addr)
 			{
 				break;
@@ -120,20 +120,24 @@ static host_t *find_addr(private_stroke_attribute_t *this, linked_list_t *pools,
 }
 
 METHOD(attribute_provider_t, acquire_address, host_t*,
-	private_stroke_attribute_t *this, linked_list_t *pools, identification_t *id,
+	private_stroke_attribute_t *this, linked_list_t *pools, ike_sa_t *ike_sa,
 	host_t *requested)
 {
-	host_t *addr;
+	identification_t *id;
+	host_t *addr, *peer;
+
+	id = ike_sa->get_other_eap_id(ike_sa);
+	peer = ike_sa->get_other_host(ike_sa);
 
 	this->lock->read_lock(this->lock);
 
-	addr = find_addr(this, pools, id, requested, MEM_POOL_EXISTING);
+	addr = find_addr(this, pools, id, requested, MEM_POOL_EXISTING, peer);
 	if (!addr)
 	{
-		addr = find_addr(this, pools, id, requested, MEM_POOL_NEW);
+		addr = find_addr(this, pools, id, requested, MEM_POOL_NEW, peer);
 		if (!addr)
 		{
-			addr = find_addr(this, pools, id, requested, MEM_POOL_REASSIGN);
+			addr = find_addr(this, pools, id, requested, MEM_POOL_REASSIGN, peer);
 		}
 	}
 
@@ -144,13 +148,16 @@ METHOD(attribute_provider_t, acquire_address, host_t*,
 
 METHOD(attribute_provider_t, release_address, bool,
 	private_stroke_attribute_t *this, linked_list_t *pools, host_t *address,
-	identification_t *id)
+	ike_sa_t *ike_sa)
 {
 	enumerator_t *enumerator;
+	identification_t *id;
 	mem_pool_t *pool;
 	bool found = FALSE;
 	char *name;
 
+	id = ike_sa->get_other_eap_id(ike_sa);
+
 	enumerator = pools->create_enumerator(pools);
 	this->lock->read_lock(this->lock);
 	while (enumerator->enumerate(enumerator, &name))
@@ -197,9 +204,8 @@ static bool attr_filter(void *lock, host_t **in,
 
 METHOD(attribute_provider_t, create_attribute_enumerator, enumerator_t*,
 	private_stroke_attribute_t *this, linked_list_t *pools,
-	identification_t *id, linked_list_t *vips)
+	ike_sa_t *ike_sa, linked_list_t *vips)
 {
-	ike_sa_t *ike_sa;
 	peer_cfg_t *peer_cfg;
 	enumerator_t *enumerator;
 	attributes_t *attr;
@@ -413,4 +419,3 @@ stroke_attribute_t *stroke_attribute_create()
 
 	return &this->public;
 }
-
diff --git a/src/libcharon/plugins/stroke/stroke_ca.c b/src/libcharon/plugins/stroke/stroke_ca.c
index f802687..b470b81 100644
--- a/src/libcharon/plugins/stroke/stroke_ca.c
+++ b/src/libcharon/plugins/stroke/stroke_ca.c
@@ -120,6 +120,84 @@ static void ca_section_destroy(ca_section_t *this)
 }
 
 /**
+ * Data for the certificate enumerator
+ */
+typedef struct {
+	private_stroke_ca_t *this;
+	certificate_type_t cert;
+	key_type_t key;
+	identification_t *id;
+} cert_data_t;
+
+/**
+ * destroy cert_data
+ */
+static void cert_data_destroy(cert_data_t *data)
+{
+	data->this->lock->unlock(data->this->lock);
+	free(data);
+}
+
+/**
+ * filter function for certs enumerator
+ */
+static bool certs_filter(cert_data_t *data, ca_section_t **in,
+						 certificate_t **out)
+{
+	public_key_t *public;
+	certificate_t *cert = (*in)->cert;
+
+	if (data->cert == CERT_ANY || data->cert == cert->get_type(cert))
+	{
+		public = cert->get_public_key(cert);
+		if (public)
+		{
+			if (data->key == KEY_ANY || data->key == public->get_type(public))
+			{
+				if (data->id && public->has_fingerprint(public,
+											data->id->get_encoding(data->id)))
+				{
+					public->destroy(public);
+					*out = cert;
+					return TRUE;
+				}
+			}
+			public->destroy(public);
+		}
+		else if (data->key != KEY_ANY)
+		{
+			return FALSE;
+		}
+		if (data->id == NULL || cert->has_subject(cert, data->id))
+		{
+			*out = cert;
+			return TRUE;
+		}
+	}
+	return FALSE;
+}
+
+METHOD(credential_set_t, create_cert_enumerator, enumerator_t*,
+	private_stroke_ca_t *this, certificate_type_t cert, key_type_t key,
+	identification_t *id, bool trusted)
+{
+	enumerator_t *enumerator;
+	cert_data_t *data;
+
+	INIT(data,
+		.this = this,
+		.cert = cert,
+		.key = key,
+		.id = id,
+	);
+
+	this->lock->read_lock(this->lock);
+	enumerator = this->sections->create_enumerator(this->sections);
+	return enumerator_create_filter(enumerator, (void*)certs_filter, data,
+									(void*)cert_data_destroy);
+}
+
+/**
  * data to pass to create_inner_cdp
  */
 typedef struct {
@@ -438,7 +516,7 @@ stroke_ca_t *stroke_ca_create(stroke_cred_t *cred)
 		.public = {
 			.set = {
 				.create_private_enumerator = (void*)return_null,
-				.create_cert_enumerator = (void*)return_null,
+				.create_cert_enumerator = _create_cert_enumerator,
 				.create_shared_enumerator = (void*)return_null,
 				.create_cdp_enumerator = _create_cdp_enumerator,
 				.cache_cert = (void*)nop,
@@ -456,4 +534,3 @@ stroke_ca_t *stroke_ca_create(stroke_cred_t *cred)
 
 	return &this->public;
 }
-
diff --git a/src/libcharon/plugins/stroke/stroke_config.c b/src/libcharon/plugins/stroke/stroke_config.c
index 62967b0..55ec7cd 100644
--- a/src/libcharon/plugins/stroke/stroke_config.c
+++ b/src/libcharon/plugins/stroke/stroke_config.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2012 Tobias Brunner
+ * Copyright (C) 2012-2014 Tobias Brunner
  * Copyright (C) 2008 Martin Willi
  * Hochschule fuer Technik Rapperswil
  *
@@ -301,7 +301,8 @@ static void build_crl_policy(auth_cfg_t *cfg, bool local, int policy)
 static void parse_pubkey_constraints(char *auth, auth_cfg_t *cfg)
 {
 	enumerator_t *enumerator;
-	bool rsa = FALSE, ecdsa = FALSE, rsa_len = FALSE, ecdsa_len = FALSE;
+	bool rsa = FALSE, ecdsa = FALSE, bliss = FALSE,
+		 rsa_len = FALSE, ecdsa_len = FALSE, bliss_strength = FALSE;
 	int strength;
 	char *token;
 
@@ -328,9 +329,12 @@ static void parse_pubkey_constraints(char *auth, auth_cfg_t *cfg)
 			{ "sha256",		SIGN_ECDSA_256,					KEY_ECDSA,	},
 			{ "sha384",		SIGN_ECDSA_384,					KEY_ECDSA,	},
 			{ "sha512",		SIGN_ECDSA_521,					KEY_ECDSA,	},
+			{ "sha256",		SIGN_BLISS_WITH_SHA256,			KEY_BLISS,	},
+			{ "sha384",		SIGN_BLISS_WITH_SHA384,			KEY_BLISS,	},
+			{ "sha512",		SIGN_BLISS_WITH_SHA512,			KEY_BLISS,	},
 		};
 
-		if (rsa_len || ecdsa_len)
+		if (rsa_len || ecdsa_len || bliss_strength)
 		{	/* expecting a key strength token */
 			strength = atoi(token);
 			if (strength)
@@ -343,8 +347,12 @@ static void parse_pubkey_constraints(char *auth, auth_cfg_t *cfg)
 				{
 					cfg->add(cfg, AUTH_RULE_ECDSA_STRENGTH, (uintptr_t)strength);
 				}
+				else if (bliss_strength)
+				{
+					cfg->add(cfg, AUTH_RULE_BLISS_STRENGTH, (uintptr_t)strength);
+				}
 			}
-			rsa_len = ecdsa_len = FALSE;
+			rsa_len = ecdsa_len = bliss_strength = FALSE;
 			if (strength)
 			{
 				continue;
@@ -360,6 +368,11 @@ static void parse_pubkey_constraints(char *auth, auth_cfg_t *cfg)
 			ecdsa = ecdsa_len = TRUE;
 			continue;
 		}
+		if (streq(token, "bliss"))
+		{
+			bliss = bliss_strength = TRUE;
+			continue;
+		}
 		if (streq(token, "pubkey"))
 		{
 			continue;
@@ -376,7 +389,8 @@ static void parse_pubkey_constraints(char *auth, auth_cfg_t *cfg)
 				 */
 				if ((rsa && schemes[i].key == KEY_RSA) ||
 					(ecdsa && schemes[i].key == KEY_ECDSA) ||
-					(!rsa && !ecdsa))
+					(bliss && schemes[i].key == KEY_BLISS) ||
+					(!rsa && !ecdsa && !bliss))
 				{
 					cfg->add(cfg, AUTH_RULE_SIGNATURE_SCHEME,
 							 (uintptr_t)schemes[i].scheme);
@@ -590,7 +604,8 @@ static auth_cfg_t *build_auth_cfg(private_stroke_config_t *this,
 	/* authentication metod (class, actually) */
 	if (strpfx(auth, "pubkey") ||
 		strpfx(auth, "rsa") ||
-		strpfx(auth, "ecdsa"))
+		strpfx(auth, "ecdsa") ||
+		strpfx(auth, "bliss"))
 	{
 		cfg->add(cfg, AUTH_RULE_AUTH_CLASS, AUTH_CLASS_PUBKEY);
 		build_crl_policy(cfg, local, msg->add_conn.crl_policy);
@@ -620,9 +635,16 @@ static auth_cfg_t *build_auth_cfg(private_stroke_config_t *this,
 	else if (strpfx(auth, "eap"))
 	{
 		eap_vendor_type_t *type;
+		char *pos;
 
 		cfg->add(cfg, AUTH_RULE_AUTH_CLASS, AUTH_CLASS_EAP);
-
+		/* check for public key constraints for EAP-TLS etc. */
+		pos = strchr(auth, ':');
+		if (pos)
+		{
+			*pos = 0;
+			parse_pubkey_constraints(pos + 1, cfg);
+		}
 		type = eap_vendor_type_from_string(auth);
 		if (type)
 		{
@@ -667,6 +689,24 @@ static auth_cfg_t *build_auth_cfg(private_stroke_config_t *this,
 }
 
 /**
+ * build a mem_pool_t from an address range
+ */
+static mem_pool_t *create_pool_range(char *str)
+{
+	mem_pool_t *pool;
+	host_t *from, *to;
+
+	if (!host_create_from_range(str, &from, &to))
+	{
+		return NULL;
+	}
+	pool = mem_pool_create_range(str, from, to);
+	from->destroy(from);
+	to->destroy(to);
+	return pool;
+}
+
+/**
  * build a peer_cfg from a stroke msg
  */
 static peer_cfg_t *build_peer_cfg(private_stroke_config_t *this,
@@ -789,17 +829,25 @@ static peer_cfg_t *build_peer_cfg(private_stroke_config_t *this,
 			}
 			else
 			{
-				/* in-memory pool, named using CIDR notation */
+				/* in-memory pool, using range or CIDR notation */
+				mem_pool_t *pool;
 				host_t *base;
 				int bits;
 
-				base = host_create_from_subnet(token, &bits);
-				if (base)
+				pool = create_pool_range(token);
+				if (!pool)
+				{
+					base = host_create_from_subnet(token, &bits);
+					if (base)
+					{
+						pool = mem_pool_create(token, base, bits);
+						base->destroy(base);
+					}
+				}
+				if (pool)
 				{
-					this->attributes->add_pool(this->attributes,
-										mem_pool_create(token, base, bits));
+					this->attributes->add_pool(this->attributes, pool);
 					peer_cfg->add_pool(peer_cfg, token);
-					base->destroy(base);
 				}
 				else
 				{
diff --git a/src/libcharon/plugins/stroke/stroke_control.c b/src/libcharon/plugins/stroke/stroke_control.c
index f770d7c..0084fbf 100644
--- a/src/libcharon/plugins/stroke/stroke_control.c
+++ b/src/libcharon/plugins/stroke/stroke_control.c
@@ -352,7 +352,7 @@ METHOD(stroke_control_t, terminate, void,
 				if (streq(name, child_sa->get_name(child_sa)))
 				{
 					child_list->insert_last(child_list,
-							(void*)(uintptr_t)child_sa->get_reqid(child_sa));
+							(void*)(uintptr_t)child_sa->get_unique_id(child_sa));
 					if (!all)
 					{
 						break;
@@ -432,13 +432,13 @@ METHOD(stroke_control_t, rekey, void,
 			while (children->enumerate(children, (void**)&child_sa))
 			{
 				if ((name && streq(name, child_sa->get_name(child_sa))) ||
-					(id && id == child_sa->get_reqid(child_sa)))
+					(id && id == child_sa->get_unique_id(child_sa)))
 				{
 					lib->processor->queue_job(lib->processor,
 						(job_t*)rekey_child_sa_job_create(
-								child_sa->get_reqid(child_sa),
 								child_sa->get_protocol(child_sa),
-								child_sa->get_spi(child_sa, TRUE)));
+								child_sa->get_spi(child_sa, TRUE),
+								ike_sa->get_my_host(ike_sa)));
 					if (!all)
 					{
 						finished = TRUE;
diff --git a/src/libcharon/plugins/stroke/stroke_cred.c b/src/libcharon/plugins/stroke/stroke_cred.c
index 83431d1..5e423f1 100644
--- a/src/libcharon/plugins/stroke/stroke_cred.c
+++ b/src/libcharon/plugins/stroke/stroke_cred.c
@@ -70,11 +70,21 @@ struct private_stroke_cred_t {
 	char *secrets_file;
 
 	/**
-	 * credentials
+	 * credentials: end entity certs, attribute certs, CRLs, etc.
 	 */
 	mem_cred_t *creds;
 
 	/**
+	 * CA certificates
+	 */
+	mem_cred_t *cacerts;
+
+	/**
+	 * Attribute Authority certificates
+	 */
+	mem_cred_t *aacerts;
+
+	/**
 	 * ignore missing CA basic constraint (i.e. treat all certificates in
 	 * ipsec.conf ca sections and ipsec.d/cacerts as CA certificates)
 	 */
@@ -231,7 +241,7 @@ METHOD(stroke_cred_t, load_ca, certificate_t*,
 		}
 		DBG1(DBG_CFG, "  loaded ca certificate \"%Y\" from '%s'",
 			 cert->get_subject(cert), filename);
-		return this->creds->add_cert_ref(this->creds, TRUE, cert);
+		return this->creds->get_cert_ref(this->creds, cert);
 	}
 	return NULL;
 }
@@ -374,133 +384,183 @@ METHOD(stroke_cred_t, load_pubkey, certificate_t*,
 }
 
 /**
- * load trusted certificates from a directory
+ * Load a CA certificate  from disk
  */
-static void load_certdir(private_stroke_cred_t *this, char *path,
-						 certificate_type_t type, x509_flag_t flag)
+static void load_x509_ca(private_stroke_cred_t *this, char *file)
 {
-	struct stat st;
-	char *file;
-
-	enumerator_t *enumerator = enumerator_create_directory(path);
+	certificate_t *cert;
 
-	if (!enumerator)
+	if (this->force_ca_cert)
+	{	/* treat certificate as CA cert even it has no CA basic constraint */
+		cert = lib->creds->create(lib->creds, CRED_CERTIFICATE, CERT_X509,
+								  BUILD_FROM_FILE, file,
+								  BUILD_X509_FLAG, X509_CA, BUILD_END);
+	}
+	else
 	{
-		DBG1(DBG_CFG, "  reading directory failed");
-		return;
+		cert = lib->creds->create(lib->creds, CRED_CERTIFICATE, CERT_X509,
+								  BUILD_FROM_FILE, file, BUILD_END);
 	}
-
-	while (enumerator->enumerate(enumerator, NULL, &file, &st))
+	if (cert)
 	{
-		certificate_t *cert;
+		x509_t *x509 = (x509_t*)cert;
 
-		if (!S_ISREG(st.st_mode))
+		if (!(x509->get_flags(x509) & X509_CA))
 		{
-			/* skip special file */
-			continue;
+			DBG1(DBG_CFG, "  ca certificate \"%Y\" lacks ca basic constraint, "
+				 "discarded", cert->get_subject(cert));
+			cert->destroy(cert);
 		}
-		switch (type)
+		else
 		{
-			case CERT_X509:
-				if (flag & X509_CA)
-				{
-					if (this->force_ca_cert)
-					{	/* treat this certificate as CA cert even it has no
-						 * CA basic constraint */
-						cert = lib->creds->create(lib->creds,
-										CRED_CERTIFICATE, CERT_X509,
-										BUILD_FROM_FILE, file, BUILD_X509_FLAG,
-										X509_CA, BUILD_END);
-					}
-					else
-					{
-						cert = lib->creds->create(lib->creds,
-										CRED_CERTIFICATE, CERT_X509,
-										BUILD_FROM_FILE, file, BUILD_END);
-					}
-					if (cert)
-					{
-						x509_t *x509 = (x509_t*)cert;
-
-						if (!(x509->get_flags(x509) & X509_CA))
-						{
-							DBG1(DBG_CFG, "  ca certificate \"%Y\" lacks "
-								 "ca basic constraint, discarded",
-								 cert->get_subject(cert));
-							cert->destroy(cert);
-							cert = NULL;
-						}
-						else
-						{
-							DBG1(DBG_CFG, "  loaded ca certificate \"%Y\" "
-								 "from '%s'", cert->get_subject(cert), file);
-						}
-					}
-					else
+			DBG1(DBG_CFG, "  loaded ca certificate \"%Y\" from '%s'",
+				 cert->get_subject(cert), file);
+			this->cacerts->add_cert(this->cacerts, TRUE, cert);
+		}
+	}
+	else
+	{
+		DBG1(DBG_CFG, "  loading ca certificate from '%s' failed", file);
+	}
+}
+
+/**
+ * Load AA certificate with flags from disk
+ */
+static void load_x509_aa(private_stroke_cred_t *this, char *file)
+{
+	certificate_t *cert;
+
+	cert = lib->creds->create(lib->creds, CRED_CERTIFICATE, CERT_X509,
+							  BUILD_FROM_FILE, file,
+							  BUILD_X509_FLAG, X509_AA, BUILD_END);
+	if (cert)
+	{
+		DBG1(DBG_CFG, "  loaded AA certificate \"%Y\" from '%s'",
+			 cert->get_subject(cert), file);
+		this->aacerts->add_cert(this->aacerts, TRUE, cert);
+	}
+	else
+	{
+		DBG1(DBG_CFG, "  loading AA certificate from '%s' failed", file);
+	}
+}
+
+/**
+ * Load a certificate with flags from disk
+ */
+static void load_x509(private_stroke_cred_t *this, char *file, x509_flag_t flag)
+{
+	certificate_t *cert;
+
+	/* for all other flags, we add them to the certificate. */
+	cert = lib->creds->create(lib->creds, CRED_CERTIFICATE, CERT_X509,
+							  BUILD_FROM_FILE, file,
+							  BUILD_X509_FLAG, flag, BUILD_END);
+	if (cert)
+	{
+		DBG1(DBG_CFG, "  loaded certificate \"%Y\" from '%s'",
+			 cert->get_subject(cert), file);
+		this->creds->add_cert(this->creds, TRUE, cert);
+	}
+	else
+	{
+		DBG1(DBG_CFG, "  loading certificate from '%s' failed", file);
+	}
+}
+
+/**
+ * Load a CRL from a file
+ */
+static void load_x509_crl(private_stroke_cred_t *this, char *file)
+{
+	certificate_t *cert;
+
+	cert = lib->creds->create(lib->creds, CRED_CERTIFICATE, CERT_X509_CRL,
+							  BUILD_FROM_FILE, file, BUILD_END);
+	if (cert)
+	{
+		this->creds->add_crl(this->creds, (crl_t*)cert);
+		DBG1(DBG_CFG, "  loaded crl from '%s'",  file);
+	}
+	else
+	{
+		DBG1(DBG_CFG, "  loading crl from '%s' failed", file);
+	}
+}
+
+/**
+ * Load an attribute certificate from a file
+ */
+static void load_x509_ac(private_stroke_cred_t *this, char *file)
+{
+	certificate_t *cert;
+
+	cert = lib->creds->create(lib->creds, CRED_CERTIFICATE, CERT_X509_AC,
+							  BUILD_FROM_FILE, file, BUILD_END);
+	if (cert)
+	{
+		DBG1(DBG_CFG, "  loaded attribute certificate from '%s'", file);
+		this->creds->add_cert(this->creds, FALSE, cert);
+	}
+	else
+	{
+		DBG1(DBG_CFG, "  loading attribute certificate from '%s' failed", file);
+	}
+}
+
+/**
+ * load trusted certificates from a directory
+ */
+static void load_certdir(private_stroke_cred_t *this, char *path,
+						 certificate_type_t type, x509_flag_t flag)
+{
+	enumerator_t *enumerator;
+	struct stat st;
+	char *file;
+
+	enumerator = enumerator_create_directory(path);
+	if (enumerator)
+	{
+		while (enumerator->enumerate(enumerator, NULL, &file, &st))
+		{
+			if (!S_ISREG(st.st_mode))
+			{
+				/* skip special file */
+				continue;
+			}
+			switch (type)
+			{
+				case CERT_X509:
+					if (flag & X509_CA)
 					{
-						DBG1(DBG_CFG, "  loading ca certificate from '%s' "
-									  "failed", file);
+						load_x509_ca(this, file);
 					}
-				}
-				else
-				{	/* for all other flags, we add them to the certificate. */
-					cert = lib->creds->create(lib->creds,
-										CRED_CERTIFICATE, CERT_X509,
-										BUILD_FROM_FILE, file,
-										BUILD_X509_FLAG, flag, BUILD_END);
-					if (cert)
+					else if (flag & X509_AA)
 					{
-						DBG1(DBG_CFG, "  loaded certificate \"%Y\" from '%s'",
-									  cert->get_subject(cert), file);
+						load_x509_aa(this, file);
 					}
 					else
 					{
-						DBG1(DBG_CFG, "  loading certificate from '%s' "
-									  "failed", file);
+						load_x509(this, file, flag);
 					}
-				}
-				if (cert)
-				{
-					this->creds->add_cert(this->creds, TRUE, cert);
-				}
-				break;
-			case CERT_X509_CRL:
-				cert = lib->creds->create(lib->creds,
-										  CRED_CERTIFICATE, CERT_X509_CRL,
-										  BUILD_FROM_FILE, file,
-										  BUILD_END);
-				if (cert)
-				{
-					this->creds->add_crl(this->creds, (crl_t*)cert);
-					DBG1(DBG_CFG, "  loaded crl from '%s'",  file);
-				}
-				else
-				{
-					DBG1(DBG_CFG, "  loading crl from '%s' failed", file);
-				}
-				break;
-			case CERT_X509_AC:
-				cert = lib->creds->create(lib->creds,
-										  CRED_CERTIFICATE, CERT_X509_AC,
-										  BUILD_FROM_FILE, file,
-										  BUILD_END);
-				if (cert)
-				{
-					this->creds->add_cert(this->creds, FALSE, cert);
-					DBG1(DBG_CFG, "  loaded attribute certificate from '%s'",
-								  file);
-				}
-				else
-				{
-					DBG1(DBG_CFG, "  loading attribute certificate from '%s' "
-								  "failed", file);
-				}
-				break;
-			default:
-				break;
+					break;
+				case CERT_X509_CRL:
+					load_x509_crl(this, file);
+					break;
+				case CERT_X509_AC:
+					load_x509_ac(this, file);
+					break;
+				default:
+					break;
+			}
 		}
+		enumerator->destroy(enumerator);
+	}
+	else
+	{
+		DBG1(DBG_CFG, "  reading directory failed");
 	}
-	enumerator->destroy(enumerator);
 }
 
 METHOD(stroke_cred_t, cache_cert, void,
@@ -1124,6 +1184,7 @@ static void load_secrets(private_stroke_cred_t *this, mem_cred_t *secrets,
 	while (fetchline(src, &line))
 	{
 		chunk_t ids, token;
+		key_type_t key_type;
 		shared_key_type_t type;
 
 		line_nr++;
@@ -1222,10 +1283,22 @@ static void load_secrets(private_stroke_cred_t *this, mem_cred_t *secrets,
 			DBG1(DBG_CFG, "line %d: missing token", line_nr);
 			break;
 		}
-		if (match("RSA", &token) || match("ECDSA", &token))
+		if (match("RSA", &token) || match("ECDSA", &token) ||
+			match("BLISS", &token))
 		{
-			if (!load_private(secrets, line, line_nr, prompt,
-							  match("RSA", &token) ? KEY_RSA : KEY_ECDSA))
+			if (match("RSA", &token))
+			{
+				key_type = KEY_RSA;
+			}
+			else if (match("ECDSA", &token))
+			{
+				key_type = KEY_ECDSA;
+			}
+			else
+			{
+				key_type = KEY_BLISS;
+			}
+			if (!load_private(secrets, line, line_nr, prompt, key_type))
 			{
 				break;
 			}
@@ -1256,8 +1329,8 @@ static void load_secrets(private_stroke_cred_t *this, mem_cred_t *secrets,
 		}
 		else
 		{
-			DBG1(DBG_CFG, "line %d: token must be either "
-				 "RSA, ECDSA, P12, PIN, PSK, EAP, XAUTH or NTLM", line_nr);
+			DBG1(DBG_CFG, "line %d: token must be either RSA, ECDSA, BLISS, "
+						  "P12, PIN, PSK, EAP, XAUTH or NTLM", line_nr);
 			break;
 		}
 	}
@@ -1308,6 +1381,8 @@ METHOD(stroke_cred_t, reread, void,
 	{
 		DBG1(DBG_CFG, "rereading ca certificates from '%s'",
 			 CA_CERTIFICATE_DIR);
+		this->cacerts->clear(this->cacerts);
+		lib->credmgr->flush_cache(lib->credmgr, CERT_X509);
 		load_certdir(this, CA_CERTIFICATE_DIR, CERT_X509, X509_CA);
 	}
 	if (msg->reread.flags & REREAD_OCSPCERTS)
@@ -1321,6 +1396,8 @@ METHOD(stroke_cred_t, reread, void,
 	{
 		DBG1(DBG_CFG, "rereading aa certificates from '%s'",
 			 AA_CERTIFICATE_DIR);
+		this->aacerts->clear(this->aacerts);
+		lib->credmgr->flush_cache(lib->credmgr, CERT_X509);
 		load_certdir(this, AA_CERTIFICATE_DIR, CERT_X509, X509_AA);
 	}
 	if (msg->reread.flags & REREAD_ACERTS)
@@ -1346,7 +1423,11 @@ METHOD(stroke_cred_t, add_shared, void,
 METHOD(stroke_cred_t, destroy, void,
 	private_stroke_cred_t *this)
 {
+	lib->credmgr->remove_set(lib->credmgr, &this->aacerts->set);
+	lib->credmgr->remove_set(lib->credmgr, &this->cacerts->set);
 	lib->credmgr->remove_set(lib->credmgr, &this->creds->set);
+	this->aacerts->destroy(this->aacerts);
+	this->cacerts->destroy(this->cacerts);
 	this->creds->destroy(this->creds);
 	free(this);
 }
@@ -1379,9 +1460,13 @@ stroke_cred_t *stroke_cred_create()
 								"%s.plugins.stroke.secrets_file", SECRETS_FILE,
 								lib->ns),
 		.creds = mem_cred_create(),
+		.cacerts = mem_cred_create(),
+		.aacerts = mem_cred_create(),
 	);
 
 	lib->credmgr->add_set(lib->credmgr, &this->creds->set);
+	lib->credmgr->add_set(lib->credmgr, &this->cacerts->set);
+	lib->credmgr->add_set(lib->credmgr, &this->aacerts->set);
 
 	this->force_ca_cert = lib->settings->get_bool(lib->settings,
 						"%s.plugins.stroke.ignore_missing_ca_basic_constraint",
diff --git a/src/libcharon/plugins/stroke/stroke_cred.h b/src/libcharon/plugins/stroke/stroke_cred.h
index f6fbb96..9434629 100644
--- a/src/libcharon/plugins/stroke/stroke_cred.h
+++ b/src/libcharon/plugins/stroke/stroke_cred.h
@@ -50,10 +50,13 @@ struct stroke_cred_t {
 	void (*reread)(stroke_cred_t *this, stroke_msg_t *msg, FILE *prompt);
 
 	/**
-	 * Load a CA certificate, and serve it through the credential_set.
+	 * Load a CA certificate.
+	 *
+	 * This method does not add the loaded CA certificate to the internal
+	 * credentail set, but returns it only.
 	 *
 	 * @param filename		file to load CA cert from
-	 * @return				reference to loaded certificate, or NULL
+	 * @return				loaded certificate, or NULL
 	 */
 	certificate_t* (*load_ca)(stroke_cred_t *this, char *filename);
 
diff --git a/src/libcharon/plugins/stroke/stroke_handler.c b/src/libcharon/plugins/stroke/stroke_handler.c
index fef8cab..d0cc9af 100644
--- a/src/libcharon/plugins/stroke/stroke_handler.c
+++ b/src/libcharon/plugins/stroke/stroke_handler.c
@@ -94,10 +94,9 @@ static bool attr_filter(void *lock, host_t **in,
 }
 
 METHOD(attribute_handler_t, create_attribute_enumerator, enumerator_t*,
-	private_stroke_handler_t *this, identification_t *server,
+	private_stroke_handler_t *this, ike_sa_t *ike_sa,
 	linked_list_t *vips)
 {
-	ike_sa_t *ike_sa;
 	peer_cfg_t *peer_cfg;
 	enumerator_t *enumerator;
 	attributes_t *attr;
diff --git a/src/libcharon/plugins/stroke/stroke_list.c b/src/libcharon/plugins/stroke/stroke_list.c
index 1aa49ce..68b8232 100644
--- a/src/libcharon/plugins/stroke/stroke_list.c
+++ b/src/libcharon/plugins/stroke/stroke_list.c
@@ -214,11 +214,12 @@ static void log_child_sa(FILE *out, child_sa_t *child_sa, bool all)
 	config = child_sa->get_config(child_sa);
 	now = time_monotonic(NULL);
 
-	fprintf(out, "%12s{%d}:  %N, %N%s",
-			child_sa->get_name(child_sa), child_sa->get_reqid(child_sa),
+	fprintf(out, "%12s{%d}:  %N, %N%s, reqid %u",
+			child_sa->get_name(child_sa), child_sa->get_unique_id(child_sa),
 			child_sa_state_names, child_sa->get_state(child_sa),
 			ipsec_mode_names, child_sa->get_mode(child_sa),
-			config->use_proxy_mode(config) ? "_PROXY" : "");
+			config->use_proxy_mode(config) ? "_PROXY" : "",
+			child_sa->get_reqid(child_sa));
 
 	if (child_sa->get_state(child_sa) == CHILD_INSTALLED)
 	{
@@ -238,7 +239,7 @@ static void log_child_sa(FILE *out, child_sa_t *child_sa, bool all)
 		if (all)
 		{
 			fprintf(out, "\n%12s{%d}:  ", child_sa->get_name(child_sa),
-					child_sa->get_reqid(child_sa));
+					child_sa->get_unique_id(child_sa));
 
 			proposal = child_sa->get_proposal(child_sa);
 			if (proposal)
@@ -322,7 +323,8 @@ static void log_child_sa(FILE *out, child_sa_t *child_sa, bool all)
 
 		}
 	}
-	else if (child_sa->get_state(child_sa) == CHILD_REKEYING)
+	else if (child_sa->get_state(child_sa) == CHILD_REKEYING ||
+			 child_sa->get_state(child_sa) == CHILD_REKEYED)
 	{
 		rekey = child_sa->get_lifetime(child_sa, TRUE);
 		fprintf(out, ", expires in %V", &now, &rekey);
@@ -333,7 +335,7 @@ static void log_child_sa(FILE *out, child_sa_t *child_sa, bool all)
 	other_ts = linked_list_create_from_enumerator(
 							child_sa->create_ts_enumerator(child_sa, FALSE));
 	fprintf(out, "\n%12s{%d}:   %#R=== %#R\n",
-			child_sa->get_name(child_sa), child_sa->get_reqid(child_sa),
+			child_sa->get_name(child_sa), child_sa->get_unique_id(child_sa),
 			my_ts, other_ts);
 	my_ts->destroy(my_ts);
 	other_ts->destroy(other_ts);
@@ -496,7 +498,7 @@ METHOD(stroke_list_t, status, void,
 		{
 			struct mallinfo mi = mallinfo();
 
-			fprintf(out, "  malloc: sbrk %d, mmap %d, used %d, free %d\n",
+			fprintf(out, "  malloc: sbrk %u, mmap %u, used %u, free %u\n",
 				    mi.arena, mi.hblkhd, mi.uordblks, mi.fordblks);
 		}
 #endif /* HAVE_MALLINFO */
diff --git a/src/libcharon/plugins/stroke/stroke_plugin.c b/src/libcharon/plugins/stroke/stroke_plugin.c
index 31df1f9..f64b99f 100644
--- a/src/libcharon/plugins/stroke/stroke_plugin.c
+++ b/src/libcharon/plugins/stroke/stroke_plugin.c
@@ -69,6 +69,7 @@ METHOD(plugin_t, get_features, int,
 				PLUGIN_SDEPEND(PRIVKEY, KEY_RSA),
 				PLUGIN_SDEPEND(PRIVKEY, KEY_ECDSA),
 				PLUGIN_SDEPEND(PRIVKEY, KEY_DSA),
+				PLUGIN_SDEPEND(PRIVKEY, KEY_BLISS),
 				PLUGIN_SDEPEND(CERT_DECODE, CERT_ANY),
 				PLUGIN_SDEPEND(CERT_DECODE, CERT_X509),
 				PLUGIN_SDEPEND(CERT_DECODE, CERT_X509_CRL),
diff --git a/src/libcharon/plugins/stroke/stroke_socket.c b/src/libcharon/plugins/stroke/stroke_socket.c
index 54dd56e..db7e66f 100644
--- a/src/libcharon/plugins/stroke/stroke_socket.c
+++ b/src/libcharon/plugins/stroke/stroke_socket.c
@@ -24,7 +24,6 @@
 #include <unistd.h>
 #include <errno.h>
 
-#include <hydra.h>
 #include <daemon.h>
 
 #include "stroke_config.h"
@@ -747,8 +746,10 @@ METHOD(stroke_socket_t, destroy, void,
 	lib->credmgr->remove_set(lib->credmgr, &this->ca->set);
 	lib->credmgr->remove_set(lib->credmgr, &this->cred->set);
 	charon->backends->remove_backend(charon->backends, &this->config->backend);
-	hydra->attributes->remove_provider(hydra->attributes, &this->attribute->provider);
-	hydra->attributes->remove_handler(hydra->attributes, &this->handler->handler);
+	charon->attributes->remove_provider(charon->attributes,
+										&this->attribute->provider);
+	charon->attributes->remove_handler(charon->attributes,
+									   &this->handler->handler);
 	charon->bus->remove_listener(charon->bus, &this->counter->listener);
 	this->cred->destroy(this->cred);
 	this->ca->destroy(this->ca);
@@ -790,8 +791,10 @@ stroke_socket_t *stroke_socket_create()
 	lib->credmgr->add_set(lib->credmgr, &this->ca->set);
 	lib->credmgr->add_set(lib->credmgr, &this->cred->set);
 	charon->backends->add_backend(charon->backends, &this->config->backend);
-	hydra->attributes->add_provider(hydra->attributes, &this->attribute->provider);
-	hydra->attributes->add_handler(hydra->attributes, &this->handler->handler);
+	charon->attributes->add_provider(charon->attributes,
+									 &this->attribute->provider);
+	charon->attributes->add_handler(charon->attributes,
+									&this->handler->handler);
 	charon->bus->add_listener(charon->bus, &this->counter->listener);
 
 	max_concurrent = lib->settings->get_int(lib->settings,
diff --git a/src/libcharon/plugins/systime_fix/Makefile.in b/src/libcharon/plugins/systime_fix/Makefile.in
index 0e477f9..be148b6 100644
--- a/src/libcharon/plugins/systime_fix/Makefile.in
+++ b/src/libcharon/plugins/systime_fix/Makefile.in
@@ -229,6 +229,7 @@ DLLIB = @DLLIB@
 DLLTOOL = @DLLTOOL@
 DSYMUTIL = @DSYMUTIL@
 DUMPBIN = @DUMPBIN@
+EASY_INSTALL = @EASY_INSTALL@
 ECHO_C = @ECHO_C@
 ECHO_N = @ECHO_N@
 ECHO_T = @ECHO_T@
@@ -289,10 +290,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
 PLUGIN_CFLAGS = @PLUGIN_CFLAGS@
 PTHREADLIB = @PTHREADLIB@
 PYTHON = @PYTHON@
+PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@
 PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
 PYTHON_PLATFORM = @PYTHON_PLATFORM@
 PYTHON_PREFIX = @PYTHON_PREFIX@
 PYTHON_VERSION = @PYTHON_VERSION@
+PY_TEST = @PY_TEST@
 RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
@@ -366,6 +369,8 @@ json_CFLAGS = @json_CFLAGS@
 json_LIBS = @json_LIBS@
 libdir = @libdir@
 libexecdir = @libexecdir@
+libiptc_CFLAGS = @libiptc_CFLAGS@
+libiptc_LIBS = @libiptc_LIBS@
 linux_headers = @linux_headers@
 localedir = @localedir@
 localstatedir = @localstatedir@
diff --git a/src/libcharon/plugins/tnc_ifmap/Makefile.in b/src/libcharon/plugins/tnc_ifmap/Makefile.in
index 3f2952c..17cc341 100644
--- a/src/libcharon/plugins/tnc_ifmap/Makefile.in
+++ b/src/libcharon/plugins/tnc_ifmap/Makefile.in
@@ -232,6 +232,7 @@ DLLIB = @DLLIB@
 DLLTOOL = @DLLTOOL@
 DSYMUTIL = @DSYMUTIL@
 DUMPBIN = @DUMPBIN@
+EASY_INSTALL = @EASY_INSTALL@
 ECHO_C = @ECHO_C@
 ECHO_N = @ECHO_N@
 ECHO_T = @ECHO_T@
@@ -292,10 +293,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
 PLUGIN_CFLAGS = @PLUGIN_CFLAGS@
 PTHREADLIB = @PTHREADLIB@
 PYTHON = @PYTHON@
+PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@
 PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
 PYTHON_PLATFORM = @PYTHON_PLATFORM@
 PYTHON_PREFIX = @PYTHON_PREFIX@
 PYTHON_VERSION = @PYTHON_VERSION@
+PY_TEST = @PY_TEST@
 RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
@@ -369,6 +372,8 @@ json_CFLAGS = @json_CFLAGS@
 json_LIBS = @json_LIBS@
 libdir = @libdir@
 libexecdir = @libexecdir@
+libiptc_CFLAGS = @libiptc_CFLAGS@
+libiptc_LIBS = @libiptc_LIBS@
 linux_headers = @linux_headers@
 localedir = @localedir@
 localstatedir = @localstatedir@
diff --git a/src/libcharon/plugins/tnc_pdp/Makefile.in b/src/libcharon/plugins/tnc_pdp/Makefile.in
index 97c4796..ef05275 100644
--- a/src/libcharon/plugins/tnc_pdp/Makefile.in
+++ b/src/libcharon/plugins/tnc_pdp/Makefile.in
@@ -233,6 +233,7 @@ DLLIB = @DLLIB@
 DLLTOOL = @DLLTOOL@
 DSYMUTIL = @DSYMUTIL@
 DUMPBIN = @DUMPBIN@
+EASY_INSTALL = @EASY_INSTALL@
 ECHO_C = @ECHO_C@
 ECHO_N = @ECHO_N@
 ECHO_T = @ECHO_T@
@@ -293,10 +294,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
 PLUGIN_CFLAGS = @PLUGIN_CFLAGS@
 PTHREADLIB = @PTHREADLIB@
 PYTHON = @PYTHON@
+PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@
 PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
 PYTHON_PLATFORM = @PYTHON_PLATFORM@
 PYTHON_PREFIX = @PYTHON_PREFIX@
 PYTHON_VERSION = @PYTHON_VERSION@
+PY_TEST = @PY_TEST@
 RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
@@ -370,6 +373,8 @@ json_CFLAGS = @json_CFLAGS@
 json_LIBS = @json_LIBS@
 libdir = @libdir@
 libexecdir = @libexecdir@
+libiptc_CFLAGS = @libiptc_CFLAGS@
+libiptc_LIBS = @libiptc_LIBS@
 linux_headers = @linux_headers@
 localedir = @localedir@
 localstatedir = @localstatedir@
diff --git a/src/libcharon/plugins/tnc_pdp/tnc_pdp.c b/src/libcharon/plugins/tnc_pdp/tnc_pdp.c
index 109c216..91456f8 100644
--- a/src/libcharon/plugins/tnc_pdp/tnc_pdp.c
+++ b/src/libcharon/plugins/tnc_pdp/tnc_pdp.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2012-2013 Andreas Steffen
+ * Copyright (C) 2012-2015 Andreas Steffen
  * HSR Hochschule fuer Technik Rapperswil
  *
  * This program is free software; you can redistribute it and/or modify it
@@ -646,8 +646,8 @@ static bool pt_tls_receive(private_tnc_pdp_t *this, int fd, watcher_event_t even
 	int pt_tls_fd;
 	struct sockaddr_storage addr;
 	socklen_t addrlen = sizeof(addr);
-	identification_t *peer;
-	host_t *host;
+	identification_t *client_id;
+	host_t *server_ip, *client_ip;
 	pt_tls_server_t *pt_tls;
 	tnccs_t *tnccs;
 	pt_tls_auth_t auth = PT_TLS_AUTH_TLS_OR_SASL;
@@ -658,17 +658,22 @@ static bool pt_tls_receive(private_tnc_pdp_t *this, int fd, watcher_event_t even
 		DBG1(DBG_TNC, "accepting PT-TLS stream failed: %s", strerror(errno));
 		return FALSE;
 	}
-	host = host_create_from_sockaddr((sockaddr_t*)&addr);
-	DBG1(DBG_TNC, "accepting PT-TLS stream from %H", host);
-	host->destroy(host);
+	client_ip = host_create_from_sockaddr((sockaddr_t*)&addr);
+	DBG1(DBG_TNC, "accepting PT-TLS stream from %H", client_ip);
+
+	/* Currently we do not determine the IP address of the server interface */
+	server_ip = host_create_any(client_ip->get_family(client_ip));
 
-	/* At this moment the peer identity is not known yet */
-	peer = identification_create_from_encoding(ID_ANY, chunk_empty),
+	/* At this moment the client identity is not known yet */
+	client_id = identification_create_from_encoding(ID_ANY, chunk_empty),
 
 	tnccs = tnc->tnccs->create_instance(tnc->tnccs, TNCCS_2_0, TRUE,
-										this->server, peer, TNC_IFT_TLS_2_0,
+										this->server, client_id, server_ip,
+										client_ip, TNC_IFT_TLS_2_0,
 										(tnccs_cb_t)get_recommendation);
-	peer->destroy(peer);
+	client_id->destroy(client_id);
+	server_ip->destroy(server_ip);
+	client_ip->destroy(client_ip);
 
 	if (!tnccs)
 	{
diff --git a/src/libcharon/plugins/uci/Makefile.in b/src/libcharon/plugins/uci/Makefile.in
index 5e16c3c..2c03138 100644
--- a/src/libcharon/plugins/uci/Makefile.in
+++ b/src/libcharon/plugins/uci/Makefile.in
@@ -227,6 +227,7 @@ DLLIB = @DLLIB@
 DLLTOOL = @DLLTOOL@
 DSYMUTIL = @DSYMUTIL@
 DUMPBIN = @DUMPBIN@
+EASY_INSTALL = @EASY_INSTALL@
 ECHO_C = @ECHO_C@
 ECHO_N = @ECHO_N@
 ECHO_T = @ECHO_T@
@@ -287,10 +288,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
 PLUGIN_CFLAGS = @PLUGIN_CFLAGS@
 PTHREADLIB = @PTHREADLIB@
 PYTHON = @PYTHON@
+PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@
 PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
 PYTHON_PLATFORM = @PYTHON_PLATFORM@
 PYTHON_PREFIX = @PYTHON_PREFIX@
 PYTHON_VERSION = @PYTHON_VERSION@
+PY_TEST = @PY_TEST@
 RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
@@ -364,6 +367,8 @@ json_CFLAGS = @json_CFLAGS@
 json_LIBS = @json_LIBS@
 libdir = @libdir@
 libexecdir = @libexecdir@
+libiptc_CFLAGS = @libiptc_CFLAGS@
+libiptc_LIBS = @libiptc_LIBS@
 linux_headers = @linux_headers@
 localedir = @localedir@
 localstatedir = @localstatedir@
diff --git a/src/libcharon/plugins/unit_tester/Makefile.am b/src/libcharon/plugins/unit_tester/Makefile.am
deleted file mode 100644
index b7f8fc3..0000000
--- a/src/libcharon/plugins/unit_tester/Makefile.am
+++ /dev/null
@@ -1,26 +0,0 @@
-AM_CPPFLAGS = \
-	-I$(top_srcdir)/src/libstrongswan \
-	-I$(top_srcdir)/src/libhydra \
-	-I$(top_srcdir)/src/libcharon
-
-AM_CFLAGS = \
-	$(PLUGIN_CFLAGS)
-
-if MONOLITHIC
-noinst_LTLIBRARIES = libstrongswan-unit-tester.la
-else
-plugin_LTLIBRARIES = libstrongswan-unit-tester.la
-endif
-
-libstrongswan_unit_tester_la_SOURCES = \
-	unit_tester.c unit_tester.h tests.h \
-	tests/test_auth_info.c \
-	tests/test_curl.c \
-	tests/test_mysql.c \
-	tests/test_sqlite.c \
-	tests/test_cert.c \
-	tests/test_med_db.c \
-	tests/test_pool.c \
-	tests/test_agent.c
-
-libstrongswan_unit_tester_la_LDFLAGS = -module -avoid-version
diff --git a/src/libcharon/plugins/unit_tester/Makefile.in b/src/libcharon/plugins/unit_tester/Makefile.in
deleted file mode 100644
index 1aca319..0000000
--- a/src/libcharon/plugins/unit_tester/Makefile.in
+++ /dev/null
@@ -1,819 +0,0 @@
-# Makefile.in generated by automake 1.14.1 from Makefile.am.
-# @configure_input@
-
-# Copyright (C) 1994-2013 Free Software Foundation, Inc.
-
-# This Makefile.in is free software; the Free Software Foundation
-# gives unlimited permission to copy and/or distribute it,
-# with or without modifications, as long as this notice is preserved.
-
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
-# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
-# PARTICULAR PURPOSE.
-
- at SET_MAKE@
-
-VPATH = @srcdir@
-am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)'
-am__make_running_with_option = \
-  case $${target_option-} in \
-      ?) ;; \
-      *) echo "am__make_running_with_option: internal error: invalid" \
-              "target option '$${target_option-}' specified" >&2; \
-         exit 1;; \
-  esac; \
-  has_opt=no; \
-  sane_makeflags=$$MAKEFLAGS; \
-  if $(am__is_gnu_make); then \
-    sane_makeflags=$$MFLAGS; \
-  else \
-    case $$MAKEFLAGS in \
-      *\\[\ \	]*) \
-        bs=\\; \
-        sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
-          | sed "s/$$bs$$bs[$$bs $$bs	]*//g"`;; \
-    esac; \
-  fi; \
-  skip_next=no; \
-  strip_trailopt () \
-  { \
-    flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
-  }; \
-  for flg in $$sane_makeflags; do \
-    test $$skip_next = yes && { skip_next=no; continue; }; \
-    case $$flg in \
-      *=*|--*) continue;; \
-        -*I) strip_trailopt 'I'; skip_next=yes;; \
-      -*I?*) strip_trailopt 'I';; \
-        -*O) strip_trailopt 'O'; skip_next=yes;; \
-      -*O?*) strip_trailopt 'O';; \
-        -*l) strip_trailopt 'l'; skip_next=yes;; \
-      -*l?*) strip_trailopt 'l';; \
-      -[dEDm]) skip_next=yes;; \
-      -[JT]) skip_next=yes;; \
-    esac; \
-    case $$flg in \
-      *$$target_option*) has_opt=yes; break;; \
-    esac; \
-  done; \
-  test $$has_opt = yes
-am__make_dryrun = (target_option=n; $(am__make_running_with_option))
-am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
-pkgdatadir = $(datadir)/@PACKAGE@
-pkgincludedir = $(includedir)/@PACKAGE@
-pkglibdir = $(libdir)/@PACKAGE@
-pkglibexecdir = $(libexecdir)/@PACKAGE@
-am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
-install_sh_DATA = $(install_sh) -c -m 644
-install_sh_PROGRAM = $(install_sh) -c
-install_sh_SCRIPT = $(install_sh) -c
-INSTALL_HEADER = $(INSTALL_DATA)
-transform = $(program_transform_name)
-NORMAL_INSTALL = :
-PRE_INSTALL = :
-POST_INSTALL = :
-NORMAL_UNINSTALL = :
-PRE_UNINSTALL = :
-POST_UNINSTALL = :
-build_triplet = @build@
-host_triplet = @host@
-subdir = src/libcharon/plugins/unit_tester
-DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
-	$(top_srcdir)/depcomp
-ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
-am__aclocal_m4_deps = $(top_srcdir)/m4/config/libtool.m4 \
-	$(top_srcdir)/m4/config/ltoptions.m4 \
-	$(top_srcdir)/m4/config/ltsugar.m4 \
-	$(top_srcdir)/m4/config/ltversion.m4 \
-	$(top_srcdir)/m4/config/lt~obsolete.m4 \
-	$(top_srcdir)/m4/macros/split-package-version.m4 \
-	$(top_srcdir)/m4/macros/with.m4 \
-	$(top_srcdir)/m4/macros/enable-disable.m4 \
-	$(top_srcdir)/m4/macros/add-plugin.m4 \
-	$(top_srcdir)/configure.ac
-am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
-	$(ACLOCAL_M4)
-mkinstalldirs = $(install_sh) -d
-CONFIG_HEADER = $(top_builddir)/config.h
-CONFIG_CLEAN_FILES =
-CONFIG_CLEAN_VPATH_FILES =
-am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
-am__vpath_adj = case $$p in \
-    $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
-    *) f=$$p;; \
-  esac;
-am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
-am__install_max = 40
-am__nobase_strip_setup = \
-  srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
-am__nobase_strip = \
-  for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
-am__nobase_list = $(am__nobase_strip_setup); \
-  for p in $$list; do echo "$$p $$p"; done | \
-  sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
-  $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
-    if (++n[$$2] == $(am__install_max)) \
-      { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
-    END { for (dir in files) print dir, files[dir] }'
-am__base_list = \
-  sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
-  sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
-am__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; }; \
-  }
-am__installdirs = "$(DESTDIR)$(plugindir)"
-LTLIBRARIES = $(noinst_LTLIBRARIES) $(plugin_LTLIBRARIES)
-libstrongswan_unit_tester_la_LIBADD =
-am__dirstamp = $(am__leading_dot)dirstamp
-am_libstrongswan_unit_tester_la_OBJECTS = unit_tester.lo \
-	tests/test_auth_info.lo tests/test_curl.lo tests/test_mysql.lo \
-	tests/test_sqlite.lo tests/test_cert.lo tests/test_med_db.lo \
-	tests/test_pool.lo tests/test_agent.lo
-libstrongswan_unit_tester_la_OBJECTS =  \
-	$(am_libstrongswan_unit_tester_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_unit_tester_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \
-	$(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \
-	$(AM_CFLAGS) $(CFLAGS) $(libstrongswan_unit_tester_la_LDFLAGS) \
-	$(LDFLAGS) -o $@
- at MONOLITHIC_FALSE@am_libstrongswan_unit_tester_la_rpath = -rpath \
- at MONOLITHIC_FALSE@	$(plugindir)
- at MONOLITHIC_TRUE@am_libstrongswan_unit_tester_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
-am__v_P_1 = :
-AM_V_GEN = $(am__v_GEN_ at AM_V@)
-am__v_GEN_ = $(am__v_GEN_ at AM_DEFAULT_V@)
-am__v_GEN_0 = @echo "  GEN     " $@;
-am__v_GEN_1 = 
-AM_V_at = $(am__v_at_ at AM_V@)
-am__v_at_ = $(am__v_at_ at AM_DEFAULT_V@)
-am__v_at_0 = @
-am__v_at_1 = 
-DEFAULT_INCLUDES = -I. at am__isrc@ -I$(top_builddir)
-depcomp = $(SHELL) $(top_srcdir)/depcomp
-am__depfiles_maybe = depfiles
-am__mv = mv -f
-COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
-	$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
-LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
-	$(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \
-	$(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
-	$(AM_CFLAGS) $(CFLAGS)
-AM_V_CC = $(am__v_CC_ at AM_V@)
-am__v_CC_ = $(am__v_CC_ at AM_DEFAULT_V@)
-am__v_CC_0 = @echo "  CC      " $@;
-am__v_CC_1 = 
-CCLD = $(CC)
-LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
-	$(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
-	$(AM_LDFLAGS) $(LDFLAGS) -o $@
-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_unit_tester_la_SOURCES)
-DIST_SOURCES = $(libstrongswan_unit_tester_la_SOURCES)
-am__can_run_installinfo = \
-  case $$AM_UPDATE_INFO_DIR in \
-    n|no|NO) false;; \
-    *) (install-info --version) >/dev/null 2>&1;; \
-  esac
-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
-# *not* preserved.
-am__uniquify_input = $(AWK) '\
-  BEGIN { nonempty = 0; } \
-  { items[$$0] = 1; nonempty = 1; } \
-  END { if (nonempty) { for (i in items) print i; }; } \
-'
-# Make sure the list of sources is unique.  This is necessary because,
-# e.g., the same source file might be shared among _SOURCES variables
-# for different programs/libraries.
-am__define_uniq_tagged_files = \
-  list='$(am__tagged_files)'; \
-  unique=`for i in $$list; do \
-    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
-  done | $(am__uniquify_input)`
-ETAGS = etags
-CTAGS = ctags
-DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
-ACLOCAL = @ACLOCAL@
-ALLOCA = @ALLOCA@
-AMTAR = @AMTAR@
-AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
-AR = @AR@
-AUTOCONF = @AUTOCONF@
-AUTOHEADER = @AUTOHEADER@
-AUTOMAKE = @AUTOMAKE@
-AWK = @AWK@
-BFDLIB = @BFDLIB@
-BTLIB = @BTLIB@
-CC = @CC@
-CCDEPMODE = @CCDEPMODE@
-CFLAGS = @CFLAGS@
-COVERAGE_CFLAGS = @COVERAGE_CFLAGS@
-COVERAGE_LDFLAGS = @COVERAGE_LDFLAGS@
-CPP = @CPP@
-CPPFLAGS = @CPPFLAGS@
-CYGPATH_W = @CYGPATH_W@
-DEFS = @DEFS@
-DEPDIR = @DEPDIR@
-DLLIB = @DLLIB@
-DLLTOOL = @DLLTOOL@
-DSYMUTIL = @DSYMUTIL@
-DUMPBIN = @DUMPBIN@
-ECHO_C = @ECHO_C@
-ECHO_N = @ECHO_N@
-ECHO_T = @ECHO_T@
-EGREP = @EGREP@
-EXEEXT = @EXEEXT@
-FGREP = @FGREP@
-GEM = @GEM@
-GENHTML = @GENHTML@
-GPERF = @GPERF@
-GPRBUILD = @GPRBUILD@
-GREP = @GREP@
-INSTALL = @INSTALL@
-INSTALL_DATA = @INSTALL_DATA@
-INSTALL_PROGRAM = @INSTALL_PROGRAM@
-INSTALL_SCRIPT = @INSTALL_SCRIPT@
-INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
-LCOV = @LCOV@
-LD = @LD@
-LDFLAGS = @LDFLAGS@
-LEX = @LEX@
-LEXLIB = @LEXLIB@
-LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@
-LIBOBJS = @LIBOBJS@
-LIBS = @LIBS@
-LIBTOOL = @LIBTOOL@
-LIPO = @LIPO@
-LN_S = @LN_S@
-LTLIBOBJS = @LTLIBOBJS@
-MAKEINFO = @MAKEINFO@
-MANIFEST_TOOL = @MANIFEST_TOOL@
-MKDIR_P = @MKDIR_P@
-MYSQLCFLAG = @MYSQLCFLAG@
-MYSQLCONFIG = @MYSQLCONFIG@
-MYSQLLIB = @MYSQLLIB@
-NM = @NM@
-NMEDIT = @NMEDIT@
-OBJDUMP = @OBJDUMP@
-OBJEXT = @OBJEXT@
-OPENSSL_LIB = @OPENSSL_LIB@
-OTOOL = @OTOOL@
-OTOOL64 = @OTOOL64@
-PACKAGE = @PACKAGE@
-PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
-PACKAGE_NAME = @PACKAGE_NAME@
-PACKAGE_STRING = @PACKAGE_STRING@
-PACKAGE_TARNAME = @PACKAGE_TARNAME@
-PACKAGE_URL = @PACKAGE_URL@
-PACKAGE_VERSION = @PACKAGE_VERSION@
-PACKAGE_VERSION_BUILD = @PACKAGE_VERSION_BUILD@
-PACKAGE_VERSION_MAJOR = @PACKAGE_VERSION_MAJOR@
-PACKAGE_VERSION_MINOR = @PACKAGE_VERSION_MINOR@
-PACKAGE_VERSION_REVIEW = @PACKAGE_VERSION_REVIEW@
-PATH_SEPARATOR = @PATH_SEPARATOR@
-PERL = @PERL@
-PKG_CONFIG = @PKG_CONFIG@
-PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
-PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
-PLUGIN_CFLAGS = @PLUGIN_CFLAGS@
-PTHREADLIB = @PTHREADLIB@
-PYTHON = @PYTHON@
-PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
-PYTHON_PLATFORM = @PYTHON_PLATFORM@
-PYTHON_PREFIX = @PYTHON_PREFIX@
-PYTHON_VERSION = @PYTHON_VERSION@
-RANLIB = @RANLIB@
-RTLIB = @RTLIB@
-RUBY = @RUBY@
-RUBYGEMDIR = @RUBYGEMDIR@
-RUBYINCLUDE = @RUBYINCLUDE@
-RUBYLIB = @RUBYLIB@
-SED = @SED@
-SET_MAKE = @SET_MAKE@
-SHELL = @SHELL@
-SOCKLIB = @SOCKLIB@
-STRIP = @STRIP@
-UNWINDLIB = @UNWINDLIB@
-VERSION = @VERSION@
-YACC = @YACC@
-YFLAGS = @YFLAGS@
-abs_builddir = @abs_builddir@
-abs_srcdir = @abs_srcdir@
-abs_top_builddir = @abs_top_builddir@
-abs_top_srcdir = @abs_top_srcdir@
-ac_ct_AR = @ac_ct_AR@
-ac_ct_CC = @ac_ct_CC@
-ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
-aikgen_plugins = @aikgen_plugins@
-am__include = @am__include@
-am__leading_dot = @am__leading_dot@
-am__quote = @am__quote@
-am__tar = @am__tar@
-am__untar = @am__untar@
-attest_plugins = @attest_plugins@
-bindir = @bindir@
-build = @build@
-build_alias = @build_alias@
-build_cpu = @build_cpu@
-build_os = @build_os@
-build_vendor = @build_vendor@
-builddir = @builddir@
-c_plugins = @c_plugins@
-charon_natt_port = @charon_natt_port@
-charon_plugins = @charon_plugins@
-charon_udp_port = @charon_udp_port@
-clearsilver_LIBS = @clearsilver_LIBS@
-cmd_plugins = @cmd_plugins@
-datadir = @datadir@
-datarootdir = @datarootdir@
-dbusservicedir = @dbusservicedir@
-dev_headers = @dev_headers@
-docdir = @docdir@
-dvidir = @dvidir@
-exec_prefix = @exec_prefix@
-fips_mode = @fips_mode@
-gtk_CFLAGS = @gtk_CFLAGS@
-gtk_LIBS = @gtk_LIBS@
-h_plugins = @h_plugins@
-host = @host@
-host_alias = @host_alias@
-host_cpu = @host_cpu@
-host_os = @host_os@
-host_vendor = @host_vendor@
-htmldir = @htmldir@
-imcvdir = @imcvdir@
-includedir = @includedir@
-infodir = @infodir@
-install_sh = @install_sh@
-ipsec_script = @ipsec_script@
-ipsec_script_upper = @ipsec_script_upper@
-ipsecdir = @ipsecdir@
-ipsecgroup = @ipsecgroup@
-ipseclibdir = @ipseclibdir@
-ipsecuser = @ipsecuser@
-json_CFLAGS = @json_CFLAGS@
-json_LIBS = @json_LIBS@
-libdir = @libdir@
-libexecdir = @libexecdir@
-linux_headers = @linux_headers@
-localedir = @localedir@
-localstatedir = @localstatedir@
-maemo_CFLAGS = @maemo_CFLAGS@
-maemo_LIBS = @maemo_LIBS@
-manager_plugins = @manager_plugins@
-mandir = @mandir@
-medsrv_plugins = @medsrv_plugins@
-mkdir_p = @mkdir_p@
-nm_CFLAGS = @nm_CFLAGS@
-nm_LIBS = @nm_LIBS@
-nm_ca_dir = @nm_ca_dir@
-nm_plugins = @nm_plugins@
-oldincludedir = @oldincludedir@
-pcsclite_CFLAGS = @pcsclite_CFLAGS@
-pcsclite_LIBS = @pcsclite_LIBS@
-pdfdir = @pdfdir@
-piddir = @piddir@
-pkgpyexecdir = @pkgpyexecdir@
-pkgpythondir = @pkgpythondir@
-pki_plugins = @pki_plugins@
-plugindir = @plugindir@
-pool_plugins = @pool_plugins@
-prefix = @prefix@
-program_transform_name = @program_transform_name@
-psdir = @psdir@
-pyexecdir = @pyexecdir@
-pythondir = @pythondir@
-random_device = @random_device@
-resolv_conf = @resolv_conf@
-routing_table = @routing_table@
-routing_table_prio = @routing_table_prio@
-s_plugins = @s_plugins@
-sbindir = @sbindir@
-scepclient_plugins = @scepclient_plugins@
-scripts_plugins = @scripts_plugins@
-sharedstatedir = @sharedstatedir@
-soup_CFLAGS = @soup_CFLAGS@
-soup_LIBS = @soup_LIBS@
-srcdir = @srcdir@
-starter_plugins = @starter_plugins@
-strongswan_conf = @strongswan_conf@
-strongswan_options = @strongswan_options@
-swanctldir = @swanctldir@
-sysconfdir = @sysconfdir@
-systemd_daemon_CFLAGS = @systemd_daemon_CFLAGS@
-systemd_daemon_LIBS = @systemd_daemon_LIBS@
-systemd_journal_CFLAGS = @systemd_journal_CFLAGS@
-systemd_journal_LIBS = @systemd_journal_LIBS@
-systemdsystemunitdir = @systemdsystemunitdir@
-t_plugins = @t_plugins@
-target_alias = @target_alias@
-top_build_prefix = @top_build_prefix@
-top_builddir = @top_builddir@
-top_srcdir = @top_srcdir@
-urandom_device = @urandom_device@
-xml_CFLAGS = @xml_CFLAGS@
-xml_LIBS = @xml_LIBS@
-AM_CPPFLAGS = \
-	-I$(top_srcdir)/src/libstrongswan \
-	-I$(top_srcdir)/src/libhydra \
-	-I$(top_srcdir)/src/libcharon
-
-AM_CFLAGS = \
-	$(PLUGIN_CFLAGS)
-
- at MONOLITHIC_TRUE@noinst_LTLIBRARIES = libstrongswan-unit-tester.la
- at MONOLITHIC_FALSE@plugin_LTLIBRARIES = libstrongswan-unit-tester.la
-libstrongswan_unit_tester_la_SOURCES = \
-	unit_tester.c unit_tester.h tests.h \
-	tests/test_auth_info.c \
-	tests/test_curl.c \
-	tests/test_mysql.c \
-	tests/test_sqlite.c \
-	tests/test_cert.c \
-	tests/test_med_db.c \
-	tests/test_pool.c \
-	tests/test_agent.c
-
-libstrongswan_unit_tester_la_LDFLAGS = -module -avoid-version
-all: all-am
-
-.SUFFIXES:
-.SUFFIXES: .c .lo .o .obj
-$(srcdir)/Makefile.in:  $(srcdir)/Makefile.am  $(am__configure_deps)
-	@for dep in $?; do \
-	  case '$(am__configure_deps)' in \
-	    *$$dep*) \
-	      ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
-	        && { if test -f $@; then exit 0; else break; fi; }; \
-	      exit 1;; \
-	  esac; \
-	done; \
-	echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/libcharon/plugins/unit_tester/Makefile'; \
-	$(am__cd) $(top_srcdir) && \
-	  $(AUTOMAKE) --gnu src/libcharon/plugins/unit_tester/Makefile
-.PRECIOUS: Makefile
-Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
-	@case '$?' in \
-	  *config.status*) \
-	    cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
-	  *) \
-	    echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
-	    cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
-	esac;
-
-$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
-	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
-
-$(top_srcdir)/configure:  $(am__configure_deps)
-	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
-$(ACLOCAL_M4):  $(am__aclocal_m4_deps)
-	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
-$(am__aclocal_m4_deps):
-
-clean-noinstLTLIBRARIES:
-	-test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES)
-	@list='$(noinst_LTLIBRARIES)'; \
-	locs=`for p in $$list; do echo $$p; done | \
-	      sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \
-	      sort -u`; \
-	test -z "$$locs" || { \
-	  echo rm -f $${locs}; \
-	  rm -f $${locs}; \
-	}
-
-install-pluginLTLIBRARIES: $(plugin_LTLIBRARIES)
-	@$(NORMAL_INSTALL)
-	@list='$(plugin_LTLIBRARIES)'; test -n "$(plugindir)" || list=; \
-	list2=; for p in $$list; do \
-	  if test -f $$p; then \
-	    list2="$$list2 $$p"; \
-	  else :; fi; \
-	done; \
-	test -z "$$list2" || { \
-	  echo " $(MKDIR_P) '$(DESTDIR)$(plugindir)'"; \
-	  $(MKDIR_P) "$(DESTDIR)$(plugindir)" || exit 1; \
-	  echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(plugindir)'"; \
-	  $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(plugindir)"; \
-	}
-
-uninstall-pluginLTLIBRARIES:
-	@$(NORMAL_UNINSTALL)
-	@list='$(plugin_LTLIBRARIES)'; test -n "$(plugindir)" || list=; \
-	for p in $$list; do \
-	  $(am__strip_dir) \
-	  echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(plugindir)/$$f'"; \
-	  $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(plugindir)/$$f"; \
-	done
-
-clean-pluginLTLIBRARIES:
-	-test -z "$(plugin_LTLIBRARIES)" || rm -f $(plugin_LTLIBRARIES)
-	@list='$(plugin_LTLIBRARIES)'; \
-	locs=`for p in $$list; do echo $$p; done | \
-	      sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \
-	      sort -u`; \
-	test -z "$$locs" || { \
-	  echo rm -f $${locs}; \
-	  rm -f $${locs}; \
-	}
-tests/$(am__dirstamp):
-	@$(MKDIR_P) tests
-	@: > tests/$(am__dirstamp)
-tests/$(DEPDIR)/$(am__dirstamp):
-	@$(MKDIR_P) tests/$(DEPDIR)
-	@: > tests/$(DEPDIR)/$(am__dirstamp)
-tests/test_auth_info.lo: tests/$(am__dirstamp) \
-	tests/$(DEPDIR)/$(am__dirstamp)
-tests/test_curl.lo: tests/$(am__dirstamp) \
-	tests/$(DEPDIR)/$(am__dirstamp)
-tests/test_mysql.lo: tests/$(am__dirstamp) \
-	tests/$(DEPDIR)/$(am__dirstamp)
-tests/test_sqlite.lo: tests/$(am__dirstamp) \
-	tests/$(DEPDIR)/$(am__dirstamp)
-tests/test_cert.lo: tests/$(am__dirstamp) \
-	tests/$(DEPDIR)/$(am__dirstamp)
-tests/test_med_db.lo: tests/$(am__dirstamp) \
-	tests/$(DEPDIR)/$(am__dirstamp)
-tests/test_pool.lo: tests/$(am__dirstamp) \
-	tests/$(DEPDIR)/$(am__dirstamp)
-tests/test_agent.lo: tests/$(am__dirstamp) \
-	tests/$(DEPDIR)/$(am__dirstamp)
-
-libstrongswan-unit-tester.la: $(libstrongswan_unit_tester_la_OBJECTS) $(libstrongswan_unit_tester_la_DEPENDENCIES) $(EXTRA_libstrongswan_unit_tester_la_DEPENDENCIES) 
-	$(AM_V_CCLD)$(libstrongswan_unit_tester_la_LINK) $(am_libstrongswan_unit_tester_la_rpath) $(libstrongswan_unit_tester_la_OBJECTS) $(libstrongswan_unit_tester_la_LIBADD) $(LIBS)
-
-mostlyclean-compile:
-	-rm -f *.$(OBJEXT)
-	-rm -f tests/*.$(OBJEXT)
-	-rm -f tests/*.lo
-
-distclean-compile:
-	-rm -f *.tab.c
-
- at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/unit_tester.Plo at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at tests/$(DEPDIR)/test_agent.Plo at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at tests/$(DEPDIR)/test_auth_info.Plo at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at tests/$(DEPDIR)/test_cert.Plo at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at tests/$(DEPDIR)/test_curl.Plo at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at tests/$(DEPDIR)/test_med_db.Plo at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at tests/$(DEPDIR)/test_mysql.Plo at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at tests/$(DEPDIR)/test_pool.Plo at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at tests/$(DEPDIR)/test_sqlite.Plo at am__quote@
-
-.c.o:
- at am__fastdepCC_TRUE@	$(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\
- at am__fastdepCC_TRUE@	$(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\
- at am__fastdepCC_TRUE@	$(am__mv) $$depbase.Tpo $$depbase.Po
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(COMPILE) -c -o $@ $<
-
-.c.obj:
- at am__fastdepCC_TRUE@	$(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\
- at am__fastdepCC_TRUE@	$(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\
- at am__fastdepCC_TRUE@	$(am__mv) $$depbase.Tpo $$depbase.Po
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
-
-.c.lo:
- at am__fastdepCC_TRUE@	$(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\
- at am__fastdepCC_TRUE@	$(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\
- at am__fastdepCC_TRUE@	$(am__mv) $$depbase.Tpo $$depbase.Plo
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(LTCOMPILE) -c -o $@ $<
-
-mostlyclean-libtool:
-	-rm -f *.lo
-
-clean-libtool:
-	-rm -rf .libs _libs
-	-rm -rf tests/.libs tests/_libs
-
-ID: $(am__tagged_files)
-	$(am__define_uniq_tagged_files); mkid -fID $$unique
-tags: tags-am
-TAGS: tags
-
-tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
-	set x; \
-	here=`pwd`; \
-	$(am__define_uniq_tagged_files); \
-	shift; \
-	if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
-	  test -n "$$unique" || unique=$$empty_fix; \
-	  if test $$# -gt 0; then \
-	    $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
-	      "$$@" $$unique; \
-	  else \
-	    $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
-	      $$unique; \
-	  fi; \
-	fi
-ctags: ctags-am
-
-CTAGS: ctags
-ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
-	$(am__define_uniq_tagged_files); \
-	test -z "$(CTAGS_ARGS)$$unique" \
-	  || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
-	     $$unique
-
-GTAGS:
-	here=`$(am__cd) $(top_builddir) && pwd` \
-	  && $(am__cd) $(top_srcdir) \
-	  && gtags -i $(GTAGS_ARGS) "$$here"
-cscopelist: cscopelist-am
-
-cscopelist-am: $(am__tagged_files)
-	list='$(am__tagged_files)'; \
-	case "$(srcdir)" in \
-	  [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
-	  *) sdir=$(subdir)/$(srcdir) ;; \
-	esac; \
-	for i in $$list; do \
-	  if test -f "$$i"; then \
-	    echo "$(subdir)/$$i"; \
-	  else \
-	    echo "$$sdir/$$i"; \
-	  fi; \
-	done >> $(top_builddir)/cscope.files
-
-distclean-tags:
-	-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
-
-distdir: $(DISTFILES)
-	@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
-	topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
-	list='$(DISTFILES)'; \
-	  dist_files=`for file in $$list; do echo $$file; done | \
-	  sed -e "s|^$$srcdirstrip/||;t" \
-	      -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
-	case $$dist_files in \
-	  */*) $(MKDIR_P) `echo "$$dist_files" | \
-			   sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
-			   sort -u` ;; \
-	esac; \
-	for file in $$dist_files; do \
-	  if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
-	  if test -d $$d/$$file; then \
-	    dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
-	    if test -d "$(distdir)/$$file"; then \
-	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
-	    fi; \
-	    if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
-	      cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
-	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
-	    fi; \
-	    cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
-	  else \
-	    test -f "$(distdir)/$$file" \
-	    || cp -p $$d/$$file "$(distdir)/$$file" \
-	    || exit 1; \
-	  fi; \
-	done
-check-am: all-am
-check: check-am
-all-am: Makefile $(LTLIBRARIES)
-installdirs:
-	for dir in "$(DESTDIR)$(plugindir)"; do \
-	  test -z "$$dir" || $(MKDIR_P) "$$dir"; \
-	done
-install: install-am
-install-exec: install-exec-am
-install-data: install-data-am
-uninstall: uninstall-am
-
-install-am: all-am
-	@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
-
-installcheck: installcheck-am
-install-strip:
-	if test -z '$(STRIP)'; then \
-	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
-	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
-	      install; \
-	else \
-	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
-	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
-	    "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
-	fi
-mostlyclean-generic:
-
-clean-generic:
-
-distclean-generic:
-	-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
-	-test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
-	-rm -f tests/$(DEPDIR)/$(am__dirstamp)
-	-rm -f tests/$(am__dirstamp)
-
-maintainer-clean-generic:
-	@echo "This command is intended for maintainers to use"
-	@echo "it deletes files that may require special tools to rebuild."
-clean: clean-am
-
-clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \
-	clean-pluginLTLIBRARIES mostlyclean-am
-
-distclean: distclean-am
-	-rm -rf ./$(DEPDIR) tests/$(DEPDIR)
-	-rm -f Makefile
-distclean-am: clean-am distclean-compile distclean-generic \
-	distclean-tags
-
-dvi: dvi-am
-
-dvi-am:
-
-html: html-am
-
-html-am:
-
-info: info-am
-
-info-am:
-
-install-data-am: install-pluginLTLIBRARIES
-
-install-dvi: install-dvi-am
-
-install-dvi-am:
-
-install-exec-am:
-
-install-html: install-html-am
-
-install-html-am:
-
-install-info: install-info-am
-
-install-info-am:
-
-install-man:
-
-install-pdf: install-pdf-am
-
-install-pdf-am:
-
-install-ps: install-ps-am
-
-install-ps-am:
-
-installcheck-am:
-
-maintainer-clean: maintainer-clean-am
-	-rm -rf ./$(DEPDIR) tests/$(DEPDIR)
-	-rm -f Makefile
-maintainer-clean-am: distclean-am maintainer-clean-generic
-
-mostlyclean: mostlyclean-am
-
-mostlyclean-am: mostlyclean-compile mostlyclean-generic \
-	mostlyclean-libtool
-
-pdf: pdf-am
-
-pdf-am:
-
-ps: ps-am
-
-ps-am:
-
-uninstall-am: uninstall-pluginLTLIBRARIES
-
-.MAKE: install-am install-strip
-
-.PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \
-	clean-libtool clean-noinstLTLIBRARIES clean-pluginLTLIBRARIES \
-	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-man install-pdf \
-	install-pdf-am install-pluginLTLIBRARIES install-ps \
-	install-ps-am install-strip installcheck installcheck-am \
-	installdirs maintainer-clean maintainer-clean-generic \
-	mostlyclean mostlyclean-compile mostlyclean-generic \
-	mostlyclean-libtool pdf pdf-am ps ps-am tags tags-am uninstall \
-	uninstall-am uninstall-pluginLTLIBRARIES
-
-
-# Tell versions [3.59,3.63) of GNU make to not export all variables.
-# Otherwise a system limit (for SysV at least) may be exceeded.
-.NOEXPORT:
diff --git a/src/libcharon/plugins/unit_tester/tests.h b/src/libcharon/plugins/unit_tester/tests.h
deleted file mode 100644
index 169292e..0000000
--- a/src/libcharon/plugins/unit_tester/tests.h
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * Copyright (C) 2007 Martin Willi
- * Hochschule fuer Technik Rapperswil
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * for more details.
- */
-
-/**
- * @defgroup tests tests
- * @{ @ingroup unit_tester
- */
-
-DEFINE_TEST("auth cfg", test_auth_cfg, FALSE)
-DEFINE_TEST("CURL get", test_curl_get, FALSE)
-DEFINE_TEST("MySQL operations", test_mysql, FALSE)
-DEFINE_TEST("SQLite operations", test_sqlite, FALSE)
-DEFINE_TEST("X509 certificate", test_cert_x509, FALSE)
-DEFINE_TEST("Mediation database key fetch", test_med_db, FALSE)
-DEFINE_TEST("IP pool", test_pool, FALSE)
-DEFINE_TEST("SSH agent", test_agent, FALSE)
-
-/** @}*/
diff --git a/src/libcharon/plugins/unit_tester/tests/test_agent.c b/src/libcharon/plugins/unit_tester/tests/test_agent.c
deleted file mode 100644
index baab629..0000000
--- a/src/libcharon/plugins/unit_tester/tests/test_agent.c
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * Copyright (C) 2008 Martin Willi
- * Hochschule fuer Technik Rapperswil
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * for more details.
- */
-
-#include <library.h>
-#include <daemon.h>
-
-/*******************************************************************************
- * SSH agent signature creation and verification
- ******************************************************************************/
-bool test_agent()
-{
-	char *path;
-	chunk_t sig, data = chunk_from_chars(0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08);
-	private_key_t *private;
-	public_key_t *public;
-
-	path = getenv("SSH_AUTH_SOCK");
-	if (!path)
-	{
-		DBG1(DBG_CFG, "ssh-agent not found.");
-		return FALSE;
-	}
-
-	private = lib->creds->create(lib->creds, CRED_PRIVATE_KEY, KEY_RSA,
-								 BUILD_AGENT_SOCKET, path, BUILD_END);
-	if (!private)
-	{
-		return FALSE;
-	}
-	if (!private->sign(private, SIGN_RSA_EMSA_PKCS1_SHA1, data, &sig))
-	{
-		return FALSE;
-	}
-	public = private->get_public_key(private);
-	if (!public)
-	{
-		return FALSE;;
-	}
-	if (!public->verify(public, SIGN_RSA_EMSA_PKCS1_SHA1, data, sig))
-	{
-		return FALSE;
-	}
-	free(sig.ptr);
-	data.ptr[1] = 0x01; /* fake it */
-	if (public->verify(public, SIGN_RSA_EMSA_PKCS1_SHA1, data, sig))
-	{
-		return FALSE;
-	}
-
-	private->destroy(private);
-	public->destroy(public);
-
-	return TRUE;
-}
-
diff --git a/src/libcharon/plugins/unit_tester/tests/test_auth_info.c b/src/libcharon/plugins/unit_tester/tests/test_auth_info.c
deleted file mode 100644
index c250c35..0000000
--- a/src/libcharon/plugins/unit_tester/tests/test_auth_info.c
+++ /dev/null
@@ -1,140 +0,0 @@
-/*
- * Copyright (C) 2007 Martin Willi
- * Hochschule fuer Technik Rapperswil
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * for more details.
- */
-
-#include <daemon.h>
-#include <library.h>
-#include <credentials/auth_cfg.h>
-
-
-static chunk_t certchunk = chunk_from_chars(
-	0x30,0x82,0x02,0xfa,0x30,0x82,0x01,0xe2,0xa0,0x03,0x02,0x01,0x02,0x02,0x10,0x5a,
-	0xf2,0x65,0xae,0x78,0xff,0x23,0xde,0xf7,0xa6,0xa3,0x94,0x8c,0x3f,0xa0,0xc1,0x30,
-	0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x05,0x05,0x00,0x30,0x39,
-	0x31,0x0b,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x43,0x48,0x31,0x19,0x30,
-	0x17,0x06,0x03,0x55,0x04,0x0a,0x13,0x10,0x4c,0x69,0x6e,0x75,0x78,0x20,0x73,0x74,
-	0x72,0x6f,0x6e,0x67,0x53,0x77,0x61,0x6e,0x31,0x0f,0x30,0x0d,0x06,0x03,0x55,0x04,
-	0x03,0x13,0x06,0x6d,0x61,0x72,0x74,0x69,0x6e,0x30,0x1e,0x17,0x0d,0x30,0x37,0x30,
-	0x34,0x32,0x37,0x30,0x37,0x31,0x34,0x32,0x36,0x5a,0x17,0x0d,0x31,0x32,0x30,0x34,
-	0x32,0x35,0x30,0x37,0x31,0x34,0x32,0x36,0x5a,0x30,0x39,0x31,0x0b,0x30,0x09,0x06,
-	0x03,0x55,0x04,0x06,0x13,0x02,0x43,0x48,0x31,0x19,0x30,0x17,0x06,0x03,0x55,0x04,
-	0x0a,0x13,0x10,0x4c,0x69,0x6e,0x75,0x78,0x20,0x73,0x74,0x72,0x6f,0x6e,0x67,0x53,
-	0x77,0x61,0x6e,0x31,0x0f,0x30,0x0d,0x06,0x03,0x55,0x04,0x03,0x13,0x06,0x6d,0x61,
-	0x72,0x74,0x69,0x6e,0x30,0x82,0x01,0x22,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,
-	0xf7,0x0d,0x01,0x01,0x01,0x05,0x00,0x03,0x82,0x01,0x0f,0x00,0x30,0x82,0x01,0x0a,
-	0x02,0x82,0x01,0x01,0x00,0xd7,0xb9,0xba,0x4d,0xe2,0x3b,0x3d,0x35,0x7a,0x3f,0x88,
-	0x67,0x95,0xe7,0xfd,0x9f,0xe9,0x0a,0x0d,0x79,0x3a,0x9e,0x21,0x8f,0xcb,0xe4,0x67,
-	0x24,0xae,0x0c,0xda,0xb3,0xcc,0xec,0x36,0xb4,0xa8,0x4d,0xf1,0x3d,0xad,0xe4,0x8c,
-	0x63,0x92,0x54,0xb7,0xb2,0x02,0xa2,0x00,0x62,0x8b,0x04,0xac,0xa0,0x17,0xad,0x17,
-	0x9a,0x05,0x0d,0xd7,0xb3,0x08,0x02,0xc5,0x26,0xcf,0xdd,0x05,0x42,0xfc,0x13,0x6d,
-	0x9f,0xb1,0xf3,0x4f,0x82,0x1d,0xef,0x01,0xc9,0x91,0xea,0x37,0x1b,0x79,0x28,0xfa,
-	0xbf,0x9f,0xb3,0xeb,0x82,0x4f,0x10,0xc6,0x4b,0xa4,0x08,0xf7,0x8e,0xf2,0x00,0xea,
-	0x04,0x97,0x80,0x9f,0x65,0x86,0xde,0x6b,0xc7,0xda,0x83,0xfc,0xad,0x4a,0xaf,0x52,
-	0x8b,0x4d,0x33,0xee,0x49,0x87,0x2f,0x3b,0x60,0x45,0x66,0x8f,0xe6,0x89,0xcc,0xb1,
-	0x92,0x02,0x17,0x2b,0x7b,0x8e,0x90,0x47,0x84,0x84,0x59,0x95,0x81,0xd8,0xe0,0xf3,
-	0x87,0xe0,0x04,0x09,0xfd,0xcc,0x3a,0x21,0x34,0xfa,0xec,0xbe,0xf5,0x9c,0xcf,0x55,
-	0x80,0x7b,0xe3,0x75,0x9d,0x36,0x68,0xab,0x83,0xe3,0xad,0x01,0x53,0x0d,0x8a,0x9a,
-	0xa6,0xb0,0x15,0xc9,0xc5,0xf8,0x9b,0x51,0x32,0xcf,0x97,0x6c,0xfe,0x4a,0x56,0x3c,
-	0xc8,0x8f,0x4a,0x70,0x23,0x4f,0xf6,0xf7,0xe6,0x9f,0x09,0xcd,0x8f,0xea,0x20,0x7d,
-	0x34,0xc0,0xc5,0xc0,0x34,0x06,0x6f,0x8b,0xeb,0x04,0x54,0x3f,0x0e,0xcd,0xe2,0x85,
-	0xab,0x94,0x3e,0x91,0x6c,0x18,0x6f,0x96,0x5d,0xf2,0x8b,0x10,0xe9,0x90,0x43,0xb0,
-	0x61,0x52,0xac,0xcf,0x75,0x02,0x03,0x01,0x00,0x01,0x30,0x0d,0x06,0x09,0x2a,0x86,
-	0x48,0x86,0xf7,0x0d,0x01,0x01,0x05,0x05,0x00,0x03,0x82,0x01,0x01,0x00,0x09,0x63,
-	0x42,0xad,0xe5,0xa3,0xf6,0xc9,0x5d,0x08,0xf2,0x78,0x7b,0xeb,0x8a,0xef,0x50,0x00,
-	0xc8,0xeb,0xe9,0x26,0x94,0xcb,0x84,0x10,0x7e,0x42,0x6b,0x86,0x38,0x57,0xa6,0x02,
-	0x98,0x5a,0x2c,0x8f,0x44,0x32,0x1b,0x97,0x8c,0x7e,0x4b,0xd8,0xe8,0xe8,0x0f,0x4a,
-	0xb9,0x31,0x9f,0xf6,0x9f,0x0e,0x67,0x26,0x05,0x2a,0x99,0x14,0x35,0x41,0x47,0x9a,
-	0xfa,0x12,0x94,0x0b,0xe9,0x27,0x7c,0x71,0x20,0xd7,0x8d,0x3b,0x97,0x19,0x2d,0x15,
-	0xff,0xa4,0xf3,0x89,0x8d,0x29,0x5f,0xf6,0x3f,0x93,0xaf,0x78,0x61,0xe4,0xe1,0x2e,
-	0x75,0xc1,0x2c,0xc4,0x76,0x95,0x19,0xf8,0x37,0xdc,0xd8,0x00,0x7a,0x3c,0x0f,0x49,
-	0x2e,0x88,0x09,0x16,0xb3,0x92,0x33,0xdf,0x77,0x83,0x4f,0xb5,0x9e,0x30,0x8c,0x48,
-	0x1d,0xd8,0x84,0xfb,0xf1,0xb9,0xa0,0xbe,0x25,0xff,0x4c,0xeb,0xef,0x2b,0xcd,0xfa,
-	0x0b,0x94,0x66,0x3b,0x28,0x08,0x3f,0x3a,0xda,0x41,0xd0,0x6b,0xab,0x5e,0xbb,0x8a,
-	0x9f,0xdc,0x98,0x3e,0x59,0x37,0x48,0xbe,0x69,0xde,0x85,0x82,0xf2,0x53,0x8b,0xe4,
-	0x44,0xe4,0x71,0x91,0x14,0x85,0x0e,0x1e,0x79,0xdd,0x62,0xf5,0xdc,0x25,0x89,0xab,
-	0x50,0x5b,0xaa,0xae,0xe3,0x64,0x6a,0x23,0x34,0xd7,0x30,0xe2,0x2a,0xc8,0x81,0x0c,
-	0xec,0xd2,0x31,0xc6,0x1e,0xb6,0xc0,0x57,0xd9,0xe1,0x14,0x06,0x9b,0xf8,0x51,0x69,
-	0x47,0xf0,0x9c,0xcd,0x69,0xef,0x8e,0x5f,0x62,0xda,0x10,0xf7,0x3c,0x6d,0x0f,0x33,
-	0xec,0x6f,0xfd,0x94,0x07,0x16,0x41,0x32,0x06,0xa4,0xe1,0x08,0x31,0x87,
-);
-
-/*******************************************************************************
- * auth info test
- ******************************************************************************/
-bool test_auth_cfg()
-{
-	auth_cfg_t *auth = auth_cfg_create(), *auth2;
-	certificate_t *c1, *c2;
-	enumerator_t *enumerator;
-	int round = 0;
-	void *value;
-	auth_rule_t type;
-
-	c1 = lib->creds->create(lib->creds, CRED_CERTIFICATE, CERT_X509,
-							BUILD_BLOB_ASN1_DER, certchunk,
-							BUILD_END);
-	if (!c1)
-	{
-		return FALSE;
-	}
-
-	auth->add(auth, AUTH_RULE_SUBJECT_CERT, c1->get_ref(c1));
-	c2 = auth->get(auth, AUTH_RULE_SUBJECT_CERT);
-	if (!c2)
-	{
-		return FALSE;
-	}
-	if (!c1->equals(c1, c2))
-	{
-		return FALSE;
-	}
-
-	enumerator = auth->create_enumerator(auth);
-	while (enumerator->enumerate(enumerator, &type, &value))
-	{
-		round++;
-		if (round == 1 && type == AUTH_RULE_SUBJECT_CERT && value == c1)
-		{
-			continue;
-		}
-		return FALSE;
-	}
-	enumerator->destroy(enumerator);
-
-	auth2 = auth_cfg_create();
-	auth2->add(auth2, AUTH_RULE_CA_CERT, c1->get_ref(c1));
-	auth2->merge(auth2, auth, FALSE);
-
-	round = 0;
-	enumerator = auth2->create_enumerator(auth2);
-	while (enumerator->enumerate(enumerator, &type, &value))
-	{
-		round++;
-		if (round == 1 && type == AUTH_RULE_CA_CERT && value == c1)
-		{
-			continue;
-		}
-		if (round == 2 && type == AUTH_RULE_SUBJECT_CERT && value == c1)
-		{
-			continue;
-		}
-		return FALSE;
-	}
-	enumerator->destroy(enumerator);
-	auth->destroy(auth);
-	auth2->destroy(auth2);
-	c1->destroy(c1);
-	return TRUE;
-}
-
diff --git a/src/libcharon/plugins/unit_tester/tests/test_cert.c b/src/libcharon/plugins/unit_tester/tests/test_cert.c
deleted file mode 100644
index f4410a6..0000000
--- a/src/libcharon/plugins/unit_tester/tests/test_cert.c
+++ /dev/null
@@ -1,108 +0,0 @@
-/*
- * Copyright (C) 2008 Martin Willi
- * Hochschule fuer Technik Rapperswil
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * for more details.
- */
-
-#include <library.h>
-#include <daemon.h>
-#include <credentials/certificates/x509.h>
-
-/*******************************************************************************
- * X509 certificate generation and parsing
- ******************************************************************************/
-bool test_cert_x509()
-{
-	private_key_t *ca_key, *peer_key;
-	public_key_t *public;
-	certificate_t *ca_cert, *peer_cert, *parsed;
-	identification_t *issuer, *subject;
-	u_int32_t serial = htonl(0);
-	chunk_t encoding;
-
-	issuer = identification_create_from_string("CN=CA, OU=Test, O=strongSwan");
-	subject = identification_create_from_string("CN=Peer, OU=Test, O=strongSwan");
-
-	ca_key = lib->creds->create(lib->creds, CRED_PRIVATE_KEY, KEY_RSA,
-						BUILD_KEY_SIZE, 1024, BUILD_END);
-	peer_key = lib->creds->create(lib->creds, CRED_PRIVATE_KEY, KEY_RSA,
-						BUILD_KEY_SIZE, 1024, BUILD_END);
-	if (!ca_key)
-	{
-		return FALSE;
-	}
-	ca_cert = lib->creds->create(lib->creds, CRED_CERTIFICATE, CERT_X509,
-						BUILD_SIGNING_KEY, ca_key,
-						BUILD_SUBJECT, issuer,
-						BUILD_SERIAL, chunk_from_thing(serial),
-						BUILD_X509_FLAG, X509_CA,
-						BUILD_END);
-	if (!ca_cert)
-	{
-		return FALSE;
-	}
-
-	ca_cert->get_encoding(ca_cert, CERT_ASN1_DER, &encoding);
-	parsed = lib->creds->create(lib->creds, CRED_CERTIFICATE, CERT_X509,
-						BUILD_BLOB_ASN1_DER, encoding,
-						BUILD_END);
-	chunk_free(&encoding);
-	if (!parsed)
-	{
-		return FALSE;
-	}
-	if (!parsed->issued_by(parsed, ca_cert, NULL))
-	{
-		return FALSE;
-	}
-	parsed->destroy(parsed);
-
-	serial = htonl(ntohl(serial) + 1);
-	public = peer_key->get_public_key(peer_key);
-	peer_cert = lib->creds->create(lib->creds, CRED_CERTIFICATE, CERT_X509,
-						BUILD_SIGNING_KEY, ca_key,
-						BUILD_SIGNING_CERT, ca_cert,
-						BUILD_PUBLIC_KEY, public,
-						BUILD_SUBJECT, subject,
-						BUILD_SERIAL, chunk_from_thing(serial),
-						BUILD_END);
-	public->destroy(public);
-	if (!peer_cert)
-	{
-		return FALSE;
-	}
-
-	peer_cert->get_encoding(peer_cert, CERT_ASN1_DER, &encoding);
-	parsed = lib->creds->create(lib->creds, CRED_CERTIFICATE, CERT_X509,
-						BUILD_BLOB_ASN1_DER, encoding,
-						BUILD_END);
-	chunk_free(&encoding);
-	if (!parsed)
-	{
-		return FALSE;
-	}
-	if (!parsed->issued_by(parsed, ca_cert, NULL))
-	{
-		return FALSE;
-	}
-	parsed->destroy(parsed);
-
-	ca_cert->destroy(ca_cert);
-	ca_key->destroy(ca_key);
-	peer_cert->destroy(peer_cert);
-	peer_key->destroy(peer_key);
-	issuer->destroy(issuer);
-	subject->destroy(subject);
-	return TRUE;
-}
-
-
diff --git a/src/libcharon/plugins/unit_tester/tests/test_curl.c b/src/libcharon/plugins/unit_tester/tests/test_curl.c
deleted file mode 100644
index 21656a9..0000000
--- a/src/libcharon/plugins/unit_tester/tests/test_curl.c
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * Copyright (C) 2007 Martin Willi
- * Hochschule fuer Technik Rapperswil
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * for more details.
- */
-
-#include <daemon.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <netdb.h>
-
-/*******************************************************************************
- * curl get test
- ******************************************************************************/
-
-bool test_curl_get()
-{
-	chunk_t chunk;
-
-	if (lib->fetcher->fetch(lib->fetcher, "http://www.strongswan.org",
-							&chunk, FETCH_END) != SUCCESS)
-	{
-		return FALSE;
-	}
-	free(chunk.ptr);
-
-	if (lib->fetcher->fetch(lib->fetcher, "http://www.google.com",
-							&chunk, FETCH_END) != SUCCESS)
-	{
-		return FALSE;
-	}
-	free(chunk.ptr);
-	return TRUE;
-}
-
diff --git a/src/libcharon/plugins/unit_tester/tests/test_med_db.c b/src/libcharon/plugins/unit_tester/tests/test_med_db.c
deleted file mode 100644
index 75244ab..0000000
--- a/src/libcharon/plugins/unit_tester/tests/test_med_db.c
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * Copyright (C) 2008 Martin Willi
- * Hochschule fuer Technik Rapperswil
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * for more details.
- */
-
-#include <library.h>
-#include <daemon.h>
-#include <collections/enumerator.h>
-
-#include <unistd.h>
-
-/*******************************************************************************
- * fetch public key from mediation database
- ******************************************************************************/
-
-bool test_med_db()
-{
-	chunk_t found, keyid = chunk_from_chars(
-		0xed,0x90,0xe6,0x4f,0xec,0xa2,0x1f,0x4b,
-		0x68,0x97,0x99,0x24,0x22,0xe0,0xde,0x21,
-		0xb9,0xd6,0x26,0x29
-	);
-	identification_t *id;
-	enumerator_t *enumerator;
-	public_key_t *public;
-	auth_cfg_t *auth;
-	bool good = FALSE;
-
-	id = identification_create_from_encoding(ID_KEY_ID, keyid);
-	enumerator = lib->credmgr->create_public_enumerator(lib->credmgr,
-														KEY_ANY, id, NULL);
-	while (enumerator->enumerate(enumerator, &public, &auth))
-	{
-		good = public->get_fingerprint(public, KEYID_PUBKEY_SHA1, &found);
-		if (good)
-		{
-			good = chunk_equals(id->get_encoding(id), found);
-		}
-	}
-	enumerator->destroy(enumerator);
-	id->destroy(id);
-	return good;
-}
-
diff --git a/src/libcharon/plugins/unit_tester/tests/test_mysql.c b/src/libcharon/plugins/unit_tester/tests/test_mysql.c
deleted file mode 100644
index eda2386..0000000
--- a/src/libcharon/plugins/unit_tester/tests/test_mysql.c
+++ /dev/null
@@ -1,89 +0,0 @@
-/*
- * Copyright (C) 2008 Martin Willi
- * Hochschule fuer Technik Rapperswil
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * for more details.
- */
-
-#include <library.h>
-#include <daemon.h>
-#include <collections/enumerator.h>
-
-/*******************************************************************************
- * mysql simple test
- ******************************************************************************/
-bool test_mysql()
-{
-	database_t *db;
-	char *txt = "I'm a superduper test";
-	chunk_t data = chunk_from_chars(0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08);
-	int row;
-	chunk_t qdata;
-	char *qtxt;
-	bool good = FALSE;
-	enumerator_t *enumerator;
-
-	db = lib->db->create(lib->db, "mysql://testuser:testpass@localhost/test");
-	if (!db)
-	{
-		return FALSE;
-	}
-	if (db->execute(db, NULL, "CREATE TABLE test ("
-								"id INT NOT NULL AUTO_INCREMENT PRIMARY KEY, "
-								"txt TEXT, data BLOB)") < 0)
-	{
-		return FALSE;
-	}
-	if (db->execute(db, &row, "INSERT INTO test (txt, data) VALUES (?,?)",
-					DB_TEXT, txt, DB_BLOB, data) < 0)
-	{
-		return FALSE;
-	}
-	if (row != 1)
-	{
-		return FALSE;
-	}
-	enumerator = db->query(db, "SELECT txt, data FROM test WHERE id = ?",
-						   DB_INT, row,
-						   DB_TEXT, DB_BLOB);
-	if (!enumerator)
-	{
-		return FALSE;
-	}
-	while (enumerator->enumerate(enumerator, &qtxt, &qdata))
-	{
-		if (good)
-		{	/* only one row */
-			good = FALSE;
-			break;
-		}
-		if (streq(qtxt, txt) && chunk_equals(data, qdata))
-		{
-			good = TRUE;
-		}
-	}
-	enumerator->destroy(enumerator);
-	if (!good)
-	{
-		return FALSE;
-	}
-	if (db->execute(db, NULL, "DELETE FROM test WHERE id = ?", DB_INT, row) != 1)
-	{
-		return FALSE;
-	}
-	if (db->execute(db, NULL, "DROP TABLE test") < 0)
-	{
-		return FALSE;
-	}
-	db->destroy(db);
-	return TRUE;
-}
-
diff --git a/src/libcharon/plugins/unit_tester/tests/test_pool.c b/src/libcharon/plugins/unit_tester/tests/test_pool.c
deleted file mode 100644
index f36953f..0000000
--- a/src/libcharon/plugins/unit_tester/tests/test_pool.c
+++ /dev/null
@@ -1,100 +0,0 @@
-/*
- * Copyright (C) 2008 Martin Willi
- * Hochschule fuer Technik Rapperswil
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * for more details.
- */
-
-#include <time.h>
-
-#include <library.h>
-#include <threading/thread.h>
-#include <hydra.h>
-
-#define ALLOCS 1000
-#define THREADS 20
-
-static void* testing(void *thread)
-{
-	int i;
-	host_t *addr[ALLOCS];
-	identification_t *id[ALLOCS];
-	linked_list_t *pools;
-
-	/* prepare identities */
-	for (i = 0; i < ALLOCS; i++)
-	{
-		char buf[256];
-
-		snprintf(buf, sizeof(buf), "%d-%d at strongswan.org", (uintptr_t)thread, i);
-		id[i] = identification_create_from_string(buf);
-	}
-
-	pools = linked_list_create();
-	pools->insert_last(pools, "test");
-
-	/* allocate addresses */
-	for (i = 0; i < ALLOCS; i++)
-	{
-		addr[i] = hydra->attributes->acquire_address(hydra->attributes,
-													 pools, id[i], NULL);
-		if (!addr[i])
-		{
-			pools->destroy(pools);
-			return (void*)FALSE;
-		}
-	}
-
-	/* release addresses */
-	for (i = 0; i < ALLOCS; i++)
-	{
-		hydra->attributes->release_address(hydra->attributes,
-										   pools, addr[i], id[i]);
-	}
-
-	pools->destroy(pools);
-
-	/* cleanup */
-	for (i = 0; i < ALLOCS; i++)
-	{
-		addr[i]->destroy(addr[i]);
-		id[i]->destroy(id[i]);
-	}
-	return (void*)TRUE;
-}
-
-
-/*******************************************************************************
- * SQL pool performance test
- ******************************************************************************/
-bool test_pool()
-{
-	thread_t *threads[THREADS];
-	uintptr_t i;
-
-	for (i = 0; i < THREADS; i++)
-	{
-		if (!(threads[i] = thread_create((thread_main_t)testing, (void*)i)))
-		{
-			return FALSE;
-		}
-	}
-	for (i = 0; i < THREADS; i++)
-	{
-		bool *res = threads[i]->join(threads[i]);
-		if (!res)
-		{
-			return FALSE;
-		}
-	}
-	return TRUE;
-}
-
diff --git a/src/libcharon/plugins/unit_tester/tests/test_sqlite.c b/src/libcharon/plugins/unit_tester/tests/test_sqlite.c
deleted file mode 100644
index 99490b5..0000000
--- a/src/libcharon/plugins/unit_tester/tests/test_sqlite.c
+++ /dev/null
@@ -1,93 +0,0 @@
-/*
- * Copyright (C) 2008 Martin Willi
- * Hochschule fuer Technik Rapperswil
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * for more details.
- */
-
-#include <library.h>
-#include <daemon.h>
-#include <collections/enumerator.h>
-
-#include <unistd.h>
-
-
-#define DBFILE "/tmp/strongswan-test.db"
-
-/*******************************************************************************
- * sqlite simple test
- ******************************************************************************/
-bool test_sqlite()
-{
-	database_t *db;
-	char *txt = "I'm a superduper test";
-	chunk_t data = chunk_from_chars(0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08);
-	int row;
-	chunk_t qdata;
-	char *qtxt;
-	bool good = FALSE;
-	enumerator_t *enumerator;
-
-	db = lib->db->create(lib->db, "sqlite://" DBFILE);
-	if (!db)
-	{
-		return FALSE;
-	}
-	if (db->execute(db, NULL, "CREATE TABLE test (txt TEXT, data BLOB)") < 0)
-	{
-		return FALSE;
-	}
-	if (db->execute(db, &row, "INSERT INTO test (txt, data) VALUES (?,?)",
-					DB_TEXT, txt, DB_BLOB, data) < 0)
-	{
-		return FALSE;
-	}
-	if (row != 1)
-	{
-		return FALSE;
-	}
-	enumerator = db->query(db, "SELECT txt, data FROM test WHERE oid = ?",
-						   DB_INT, row,
-						   DB_TEXT, DB_BLOB);
-	if (!enumerator)
-	{
-		return FALSE;
-	}
-	while (enumerator->enumerate(enumerator, &qtxt, &qdata))
-	{
-		if (good)
-		{	/* only one row */
-			good = FALSE;
-			break;
-		}
-		if (streq(qtxt, txt) && chunk_equals(data, qdata))
-		{
-			good = TRUE;
-		}
-	}
-	enumerator->destroy(enumerator);
-	if (!good)
-	{
-		return FALSE;
-	}
-	if (db->execute(db, NULL, "DELETE FROM test WHERE oid = ?", DB_INT, row) != 1)
-	{
-		return FALSE;
-	}
-	if (db->execute(db, NULL, "DROP TABLE test") < 0)
-	{
-		return FALSE;
-	}
-	db->destroy(db);
-	unlink(DBFILE);
-	return TRUE;
-}
-
diff --git a/src/libcharon/plugins/unit_tester/unit_tester.c b/src/libcharon/plugins/unit_tester/unit_tester.c
deleted file mode 100644
index ea7ffca..0000000
--- a/src/libcharon/plugins/unit_tester/unit_tester.c
+++ /dev/null
@@ -1,152 +0,0 @@
-/*
- * Copyright (C) 2013 Tobias Brunner
- * Copyright (C) 2007 Martin Willi
- * Hochschule fuer Technik Rapperswil
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * for more details.
- */
-
-#include "unit_tester.h"
-
-#include <daemon.h>
-
-typedef struct private_unit_tester_t private_unit_tester_t;
-typedef struct unit_test_t unit_test_t;
-typedef enum test_status_t test_status_t;
-
-/**
- * private data of unit_tester
- */
-struct private_unit_tester_t {
-
-	/**
-	 * public functions
-	 */
-	unit_tester_t public;
-};
-
-struct unit_test_t {
-
-	/**
-	 * name of the test
-	 */
-	char *name;
-
-	/**
-	 * test function
-	 */
-	bool (*test)(void);
-
-	/**
-	 * run the test?
-	 */
-	bool enabled;
-};
-
-#undef DEFINE_TEST
-#define DEFINE_TEST(name, function, enabled) bool function();
-#include <plugins/unit_tester/tests.h>
-#undef DEFINE_TEST
-#define DEFINE_TEST(name, function, enabled) {name, function, enabled},
-static unit_test_t tests[] = {
-#include <plugins/unit_tester/tests.h>
-};
-
-static void run_tests(private_unit_tester_t *this)
-{
-	int i, run = 0, failed = 0, success = 0, skipped = 0;
-
-	DBG1(DBG_CFG, "running unit tests, %d tests registered",
-		 sizeof(tests)/sizeof(unit_test_t));
-
-	for (i = 0; i < sizeof(tests)/sizeof(unit_test_t); i++)
-	{
-		if (tests[i].enabled)
-		{
-			run++;
-			if (tests[i].test())
-			{
-				DBG1(DBG_CFG, "test '%s' successful", tests[i].name);
-				success++;
-			}
-			else
-			{
-				DBG1(DBG_CFG, "test '%s' failed", tests[i].name);
-				failed++;
-			}
-		}
-		else
-		{
-			DBG1(DBG_CFG, "test '%s' disabled", tests[i].name);
-			skipped++;
-		}
-	}
-	DBG1(DBG_CFG, "%d/%d tests successful (%d failed, %d disabled)",
-		 success, run, failed, skipped);
-}
-
-METHOD(plugin_t, get_name, char*,
-	private_unit_tester_t *this)
-{
-	return "unit-tester";
-}
-
-/**
- * We currently don't depend explicitly on any plugin features.  But in case
- * activated tests depend on such features we at least try to run them in plugin
- * order.
- */
-static bool plugin_cb(private_unit_tester_t *this,
-					  plugin_feature_t *feature, bool reg, void *cb_data)
-{
-	if (reg)
-	{
-		run_tests(this);
-	}
-	return TRUE;
-}
-
-METHOD(plugin_t, get_features, int,
-	private_unit_tester_t *this, plugin_feature_t *features[])
-{
-	static plugin_feature_t f[] = {
-		PLUGIN_CALLBACK((plugin_feature_callback_t)plugin_cb, NULL),
-			PLUGIN_PROVIDE(CUSTOM, "unit-tester"),
-	};
-	*features = f;
-	return countof(f);
-}
-
-METHOD(plugin_t, destroy, void,
-	private_unit_tester_t *this)
-{
-	free(this);
-}
-
-/*
- * see header file
- */
-plugin_t *unit_tester_plugin_create()
-{
-	private_unit_tester_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/unit_tester/unit_tester.h b/src/libcharon/plugins/unit_tester/unit_tester.h
deleted file mode 100644
index 08784f6..0000000
--- a/src/libcharon/plugins/unit_tester/unit_tester.h
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * Copyright (C) 2007 Martin Willi
- * Hochschule fuer Technik Rapperswil
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * for more details.
- */
-
-/**
- * @defgroup unit_tester unit_tester
- * @{ @ingroup cplugins
- */
-
-#ifndef UNIT_TESTER_H_
-#define UNIT_TESTER_H_
-
-#include <plugins/plugin.h>
-
-typedef struct unit_tester_t unit_tester_t;
-
-/**
- * Unit testing plugin.
- *
- * The unit testing plugin runs tests on plugin initialization. Tests are
- * defined in tests.h using the DEFINE_TEST macro. Implementation of the
- * tests is done in the tests folder. Each test has uses a function which
- * returns TRUE for success or FALSE for failure.
- */
-struct unit_tester_t {
-
-	/**
-	 * Implements the plugin interface.
-	 */
-	plugin_t plugin;
-};
-
-#endif /** UNIT_TESTER_H_ @}*/
diff --git a/src/libcharon/plugins/unity/Makefile.in b/src/libcharon/plugins/unity/Makefile.in
index 1e04ebc..4f0a7e7 100644
--- a/src/libcharon/plugins/unity/Makefile.in
+++ b/src/libcharon/plugins/unity/Makefile.in
@@ -228,6 +228,7 @@ DLLIB = @DLLIB@
 DLLTOOL = @DLLTOOL@
 DSYMUTIL = @DSYMUTIL@
 DUMPBIN = @DUMPBIN@
+EASY_INSTALL = @EASY_INSTALL@
 ECHO_C = @ECHO_C@
 ECHO_N = @ECHO_N@
 ECHO_T = @ECHO_T@
@@ -288,10 +289,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
 PLUGIN_CFLAGS = @PLUGIN_CFLAGS@
 PTHREADLIB = @PTHREADLIB@
 PYTHON = @PYTHON@
+PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@
 PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
 PYTHON_PLATFORM = @PYTHON_PLATFORM@
 PYTHON_PREFIX = @PYTHON_PREFIX@
 PYTHON_VERSION = @PYTHON_VERSION@
+PY_TEST = @PY_TEST@
 RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
@@ -365,6 +368,8 @@ json_CFLAGS = @json_CFLAGS@
 json_LIBS = @json_LIBS@
 libdir = @libdir@
 libexecdir = @libexecdir@
+libiptc_CFLAGS = @libiptc_CFLAGS@
+libiptc_LIBS = @libiptc_LIBS@
 linux_headers = @linux_headers@
 localedir = @localedir@
 localstatedir = @localstatedir@
diff --git a/src/libcharon/plugins/unity/unity_handler.c b/src/libcharon/plugins/unity/unity_handler.c
index bcef0dc..9fc9be6 100644
--- a/src/libcharon/plugins/unity/unity_handler.c
+++ b/src/libcharon/plugins/unity/unity_handler.c
@@ -50,8 +50,8 @@ struct private_unity_handler_t {
  * Traffic selector entry for networks to include under a given IKE_SA
  */
 typedef struct {
-	/** associated IKE_SA, unique ID */
-	u_int32_t sa;
+	/** associated IKE_SA COOKIEs */
+	ike_sa_id_t *id;
 	/** traffic selector to include/exclude */
 	traffic_selector_t *ts;
 } entry_t;
@@ -61,6 +61,7 @@ typedef struct {
  */
 static void entry_destroy(entry_t *this)
 {
+	this->id->destroy(this->id);
 	this->ts->destroy(this->ts);
 	free(this);
 }
@@ -131,9 +132,10 @@ static bool add_include(private_unity_handler_t *this, chunk_t data)
 	while (list->remove_first(list, (void**)&ts) == SUCCESS)
 	{
 		INIT(entry,
-			.sa = ike_sa->get_unique_id(ike_sa),
+			.id = ike_sa->get_id(ike_sa),
 			.ts = ts,
 		);
+		entry->id = entry->id->clone(entry->id);
 
 		this->mutex->lock(this->mutex);
 		this->include->insert_last(this->include, entry);
@@ -171,7 +173,7 @@ static bool remove_include(private_unity_handler_t *this, chunk_t data)
 		enumerator = this->include->create_enumerator(this->include);
 		while (enumerator->enumerate(enumerator, &entry))
 		{
-			if (entry->sa == ike_sa->get_unique_id(ike_sa) &&
+			if (entry->id->equals(entry->id, ike_sa->get_id(ike_sa)) &&
 				ts->equals(ts, entry->ts))
 			{
 				this->include->remove_at(this->include, enumerator);
@@ -209,8 +211,7 @@ static job_requeue_t add_exclude_async(entry_t *entry)
 	char name[128];
 	host_t *host;
 
-	ike_sa = charon->ike_sa_manager->checkout_by_id(charon->ike_sa_manager,
-													entry->sa, FALSE);
+	ike_sa = charon->ike_sa_manager->checkout(charon->ike_sa_manager, entry->id);
 	if (ike_sa)
 	{
 		create_shunt_name(ike_sa, entry->ts, name, sizeof(name));
@@ -267,9 +268,10 @@ static bool add_exclude(private_unity_handler_t *this, chunk_t data)
 	while (list->remove_first(list, (void**)&ts) == SUCCESS)
 	{
 		INIT(entry,
-			.sa = ike_sa->get_unique_id(ike_sa),
+			.id = ike_sa->get_id(ike_sa),
 			.ts = ts,
 		);
+		entry->id = entry->id->clone(entry->id);
 
 		/* we can't install the shunt policy yet, as we don't know the virtual IP.
 		 * Defer installation using an async callback. */
@@ -315,7 +317,7 @@ static bool remove_exclude(private_unity_handler_t *this, chunk_t data)
 }
 
 METHOD(attribute_handler_t, handle, bool,
-	private_unity_handler_t *this, identification_t *id,
+	private_unity_handler_t *this, ike_sa_t *ike_sa,
 	configuration_attribute_type_t type, chunk_t data)
 {
 	switch (type)
@@ -330,7 +332,7 @@ METHOD(attribute_handler_t, handle, bool,
 }
 
 METHOD(attribute_handler_t, release, void,
-	private_unity_handler_t *this, identification_t *server,
+	private_unity_handler_t *this, ike_sa_t *ike_sa,
 	configuration_attribute_type_t type, chunk_t data)
 {
 	switch (type)
@@ -378,10 +380,9 @@ METHOD(enumerator_t, enumerate_attributes, bool,
 }
 
 METHOD(attribute_handler_t, create_attribute_enumerator, enumerator_t *,
-	unity_handler_t *this, identification_t *id, linked_list_t *vips)
+	unity_handler_t *this, ike_sa_t *ike_sa, linked_list_t *vips)
 {
 	attribute_enumerator_t *enumerator;
-	ike_sa_t *ike_sa;
 
 	ike_sa = charon->bus->get_sa(charon->bus);
 	if (!ike_sa || ike_sa->get_version(ike_sa) != IKEV1 ||
@@ -402,7 +403,7 @@ typedef struct {
 	/** mutex to unlock */
 	mutex_t *mutex;
 	/** IKE_SA ID to filter for */
-	u_int32_t id;
+	ike_sa_id_t *id;
 } include_filter_t;
 
 /**
@@ -411,7 +412,7 @@ typedef struct {
 static bool include_filter(include_filter_t *data,
 						   entry_t **entry, traffic_selector_t **ts)
 {
-	if ((*entry)->sa == data->id)
+	if (data->id->equals(data->id, (*entry)->id))
 	{
 		*ts = (*entry)->ts;
 		return TRUE;
@@ -429,7 +430,7 @@ static void destroy_filter(include_filter_t *data)
 }
 
 METHOD(unity_handler_t, create_include_enumerator, enumerator_t*,
-	private_unity_handler_t *this, u_int32_t id)
+	private_unity_handler_t *this, ike_sa_id_t *id)
 {
 	include_filter_t *data;
 
diff --git a/src/libcharon/plugins/unity/unity_handler.h b/src/libcharon/plugins/unity/unity_handler.h
index 8656fd3..18efe29 100644
--- a/src/libcharon/plugins/unity/unity_handler.h
+++ b/src/libcharon/plugins/unity/unity_handler.h
@@ -21,6 +21,7 @@
 #ifndef UNITY_HANDLER_H_
 #define UNITY_HANDLER_H_
 
+#include <sa/ike_sa_id.h>
 #include <attributes/attribute_handler.h>
 
 typedef struct unity_handler_t unity_handler_t;
@@ -38,11 +39,11 @@ struct unity_handler_t {
 	/**
 	 * Create an enumerator over Split-Include attributes received for an IKE_SA.
 	 *
-	 * @param id			IKE_SA unique ID to get Split-Includes for
+	 * @param id			IKE_SA ID to get Split-Includes for
 	 * @return				enumerator over traffic_selector_t*
 	 */
 	enumerator_t* (*create_include_enumerator)(unity_handler_t *this,
-											   u_int32_t id);
+											   ike_sa_id_t *id);
 
 	/**
 	 * Destroy a unity_handler_t.
diff --git a/src/libcharon/plugins/unity/unity_narrow.c b/src/libcharon/plugins/unity/unity_narrow.c
index 52a2c7f..227d24b 100644
--- a/src/libcharon/plugins/unity/unity_narrow.c
+++ b/src/libcharon/plugins/unity/unity_narrow.c
@@ -1,4 +1,7 @@
 /*
+ * Copyright (C) 2014 Tobias Brunner
+ * Hochschule fuer Technik Rapperswil
+ *
  * Copyright (C) 2012 Martin Willi
  * Copyright (C) 2012 revosec AG
  *
@@ -16,6 +19,8 @@
 #include "unity_narrow.h"
 
 #include <daemon.h>
+#include <encoding/payloads/id_payload.h>
+#include <collections/hashtable.h>
 
 typedef struct private_unity_narrow_t private_unity_narrow_t;
 
@@ -33,6 +38,11 @@ struct private_unity_narrow_t {
 	 * Unity attribute handler
 	 */
 	unity_handler_t *handler;
+
+	/**
+	 * IKE_SAs for which we received 0.0.0.0/0 as remote traffic selector
+	 */
+	hashtable_t *wildcard_ts;
 };
 
 /**
@@ -65,7 +75,7 @@ static void narrow_initiator(private_unity_narrow_t *this, ike_sa_t *ike_sa,
 	enumerator_t *enumerator;
 
 	enumerator = this->handler->create_include_enumerator(this->handler,
-											ike_sa->get_unique_id(ike_sa));
+											ike_sa->get_id(ike_sa));
 	while (enumerator->enumerate(enumerator, &current))
 	{
 		if (orig == NULL)
@@ -149,7 +159,7 @@ static bool has_split_includes(private_unity_narrow_t *this, ike_sa_t *ike_sa)
 	bool has;
 
 	enumerator = this->handler->create_include_enumerator(this->handler,
-												ike_sa->get_unique_id(ike_sa));
+												ike_sa->get_id(ike_sa));
 	has = enumerator->enumerate(enumerator, &ts);
 	enumerator->destroy(enumerator);
 
@@ -191,11 +201,19 @@ METHOD(listener_t, narrow, bool,
 			{
 				case NARROW_INITIATOR_PRE_AUTH:
 				case NARROW_RESPONDER:
-					narrow_pre(local, "us");
+					if (this->wildcard_ts->get(this->wildcard_ts, ike_sa))
+					{
+						narrow_pre(local, "us");
+
+					}
 					break;
 				case NARROW_INITIATOR_POST_AUTH:
 				case NARROW_RESPONDER_POST:
-					narrow_responder_post(child_sa->get_config(child_sa), local);
+					if (this->wildcard_ts->get(this->wildcard_ts, ike_sa))
+					{
+						narrow_responder_post(child_sa->get_config(child_sa),
+											  local);
+					}
 					break;
 				default:
 					break;
@@ -205,9 +223,69 @@ METHOD(listener_t, narrow, bool,
 	return TRUE;
 }
 
+METHOD(listener_t, message, bool,
+	private_unity_narrow_t *this, ike_sa_t *ike_sa, message_t *message,
+	bool incoming, bool plain)
+{
+	traffic_selector_t *tsr = NULL, *wildcard;
+	enumerator_t *enumerator;
+	id_payload_t *id_payload;
+	payload_t *payload;
+	bool first = TRUE;
+
+	if (!incoming || !plain ||
+		message->get_exchange_type(message) != QUICK_MODE ||
+		!ike_sa || !ike_sa->supports_extension(ike_sa, EXT_CISCO_UNITY))
+	{
+		return TRUE;
+	}
+	enumerator = message->create_payload_enumerator(message);
+	while (enumerator->enumerate(enumerator, &payload))
+	{
+		if (payload->get_type(payload) == PLV1_ID)
+		{
+			if (!first)
+			{
+				id_payload = (id_payload_t*)payload;
+				tsr = id_payload->get_ts(id_payload);
+				break;
+			}
+			first = FALSE;
+		}
+	}
+	enumerator->destroy(enumerator);
+	if (!tsr)
+	{
+		return TRUE;
+	}
+	wildcard = traffic_selector_create_from_cidr("0.0.0.0/0", 0, 0, 65535);
+	if (tsr->equals(tsr, wildcard))
+	{
+		this->wildcard_ts->put(this->wildcard_ts, ike_sa, ike_sa);
+	}
+	else
+	{
+		this->wildcard_ts->remove(this->wildcard_ts, ike_sa);
+	}
+	wildcard->destroy(wildcard);
+	tsr->destroy(tsr);
+	return TRUE;
+}
+
+METHOD(listener_t, ike_updown, bool,
+	private_unity_narrow_t *this, ike_sa_t *ike_sa, bool up)
+{
+	if (!up)
+	{
+		this->wildcard_ts->remove(this->wildcard_ts, ike_sa);
+	}
+	return TRUE;
+}
+
 METHOD(unity_narrow_t, destroy, void,
 	private_unity_narrow_t *this)
 {
+	this->wildcard_ts->destroy(this->wildcard_ts);
 	free(this);
 }
 
@@ -222,10 +300,14 @@ unity_narrow_t *unity_narrow_create(unity_handler_t *handler)
 		.public = {
 			.listener = {
 				.narrow = _narrow,
+				.message = _message,
+				.ike_updown = _ike_updown,
 			},
 			.destroy = _destroy,
 		},
 		.handler = handler,
+		.wildcard_ts = hashtable_create(hashtable_hash_ptr,
+										hashtable_equals_ptr, 4),
 	);
 
 	return &this->public;
diff --git a/src/libcharon/plugins/unity/unity_plugin.c b/src/libcharon/plugins/unity/unity_plugin.c
index 9e4571d..b7a3fee 100644
--- a/src/libcharon/plugins/unity/unity_plugin.c
+++ b/src/libcharon/plugins/unity/unity_plugin.c
@@ -19,7 +19,6 @@
 #include "unity_provider.h"
 
 #include <daemon.h>
-#include <hydra.h>
 
 typedef struct private_unity_plugin_t private_unity_plugin_t;
 
@@ -63,19 +62,19 @@ static bool plugin_cb(private_unity_plugin_t *this,
 {
 	if (reg)
 	{
-		hydra->attributes->add_handler(hydra->attributes,
-									   &this->handler->handler);
-		hydra->attributes->add_provider(hydra->attributes,
-										&this->provider->provider);
+		charon->attributes->add_handler(charon->attributes,
+										&this->handler->handler);
+		charon->attributes->add_provider(charon->attributes,
+										 &this->provider->provider);
 		charon->bus->add_listener(charon->bus, &this->narrower->listener);
 	}
 	else
 	{
 		charon->bus->remove_listener(charon->bus, &this->narrower->listener);
-		hydra->attributes->remove_handler(hydra->attributes,
-										  &this->handler->handler);
-		hydra->attributes->remove_provider(hydra->attributes,
-										   &this->provider->provider);
+		charon->attributes->remove_handler(charon->attributes,
+										   &this->handler->handler);
+		charon->attributes->remove_provider(charon->attributes,
+											&this->provider->provider);
 
 	}
 	return TRUE;
diff --git a/src/libcharon/plugins/unity/unity_provider.c b/src/libcharon/plugins/unity/unity_provider.c
index 86f81fc..1e297a3 100644
--- a/src/libcharon/plugins/unity/unity_provider.c
+++ b/src/libcharon/plugins/unity/unity_provider.c
@@ -135,19 +135,17 @@ static bool use_ts(traffic_selector_t *ts)
 }
 
 METHOD(attribute_provider_t, create_attribute_enumerator, enumerator_t*,
-	private_unity_provider_t *this, linked_list_t *pools, identification_t *id,
+	private_unity_provider_t *this, linked_list_t *pools, ike_sa_t *ike_sa,
 	linked_list_t *vips)
 {
 	attribute_enumerator_t *attr_enum;
 	enumerator_t *enumerator;
 	linked_list_t *list, *current;
 	traffic_selector_t *ts;
-	ike_sa_t *ike_sa;
 	peer_cfg_t *peer_cfg;
 	child_cfg_t *child_cfg;
 
-	ike_sa = charon->bus->get_sa(charon->bus);
-	if (!ike_sa || ike_sa->get_version(ike_sa) != IKEV1 ||
+	if (ike_sa->get_version(ike_sa) != IKEV1 ||
 		!ike_sa->supports_extension(ike_sa, EXT_CISCO_UNITY) ||
 		!vips->get_count(vips))
 	{
diff --git a/src/libcharon/plugins/updown/Makefile.in b/src/libcharon/plugins/updown/Makefile.in
index 834d373..619d17a 100644
--- a/src/libcharon/plugins/updown/Makefile.in
+++ b/src/libcharon/plugins/updown/Makefile.in
@@ -229,6 +229,7 @@ DLLIB = @DLLIB@
 DLLTOOL = @DLLTOOL@
 DSYMUTIL = @DSYMUTIL@
 DUMPBIN = @DUMPBIN@
+EASY_INSTALL = @EASY_INSTALL@
 ECHO_C = @ECHO_C@
 ECHO_N = @ECHO_N@
 ECHO_T = @ECHO_T@
@@ -289,10 +290,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
 PLUGIN_CFLAGS = @PLUGIN_CFLAGS@
 PTHREADLIB = @PTHREADLIB@
 PYTHON = @PYTHON@
+PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@
 PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
 PYTHON_PLATFORM = @PYTHON_PLATFORM@
 PYTHON_PREFIX = @PYTHON_PREFIX@
 PYTHON_VERSION = @PYTHON_VERSION@
+PY_TEST = @PY_TEST@
 RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
@@ -366,6 +369,8 @@ json_CFLAGS = @json_CFLAGS@
 json_LIBS = @json_LIBS@
 libdir = @libdir@
 libexecdir = @libexecdir@
+libiptc_CFLAGS = @libiptc_CFLAGS@
+libiptc_LIBS = @libiptc_LIBS@
 linux_headers = @linux_headers@
 localedir = @localedir@
 localstatedir = @localstatedir@
diff --git a/src/libcharon/plugins/updown/updown_handler.c b/src/libcharon/plugins/updown/updown_handler.c
index 0894d2d..72d7f7d 100644
--- a/src/libcharon/plugins/updown/updown_handler.c
+++ b/src/libcharon/plugins/updown/updown_handler.c
@@ -62,19 +62,13 @@ static void attributes_destroy(attributes_t *this)
 }
 
 METHOD(attribute_handler_t, handle, bool,
-	private_updown_handler_t *this, identification_t *server,
+	private_updown_handler_t *this, ike_sa_t *ike_sa,
 	configuration_attribute_type_t type, chunk_t data)
 {
 	attributes_t *current, *attr = NULL;
 	enumerator_t *enumerator;
-	ike_sa_t *ike_sa;
 	host_t *host;
 
-	ike_sa = charon->bus->get_sa(charon->bus);
-	if (!ike_sa)
-	{
-		return FALSE;
-	}
 	switch (type)
 	{
 		case INTERNAL_IP4_DNS:
@@ -117,12 +111,11 @@ METHOD(attribute_handler_t, handle, bool,
 }
 
 METHOD(attribute_handler_t, release, void,
-	private_updown_handler_t *this, identification_t *server,
+	private_updown_handler_t *this, ike_sa_t *ike_sa,
 	configuration_attribute_type_t type, chunk_t data)
 {
 	attributes_t *attr;
 	enumerator_t *enumerator, *servers;
-	ike_sa_t *ike_sa;
 	host_t *host;
 	bool found = FALSE;
 	int family;
@@ -139,43 +132,39 @@ METHOD(attribute_handler_t, release, void,
 			return;
 	}
 
-	ike_sa = charon->bus->get_sa(charon->bus);
-	if (ike_sa)
+	this->lock->write_lock(this->lock);
+	enumerator = this->attrs->create_enumerator(this->attrs);
+	while (enumerator->enumerate(enumerator, &attr))
 	{
-		this->lock->write_lock(this->lock);
-		enumerator = this->attrs->create_enumerator(this->attrs);
-		while (enumerator->enumerate(enumerator, &attr))
+		if (attr->id == ike_sa->get_unique_id(ike_sa))
 		{
-			if (attr->id == ike_sa->get_unique_id(ike_sa))
+			servers = attr->dns->create_enumerator(attr->dns);
+			while (servers->enumerate(servers, &host))
 			{
-				servers = attr->dns->create_enumerator(attr->dns);
-				while (servers->enumerate(servers, &host))
+				if (host->get_family(host) == family &&
+					chunk_equals(data, host->get_address(host)))
 				{
-					if (host->get_family(host) == family &&
-						chunk_equals(data, host->get_address(host)))
-					{
-						attr->dns->remove_at(attr->dns, servers);
-						host->destroy(host);
-						found = TRUE;
-						break;
-					}
-				}
-				servers->destroy(servers);
-				if (attr->dns->get_count(attr->dns) == 0)
-				{
-					this->attrs->remove_at(this->attrs, enumerator);
-					attributes_destroy(attr);
+					attr->dns->remove_at(attr->dns, servers);
+					host->destroy(host);
+					found = TRUE;
 					break;
 				}
 			}
-			if (found)
+			servers->destroy(servers);
+			if (attr->dns->get_count(attr->dns) == 0)
 			{
+				this->attrs->remove_at(this->attrs, enumerator);
+				attributes_destroy(attr);
 				break;
 			}
 		}
-		enumerator->destroy(enumerator);
-		this->lock->unlock(this->lock);
+		if (found)
+		{
+			break;
+		}
 	}
+	enumerator->destroy(enumerator);
+	this->lock->unlock(this->lock);
 }
 
 METHOD(updown_handler_t, create_dns_enumerator, enumerator_t*,
diff --git a/src/libcharon/plugins/updown/updown_listener.c b/src/libcharon/plugins/updown/updown_listener.c
index 1d15cc5..be65d59 100644
--- a/src/libcharon/plugins/updown/updown_listener.c
+++ b/src/libcharon/plugins/updown/updown_listener.c
@@ -243,6 +243,7 @@ static void invoke_once(private_updown_listener_t *this, ike_sa_t *ike_sa,
 	me = ike_sa->get_my_host(ike_sa);
 	other = ike_sa->get_other_host(ike_sa);
 
+	push_env(envp, countof(envp), "PATH=%s", getenv("PATH"));
 	push_env(envp, countof(envp), "PLUTO_VERSION=1.1");
 	is_host = my_ts->is_host(my_ts, me);
 	if (is_host)
diff --git a/src/libcharon/plugins/updown/updown_plugin.c b/src/libcharon/plugins/updown/updown_plugin.c
index d30267d..60ecfcc 100644
--- a/src/libcharon/plugins/updown/updown_plugin.c
+++ b/src/libcharon/plugins/updown/updown_plugin.c
@@ -18,7 +18,6 @@
 #include "updown_handler.h"
 
 #include <daemon.h>
-#include <hydra.h>
 
 typedef struct private_updown_plugin_t private_updown_plugin_t;
 
@@ -61,8 +60,8 @@ static bool plugin_cb(private_updown_plugin_t *this,
 							"%s.plugins.updown.dns_handler", FALSE, lib->ns))
 		{
 			this->handler = updown_handler_create();
-			hydra->attributes->add_handler(hydra->attributes,
-										   &this->handler->handler);
+			charon->attributes->add_handler(charon->attributes,
+											&this->handler->handler);
 		}
 		this->listener = updown_listener_create(this->handler);
 		charon->bus->add_listener(charon->bus, &this->listener->listener);
@@ -74,8 +73,8 @@ static bool plugin_cb(private_updown_plugin_t *this,
 		if (this->handler)
 		{
 			this->handler->destroy(this->handler);
-			hydra->attributes->remove_handler(hydra->attributes,
-											  &this->handler->handler);
+			charon->attributes->remove_handler(charon->attributes,
+											   &this->handler->handler);
 		}
 	}
 	return TRUE;
diff --git a/src/libcharon/plugins/vici/Makefile.am b/src/libcharon/plugins/vici/Makefile.am
index da71de3..b253960 100644
--- a/src/libcharon/plugins/vici/Makefile.am
+++ b/src/libcharon/plugins/vici/Makefile.am
@@ -74,3 +74,7 @@ SUBDIRS =
 if USE_RUBY_GEMS
 SUBDIRS += ruby
 endif
+
+if USE_PYTHON_EGGS
+SUBDIRS += python
+endif
diff --git a/src/libcharon/plugins/vici/Makefile.in b/src/libcharon/plugins/vici/Makefile.in
index 34546b9..b63226d 100644
--- a/src/libcharon/plugins/vici/Makefile.in
+++ b/src/libcharon/plugins/vici/Makefile.in
@@ -81,6 +81,7 @@ host_triplet = @host@
 TESTS = vici_tests$(EXEEXT)
 check_PROGRAMS = $(am__EXEEXT_1)
 @USE_RUBY_GEMS_TRUE at am__append_1 = ruby
+ at USE_PYTHON_EGGS_TRUE@am__append_2 = python
 subdir = src/libcharon/plugins/vici
 DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
 	$(top_srcdir)/depcomp
@@ -269,7 +270,7 @@ am__tty_colors = { \
     std=''; \
   fi; \
 }
-DIST_SUBDIRS = ruby
+DIST_SUBDIRS = ruby python
 DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
 am__relativize = \
   dir0=`pwd`; \
@@ -321,6 +322,7 @@ DLLIB = @DLLIB@
 DLLTOOL = @DLLTOOL@
 DSYMUTIL = @DSYMUTIL@
 DUMPBIN = @DUMPBIN@
+EASY_INSTALL = @EASY_INSTALL@
 ECHO_C = @ECHO_C@
 ECHO_N = @ECHO_N@
 ECHO_T = @ECHO_T@
@@ -381,10 +383,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
 PLUGIN_CFLAGS = @PLUGIN_CFLAGS@
 PTHREADLIB = @PTHREADLIB@
 PYTHON = @PYTHON@
+PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@
 PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
 PYTHON_PLATFORM = @PYTHON_PLATFORM@
 PYTHON_PREFIX = @PYTHON_PREFIX@
 PYTHON_VERSION = @PYTHON_VERSION@
+PY_TEST = @PY_TEST@
 RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
@@ -458,6 +462,8 @@ json_CFLAGS = @json_CFLAGS@
 json_LIBS = @json_LIBS@
 libdir = @libdir@
 libexecdir = @libexecdir@
+libiptc_CFLAGS = @libiptc_CFLAGS@
+libiptc_LIBS = @libiptc_LIBS@
 linux_headers = @linux_headers@
 localedir = @localedir@
 localstatedir = @localstatedir@
@@ -571,7 +577,7 @@ vici_tests_LDADD = \
 	$(top_builddir)/src/libstrongswan/libstrongswan.la \
 	$(top_builddir)/src/libstrongswan/tests/libtest.la
 
-SUBDIRS = $(am__append_1)
+SUBDIRS = $(am__append_1) $(am__append_2)
 all: all-recursive
 
 .SUFFIXES:
diff --git a/src/libcharon/plugins/vici/README.md b/src/libcharon/plugins/vici/README.md
index 2724910..0ce4271 100644
--- a/src/libcharon/plugins/vici/README.md
+++ b/src/libcharon/plugins/vici/README.md
@@ -145,25 +145,25 @@ the following C array:
 
 	char msg[] = {
 		/* key1 = value1 */
-		2, 4,'k','e','y','1', 0,6,'v','a','l','u','e','1',
+		3, 4,'k','e','y','1', 0,6,'v','a','l','u','e','1',
 		/* section1 */
-		0, 8,'s','e','c','t','i','o','n','1',
+		1, 8,'s','e','c','t','i','o','n','1',
 		/* sub-section */
-		0, 11,'s','u','b','-','s','e','c','t','i','o','n',
+		1, 11,'s','u','b','-','s','e','c','t','i','o','n',
 		/* key2 = value2 */
-		2, 4,'k','e','y','2', 0,6,'v','a','l','u','e','2',
+		3, 4,'k','e','y','2', 0,6,'v','a','l','u','e','2',
 		/* sub-section end */
-		1,
+		2,
 		/* list1 */
-		3, 5, 'l','i','s','t','1',
+		4, 5, 'l','i','s','t','1',
 		/* item1 */
-		4, 0,5,'i','t','e','m','1',
+		5, 0,5,'i','t','e','m','1',
 		/* item2 */
-		4, 0,5,'i','t','e','m','2',
+		5, 0,5,'i','t','e','m','2',
 		/* list1 end */
-		5,
+		6,
 		/* section1 end */
-		1,
+		2,
 	};
 
 ## Client-initiated commands ##
@@ -559,6 +559,7 @@ command.
 			]
 			child-sas = {
 				<child-sa-name>* = {
+					uniqueid = <unique CHILD_SA identifier>
 					reqid = <reqid of CHILD_SA>
 					state = <state string of CHILD_SA>
 					mode = <IPsec mode, tunnel|transport|beet>
@@ -820,9 +821,9 @@ during encoding.
 
 ## Connecting to the daemon ##
 
-To create a connection to the daemon, a socket must be passed to the
-_Connection_ constructor. There is no default, but on Unix systems usually
-a Unix socket over _/var/run/charon.vici_ is used:
+To create a connection to the daemon, a socket can be passed to the
+_Connection_ constructor. If none is passed, a default Unix socket at
+_/var/run/charon.vici_ is used:
 
 	require "vici"
 	require "socket"
@@ -854,3 +855,73 @@ _list-conns_ command and implicitly the _list-conn_ event:
 
 For more details about the ruby gem refer to the comments in the gem source
 code or the generated documentation.
+
+# vici Python egg #
+
+The _vici Python egg_ is a pure Python implementation of the VICI protocol to
+implement client applications. It is provided in the _python_ subdirectory, and
+gets built and installed if strongSwan has been _./configure_'d with
+_--enable-vici_ and _--enable-python-eggs_.
+
+The _vici_ module provides a _Session()_ constructor for a high level interface,
+the underlying classes are usually not required to build Python applications
+using VICI. The _Session_ class provides methods for the supported VICI
+commands.
+
+To represent the VICI message data tree, the library converts the binary
+encoding to Python data types. The _Session_ class takes and returns Python
+objects for the exchanged message data:
+ * Sections get encoded as OrderedDict, containing other sections, or
+ * Key/Values, where the values are strings as dictionary values
+ * Lists get encoded as Python Lists with string values
+Values that do not conform to Python dict or list get converted to strings using
+str().
+
+## Connecting to the daemon ##
+
+To create a connection to the daemon, a socket can be passed to the _Session_
+constructor. If none is passed, a default Unix socket at _/var/run/charon.vici_
+is used:
+
+	import vici
+	import socket
+
+	s = socket.socket(socket.AF_UNIX)
+	s.connect("/var/run/charon.vici")
+	v = vici.Session(s)
+
+## A simple client request ##
+
+An example to print the daemon version information is as simple as:
+
+	ver = v.version()
+
+	print "{daemon} {version} ({sysname}, {release}, {machine})".format(**ver)
+
+## A request with response iteration ##
+
+The _Session_ class returns an iterable Python generator for streamed events to
+continuously stream objects to the caller. The following example lists all
+loaded connections using the _list-conns_ command and implicitly the _list-conn_
+event:
+
+	for conn in v.list_conns():
+		for key in conn:
+			print key
+
+Please note that if the returned generator is not iterated completely, it must
+be closed using _close()_. This is implicitly done when breaking from a loop,
+but an explicit call may be required when directly iterating the generator with
+_next()_.
+
+## Sorting in dictionaries ##
+
+In VICI, in some message trees the order of objects in dictionary matters. In
+contrast to ruby Hashes, Python dictionaries do not preserve order of added
+objects. It is therefore recommended to use OrderedDicts instead of the default
+dictionaries. Objects returned by the library use OrderedDicts.
+
+## API documentation ##
+
+For more details about the Python egg refer to the comments in the Python source
+code.
diff --git a/src/libcharon/plugins/vici/libvici.c b/src/libcharon/plugins/vici/libvici.c
index c0205cc..7c98c8b 100644
--- a/src/libcharon/plugins/vici/libvici.c
+++ b/src/libcharon/plugins/vici/libvici.c
@@ -427,14 +427,8 @@ vici_res_t* vici_submit(vici_req_t *req, vici_conn_t *conn)
 
 void vici_free_req(vici_req_t *req)
 {
-	vici_message_t *message;
-
 	free(req->name);
-	message = req->b->finalize(req->b);
-	if (message)
-	{
-		message->destroy(message);
-	}
+	req->b->destroy(req->b);
 	free(req);
 }
 
diff --git a/src/libcharon/plugins/vici/python/LICENSE b/src/libcharon/plugins/vici/python/LICENSE
new file mode 100644
index 0000000..111523c
--- /dev/null
+++ b/src/libcharon/plugins/vici/python/LICENSE
@@ -0,0 +1,19 @@
+Copyright (c) 2015 Björn Schuberg
+
+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.
diff --git a/src/libcharon/plugins/vici/python/MANIFEST.in b/src/libcharon/plugins/vici/python/MANIFEST.in
new file mode 100644
index 0000000..1aba38f
--- /dev/null
+++ b/src/libcharon/plugins/vici/python/MANIFEST.in
@@ -0,0 +1 @@
+include LICENSE
diff --git a/src/libcharon/plugins/vici/python/Makefile.am b/src/libcharon/plugins/vici/python/Makefile.am
new file mode 100644
index 0000000..f517378
--- /dev/null
+++ b/src/libcharon/plugins/vici/python/Makefile.am
@@ -0,0 +1,33 @@
+EXTRA_DIST = LICENSE MANIFEST.in \
+	setup.py.in \
+	vici/test/__init__.py \
+	vici/test/test_protocol.py \
+	vici/__init__.py \
+	vici/compat.py \
+	vici/exception.py \
+	vici/protocol.py \
+	vici/session.py
+
+setup.py: $(srcdir)/setup.py.in
+	$(AM_V_GEN) sed \
+	-e "s:@EGG_VERSION@:$(PACKAGE_VERSION):" \
+	$(srcdir)/setup.py.in > $@
+
+all-local: dist/vici-$(PACKAGE_VERSION)-py$(PYTHON_VERSION).egg
+
+dist/vici-$(PACKAGE_VERSION)-py$(PYTHON_VERSION).egg: $(EXTRA_DIST) setup.py
+	(cd $(srcdir); $(PYTHON) setup.py bdist_egg \
+		-b $(shell readlink -f $(builddir))/build \
+		-d $(shell readlink -f $(builddir))/dist)
+
+clean-local: setup.py
+	$(PYTHON) setup.py clean -a
+	rm -rf vici.egg-info dist setup.py
+
+install-exec-local: dist/vici-$(PACKAGE_VERSION)-py$(PYTHON_VERSION).egg
+	$(EASY_INSTALL) $(PYTHONEGGINSTALLDIR) \
+		dist/vici-$(PACKAGE_VERSION)-py$(PYTHON_VERSION).egg
+
+if USE_PY_TEST
+  TESTS = $(PY_TEST)
+endif
diff --git a/src/libcharon/plugins/vici/python/Makefile.in b/src/libcharon/plugins/vici/python/Makefile.in
new file mode 100644
index 0000000..3a5e5ea
--- /dev/null
+++ b/src/libcharon/plugins/vici/python/Makefile.in
@@ -0,0 +1,686 @@
+# Makefile.in generated by automake 1.14.1 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994-2013 Free Software Foundation, Inc.
+
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+ at SET_MAKE@
+VPATH = @srcdir@
+am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)'
+am__make_running_with_option = \
+  case $${target_option-} in \
+      ?) ;; \
+      *) echo "am__make_running_with_option: internal error: invalid" \
+              "target option '$${target_option-}' specified" >&2; \
+         exit 1;; \
+  esac; \
+  has_opt=no; \
+  sane_makeflags=$$MAKEFLAGS; \
+  if $(am__is_gnu_make); then \
+    sane_makeflags=$$MFLAGS; \
+  else \
+    case $$MAKEFLAGS in \
+      *\\[\ \	]*) \
+        bs=\\; \
+        sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
+          | sed "s/$$bs$$bs[$$bs $$bs	]*//g"`;; \
+    esac; \
+  fi; \
+  skip_next=no; \
+  strip_trailopt () \
+  { \
+    flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
+  }; \
+  for flg in $$sane_makeflags; do \
+    test $$skip_next = yes && { skip_next=no; continue; }; \
+    case $$flg in \
+      *=*|--*) continue;; \
+        -*I) strip_trailopt 'I'; skip_next=yes;; \
+      -*I?*) strip_trailopt 'I';; \
+        -*O) strip_trailopt 'O'; skip_next=yes;; \
+      -*O?*) strip_trailopt 'O';; \
+        -*l) strip_trailopt 'l'; skip_next=yes;; \
+      -*l?*) strip_trailopt 'l';; \
+      -[dEDm]) skip_next=yes;; \
+      -[JT]) skip_next=yes;; \
+    esac; \
+    case $$flg in \
+      *$$target_option*) has_opt=yes; break;; \
+    esac; \
+  done; \
+  test $$has_opt = yes
+am__make_dryrun = (target_option=n; $(am__make_running_with_option))
+am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+subdir = src/libcharon/plugins/vici/python
+DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/m4/config/libtool.m4 \
+	$(top_srcdir)/m4/config/ltoptions.m4 \
+	$(top_srcdir)/m4/config/ltsugar.m4 \
+	$(top_srcdir)/m4/config/ltversion.m4 \
+	$(top_srcdir)/m4/config/lt~obsolete.m4 \
+	$(top_srcdir)/m4/macros/split-package-version.m4 \
+	$(top_srcdir)/m4/macros/with.m4 \
+	$(top_srcdir)/m4/macros/enable-disable.m4 \
+	$(top_srcdir)/m4/macros/add-plugin.m4 \
+	$(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+	$(ACLOCAL_M4)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+AM_V_P = $(am__v_P_ at AM_V@)
+am__v_P_ = $(am__v_P_ at AM_DEFAULT_V@)
+am__v_P_0 = false
+am__v_P_1 = :
+AM_V_GEN = $(am__v_GEN_ at AM_V@)
+am__v_GEN_ = $(am__v_GEN_ at AM_DEFAULT_V@)
+am__v_GEN_0 = @echo "  GEN     " $@;
+am__v_GEN_1 = 
+AM_V_at = $(am__v_at_ at AM_V@)
+am__v_at_ = $(am__v_at_ at AM_DEFAULT_V@)
+am__v_at_0 = @
+am__v_at_1 = 
+SOURCES =
+DIST_SOURCES =
+am__can_run_installinfo = \
+  case $$AM_UPDATE_INFO_DIR in \
+    n|no|NO) false;; \
+    *) (install-info --version) >/dev/null 2>&1;; \
+  esac
+am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
+am__tty_colors_dummy = \
+  mgn= red= grn= lgn= blu= brg= std=; \
+  am__color_tests=no
+am__tty_colors = { \
+  $(am__tty_colors_dummy); \
+  if test "X$(AM_COLOR_TESTS)" = Xno; then \
+    am__color_tests=no; \
+  elif test "X$(AM_COLOR_TESTS)" = Xalways; then \
+    am__color_tests=yes; \
+  elif test "X$$TERM" != Xdumb && { test -t 1; } 2>/dev/null; then \
+    am__color_tests=yes; \
+  fi; \
+  if test $$am__color_tests = yes; then \
+    red=''; \
+    grn=''; \
+    lgn=''; \
+    blu=''; \
+    mgn=''; \
+    brg=''; \
+    std=''; \
+  fi; \
+}
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+ALLOCA = @ALLOCA@
+AMTAR = @AMTAR@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+BFDLIB = @BFDLIB@
+BTLIB = @BTLIB@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+COVERAGE_CFLAGS = @COVERAGE_CFLAGS@
+COVERAGE_LDFLAGS = @COVERAGE_LDFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DLLIB = @DLLIB@
+DLLTOOL = @DLLTOOL@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+EASY_INSTALL = @EASY_INSTALL@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+FGREP = @FGREP@
+GEM = @GEM@
+GENHTML = @GENHTML@
+GPERF = @GPERF@
+GPRBUILD = @GPRBUILD@
+GREP = @GREP@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+LCOV = @LCOV@
+LD = @LD@
+LDFLAGS = @LDFLAGS@
+LEX = @LEX@
+LEXLIB = @LEXLIB@
+LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LIPO = @LIPO@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+MAKEINFO = @MAKEINFO@
+MANIFEST_TOOL = @MANIFEST_TOOL@
+MKDIR_P = @MKDIR_P@
+MYSQLCFLAG = @MYSQLCFLAG@
+MYSQLCONFIG = @MYSQLCONFIG@
+MYSQLLIB = @MYSQLLIB@
+NM = @NM@
+NMEDIT = @NMEDIT@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OPENSSL_LIB = @OPENSSL_LIB@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PACKAGE_VERSION_BUILD = @PACKAGE_VERSION_BUILD@
+PACKAGE_VERSION_MAJOR = @PACKAGE_VERSION_MAJOR@
+PACKAGE_VERSION_MINOR = @PACKAGE_VERSION_MINOR@
+PACKAGE_VERSION_REVIEW = @PACKAGE_VERSION_REVIEW@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PERL = @PERL@
+PKG_CONFIG = @PKG_CONFIG@
+PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
+PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
+PLUGIN_CFLAGS = @PLUGIN_CFLAGS@
+PTHREADLIB = @PTHREADLIB@
+PYTHON = @PYTHON@
+PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@
+PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
+PYTHON_PLATFORM = @PYTHON_PLATFORM@
+PYTHON_PREFIX = @PYTHON_PREFIX@
+PYTHON_VERSION = @PYTHON_VERSION@
+PY_TEST = @PY_TEST@
+RANLIB = @RANLIB@
+RTLIB = @RTLIB@
+RUBY = @RUBY@
+RUBYGEMDIR = @RUBYGEMDIR@
+RUBYINCLUDE = @RUBYINCLUDE@
+RUBYLIB = @RUBYLIB@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+SOCKLIB = @SOCKLIB@
+STRIP = @STRIP@
+UNWINDLIB = @UNWINDLIB@
+VERSION = @VERSION@
+YACC = @YACC@
+YFLAGS = @YFLAGS@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+aikgen_plugins = @aikgen_plugins@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+attest_plugins = @attest_plugins@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+c_plugins = @c_plugins@
+charon_natt_port = @charon_natt_port@
+charon_plugins = @charon_plugins@
+charon_udp_port = @charon_udp_port@
+clearsilver_LIBS = @clearsilver_LIBS@
+cmd_plugins = @cmd_plugins@
+datadir = @datadir@
+datarootdir = @datarootdir@
+dbusservicedir = @dbusservicedir@
+dev_headers = @dev_headers@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+fips_mode = @fips_mode@
+gtk_CFLAGS = @gtk_CFLAGS@
+gtk_LIBS = @gtk_LIBS@
+h_plugins = @h_plugins@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+imcvdir = @imcvdir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+ipsec_script = @ipsec_script@
+ipsec_script_upper = @ipsec_script_upper@
+ipsecdir = @ipsecdir@
+ipsecgroup = @ipsecgroup@
+ipseclibdir = @ipseclibdir@
+ipsecuser = @ipsecuser@
+json_CFLAGS = @json_CFLAGS@
+json_LIBS = @json_LIBS@
+libdir = @libdir@
+libexecdir = @libexecdir@
+libiptc_CFLAGS = @libiptc_CFLAGS@
+libiptc_LIBS = @libiptc_LIBS@
+linux_headers = @linux_headers@
+localedir = @localedir@
+localstatedir = @localstatedir@
+maemo_CFLAGS = @maemo_CFLAGS@
+maemo_LIBS = @maemo_LIBS@
+manager_plugins = @manager_plugins@
+mandir = @mandir@
+medsrv_plugins = @medsrv_plugins@
+mkdir_p = @mkdir_p@
+nm_CFLAGS = @nm_CFLAGS@
+nm_LIBS = @nm_LIBS@
+nm_ca_dir = @nm_ca_dir@
+nm_plugins = @nm_plugins@
+oldincludedir = @oldincludedir@
+pcsclite_CFLAGS = @pcsclite_CFLAGS@
+pcsclite_LIBS = @pcsclite_LIBS@
+pdfdir = @pdfdir@
+piddir = @piddir@
+pkgpyexecdir = @pkgpyexecdir@
+pkgpythondir = @pkgpythondir@
+pki_plugins = @pki_plugins@
+plugindir = @plugindir@
+pool_plugins = @pool_plugins@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+pyexecdir = @pyexecdir@
+pythondir = @pythondir@
+random_device = @random_device@
+resolv_conf = @resolv_conf@
+routing_table = @routing_table@
+routing_table_prio = @routing_table_prio@
+s_plugins = @s_plugins@
+sbindir = @sbindir@
+scepclient_plugins = @scepclient_plugins@
+scripts_plugins = @scripts_plugins@
+sharedstatedir = @sharedstatedir@
+soup_CFLAGS = @soup_CFLAGS@
+soup_LIBS = @soup_LIBS@
+srcdir = @srcdir@
+starter_plugins = @starter_plugins@
+strongswan_conf = @strongswan_conf@
+strongswan_options = @strongswan_options@
+swanctldir = @swanctldir@
+sysconfdir = @sysconfdir@
+systemd_daemon_CFLAGS = @systemd_daemon_CFLAGS@
+systemd_daemon_LIBS = @systemd_daemon_LIBS@
+systemd_journal_CFLAGS = @systemd_journal_CFLAGS@
+systemd_journal_LIBS = @systemd_journal_LIBS@
+systemdsystemunitdir = @systemdsystemunitdir@
+t_plugins = @t_plugins@
+target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+urandom_device = @urandom_device@
+xml_CFLAGS = @xml_CFLAGS@
+xml_LIBS = @xml_LIBS@
+EXTRA_DIST = LICENSE MANIFEST.in \
+	setup.py.in \
+	vici/test/__init__.py \
+	vici/test/test_protocol.py \
+	vici/__init__.py \
+	vici/compat.py \
+	vici/exception.py \
+	vici/protocol.py \
+	vici/session.py
+
+ at USE_PY_TEST_TRUE@TESTS = $(PY_TEST)
+all: all-am
+
+.SUFFIXES:
+$(srcdir)/Makefile.in:  $(srcdir)/Makefile.am  $(am__configure_deps)
+	@for dep in $?; do \
+	  case '$(am__configure_deps)' in \
+	    *$$dep*) \
+	      ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+	        && { if test -f $@; then exit 0; else break; fi; }; \
+	      exit 1;; \
+	  esac; \
+	done; \
+	echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/libcharon/plugins/vici/python/Makefile'; \
+	$(am__cd) $(top_srcdir) && \
+	  $(AUTOMAKE) --gnu src/libcharon/plugins/vici/python/Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+	@case '$?' in \
+	  *config.status*) \
+	    cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+	  *) \
+	    echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+	    cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+	esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure:  $(am__configure_deps)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4):  $(am__aclocal_m4_deps)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+
+mostlyclean-libtool:
+	-rm -f *.lo
+
+clean-libtool:
+	-rm -rf .libs _libs
+tags TAGS:
+
+ctags CTAGS:
+
+cscope cscopelist:
+
+
+check-TESTS: $(TESTS)
+	@failed=0; all=0; xfail=0; xpass=0; skip=0; \
+	srcdir=$(srcdir); export srcdir; \
+	list=' $(TESTS) '; \
+	$(am__tty_colors); \
+	if test -n "$$list"; then \
+	  for tst in $$list; do \
+	    if test -f ./$$tst; then dir=./; \
+	    elif test -f $$tst; then dir=; \
+	    else dir="$(srcdir)/"; fi; \
+	    if $(TESTS_ENVIRONMENT) $${dir}$$tst $(AM_TESTS_FD_REDIRECT); then \
+	      all=`expr $$all + 1`; \
+	      case " $(XFAIL_TESTS) " in \
+	      *[\ \	]$$tst[\ \	]*) \
+		xpass=`expr $$xpass + 1`; \
+		failed=`expr $$failed + 1`; \
+		col=$$red; res=XPASS; \
+	      ;; \
+	      *) \
+		col=$$grn; res=PASS; \
+	      ;; \
+	      esac; \
+	    elif test $$? -ne 77; then \
+	      all=`expr $$all + 1`; \
+	      case " $(XFAIL_TESTS) " in \
+	      *[\ \	]$$tst[\ \	]*) \
+		xfail=`expr $$xfail + 1`; \
+		col=$$lgn; res=XFAIL; \
+	      ;; \
+	      *) \
+		failed=`expr $$failed + 1`; \
+		col=$$red; res=FAIL; \
+	      ;; \
+	      esac; \
+	    else \
+	      skip=`expr $$skip + 1`; \
+	      col=$$blu; res=SKIP; \
+	    fi; \
+	    echo "$${col}$$res$${std}: $$tst"; \
+	  done; \
+	  if test "$$all" -eq 1; then \
+	    tests="test"; \
+	    All=""; \
+	  else \
+	    tests="tests"; \
+	    All="All "; \
+	  fi; \
+	  if test "$$failed" -eq 0; then \
+	    if test "$$xfail" -eq 0; then \
+	      banner="$$All$$all $$tests passed"; \
+	    else \
+	      if test "$$xfail" -eq 1; then failures=failure; else failures=failures; fi; \
+	      banner="$$All$$all $$tests behaved as expected ($$xfail expected $$failures)"; \
+	    fi; \
+	  else \
+	    if test "$$xpass" -eq 0; then \
+	      banner="$$failed of $$all $$tests failed"; \
+	    else \
+	      if test "$$xpass" -eq 1; then passes=pass; else passes=passes; fi; \
+	      banner="$$failed of $$all $$tests did not behave as expected ($$xpass unexpected $$passes)"; \
+	    fi; \
+	  fi; \
+	  dashes="$$banner"; \
+	  skipped=""; \
+	  if test "$$skip" -ne 0; then \
+	    if test "$$skip" -eq 1; then \
+	      skipped="($$skip test was not run)"; \
+	    else \
+	      skipped="($$skip tests were not run)"; \
+	    fi; \
+	    test `echo "$$skipped" | wc -c` -le `echo "$$banner" | wc -c` || \
+	      dashes="$$skipped"; \
+	  fi; \
+	  report=""; \
+	  if test "$$failed" -ne 0 && test -n "$(PACKAGE_BUGREPORT)"; then \
+	    report="Please report to $(PACKAGE_BUGREPORT)"; \
+	    test `echo "$$report" | wc -c` -le `echo "$$banner" | wc -c` || \
+	      dashes="$$report"; \
+	  fi; \
+	  dashes=`echo "$$dashes" | sed s/./=/g`; \
+	  if test "$$failed" -eq 0; then \
+	    col="$$grn"; \
+	  else \
+	    col="$$red"; \
+	  fi; \
+	  echo "$${col}$$dashes$${std}"; \
+	  echo "$${col}$$banner$${std}"; \
+	  test -z "$$skipped" || echo "$${col}$$skipped$${std}"; \
+	  test -z "$$report" || echo "$${col}$$report$${std}"; \
+	  echo "$${col}$$dashes$${std}"; \
+	  test "$$failed" -eq 0; \
+	else :; fi
+
+distdir: $(DISTFILES)
+	@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+	topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+	list='$(DISTFILES)'; \
+	  dist_files=`for file in $$list; do echo $$file; done | \
+	  sed -e "s|^$$srcdirstrip/||;t" \
+	      -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+	case $$dist_files in \
+	  */*) $(MKDIR_P) `echo "$$dist_files" | \
+			   sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+			   sort -u` ;; \
+	esac; \
+	for file in $$dist_files; do \
+	  if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+	  if test -d $$d/$$file; then \
+	    dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+	    if test -d "$(distdir)/$$file"; then \
+	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+	    fi; \
+	    if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+	      cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+	    fi; \
+	    cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+	  else \
+	    test -f "$(distdir)/$$file" \
+	    || cp -p $$d/$$file "$(distdir)/$$file" \
+	    || exit 1; \
+	  fi; \
+	done
+check-am: all-am
+	$(MAKE) $(AM_MAKEFLAGS) check-TESTS
+check: check-am
+all-am: Makefile all-local
+installdirs:
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+	@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+	if test -z '$(STRIP)'; then \
+	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	      install; \
+	else \
+	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	    "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+	fi
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+	-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+	-test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+
+maintainer-clean-generic:
+	@echo "This command is intended for maintainers to use"
+	@echo "it deletes files that may require special tools to rebuild."
+clean: clean-am
+
+clean-am: clean-generic clean-libtool clean-local mostlyclean-am
+
+distclean: distclean-am
+	-rm -f Makefile
+distclean-am: clean-am distclean-generic
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+html-am:
+
+info: info-am
+
+info-am:
+
+install-data-am:
+
+install-dvi: install-dvi-am
+
+install-dvi-am:
+
+install-exec-am: install-exec-local
+
+install-html: install-html-am
+
+install-html-am:
+
+install-info: install-info-am
+
+install-info-am:
+
+install-man:
+
+install-pdf: install-pdf-am
+
+install-pdf-am:
+
+install-ps: install-ps-am
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+	-rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-generic mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am:
+
+.MAKE: check-am install-am install-strip
+
+.PHONY: all all-am all-local check check-TESTS check-am clean \
+	clean-generic clean-libtool clean-local cscopelist-am ctags-am \
+	distclean distclean-generic distclean-libtool 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-exec-local install-html \
+	install-html-am 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-generic mostlyclean-libtool pdf pdf-am ps ps-am \
+	tags-am uninstall uninstall-am
+
+
+setup.py: $(srcdir)/setup.py.in
+	$(AM_V_GEN) sed \
+	-e "s:@EGG_VERSION@:$(PACKAGE_VERSION):" \
+	$(srcdir)/setup.py.in > $@
+
+all-local: dist/vici-$(PACKAGE_VERSION)-py$(PYTHON_VERSION).egg
+
+dist/vici-$(PACKAGE_VERSION)-py$(PYTHON_VERSION).egg: $(EXTRA_DIST) setup.py
+	(cd $(srcdir); $(PYTHON) setup.py bdist_egg \
+		-b $(shell readlink -f $(builddir))/build \
+		-d $(shell readlink -f $(builddir))/dist)
+
+clean-local: setup.py
+	$(PYTHON) setup.py clean -a
+	rm -rf vici.egg-info dist setup.py
+
+install-exec-local: dist/vici-$(PACKAGE_VERSION)-py$(PYTHON_VERSION).egg
+	$(EASY_INSTALL) $(PYTHONEGGINSTALLDIR) \
+		dist/vici-$(PACKAGE_VERSION)-py$(PYTHON_VERSION).egg
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/src/libcharon/plugins/vici/python/setup.py.in b/src/libcharon/plugins/vici/python/setup.py.in
new file mode 100644
index 0000000..0e4ad82
--- /dev/null
+++ b/src/libcharon/plugins/vici/python/setup.py.in
@@ -0,0 +1,34 @@
+from setuptools import setup
+
+
+long_description = (
+    "The strongSwan VICI protocol allows external application to monitor, "
+    "configure and control the IKE daemon charon. This python package provides "
+    "a native client side implementation of the VICI protocol, well suited to "
+    "script automated tasks in a reliable way."
+)
+
+setup(
+    name="vici",
+    version="@EGG_VERSION@",
+    description="Native python interface for strongSwan VICI",
+    author="Bjorn Schuberg",
+    url="https://wiki.strongswan.org/projects/strongswan/wiki/Vici",
+    license="MIT",
+    packages=["vici"],
+    long_description=long_description,
+    include_package_data=True,
+    classifiers=(
+        "Development Status :: 3 - Alpha",
+        "Intended Audience :: Developers",
+        "Intended Audience :: System Administrators",
+        "License :: OSI Approved :: MIT License",
+        "Natural Language :: English",
+        "Programming Language :: Python :: 2.7",
+        "Programming Language :: Python :: 3.2",
+        "Programming Language :: Python :: 3.3",
+        "Programming Language :: Python :: 3.4",
+        "Topic :: Security",
+        "Topic :: Software Development :: Libraries",
+    )
+)
diff --git a/src/libcharon/plugins/vici/python/vici/__init__.py b/src/libcharon/plugins/vici/python/vici/__init__.py
new file mode 100644
index 0000000..d314325
--- /dev/null
+++ b/src/libcharon/plugins/vici/python/vici/__init__.py
@@ -0,0 +1 @@
+from .session import Session
diff --git a/src/libcharon/plugins/vici/python/vici/compat.py b/src/libcharon/plugins/vici/python/vici/compat.py
new file mode 100644
index 0000000..b5f4699
--- /dev/null
+++ b/src/libcharon/plugins/vici/python/vici/compat.py
@@ -0,0 +1,14 @@
+# Help functions for compatibility between python version 2 and 3
+
+
+# From http://legacy.python.org/dev/peps/pep-0469
+try:
+    dict.iteritems
+except AttributeError:
+    # python 3
+    def iteritems(d):
+        return iter(d.items())
+else:
+    # python 2
+    def iteritems(d):
+        return d.iteritems()
diff --git a/src/libcharon/plugins/vici/python/vici/exception.py b/src/libcharon/plugins/vici/python/vici/exception.py
new file mode 100644
index 0000000..36384e5
--- /dev/null
+++ b/src/libcharon/plugins/vici/python/vici/exception.py
@@ -0,0 +1,10 @@
+"""Exception types that may be thrown by this library."""
+
+class DeserializationException(Exception):
+    """Encountered an unexpected byte sequence or missing element type."""
+
+class SessionException(Exception):
+    """Session request exception."""
+
+class CommandException(Exception):
+    """Command result exception."""
diff --git a/src/libcharon/plugins/vici/python/vici/protocol.py b/src/libcharon/plugins/vici/python/vici/protocol.py
new file mode 100644
index 0000000..855a7b2
--- /dev/null
+++ b/src/libcharon/plugins/vici/python/vici/protocol.py
@@ -0,0 +1,196 @@
+import io
+import socket
+import struct
+
+from collections import namedtuple
+from collections import OrderedDict
+
+from .compat import iteritems
+from .exception import DeserializationException
+
+
+class Transport(object):
+    HEADER_LENGTH = 4
+    MAX_SEGMENT = 512 * 1024
+
+    def __init__(self, sock):
+        self.socket = sock
+
+    def send(self, packet):
+        self.socket.sendall(struct.pack("!I", len(packet)) + packet)
+
+    def receive(self):
+        raw_length = self.socket.recv(self.HEADER_LENGTH)
+        length, = struct.unpack("!I", raw_length)
+        payload = self.socket.recv(length)
+        return payload
+
+    def close(self):
+        self.socket.shutdown(socket.SHUT_RDWR)
+        self.socket.close()
+
+
+class Packet(object):
+    CMD_REQUEST = 0         # Named request message
+    CMD_RESPONSE = 1        # Unnamed response message for a request
+    CMD_UNKNOWN = 2         # Unnamed response if requested command is unknown
+    EVENT_REGISTER = 3      # Named event registration request
+    EVENT_UNREGISTER = 4    # Named event de-registration request
+    EVENT_CONFIRM = 5       # Unnamed confirmation for event (de-)registration
+    EVENT_UNKNOWN = 6       # Unnamed response if event (de-)registration failed
+    EVENT = 7               # Named event message
+
+    ParsedPacket = namedtuple(
+        "ParsedPacket",
+        ["response_type", "payload"]
+    )
+
+    ParsedEventPacket = namedtuple(
+        "ParsedEventPacket",
+        ["response_type", "event_type", "payload"]
+    )
+
+    @classmethod
+    def _named_request(cls, request_type, request, message=None):
+        request = request.encode()
+        payload = struct.pack("!BB", request_type, len(request)) + request
+        if message is not None:
+            return payload + message
+        else:
+            return payload
+
+    @classmethod
+    def request(cls, command, message=None):
+        return cls._named_request(cls.CMD_REQUEST, command, message)
+
+    @classmethod
+    def register_event(cls, event_type):
+        return cls._named_request(cls.EVENT_REGISTER, event_type)
+
+    @classmethod
+    def unregister_event(cls, event_type):
+        return cls._named_request(cls.EVENT_UNREGISTER, event_type)
+
+    @classmethod
+    def parse(cls, packet):
+        stream = FiniteStream(packet)
+        response_type, = struct.unpack("!B", stream.read(1))
+
+        if response_type == cls.EVENT:
+            length, = struct.unpack("!B", stream.read(1))
+            event_type = stream.read(length)
+            return cls.ParsedEventPacket(response_type, event_type, stream)
+        else:
+            return cls.ParsedPacket(response_type, stream)
+
+
+class Message(object):
+    SECTION_START = 1       # Begin a new section having a name
+    SECTION_END = 2         # End a previously started section
+    KEY_VALUE = 3           # Define a value for a named key in the section
+    LIST_START = 4          # Begin a named list for list items
+    LIST_ITEM = 5           # Define an unnamed item value in the current list
+    LIST_END = 6            # End a previously started list
+
+    @classmethod
+    def serialize(cls, message):
+        def encode_named_type(marker, name):
+            name = name.encode()
+            return struct.pack("!BB", marker, len(name)) + name
+
+        def encode_blob(value):
+            if not isinstance(value, bytes):
+                value = str(value).encode()
+            return struct.pack("!H", len(value)) + value
+
+        def serialize_list(lst):
+            segment = bytes()
+            for item in lst:
+                segment += struct.pack("!B", cls.LIST_ITEM) + encode_blob(item)
+            return segment
+
+        def serialize_dict(d):
+            segment = bytes()
+            for key, value in iteritems(d):
+                if isinstance(value, dict):
+                    segment += (
+                        encode_named_type(cls.SECTION_START, key)
+                        + serialize_dict(value)
+                        + struct.pack("!B", cls.SECTION_END)
+                    )
+                elif isinstance(value, list):
+                    segment += (
+                        encode_named_type(cls.LIST_START, key)
+                        + serialize_list(value)
+                        + struct.pack("!B", cls.LIST_END)
+                    )
+                else:
+                    segment += (
+                        encode_named_type(cls.KEY_VALUE, key)
+                        + encode_blob(value)
+                    )
+            return segment
+
+        return serialize_dict(message)
+
+    @classmethod
+    def deserialize(cls, stream):
+        def decode_named_type(stream):
+            length, = struct.unpack("!B", stream.read(1))
+            return stream.read(length).decode()
+
+        def decode_blob(stream):
+            length, = struct.unpack("!H", stream.read(2))
+            return stream.read(length)
+
+        def decode_list_item(stream):
+            marker, = struct.unpack("!B", stream.read(1))
+            while marker == cls.LIST_ITEM:
+                yield decode_blob(stream)
+                marker, = struct.unpack("!B", stream.read(1))
+
+            if marker != cls.LIST_END:
+                raise DeserializationException(
+                    "Expected end of list at {pos}".format(pos=stream.tell())
+                )
+
+        section = OrderedDict()
+        section_stack = []
+        while stream.has_more():
+            element_type, = struct.unpack("!B", stream.read(1))
+            if element_type == cls.SECTION_START:
+                section_name = decode_named_type(stream)
+                new_section = OrderedDict()
+                section[section_name] = new_section
+                section_stack.append(section)
+                section = new_section
+
+            elif element_type == cls.LIST_START:
+                list_name = decode_named_type(stream)
+                section[list_name] = [item for item in decode_list_item(stream)]
+
+            elif element_type == cls.KEY_VALUE:
+                key = decode_named_type(stream)
+                section[key] = decode_blob(stream)
+
+            elif element_type == cls.SECTION_END:
+                if len(section_stack):
+                    section = section_stack.pop()
+                else:
+                    raise DeserializationException(
+                        "Unexpected end of section at {pos}".format(
+                            pos=stream.tell()
+                        )
+                    )
+
+        if len(section_stack):
+            raise DeserializationException("Expected end of section")
+        return section
+
+
+class FiniteStream(io.BytesIO):
+    def __len__(self):
+        return len(self.getvalue())
+
+    def has_more(self):
+        return self.tell() < len(self)
diff --git a/src/libcharon/plugins/vici/python/vici/session.py b/src/libcharon/plugins/vici/python/vici/session.py
new file mode 100644
index 0000000..dee5869
--- /dev/null
+++ b/src/libcharon/plugins/vici/python/vici/session.py
@@ -0,0 +1,327 @@
+import collections
+import socket
+
+from .exception import SessionException, CommandException
+from .protocol import Transport, Packet, Message
+
+
+class Session(object):
+    def __init__(self, sock=None):
+        if sock is None:
+            sock = socket.socket(socket.AF_UNIX)
+            sock.connect("/var/run/charon.vici")
+        self.handler = SessionHandler(Transport(sock))
+
+    def version(self):
+        """Retrieve daemon and system specific version information.
+
+        :return: daemon and system specific version information
+        :rtype: dict
+        """
+        return self.handler.request("version")
+
+    def stats(self):
+        """Retrieve IKE daemon statistics and load information.
+
+        :return: IKE daemon statistics and load information
+        :rtype: dict
+        """
+        return self.handler.request("stats")
+
+    def reload_settings(self):
+        """Reload strongswan.conf settings and any plugins supporting reload.
+        """
+        self.handler.request("reload-settings")
+
+    def initiate(self, sa):
+        """Initiate an SA.
+
+        :param sa: the SA to initiate
+        :type sa: dict
+        :return: generator for logs emitted as dict
+        :rtype: generator
+        """
+        return self.handler.streamed_request("initiate", "control-log", sa)
+
+    def terminate(self, sa):
+        """Terminate an SA.
+
+        :param sa: the SA to terminate
+        :type sa: dict
+        :return: generator for logs emitted as dict
+        :rtype: generator
+        """
+        return self.handler.streamed_request("terminate", "control-log", sa)
+
+    def install(self, policy):
+        """Install a trap, drop or bypass policy defined by a CHILD_SA config.
+
+        :param policy: policy to install
+        :type policy: dict
+        """
+        self.handler.request("install", policy)
+
+    def uninstall(self, policy):
+        """Uninstall a trap, drop or bypass policy defined by a CHILD_SA config.
+
+        :param policy: policy to uninstall
+        :type policy: dict
+        """
+        self.handler.request("uninstall", policy)
+
+    def list_sas(self, filters=None):
+        """Retrieve active IKE_SAs and associated CHILD_SAs.
+
+        :param filters: retrieve only matching IKE_SAs (optional)
+        :type filters: dict
+        :return: generator for active IKE_SAs and associated CHILD_SAs as dict
+        :rtype: generator
+        """
+        return self.handler.streamed_request("list-sas", "list-sa", filters)
+
+    def list_policies(self, filters=None):
+        """Retrieve installed trap, drop and bypass policies.
+
+        :param filters: retrieve only matching policies (optional)
+        :type filters: dict
+        :return: generator for installed trap, drop and bypass policies as dict
+        :rtype: generator
+        """
+        return self.handler.streamed_request("list-policies", "list-policy",
+                                             filters)
+
+    def list_conns(self, filters=None):
+        """Retrieve loaded connections.
+
+        :param filters: retrieve only matching configuration names (optional)
+        :type filters: dict
+        :return: generator for loaded connections as dict
+        :rtype: generator
+        """
+        return self.handler.streamed_request("list-conns", "list-conn",
+                                             filters)
+
+    def get_conns(self):
+        """Retrieve connection names loaded exclusively over vici.
+
+        :return: connection names
+        :rtype: dict
+        """
+        return self.handler.request("get-conns")
+
+    def list_certs(self, filters=None):
+        """Retrieve loaded certificates.
+
+        :param filters: retrieve only matching certificates (optional)
+        :type filters: dict
+        :return: generator for loaded certificates as dict
+        :rtype: generator
+        """
+        return self.handler.streamed_request("list-certs", "list-cert", filters)
+
+    def load_conn(self, connection):
+        """Load a connection definition into the daemon.
+
+        :param connection: connection definition
+        :type connection: dict
+        """
+        self.handler.request("load-conn", connection)
+
+    def unload_conn(self, name):
+        """Unload a connection definition.
+
+        :param name: connection definition name
+        :type name: dict
+        """
+        self.handler.request("unload-conn", name)
+
+    def load_cert(self, certificate):
+        """Load a certificate into the daemon.
+
+        :param certificate: PEM or DER encoded certificate
+        :type certificate: dict
+        """
+        self.handler.request("load-cert", certificate)
+
+    def load_key(self, private_key):
+        """Load a private key into the daemon.
+
+        :param private_key: PEM or DER encoded key
+        """
+        self.handler.request("load-key", private_key)
+
+    def load_shared(self, secret):
+        """Load a shared IKE PSK, EAP or XAuth secret into the daemon.
+
+        :param secret: shared IKE PSK, EAP or XAuth secret
+        :type secret: dict
+        """
+        self.handler.request("load-shared", secret)
+
+    def clear_creds(self):
+        """Clear credentials loaded over vici.
+
+        Clear all loaded certificate, private key and shared key credentials.
+        This affects only credentials loaded over vici, but additionally
+        flushes the credential cache.
+        """
+        self.handler.request("clear-creds")
+
+    def load_pool(self, pool):
+        """Load a virtual IP pool.
+
+        Load an in-memory virtual IP and configuration attribute pool.
+        Existing pools with the same name get updated, if possible.
+
+        :param pool: virtual IP and configuration attribute pool
+        :type pool: dict
+        """
+        return self.handler.request("load-pool", pool)
+
+    def unload_pool(self, pool_name):
+        """Unload a virtual IP pool.
+
+        Unload a previously loaded virtual IP and configuration attribute pool.
+        Unloading fails for pools with leases currently online.
+
+        :param pool_name: pool by name
+        :type pool_name: dict
+        """
+        self.handler.request("unload-pool", pool_name)
+
+    def get_pools(self):
+        """Retrieve loaded pools.
+
+        :return: loaded pools
+        :rtype: dict
+        """
+        return self.handler.request("get-pools")
+
+
+class SessionHandler(object):
+    """Handles client command execution requests over vici."""
+
+    def __init__(self, transport):
+        self.transport = transport
+
+    def _communicate(self, packet):
+        """Send packet over transport and parse response.
+
+        :param packet: packet to send
+        :type packet: :py:class:`vici.protocol.Packet`
+        :return: parsed packet in a tuple with message type and payload
+        :rtype: :py:class:`collections.namedtuple`
+        """
+        self.transport.send(packet)
+        return Packet.parse(self.transport.receive())
+
+    def request(self, command, message=None):
+        """Send request with an optional message.
+
+        :param command: command to send
+        :type command: str
+        :param message: message (optional)
+        :type message: str
+        :return: command result
+        :rtype: dict
+        """
+        if message is not None:
+            message = Message.serialize(message)
+        packet = Packet.request(command, message)
+        response = self._communicate(packet)
+
+        if response.response_type != Packet.CMD_RESPONSE:
+            raise SessionException(
+                "Unexpected response type {type}, "
+                "expected '{response}' (CMD_RESPONSE)".format(
+                    type=response.response_type,
+                    response=Packet.CMD_RESPONSE
+                )
+            )
+
+        command_response = Message.deserialize(response.payload)
+        if "success" in command_response:
+            if command_response["success"] != b"yes":
+                raise CommandException(
+                    "Command failed: {errmsg}".format(
+                        errmsg=command_response["errmsg"]
+                    )
+                )
+
+        return command_response
+
+    def streamed_request(self, command, event_stream_type, message=None):
+        """Send command request and collect and return all emitted events.
+
+        :param command: command to send
+        :type command: str
+        :param event_stream_type: event type emitted on command execution
+        :type event_stream_type: str
+        :param message: message (optional)
+        :type message: str
+        :return: generator for streamed event responses as dict
+        :rtype: generator
+        """
+        if message is not None:
+            message = Message.serialize(message)
+
+        # subscribe to event stream
+        packet = Packet.register_event(event_stream_type)
+        response = self._communicate(packet)
+
+        if response.response_type != Packet.EVENT_CONFIRM:
+            raise SessionException(
+                "Unexpected response type {type}, "
+                "expected '{confirm}' (EVENT_CONFIRM)".format(
+                    type=response.response_type,
+                    confirm=Packet.EVENT_CONFIRM,
+                )
+            )
+
+        # issue command, and read any event messages
+        packet = Packet.request(command, message)
+        self.transport.send(packet)
+        exited = False
+        while True:
+            response = Packet.parse(self.transport.receive())
+            if response.response_type == Packet.EVENT:
+                if not exited:
+                    try:
+                        yield Message.deserialize(response.payload)
+                    except GeneratorExit:
+                        exited = True
+                        pass
+            else:
+                break
+
+        if response.response_type == Packet.CMD_RESPONSE:
+            command_response = Message.deserialize(response.payload)
+        else:
+            raise SessionException(
+                "Unexpected response type {type}, "
+                "expected '{response}' (CMD_RESPONSE)".format(
+                    type=response.response_type,
+                    response=Packet.CMD_RESPONSE
+                )
+            )
+
+        # unsubscribe from event stream
+        packet = Packet.unregister_event(event_stream_type)
+        response = self._communicate(packet)
+        if response.response_type != Packet.EVENT_CONFIRM:
+            raise SessionException(
+                "Unexpected response type {type}, "
+                "expected '{confirm}' (EVENT_CONFIRM)".format(
+                    type=response.response_type,
+                    confirm=Packet.EVENT_CONFIRM,
+                )
+            )
+
+        # evaluate command result, if any
+        if "success" in command_response:
+            if command_response["success"] != b"yes":
+                raise CommandException(
+                    "Command failed: {errmsg}".format(
+                        errmsg=command_response["errmsg"]
+                    )
+                )
diff --git a/src/libcharon/plugins/vici/python/vici/test/__init__.py b/src/libcharon/plugins/vici/python/vici/test/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/src/libcharon/plugins/vici/python/vici/test/test_protocol.py b/src/libcharon/plugins/vici/python/vici/test/test_protocol.py
new file mode 100644
index 0000000..a1f202d
--- /dev/null
+++ b/src/libcharon/plugins/vici/python/vici/test/test_protocol.py
@@ -0,0 +1,144 @@
+import pytest
+
+from ..protocol import Packet, Message, FiniteStream
+from ..exception import DeserializationException
+
+
+class TestPacket(object):
+    # test data definitions for outgoing packet types
+    cmd_request = b"\x00\x0c" b"command_type"
+    cmd_request_msg = b"\x00\x07" b"command" b"payload"
+    event_register = b"\x03\x0a" b"event_type"
+    event_unregister = b"\x04\x0a" b"event_type"
+
+    # test data definitions for incoming packet types
+    cmd_response = b"\x01" b"reply"
+    cmd_unknown = b"\x02"
+    event_confirm = b"\x05"
+    event_unknown = b"\x06"
+    event = b"\x07\x03" b"log" b"message"
+
+    def test_request(self):
+        assert Packet.request("command_type") == self.cmd_request
+        assert Packet.request("command", b"payload") == self.cmd_request_msg
+
+    def test_register_event(self):
+        assert Packet.register_event("event_type") == self.event_register
+
+    def test_unregister_event(self):
+        assert Packet.unregister_event("event_type") == self.event_unregister
+
+    def test_parse(self):
+        parsed_cmd_response = Packet.parse(self.cmd_response)
+        assert parsed_cmd_response.response_type == Packet.CMD_RESPONSE
+        assert parsed_cmd_response.payload.getvalue() == self.cmd_response
+
+        parsed_cmd_unknown = Packet.parse(self.cmd_unknown)
+        assert parsed_cmd_unknown.response_type == Packet.CMD_UNKNOWN
+        assert parsed_cmd_unknown.payload.getvalue() == self.cmd_unknown
+
+        parsed_event_confirm = Packet.parse(self.event_confirm)
+        assert parsed_event_confirm.response_type == Packet.EVENT_CONFIRM
+        assert parsed_event_confirm.payload.getvalue() == self.event_confirm
+
+        parsed_event_unknown = Packet.parse(self.event_unknown)
+        assert parsed_event_unknown.response_type == Packet.EVENT_UNKNOWN
+        assert parsed_event_unknown.payload.getvalue() == self.event_unknown
+
+        parsed_event = Packet.parse(self.event)
+        assert parsed_event.response_type == Packet.EVENT
+        assert parsed_event.payload.getvalue() == self.event
+
+
+class TestMessage(object):
+    """Message (de)serialization test."""
+
+    # data definitions for test of de(serialization)
+    # serialized messages holding a section
+    ser_sec_unclosed = b"\x01\x08unclosed"
+    ser_sec_single = b"\x01\x07section\x02"
+    ser_sec_nested = b"\x01\x05outer\x01\x0asubsection\x02\x02"
+
+    # serialized messages holding a list
+    ser_list_invalid = b"\x04\x07invalid\x05\x00\x02e1\x02\x03sec\x06"
+    ser_list_0_item = b"\x04\x05empty\x06"
+    ser_list_1_item = b"\x04\x01l\x05\x00\x02e1\x06"
+    ser_list_2_item = b"\x04\x01l\x05\x00\x02e1\x05\x00\x02e2\x06"
+
+    # serialized messages with key value pairs
+    ser_kv_pair = b"\x03\x03key\x00\x05value"
+    ser_kv_zero = b"\x03\x0azerolength\x00\x00"
+
+    # deserialized messages holding a section
+    des_sec_single = { "section": {} }
+    des_sec_nested = { "outer": { "subsection": {} } }
+
+    # deserialized messages holding a list
+    des_list_0_item = { "empty": [] }
+    des_list_1_item = { "l": [ b"e1" ] }
+    des_list_2_item = { "l": [ b"e1", b"e2" ] }
+
+    # deserialized messages with key value pairs
+    des_kv_pair = { "key": b"value" }
+    des_kv_zero = { "zerolength": b"" }
+
+    def test_section_serialization(self):
+        assert Message.serialize(self.des_sec_single) == self.ser_sec_single
+        assert Message.serialize(self.des_sec_nested) == self.ser_sec_nested
+
+    def test_list_serialization(self):
+        assert Message.serialize(self.des_list_0_item) == self.ser_list_0_item
+        assert Message.serialize(self.des_list_1_item) == self.ser_list_1_item
+        assert Message.serialize(self.des_list_2_item) == self.ser_list_2_item
+
+    def test_key_serialization(self):
+        assert Message.serialize(self.des_kv_pair) == self.ser_kv_pair
+        assert Message.serialize(self.des_kv_zero) == self.ser_kv_zero
+
+    def test_section_deserialization(self):
+        single = Message.deserialize(FiniteStream(self.ser_sec_single))
+        nested = Message.deserialize(FiniteStream(self.ser_sec_nested))
+
+        assert single == self.des_sec_single
+        assert nested == self.des_sec_nested
+
+        with pytest.raises(DeserializationException):
+            Message.deserialize(FiniteStream(self.ser_sec_unclosed))
+
+    def test_list_deserialization(self):
+        l0 = Message.deserialize(FiniteStream(self.ser_list_0_item))
+        l1 = Message.deserialize(FiniteStream(self.ser_list_1_item))
+        l2 = Message.deserialize(FiniteStream(self.ser_list_2_item))
+
+        assert l0 == self.des_list_0_item
+        assert l1 == self.des_list_1_item
+        assert l2 == self.des_list_2_item
+
+        with pytest.raises(DeserializationException):
+            Message.deserialize(FiniteStream(self.ser_list_invalid))
+
+    def test_key_deserialization(self):
+        pair = Message.deserialize(FiniteStream(self.ser_kv_pair))
+        zerolength = Message.deserialize(FiniteStream(self.ser_kv_zero))
+
+        assert pair == self.des_kv_pair
+        assert zerolength == self.des_kv_zero
+
+    def test_roundtrip(self):
+        message = {
+            "key1": "value1",
+            "section1": {
+                "sub-section": {
+                    "key2": b"value2",
+                },
+                "list1": [ "item1", "item2" ],
+            },
+        }
+        serialized_message = FiniteStream(Message.serialize(message))
+        deserialized_message = Message.deserialize(serialized_message)
+
+        # ensure that list items and key values remain as undecoded bytes
+        deserialized_section = deserialized_message["section1"]
+        assert deserialized_message["key1"] == b"value1"
+        assert deserialized_section["sub-section"]["key2"] == b"value2"
+        assert deserialized_section["list1"] == [ b"item1", b"item2" ]
diff --git a/src/libcharon/plugins/vici/ruby/Makefile.am b/src/libcharon/plugins/vici/ruby/Makefile.am
index ce38e1c..3e12f86 100644
--- a/src/libcharon/plugins/vici/ruby/Makefile.am
+++ b/src/libcharon/plugins/vici/ruby/Makefile.am
@@ -5,8 +5,10 @@ vici.gemspec: $(srcdir)/vici.gemspec.in
 	-e "s:@GEM_VERSION@:$(PACKAGE_VERSION):" \
 	$(srcdir)/vici.gemspec.in > $@
 
-vici-$(PACKAGE_VERSION).gem: vici.gemspec
-	$(GEM) build vici.gemspec
+vici-$(PACKAGE_VERSION).gem: vici.gemspec $(EXTRA_DIST)
+	(cd $(srcdir); $(GEM) build $(abs_builddir)/vici.gemspec)
+	[ "$(srcdir)" = "$(builddir)" ] || \
+		mv $(srcdir)/vici-$(PACKAGE_VERSION).gem $(builddir)
 
 all-local: vici-$(PACKAGE_VERSION).gem
 
diff --git a/src/libcharon/plugins/vici/ruby/Makefile.in b/src/libcharon/plugins/vici/ruby/Makefile.in
index c8a8c11..f37c09e 100644
--- a/src/libcharon/plugins/vici/ruby/Makefile.in
+++ b/src/libcharon/plugins/vici/ruby/Makefile.in
@@ -142,6 +142,7 @@ DLLIB = @DLLIB@
 DLLTOOL = @DLLTOOL@
 DSYMUTIL = @DSYMUTIL@
 DUMPBIN = @DUMPBIN@
+EASY_INSTALL = @EASY_INSTALL@
 ECHO_C = @ECHO_C@
 ECHO_N = @ECHO_N@
 ECHO_T = @ECHO_T@
@@ -202,10 +203,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
 PLUGIN_CFLAGS = @PLUGIN_CFLAGS@
 PTHREADLIB = @PTHREADLIB@
 PYTHON = @PYTHON@
+PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@
 PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
 PYTHON_PLATFORM = @PYTHON_PLATFORM@
 PYTHON_PREFIX = @PYTHON_PREFIX@
 PYTHON_VERSION = @PYTHON_VERSION@
+PY_TEST = @PY_TEST@
 RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
@@ -279,6 +282,8 @@ json_CFLAGS = @json_CFLAGS@
 json_LIBS = @json_LIBS@
 libdir = @libdir@
 libexecdir = @libexecdir@
+libiptc_CFLAGS = @libiptc_CFLAGS@
+libiptc_LIBS = @libiptc_LIBS@
 linux_headers = @linux_headers@
 localedir = @localedir@
 localstatedir = @localstatedir@
@@ -535,8 +540,10 @@ vici.gemspec: $(srcdir)/vici.gemspec.in
 	-e "s:@GEM_VERSION@:$(PACKAGE_VERSION):" \
 	$(srcdir)/vici.gemspec.in > $@
 
-vici-$(PACKAGE_VERSION).gem: vici.gemspec
-	$(GEM) build vici.gemspec
+vici-$(PACKAGE_VERSION).gem: vici.gemspec $(EXTRA_DIST)
+	(cd $(srcdir); $(GEM) build $(abs_builddir)/vici.gemspec)
+	[ "$(srcdir)" = "$(builddir)" ] || \
+		mv $(srcdir)/vici-$(PACKAGE_VERSION).gem $(builddir)
 
 all-local: vici-$(PACKAGE_VERSION).gem
 
diff --git a/src/libcharon/plugins/vici/ruby/lib/vici.rb b/src/libcharon/plugins/vici/ruby/lib/vici.rb
index e8a9ddc..f87e46e 100644
--- a/src/libcharon/plugins/vici/ruby/lib/vici.rb
+++ b/src/libcharon/plugins/vici/ruby/lib/vici.rb
@@ -243,6 +243,25 @@ module Vici
     end
 
     ##
+    # Receive data from socket, until len bytes read
+    def recv_all(len)
+      encoding = ""
+      while encoding.length < len do
+        encoding << @socket.recv(len - encoding.length)
+      end
+      encoding
+    end
+
+    ##
+    # Send data to socket, until all bytes sent
+    def send_all(encoding)
+      len = 0
+      while len < encoding.length do
+        len += @socket.send(encoding[len..-1], 0)
+      end
+    end
+
+    ##
     # Write a packet prefixed by its length over the transport socket. Type
     # specifies the message, the optional label and message get appended.
     def write(type, label, message)
@@ -253,15 +272,15 @@ module Vici
       if message
         encoding << message.encoding
       end
-      @socket.send([encoding.length + 1, type].pack("Nc") + encoding, 0)
+      send_all([encoding.length + 1, type].pack("Nc") + encoding)
     end
 
     ##
     # Read a packet from the transport socket. Returns the packet type, and
     # if available in the packet a label and the contained message.
     def read
-      len = @socket.recv(4).unpack("N")[0]
-      encoding = @socket.recv(len)
+      len = recv_all(4).unpack("N")[0]
+      encoding = recv_all(len)
       type = encoding.unpack("c")[0]
       len = 1
       case type
@@ -371,7 +390,10 @@ module Vici
   # during encoding.
   class Connection
 
-    def initialize(socket)
+    def initialize(socket = nil)
+      if socket == nil
+        socket = UNIXSocket.new("/var/run/charon.vici")
+      end
       @transp = Transport.new(socket)
     end
 
diff --git a/src/libcharon/plugins/vici/ruby/vici.gemspec.in b/src/libcharon/plugins/vici/ruby/vici.gemspec.in
index 5ad61c0..2bd2b3d 100644
--- a/src/libcharon/plugins/vici/ruby/vici.gemspec.in
+++ b/src/libcharon/plugins/vici/ruby/vici.gemspec.in
@@ -2,7 +2,7 @@ Gem::Specification.new do |s|
   s.name          = "vici"
   s.version       = "@GEM_VERSION@"
   s.authors       = ["Martin Willi"]
-  s.email         = ["martin at strongswan.ch"]
+  s.email         = ["martin at strongswan.org"]
   s.description   = %q{
      The strongSwan VICI protocol allows external application to monitor,
      configure and control the IKE daemon charon. This ruby gem provides a
diff --git a/src/libcharon/plugins/vici/vici_attribute.c b/src/libcharon/plugins/vici/vici_attribute.c
index 2178116..f04bae7 100644
--- a/src/libcharon/plugins/vici/vici_attribute.c
+++ b/src/libcharon/plugins/vici/vici_attribute.c
@@ -1,4 +1,7 @@
 /*
+ * Copyright (C) 2014 Tobias Brunner
+ * Hochschule fuer Technik Rapperswil
+ *
  * Copyright (C) 2014 Martin Willi
  * Copyright (C) 2014 revosec AG
  *
@@ -93,7 +96,8 @@ static void pool_destroy(pool_t *pool)
  * Find an existing or not yet existing lease
  */
 static host_t *find_addr(private_vici_attribute_t *this, linked_list_t *pools,
-					identification_t *id, host_t *requested, mem_pool_op_t op)
+						 identification_t *id, host_t *requested,
+						 mem_pool_op_t op, host_t *peer)
 {
 	enumerator_t *enumerator;
 	host_t *addr = NULL;
@@ -106,7 +110,8 @@ static host_t *find_addr(private_vici_attribute_t *this, linked_list_t *pools,
 		pool = this->pools->get(this->pools, name);
 		if (pool)
 		{
-			addr = pool->vips->acquire_address(pool->vips, id, requested, op);
+			addr = pool->vips->acquire_address(pool->vips, id, requested,
+											   op, peer);
 			if (addr)
 			{
 				break;
@@ -119,20 +124,24 @@ static host_t *find_addr(private_vici_attribute_t *this, linked_list_t *pools,
 }
 
 METHOD(attribute_provider_t, acquire_address, host_t*,
-	private_vici_attribute_t *this, linked_list_t *pools, identification_t *id,
+	private_vici_attribute_t *this, linked_list_t *pools, ike_sa_t *ike_sa,
 	host_t *requested)
 {
-	host_t *addr;
+	identification_t *id;
+	host_t *addr, *peer;
+
+	id = ike_sa->get_other_eap_id(ike_sa);
+	peer = ike_sa->get_other_host(ike_sa);
 
 	this->lock->read_lock(this->lock);
 
-	addr = find_addr(this, pools, id, requested, MEM_POOL_EXISTING);
+	addr = find_addr(this, pools, id, requested, MEM_POOL_EXISTING, peer);
 	if (!addr)
 	{
-		addr = find_addr(this, pools, id, requested, MEM_POOL_NEW);
+		addr = find_addr(this, pools, id, requested, MEM_POOL_NEW, peer);
 		if (!addr)
 		{
-			addr = find_addr(this, pools, id, requested, MEM_POOL_REASSIGN);
+			addr = find_addr(this, pools, id, requested, MEM_POOL_REASSIGN, peer);
 		}
 	}
 
@@ -143,13 +152,16 @@ METHOD(attribute_provider_t, acquire_address, host_t*,
 
 METHOD(attribute_provider_t, release_address, bool,
 	private_vici_attribute_t *this, linked_list_t *pools, host_t *address,
-	identification_t *id)
+	ike_sa_t *ike_sa)
 {
 	enumerator_t *enumerator;
+	identification_t *id;
 	bool found = FALSE;
 	pool_t *pool;
 	char *name;
 
+	id = ike_sa->get_other_eap_id(ike_sa);
+
 	this->lock->read_lock(this->lock);
 
 	enumerator = pools->create_enumerator(pools);
@@ -256,7 +268,7 @@ static bool have_vips_from_pool(mem_pool_t *pool, linked_list_t *vips)
 
 METHOD(attribute_provider_t, create_attribute_enumerator, enumerator_t*,
 	private_vici_attribute_t *this, linked_list_t *pools,
-	identification_t *id, linked_list_t *vips)
+	ike_sa_t *ike_sa, linked_list_t *vips)
 {
 	enumerator_t *enumerator;
 	nested_data_t *data;
@@ -355,6 +367,24 @@ static vici_message_t* create_reply(char *fmt, ...)
 }
 
 /**
+ * Parse a range definition of an address pool
+ */
+static mem_pool_t *create_pool_range(char *name, char *buf)
+{
+	mem_pool_t *pool;
+	host_t *from, *to;
+
+	if (!host_create_from_range(buf, &from, &to))
+	{
+		return NULL;
+	}
+	pool = mem_pool_create_range(name, from, to);
+	from->destroy(from);
+	to->destroy(to);
+	return pool;
+}
+
+/**
  * Parse callback data, passed to each callback
  */
 typedef struct {
@@ -490,7 +520,8 @@ CALLBACK(pool_kv, bool,
 	if (streq(name, "addrs"))
 	{
 		char buf[128];
-		host_t *base;
+		mem_pool_t *pool;
+		host_t *base = NULL;
 		int bits;
 
 		if (data->pool->vips)
@@ -503,14 +534,22 @@ CALLBACK(pool_kv, bool,
 			data->request->reply = create_reply("invalid addrs value");
 			return FALSE;
 		}
-		base = host_create_from_subnet(buf, &bits);
-		if (!base)
+		pool = create_pool_range(data->name, buf);
+		if (!pool)
+		{
+			base = host_create_from_subnet(buf, &bits);
+			if (base)
+			{
+				pool = mem_pool_create(data->name, base, bits);
+				base->destroy(base);
+			}
+		}
+		if (!pool)
 		{
 			data->request->reply = create_reply("invalid addrs value: %s", buf);
 			return FALSE;
 		}
-		data->pool->vips = mem_pool_create(data->name, base, bits);
-		base->destroy(base);
+		data->pool->vips = pool;
 		return TRUE;
 	}
 	data->request->reply = create_reply("invalid attribute: %s", name);
diff --git a/src/libcharon/plugins/vici/vici_builder.c b/src/libcharon/plugins/vici/vici_builder.c
index 5616320..82f12c9 100644
--- a/src/libcharon/plugins/vici/vici_builder.c
+++ b/src/libcharon/plugins/vici/vici_builder.c
@@ -84,6 +84,8 @@ METHOD(vici_builder_t, add, void,
 
 	if (value.len > 0xffff)
 	{
+		DBG1(DBG_ENC, "vici value exceeds size limit (%zu > %u)",
+			 value.len, 0xffff);
 		this->error++;
 		return;
 	}
@@ -125,24 +127,58 @@ METHOD(vici_builder_t, add, void,
 	}
 }
 
-METHOD(vici_builder_t, vadd_kv, void,
-	private_vici_builder_t *this, char *key, char *fmt, va_list args)
+/**
+ * Add a list item or a key/value, if key given
+ */
+static void vadd_kv_or_li(private_vici_builder_t *this, char *key,
+						  char *fmt, va_list args)
 {
-	char buf[2048];
+	u_char buf[512];
+	chunk_t value;
 	ssize_t len;
+	va_list copy;
 
-	len = vsnprintf(buf, sizeof(buf), fmt, args);
-	if (len < 0 || len >= sizeof(buf))
+	va_copy(copy, args);
+	len = vsnprintf(buf, sizeof(buf), fmt, copy);
+	va_end(copy);
+	if (len >= sizeof(buf))
 	{
-		DBG1(DBG_ENC, "vici builder format buffer exceeds limit");
+		value = chunk_alloc(len + 1);
+		len = vsnprintf(value.ptr, value.len, fmt, args);
+	}
+	else
+	{
+		value = chunk_create(buf, len);
+	}
+
+	if (len < 0)
+	{
+		DBG1(DBG_ENC, "vici builder format print failed");
 		this->error++;
 	}
 	else
 	{
-		add(this, VICI_KEY_VALUE, key, chunk_create(buf, len));
+		if (key)
+		{
+			add(this, VICI_KEY_VALUE, key, value);
+		}
+		else
+		{
+			add(this, VICI_LIST_ITEM, value);
+		}
+	}
+	if (value.ptr != buf)
+	{
+		free(value.ptr);
 	}
 }
 
+METHOD(vici_builder_t, vadd_kv, void,
+	private_vici_builder_t *this, char *key, char *fmt, va_list args)
+{
+	vadd_kv_or_li(this, key, fmt, args);
+}
+
 METHOD(vici_builder_t, add_kv, void,
 	private_vici_builder_t *this, char *key, char *fmt, ...)
 {
@@ -153,23 +189,10 @@ METHOD(vici_builder_t, add_kv, void,
 	va_end(args);
 }
 
-
 METHOD(vici_builder_t, vadd_li, void,
 	private_vici_builder_t *this, char *fmt, va_list args)
 {
-	char buf[2048];
-	ssize_t len;
-
-	len = vsnprintf(buf, sizeof(buf), fmt, args);
-	if (len < 0 || len >= sizeof(buf))
-	{
-		DBG1(DBG_ENC, "vici builder format buffer exceeds limit");
-		this->error++;
-	}
-	else
-	{
-		add(this, VICI_LIST_ITEM, chunk_create(buf, len));
-	}
+	vadd_kv_or_li(this, NULL, fmt, args);
 }
 
 METHOD(vici_builder_t, add_li, void,
@@ -206,6 +229,13 @@ METHOD(vici_builder_t, end_list, void,
 	add(this, VICI_LIST_END);
 }
 
+METHOD(vici_builder_t, destroy, void,
+	private_vici_builder_t *this)
+{
+	this->writer->destroy(this->writer);
+	free(this);
+}
+
 METHOD(vici_builder_t, finalize, vici_message_t*,
 	private_vici_builder_t *this)
 {
@@ -215,14 +245,12 @@ METHOD(vici_builder_t, finalize, vici_message_t*,
 	{
 		DBG1(DBG_ENC, "vici builder error: %u errors (section: %u, list %u)",
 			 this->error, this->section, this->list);
-		this->writer->destroy(this->writer);
-		free(this);
+		destroy(this);
 		return NULL;
 	}
 	product = vici_message_create_from_data(
 								this->writer->extract_buf(this->writer), TRUE);
-	this->writer->destroy(this->writer);
-	free(this);
+	destroy(this);
 	return product;
 }
 
@@ -245,6 +273,7 @@ vici_builder_t *vici_builder_create()
 			.begin_list = _begin_list,
 			.end_list = _end_list,
 			.finalize = _finalize,
+			.destroy = _destroy,
 		},
 		.writer = bio_writer_create(0),
 	);
diff --git a/src/libcharon/plugins/vici/vici_builder.h b/src/libcharon/plugins/vici/vici_builder.h
index 5a5cc8a..f7d21eb 100644
--- a/src/libcharon/plugins/vici/vici_builder.h
+++ b/src/libcharon/plugins/vici/vici_builder.h
@@ -119,6 +119,14 @@ struct vici_builder_t {
 	 * @return		vici message, NULL on error
 	 */
 	vici_message_t* (*finalize)(vici_builder_t *this);
+
+	/**
+	 * Destroy a vici builder without finalization.
+	 *
+	 * Note that finalize() already destroys the message, and calling destroy()
+	 * is required only if the message does not get finalize()d.
+	 */
+	void (*destroy)(vici_builder_t *this);
 };
 
 /**
diff --git a/src/libcharon/plugins/vici/vici_config.c b/src/libcharon/plugins/vici/vici_config.c
index 113d480..6491610 100644
--- a/src/libcharon/plugins/vici/vici_config.c
+++ b/src/libcharon/plugins/vici/vici_config.c
@@ -1551,8 +1551,8 @@ static void clear_start_action(private_vici_config_t *this,
 	enumerator_t *enumerator, *children;
 	child_sa_t *child_sa;
 	ike_sa_t *ike_sa;
-	u_int32_t reqid = 0, *del;
-	array_t *reqids = NULL;
+	u_int32_t id = 0, *del;
+	array_t *ids = NULL;
 	char *name;
 
 	name = child_cfg->get_name(child_cfg);
@@ -1568,23 +1568,23 @@ static void clear_start_action(private_vici_config_t *this,
 				{
 					if (streq(name, child_sa->get_name(child_sa)))
 					{
-						reqid = child_sa->get_reqid(child_sa);
-						array_insert_create(&reqids, ARRAY_TAIL, &reqid);
+						id = child_sa->get_unique_id(child_sa);
+						array_insert_create(&ids, ARRAY_TAIL, &id);
 					}
 				}
 				children->destroy(children);
 			}
 			enumerator->destroy(enumerator);
 
-			if (array_count(reqids))
+			if (array_count(ids))
 			{
-				while (array_remove(reqids, ARRAY_HEAD, &del))
+				while (array_remove(ids, ARRAY_HEAD, &del))
 				{
 					DBG1(DBG_CFG, "closing '%s' #%u", name, *del);
 					charon->controller->terminate_child(charon->controller,
 														*del, NULL, NULL, 0);
 				}
-				array_destroy(reqids);
+				array_destroy(ids);
 			}
 			break;
 		case ACTION_ROUTE:
@@ -1601,14 +1601,14 @@ static void clear_start_action(private_vici_config_t *this,
 					{
 						if (streq(name, child_sa->get_name(child_sa)))
 						{
-							reqid = child_sa->get_reqid(child_sa);
+							id = child_sa->get_reqid(child_sa);
 							break;
 						}
 					}
 					enumerator->destroy(enumerator);
-					if (reqid)
+					if (id)
 					{
-						charon->traps->uninstall(charon->traps, reqid);
+						charon->traps->uninstall(charon->traps, id);
 					}
 					break;
 			}
@@ -1751,7 +1751,8 @@ CALLBACK(config_sn, bool,
 		.fragmentation = FRAGMENTATION_NO,
 		.unique = UNIQUE_NO,
 		.keyingtries = 1,
-		.rekey_time = LFT_DEFAULT_IKE_REKEY,
+		.rekey_time = LFT_UNDEFINED,
+		.reauth_time = LFT_UNDEFINED,
 		.over_time = LFT_UNDEFINED,
 		.rand_time = LFT_UNDEFINED,
 	};
@@ -1809,6 +1810,20 @@ CALLBACK(config_sn, bool,
 		peer.local_port = charon->socket->get_port(charon->socket, FALSE);
 	}
 
+	if (peer.rekey_time == LFT_UNDEFINED && peer.reauth_time == LFT_UNDEFINED)
+	{
+		/* apply a default rekey time if no rekey/reauth time set */
+		peer.rekey_time = LFT_DEFAULT_IKE_REKEY;
+		peer.reauth_time = 0;
+	}
+	if (peer.rekey_time == LFT_UNDEFINED)
+	{
+		peer.rekey_time = 0;
+	}
+	if (peer.reauth_time == LFT_UNDEFINED)
+	{
+		peer.reauth_time = 0;
+	}
 	if (peer.over_time == LFT_UNDEFINED)
 	{
 		/* default over_time to 10% of rekey/reauth time if not given */
@@ -1816,9 +1831,17 @@ CALLBACK(config_sn, bool,
 	}
 	if (peer.rand_time == LFT_UNDEFINED)
 	{
-		/* default rand_time to over_time if not given */
-		peer.rand_time = min(peer.over_time,
-							 max(peer.rekey_time, peer.reauth_time) / 2);
+		/* default rand_time to over_time if not given, but don't make it
+		 * longer than half of rekey/rauth time */
+		if (peer.rekey_time && peer.reauth_time)
+		{
+			peer.rand_time = min(peer.rekey_time, peer.reauth_time);
+		}
+		else
+		{
+			peer.rand_time = max(peer.rekey_time, peer.reauth_time);
+		}
+		peer.rand_time = min(peer.over_time, peer.rand_time / 2);
 	}
 
 	log_peer_data(&peer);
diff --git a/src/libcharon/plugins/vici/vici_control.c b/src/libcharon/plugins/vici/vici_control.c
index 292a400..01d5036 100644
--- a/src/libcharon/plugins/vici/vici_control.c
+++ b/src/libcharon/plugins/vici/vici_control.c
@@ -264,11 +264,11 @@ CALLBACK(terminate, vici_message_t*,
 				{
 					continue;
 				}
-				if (child_id && child_sa->get_reqid(child_sa) != child_id)
+				if (child_id && child_sa->get_unique_id(child_sa) != child_id)
 				{
 					continue;
 				}
-				current = child_sa->get_reqid(child_sa);
+				current = child_sa->get_unique_id(child_sa);
 				array_insert(ids, ARRAY_TAIL, &current);
 			}
 			csas->destroy(csas);
diff --git a/src/libcharon/plugins/vici/vici_plugin.c b/src/libcharon/plugins/vici/vici_plugin.c
index 8881fec..af8bd28 100644
--- a/src/libcharon/plugins/vici/vici_plugin.c
+++ b/src/libcharon/plugins/vici/vici_plugin.c
@@ -23,7 +23,6 @@
 #include "vici_logger.h"
 
 #include <library.h>
-#include <hydra.h>
 #include <daemon.h>
 
 typedef struct private_vici_plugin_t private_vici_plugin_t;
@@ -104,8 +103,8 @@ static bool register_vici(private_vici_plugin_t *this,
 
 			charon->backends->add_backend(charon->backends,
 										  &this->config->backend);
-			hydra->attributes->add_provider(hydra->attributes,
-											&this->attrs->provider);
+			charon->attributes->add_provider(charon->attributes,
+											 &this->attrs->provider);
 			charon->bus->add_logger(charon->bus, &this->logger->logger);
 			return TRUE;
 		}
@@ -114,8 +113,8 @@ static bool register_vici(private_vici_plugin_t *this,
 	else
 	{
 		charon->bus->remove_logger(charon->bus, &this->logger->logger);
-		hydra->attributes->remove_provider(hydra->attributes,
-										   &this->attrs->provider);
+		charon->attributes->remove_provider(charon->attributes,
+											&this->attrs->provider);
 		charon->backends->remove_backend(charon->backends,
 										 &this->config->backend);
 
diff --git a/src/libcharon/plugins/vici/vici_query.c b/src/libcharon/plugins/vici/vici_query.c
index 54833ab..3e0d73c 100644
--- a/src/libcharon/plugins/vici/vici_query.c
+++ b/src/libcharon/plugins/vici/vici_query.c
@@ -63,11 +63,13 @@ static void list_child(private_vici_query_t *this, vici_builder_t *b,
 	enumerator_t *enumerator;
 	traffic_selector_t *ts;
 
+	b->add_kv(b, "uniqueid", "%u", child->get_unique_id(child));
 	b->add_kv(b, "reqid", "%u", child->get_reqid(child));
 	b->add_kv(b, "state", "%N", child_sa_state_names, child->get_state(child));
 	b->add_kv(b, "mode", "%N", ipsec_mode_names, child->get_mode(child));
 	if (child->get_state(child) == CHILD_INSTALLED ||
-		child->get_state(child) == CHILD_REKEYING)
+		child->get_state(child) == CHILD_REKEYING ||
+		child->get_state(child) == CHILD_REKEYED)
 	{
 		b->add_kv(b, "protocol", "%N", protocol_id_names,
 				  child->get_protocol(child));
@@ -507,11 +509,14 @@ static void build_auth_cfgs(peer_cfg_t *peer_cfg, bool local, vici_builder_t *b)
 		certificate_t *cert;
 		char *str;
 	} v;
+	char buf[32];
+	int i = 0;
 
 	enumerator = peer_cfg->create_auth_cfg_enumerator(peer_cfg, local);
 	while (enumerator->enumerate(enumerator, &auth))
 	{
-		b->begin_section(b, local ? "local" : "remote");
+		snprintf(buf, sizeof(buf), "%s-%d", local ? "local" : "remote", ++i);
+		b->begin_section(b, buf);
 
 		rules = auth->create_enumerator(auth);
 		while (rules->enumerate(rules, &rule, &v))
@@ -976,10 +981,10 @@ CALLBACK(stats, vici_message_t*,
 		struct mallinfo mi = mallinfo();
 
 		b->begin_section(b, "mallinfo");
-		b->add_kv(b, "sbrk", "%d", mi.arena);
-		b->add_kv(b, "mmap", "%d", mi.hblkhd);
-		b->add_kv(b, "used", "%d", mi.uordblks);
-		b->add_kv(b, "free", "%d", mi.fordblks);
+		b->add_kv(b, "sbrk", "%u", mi.arena);
+		b->add_kv(b, "mmap", "%u", mi.hblkhd);
+		b->add_kv(b, "used", "%u", mi.uordblks);
+		b->add_kv(b, "free", "%u", mi.fordblks);
 		b->end_section(b);
 	}
 #endif /* HAVE_MALLINFO */
diff --git a/src/libcharon/plugins/whitelist/Makefile.in b/src/libcharon/plugins/whitelist/Makefile.in
index b1cc1d1..e400d9f 100644
--- a/src/libcharon/plugins/whitelist/Makefile.in
+++ b/src/libcharon/plugins/whitelist/Makefile.in
@@ -236,6 +236,7 @@ DLLIB = @DLLIB@
 DLLTOOL = @DLLTOOL@
 DSYMUTIL = @DSYMUTIL@
 DUMPBIN = @DUMPBIN@
+EASY_INSTALL = @EASY_INSTALL@
 ECHO_C = @ECHO_C@
 ECHO_N = @ECHO_N@
 ECHO_T = @ECHO_T@
@@ -296,10 +297,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
 PLUGIN_CFLAGS = @PLUGIN_CFLAGS@
 PTHREADLIB = @PTHREADLIB@
 PYTHON = @PYTHON@
+PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@
 PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
 PYTHON_PLATFORM = @PYTHON_PLATFORM@
 PYTHON_PREFIX = @PYTHON_PREFIX@
 PYTHON_VERSION = @PYTHON_VERSION@
+PY_TEST = @PY_TEST@
 RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
@@ -373,6 +376,8 @@ json_CFLAGS = @json_CFLAGS@
 json_LIBS = @json_LIBS@
 libdir = @libdir@
 libexecdir = @libexecdir@
+libiptc_CFLAGS = @libiptc_CFLAGS@
+libiptc_LIBS = @libiptc_LIBS@
 linux_headers = @linux_headers@
 localedir = @localedir@
 localstatedir = @localstatedir@
diff --git a/src/libcharon/plugins/xauth_eap/Makefile.in b/src/libcharon/plugins/xauth_eap/Makefile.in
index e393ee1..a968445 100644
--- a/src/libcharon/plugins/xauth_eap/Makefile.in
+++ b/src/libcharon/plugins/xauth_eap/Makefile.in
@@ -229,6 +229,7 @@ DLLIB = @DLLIB@
 DLLTOOL = @DLLTOOL@
 DSYMUTIL = @DSYMUTIL@
 DUMPBIN = @DUMPBIN@
+EASY_INSTALL = @EASY_INSTALL@
 ECHO_C = @ECHO_C@
 ECHO_N = @ECHO_N@
 ECHO_T = @ECHO_T@
@@ -289,10 +290,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
 PLUGIN_CFLAGS = @PLUGIN_CFLAGS@
 PTHREADLIB = @PTHREADLIB@
 PYTHON = @PYTHON@
+PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@
 PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
 PYTHON_PLATFORM = @PYTHON_PLATFORM@
 PYTHON_PREFIX = @PYTHON_PREFIX@
 PYTHON_VERSION = @PYTHON_VERSION@
+PY_TEST = @PY_TEST@
 RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
@@ -366,6 +369,8 @@ json_CFLAGS = @json_CFLAGS@
 json_LIBS = @json_LIBS@
 libdir = @libdir@
 libexecdir = @libexecdir@
+libiptc_CFLAGS = @libiptc_CFLAGS@
+libiptc_LIBS = @libiptc_LIBS@
 linux_headers = @linux_headers@
 localedir = @localedir@
 localstatedir = @localstatedir@
diff --git a/src/libcharon/plugins/xauth_generic/Makefile.in b/src/libcharon/plugins/xauth_generic/Makefile.in
index f0e7727..5170c92 100644
--- a/src/libcharon/plugins/xauth_generic/Makefile.in
+++ b/src/libcharon/plugins/xauth_generic/Makefile.in
@@ -229,6 +229,7 @@ DLLIB = @DLLIB@
 DLLTOOL = @DLLTOOL@
 DSYMUTIL = @DSYMUTIL@
 DUMPBIN = @DUMPBIN@
+EASY_INSTALL = @EASY_INSTALL@
 ECHO_C = @ECHO_C@
 ECHO_N = @ECHO_N@
 ECHO_T = @ECHO_T@
@@ -289,10 +290,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
 PLUGIN_CFLAGS = @PLUGIN_CFLAGS@
 PTHREADLIB = @PTHREADLIB@
 PYTHON = @PYTHON@
+PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@
 PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
 PYTHON_PLATFORM = @PYTHON_PLATFORM@
 PYTHON_PREFIX = @PYTHON_PREFIX@
 PYTHON_VERSION = @PYTHON_VERSION@
+PY_TEST = @PY_TEST@
 RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
@@ -366,6 +369,8 @@ json_CFLAGS = @json_CFLAGS@
 json_LIBS = @json_LIBS@
 libdir = @libdir@
 libexecdir = @libexecdir@
+libiptc_CFLAGS = @libiptc_CFLAGS@
+libiptc_LIBS = @libiptc_LIBS@
 linux_headers = @linux_headers@
 localedir = @localedir@
 localstatedir = @localstatedir@
diff --git a/src/libcharon/plugins/xauth_noauth/Makefile.in b/src/libcharon/plugins/xauth_noauth/Makefile.in
index a4c1aae..087f5b3 100644
--- a/src/libcharon/plugins/xauth_noauth/Makefile.in
+++ b/src/libcharon/plugins/xauth_noauth/Makefile.in
@@ -229,6 +229,7 @@ DLLIB = @DLLIB@
 DLLTOOL = @DLLTOOL@
 DSYMUTIL = @DSYMUTIL@
 DUMPBIN = @DUMPBIN@
+EASY_INSTALL = @EASY_INSTALL@
 ECHO_C = @ECHO_C@
 ECHO_N = @ECHO_N@
 ECHO_T = @ECHO_T@
@@ -289,10 +290,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
 PLUGIN_CFLAGS = @PLUGIN_CFLAGS@
 PTHREADLIB = @PTHREADLIB@
 PYTHON = @PYTHON@
+PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@
 PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
 PYTHON_PLATFORM = @PYTHON_PLATFORM@
 PYTHON_PREFIX = @PYTHON_PREFIX@
 PYTHON_VERSION = @PYTHON_VERSION@
+PY_TEST = @PY_TEST@
 RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
@@ -366,6 +369,8 @@ json_CFLAGS = @json_CFLAGS@
 json_LIBS = @json_LIBS@
 libdir = @libdir@
 libexecdir = @libexecdir@
+libiptc_CFLAGS = @libiptc_CFLAGS@
+libiptc_LIBS = @libiptc_LIBS@
 linux_headers = @linux_headers@
 localedir = @localedir@
 localstatedir = @localstatedir@
diff --git a/src/libcharon/plugins/xauth_pam/Makefile.in b/src/libcharon/plugins/xauth_pam/Makefile.in
index 296ccaa..29441bc 100644
--- a/src/libcharon/plugins/xauth_pam/Makefile.in
+++ b/src/libcharon/plugins/xauth_pam/Makefile.in
@@ -229,6 +229,7 @@ DLLIB = @DLLIB@
 DLLTOOL = @DLLTOOL@
 DSYMUTIL = @DSYMUTIL@
 DUMPBIN = @DUMPBIN@
+EASY_INSTALL = @EASY_INSTALL@
 ECHO_C = @ECHO_C@
 ECHO_N = @ECHO_N@
 ECHO_T = @ECHO_T@
@@ -289,10 +290,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
 PLUGIN_CFLAGS = @PLUGIN_CFLAGS@
 PTHREADLIB = @PTHREADLIB@
 PYTHON = @PYTHON@
+PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@
 PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
 PYTHON_PLATFORM = @PYTHON_PLATFORM@
 PYTHON_PREFIX = @PYTHON_PREFIX@
 PYTHON_VERSION = @PYTHON_VERSION@
+PY_TEST = @PY_TEST@
 RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
@@ -366,6 +369,8 @@ json_CFLAGS = @json_CFLAGS@
 json_LIBS = @json_LIBS@
 libdir = @libdir@
 libexecdir = @libexecdir@
+libiptc_CFLAGS = @libiptc_CFLAGS@
+libiptc_LIBS = @libiptc_LIBS@
 linux_headers = @linux_headers@
 localedir = @localedir@
 localstatedir = @localstatedir@
diff --git a/src/libcharon/processing/jobs/adopt_children_job.c b/src/libcharon/processing/jobs/adopt_children_job.c
index fb480ee..c8a9c17 100644
--- a/src/libcharon/processing/jobs/adopt_children_job.c
+++ b/src/libcharon/processing/jobs/adopt_children_job.c
@@ -1,4 +1,7 @@
 /*
+ * Copyright (C) 2015 Tobias Brunner
+ * Hochschule fuer Technik Rapperswil
+ *
  * Copyright (C) 2012 Martin Willi
  * Copyright (C) 2012 revosec AG
  *
@@ -54,10 +57,10 @@ METHOD(job_t, execute, job_requeue_t,
 	private_adopt_children_job_t *this)
 {
 	identification_t *my_id, *other_id, *xauth;
-	host_t *me, *other;
+	host_t *me, *other, *vip;
 	peer_cfg_t *cfg;
-	linked_list_t *children;
-	enumerator_t *enumerator, *childenum;
+	linked_list_t *children, *vips;
+	enumerator_t *enumerator, *subenum;
 	ike_sa_id_t *id;
 	ike_sa_t *ike_sa;
 	child_sa_t *child_sa;
@@ -81,7 +84,8 @@ METHOD(job_t, execute, job_requeue_t,
 
 		charon->ike_sa_manager->checkin(charon->ike_sa_manager, ike_sa);
 
-		/* find old SA to adopt children from */
+		/* find old SA to adopt children and virtual IPs from */
+		vips = linked_list_create();
 		children = linked_list_create();
 		enumerator = charon->ike_sa_manager->create_id_enumerator(
 									charon->ike_sa_manager, my_id, xauth,
@@ -102,18 +106,29 @@ METHOD(job_t, execute, job_requeue_t,
 					other_id->equals(other_id, ike_sa->get_other_id(ike_sa)) &&
 					cfg->equals(cfg, ike_sa->get_peer_cfg(ike_sa)))
 				{
-					childenum = ike_sa->create_child_sa_enumerator(ike_sa);
-					while (childenum->enumerate(childenum, &child_sa))
+					subenum = ike_sa->create_child_sa_enumerator(ike_sa);
+					while (subenum->enumerate(subenum, &child_sa))
 					{
-						ike_sa->remove_child_sa(ike_sa, childenum);
+						ike_sa->remove_child_sa(ike_sa, subenum);
 						children->insert_last(children, child_sa);
 					}
-					childenum->destroy(childenum);
-					if (children->get_count(children))
+					subenum->destroy(subenum);
+
+					subenum = ike_sa->create_virtual_ip_enumerator(ike_sa, FALSE);
+					while (subenum->enumerate(subenum, &vip))
+					{
+						vips->insert_last(vips, vip->clone(vip));
+					}
+					subenum->destroy(subenum);
+					/* this does not release the addresses, which is good, but
+					 * it does trigger an assign_vips(FALSE) event, so we also
+					 * trigger one below */
+					ike_sa->clear_virtual_ips(ike_sa, FALSE);
+					if (children->get_count(children) || vips->get_count(vips))
 					{
 						DBG1(DBG_IKE, "detected reauth of existing IKE_SA, "
-							 "adopting %d children",
-							 children->get_count(children));
+							 "adopting %d children and %d virtual IPs",
+							 children->get_count(children), vips->get_count(vips));
 					}
 					ike_sa->set_state(ike_sa, IKE_DELETING);
 					charon->bus->ike_updown(charon->bus, ike_sa, FALSE);
@@ -125,7 +140,7 @@ METHOD(job_t, execute, job_requeue_t,
 					charon->ike_sa_manager->checkin(
 											charon->ike_sa_manager, ike_sa);
 				}
-				if (children->get_count(children))
+				if (children->get_count(children) || vips->get_count(vips))
 				{
 					break;
 				}
@@ -140,7 +155,7 @@ METHOD(job_t, execute, job_requeue_t,
 		xauth->destroy(xauth);
 		cfg->destroy(cfg);
 
-		if (children->get_count(children))
+		if (children->get_count(children) || vips->get_count(vips))
 		{
 			/* adopt children by new SA */
 			ike_sa = charon->ike_sa_manager->checkout(charon->ike_sa_manager,
@@ -152,10 +167,27 @@ METHOD(job_t, execute, job_requeue_t,
 				{
 					ike_sa->add_child_sa(ike_sa, child_sa);
 				}
+				if (vips->get_count(vips))
+				{
+					while (vips->remove_first(vips, (void**)&vip) == SUCCESS)
+					{
+						ike_sa->add_virtual_ip(ike_sa, FALSE, vip);
+						vip->destroy(vip);
+					}
+					charon->bus->assign_vips(charon->bus, ike_sa, TRUE);
+				}
 				charon->ike_sa_manager->checkin(charon->ike_sa_manager, ike_sa);
 			}
 		}
 		children->destroy_offset(children, offsetof(child_sa_t, destroy));
+		/* FIXME: If we still have addresses here it means we weren't able to
+		 * find the new SA anymore (while not very likely during a proper
+		 * reauthentication, this theoretically could happen because the SA is
+		 * not locked while we search for the old one).  So the addresses here
+		 * should be released properly to avoid leaking these leases.  This is
+		 * currently not possible, though, due to the changed interface of
+		 * release_address(), which now takes a complete IKE_SA object. */
+		vips->destroy_offset(vips, offsetof(host_t, destroy));
 
 		if (array_count(this->tasks))
 		{
diff --git a/src/libcharon/processing/jobs/delete_child_sa_job.c b/src/libcharon/processing/jobs/delete_child_sa_job.c
index 9afbac0..0d85883 100644
--- a/src/libcharon/processing/jobs/delete_child_sa_job.c
+++ b/src/libcharon/processing/jobs/delete_child_sa_job.c
@@ -31,11 +31,6 @@ struct private_delete_child_sa_job_t {
 	delete_child_sa_job_t public;
 
 	/**
-	 * reqid of the CHILD_SA
-	 */
-	u_int32_t reqid;
-
-	/**
 	 * protocol of the CHILD_SA (ESP/AH)
 	 */
 	protocol_id_t protocol;
@@ -46,6 +41,11 @@ struct private_delete_child_sa_job_t {
 	u_int32_t spi;
 
 	/**
+	 * SA destination address
+	 */
+	host_t *dst;
+
+	/**
 	 * Delete for an expired CHILD_SA
 	 */
 	bool expired;
@@ -54,6 +54,7 @@ struct private_delete_child_sa_job_t {
 METHOD(job_t, destroy, void,
 	private_delete_child_sa_job_t *this)
 {
+	this->dst->destroy(this->dst);
 	free(this);
 }
 
@@ -62,12 +63,12 @@ METHOD(job_t, execute, job_requeue_t,
 {
 	ike_sa_t *ike_sa;
 
-	ike_sa = charon->ike_sa_manager->checkout_by_id(charon->ike_sa_manager,
-													this->reqid, TRUE);
+	ike_sa = charon->child_sa_manager->checkout(charon->child_sa_manager,
+									this->protocol, this->spi, this->dst, NULL);
 	if (ike_sa == NULL)
 	{
-		DBG1(DBG_JOB, "CHILD_SA with reqid %d not found for delete",
-			 this->reqid);
+		DBG1(DBG_JOB, "CHILD_SA %N/0x%08x/%H not found for delete",
+			 protocol_id_names, this->protocol, htonl(this->spi), this->dst);
 	}
 	else
 	{
@@ -87,8 +88,8 @@ METHOD(job_t, get_priority, job_priority_t,
 /*
  * Described in header
  */
-delete_child_sa_job_t *delete_child_sa_job_create(u_int32_t reqid,
-							protocol_id_t protocol, u_int32_t spi, bool expired)
+delete_child_sa_job_t *delete_child_sa_job_create(protocol_id_t protocol,
+									u_int32_t spi, host_t *dst, bool expired)
 {
 	private_delete_child_sa_job_t *this;
 
@@ -100,12 +101,11 @@ delete_child_sa_job_t *delete_child_sa_job_create(u_int32_t reqid,
 				.destroy = _destroy,
 			},
 		},
-		.reqid = reqid,
 		.protocol = protocol,
 		.spi = spi,
+		.dst = dst->clone(dst),
 		.expired = expired,
 	);
 
 	return &this->public;
 }
-
diff --git a/src/libcharon/processing/jobs/delete_child_sa_job.h b/src/libcharon/processing/jobs/delete_child_sa_job.h
index be6d578..6fa5364 100644
--- a/src/libcharon/processing/jobs/delete_child_sa_job.h
+++ b/src/libcharon/processing/jobs/delete_child_sa_job.h
@@ -44,16 +44,13 @@ struct delete_child_sa_job_t {
 /**
  * Creates a job of type DELETE_CHILD_SA.
  *
- * The CHILD_SA is identified by its reqid, protocol (AH/ESP) and its
- * inbound SPI.
- *
- * @param reqid		reqid of the CHILD_SA, as used in kernel
  * @param protocol	protocol of the CHILD_SA
  * @param spi		security parameter index of the CHILD_SA
+ * @param dst		SA destination address
  * @param expired	TRUE if CHILD_SA already expired
  * @return			delete_child_sa_job_t object
  */
-delete_child_sa_job_t *delete_child_sa_job_create(u_int32_t reqid,
-							protocol_id_t protocol, u_int32_t spi, bool expired);
+delete_child_sa_job_t *delete_child_sa_job_create(protocol_id_t protocol,
+									u_int32_t spi, host_t *dst, bool expired);
 
 #endif /** DELETE_CHILD_SA_JOB_H_ @}*/
diff --git a/src/libcharon/processing/jobs/dpd_timeout_job.c b/src/libcharon/processing/jobs/dpd_timeout_job.c
index 9cdce5c..4c88c13 100644
--- a/src/libcharon/processing/jobs/dpd_timeout_job.c
+++ b/src/libcharon/processing/jobs/dpd_timeout_job.c
@@ -63,6 +63,12 @@ METHOD(job_t, execute, job_requeue_t,
 											  this->ike_sa_id);
 	if (ike_sa)
 	{
+		if (ike_sa->get_state(ike_sa) == IKE_PASSIVE)
+		{
+			charon->ike_sa_manager->checkin(charon->ike_sa_manager, ike_sa);
+			return JOB_REQUEUE_NONE;
+		}
+
 		use_time = ike_sa->get_statistic(ike_sa, STAT_INBOUND);
 
 		enumerator = ike_sa->create_child_sa_enumerator(ike_sa);
diff --git a/src/libcharon/processing/jobs/inactivity_job.c b/src/libcharon/processing/jobs/inactivity_job.c
index 1977339..f0f90ee 100644
--- a/src/libcharon/processing/jobs/inactivity_job.c
+++ b/src/libcharon/processing/jobs/inactivity_job.c
@@ -30,9 +30,9 @@ struct private_inactivity_job_t {
 	inactivity_job_t public;
 
 	/**
-	 * Reqid of CHILD_SA to check
+	 * Unique CHILD_SA identifier to check
 	 */
-	u_int32_t reqid;
+	u_int32_t id;
 
 	/**
 	 * Inactivity timeout
@@ -57,8 +57,8 @@ METHOD(job_t, execute, job_requeue_t,
 	ike_sa_t *ike_sa;
 	u_int32_t reschedule = 0;
 
-	ike_sa = charon->ike_sa_manager->checkout_by_id(charon->ike_sa_manager,
-													this->reqid, TRUE);
+	ike_sa = charon->child_sa_manager->checkout_by_id(charon->child_sa_manager,
+													  this->id, NULL);
 	if (ike_sa)
 	{
 		enumerator_t *enumerator;
@@ -69,9 +69,9 @@ METHOD(job_t, execute, job_requeue_t,
 		status_t status = SUCCESS;
 
 		enumerator = ike_sa->create_child_sa_enumerator(ike_sa);
-		while (enumerator->enumerate(enumerator, (void**)&child_sa))
+		while (enumerator->enumerate(enumerator, &child_sa))
 		{
-			if (child_sa->get_reqid(child_sa) == this->reqid)
+			if (child_sa->get_unique_id(child_sa) == this->id)
 			{
 				time_t in, out, install, diff;
 
@@ -136,7 +136,7 @@ METHOD(job_t, get_priority, job_priority_t,
 /**
  * See header
  */
-inactivity_job_t *inactivity_job_create(u_int32_t reqid, u_int32_t timeout,
+inactivity_job_t *inactivity_job_create(u_int32_t unique_id, u_int32_t timeout,
 										bool close_ike)
 {
 	private_inactivity_job_t *this;
@@ -149,7 +149,7 @@ inactivity_job_t *inactivity_job_create(u_int32_t reqid, u_int32_t timeout,
 				.destroy = _destroy,
 			},
 		},
-		.reqid = reqid,
+		.id = unique_id,
 		.timeout = timeout,
 		.close_ike = close_ike,
 	);
diff --git a/src/libcharon/processing/jobs/inactivity_job.h b/src/libcharon/processing/jobs/inactivity_job.h
index 890f770..ff19fe5 100644
--- a/src/libcharon/processing/jobs/inactivity_job.h
+++ b/src/libcharon/processing/jobs/inactivity_job.h
@@ -42,12 +42,12 @@ struct inactivity_job_t {
 /**
  * Create a inactivity_job instance.
  *
- * @param reqid		reqid of CHILD_SA to check for inactivity
+ * @param unique_id	unique CHILD_SA identifier to check for inactivity
  * @param timeout	inactivity timeout in s
  * @param close_ike	close IKE_SA if the last remaining CHILD_SA is inactive?
  * @return			inactivity checking job
  */
-inactivity_job_t *inactivity_job_create(u_int32_t reqid, u_int32_t timeout,
+inactivity_job_t *inactivity_job_create(u_int32_t unique_id, u_int32_t timeout,
 										bool close_ike);
 
 #endif /** INACTIVITY_JOB_H_ @}*/
diff --git a/src/libcharon/processing/jobs/initiate_tasks_job.c b/src/libcharon/processing/jobs/initiate_tasks_job.c
new file mode 100644
index 0000000..001e71f
--- /dev/null
+++ b/src/libcharon/processing/jobs/initiate_tasks_job.c
@@ -0,0 +1,96 @@
+/*
+ * Copyright (C) 2015 Martin Willi
+ * Copyright (C) 2015 revosec AG
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * for more details.
+ */
+
+#include <stdlib.h>
+
+#include "initiate_tasks_job.h"
+
+#include <sa/ike_sa.h>
+#include <daemon.h>
+
+
+typedef struct private_initiate_tasks_job_t private_initiate_tasks_job_t;
+
+/**
+ * Private data of an initiate_tasks_job_t Object
+ */
+struct private_initiate_tasks_job_t {
+
+	/**
+	 * Public initiate_tasks_job_t interface
+	 */
+	initiate_tasks_job_t public;
+
+	/**
+	 * ID of the IKE_SA to trigger task initiation
+	 */
+	ike_sa_id_t *ike_sa_id;
+};
+
+METHOD(job_t, destroy, void,
+	private_initiate_tasks_job_t *this)
+{
+	this->ike_sa_id->destroy(this->ike_sa_id);
+	free(this);
+}
+
+METHOD(job_t, execute, job_requeue_t,
+	private_initiate_tasks_job_t *this)
+{
+	ike_sa_t *ike_sa;
+
+	ike_sa = charon->ike_sa_manager->checkout(charon->ike_sa_manager,
+											  this->ike_sa_id);
+	if (ike_sa)
+	{
+		if (ike_sa->initiate(ike_sa, NULL, 0, NULL, NULL) == DESTROY_ME)
+		{
+			charon->ike_sa_manager->checkin_and_destroy(charon->ike_sa_manager,
+														ike_sa);
+		}
+		else
+		{
+			charon->ike_sa_manager->checkin(charon->ike_sa_manager, ike_sa);
+		}
+	}
+	return JOB_REQUEUE_NONE;
+}
+
+METHOD(job_t, get_priority, job_priority_t,
+	private_initiate_tasks_job_t *this)
+{
+	return JOB_PRIO_MEDIUM;
+}
+
+/*
+ * Described in header
+ */
+initiate_tasks_job_t *initiate_tasks_job_create(ike_sa_id_t *ike_sa_id)
+{
+	private_initiate_tasks_job_t *this;
+
+	INIT(this,
+		.public = {
+			.job_interface = {
+				.execute = _execute,
+				.get_priority = _get_priority,
+				.destroy = _destroy,
+			},
+		},
+		.ike_sa_id = ike_sa_id->clone(ike_sa_id),
+	);
+
+	return &this->public;
+}
diff --git a/src/libcharon/processing/jobs/initiate_tasks_job.h b/src/libcharon/processing/jobs/initiate_tasks_job.h
new file mode 100644
index 0000000..0714978
--- /dev/null
+++ b/src/libcharon/processing/jobs/initiate_tasks_job.h
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2015 Martin Willi
+ * Copyright (C) 2015 revosec AG
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * for more details.
+ */
+
+/**
+ * @defgroup initiate_tasks_job initiate_tasks_job
+ * @{ @ingroup cjobs
+ */
+
+#ifndef INITIATE_TASKS_JOB_H_
+#define INITIATE_TASKS_JOB_H_
+
+typedef struct initiate_tasks_job_t initiate_tasks_job_t;
+
+#include <library.h>
+#include <processing/jobs/job.h>
+#include <sa/ike_sa_id.h>
+
+/**
+ * Job triggering initiation of any queued IKE_SA tasks.
+ */
+struct initiate_tasks_job_t {
+
+	/**
+	 * Implements job_t interface
+	 */
+	job_t job_interface;
+};
+
+/**
+ * Creates a job to trigger IKE_SA task initiation.
+ *
+ * @param ike_sa_id		ID of IKE_SA to trigger tasks for (gets cloned)
+ * @return				job instance
+ */
+initiate_tasks_job_t *initiate_tasks_job_create(ike_sa_id_t *ike_sa_id);
+
+#endif /** INITIATE_TASKS_JOB_H_ @}*/
diff --git a/src/libcharon/processing/jobs/migrate_job.c b/src/libcharon/processing/jobs/migrate_job.c
index 2ebfc67..097dbdf 100644
--- a/src/libcharon/processing/jobs/migrate_job.c
+++ b/src/libcharon/processing/jobs/migrate_job.c
@@ -70,29 +70,34 @@ METHOD(job_t, destroy, void,
 METHOD(job_t, execute, job_requeue_t,
 	private_migrate_job_t *this)
 {
-	ike_sa_t *ike_sa = NULL;
+	enumerator_t *ike_sas, *children;
+	ike_sa_t *ike_sa;
 
-	if (this->reqid)
+	ike_sas = charon->ike_sa_manager->create_enumerator(charon->ike_sa_manager,
+														TRUE);
+	while (ike_sas->enumerate(ike_sas, &ike_sa))
 	{
-		ike_sa = charon->ike_sa_manager->checkout_by_id(charon->ike_sa_manager,
-														this->reqid, TRUE);
-	}
-	if (ike_sa)
-	{
-		enumerator_t *children, *enumerator;
-		child_sa_t *child_sa;
-		host_t *host;
+		child_sa_t *current, *child_sa = NULL;
 		linked_list_t *vips;
+		status_t status;
+		host_t *host;
 
 		children = ike_sa->create_child_sa_enumerator(ike_sa);
-		while (children->enumerate(children, (void**)&child_sa))
+		while (children->enumerate(children, &current))
 		{
-			if (child_sa->get_reqid(child_sa) == this->reqid)
+			if (current->get_reqid(current) == this->reqid)
 			{
+				child_sa = current;
 				break;
 			}
 		}
 		children->destroy(children);
+
+		if (!child_sa)
+		{
+			continue;
+		}
+
 		DBG2(DBG_JOB, "found CHILD_SA with reqid {%d}", this->reqid);
 
 		ike_sa->set_kmaddress(ike_sa, this->local, this->remote);
@@ -105,27 +110,28 @@ METHOD(job_t, execute, job_requeue_t,
 		host->set_port(host, IKEV2_UDP_PORT);
 		ike_sa->set_other_host(ike_sa, host);
 
-		vips = linked_list_create();
-		enumerator = ike_sa->create_virtual_ip_enumerator(ike_sa, TRUE);
-		while (enumerator->enumerate(enumerator, &host))
-		{
-			vips->insert_last(vips, host);
-		}
-		enumerator->destroy(enumerator);
+		vips = linked_list_create_from_enumerator(
+							ike_sa->create_virtual_ip_enumerator(ike_sa, TRUE));
 
-		if (child_sa->update(child_sa, this->local, this->remote, vips,
-				ike_sa->has_condition(ike_sa, COND_NAT_ANY)) == NOT_SUPPORTED)
+		status = child_sa->update(child_sa, this->local, this->remote, vips,
+								  ike_sa->has_condition(ike_sa, COND_NAT_ANY));
+		switch (status)
 		{
-			ike_sa->rekey_child_sa(ike_sa, child_sa->get_protocol(child_sa),
-								   child_sa->get_spi(child_sa, TRUE));
+			case NOT_SUPPORTED:
+				ike_sa->rekey_child_sa(ike_sa, child_sa->get_protocol(child_sa),
+									   child_sa->get_spi(child_sa, TRUE));
+				break;
+			case SUCCESS:
+				charon->child_sa_manager->remove(charon->child_sa_manager,
+												 child_sa);
+				charon->child_sa_manager->add(charon->child_sa_manager,
+											  child_sa, ike_sa);
+			default:
+				break;
 		}
-		charon->ike_sa_manager->checkin(charon->ike_sa_manager, ike_sa);
 		vips->destroy(vips);
 	}
-	else
-	{
-		DBG1(DBG_JOB, "no CHILD_SA found with reqid {%d}", this->reqid);
-	}
+	ike_sas->destroy(ike_sas);
 	return JOB_REQUEUE_NONE;
 }
 
diff --git a/src/libcharon/processing/jobs/migrate_job.h b/src/libcharon/processing/jobs/migrate_job.h
index 30c0ad0..0f2b9aa 100644
--- a/src/libcharon/processing/jobs/migrate_job.h
+++ b/src/libcharon/processing/jobs/migrate_job.h
@@ -46,7 +46,7 @@ struct migrate_job_t {
  *
  * We use the reqid or the traffic selectors to find a matching CHILD_SA.
  *
- * @param reqid		reqid of the CHILD_SA to acquire
+ * @param reqid		reqid of the CHILD_SA to migrate
  * @param src_ts	source traffic selector to be used in the policy
  * @param dst_ts	destination traffic selector to be used in the policy
  * @param dir		direction of the policy (in|out)
diff --git a/src/libcharon/processing/jobs/rekey_child_sa_job.c b/src/libcharon/processing/jobs/rekey_child_sa_job.c
index 1bf8dc0..8f17d39 100644
--- a/src/libcharon/processing/jobs/rekey_child_sa_job.c
+++ b/src/libcharon/processing/jobs/rekey_child_sa_job.c
@@ -24,17 +24,13 @@ typedef struct private_rekey_child_sa_job_t private_rekey_child_sa_job_t;
  * Private data of an rekey_child_sa_job_t object.
  */
 struct private_rekey_child_sa_job_t {
+
 	/**
 	 * Public rekey_child_sa_job_t interface.
 	 */
 	rekey_child_sa_job_t public;
 
 	/**
-	 * reqid of the child to rekey
-	 */
-	u_int32_t reqid;
-
-	/**
 	 * protocol of the CHILD_SA (ESP/AH)
 	 */
 	protocol_id_t protocol;
@@ -43,11 +39,17 @@ struct private_rekey_child_sa_job_t {
 	 * inbound SPI of the CHILD_SA
 	 */
 	u_int32_t spi;
+
+	/**
+	 * SA destination address
+	 */
+	host_t *dst;
 };
 
 METHOD(job_t, destroy, void,
 	private_rekey_child_sa_job_t *this)
 {
+	this->dst->destroy(this->dst);
 	free(this);
 }
 
@@ -56,12 +58,12 @@ METHOD(job_t, execute, job_requeue_t,
 {
 	ike_sa_t *ike_sa;
 
-	ike_sa = charon->ike_sa_manager->checkout_by_id(charon->ike_sa_manager,
-													this->reqid, TRUE);
+	ike_sa = charon->child_sa_manager->checkout(charon->child_sa_manager,
+									this->protocol, this->spi, this->dst, NULL);
 	if (ike_sa == NULL)
 	{
-		DBG2(DBG_JOB, "CHILD_SA with reqid %d not found for rekeying",
-			 this->reqid);
+		DBG1(DBG_JOB, "CHILD_SA %N/0x%08x/%H not found for rekey",
+			 protocol_id_names, this->protocol, htonl(this->spi), this->dst);
 	}
 	else
 	{
@@ -80,9 +82,8 @@ METHOD(job_t, get_priority, job_priority_t,
 /*
  * Described in header
  */
-rekey_child_sa_job_t *rekey_child_sa_job_create(u_int32_t reqid,
-												protocol_id_t protocol,
-												u_int32_t spi)
+rekey_child_sa_job_t *rekey_child_sa_job_create(protocol_id_t protocol,
+												u_int32_t spi, host_t *dst)
 {
 	private_rekey_child_sa_job_t *this;
 
@@ -94,9 +95,9 @@ rekey_child_sa_job_t *rekey_child_sa_job_create(u_int32_t reqid,
 				.destroy = _destroy,
 			},
 		},
-		.reqid = reqid,
 		.protocol = protocol,
 		.spi = spi,
+		.dst = dst->clone(dst),
 	);
 
 	return &this->public;
diff --git a/src/libcharon/processing/jobs/rekey_child_sa_job.h b/src/libcharon/processing/jobs/rekey_child_sa_job.h
index fcbe65a..364bb5a 100644
--- a/src/libcharon/processing/jobs/rekey_child_sa_job.h
+++ b/src/libcharon/processing/jobs/rekey_child_sa_job.h
@@ -43,15 +43,11 @@ struct rekey_child_sa_job_t {
 /**
  * Creates a job of type REKEY_CHILD_SA.
  *
- * The CHILD_SA is identified by its protocol (AH/ESP) and its
- * inbound SPI.
- *
- * @param reqid		reqid of the CHILD_SA to rekey
  * @param protocol	protocol of the CHILD_SA
  * @param spi		security parameter index of the CHILD_SA
+ * @param dst		SA destination address
  * @return			rekey_child_sa_job_t object
  */
-rekey_child_sa_job_t *rekey_child_sa_job_create(u_int32_t reqid,
-												protocol_id_t protocol,
-												u_int32_t spi);
+rekey_child_sa_job_t *rekey_child_sa_job_create(protocol_id_t protocol,
+												u_int32_t spi, host_t *dst);
 #endif /** REKEY_CHILD_SA_JOB_H_ @}*/
diff --git a/src/libcharon/processing/jobs/rekey_ike_sa_job.c b/src/libcharon/processing/jobs/rekey_ike_sa_job.c
index 516dc5d..403d826 100644
--- a/src/libcharon/processing/jobs/rekey_ike_sa_job.c
+++ b/src/libcharon/processing/jobs/rekey_ike_sa_job.c
@@ -67,7 +67,8 @@ static u_int32_t get_retry_delay(ike_sa_t *ike_sa)
 		enumerator = ike_sa->create_child_sa_enumerator(ike_sa);
 		while (enumerator->enumerate(enumerator, &child_sa))
 		{
-			if (child_sa->get_state(child_sa) != CHILD_INSTALLED)
+			if (child_sa->get_state(child_sa) != CHILD_INSTALLED &&
+				child_sa->get_state(child_sa) != CHILD_REKEYED)
 			{
 				retry = RETRY_INTERVAL - (random() % RETRY_JITTER);
 				DBG1(DBG_IKE, "unable to reauthenticate in CHILD_SA %N state, "
diff --git a/src/libcharon/processing/jobs/update_sa_job.c b/src/libcharon/processing/jobs/update_sa_job.c
index e6d7da2..862506d 100644
--- a/src/libcharon/processing/jobs/update_sa_job.c
+++ b/src/libcharon/processing/jobs/update_sa_job.c
@@ -27,15 +27,26 @@ typedef struct private_update_sa_job_t private_update_sa_job_t;
  * Private data of an update_sa_job_t Object
  */
 struct private_update_sa_job_t {
+
 	/**
 	 * public update_sa_job_t interface
 	 */
 	update_sa_job_t public;
 
 	/**
-	 * reqid of the CHILD_SA
+	 * protocol of the CHILD_SA (ESP/AH)
+	 */
+	protocol_id_t protocol;
+
+	/**
+	 * SPI of the CHILD_SA
 	 */
-	u_int32_t reqid;
+	u_int32_t spi;
+
+	/**
+	 * Old SA destination address
+	 */
+	host_t *dst;
 
 	/**
 	 * New SA address and port
@@ -46,6 +57,7 @@ struct private_update_sa_job_t {
 METHOD(job_t, destroy, void,
 	private_update_sa_job_t *this)
 {
+	this->dst->destroy(this->dst);
 	this->new->destroy(this->new);
 	free(this);
 }
@@ -55,11 +67,12 @@ METHOD(job_t, execute, job_requeue_t,
 {
 	ike_sa_t *ike_sa;
 
-	ike_sa = charon->ike_sa_manager->checkout_by_id(charon->ike_sa_manager,
-													this->reqid, TRUE);
+	ike_sa = charon->child_sa_manager->checkout(charon->child_sa_manager,
+									this->protocol, this->spi, this->dst, NULL);
 	if (ike_sa == NULL)
 	{
-		DBG1(DBG_JOB, "CHILD_SA with reqid %d not found for update", this->reqid);
+		DBG1(DBG_JOB, "CHILD_SA %N/0x%08x/%H not found for update",
+			 protocol_id_names, this->protocol, htonl(this->spi), this->dst);
 	}
 	else
 	{
@@ -78,7 +91,8 @@ METHOD(job_t, get_priority, job_priority_t,
 /*
  * Described in header
  */
-update_sa_job_t *update_sa_job_create(u_int32_t reqid, host_t *new)
+update_sa_job_t *update_sa_job_create(protocol_id_t protocol,
+									  u_int32_t spi, host_t *dst, host_t *new)
 {
 	private_update_sa_job_t *this;
 
@@ -90,10 +104,11 @@ update_sa_job_t *update_sa_job_create(u_int32_t reqid, host_t *new)
 				.destroy = _destroy,
 			},
 		},
-		.reqid = reqid,
-		.new = new,
+		.protocol = protocol,
+		.spi = spi,
+		.dst = dst->clone(dst),
+		.new = new->clone(new),
 	);
 
 	return &this->public;
 }
-
diff --git a/src/libcharon/processing/jobs/update_sa_job.h b/src/libcharon/processing/jobs/update_sa_job.h
index 55a3df8..9c19f5b 100644
--- a/src/libcharon/processing/jobs/update_sa_job.h
+++ b/src/libcharon/processing/jobs/update_sa_job.h
@@ -26,6 +26,7 @@ typedef struct update_sa_job_t update_sa_job_t;
 #include <library.h>
 #include <networking/host.h>
 #include <processing/jobs/job.h>
+#include <config/proposal.h>
 
 /**
  * Update the addresses of an IKE and its CHILD_SAs.
@@ -41,10 +42,13 @@ struct update_sa_job_t {
 /**
  * Creates a job to update IKE and CHILD_SA addresses.
  *
- * @param reqid			reqid of the CHILD_SA
+ * @param protocol		IPsec protocol of SA to update
+ * @param spi			SPI of SA to update
+ * @param dst			old destination host of SA to update
  * @param new			new address and port
  * @return				update_sa_job_t object
  */
-update_sa_job_t *update_sa_job_create(u_int32_t reqid, host_t *new);
+update_sa_job_t *update_sa_job_create(protocol_id_t protocol,
+									  u_int32_t spi, host_t *dst, host_t *new);
 
 #endif /** UPDATE_SA_JOB_H_ @}*/
diff --git a/src/libcharon/sa/authenticator.c b/src/libcharon/sa/authenticator.c
index 8571274..6c3681a 100644
--- a/src/libcharon/sa/authenticator.c
+++ b/src/libcharon/sa/authenticator.c
@@ -31,12 +31,14 @@ ENUM_BEGIN(auth_method_names, AUTH_RSA, AUTH_DSS,
 	"RSA signature",
 	"pre-shared key",
 	"DSS signature");
-ENUM_NEXT(auth_method_names, AUTH_ECDSA_256, AUTH_GSPM, AUTH_DSS,
+ENUM_NEXT(auth_method_names, AUTH_ECDSA_256, AUTH_DS, AUTH_DSS,
 	"ECDSA-256 signature",
 	"ECDSA-384 signature",
 	"ECDSA-521 signature",
-	"secure password method");
-ENUM_NEXT(auth_method_names, AUTH_XAUTH_INIT_PSK, AUTH_HYBRID_RESP_RSA, AUTH_GSPM,
+	"secure password method",
+	"NULL authentication",
+	"digital signature");
+ENUM_NEXT(auth_method_names, AUTH_XAUTH_INIT_PSK, AUTH_HYBRID_RESP_RSA, AUTH_DS,
 	"XAuthInitPSK",
 	"XAuthRespPSK",
 	"XAuthInitRSA",
@@ -99,6 +101,7 @@ authenticator_t *authenticator_create_verifier(
 		case AUTH_ECDSA_256:
 		case AUTH_ECDSA_384:
 		case AUTH_ECDSA_521:
+		case AUTH_DS:
 			return (authenticator_t*)pubkey_authenticator_create_verifier(ike_sa,
 										sent_nonce, received_init, reserved);
 		case AUTH_PSK:
diff --git a/src/libcharon/sa/authenticator.h b/src/libcharon/sa/authenticator.h
index 914f42d..97c042e 100644
--- a/src/libcharon/sa/authenticator.h
+++ b/src/libcharon/sa/authenticator.h
@@ -80,6 +80,16 @@ enum auth_method_t {
 	AUTH_GSPM = 12,
 
 	/**
+	 * NULL Authentication Method as specified in draft-ietf-ipsecme-ikev2-null-auth
+	 */
+	AUTH_NULL = 13,
+
+	/**
+	 * Digital Signature as specified in RFC 7427
+	 */
+	AUTH_DS = 14,
+
+	/**
 	 * IKEv1 initiator XAUTH with PSK, outside of IANA range
 	 */
 	AUTH_XAUTH_INIT_PSK = 256,
diff --git a/src/libcharon/sa/child_sa.c b/src/libcharon/sa/child_sa.c
index a96ab4e..e0db2e6 100644
--- a/src/libcharon/sa/child_sa.c
+++ b/src/libcharon/sa/child_sa.c
@@ -34,6 +34,8 @@ ENUM(child_sa_state_names, CHILD_CREATED, CHILD_DESTROYING,
 	"INSTALLED",
 	"UPDATING",
 	"REKEYING",
+	"REKEYED",
+	"RETRYING",
 	"DELETING",
 	"DESTROYING",
 );
@@ -100,6 +102,16 @@ struct private_child_sa_t {
 	u_int32_t reqid;
 
 	/**
+	 * Did we allocate/confirm and must release the reqid?
+	 */
+	bool reqid_allocated;
+
+	/*
+	 * Unique CHILD_SA identifier
+	 */
+	u_int32_t unique_id;
+
+	/**
 	 * inbound mark used for this child_sa
 	 */
 	mark_t mark_in;
@@ -228,6 +240,12 @@ METHOD(child_sa_t, get_reqid, u_int32_t,
 	return this->reqid;
 }
 
+METHOD(child_sa_t, get_unique_id, u_int32_t,
+	private_child_sa_t *this)
+{
+	return this->unique_id;
+}
+
 METHOD(child_sa_t, get_config, child_cfg_t*,
 	   private_child_sa_t *this)
 {
@@ -602,7 +620,7 @@ METHOD(child_sa_t, alloc_spi, u_int32_t,
 {
 	if (hydra->kernel_interface->get_spi(hydra->kernel_interface,
 										 this->other_addr, this->my_addr,
-										 proto_ike2ip(protocol), this->reqid,
+										 proto_ike2ip(protocol),
 										 &this->my_spi) == SUCCESS)
 	{
 		/* if we allocate a SPI, but then are unable to establish the SA, we
@@ -618,7 +636,7 @@ METHOD(child_sa_t, alloc_cpi, u_int16_t,
 {
 	if (hydra->kernel_interface->get_cpi(hydra->kernel_interface,
 										 this->other_addr, this->my_addr,
-										 this->reqid, &this->my_cpi) == SUCCESS)
+										 &this->my_cpi) == SUCCESS)
 	{
 		return this->my_cpi;
 	}
@@ -632,7 +650,7 @@ METHOD(child_sa_t, install, status_t,
 {
 	u_int16_t enc_alg = ENCR_UNDEFINED, int_alg = AUTH_UNDEFINED, size;
 	u_int16_t esn = NO_EXT_SEQ_NUMBERS;
-	traffic_selector_t *src_ts = NULL, *dst_ts = NULL;
+	linked_list_t *src_ts = NULL, *dst_ts = NULL;
 	time_t now;
 	lifetime_cfg_t *lifetime;
 	u_int32_t tfc = 0;
@@ -680,6 +698,18 @@ METHOD(child_sa_t, install, status_t,
 	this->proposal->get_algorithm(this->proposal, EXTENDED_SEQUENCE_NUMBERS,
 								  &esn, NULL);
 
+	if (!this->reqid_allocated)
+	{
+		status = hydra->kernel_interface->alloc_reqid(hydra->kernel_interface,
+							my_ts, other_ts, this->mark_in, this->mark_out,
+							&this->reqid);
+		if (status != SUCCESS)
+		{
+			return status;
+		}
+		this->reqid_allocated = TRUE;
+	}
+
 	lifetime = this->config->get_lifetime(this->config);
 
 	now = time_monotonic(NULL);
@@ -704,18 +734,16 @@ METHOD(child_sa_t, install, status_t,
 		lifetime->time.rekey = 0;
 	}
 
-	/* BEET requires the bound address from the traffic selectors.
-	 * TODO: We add just the first traffic selector for now, as the
-	 * kernel accepts a single TS per SA only */
+	/* BEET requires the bound address from the traffic selectors */
 	if (inbound)
 	{
-		my_ts->get_first(my_ts, (void**)&dst_ts);
-		other_ts->get_first(other_ts, (void**)&src_ts);
+		dst_ts = my_ts;
+		src_ts = other_ts;
 	}
 	else
 	{
-		my_ts->get_first(my_ts, (void**)&src_ts);
-		other_ts->get_first(other_ts, (void**)&dst_ts);
+		src_ts = my_ts;
+		dst_ts = other_ts;
 	}
 
 	status = hydra->kernel_interface->add_sa(hydra->kernel_interface,
@@ -723,7 +751,7 @@ METHOD(child_sa_t, install, status_t,
 				inbound ? this->mark_in : this->mark_out, tfc,
 				lifetime, enc_alg, encr, int_alg, integ, this->mode,
 				this->ipcomp, cpi, this->config->get_replay_window(this->config),
-				initiator, this->encap, esn, update, src_ts, dst_ts);
+				initiator, this->encap, esn, inbound, update, src_ts, dst_ts);
 
 	free(lifetime);
 
@@ -798,6 +826,19 @@ METHOD(child_sa_t, add_policies, status_t,
 	traffic_selector_t *my_ts, *other_ts;
 	status_t status = SUCCESS;
 
+	if (!this->reqid_allocated)
+	{
+		/* trap policy, get or confirm reqid */
+		status = hydra->kernel_interface->alloc_reqid(
+							hydra->kernel_interface, my_ts_list, other_ts_list,
+							this->mark_in, this->mark_out, &this->reqid);
+		if (status != SUCCESS)
+		{
+			return status;
+		}
+		this->reqid_allocated = TRUE;
+	}
+
 	/* apply traffic selectors */
 	enumerator = my_ts_list->create_enumerator(my_ts_list);
 	while (enumerator->enumerate(enumerator, &my_ts))
@@ -805,12 +846,15 @@ METHOD(child_sa_t, add_policies, status_t,
 		array_insert(this->my_ts, ARRAY_TAIL, my_ts->clone(my_ts));
 	}
 	enumerator->destroy(enumerator);
+	array_sort(this->my_ts, (void*)traffic_selector_cmp, NULL);
+
 	enumerator = other_ts_list->create_enumerator(other_ts_list);
 	while (enumerator->enumerate(enumerator, &other_ts))
 	{
 		array_insert(this->other_ts, ARRAY_TAIL, other_ts->clone(other_ts));
 	}
 	enumerator->destroy(enumerator);
+	array_sort(this->other_ts, (void*)traffic_selector_cmp, NULL);
 
 	if (this->config->install_policy(this->config))
 	{
@@ -1071,6 +1115,22 @@ METHOD(child_sa_t, destroy, void,
 
 	set_state(this, CHILD_DESTROYING);
 
+	if (this->config->install_policy(this->config))
+	{
+		/* delete all policies in the kernel */
+		enumerator = create_policy_enumerator(this);
+		while (enumerator->enumerate(enumerator, &my_ts, &other_ts))
+		{
+			del_policies_internal(this, my_ts, other_ts, priority);
+			if (priority == POLICY_PRIORITY_DEFAULT && require_policy_update())
+			{
+				del_policies_internal(this, my_ts, other_ts,
+									  POLICY_PRIORITY_FALLBACK);
+			}
+		}
+		enumerator->destroy(enumerator);
+	}
+
 	/* delete SAs in the kernel, if they are set up */
 	if (this->my_spi)
 	{
@@ -1087,20 +1147,13 @@ METHOD(child_sa_t, destroy, void,
 					this->mark_out);
 	}
 
-	if (this->config->install_policy(this->config))
+	if (this->reqid_allocated)
 	{
-		/* delete all policies in the kernel */
-		enumerator = create_policy_enumerator(this);
-		while (enumerator->enumerate(enumerator, &my_ts, &other_ts))
+		if (hydra->kernel_interface->release_reqid(hydra->kernel_interface,
+						this->reqid, this->mark_in, this->mark_out) != SUCCESS)
 		{
-			del_policies_internal(this, my_ts, other_ts, priority);
-			if (priority == POLICY_PRIORITY_DEFAULT && require_policy_update())
-			{
-				del_policies_internal(this, my_ts, other_ts,
-									  POLICY_PRIORITY_FALLBACK);
-			}
+			DBG1(DBG_CHD, "releasing reqid %u failed", this->reqid);
 		}
-		enumerator->destroy(enumerator);
 	}
 
 	array_destroy_offset(this->my_ts, offsetof(traffic_selector_t, destroy));
@@ -1151,15 +1204,17 @@ static host_t* get_proxy_addr(child_cfg_t *config, host_t *ike, bool local)
  * Described in header.
  */
 child_sa_t * child_sa_create(host_t *me, host_t* other,
-							 child_cfg_t *config, u_int32_t rekey, bool encap)
+							 child_cfg_t *config, u_int32_t rekey, bool encap,
+							 u_int mark_in, u_int mark_out)
 {
-	static refcount_t reqid = 0;
 	private_child_sa_t *this;
+	static refcount_t unique_id = 0, unique_mark = 0, mark;
 
 	INIT(this,
 		.public = {
 			.get_name = _get_name,
 			.get_reqid = _get_reqid,
+			.get_unique_id = _get_unique_id,
 			.get_config = _get_config,
 			.get_state = _get_state,
 			.set_state = _set_state,
@@ -1201,6 +1256,7 @@ child_sa_t * child_sa_create(host_t *me, host_t* other,
 		.close_action = config->get_close_action(config),
 		.dpd_action = config->get_dpd_action(config),
 		.reqid = config->get_reqid(config),
+		.unique_id = ref_get(&unique_id),
 		.mark_in = config->get_mark(config, TRUE),
 		.mark_out = config->get_mark(config, FALSE),
 		.install_time = time_monotonic(NULL),
@@ -1209,9 +1265,37 @@ child_sa_t * child_sa_create(host_t *me, host_t* other,
 	this->config = config;
 	config->get_ref(config);
 
+	if (mark_in)
+	{
+		this->mark_in.value = mark_in;
+	}
+	if (mark_out)
+	{
+		this->mark_out.value = mark_out;
+	}
+	if (this->mark_in.value == MARK_UNIQUE ||
+		this->mark_out.value == MARK_UNIQUE)
+	{
+		mark = ref_get(&unique_mark);
+		if (this->mark_in.value == MARK_UNIQUE)
+		{
+			this->mark_in.value = mark;
+		}
+		if (this->mark_out.value == MARK_UNIQUE)
+		{
+			this->mark_out.value = mark;
+		}
+	}
+
 	if (!this->reqid)
 	{
-		/* reuse old reqid if we are rekeying an existing CHILD_SA */
+		/* reuse old reqid if we are rekeying an existing CHILD_SA. While the
+		 * reqid cache would find the same reqid for our selectors, this does
+		 * not work in a special case: If an SA is triggered by a trap policy,
+		 * but the negotiated SA gets narrowed, we still must reuse the same
+		 * reqid to successfully "trigger" the SA on the kernel level. Rekeying
+		 * such an SA requires an explicit reqid, as the cache currently knows
+		 * the original selectors only for that reqid. */
 		if (rekey)
 		{
 			this->reqid = rekey;
@@ -1219,22 +1303,9 @@ child_sa_t * child_sa_create(host_t *me, host_t* other,
 		else
 		{
 			this->reqid = charon->traps->find_reqid(charon->traps, config);
-			if (!this->reqid)
-			{
-				this->reqid = ref_get(&reqid);
-			}
 		}
 	}
 
-	if (this->mark_in.value == MARK_REQID)
-	{
-		this->mark_in.value = this->reqid;
-	}
-	if (this->mark_out.value == MARK_REQID)
-	{
-		this->mark_out.value = this->reqid;
-	}
-
 	/* MIPv6 proxy transport mode sets SA endpoints to TS hosts */
 	if (config->get_mode(config) == MODE_TRANSPORT &&
 		config->use_proxy_mode(config))
diff --git a/src/libcharon/sa/child_sa.h b/src/libcharon/sa/child_sa.h
index a0c6c35..debe8eb 100644
--- a/src/libcharon/sa/child_sa.h
+++ b/src/libcharon/sa/child_sa.h
@@ -68,6 +68,16 @@ enum child_sa_state_t {
 	CHILD_REKEYING,
 
 	/**
+	 * CHILD_SA that was rekeyed, but stays installed
+	 */
+	CHILD_REKEYED,
+
+	/**
+	 * CHILD_SA negotiation failed, but gets retried
+	 */
+	CHILD_RETRYING,
+
+	/**
 	 * CHILD_SA in progress of delete
 	 */
 	CHILD_DELETING,
@@ -121,6 +131,16 @@ struct child_sa_t {
 	u_int32_t (*get_reqid)(child_sa_t *this);
 
 	/**
+	 * Get the unique numerical identifier for this CHILD_SA.
+	 *
+	 * While the same reqid might be shared between multiple SAs, the unique_id
+	 * is truly unique for all CHILD_SA instances.
+	 *
+	 * @return			unique CHILD_SA identifier
+	 */
+	u_int32_t (*get_unique_id)(child_sa_t *this);
+
+	/**
 	 * Get the config used to set up this child sa.
 	 *
 	 * @return			child_cfg
@@ -379,9 +399,12 @@ struct child_sa_t {
  * @param config			config to use for this CHILD_SA
  * @param reqid				reqid of old CHILD_SA when rekeying, 0 otherwise
  * @param encap				TRUE to enable UDP encapsulation (NAT traversal)
+ * @param mark_in			explicit inbound mark value to use, 0 for config
+ * @param mark_out			explicit outbound mark value to use, 0 for config
  * @return					child_sa_t object
  */
 child_sa_t * child_sa_create(host_t *me, host_t *other, child_cfg_t *config,
-							 u_int32_t reqid, bool encap);
+							 u_int32_t reqid, bool encap,
+							 u_int mark_in, u_int mark_out);
 
 #endif /** CHILD_SA_H_ @}*/
diff --git a/src/libcharon/sa/child_sa_manager.c b/src/libcharon/sa/child_sa_manager.c
new file mode 100644
index 0000000..071a119
--- /dev/null
+++ b/src/libcharon/sa/child_sa_manager.c
@@ -0,0 +1,333 @@
+/*
+ * Copyright (C) 2014 Martin Willi
+ * Copyright (C) 2014 revosec AG
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * for more details.
+ */
+
+#include "child_sa_manager.h"
+
+#include <daemon.h>
+#include <threading/mutex.h>
+#include <collections/hashtable.h>
+
+typedef struct private_child_sa_manager_t private_child_sa_manager_t;
+
+/**
+ * Private data of an child_sa_manager_t object.
+ */
+struct private_child_sa_manager_t {
+
+	/**
+	 * Public child_sa_manager_t interface.
+	 */
+	child_sa_manager_t public;
+
+	/**
+	 * CHILD_SAs by inbound SPI/dst, child_entry_t => child_entry_t
+	 */
+	hashtable_t *in;
+
+	/**
+	 * CHILD_SAs by outbound SPI/dst, child_entry_t => child_entry_t
+	 */
+	hashtable_t *out;
+
+	/**
+	 * CHILD_SAs by unique ID, child_entry_t => child_entry_t
+	 */
+	hashtable_t *ids;
+
+	/**
+	 * Mutex to access any hashtable
+	 */
+	mutex_t *mutex;
+};
+
+/**
+ * Hashtable entry for a known CHILD_SA
+ */
+typedef struct {
+	/** the associated IKE_SA */
+	ike_sa_id_t *ike_id;
+	/** unique CHILD_SA identifier */
+	u_int32_t unique_id;
+	/** inbound SPI */
+	u_int32_t spi_in;
+	/** outbound SPI */
+	u_int32_t spi_out;
+	/** inbound host address */
+	host_t *host_in;
+	/** outbound host address and port */
+	host_t *host_out;
+	/** IPsec protocol, AH|ESP */
+	protocol_id_t proto;
+} child_entry_t;
+
+/**
+ * Destroy a CHILD_SA entry
+ */
+static void child_entry_destroy(child_entry_t *entry)
+{
+	entry->ike_id->destroy(entry->ike_id);
+	entry->host_in->destroy(entry->host_in);
+	entry->host_out->destroy(entry->host_out);
+	free(entry);
+}
+
+/**
+ * Hashtable hash function for inbound SAs
+ */
+static u_int hash_in(child_entry_t *entry)
+{
+	return chunk_hash_inc(chunk_from_thing(entry->spi_in),
+			chunk_hash_inc(entry->host_in->get_address(entry->host_in),
+			 chunk_hash(chunk_from_thing(entry->proto))));
+}
+
+/**
+ * Hashtable equals function for inbound SAs
+ */
+static bool equals_in(child_entry_t *a, child_entry_t *b)
+{
+	return a->spi_in == b->spi_in &&
+		   a->proto == b->proto &&
+		   a->host_in->ip_equals(a->host_in, b->host_in);
+}
+
+/**
+ * Hashtable hash function for outbound SAs
+ */
+static u_int hash_out(child_entry_t *entry)
+{
+	return chunk_hash_inc(chunk_from_thing(entry->spi_out),
+			chunk_hash_inc(entry->host_out->get_address(entry->host_out),
+			 chunk_hash(chunk_from_thing(entry->proto))));
+}
+
+/**
+ * Hashtable equals function for outbound SAs
+ */
+static bool equals_out(child_entry_t *a, child_entry_t *b)
+{
+	return a->spi_out == b->spi_out &&
+		   a->proto == b->proto &&
+		   a->host_out->ip_equals(a->host_out, b->host_out);
+}
+
+/**
+ * Hashtable hash function for SAs by unique ID
+ */
+static u_int hash_id(child_entry_t *entry)
+{
+	return chunk_hash(chunk_from_thing(entry->unique_id));
+}
+
+/**
+ * Hashtable equals function for SAs by unique ID
+ */
+static bool equals_id(child_entry_t *a, child_entry_t *b)
+{
+	return a->unique_id == b->unique_id;
+}
+
+METHOD(child_sa_manager_t, add, void,
+	private_child_sa_manager_t *this, child_sa_t *child_sa, ike_sa_t *ike_sa)
+{
+	child_entry_t *entry;
+	host_t *in, *out;
+	ike_sa_id_t *id;
+
+	id = ike_sa->get_id(ike_sa);
+	in = ike_sa->get_my_host(ike_sa);
+	out = ike_sa->get_other_host(ike_sa);
+
+	INIT(entry,
+		.ike_id = id->clone(id),
+		.unique_id = child_sa->get_unique_id(child_sa),
+		.proto = child_sa->get_protocol(child_sa),
+		.spi_in = child_sa->get_spi(child_sa, TRUE),
+		.spi_out = child_sa->get_spi(child_sa, FALSE),
+		.host_in = in->clone(in),
+		.host_out = out->clone(out),
+	);
+
+	this->mutex->lock(this->mutex);
+	if (!this->in->get(this->in, entry) &&
+		!this->out->get(this->out, entry))
+	{
+		this->in->put(this->in, entry, entry);
+		this->out->put(this->out, entry, entry);
+		entry = this->ids->put(this->ids, entry, entry);
+	}
+	this->mutex->unlock(this->mutex);
+
+	if (entry)
+	{
+		child_entry_destroy(entry);
+	}
+}
+
+METHOD(child_sa_manager_t, remove_, void,
+	private_child_sa_manager_t *this, child_sa_t *child_sa)
+{
+	child_entry_t *entry, key = {
+		.unique_id = child_sa->get_unique_id(child_sa),
+	};
+
+	this->mutex->lock(this->mutex);
+	entry = this->ids->remove(this->ids, &key);
+	if (entry)
+	{
+		this->in->remove(this->in, entry);
+		this->out->remove(this->out, entry);
+	}
+	this->mutex->unlock(this->mutex);
+
+	if (entry)
+	{
+		child_entry_destroy(entry);
+	}
+}
+
+/**
+ * Check out an IKE_SA for a given CHILD_SA
+ */
+static ike_sa_t *checkout_ikesa(private_child_sa_manager_t *this,
+					ike_sa_id_t *id, u_int32_t unique_id, child_sa_t **child_sa)
+{
+	enumerator_t *enumerator;
+	child_sa_t *current;
+	ike_sa_t *ike_sa;
+	bool found = FALSE;
+
+	ike_sa = charon->ike_sa_manager->checkout(charon->ike_sa_manager, id);
+	id->destroy(id);
+	if (ike_sa)
+	{
+		enumerator = ike_sa->create_child_sa_enumerator(ike_sa);
+		while (enumerator->enumerate(enumerator, &current))
+		{
+			found = current->get_unique_id(current) == unique_id;
+			if (found)
+			{
+				if (child_sa)
+				{
+					*child_sa = current;
+				}
+				break;
+			}
+		}
+		enumerator->destroy(enumerator);
+
+		if (found)
+		{
+			return ike_sa;
+		}
+		charon->ike_sa_manager->checkin(charon->ike_sa_manager, ike_sa);
+	}
+	return NULL;
+}
+
+METHOD(child_sa_manager_t, checkout_by_id, ike_sa_t*,
+	private_child_sa_manager_t *this, u_int32_t unique_id,
+	child_sa_t **child_sa)
+{
+	ike_sa_id_t *id;
+	child_entry_t *entry, key = {
+		.unique_id = unique_id,
+	};
+
+	this->mutex->lock(this->mutex);
+	entry = this->ids->get(this->ids, &key);
+	if (entry)
+	{
+		id = entry->ike_id->clone(entry->ike_id);
+	}
+	this->mutex->unlock(this->mutex);
+
+	if (entry)
+	{
+		return checkout_ikesa(this, id, unique_id, child_sa);
+	}
+	return NULL;
+}
+
+METHOD(child_sa_manager_t, checkout, ike_sa_t*,
+	private_child_sa_manager_t *this, protocol_id_t protocol, u_int32_t spi,
+	host_t *dst, child_sa_t **child_sa)
+{
+	ike_sa_id_t *id;
+	u_int32_t unique_id;
+	child_entry_t *entry, key = {
+		.spi_in = spi,
+		.spi_out = spi,
+		.host_in = dst,
+		.host_out = dst,
+		.proto = protocol,
+	};
+
+	this->mutex->lock(this->mutex);
+	entry = this->in->get(this->in, &key);
+	if (!entry)
+	{
+		entry = this->out->get(this->out, &key);
+	}
+	if (entry)
+	{
+		unique_id = entry->unique_id;
+		id = entry->ike_id->clone(entry->ike_id);
+	}
+	this->mutex->unlock(this->mutex);
+
+	if (entry)
+	{
+		return checkout_ikesa(this, id, unique_id, child_sa);
+	}
+	return NULL;
+}
+
+METHOD(child_sa_manager_t, destroy, void,
+	private_child_sa_manager_t *this)
+{
+	this->in->destroy(this->in);
+	this->out->destroy(this->out);
+	this->ids->destroy(this->ids);
+	this->mutex->destroy(this->mutex);
+	free(this);
+}
+
+/**
+ * See header
+ */
+child_sa_manager_t *child_sa_manager_create()
+{
+	private_child_sa_manager_t *this;
+
+	INIT(this,
+		.public = {
+			.add = _add,
+			.remove = _remove_,
+			.checkout = _checkout,
+			.checkout_by_id = _checkout_by_id,
+			.destroy = _destroy,
+		},
+		.in = hashtable_create((hashtable_hash_t)hash_in,
+							   (hashtable_equals_t)equals_in, 8),
+		.out = hashtable_create((hashtable_hash_t)hash_out,
+							   (hashtable_equals_t)equals_out, 8),
+		.ids = hashtable_create((hashtable_hash_t)hash_id,
+							   (hashtable_equals_t)equals_id, 8),
+		.mutex = mutex_create(MUTEX_TYPE_DEFAULT),
+	);
+
+	return &this->public;
+}
diff --git a/src/libcharon/sa/child_sa_manager.h b/src/libcharon/sa/child_sa_manager.h
new file mode 100644
index 0000000..4d57528
--- /dev/null
+++ b/src/libcharon/sa/child_sa_manager.h
@@ -0,0 +1,89 @@
+/*
+ * Copyright (C) 2014 Martin Willi
+ * Copyright (C) 2014 revosec AG
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * for more details.
+ */
+
+/**
+ * @defgroup child_sa_manager child_sa_manager
+ * @{ @ingroup sa
+ */
+
+#ifndef CHILD_SA_MANAGER_H_
+#define CHILD_SA_MANAGER_H_
+
+#include <sa/ike_sa.h>
+#include <sa/child_sa.h>
+
+typedef struct child_sa_manager_t child_sa_manager_t;
+
+/**
+ * Handle CHILD_SA to IKE_SA relations
+ */
+struct child_sa_manager_t {
+
+	/**
+	 * Register a CHILD_SA/IKE_SA relation.
+	 *
+	 * @param child_sa		CHILD_SA to register
+	 * @param ike_sa		IKE_SA owning the CHILD_SA
+	 */
+	void (*add)(child_sa_manager_t *this, child_sa_t *child_sa, ike_sa_t *ike_sa);
+
+	/**
+	 * Unregister a CHILD_SA/IKE_SA relation.
+	 *
+	 * @param child_sa		CHILD_SA to unregister
+	 */
+	void (*remove)(child_sa_manager_t *this, child_sa_t *child_sa);
+
+	/**
+	 * Find a CHILD_SA and check out the associated IKE_SA by SPI.
+	 *
+	 * On success, the returned IKE_SA must be checked in after use to
+	 * the IKE_SA manager.
+	 *
+	 * @param protocol		IPsec protocol, AH|ESP
+	 * @param spi			SPI of CHILD_SA to check out
+	 * @param dst			SA destination host related to SPI
+	 * @param child_sa		returns CHILD_SA managed by IKE_SA
+	 * @return				IKE_SA, NULL if not found
+	 */
+	ike_sa_t *(*checkout)(child_sa_manager_t *this,
+						  protocol_id_t protocol, u_int32_t spi, host_t *dst,
+						  child_sa_t **child_sa);
+
+	/**
+	 * Find a CHILD_SA and check out the associated IKE_SA by unique_id.
+	 *
+	 * On success, the returned IKE_SA must be checked in after use to
+	 * the IKE_SA manager.
+	 *
+	 * @param unique_id		unique ID of CHILD_SA to check out
+	 * @param child_sa		returns CHILD_SA managed by IKE_SA
+	 * @return				IKE_SA, NULL if not found
+	 */
+	ike_sa_t *(*checkout_by_id)(child_sa_manager_t *this, u_int32_t unique_id,
+								child_sa_t **child_sa);
+
+	/**
+	 * Destroy a child_sa_manager_t.
+	 */
+	void (*destroy)(child_sa_manager_t *this);
+};
+
+/**
+ * Create a child_sa_manager instance.
+ */
+child_sa_manager_t *child_sa_manager_create();
+
+#endif /** CHILD_SA_MANAGER_H_ @}*/
diff --git a/src/libcharon/sa/eap/eap_method.h b/src/libcharon/sa/eap/eap_method.h
index 6242a5a..689c0f9 100644
--- a/src/libcharon/sa/eap/eap_method.h
+++ b/src/libcharon/sa/eap/eap_method.h
@@ -137,6 +137,18 @@ struct eap_method_t {
 	void (*set_identifier) (eap_method_t *this, u_int8_t identifier);
 
 	/**
+	 * Get authentication details performed by this EAP method.
+	 *
+	 * After EAP completion, the auth data contains additional information
+	 * of the authentication process, used certificates etc.
+	 * This method is optional to implement, but if it is, it must return
+	 * a valid auth_cfg.
+	 *
+	 * @return				auth method, internal data
+	 */
+	auth_cfg_t* (*get_auth)(eap_method_t *this);
+
+	/**
 	 * Destroys a eap_method_t object.
 	 */
 	void (*destroy) (eap_method_t *this);
diff --git a/src/libcharon/sa/ike_sa.c b/src/libcharon/sa/ike_sa.c
index d92b9df..3aafa4c 100644
--- a/src/libcharon/sa/ike_sa.c
+++ b/src/libcharon/sa/ike_sa.c
@@ -932,6 +932,7 @@ METHOD(ike_sa_t, update_hosts, void,
 		/* update our address in any case */
 		if (force && !me->equals(me, this->my_host))
 		{
+			charon->bus->ike_update(charon->bus, &this->public, TRUE, me);
 			set_my_host(this, me->clone(me));
 			update = TRUE;
 		}
@@ -945,6 +946,7 @@ METHOD(ike_sa_t, update_hosts, void,
 				(!has_condition(this, COND_NAT_HERE) ||
 				 !has_condition(this, COND_ORIGINAL_INITIATOR)))
 			{
+				charon->bus->ike_update(charon->bus, &this->public, FALSE, other);
 				set_other_host(this, other->clone(other));
 				update = TRUE;
 			}
@@ -964,6 +966,10 @@ METHOD(ike_sa_t, update_hosts, void,
 		enumerator = array_create_enumerator(this->child_sas);
 		while (enumerator->enumerate(enumerator, &child_sa))
 		{
+			charon->child_sa_manager->remove(charon->child_sa_manager, child_sa);
+			charon->child_sa_manager->add(charon->child_sa_manager,
+										  child_sa, &this->public);
+
 			if (child_sa->update(child_sa, this->my_host, this->other_host,
 					vips, has_condition(this, COND_NAT_ANY)) == NOT_SUPPORTED)
 			{
@@ -971,6 +977,7 @@ METHOD(ike_sa_t, update_hosts, void,
 						child_sa->get_protocol(child_sa),
 						child_sa->get_spi(child_sa, TRUE));
 			}
+
 		}
 		enumerator->destroy(enumerator);
 
@@ -1444,6 +1451,8 @@ METHOD(ike_sa_t, add_child_sa, void,
 	private_ike_sa_t *this, child_sa_t *child_sa)
 {
 	array_insert_create(&this->child_sas, ARRAY_TAIL, child_sa);
+	charon->child_sa_manager->add(charon->child_sa_manager,
+								  child_sa, &this->public);
 }
 
 METHOD(ike_sa_t, get_child_sa, child_sa_t*,
@@ -1471,16 +1480,58 @@ METHOD(ike_sa_t, get_child_count, int,
 	return array_count(this->child_sas);
 }
 
+/**
+ * Private data of a create_child_sa_enumerator()
+ */
+typedef struct {
+	/** implements enumerator */
+	enumerator_t public;
+	/** inner array enumerator */
+	enumerator_t *inner;
+	/** current item */
+	child_sa_t *current;
+} child_enumerator_t;
+
+METHOD(enumerator_t, child_enumerate, bool,
+	child_enumerator_t *this, child_sa_t **child_sa)
+{
+	if (this->inner->enumerate(this->inner, &this->current))
+	{
+		*child_sa = this->current;
+		return TRUE;
+	}
+	return FALSE;
+}
+
+METHOD(enumerator_t, child_enumerator_destroy, void,
+	child_enumerator_t *this)
+{
+	this->inner->destroy(this->inner);
+	free(this);
+}
+
 METHOD(ike_sa_t, create_child_sa_enumerator, enumerator_t*,
 	private_ike_sa_t *this)
 {
-	return array_create_enumerator(this->child_sas);
+	child_enumerator_t *enumerator;
+
+	INIT(enumerator,
+		.public = {
+			.enumerate = (void*)_child_enumerate,
+			.destroy = _child_enumerator_destroy,
+		},
+		.inner = array_create_enumerator(this->child_sas),
+	);
+	return &enumerator->public;
 }
 
 METHOD(ike_sa_t, remove_child_sa, void,
 	private_ike_sa_t *this, enumerator_t *enumerator)
 {
-	array_remove_at(this->child_sas, enumerator);
+	child_enumerator_t *ce = (child_enumerator_t*)enumerator;
+
+	charon->child_sa_manager->remove(charon->child_sa_manager, ce->current);
+	array_remove_at(this->child_sas, ce->inner);
 }
 
 METHOD(ike_sa_t, rekey_child_sa, status_t,
@@ -1513,13 +1564,13 @@ METHOD(ike_sa_t, destroy_child_sa, status_t,
 	child_sa_t *child_sa;
 	status_t status = NOT_FOUND;
 
-	enumerator = array_create_enumerator(this->child_sas);
+	enumerator = create_child_sa_enumerator(this);
 	while (enumerator->enumerate(enumerator, (void**)&child_sa))
 	{
 		if (child_sa->get_protocol(child_sa) == protocol &&
 			child_sa->get_spi(child_sa, TRUE) == spi)
 		{
-			array_remove_at(this->child_sas, enumerator);
+			remove_child_sa(this, enumerator);
 			child_sa->destroy(child_sa);
 			status = SUCCESS;
 			break;
@@ -1771,7 +1822,7 @@ METHOD(ike_sa_t, reestablish, status_t,
 #endif /* ME */
 	{
 		/* handle existing CHILD_SAs */
-		enumerator = array_create_enumerator(this->child_sas);
+		enumerator = create_child_sa_enumerator(this);
 		while (enumerator->enumerate(enumerator, (void**)&child_sa))
 		{
 			if (has_condition(this, COND_REAUTHENTICATING))
@@ -1780,7 +1831,7 @@ METHOD(ike_sa_t, reestablish, status_t,
 				{
 					case CHILD_ROUTED:
 					{	/* move routed child directly */
-						array_remove_at(this->child_sas, enumerator);
+						remove_child_sa(this, enumerator);
 						new->add_child_sa(new, child_sa);
 						action = ACTION_NONE;
 						break;
@@ -2209,6 +2260,12 @@ METHOD(ike_sa_t, inherit_post, void,
 		array_insert_create(&this->other_vips, ARRAY_TAIL, vip);
 	}
 
+	/* MOBIKE additional addresses */
+	while (array_remove(other->peer_addresses, ARRAY_HEAD, &vip))
+	{
+		array_insert_create(&this->peer_addresses, ARRAY_TAIL, vip);
+	}
+
 	/* authentication information */
 	enumerator = array_create_enumerator(other->my_auths);
 	while (enumerator->enumerate(enumerator, &cfg))
@@ -2251,7 +2308,8 @@ METHOD(ike_sa_t, inherit_post, void,
 	/* adopt all children */
 	while (array_remove(other->child_sas, ARRAY_HEAD, &child_sa))
 	{
-		array_insert_create(&this->child_sas, ARRAY_TAIL, child_sa);
+		charon->child_sa_manager->remove(charon->child_sa_manager, child_sa);
+		add_child_sa(this, child_sa);
 	}
 
 	/* move pending tasks to the new IKE_SA */
@@ -2296,8 +2354,8 @@ METHOD(ike_sa_t, destroy, void,
 	{
 		if (entry.handler)
 		{
-			hydra->attributes->release(hydra->attributes, entry.handler,
-									   this->other_id, entry.type, entry.data);
+			charon->attributes->release(charon->attributes, entry.handler,
+										&this->public, entry.type, entry.data);
 		}
 		free(entry.data.ptr);
 	}
@@ -2305,6 +2363,7 @@ METHOD(ike_sa_t, destroy, void,
 	 * routes that the CHILD_SA tries to uninstall. */
 	while (array_remove(this->child_sas, ARRAY_TAIL, &child_sa))
 	{
+		charon->child_sa_manager->remove(charon->child_sa_manager, child_sa);
 		child_sa->destroy(child_sa);
 	}
 	while (array_remove(this->my_vips, ARRAY_TAIL, &vip))
@@ -2321,12 +2380,11 @@ METHOD(ike_sa_t, destroy, void,
 		if (this->peer_cfg)
 		{
 			linked_list_t *pools;
-			identification_t *id;
 
-			id = get_other_eap_id(this);
 			pools = linked_list_create_from_enumerator(
 						this->peer_cfg->create_pool_enumerator(this->peer_cfg));
-			hydra->attributes->release_address(hydra->attributes, pools, vip, id);
+			charon->attributes->release_address(charon->attributes,
+												pools, vip, &this->public);
 			pools->destroy(pools);
 		}
 		vip->destroy(vip);
diff --git a/src/libcharon/sa/ike_sa.h b/src/libcharon/sa/ike_sa.h
index c72d873..9dbc805 100644
--- a/src/libcharon/sa/ike_sa.h
+++ b/src/libcharon/sa/ike_sa.h
@@ -131,6 +131,11 @@ enum ike_extension_t {
 	 * peer supports proprietary IKEv1 or standardized IKEv2 fragmentation
 	 */
 	EXT_IKE_FRAGMENTATION = (1<<11),
+
+	/**
+	 * Signature Authentication, RFC 7427
+	 */
+	EXT_SIGNATURE_AUTH = (1<<12),
 };
 
 /**
@@ -936,8 +941,9 @@ struct ike_sa_t {
 	/**
 	 * Reauthenticate the IKE_SA.
 	 *
-	 * Create a completely new IKE_SA with authentication, recreates all children
-	 * within the IKE_SA, closes this IKE_SA.
+	 * Triggers a new IKE_SA that replaces this one. IKEv1 implicitly inherits
+	 * all Quick Modes, while IKEv2 recreates all active and queued CHILD_SAs
+	 * in the new IKE_SA.
 	 *
 	 * @return				DESTROY_ME to destroy the IKE_SA
 	 */
diff --git a/src/libcharon/sa/ike_sa_manager.c b/src/libcharon/sa/ike_sa_manager.c
index bdabc59..13fc74f 100644
--- a/src/libcharon/sa/ike_sa_manager.c
+++ b/src/libcharon/sa/ike_sa_manager.c
@@ -1184,7 +1184,8 @@ METHOD(ike_sa_manager_t, checkout_by_message, ike_sa_t*,
 
 	DBG2(DBG_MGR, "checkout IKE_SA by message");
 
-	if (id->get_responder_spi(id) == 0)
+	if (id->get_responder_spi(id) == 0 &&
+		message->get_message_id(message) == 0)
 	{
 		if (message->get_major_version(message) == IKEV2_MAJOR_VERSION)
 		{
@@ -1383,54 +1384,35 @@ METHOD(ike_sa_manager_t, checkout_by_config, ike_sa_t*,
 }
 
 METHOD(ike_sa_manager_t, checkout_by_id, ike_sa_t*,
-	private_ike_sa_manager_t *this, u_int32_t id, bool child)
+	private_ike_sa_manager_t *this, u_int32_t id)
 {
-	enumerator_t *enumerator, *children;
+	enumerator_t *enumerator;
 	entry_t *entry;
 	ike_sa_t *ike_sa = NULL;
-	child_sa_t *child_sa;
 	u_int segment;
 
-	DBG2(DBG_MGR, "checkout IKE_SA by ID");
+	DBG2(DBG_MGR, "checkout IKE_SA by ID %u", id);
 
 	enumerator = create_table_enumerator(this);
 	while (enumerator->enumerate(enumerator, &entry, &segment))
 	{
 		if (wait_for_entry(this, entry, segment))
 		{
-			/* look for a child with such a reqid ... */
-			if (child)
-			{
-				children = entry->ike_sa->create_child_sa_enumerator(entry->ike_sa);
-				while (children->enumerate(children, (void**)&child_sa))
-				{
-					if (child_sa->get_reqid(child_sa) == id)
-					{
-						ike_sa = entry->ike_sa;
-						break;
-					}
-				}
-				children->destroy(children);
-			}
-			else /* ... or for a IKE_SA with such a unique id */
-			{
-				if (entry->ike_sa->get_unique_id(entry->ike_sa) == id)
-				{
-					ike_sa = entry->ike_sa;
-				}
-			}
-			/* got one, return */
-			if (ike_sa)
+			if (entry->ike_sa->get_unique_id(entry->ike_sa) == id)
 			{
+				ike_sa = entry->ike_sa;
 				entry->checked_out = TRUE;
-				DBG2(DBG_MGR, "IKE_SA %s[%u] successfully checked out",
-						ike_sa->get_name(ike_sa), ike_sa->get_unique_id(ike_sa));
 				break;
 			}
 		}
 	}
 	enumerator->destroy(enumerator);
 
+	if (ike_sa)
+	{
+		DBG2(DBG_MGR, "IKE_SA %s[%u] successfully checked out",
+			 ike_sa->get_name(ike_sa), ike_sa->get_unique_id(ike_sa));
+	}
 	charon->bus->set_sa(charon->bus, ike_sa);
 	return ike_sa;
 }
@@ -1746,29 +1728,45 @@ METHOD(ike_sa_manager_t, create_id_enumerator, enumerator_t*,
 }
 
 /**
- * Move all CHILD_SAs from old to new
+ * Move all CHILD_SAs and virtual IPs from old to new
  */
-static void adopt_children(ike_sa_t *old, ike_sa_t *new)
+static void adopt_children_and_vips(ike_sa_t *old, ike_sa_t *new)
 {
 	enumerator_t *enumerator;
 	child_sa_t *child_sa;
+	host_t *vip;
+	int chcount = 0, vipcount = 0;
+
 
 	enumerator = old->create_child_sa_enumerator(old);
 	while (enumerator->enumerate(enumerator, &child_sa))
 	{
 		old->remove_child_sa(old, enumerator);
 		new->add_child_sa(new, child_sa);
+		chcount++;
 	}
 	enumerator->destroy(enumerator);
-}
 
-/**
- * Check if the replaced IKE_SA might get reauthenticated from host
- */
-static bool is_ikev1_reauth(ike_sa_t *duplicate, host_t *host)
-{
-	return duplicate->get_version(duplicate) == IKEV1 &&
-		   host->equals(host, duplicate->get_other_host(duplicate));
+	enumerator = old->create_virtual_ip_enumerator(old, FALSE);
+	while (enumerator->enumerate(enumerator, &vip))
+	{
+		new->add_virtual_ip(new, FALSE, vip);
+		vipcount++;
+	}
+	enumerator->destroy(enumerator);
+	/* this does not release the addresses, which is good, but it does trigger
+	 * an assign_vips(FALSE) event... */
+	old->clear_virtual_ips(old, FALSE);
+	/* ...trigger the analogous event on the new SA */
+	charon->bus->set_sa(charon->bus, new);
+	charon->bus->assign_vips(charon->bus, new, TRUE);
+	charon->bus->set_sa(charon->bus, old);
+
+	if (chcount || vipcount)
+	{
+		DBG1(DBG_IKE, "detected reauth of existing IKE_SA, adopting %d "
+			 "children and %d virtual IPs", chcount, vipcount);
+	}
 }
 
 /**
@@ -1780,13 +1778,20 @@ static status_t enforce_replace(private_ike_sa_manager_t *this,
 {
 	charon->bus->alert(charon->bus, ALERT_UNIQUE_REPLACE);
 
-	if (is_ikev1_reauth(duplicate, host))
+	if (host->equals(host, duplicate->get_other_host(duplicate)))
 	{
 		/* looks like a reauthentication attempt */
-		adopt_children(duplicate, new);
+		if (!new->has_condition(new, COND_INIT_CONTACT_SEEN) &&
+			new->get_version(new) == IKEV1)
+		{
+			/* IKEv1 implicitly takes over children, IKEv2 recreates them
+			 * explicitly. */
+			adopt_children_and_vips(duplicate, new);
+		}
 		/* For IKEv1 we have to delay the delete for the old IKE_SA. Some
 		 * peers need to complete the new SA first, otherwise the quick modes
-		 * might get lost. */
+		 * might get lost. For IKEv2 we do the same, as we want overlapping
+		 * CHILD_SAs to keep connectivity up. */
 		lib->scheduler->schedule_job(lib->scheduler, (job_t*)
 			delete_ike_sa_job_create(duplicate->get_id(duplicate), TRUE), 10);
 		return SUCCESS;
@@ -1851,7 +1856,9 @@ METHOD(ike_sa_manager_t, check_uniqueness, bool,
 													 other, other_host);
 							break;
 						case UNIQUE_KEEP:
-							if (!is_ikev1_reauth(duplicate, other_host))
+							/* potential reauthentication? */
+							if (!other_host->equals(other_host,
+										duplicate->get_other_host(duplicate)))
 							{
 								cancel = TRUE;
 								/* we keep the first IKE_SA and delete all
diff --git a/src/libcharon/sa/ike_sa_manager.h b/src/libcharon/sa/ike_sa_manager.h
index a68ae77..f259d8e 100644
--- a/src/libcharon/sa/ike_sa_manager.h
+++ b/src/libcharon/sa/ike_sa_manager.h
@@ -129,19 +129,15 @@ struct ike_sa_manager_t {
 	/**
 	 * Check out an IKE_SA a unique ID.
 	 *
-	 * Every IKE_SA and every CHILD_SA is uniquely identified by an ID.
-	 * These checkout function uses, depending
-	 * on the child parameter, the unique ID of the IKE_SA or the reqid
-	 * of one of a IKE_SAs CHILD_SA.
+	 * Every IKE_SA is uniquely identified by a numerical ID. This checkout
+	 * function uses the unique ID of the IKE_SA to check it out.
 	 *
 	 * @param id				unique ID of the object
-	 * @param child				TRUE to use CHILD, FALSE to use IKE_SA
 	 * @return
 	 * 							- checked out IKE_SA, if found
 	 * 							- NULL, if not found
 	 */
-	ike_sa_t* (*checkout_by_id) (ike_sa_manager_t* this, u_int32_t id,
-								 bool child);
+	ike_sa_t* (*checkout_by_id) (ike_sa_manager_t* this, u_int32_t id);
 
 	/**
 	 * Check out an IKE_SA by the policy/connection name.
diff --git a/src/libcharon/sa/ikev1/authenticators/psk_v1_authenticator.c b/src/libcharon/sa/ikev1/authenticators/psk_v1_authenticator.c
index aa966cd..bb187f0 100644
--- a/src/libcharon/sa/ikev1/authenticators/psk_v1_authenticator.c
+++ b/src/libcharon/sa/ikev1/authenticators/psk_v1_authenticator.c
@@ -74,7 +74,10 @@ METHOD(authenticator_t, build, status_t,
 	keymat_v1_t *keymat;
 	chunk_t hash, dh;
 
-	this->dh->get_my_public_value(this->dh, &dh);
+	if (!this->dh->get_my_public_value(this->dh, &dh))
+	{
+		return FAILED;
+	}
 	keymat = (keymat_v1_t*)this->ike_sa->get_keymat(this->ike_sa);
 	if (!keymat->get_hash(keymat, this->initiator, dh, this->dh_value,
 					this->ike_sa->get_id(this->ike_sa), this->sa_payload,
@@ -108,7 +111,10 @@ METHOD(authenticator_t, process, status_t,
 		return FAILED;
 	}
 
-	this->dh->get_my_public_value(this->dh, &dh);
+	if (!this->dh->get_my_public_value(this->dh, &dh))
+	{
+		return FAILED;
+	}
 	keymat = (keymat_v1_t*)this->ike_sa->get_keymat(this->ike_sa);
 	if (!keymat->get_hash(keymat, !this->initiator, this->dh_value, dh,
 					this->ike_sa->get_id(this->ike_sa), this->sa_payload,
diff --git a/src/libcharon/sa/ikev1/authenticators/pubkey_v1_authenticator.c b/src/libcharon/sa/ikev1/authenticators/pubkey_v1_authenticator.c
index bfe5ff4..52228ef 100644
--- a/src/libcharon/sa/ikev1/authenticators/pubkey_v1_authenticator.c
+++ b/src/libcharon/sa/ikev1/authenticators/pubkey_v1_authenticator.c
@@ -94,7 +94,11 @@ METHOD(authenticator_t, build, status_t,
 		return NOT_FOUND;
 	}
 
-	this->dh->get_my_public_value(this->dh, &dh);
+	if (!this->dh->get_my_public_value(this->dh, &dh))
+	{
+		private->destroy(private);
+		return FAILED;
+	}
 	keymat = (keymat_v1_t*)this->ike_sa->get_keymat(this->ike_sa);
 	if (!keymat->get_hash(keymat, this->initiator, dh, this->dh_value,
 					this->ike_sa->get_id(this->ike_sa), this->sa_payload,
@@ -152,7 +156,10 @@ METHOD(authenticator_t, process, status_t,
 	}
 
 	id = this->ike_sa->get_other_id(this->ike_sa);
-	this->dh->get_my_public_value(this->dh, &dh);
+	if (!this->dh->get_my_public_value(this->dh, &dh))
+	{
+		return FAILED;
+	}
 	keymat = (keymat_v1_t*)this->ike_sa->get_keymat(this->ike_sa);
 	if (!keymat->get_hash(keymat, !this->initiator, this->dh_value, dh,
 					this->ike_sa->get_id(this->ike_sa), this->sa_payload,
diff --git a/src/libcharon/sa/ikev1/keymat_v1.c b/src/libcharon/sa/ikev1/keymat_v1.c
index 619d197..f5a91db 100644
--- a/src/libcharon/sa/ikev1/keymat_v1.c
+++ b/src/libcharon/sa/ikev1/keymat_v1.c
@@ -425,7 +425,7 @@ METHOD(keymat_v1_t, derive_ike_keys, bool,
 		return FALSE;
 	}
 
-	if (dh->get_shared_secret(dh, &g_xy) != SUCCESS)
+	if (!dh->get_shared_secret(dh, &g_xy))
 	{
 		return FALSE;
 	}
@@ -560,7 +560,10 @@ METHOD(keymat_v1_t, derive_ike_keys, bool,
 		return FALSE;
 	}
 
-	dh->get_my_public_value(dh, &dh_me);
+	if (!dh->get_my_public_value(dh, &dh_me))
+	{
+		return FALSE;
+	}
 	g_xi = this->initiator ? dh_me : dh_other;
 	g_xr = this->initiator ? dh_other : dh_me;
 
@@ -661,7 +664,7 @@ METHOD(keymat_v1_t, derive_child_keys, bool,
 	protocol = proposal->get_protocol(proposal);
 	if (dh)
 	{
-		if (dh->get_shared_secret(dh, &secret) != SUCCESS)
+		if (!dh->get_shared_secret(dh, &secret))
 		{
 			return FALSE;
 		}
diff --git a/src/libcharon/sa/ikev1/phase1.c b/src/libcharon/sa/ikev1/phase1.c
index d01a831..c968b2a 100644
--- a/src/libcharon/sa/ikev1/phase1.c
+++ b/src/libcharon/sa/ikev1/phase1.c
@@ -694,7 +694,13 @@ METHOD(phase1_t, add_nonce_ke, bool,
 	nonce_gen_t *nonceg;
 	chunk_t nonce;
 
-	ke_payload = ke_payload_create_from_diffie_hellman(PLV1_KEY_EXCHANGE, this->dh);
+	ke_payload = ke_payload_create_from_diffie_hellman(PLV1_KEY_EXCHANGE,
+													   this->dh);
+	if (!ke_payload)
+	{
+		DBG1(DBG_IKE, "creating KE payload failed");
+		return FALSE;
+	}
 	message->add_payload(message, &ke_payload->payload_interface);
 
 	nonceg = this->keymat->keymat.create_nonce_gen(&this->keymat->keymat);
@@ -739,7 +745,11 @@ METHOD(phase1_t, get_nonce_ke, bool,
 		return FALSE;
 	}
 	this->dh_value = chunk_clone(ke_payload->get_key_exchange_data(ke_payload));
-	this->dh->set_other_public_value(this->dh, this->dh_value);
+	if (!this->dh->set_other_public_value(this->dh, this->dh_value))
+	{
+		DBG1(DBG_IKE, "unable to apply received KE value");
+		return FALSE;
+	}
 
 	nonce_payload = (nonce_payload_t*)message->get_payload(message, PLV1_NONCE);
 	if (!nonce_payload)
diff --git a/src/libcharon/sa/ikev1/task_manager_v1.c b/src/libcharon/sa/ikev1/task_manager_v1.c
index 0f8e8bc..cb22bf6 100644
--- a/src/libcharon/sa/ikev1/task_manager_v1.c
+++ b/src/libcharon/sa/ikev1/task_manager_v1.c
@@ -1596,7 +1596,8 @@ static bool is_redundant(private_task_manager_t *this, child_sa_t *child_sa)
 				child_sa->get_lifetime(child_sa, FALSE))
 		{
 			DBG1(DBG_IKE, "deleting redundant CHILD_SA %s{%d}",
-				 child_sa->get_name(child_sa), child_sa->get_reqid(child_sa));
+				 child_sa->get_name(child_sa),
+				 child_sa->get_unique_id(child_sa));
 			redundant = TRUE;
 			break;
 		}
@@ -1647,6 +1648,8 @@ METHOD(task_manager_t, queue_child_rekey, void,
 			task = quick_mode_create(this->ike_sa, cfg->get_ref(cfg),
 				get_first_ts(child_sa, TRUE), get_first_ts(child_sa, FALSE));
 			task->use_reqid(task, child_sa->get_reqid(child_sa));
+			task->use_marks(task, child_sa->get_mark(child_sa, TRUE).value,
+							child_sa->get_mark(child_sa, FALSE).value);
 			task->rekey(task, child_sa->get_spi(child_sa, TRUE));
 
 			queue_task(this, &task->task);
diff --git a/src/libcharon/sa/ikev1/tasks/isakmp_delete.c b/src/libcharon/sa/ikev1/tasks/isakmp_delete.c
index bea0428..a56805a 100644
--- a/src/libcharon/sa/ikev1/tasks/isakmp_delete.c
+++ b/src/libcharon/sa/ikev1/tasks/isakmp_delete.c
@@ -1,4 +1,7 @@
 /*
+ * Copyright (C) 2015 Tobias Brunner
+ * Hochschule fuer Technik Rapperswil
+ *
  * Copyright (C) 2011 Martin Willi
  * Copyright (C) 2011 revosec AG
  *
@@ -74,6 +77,42 @@ METHOD(task_t, process_i, status_t,
 METHOD(task_t, process_r, status_t,
 	private_isakmp_delete_t *this, message_t *message)
 {
+	enumerator_t *payloads;
+	payload_t *payload;
+	delete_payload_t *delete_payload;
+	ike_sa_id_t *id;
+	u_int64_t spi_i, spi_r;
+	bool found = FALSE;
+
+	/* some peers send DELETE payloads for other IKE_SAs, e.g. those for expired
+	 * ones after a rekeyeing, make sure the SPIs match */
+	id = this->ike_sa->get_id(this->ike_sa);
+	payloads = message->create_payload_enumerator(message);
+	while (payloads->enumerate(payloads, &payload))
+	{
+		if (payload->get_type(payload) == PLV1_DELETE)
+		{
+			delete_payload = (delete_payload_t*)payload;
+			if (!delete_payload->get_ike_spi(delete_payload, &spi_i, &spi_r))
+			{
+				continue;
+			}
+			if (id->get_initiator_spi(id) == spi_i &&
+				id->get_responder_spi(id) == spi_r)
+			{
+				found = TRUE;
+				break;
+			}
+		}
+	}
+	payloads->destroy(payloads);
+
+	if (!found)
+	{
+		DBG1(DBG_IKE, "received DELETE for different IKE_SA, ignored");
+		return SUCCESS;
+	}
+
 	DBG1(DBG_IKE, "received DELETE for IKE_SA %s[%d]",
 		 this->ike_sa->get_name(this->ike_sa),
 		 this->ike_sa->get_unique_id(this->ike_sa));
diff --git a/src/libcharon/sa/ikev1/tasks/main_mode.c b/src/libcharon/sa/ikev1/tasks/main_mode.c
index 2fb4c69..3ea4a2a 100644
--- a/src/libcharon/sa/ikev1/tasks/main_mode.c
+++ b/src/libcharon/sa/ikev1/tasks/main_mode.c
@@ -205,6 +205,43 @@ static status_t send_delete(private_main_mode_t *this)
 	return ALREADY_DONE;
 }
 
+/**
+ * Add an INITIAL_CONTACT notify if first contact with peer
+ */
+static void add_initial_contact(private_main_mode_t *this, message_t *message,
+								identification_t *idi)
+{
+	identification_t *idr;
+	host_t *host;
+	notify_payload_t *notify;
+	ike_sa_id_t *ike_sa_id;
+	u_int64_t spi_i, spi_r;
+	chunk_t spi;
+
+	idr = this->ph1->get_id(this->ph1, this->peer_cfg, FALSE);
+	if (idr && !idr->contains_wildcards(idr))
+	{
+		if (this->peer_cfg->get_unique_policy(this->peer_cfg) != UNIQUE_NO &&
+			this->peer_cfg->get_unique_policy(this->peer_cfg) != UNIQUE_NEVER)
+		{
+			host = this->ike_sa->get_other_host(this->ike_sa);
+			if (!charon->ike_sa_manager->has_contact(charon->ike_sa_manager,
+										idi, idr, host->get_family(host)))
+			{
+				notify = notify_payload_create_from_protocol_and_type(
+								PLV1_NOTIFY, PROTO_IKE, INITIAL_CONTACT_IKEV1);
+				ike_sa_id = this->ike_sa->get_id(this->ike_sa);
+				spi_i = ike_sa_id->get_initiator_spi(ike_sa_id);
+				spi_r = ike_sa_id->get_responder_spi(ike_sa_id);
+				spi = chunk_cata("cc", chunk_from_thing(spi_i),
+								 chunk_from_thing(spi_r));
+				notify->set_spi_data(notify, spi);
+				message->add_payload(message, (payload_t*)notify);
+			}
+		}
+	}
+}
+
 METHOD(task_t, build_i, status_t,
 	private_main_mode_t *this, message_t *message)
 {
@@ -311,6 +348,8 @@ METHOD(task_t, build_i, status_t,
 				return send_notify(this, AUTHENTICATION_FAILED);
 			}
 
+			add_initial_contact(this, message, id);
+
 			this->state = MM_AUTH;
 			return NEED_MORE;
 		}
diff --git a/src/libcharon/sa/ikev1/tasks/mode_config.c b/src/libcharon/sa/ikev1/tasks/mode_config.c
index 94026b9..d0994a9 100644
--- a/src/libcharon/sa/ikev1/tasks/mode_config.c
+++ b/src/libcharon/sa/ikev1/tasks/mode_config.c
@@ -16,7 +16,6 @@
 #include "mode_config.h"
 
 #include <daemon.h>
-#include <hydra.h>
 #include <encoding/payloads/cp_payload.h>
 
 typedef struct private_mode_config_t private_mode_config_t;
@@ -136,9 +135,8 @@ static void handle_attribute(private_mode_config_t *this,
 	enumerator->destroy(enumerator);
 
 	/* and pass it to the handle function */
-	handler = hydra->attributes->handle(hydra->attributes,
-							this->ike_sa->get_other_id(this->ike_sa), handler,
-							ca->get_type(ca), ca->get_chunk(ca));
+	handler = charon->attributes->handle(charon->attributes,
+					this->ike_sa, handler, ca->get_type(ca), ca->get_chunk(ca));
 	this->ike_sa->add_configuration_attribute(this->ike_sa,
 							handler, ca->get_type(ca), ca->get_chunk(ca));
 }
@@ -326,9 +324,8 @@ static status_t build_request(private_mode_config_t *this, message_t *message)
 		enumerator->destroy(enumerator);
 	}
 
-	enumerator = hydra->attributes->create_initiator_enumerator(
-								hydra->attributes,
-								this->ike_sa->get_other_id(this->ike_sa), vips);
+	enumerator = charon->attributes->create_initiator_enumerator(
+										charon->attributes, this->ike_sa, vips);
 	while (enumerator->enumerate(enumerator, &handler, &type, &data))
 	{
 		add_attribute(this, cp, type, data, handler);
@@ -353,7 +350,7 @@ static status_t build_set(private_mode_config_t *this, message_t *message)
 	cp_payload_t *cp;
 	peer_cfg_t *config;
 	identification_t *id;
-	linked_list_t *pools;
+	linked_list_t *pools, *migrated, *vips;
 	host_t *any4, *any6, *found;
 	char *name;
 
@@ -361,45 +358,62 @@ static status_t build_set(private_mode_config_t *this, message_t *message)
 
 	id = this->ike_sa->get_other_eap_id(this->ike_sa);
 	config = this->ike_sa->get_peer_cfg(this->ike_sa);
-	any4 = host_create_any(AF_INET);
-	any6 = host_create_any(AF_INET6);
 
+	/* if we migrated virtual IPs during reauthentication, reassign them */
+	migrated = linked_list_create_from_enumerator(
+						this->ike_sa->create_virtual_ip_enumerator(this->ike_sa,
+																   FALSE));
+	vips = migrated->clone_offset(migrated, offsetof(host_t, clone));
+	migrated->destroy(migrated);
 	this->ike_sa->clear_virtual_ips(this->ike_sa, FALSE);
 
 	/* in push mode, we ask each configured pool for an address */
-	enumerator = config->create_pool_enumerator(config);
-	while (enumerator->enumerate(enumerator, &name))
+	if (!vips->get_count(vips))
 	{
-		pools = linked_list_create_with_items(name, NULL);
-		/* try IPv4, then IPv6 */
-		found = hydra->attributes->acquire_address(hydra->attributes,
-												   pools, id, any4);
-		if (!found)
-		{
-			found = hydra->attributes->acquire_address(hydra->attributes,
-													   pools, id, any6);
-		}
-		pools->destroy(pools);
-		if (found)
+		any4 = host_create_any(AF_INET);
+		any6 = host_create_any(AF_INET6);
+		enumerator = config->create_pool_enumerator(config);
+		while (enumerator->enumerate(enumerator, &name))
 		{
-			DBG1(DBG_IKE, "assigning virtual IP %H to peer '%Y'", found, id);
-			this->ike_sa->add_virtual_ip(this->ike_sa, FALSE, found);
-			cp->add_attribute(cp, build_vip(found));
-			this->vips->insert_last(this->vips, found);
+			pools = linked_list_create_with_items(name, NULL);
+			/* try IPv4, then IPv6 */
+			found = charon->attributes->acquire_address(charon->attributes,
+													pools, this->ike_sa, any4);
+			if (!found)
+			{
+				found = charon->attributes->acquire_address(charon->attributes,
+													pools, this->ike_sa, any6);
+			}
+			pools->destroy(pools);
+			if (found)
+			{
+				vips->insert_last(vips, found);
+			}
 		}
+		enumerator->destroy(enumerator);
+		any4->destroy(any4);
+		any6->destroy(any6);
 	}
-	enumerator->destroy(enumerator);
 
-	any4->destroy(any4);
-	any6->destroy(any6);
+	enumerator = vips->create_enumerator(vips);
+	while (enumerator->enumerate(enumerator, &found))
+	{
+		DBG1(DBG_IKE, "assigning virtual IP %H to peer '%Y'", found, id);
+		this->ike_sa->add_virtual_ip(this->ike_sa, FALSE, found);
+		cp->add_attribute(cp, build_vip(found));
+		this->vips->insert_last(this->vips, found);
+		vips->remove_at(vips, enumerator);
+	}
+	enumerator->destroy(enumerator);
+	vips->destroy(vips);
 
 	charon->bus->assign_vips(charon->bus, this->ike_sa, TRUE);
 
 	/* query registered providers for additional attributes to include */
 	pools = linked_list_create_from_enumerator(
 									config->create_pool_enumerator(config));
-	enumerator = hydra->attributes->create_responder_enumerator(
-									hydra->attributes, pools, id, this->vips);
+	enumerator = charon->attributes->create_responder_enumerator(
+						charon->attributes, pools, this->ike_sa, this->vips);
 	while (enumerator->enumerate(enumerator, &type, &value))
 	{
 		add_attribute(this, cp, type, value, NULL);
@@ -458,6 +472,28 @@ METHOD(task_t, process_r, status_t,
 }
 
 /**
+ * Assign a migrated virtual IP
+ */
+static host_t *assign_migrated_vip(linked_list_t *migrated, host_t *requested)
+{
+	enumerator_t *enumerator;
+	host_t *found = NULL, *vip;
+
+	enumerator = migrated->create_enumerator(migrated);
+	while (enumerator->enumerate(enumerator, &vip))
+	{
+		if (vip->ip_equals(vip, requested))
+		{
+			migrated->remove_at(migrated, enumerator);
+			found = vip;
+			break;
+		}
+	}
+	enumerator->destroy(enumerator);
+	return found;
+}
+
+/**
  * Build CFG_REPLY message after receiving CFG_REQUEST
  */
 static status_t build_reply(private_mode_config_t *this, message_t *message)
@@ -468,29 +504,35 @@ static status_t build_reply(private_mode_config_t *this, message_t *message)
 	cp_payload_t *cp;
 	peer_cfg_t *config;
 	identification_t *id;
-	linked_list_t *vips, *pools;
-	host_t *requested;
+	linked_list_t *vips, *pools, *migrated;
+	host_t *requested, *found;
 
 	cp = cp_payload_create_type(PLV1_CONFIGURATION, CFG_REPLY);
 
 	id = this->ike_sa->get_other_eap_id(this->ike_sa);
 	config = this->ike_sa->get_peer_cfg(this->ike_sa);
-	vips = linked_list_create();
 	pools = linked_list_create_from_enumerator(
 									config->create_pool_enumerator(config));
-
+	/* if we migrated virtual IPs during reauthentication, reassign them */
+	vips = linked_list_create_from_enumerator(
+						this->ike_sa->create_virtual_ip_enumerator(this->ike_sa,
+																   FALSE));
+	migrated = vips->clone_offset(vips, offsetof(host_t, clone));
+	vips->destroy(vips);
 	this->ike_sa->clear_virtual_ips(this->ike_sa, FALSE);
 
+	vips = linked_list_create();
 	enumerator = this->vips->create_enumerator(this->vips);
 	while (enumerator->enumerate(enumerator, &requested))
 	{
-		host_t *found = NULL;
-
-		/* query all pools until we get an address */
 		DBG1(DBG_IKE, "peer requested virtual IP %H", requested);
 
-		found = hydra->attributes->acquire_address(hydra->attributes,
-												   pools, id, requested);
+		found = assign_migrated_vip(migrated, requested);
+		if (!found)
+		{
+			found = charon->attributes->acquire_address(charon->attributes,
+											pools, this->ike_sa, requested);
+		}
 		if (found)
 		{
 			DBG1(DBG_IKE, "assigning virtual IP %H to peer '%Y'", found, id);
@@ -509,8 +551,8 @@ static status_t build_reply(private_mode_config_t *this, message_t *message)
 	charon->bus->assign_vips(charon->bus, this->ike_sa, TRUE);
 
 	/* query registered providers for additional attributes to include */
-	enumerator = hydra->attributes->create_responder_enumerator(
-											hydra->attributes, pools, id, vips);
+	enumerator = charon->attributes->create_responder_enumerator(
+								charon->attributes, pools, this->ike_sa, vips);
 	while (enumerator->enumerate(enumerator, &type, &value))
 	{
 		cp->add_attribute(cp,
@@ -518,6 +560,15 @@ static status_t build_reply(private_mode_config_t *this, message_t *message)
 												 type, value));
 	}
 	enumerator->destroy(enumerator);
+	/* if a client did not re-request all adresses, release them */
+	enumerator = migrated->create_enumerator(migrated);
+	while (enumerator->enumerate(enumerator, &found))
+	{
+		charon->attributes->release_address(charon->attributes,
+											pools, found, this->ike_sa);
+	}
+	enumerator->destroy(enumerator);
+	migrated->destroy_offset(migrated, offsetof(host_t, destroy));
 	vips->destroy_offset(vips, offsetof(host_t, destroy));
 	pools->destroy(pools);
 
diff --git a/src/libcharon/sa/ikev1/tasks/quick_delete.c b/src/libcharon/sa/ikev1/tasks/quick_delete.c
index 499081c..1b95a8b 100644
--- a/src/libcharon/sa/ikev1/tasks/quick_delete.c
+++ b/src/libcharon/sa/ikev1/tasks/quick_delete.c
@@ -105,7 +105,7 @@ static bool delete_child(private_quick_delete_t *this, protocol_id_t protocol,
 		this->spi = spi = child_sa->get_spi(child_sa, TRUE);
 	}
 
-	rekeyed = child_sa->get_state(child_sa) == CHILD_REKEYING;
+	rekeyed = child_sa->get_state(child_sa) == CHILD_REKEYED;
 	child_sa->set_state(child_sa, CHILD_DELETING);
 
 	my_ts = linked_list_create_from_enumerator(
@@ -116,7 +116,7 @@ static bool delete_child(private_quick_delete_t *this, protocol_id_t protocol,
 	{
 		DBG0(DBG_IKE, "closing expired CHILD_SA %s{%d} "
 			 "with SPIs %.8x_i %.8x_o and TS %#R=== %#R",
-			 child_sa->get_name(child_sa), child_sa->get_reqid(child_sa),
+			 child_sa->get_name(child_sa), child_sa->get_unique_id(child_sa),
 			 ntohl(child_sa->get_spi(child_sa, TRUE)),
 			 ntohl(child_sa->get_spi(child_sa, FALSE)), my_ts, other_ts);
 	}
@@ -127,7 +127,7 @@ static bool delete_child(private_quick_delete_t *this, protocol_id_t protocol,
 
 		DBG0(DBG_IKE, "closing CHILD_SA %s{%d} with SPIs "
 			 "%.8x_i (%llu bytes) %.8x_o (%llu bytes) and TS %#R=== %#R",
-			 child_sa->get_name(child_sa), child_sa->get_reqid(child_sa),
+			 child_sa->get_name(child_sa), child_sa->get_unique_id(child_sa),
 			 ntohl(child_sa->get_spi(child_sa, TRUE)), bytes_in,
 			 ntohl(child_sa->get_spi(child_sa, FALSE)), bytes_out,
 			 my_ts, other_ts);
diff --git a/src/libcharon/sa/ikev1/tasks/quick_mode.c b/src/libcharon/sa/ikev1/tasks/quick_mode.c
index 1133aab..96edfd8 100644
--- a/src/libcharon/sa/ikev1/tasks/quick_mode.c
+++ b/src/libcharon/sa/ikev1/tasks/quick_mode.c
@@ -156,6 +156,16 @@ struct private_quick_mode_t {
 	u_int32_t reqid;
 
 	/**
+	 * Explicit inbound mark value to use, if any
+	 */
+	u_int mark_in;
+
+	/**
+	 * Explicit inbound mark value to use, if any
+	 */
+	u_int mark_out;
+
+	/**
 	 * SPI of SA we rekey
 	 */
 	u_int32_t rekey;
@@ -196,8 +206,8 @@ static void schedule_inactivity_timeout(private_quick_mode_t *this)
 		close_ike = lib->settings->get_bool(lib->settings,
 									"%s.inactivity_close_ike", FALSE, lib->ns);
 		lib->scheduler->schedule_job(lib->scheduler, (job_t*)
-				inactivity_job_create(this->child_sa->get_reqid(this->child_sa),
-									  timeout, close_ike), timeout);
+			inactivity_job_create(this->child_sa->get_unique_id(this->child_sa),
+								  timeout, close_ike), timeout);
 	}
 }
 
@@ -375,7 +385,7 @@ static bool install(private_quick_mode_t *this)
 	DBG0(DBG_IKE, "CHILD_SA %s{%d} established "
 		 "with SPIs %.8x_i %.8x_o and TS %#R=== %#R",
 		 this->child_sa->get_name(this->child_sa),
-		 this->child_sa->get_reqid(this->child_sa),
+		 this->child_sa->get_unique_id(this->child_sa),
 		 ntohl(this->child_sa->get_spi(this->child_sa, TRUE)),
 		 ntohl(this->child_sa->get_spi(this->child_sa, FALSE)), my_ts, other_ts);
 
@@ -391,15 +401,14 @@ static bool install(private_quick_mode_t *this)
 	if (old)
 	{
 		charon->bus->child_rekey(charon->bus, old, this->child_sa);
+		/* rekeyed CHILD_SAs stay installed until they expire */
+		old->set_state(old, CHILD_REKEYED);
 	}
 	else
 	{
 		charon->bus->child_updown(charon->bus, this->child_sa, TRUE);
 	}
-	if (!this->rekey)
-	{
-		schedule_inactivity_timeout(this);
-	}
+	schedule_inactivity_timeout(this);
 	this->child_sa = NULL;
 	return TRUE;
 }
@@ -456,12 +465,19 @@ static bool get_nonce(private_quick_mode_t *this, chunk_t *nonce,
 /**
  * Add KE payload to message
  */
-static void add_ke(private_quick_mode_t *this, message_t *message)
+static bool add_ke(private_quick_mode_t *this, message_t *message)
 {
 	ke_payload_t *ke_payload;
 
-	ke_payload = ke_payload_create_from_diffie_hellman(PLV1_KEY_EXCHANGE, this->dh);
+	ke_payload = ke_payload_create_from_diffie_hellman(PLV1_KEY_EXCHANGE,
+													   this->dh);
+	if (!ke_payload)
+	{
+		DBG1(DBG_IKE, "creating KE payload failed");
+		return FALSE;
+	}
 	message->add_payload(message, &ke_payload->payload_interface);
+	return TRUE;
 }
 
 /**
@@ -477,8 +493,12 @@ static bool get_ke(private_quick_mode_t *this, message_t *message)
 		DBG1(DBG_IKE, "KE payload missing");
 		return FALSE;
 	}
-	this->dh->set_other_public_value(this->dh,
-								ke_payload->get_key_exchange_data(ke_payload));
+	if (!this->dh->set_other_public_value(this->dh,
+								ke_payload->get_key_exchange_data(ke_payload)))
+	{
+		DBG1(DBG_IKE, "unable to apply received KE value");
+		return FALSE;
+	}
 	return TRUE;
 }
 
@@ -788,7 +808,8 @@ METHOD(task_t, build_i, status_t,
 			this->child_sa = child_sa_create(
 									this->ike_sa->get_my_host(this->ike_sa),
 									this->ike_sa->get_other_host(this->ike_sa),
-									this->config, this->reqid, this->udp);
+									this->config, this->reqid, this->udp,
+									this->mark_in, this->mark_out);
 
 			if (this->udp && this->mode == MODE_TRANSPORT)
 			{
@@ -870,7 +891,10 @@ METHOD(task_t, build_i, status_t,
 			}
 			if (group != MODP_NONE)
 			{
-				add_ke(this, message);
+				if (!add_ke(this, message))
+				{
+					return FAILED;
+				}
 			}
 			if (!this->tsi)
 			{
@@ -964,6 +988,7 @@ static void check_for_rekeyed_child(private_quick_mode_t *this)
 			{
 				case CHILD_INSTALLED:
 				case CHILD_REKEYING:
+				case CHILD_REKEYED:
 					policies = child_sa->create_policy_enumerator(child_sa);
 					if (policies->enumerate(policies, &local, &remote) &&
 						local->equals(local, this->tsr) &&
@@ -972,9 +997,14 @@ static void check_for_rekeyed_child(private_quick_mode_t *this)
 					{
 						this->reqid = child_sa->get_reqid(child_sa);
 						this->rekey = child_sa->get_spi(child_sa, TRUE);
+						this->mark_in = child_sa->get_mark(child_sa,
+															TRUE).value;
+						this->mark_out = child_sa->get_mark(child_sa,
+															FALSE).value;
 						child_sa->set_state(child_sa, CHILD_REKEYING);
 						DBG1(DBG_IKE, "detected rekeying of CHILD_SA %s{%u}",
-							 child_sa->get_name(child_sa), this->reqid);
+							 child_sa->get_name(child_sa),
+							 child_sa->get_unique_id(child_sa));
 					}
 					policies->destroy(policies);
 				break;
@@ -1097,7 +1127,8 @@ METHOD(task_t, process_r, status_t,
 			this->child_sa = child_sa_create(
 									this->ike_sa->get_my_host(this->ike_sa),
 									this->ike_sa->get_other_host(this->ike_sa),
-									this->config, this->reqid, this->udp);
+									this->config, this->reqid, this->udp,
+									this->mark_in, this->mark_out);
 
 			tsi = linked_list_create_with_items(this->tsi, NULL);
 			tsr = linked_list_create_with_items(this->tsr, NULL);
@@ -1202,7 +1233,10 @@ METHOD(task_t, build_r, status_t,
 			}
 			if (this->dh)
 			{
-				add_ke(this, message);
+				if (!add_ke(this, message))
+				{
+					return FAILED;
+				}
 			}
 
 			add_ts(this, message);
@@ -1307,6 +1341,13 @@ METHOD(quick_mode_t, use_reqid, void,
 	this->reqid = reqid;
 }
 
+METHOD(quick_mode_t, use_marks, void,
+	private_quick_mode_t *this, u_int in, u_int out)
+{
+	this->mark_in = in;
+	this->mark_out = out;
+}
+
 METHOD(quick_mode_t, rekey, void,
 	private_quick_mode_t *this, u_int32_t spi)
 {
@@ -1334,6 +1375,8 @@ METHOD(task_t, migrate, void,
 	this->dh = NULL;
 	this->spi_i = 0;
 	this->spi_r = 0;
+	this->mark_in = 0;
+	this->mark_out = 0;
 
 	if (!this->initiator)
 	{
@@ -1372,6 +1415,7 @@ quick_mode_t *quick_mode_create(ike_sa_t *ike_sa, child_cfg_t *config,
 				.destroy = _destroy,
 			},
 			.use_reqid = _use_reqid,
+			.use_marks = _use_marks,
 			.rekey = _rekey,
 		},
 		.ike_sa = ike_sa,
diff --git a/src/libcharon/sa/ikev1/tasks/quick_mode.h b/src/libcharon/sa/ikev1/tasks/quick_mode.h
index 0b80cb8..ee9b64d 100644
--- a/src/libcharon/sa/ikev1/tasks/quick_mode.h
+++ b/src/libcharon/sa/ikev1/tasks/quick_mode.h
@@ -45,6 +45,14 @@ struct quick_mode_t {
 	void (*use_reqid)(quick_mode_t *this, u_int32_t reqid);
 
 	/**
+	 * Use specific mark values, overriding configuration.
+	 *
+	 * @param in			inbound mark value
+	 * @param out			outbound mark value
+	 */
+	void (*use_marks)(quick_mode_t *this, u_int in, u_int out);
+
+	/**
 	 * Set the SPI of the old SA, if rekeying.
 	 *
 	 * @param spi			spi of SA to rekey
diff --git a/src/libcharon/sa/ikev2/authenticators/eap_authenticator.c b/src/libcharon/sa/ikev2/authenticators/eap_authenticator.c
index eed6d19..ebef319 100644
--- a/src/libcharon/sa/ikev2/authenticators/eap_authenticator.c
+++ b/src/libcharon/sa/ikev2/authenticators/eap_authenticator.c
@@ -522,6 +522,13 @@ METHOD(authenticator_t, process_server, status_t,
 		{
 			return FAILED;
 		}
+		if (this->method->get_auth)
+		{
+			auth_cfg_t *auth;
+
+			auth = this->ike_sa->get_auth_cfg(this->ike_sa, FALSE);
+			auth->merge(auth, this->method->get_auth(this->method), FALSE);
+		}
 		return NEED_MORE;
 	}
 
diff --git a/src/libcharon/sa/ikev2/authenticators/pubkey_authenticator.c b/src/libcharon/sa/ikev2/authenticators/pubkey_authenticator.c
index 6fb14bc..151b497 100644
--- a/src/libcharon/sa/ikev2/authenticators/pubkey_authenticator.c
+++ b/src/libcharon/sa/ikev2/authenticators/pubkey_authenticator.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2008 Tobias Brunner
+ * Copyright (C) 2008-2015 Tobias Brunner
  * Copyright (C) 2005-2009 Martin Willi
  * Copyright (C) 2005 Jan Hutter
  * Hochschule fuer Technik Rapperswil
@@ -20,6 +20,9 @@
 #include <daemon.h>
 #include <encoding/payloads/auth_payload.h>
 #include <sa/ikev2/keymat_v2.h>
+#include <asn1/asn1.h>
+#include <asn1/oid.h>
+#include <collections/array.h>
 
 typedef struct private_pubkey_authenticator_t private_pubkey_authenticator_t;
 
@@ -52,83 +55,303 @@ struct private_pubkey_authenticator_t {
 	 * Reserved bytes of ID payload
 	 */
 	char reserved[3];
+
+	/**
+	 * Whether to store signature schemes on remote auth configs.
+	 */
+	bool store_signature_scheme;
 };
 
-METHOD(authenticator_t, build, status_t,
-	private_pubkey_authenticator_t *this, message_t *message)
+/**
+ * Parse authentication data used for Signature Authentication as per RFC 7427
+ */
+static bool parse_signature_auth_data(chunk_t *auth_data, key_type_t *key_type,
+									  signature_scheme_t *scheme)
 {
-	chunk_t octets = chunk_empty, auth_data;
-	status_t status = FAILED;
-	private_key_t *private;
-	identification_t *id;
-	auth_cfg_t *auth;
-	auth_payload_t *auth_payload;
-	auth_method_t auth_method;
+	u_int8_t len;
+	int oid;
+
+	if (!auth_data->len)
+	{
+		return FALSE;
+	}
+	len = auth_data->ptr[0];
+	*auth_data = chunk_skip(*auth_data, 1);
+	/* we currently don't support schemes that require parameters */
+	oid = asn1_parse_algorithmIdentifier(*auth_data, 1, NULL);
+	*scheme = signature_scheme_from_oid(oid);
+	if (*scheme == SIGN_UNKNOWN)
+	{
+		return FALSE;
+	}
+	*key_type = key_type_from_signature_scheme(*scheme);
+	*auth_data = chunk_skip(*auth_data, len);
+	return TRUE;
+}
+
+/**
+ * Build authentication data used for Signature Authentication as per RFC 7427
+ */
+static bool build_signature_auth_data(chunk_t *auth_data,
+									  signature_scheme_t scheme)
+{
+	chunk_t data;
+	u_int8_t len;
+	int oid;
+
+	oid = signature_scheme_to_oid(scheme);
+	if (oid == OID_UNKNOWN)
+	{
+		return FALSE;
+	}
+	data = asn1_algorithmIdentifier(oid);
+	len = data.len;
+	*auth_data = chunk_cat("cmm", chunk_from_thing(len), data, *auth_data);
+	return TRUE;
+}
+
+/**
+ * Selects possible signature schemes based on our configuration, the other
+ * peer's capabilities and the private key
+ */
+static array_t *select_signature_schemes(keymat_v2_t *keymat,
+									auth_cfg_t *auth, private_key_t *private)
+{
+	enumerator_t *enumerator;
 	signature_scheme_t scheme;
+	uintptr_t config;
+	auth_rule_t rule;
+	key_type_t key_type;
+	bool have_config = FALSE;
+	array_t *selected;
+
+	selected = array_create(sizeof(signature_scheme_t), 0);
+	key_type = private->get_type(private);
+	enumerator = auth->create_enumerator(auth);
+	while (enumerator->enumerate(enumerator, &rule, &config))
+	{
+		if (rule != AUTH_RULE_SIGNATURE_SCHEME)
+		{
+			continue;
+		}
+		have_config = TRUE;
+		if (key_type == key_type_from_signature_scheme(config) &&
+			keymat->hash_algorithm_supported(keymat,
+										hasher_from_signature_scheme(config)))
+		{
+			scheme = config;
+			array_insert(selected, ARRAY_TAIL, &scheme);
+		}
+	}
+	enumerator->destroy(enumerator);
+
+	if (!have_config)
+	{
+		/* if no specific configuration, find schemes appropriate for the key
+		 * and supported by the other peer */
+		enumerator = signature_schemes_for_key(key_type,
+											   private->get_keysize(private));
+		while (enumerator->enumerate(enumerator, &scheme))
+		{
+			if (keymat->hash_algorithm_supported(keymat,
+										hasher_from_signature_scheme(scheme)))
+			{
+				array_insert(selected, ARRAY_TAIL, &scheme);
+			}
+		}
+		enumerator->destroy(enumerator);
+
+		/* for RSA we tried at least SHA-512, also try other schemes down to
+		 * what we'd use with classic authentication */
+		if (key_type == KEY_RSA)
+		{
+			signature_scheme_t schemes[] = {
+				SIGN_RSA_EMSA_PKCS1_SHA384,
+				SIGN_RSA_EMSA_PKCS1_SHA256,
+				SIGN_RSA_EMSA_PKCS1_SHA1,
+			}, contained;
+			bool found;
+			int i, j;
+
+			for (i = 0; i < countof(schemes); i++)
+			{
+				scheme = schemes[i];
+				found = FALSE;
+				for (j = 0; j < array_count(selected); j++)
+				{
+					array_get(selected, j, &contained);
+					if (scheme == contained)
+					{
+						found = TRUE;
+						break;
+					}
+				}
+				if (!found && keymat->hash_algorithm_supported(keymat,
+										hasher_from_signature_scheme(scheme)))
+				{
+					array_insert(selected, ARRAY_TAIL, &scheme);
+				}
+			}
+		}
+	}
+	return selected;
+}
+
+/**
+ * Create a signature using RFC 7427 signature authentication
+ */
+static status_t sign_signature_auth(private_pubkey_authenticator_t *this,
+							auth_cfg_t *auth, private_key_t *private,
+							identification_t *id, chunk_t *auth_data)
+{
+	enumerator_t *enumerator;
 	keymat_v2_t *keymat;
+	signature_scheme_t scheme = SIGN_UNKNOWN, *schemep;
+	array_t *schemes;
+	chunk_t octets = chunk_empty;
+	status_t status = FAILED;
 
-	id = this->ike_sa->get_my_id(this->ike_sa);
-	auth = this->ike_sa->get_auth_cfg(this->ike_sa, TRUE);
-	private = lib->credmgr->get_private(lib->credmgr, KEY_ANY, id, auth);
-	if (private == NULL)
+	keymat = (keymat_v2_t*)this->ike_sa->get_keymat(this->ike_sa);
+	schemes = select_signature_schemes(keymat, auth, private);
+	if (!array_count(schemes))
 	{
-		DBG1(DBG_IKE, "no private key found for '%Y'", id);
-		return NOT_FOUND;
+		DBG1(DBG_IKE, "no common hash algorithm found to create signature "
+			 "with %N key", key_type_names, private->get_type(private));
+		array_destroy(schemes);
+		return FAILED;
 	}
 
+	if (keymat->get_auth_octets(keymat, FALSE, this->ike_sa_init,
+								this->nonce, id, this->reserved, &octets))
+	{
+		enumerator = array_create_enumerator(schemes);
+		while (enumerator->enumerate(enumerator, &schemep))
+		{
+			scheme = *schemep;
+			if (private->sign(private, scheme, octets, auth_data) &&
+				build_signature_auth_data(auth_data, scheme))
+			{
+				status = SUCCESS;
+				break;
+			}
+			else
+			{
+				DBG2(DBG_IKE, "unable to create %N signature for %N key",
+					 signature_scheme_names, scheme, key_type_names,
+					 private->get_type(private));
+			}
+		}
+		enumerator->destroy(enumerator);
+	}
+	DBG1(DBG_IKE, "authentication of '%Y' (myself) with %N %s", id,
+		 signature_scheme_names, scheme,
+		 status == SUCCESS ? "successful" : "failed");
+	array_destroy(schemes);
+	chunk_free(&octets);
+	return status;
+}
+
+/**
+ * Create a classic IKEv2 signature
+ */
+static status_t sign_classic(private_pubkey_authenticator_t *this,
+							 auth_cfg_t *auth, private_key_t *private,
+							 identification_t *id, auth_method_t *auth_method,
+							 chunk_t *auth_data)
+{
+	signature_scheme_t scheme;
+	keymat_v2_t *keymat;
+	chunk_t octets = chunk_empty;
+	status_t status = FAILED;
+
 	switch (private->get_type(private))
 	{
 		case KEY_RSA:
-			/* we currently use always SHA1 for signatures,
-			 * TODO: support other hashes depending on configuration/auth */
 			scheme = SIGN_RSA_EMSA_PKCS1_SHA1;
-			auth_method = AUTH_RSA;
+			*auth_method = AUTH_RSA;
 			break;
 		case KEY_ECDSA:
-			/* we try to deduct the signature scheme from the keysize */
+			/* deduct the signature scheme from the keysize */
 			switch (private->get_keysize(private))
 			{
 				case 256:
 					scheme = SIGN_ECDSA_256;
-					auth_method = AUTH_ECDSA_256;
+					*auth_method = AUTH_ECDSA_256;
 					break;
 				case 384:
 					scheme = SIGN_ECDSA_384;
-					auth_method = AUTH_ECDSA_384;
+					*auth_method = AUTH_ECDSA_384;
 					break;
 				case 521:
 					scheme = SIGN_ECDSA_521;
-					auth_method = AUTH_ECDSA_521;
+					*auth_method = AUTH_ECDSA_521;
 					break;
 				default:
 					DBG1(DBG_IKE, "%d bit ECDSA private key size not supported",
-							private->get_keysize(private));
-					return status;
+						 private->get_keysize(private));
+					return FAILED;
 			}
 			break;
 		default:
 			DBG1(DBG_IKE, "private key of type %N not supported",
-					key_type_names, private->get_type(private));
-			return status;
+				 key_type_names, private->get_type(private));
+			return FAILED;
 	}
+
 	keymat = (keymat_v2_t*)this->ike_sa->get_keymat(this->ike_sa);
 	if (keymat->get_auth_octets(keymat, FALSE, this->ike_sa_init,
 								this->nonce, id, this->reserved, &octets) &&
-		private->sign(private, scheme, octets, &auth_data))
+		private->sign(private, scheme, octets, auth_data))
 	{
-		auth_payload = auth_payload_create();
-		auth_payload->set_auth_method(auth_payload, auth_method);
-		auth_payload->set_data(auth_payload, auth_data);
-		chunk_free(&auth_data);
-		message->add_payload(message, (payload_t*)auth_payload);
 		status = SUCCESS;
 	}
 	DBG1(DBG_IKE, "authentication of '%Y' (myself) with %N %s", id,
-		 auth_method_names, auth_method,
-		 (status == SUCCESS)? "successful":"failed");
+		 auth_method_names, *auth_method,
+		 status == SUCCESS ? "successful" : "failed");
 	chunk_free(&octets);
+	return status;
+}
+
+METHOD(authenticator_t, build, status_t,
+	private_pubkey_authenticator_t *this, message_t *message)
+{
+	private_key_t *private;
+	identification_t *id;
+	auth_cfg_t *auth;
+	chunk_t auth_data;
+	status_t status;
+	auth_payload_t *auth_payload;
+	auth_method_t auth_method;
+
+	id = this->ike_sa->get_my_id(this->ike_sa);
+	auth = this->ike_sa->get_auth_cfg(this->ike_sa, TRUE);
+	private = lib->credmgr->get_private(lib->credmgr, KEY_ANY, id, auth);
+	if (!private)
+	{
+		DBG1(DBG_IKE, "no private key found for '%Y'", id);
+		return NOT_FOUND;
+	}
+
+	if (this->ike_sa->supports_extension(this->ike_sa, EXT_SIGNATURE_AUTH))
+	{
+		auth_method = AUTH_DS;
+		status = sign_signature_auth(this, auth, private, id, &auth_data);
+	}
+	else
+	{
+		status = sign_classic(this, auth, private, id, &auth_method,
+							  &auth_data);
+	}
 	private->destroy(private);
 
+	if (status == SUCCESS)
+	{
+		auth_payload = auth_payload_create();
+		auth_payload->set_auth_method(auth_payload, auth_method);
+		auth_payload->set_data(auth_payload, auth_data);
+		chunk_free(&auth_data);
+		message->add_payload(message, (payload_t*)auth_payload);
+	}
 	return status;
 }
 
@@ -153,11 +376,10 @@ METHOD(authenticator_t, process, status_t,
 		return FAILED;
 	}
 	auth_method = auth_payload->get_auth_method(auth_payload);
+	auth_data = auth_payload->get_data(auth_payload);
 	switch (auth_method)
 	{
 		case AUTH_RSA:
-			/* We currently accept SHA1 signatures only
-			 * TODO: allow other hash algorithms and note it in "auth" */
 			key_type = KEY_RSA;
 			scheme = SIGN_RSA_EMSA_PKCS1_SHA1;
 			break;
@@ -170,10 +392,15 @@ METHOD(authenticator_t, process, status_t,
 		case AUTH_ECDSA_521:
 			scheme = SIGN_ECDSA_521;
 			break;
+		case AUTH_DS:
+			if (parse_signature_auth_data(&auth_data, &key_type, &scheme))
+			{
+				break;
+			}
+			/* fall-through */
 		default:
 			return INVALID_ARG;
 	}
-	auth_data = auth_payload->get_data(auth_payload);
 	id = this->ike_sa->get_other_id(this->ike_sa);
 	keymat = (keymat_v2_t*)this->ike_sa->get_keymat(this->ike_sa);
 	if (!keymat->get_auth_octets(keymat, TRUE, this->ike_sa_init,
@@ -188,11 +415,16 @@ METHOD(authenticator_t, process, status_t,
 	{
 		if (public->verify(public, scheme, octets, auth_data))
 		{
-			DBG1(DBG_IKE, "authentication of '%Y' with %N successful",
-						   id, auth_method_names, auth_method);
+			DBG1(DBG_IKE, "authentication of '%Y' with %N successful", id,
+				 auth_method == AUTH_DS ? signature_scheme_names : auth_method_names,
+				 auth_method == AUTH_DS ? scheme : auth_method);
 			status = SUCCESS;
 			auth->merge(auth, current_auth, FALSE);
 			auth->add(auth, AUTH_RULE_AUTH_CLASS, AUTH_CLASS_PUBKEY);
+			if (this->store_signature_scheme)
+			{
+				auth->add(auth, AUTH_RULE_SIGNATURE_SCHEME, (uintptr_t)scheme);
+			}
 			break;
 		}
 		else
@@ -265,6 +497,8 @@ pubkey_authenticator_t *pubkey_authenticator_create_verifier(ike_sa_t *ike_sa,
 		.ike_sa = ike_sa,
 		.ike_sa_init = received_init,
 		.nonce = sent_nonce,
+		.store_signature_scheme = lib->settings->get_bool(lib->settings,
+					"%s.signature_authentication_constraints", TRUE, lib->ns),
 	);
 	memcpy(this->reserved, reserved, sizeof(this->reserved));
 
diff --git a/src/libcharon/sa/ikev2/keymat_v2.c b/src/libcharon/sa/ikev2/keymat_v2.c
index 88ad14f..f70f5cf 100644
--- a/src/libcharon/sa/ikev2/keymat_v2.c
+++ b/src/libcharon/sa/ikev2/keymat_v2.c
@@ -1,4 +1,5 @@
 /*
+ * Copyright (C) 2015 Tobias Brunner
  * Copyright (C) 2008 Martin Willi
  * Hochschule fuer Technik Rapperswil
  *
@@ -17,6 +18,7 @@
 
 #include <daemon.h>
 #include <crypto/prf_plus.h>
+#include <crypto/hashers/hash_algorithm_set.h>
 
 typedef struct private_keymat_v2_t private_keymat_v2_t;
 
@@ -69,6 +71,11 @@ struct private_keymat_v2_t {
 	 * Key to verify incoming authentication data (SKp)
 	 */
 	chunk_t skp_verify;
+
+	/**
+	 * Set of hash algorithms supported by peer for signature authentication
+	 */
+	hash_algorithm_set_t *hash_algorithms;
 };
 
 METHOD(keymat_t, get_version, ike_version_t,
@@ -293,7 +300,7 @@ METHOD(keymat_v2_t, derive_ike_keys, bool,
 	spi_i = chunk_alloca(sizeof(u_int64_t));
 	spi_r = chunk_alloca(sizeof(u_int64_t));
 
-	if (dh->get_shared_secret(dh, &secret) != SUCCESS)
+	if (!dh->get_shared_secret(dh, &secret))
 	{
 		return FALSE;
 	}
@@ -547,7 +554,7 @@ METHOD(keymat_v2_t, derive_child_keys, bool,
 
 	if (dh)
 	{
-		if (dh->get_shared_secret(dh, &secret) != SUCCESS)
+		if (!dh->get_shared_secret(dh, &secret))
 		{
 			return FALSE;
 		}
@@ -676,6 +683,26 @@ METHOD(keymat_v2_t, get_psk_sig, bool,
 	return TRUE;
 }
 
+METHOD(keymat_v2_t, hash_algorithm_supported, bool,
+	private_keymat_v2_t *this, hash_algorithm_t hash)
+{
+	if (!this->hash_algorithms)
+	{
+		return FALSE;
+	}
+	return this->hash_algorithms->contains(this->hash_algorithms, hash);
+}
+
+METHOD(keymat_v2_t, add_hash_algorithm, void,
+	private_keymat_v2_t *this, hash_algorithm_t hash)
+{
+	if (!this->hash_algorithms)
+	{
+		this->hash_algorithms = hash_algorithm_set_create();
+	}
+	this->hash_algorithms->add(this->hash_algorithms, hash);
+}
+
 METHOD(keymat_t, destroy, void,
 	private_keymat_v2_t *this)
 {
@@ -685,6 +712,7 @@ METHOD(keymat_t, destroy, void,
 	chunk_clear(&this->skd);
 	chunk_clear(&this->skp_verify);
 	chunk_clear(&this->skp_build);
+	DESTROY_IF(this->hash_algorithms);
 	free(this);
 }
 
@@ -709,6 +737,9 @@ keymat_v2_t *keymat_v2_create(bool initiator)
 			.get_skd = _get_skd,
 			.get_auth_octets = _get_auth_octets,
 			.get_psk_sig = _get_psk_sig,
+			.add_hash_algorithm = _add_hash_algorithm,
+			.hash_algorithm_supported = _hash_algorithm_supported,
+
 		},
 		.initiator = initiator,
 		.prf_alg = PRF_UNDEFINED,
diff --git a/src/libcharon/sa/ikev2/keymat_v2.h b/src/libcharon/sa/ikev2/keymat_v2.h
index 04432f0..927b62b 100644
--- a/src/libcharon/sa/ikev2/keymat_v2.h
+++ b/src/libcharon/sa/ikev2/keymat_v2.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2011 Tobias Brunner
+ * Copyright (C) 2011-2015 Tobias Brunner
  * Hochschule fuer Technik Rapperswil
  *
  * This program is free software; you can redistribute it and/or modify it
@@ -124,6 +124,22 @@ struct keymat_v2_t {
 	bool (*get_psk_sig)(keymat_v2_t *this, bool verify, chunk_t ike_sa_init,
 						chunk_t nonce, chunk_t secret,
 						identification_t *id, char reserved[3], chunk_t *sig);
+
+	/**
+	 * Add a hash algorithm supported by the peer for signature authentication.
+	 *
+	 * @param hash			hash algorithm
+	 */
+	void (*add_hash_algorithm)(keymat_v2_t *this, hash_algorithm_t hash);
+
+	/**
+	 * Check if a given hash algorithm is supported by the peer for signature
+	 * authentication.
+	 *
+	 * @param hash			hash algorithm
+	 * @return				TRUE if supported, FALSE otherwise
+	 */
+	bool (*hash_algorithm_supported)(keymat_v2_t *this, hash_algorithm_t hash);
 };
 
 /**
diff --git a/src/libcharon/sa/ikev2/task_manager_v2.c b/src/libcharon/sa/ikev2/task_manager_v2.c
index eb7df35..2981677 100644
--- a/src/libcharon/sa/ikev2/task_manager_v2.c
+++ b/src/libcharon/sa/ikev2/task_manager_v2.c
@@ -29,6 +29,7 @@
 #include <sa/ikev2/tasks/ike_cert_post.h>
 #include <sa/ikev2/tasks/ike_rekey.h>
 #include <sa/ikev2/tasks/ike_reauth.h>
+#include <sa/ikev2/tasks/ike_reauth_complete.h>
 #include <sa/ikev2/tasks/ike_delete.h>
 #include <sa/ikev2/tasks/ike_config.h>
 #include <sa/ikev2/tasks/ike_dpd.h>
@@ -171,6 +172,11 @@ struct private_task_manager_t {
 	 * Base to calculate retransmission timeout
 	 */
 	double retransmit_base;
+
+	/**
+	 * Use make-before-break instead of break-before-make reauth?
+	 */
+	bool make_before_break;
 };
 
 /**
@@ -510,6 +516,11 @@ METHOD(task_manager_t, initiate, status_t,
 					break;
 				}
 #endif /* ME */
+				if (activate_task(this, TASK_IKE_REAUTH_COMPLETE))
+				{
+					exchange = INFORMATIONAL;
+					break;
+				}
 			case IKE_REKEYING:
 				if (activate_task(this, TASK_IKE_DELETE))
 				{
@@ -604,6 +615,11 @@ METHOD(task_manager_t, initiate, status_t,
 
 	/* update exchange type if a task changed it */
 	this->initiating.type = message->get_exchange_type(message);
+	if (this->initiating.type == EXCHANGE_TYPE_UNDEFINED)
+	{
+		message->destroy(message);
+		return SUCCESS;
+	}
 
 	if (!generate_message(this, message, &this->initiating.packets))
 	{
@@ -1170,7 +1186,7 @@ static status_t parse_message(private_task_manager_t *this, message_t *msg)
 		{
 			unknown = (unknown_payload_t*)payload;
 			type = payload->get_type(payload);
-			if (!payload_is_known(type) &&
+			if (!payload_is_known(type, msg->get_major_version(msg)) &&
 				unknown->is_critical(unknown))
 			{
 				DBG1(DBG_ENC, "payload type %N is not supported, "
@@ -1288,17 +1304,16 @@ METHOD(task_manager_t, process_message, status_t,
 	{
 		if (mid == this->responding.mid)
 		{
-			/* reject initial messages once established */
-			if (msg->get_exchange_type(msg) == IKE_SA_INIT ||
-				msg->get_exchange_type(msg) == IKE_AUTH)
+			/* reject initial messages if not received in specific states */
+			if ((msg->get_exchange_type(msg) == IKE_SA_INIT &&
+				 this->ike_sa->get_state(this->ike_sa) != IKE_CREATED) ||
+				(msg->get_exchange_type(msg) == IKE_AUTH &&
+				 this->ike_sa->get_state(this->ike_sa) != IKE_CONNECTING))
 			{
-				if (this->ike_sa->get_state(this->ike_sa) != IKE_CREATED &&
-					this->ike_sa->get_state(this->ike_sa) != IKE_CONNECTING)
-				{
-					DBG1(DBG_IKE, "ignoring %N in established IKE_SA state",
-						 exchange_type_names, msg->get_exchange_type(msg));
-					return FAILED;
-				}
+				DBG1(DBG_IKE, "ignoring %N in IKE_SA state %N",
+					 exchange_type_names, msg->get_exchange_type(msg),
+					 ike_sa_state_names, this->ike_sa->get_state(this->ike_sa));
+				return FAILED;
 			}
 			if (!this->ike_sa->supports_extension(this->ike_sa, EXT_MOBIKE))
 			{	/* with MOBIKE, we do no implicit updates */
@@ -1339,10 +1354,6 @@ METHOD(task_manager_t, process_message, status_t,
 		{
 			DBG1(DBG_IKE, "received message ID %d, expected %d. Ignored",
 				 mid, this->responding.mid);
-			if (msg->get_exchange_type(msg) == IKE_SA_INIT)
-			{	/* clean up IKE_SA state if IKE_SA_INIT has invalid msg ID */
-				return DESTROY_ME;
-			}
 		}
 	}
 	else
@@ -1505,9 +1516,79 @@ METHOD(task_manager_t, queue_ike_rekey, void,
 	queue_task(this, (task_t*)ike_rekey_create(this->ike_sa, TRUE));
 }
 
+/**
+ * Start reauthentication using make-before-break
+ */
+static void trigger_mbb_reauth(private_task_manager_t *this)
+{
+	enumerator_t *enumerator;
+	child_sa_t *child_sa;
+	child_cfg_t *cfg;
+	ike_sa_t *new;
+	host_t *host;
+	task_t *task;
+
+	new = charon->ike_sa_manager->checkout_new(charon->ike_sa_manager,
+								this->ike_sa->get_version(this->ike_sa), TRUE);
+	if (!new)
+	{	/* shouldn't happen */
+		return;
+	}
+
+	new->set_peer_cfg(new, this->ike_sa->get_peer_cfg(this->ike_sa));
+	host = this->ike_sa->get_other_host(this->ike_sa);
+	new->set_other_host(new, host->clone(host));
+	host = this->ike_sa->get_my_host(this->ike_sa);
+	new->set_my_host(new, host->clone(host));
+	enumerator = this->ike_sa->create_virtual_ip_enumerator(this->ike_sa, TRUE);
+	while (enumerator->enumerate(enumerator, &host))
+	{
+		new->add_virtual_ip(new, TRUE, host);
+	}
+	enumerator->destroy(enumerator);
+
+	enumerator = this->ike_sa->create_child_sa_enumerator(this->ike_sa);
+	while (enumerator->enumerate(enumerator, &child_sa))
+	{
+		cfg = child_sa->get_config(child_sa);
+		new->queue_task(new, &child_create_create(new, cfg->get_ref(cfg),
+												  FALSE, NULL, NULL)->task);
+	}
+	enumerator->destroy(enumerator);
+
+	enumerator = array_create_enumerator(this->queued_tasks);
+	while (enumerator->enumerate(enumerator, &task))
+	{
+		if (task->get_type(task) == TASK_CHILD_CREATE)
+		{
+			task->migrate(task, new);
+			new->queue_task(new, task);
+			array_remove_at(this->queued_tasks, enumerator);
+		}
+	}
+	enumerator->destroy(enumerator);
+
+	if (new->initiate(new, NULL, 0, NULL, NULL) != DESTROY_ME)
+	{
+		new->queue_task(new, (task_t*)ike_reauth_complete_create(new,
+										this->ike_sa->get_id(this->ike_sa)));
+		charon->ike_sa_manager->checkin(charon->ike_sa_manager, new);
+	}
+	else
+	{
+		charon->ike_sa_manager->checkin_and_destroy(charon->ike_sa_manager, new);
+		DBG1(DBG_IKE, "reauthenticating IKE_SA failed");
+	}
+	charon->bus->set_sa(charon->bus, this->ike_sa);
+}
+
 METHOD(task_manager_t, queue_ike_reauth, void,
 	private_task_manager_t *this)
 {
+	if (this->make_before_break)
+	{
+		return trigger_mbb_reauth(this);
+	}
 	queue_task(this, (task_t*)ike_reauth_create(this->ike_sa));
 }
 
@@ -1773,6 +1854,8 @@ task_manager_v2_t *task_manager_v2_create(ike_sa_t *ike_sa)
 					"%s.retransmit_timeout", RETRANSMIT_TIMEOUT, lib->ns),
 		.retransmit_base = lib->settings->get_double(lib->settings,
 					"%s.retransmit_base", RETRANSMIT_BASE, lib->ns),
+		.make_before_break = lib->settings->get_bool(lib->settings,
+					"%s.make_before_break", FALSE, lib->ns),
 	);
 
 	return &this->public;
diff --git a/src/libcharon/sa/ikev2/tasks/child_create.c b/src/libcharon/sa/ikev2/tasks/child_create.c
index a1f01c2..6d9132a 100644
--- a/src/libcharon/sa/ikev2/tasks/child_create.c
+++ b/src/libcharon/sa/ikev2/tasks/child_create.c
@@ -105,6 +105,11 @@ struct private_child_create_t {
 	diffie_hellman_t *dh;
 
 	/**
+	 * Applying DH public value failed?
+	 */
+	bool dh_failed;
+
+	/**
 	 * group used for DH exchange
 	 */
 	diffie_hellman_group_t dh_group;
@@ -160,6 +165,16 @@ struct private_child_create_t {
 	u_int32_t reqid;
 
 	/**
+	 * Explicit inbound mark value
+	 */
+	u_int mark_in;
+
+	/**
+	 * Explicit outbound mark value
+	 */
+	u_int mark_out;
+
+	/**
 	 * CHILD_SA which gets established
 	 */
 	child_sa_t *child_sa;
@@ -286,7 +301,7 @@ static bool allocate_spi(private_child_create_t *this)
  */
 static void schedule_inactivity_timeout(private_child_create_t *this)
 {
-	u_int32_t timeout;
+	u_int32_t timeout, id;
 	bool close_ike;
 
 	timeout = this->config->get_inactivity(this->config);
@@ -294,9 +309,9 @@ static void schedule_inactivity_timeout(private_child_create_t *this)
 	{
 		close_ike = lib->settings->get_bool(lib->settings,
 									"%s.inactivity_close_ike", FALSE, lib->ns);
+		id = this->child_sa->get_unique_id(this->child_sa);
 		lib->scheduler->schedule_job(lib->scheduler, (job_t*)
-				inactivity_job_create(this->child_sa->get_reqid(this->child_sa),
-									  timeout, close_ike), timeout);
+						inactivity_job_create(id, timeout, close_ike), timeout);
 	}
 }
 
@@ -683,10 +698,7 @@ static status_t select_and_install(private_child_create_t *this,
 	this->ike_sa->add_child_sa(this->ike_sa, this->child_sa);
 	this->established = TRUE;
 
-	if (!this->rekey)
-	{	/* a rekeyed SA uses the same reqid, no need for a new job */
-		schedule_inactivity_timeout(this);
-	}
+	schedule_inactivity_timeout(this);
 
 	my_ts = linked_list_create_from_enumerator(
 				this->child_sa->create_ts_enumerator(this->child_sa, TRUE));
@@ -696,7 +708,7 @@ static status_t select_and_install(private_child_create_t *this,
 	DBG0(DBG_IKE, "CHILD_SA %s{%d} established "
 		 "with SPIs %.8x_i %.8x_o and TS %#R=== %#R",
 		 this->child_sa->get_name(this->child_sa),
-		 this->child_sa->get_reqid(this->child_sa),
+		 this->child_sa->get_unique_id(this->child_sa),
 		 ntohl(this->child_sa->get_spi(this->child_sa, TRUE)),
 		 ntohl(this->child_sa->get_spi(this->child_sa, FALSE)), my_ts, other_ts);
 
@@ -709,7 +721,7 @@ static status_t select_and_install(private_child_create_t *this,
 /**
  * build the payloads for the message
  */
-static void build_payloads(private_child_create_t *this, message_t *message)
+static bool build_payloads(private_child_create_t *this, message_t *message)
 {
 	sa_payload_t *sa_payload;
 	nonce_payload_t *nonce_payload;
@@ -741,6 +753,11 @@ static void build_payloads(private_child_create_t *this, message_t *message)
 	{
 		ke_payload = ke_payload_create_from_diffie_hellman(PLV2_KEY_EXCHANGE,
 														   this->dh);
+		if (!ke_payload)
+		{
+			DBG1(DBG_IKE, "creating KE payload failed");
+			return FALSE;
+		}
 		message->add_payload(message, (payload_t*)ke_payload);
 	}
 
@@ -769,6 +786,7 @@ static void build_payloads(private_child_create_t *this, message_t *message)
 		message->add_notify(message, FALSE, ESP_TFC_PADDING_NOT_SUPPORTED,
 							chunk_empty);
 	}
+	return TRUE;
 }
 
 /**
@@ -880,7 +898,7 @@ static void process_payloads(private_child_create_t *this, message_t *message)
 				}
 				if (this->dh)
 				{
-					this->dh->set_other_public_value(this->dh,
+					this->dh_failed = !this->dh->set_other_public_value(this->dh,
 								ke_payload->get_key_exchange_data(ke_payload));
 				}
 				break;
@@ -996,7 +1014,8 @@ METHOD(task_t, build_i, status_t,
 
 	this->child_sa = child_sa_create(this->ike_sa->get_my_host(this->ike_sa),
 			this->ike_sa->get_other_host(this->ike_sa), this->config, this->reqid,
-			this->ike_sa->has_condition(this->ike_sa, COND_NAT_ANY));
+			this->ike_sa->has_condition(this->ike_sa, COND_NAT_ANY),
+			this->mark_in, this->mark_out);
 
 	if (!allocate_spi(this))
 	{
@@ -1027,7 +1046,10 @@ METHOD(task_t, build_i, status_t,
 							NARROW_INITIATOR_PRE_AUTH, this->tsi, this->tsr);
 	}
 
-	build_payloads(this, message);
+	if (!build_payloads(this, message))
+	{
+		return FAILED;
+	}
 
 	this->tsi->destroy_offset(this->tsi, offsetof(traffic_selector_t, destroy));
 	this->tsr->destroy_offset(this->tsr, offsetof(traffic_selector_t, destroy));
@@ -1168,12 +1190,19 @@ METHOD(task_t, build_r, status_t,
 		case IKE_SA_INIT:
 			return get_nonce(message, &this->my_nonce);
 		case CREATE_CHILD_SA:
-			if (generate_nonce(this) != SUCCESS)
+			if (generate_nonce(this) != SUCCESS )
 			{
 				message->add_notify(message, FALSE, NO_PROPOSAL_CHOSEN,
 									chunk_empty);
 				return SUCCESS;
 			}
+			if (this->dh_failed)
+			{
+				DBG1(DBG_IKE, "applying DH public value failed");
+				message->add_notify(message, FALSE, NO_PROPOSAL_CHOSEN,
+									chunk_empty);
+				return SUCCESS;
+			}
 			no_dh = FALSE;
 			break;
 		case IKE_AUTH:
@@ -1241,7 +1270,8 @@ METHOD(task_t, build_r, status_t,
 
 	this->child_sa = child_sa_create(this->ike_sa->get_my_host(this->ike_sa),
 			this->ike_sa->get_other_host(this->ike_sa), this->config, this->reqid,
-			this->ike_sa->has_condition(this->ike_sa, COND_NAT_ANY));
+			this->ike_sa->has_condition(this->ike_sa, COND_NAT_ANY),
+			this->mark_in, this->mark_out);
 
 	if (this->ipcomp_received != IPCOMP_NONE)
 	{
@@ -1279,7 +1309,12 @@ METHOD(task_t, build_r, status_t,
 			return SUCCESS;
 	}
 
-	build_payloads(this, message);
+	if (!build_payloads(this, message))
+	{
+		message->add_notify(message, FALSE, NO_PROPOSAL_CHOSEN, chunk_empty);
+		handle_child_sa_failure(this, message);
+		return SUCCESS;
+	}
 
 	if (!this->rekey)
 	{	/* invoke the child_up() hook if we are not rekeying */
@@ -1408,6 +1443,7 @@ METHOD(task_t, process_i, status_t,
 						 this->dh_group, diffie_hellman_group_names, group);
 					this->retry = TRUE;
 					this->dh_group = group;
+					this->child_sa->set_state(this->child_sa, CHILD_RETRYING);
 					this->public.task.migrate(&this->public.task, this->ike_sa);
 					enumerator->destroy(enumerator);
 					return NEED_MORE;
@@ -1456,6 +1492,13 @@ METHOD(task_t, process_i, status_t,
 		return delete_failed_sa(this);
 	}
 
+	if (this->dh_failed)
+	{
+		DBG1(DBG_IKE, "applying DH public value failed");
+		handle_child_sa_failure(this, message);
+		return delete_failed_sa(this);
+	}
+
 	if (select_and_install(this, no_dh, ike_auth) == SUCCESS)
 	{
 		if (!this->rekey)
@@ -1477,6 +1520,13 @@ METHOD(child_create_t, use_reqid, void,
 	this->reqid = reqid;
 }
 
+METHOD(child_create_t, use_marks, void,
+	private_child_create_t *this, u_int in, u_int out)
+{
+	this->mark_in = in;
+	this->mark_out = out;
+}
+
 METHOD(child_create_t, get_child, child_sa_t*,
 	private_child_create_t *this)
 {
@@ -1526,6 +1576,7 @@ METHOD(task_t, migrate, void,
 	DESTROY_IF(this->child_sa);
 	DESTROY_IF(this->proposal);
 	DESTROY_IF(this->dh);
+	this->dh_failed = FALSE;
 	if (this->proposals)
 	{
 		this->proposals->destroy_offset(this->proposals, offsetof(proposal_t, destroy));
@@ -1544,6 +1595,8 @@ METHOD(task_t, migrate, void,
 	this->ipcomp_received = IPCOMP_NONE;
 	this->other_cpi = 0;
 	this->reqid = 0;
+	this->mark_in = 0;
+	this->mark_out = 0;
 	this->established = FALSE;
 }
 
@@ -1592,6 +1645,7 @@ child_create_t *child_create_create(ike_sa_t *ike_sa,
 			.set_config = _set_config,
 			.get_lower_nonce = _get_lower_nonce,
 			.use_reqid = _use_reqid,
+			.use_marks = _use_marks,
 			.task = {
 				.get_type = _get_type,
 				.migrate = _migrate,
diff --git a/src/libcharon/sa/ikev2/tasks/child_create.h b/src/libcharon/sa/ikev2/tasks/child_create.h
index d29ba3d..46d9403 100644
--- a/src/libcharon/sa/ikev2/tasks/child_create.h
+++ b/src/libcharon/sa/ikev2/tasks/child_create.h
@@ -52,6 +52,14 @@ struct child_create_t {
 	void (*use_reqid) (child_create_t *this, u_int32_t reqid);
 
 	/**
+	 * Use specific mark values to override configuration.
+	 *
+	 * @param in		inbound mark value
+	 * @param out		outbound mark value
+	 */
+	void (*use_marks)(child_create_t *this, u_int in, u_int out);
+
+	/**
 	 * Get the lower of the two nonces, used for rekey collisions.
 	 *
 	 * @return			lower nonce
diff --git a/src/libcharon/sa/ikev2/tasks/child_delete.c b/src/libcharon/sa/ikev2/tasks/child_delete.c
index 2b16974..f0b11e2 100644
--- a/src/libcharon/sa/ikev2/tasks/child_delete.c
+++ b/src/libcharon/sa/ikev2/tasks/child_delete.c
@@ -267,7 +267,7 @@ static void log_children(private_child_delete_t *this)
 		{
 			DBG0(DBG_IKE, "closing expired CHILD_SA %s{%d} "
 				 "with SPIs %.8x_i %.8x_o and TS %#R=== %#R",
-				 child_sa->get_name(child_sa), child_sa->get_reqid(child_sa),
+				 child_sa->get_name(child_sa), child_sa->get_unique_id(child_sa),
 				 ntohl(child_sa->get_spi(child_sa, TRUE)),
 				 ntohl(child_sa->get_spi(child_sa, FALSE)), my_ts, other_ts);
 		}
@@ -278,7 +278,7 @@ static void log_children(private_child_delete_t *this)
 
 			DBG0(DBG_IKE, "closing CHILD_SA %s{%d} with SPIs %.8x_i "
 				 "(%llu bytes) %.8x_o (%llu bytes) and TS %#R=== %#R",
-				 child_sa->get_name(child_sa), child_sa->get_reqid(child_sa),
+				 child_sa->get_name(child_sa), child_sa->get_unique_id(child_sa),
 				 ntohl(child_sa->get_spi(child_sa, TRUE)), bytes_in,
 				 ntohl(child_sa->get_spi(child_sa, FALSE)), bytes_out,
 				 my_ts, other_ts);
diff --git a/src/libcharon/sa/ikev2/tasks/child_rekey.c b/src/libcharon/sa/ikev2/tasks/child_rekey.c
index db87282..c806e19 100644
--- a/src/libcharon/sa/ikev2/tasks/child_rekey.c
+++ b/src/libcharon/sa/ikev2/tasks/child_rekey.c
@@ -96,9 +96,9 @@ static void schedule_delayed_rekey(private_child_rekey_t *this)
 
 	retry = RETRY_INTERVAL - (random() % RETRY_JITTER);
 	job = (job_t*)rekey_child_sa_job_create(
-						this->child_sa->get_reqid(this->child_sa),
 						this->child_sa->get_protocol(this->child_sa),
-						this->child_sa->get_spi(this->child_sa, TRUE));
+						this->child_sa->get_spi(this->child_sa, TRUE),
+						this->ike_sa->get_my_host(this->ike_sa));
 	DBG1(DBG_IKE, "CHILD_SA rekeying failed, trying again in %d seconds", retry);
 	this->child_sa->set_state(this->child_sa, CHILD_INSTALLED);
 	lib->scheduler->schedule_job(lib->scheduler, job, retry);
@@ -184,6 +184,9 @@ METHOD(task_t, build_i, status_t,
 	}
 	reqid = this->child_sa->get_reqid(this->child_sa);
 	this->child_create->use_reqid(this->child_create, reqid);
+	this->child_create->use_marks(this->child_create,
+						this->child_sa->get_mark(this->child_sa, TRUE).value,
+						this->child_sa->get_mark(this->child_sa, FALSE).value);
 
 	if (this->child_create->task.build(&this->child_create->task,
 									   message) != NEED_MORE)
@@ -224,6 +227,9 @@ METHOD(task_t, build_r, status_t,
 	/* let the CHILD_CREATE task build the response */
 	reqid = this->child_sa->get_reqid(this->child_sa);
 	this->child_create->use_reqid(this->child_create, reqid);
+	this->child_create->use_marks(this->child_create,
+						this->child_sa->get_mark(this->child_sa, TRUE).value,
+						this->child_sa->get_mark(this->child_sa, FALSE).value);
 	config = this->child_sa->get_config(this->child_sa);
 	this->child_create->set_config(this->child_create, config->get_ref(config));
 	this->child_create->task.build(&this->child_create->task, message);
diff --git a/src/libcharon/sa/ikev2/tasks/ike_cert_pre.c b/src/libcharon/sa/ikev2/tasks/ike_cert_pre.c
index 0dac975..ca17494 100644
--- a/src/libcharon/sa/ikev2/tasks/ike_cert_pre.c
+++ b/src/libcharon/sa/ikev2/tasks/ike_cert_pre.c
@@ -229,12 +229,12 @@ static void process_x509(cert_payload_t *payload, auth_cfg_t *auth,
 			return;
 		}
 		url = strdup(url);
-		if (first)
+		if (*first)
 		{	/* first URL is for an end entity certificate */
 			DBG1(DBG_IKE, "received hash-and-url for end entity cert \"%s\"",
 				 url);
 			auth->add(auth, AUTH_HELPER_SUBJECT_HASH_URL, url);
-			first = FALSE;
+			*first = FALSE;
 		}
 		else
 		{
diff --git a/src/libcharon/sa/ikev2/tasks/ike_config.c b/src/libcharon/sa/ikev2/tasks/ike_config.c
index da06e2a..646f20c 100644
--- a/src/libcharon/sa/ikev2/tasks/ike_config.c
+++ b/src/libcharon/sa/ikev2/tasks/ike_config.c
@@ -17,7 +17,6 @@
 #include "ike_config.h"
 
 #include <daemon.h>
-#include <hydra.h>
 #include <encoding/payloads/cp_payload.h>
 
 typedef struct private_ike_config_t private_ike_config_t;
@@ -127,9 +126,8 @@ static void handle_attribute(private_ike_config_t *this,
 	enumerator->destroy(enumerator);
 
 	/* and pass it to the handle function */
-	handler = hydra->attributes->handle(hydra->attributes,
-							this->ike_sa->get_other_id(this->ike_sa), handler,
-							ca->get_type(ca), ca->get_chunk(ca));
+	handler = charon->attributes->handle(charon->attributes,
+					this->ike_sa, handler, ca->get_type(ca), ca->get_chunk(ca));
 	this->ike_sa->add_configuration_attribute(this->ike_sa,
 							handler, ca->get_type(ca), ca->get_chunk(ca));
 }
@@ -274,9 +272,8 @@ METHOD(task_t, build_i, status_t,
 			enumerator->destroy(enumerator);
 		}
 
-		enumerator = hydra->attributes->create_initiator_enumerator(
-								hydra->attributes,
-								this->ike_sa->get_other_id(this->ike_sa), vips);
+		enumerator = charon->attributes->create_initiator_enumerator(
+										charon->attributes, this->ike_sa, vips);
 		while (enumerator->enumerate(enumerator, &handler, &type, &data))
 		{
 			configuration_attribute_t *ca;
@@ -352,8 +349,8 @@ METHOD(task_t, build_r, status_t,
 			/* query all pools until we get an address */
 			DBG1(DBG_IKE, "peer requested virtual IP %H", requested);
 
-			found = hydra->attributes->acquire_address(hydra->attributes,
-													   pools, id, requested);
+			found = charon->attributes->acquire_address(charon->attributes,
+												pools, this->ike_sa, requested);
 			if (found)
 			{
 				DBG1(DBG_IKE, "assigning virtual IP %H to peer '%Y'", found, id);
@@ -398,8 +395,8 @@ METHOD(task_t, build_r, status_t,
 		}
 
 		/* query registered providers for additional attributes to include */
-		enumerator = hydra->attributes->create_responder_enumerator(
-											hydra->attributes, pools, id, vips);
+		enumerator = charon->attributes->create_responder_enumerator(
+								charon->attributes, pools, this->ike_sa, vips);
 		while (enumerator->enumerate(enumerator, &type, &value))
 		{
 			if (!cp)
diff --git a/src/libcharon/sa/ikev2/tasks/ike_init.c b/src/libcharon/sa/ikev2/tasks/ike_init.c
index 71c5f22..0d5700e 100644
--- a/src/libcharon/sa/ikev2/tasks/ike_init.c
+++ b/src/libcharon/sa/ikev2/tasks/ike_init.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2008-2009 Tobias Brunner
+ * Copyright (C) 2008-2015 Tobias Brunner
  * Copyright (C) 2005-2008 Martin Willi
  * Copyright (C) 2005 Jan Hutter
  * Hochschule fuer Technik Rapperswil
@@ -20,8 +20,11 @@
 #include <string.h>
 
 #include <daemon.h>
+#include <bio/bio_reader.h>
+#include <bio/bio_writer.h>
 #include <sa/ikev2/keymat_v2.h>
 #include <crypto/diffie_hellman.h>
+#include <crypto/hashers/hash_algorithm_set.h>
 #include <encoding/payloads/sa_payload.h>
 #include <encoding/payloads/ke_payload.h>
 #include <encoding/payloads/nonce_payload.h>
@@ -67,6 +70,11 @@ struct private_ike_init_t {
 	diffie_hellman_t *dh;
 
 	/**
+	 * Applying DH public value failed?
+	 */
+	bool dh_failed;
+
+	/**
 	 * Keymat derivation (from IKE_SA)
 	 */
 	keymat_v2_t *keymat;
@@ -100,12 +108,114 @@ struct private_ike_init_t {
 	 * retries done so far after failure (cookie or bad dh group)
 	 */
 	u_int retry;
+
+	/**
+	 * Whether to use Signature Authentication as per RFC 7427
+	 */
+	bool signature_authentication;
 };
 
 /**
+ * Notify the peer about the hash algorithms we support or expect,
+ * as per RFC 7427
+ */
+static void send_supported_hash_algorithms(private_ike_init_t *this,
+										   message_t *message)
+{
+	hash_algorithm_set_t *algos;
+	enumerator_t *enumerator, *rounds;
+	bio_writer_t *writer;
+	hash_algorithm_t hash;
+	peer_cfg_t *peer;
+	auth_cfg_t *auth;
+	auth_rule_t rule;
+	uintptr_t config;
+	char *plugin_name;
+
+	algos = hash_algorithm_set_create();
+	peer = this->ike_sa->get_peer_cfg(this->ike_sa);
+	if (peer)
+	{
+		rounds = peer->create_auth_cfg_enumerator(peer, FALSE);
+		while (rounds->enumerate(rounds, &auth))
+		{
+			enumerator = auth->create_enumerator(auth);
+			while (enumerator->enumerate(enumerator, &rule, &config))
+			{
+				if (rule == AUTH_RULE_SIGNATURE_SCHEME)
+				{
+					hash = hasher_from_signature_scheme(config);
+					if (hasher_algorithm_for_ikev2(hash))
+					{
+						algos->add(algos, hash);
+					}
+				}
+			}
+			enumerator->destroy(enumerator);
+		}
+		rounds->destroy(rounds);
+	}
+
+	if (!algos->count(algos))
+	{
+		enumerator = lib->crypto->create_hasher_enumerator(lib->crypto);
+		while (enumerator->enumerate(enumerator, &hash, &plugin_name))
+		{
+			if (hasher_algorithm_for_ikev2(hash))
+			{
+				algos->add(algos, hash);
+			}
+		}
+		enumerator->destroy(enumerator);
+	}
+
+	if (algos->count(algos))
+	{
+		writer = bio_writer_create(0);
+		enumerator = algos->create_enumerator(algos);
+		while (enumerator->enumerate(enumerator, &hash))
+		{
+			writer->write_uint16(writer, hash);
+		}
+		enumerator->destroy(enumerator);
+		message->add_notify(message, FALSE, SIGNATURE_HASH_ALGORITHMS,
+							writer->get_buf(writer));
+		writer->destroy(writer);
+	}
+	algos->destroy(algos);
+}
+
+/**
+ * Store algorithms supported by other peer
+ */
+static void handle_supported_hash_algorithms(private_ike_init_t *this,
+											 notify_payload_t *notify)
+{
+	bio_reader_t *reader;
+	u_int16_t algo;
+	bool added = FALSE;
+
+	reader = bio_reader_create(notify->get_notification_data(notify));
+	while (reader->remaining(reader) >= 2 && reader->read_uint16(reader, &algo))
+	{
+		if (hasher_algorithm_for_ikev2(algo))
+		{
+			this->keymat->add_hash_algorithm(this->keymat, algo);
+			added = TRUE;
+		}
+	}
+	reader->destroy(reader);
+
+	if (added)
+	{
+		this->ike_sa->enable_extension(this->ike_sa, EXT_SIGNATURE_AUTH);
+	}
+}
+
+/**
  * build the payloads for the message
  */
-static void build_payloads(private_ike_init_t *this, message_t *message)
+static bool build_payloads(private_ike_init_t *this, message_t *message)
 {
 	sa_payload_t *sa_payload;
 	ke_payload_t *ke_payload;
@@ -149,7 +259,13 @@ static void build_payloads(private_ike_init_t *this, message_t *message)
 
 	nonce_payload = nonce_payload_create(PLV2_NONCE);
 	nonce_payload->set_nonce(nonce_payload, this->my_nonce);
-	ke_payload = ke_payload_create_from_diffie_hellman(PLV2_KEY_EXCHANGE, this->dh);
+	ke_payload = ke_payload_create_from_diffie_hellman(PLV2_KEY_EXCHANGE,
+													   this->dh);
+	if (!ke_payload)
+	{
+		DBG1(DBG_IKE, "creating KE payload failed");
+		return FALSE;
+	}
 
 	if (this->old_sa)
 	{	/* payload order differs if we are rekeying */
@@ -174,6 +290,17 @@ static void build_payloads(private_ike_init_t *this, message_t *message)
 								chunk_empty);
 		}
 	}
+	/* submit supported hash algorithms for signature authentication */
+	if (!this->old_sa && this->signature_authentication)
+	{
+		if (this->initiator ||
+			this->ike_sa->supports_extension(this->ike_sa,
+											 EXT_SIGNATURE_AUTH))
+		{
+			send_supported_hash_algorithms(this, message);
+		}
+	}
+	return TRUE;
 }
 
 /**
@@ -183,6 +310,7 @@ static void process_payloads(private_ike_init_t *this, message_t *message)
 {
 	enumerator_t *enumerator;
 	payload_t *payload;
+	ke_payload_t *ke_payload = NULL;
 
 	enumerator = message->create_payload_enumerator(message);
 	while (enumerator->enumerate(enumerator, &payload))
@@ -211,19 +339,9 @@ static void process_payloads(private_ike_init_t *this, message_t *message)
 			}
 			case PLV2_KEY_EXCHANGE:
 			{
-				ke_payload_t *ke_payload = (ke_payload_t*)payload;
+				ke_payload = (ke_payload_t*)payload;
 
 				this->dh_group = ke_payload->get_dh_group_number(ke_payload);
-				if (!this->initiator)
-				{
-					this->dh = this->keymat->keymat.create_dh(
-										&this->keymat->keymat, this->dh_group);
-				}
-				if (this->dh)
-				{
-					this->dh->set_other_public_value(this->dh,
-								ke_payload->get_key_exchange_data(ke_payload));
-				}
 				break;
 			}
 			case PLV2_NONCE:
@@ -237,17 +355,44 @@ static void process_payloads(private_ike_init_t *this, message_t *message)
 			{
 				notify_payload_t *notify = (notify_payload_t*)payload;
 
-				if (notify->get_notify_type(notify) == FRAGMENTATION_SUPPORTED)
+				switch (notify->get_notify_type(notify))
 				{
-					this->ike_sa->enable_extension(this->ike_sa,
-												   EXT_IKE_FRAGMENTATION);
+					case FRAGMENTATION_SUPPORTED:
+						this->ike_sa->enable_extension(this->ike_sa,
+													   EXT_IKE_FRAGMENTATION);
+						break;
+					case SIGNATURE_HASH_ALGORITHMS:
+						if (this->signature_authentication)
+						{
+							handle_supported_hash_algorithms(this, notify);
+						}
+						break;
+					default:
+						/* other notifies are handled elsewhere */
+						break;
 				}
+
 			}
 			default:
 				break;
 		}
 	}
 	enumerator->destroy(enumerator);
+
+	if (ke_payload && this->proposal &&
+		this->proposal->has_dh_group(this->proposal, this->dh_group))
+	{
+		if (!this->initiator)
+		{
+			this->dh = this->keymat->keymat.create_dh(
+								&this->keymat->keymat, this->dh_group);
+		}
+		if (this->dh)
+		{
+			this->dh_failed = !this->dh->set_other_public_value(this->dh,
+								ke_payload->get_key_exchange_data(ke_payload));
+		}
+	}
 }
 
 METHOD(task_t, build_i, status_t,
@@ -305,7 +450,10 @@ METHOD(task_t, build_i, status_t,
 		message->add_notify(message, FALSE, COOKIE, this->cookie);
 	}
 
-	build_payloads(this, message);
+	if (!build_payloads(this, message))
+	{
+		return FAILED;
+	}
 
 #ifdef ME
 	{
@@ -433,13 +581,24 @@ METHOD(task_t, build_r, status_t,
 		return FAILED;
 	}
 
+	if (this->dh_failed)
+	{
+		DBG1(DBG_IKE, "applying DH public value failed");
+		message->add_notify(message, TRUE, NO_PROPOSAL_CHOSEN, chunk_empty);
+		return FAILED;
+	}
+
 	if (!derive_keys(this, this->other_nonce, this->my_nonce))
 	{
 		DBG1(DBG_IKE, "key derivation failed");
 		message->add_notify(message, TRUE, NO_PROPOSAL_CHOSEN, chunk_empty);
 		return FAILED;
 	}
-	build_payloads(this, message);
+	if (!build_payloads(this, message))
+	{
+		message->add_notify(message, TRUE, NO_PROPOSAL_CHOSEN, chunk_empty);
+		return FAILED;
+	}
 	return SUCCESS;
 }
 
@@ -554,6 +713,12 @@ METHOD(task_t, process_i, status_t,
 		return FAILED;
 	}
 
+	if (this->dh_failed)
+	{
+		DBG1(DBG_IKE, "applying DH public value failed");
+		return FAILED;
+	}
+
 	if (!derive_keys(this, this->my_nonce, this->other_nonce))
 	{
 		DBG1(DBG_IKE, "key derivation failed");
@@ -577,6 +742,7 @@ METHOD(task_t, migrate, void,
 	this->ike_sa = ike_sa;
 	this->keymat = (keymat_v2_t*)ike_sa->get_keymat(ike_sa);
 	this->proposal = NULL;
+	this->dh_failed = FALSE;
 	if (this->dh && this->dh->get_dh_group(this->dh) != this->dh_group)
 	{	/* reset DH value only if group changed (INVALID_KE_PAYLOAD) */
 		this->dh->destroy(this->dh);
@@ -631,6 +797,8 @@ ike_init_t *ike_init_create(ike_sa_t *ike_sa, bool initiator, ike_sa_t *old_sa)
 		.dh_group = MODP_NONE,
 		.keymat = (keymat_v2_t*)ike_sa->get_keymat(ike_sa),
 		.old_sa = old_sa,
+		.signature_authentication = lib->settings->get_bool(lib->settings,
+								"%s.signature_authentication", TRUE, lib->ns),
 	);
 
 	if (initiator)
diff --git a/src/libcharon/sa/ikev2/tasks/ike_mobike.c b/src/libcharon/sa/ikev2/tasks/ike_mobike.c
index d91fa58..6295d79 100644
--- a/src/libcharon/sa/ikev2/tasks/ike_mobike.c
+++ b/src/libcharon/sa/ikev2/tasks/ike_mobike.c
@@ -256,6 +256,7 @@ static void update_children(private_ike_mobike_t *this)
 	enumerator_t *enumerator;
 	child_sa_t *child_sa;
 	linked_list_t *vips;
+	status_t status;
 	host_t *host;
 
 	vips = linked_list_create();
@@ -270,15 +271,25 @@ static void update_children(private_ike_mobike_t *this)
 	enumerator = this->ike_sa->create_child_sa_enumerator(this->ike_sa);
 	while (enumerator->enumerate(enumerator, (void**)&child_sa))
 	{
-		if (child_sa->update(child_sa,
-				this->ike_sa->get_my_host(this->ike_sa),
-				this->ike_sa->get_other_host(this->ike_sa), vips,
-				this->ike_sa->has_condition(this->ike_sa,
-											COND_NAT_ANY)) == NOT_SUPPORTED)
+		status = child_sa->update(child_sa,
+					this->ike_sa->get_my_host(this->ike_sa),
+					this->ike_sa->get_other_host(this->ike_sa), vips,
+					this->ike_sa->has_condition(this->ike_sa, COND_NAT_ANY));
+		switch (status)
 		{
-			this->ike_sa->rekey_child_sa(this->ike_sa,
-					child_sa->get_protocol(child_sa),
-					child_sa->get_spi(child_sa, TRUE));
+			case NOT_SUPPORTED:
+				this->ike_sa->rekey_child_sa(this->ike_sa,
+											 child_sa->get_protocol(child_sa),
+											 child_sa->get_spi(child_sa, TRUE));
+				break;
+			case SUCCESS:
+				charon->child_sa_manager->remove(charon->child_sa_manager,
+												 child_sa);
+				charon->child_sa_manager->add(charon->child_sa_manager,
+											  child_sa, this->ike_sa);
+				break;
+			default:
+				break;
 		}
 	}
 	enumerator->destroy(enumerator);
diff --git a/src/libcharon/sa/ikev2/tasks/ike_reauth.h b/src/libcharon/sa/ikev2/tasks/ike_reauth.h
index 781b463..e2e48f0 100644
--- a/src/libcharon/sa/ikev2/tasks/ike_reauth.h
+++ b/src/libcharon/sa/ikev2/tasks/ike_reauth.h
@@ -29,6 +29,8 @@ typedef struct ike_reauth_t ike_reauth_t;
 
 /**
  * Task of type ike_reauth, reestablishes an IKE_SA.
+ *
+ * This task implements break-before-make reauthentication.
  */
 struct ike_reauth_t {
 
diff --git a/src/libcharon/sa/ikev2/tasks/ike_reauth_complete.c b/src/libcharon/sa/ikev2/tasks/ike_reauth_complete.c
new file mode 100644
index 0000000..a01489c
--- /dev/null
+++ b/src/libcharon/sa/ikev2/tasks/ike_reauth_complete.c
@@ -0,0 +1,102 @@
+/*
+ * Copyright (C) 2014 Martin Willi
+ * Copyright (C) 2014 revosec AG
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * for more details.
+ */
+
+#include "ike_reauth_complete.h"
+
+#include <daemon.h>
+#include <processing/jobs/delete_ike_sa_job.h>
+
+
+typedef struct private_ike_reauth_complete_t private_ike_reauth_complete_t;
+
+/**
+ * Private members of a ike_reauth_complete_t task.
+ */
+struct private_ike_reauth_complete_t {
+
+	/**
+	 * Public methods and task_t interface.
+	 */
+	ike_reauth_complete_t public;
+
+	/**
+	 * Assigned IKE_SA.
+	 */
+	ike_sa_t *ike_sa;
+
+	/**
+	 * Reauthenticated IKE_SA identifier
+	 */
+	ike_sa_id_t *id;
+};
+
+METHOD(task_t, build_i, status_t,
+	private_ike_reauth_complete_t *this, message_t *message)
+{
+	message->set_exchange_type(message, EXCHANGE_TYPE_UNDEFINED);
+	lib->processor->queue_job(lib->processor,
+							  (job_t*)delete_ike_sa_job_create(this->id, TRUE));
+	return SUCCESS;
+}
+
+METHOD(task_t, process_i, status_t,
+	private_ike_reauth_complete_t *this, message_t *message)
+{
+	return DESTROY_ME;
+}
+
+METHOD(task_t, get_type, task_type_t,
+	private_ike_reauth_complete_t *this)
+{
+	return TASK_IKE_REAUTH_COMPLETE;
+}
+
+METHOD(task_t, migrate, void,
+	private_ike_reauth_complete_t *this, ike_sa_t *ike_sa)
+{
+	this->ike_sa = ike_sa;
+}
+
+METHOD(task_t, destroy, void,
+	private_ike_reauth_complete_t *this)
+{
+	this->id->destroy(this->id);
+	free(this);
+}
+
+/*
+ * Described in header.
+ */
+ike_reauth_complete_t *ike_reauth_complete_create(ike_sa_t *ike_sa,
+												  ike_sa_id_t *id)
+{
+	private_ike_reauth_complete_t *this;
+
+	INIT(this,
+		.public = {
+			.task = {
+				.get_type = _get_type,
+				.migrate = _migrate,
+				.build = _build_i,
+				.process = _process_i,
+				.destroy = _destroy,
+			},
+		},
+		.ike_sa = ike_sa,
+		.id = id->clone(id),
+	);
+
+	return &this->public;
+}
diff --git a/src/libcharon/sa/ikev2/tasks/ike_reauth_complete.h b/src/libcharon/sa/ikev2/tasks/ike_reauth_complete.h
new file mode 100644
index 0000000..cc3d3b7
--- /dev/null
+++ b/src/libcharon/sa/ikev2/tasks/ike_reauth_complete.h
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2014 Martin Willi
+ * Copyright (C) 2014 revosec AG
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * for more details.
+ */
+
+/**
+ * @defgroup ike_reauth_complete ike_reauth_complete
+ * @{ @ingroup tasks_v2
+ */
+
+#ifndef IKE_REAUTH_COMPLETE_H_
+#define IKE_REAUTH_COMPLETE_H_
+
+typedef struct ike_reauth_complete_t ike_reauth_complete_t;
+
+#include <library.h>
+#include <sa/ike_sa.h>
+#include <sa/task.h>
+
+/**
+ * Task of type IKE_REAUTH_COMPLETE, removes reauthenticated SA after reauth.
+ *
+ * This task completes make-before-break reauthentication by deleting the
+ * old, reauthenticated IKE_SA after the new one established.
+ */
+struct ike_reauth_complete_t {
+
+	/**
+	 * Implements the task_t interface
+	 */
+	task_t task;
+};
+
+/**
+ * Create a new ike_reauth_complete task.
+ *
+ * This task is initiator only.
+ *
+ * @param ike_sa		IKE_SA this task works for
+ * @param id			old, reauthenticated IKE_SA
+ * @return				ike_reauth_complete task to handle by the task_manager
+ */
+ike_reauth_complete_t *ike_reauth_complete_create(ike_sa_t *ike_sa,
+												  ike_sa_id_t *id);
+
+#endif /** IKE_REAUTH_COMPLETE_H_ @}*/
diff --git a/src/libcharon/sa/ikev2/tasks/ike_rekey.c b/src/libcharon/sa/ikev2/tasks/ike_rekey.c
index 444ac6a..1855517 100644
--- a/src/libcharon/sa/ikev2/tasks/ike_rekey.c
+++ b/src/libcharon/sa/ikev2/tasks/ike_rekey.c
@@ -22,6 +22,7 @@
 #include <sa/ikev2/tasks/ike_delete.h>
 #include <processing/jobs/delete_ike_sa_job.h>
 #include <processing/jobs/rekey_ike_sa_job.h>
+#include <processing/jobs/initiate_tasks_job.h>
 
 
 typedef struct private_ike_rekey_t private_ike_rekey_t;
@@ -68,12 +69,33 @@ struct private_ike_rekey_t {
 };
 
 /**
+ * Check if an IKE_SA has any queued tasks, return initiation job
+ */
+static job_t* check_queued_tasks(ike_sa_t *ike_sa)
+{
+	enumerator_t *enumerator;
+	task_t *task;
+	job_t *job = NULL;
+
+	enumerator = ike_sa->create_task_enumerator(ike_sa, TASK_QUEUE_QUEUED);
+	if (enumerator->enumerate(enumerator, &task))
+	{
+		job = (job_t*)initiate_tasks_job_create(ike_sa->get_id(ike_sa));
+	}
+	enumerator->destroy(enumerator);
+
+	return job;
+}
+
+/**
  * Establish the new replacement IKE_SA
  */
 static void establish_new(private_ike_rekey_t *this)
 {
 	if (this->new_sa)
 	{
+		job_t *job;
+
 		this->new_sa->set_state(this->new_sa, IKE_ESTABLISHED);
 		DBG0(DBG_IKE, "IKE_SA %s[%d] rekeyed between %H[%Y]...%H[%Y]",
 			 this->new_sa->get_name(this->new_sa),
@@ -85,7 +107,14 @@ static void establish_new(private_ike_rekey_t *this)
 
 		this->new_sa->inherit_post(this->new_sa, this->ike_sa);
 		charon->bus->ike_rekey(charon->bus, this->ike_sa, this->new_sa);
+		job = check_queued_tasks(this->new_sa);
+		/* don't queue job before checkin(), as the IKE_SA is not yet
+		 * registered at the manager */
 		charon->ike_sa_manager->checkin(charon->ike_sa_manager, this->new_sa);
+		if (job)
+		{
+			lib->processor->queue_job(lib->processor, job);
+		}
 		this->new_sa = NULL;
 		/* set threads active IKE_SA after checkin */
 		charon->bus->set_sa(charon->bus, this->ike_sa);
@@ -163,6 +192,7 @@ METHOD(task_t, process_r, status_t,
 		{
 			case CHILD_CREATED:
 			case CHILD_REKEYING:
+			case CHILD_RETRYING:
 			case CHILD_DELETING:
 				/* we do not allow rekeying while we have children in-progress */
 				DBG1(DBG_IKE, "peer initiated rekeying, but a child is half-open");
@@ -209,6 +239,12 @@ METHOD(task_t, build_r, status_t,
 	this->public.task.build = _build_r_delete;
 	this->public.task.process = _process_r_delete;
 
+	/* the peer does have to delete the IKE_SA. If it does not, we get a
+	 * unusable IKE_SA in REKEYING state without a replacement. We consider
+	 * this a timeout condition by the peer, and trigger a delete actively. */
+	lib->scheduler->schedule_job(lib->scheduler, (job_t*)
+		delete_ike_sa_job_create(this->ike_sa->get_id(this->ike_sa), TRUE), 90);
+
 	return NEED_MORE;
 }
 
diff --git a/src/libcharon/sa/task.c b/src/libcharon/sa/task.c
index 4336b23..b35b581 100644
--- a/src/libcharon/sa/task.c
+++ b/src/libcharon/sa/task.c
@@ -27,6 +27,7 @@ ENUM(task_type_names, TASK_IKE_INIT, TASK_ISAKMP_CERT_POST,
 	"IKE_CONFIG",
 	"IKE_REKEY",
 	"IKE_REAUTH",
+	"IKE_REAUTH_COMPLETE",
 	"IKE_DELETE",
 	"IKE_DPD",
 	"IKE_VENDOR",
diff --git a/src/libcharon/sa/task.h b/src/libcharon/sa/task.h
index f2c4299..7bd3da1 100644
--- a/src/libcharon/sa/task.h
+++ b/src/libcharon/sa/task.h
@@ -22,6 +22,8 @@
 #ifndef TASK_H_
 #define TASK_H_
 
+#include <utils/utils.h>
+
 typedef enum task_type_t task_type_t;
 typedef struct task_t task_t;
 
@@ -51,8 +53,10 @@ enum task_type_t {
 	TASK_IKE_CONFIG,
 	/** rekey an IKE_SA */
 	TASK_IKE_REKEY,
-	/** reestablish a complete IKE_SA */
+	/** reestablish a complete IKE_SA, break-before-make */
 	TASK_IKE_REAUTH,
+	/** completion task for make-before-break IKE_SA re-authentication */
+	TASK_IKE_REAUTH_COMPLETE,
 	/** delete an IKE_SA */
 	TASK_IKE_DELETE,
 	/** liveness check */
diff --git a/src/libcharon/sa/trap_manager.c b/src/libcharon/sa/trap_manager.c
index 7e55d6b..d6ff3c8 100644
--- a/src/libcharon/sa/trap_manager.c
+++ b/src/libcharon/sa/trap_manager.c
@@ -65,6 +65,11 @@ struct private_trap_manager_t {
 	 * listener to track acquiring IKE_SAs
 	 */
 	trap_listener_t listener;
+
+	/**
+	 * Whether to ignore traffic selectors from acquires
+	 */
+	bool ignore_acquire_ts;
 };
 
 /**
@@ -171,7 +176,7 @@ METHOD(trap_manager_t, install, u_int32_t,
 	this->lock->unlock(this->lock);
 
 	/* create and route CHILD_SA */
-	child_sa = child_sa_create(me, other, child, reqid, FALSE);
+	child_sa = child_sa_create(me, other, child, reqid, FALSE, 0, 0);
 
 	list = linked_list_create_with_items(me, NULL);
 	my_ts = child->get_traffic_selectors(child, TRUE, NULL, list);
@@ -353,7 +358,7 @@ METHOD(trap_manager_t, acquire, void,
 		{
 			ike_sa->set_peer_cfg(ike_sa, peer);
 		}
-		if (ike_sa->get_version(ike_sa) == IKEV1)
+		if (this->ignore_acquire_ts || ike_sa->get_version(ike_sa) == IKEV1)
 		{	/* in IKEv1, don't prepend the acquiring packet TS, as we only
 			 * have a single TS that we can establish in a Quick Mode. */
 			src = dst = NULL;
@@ -484,6 +489,8 @@ trap_manager_t *trap_manager_create(void)
 		},
 		.traps = linked_list_create(),
 		.lock = rwlock_create(RWLOCK_TYPE_DEFAULT),
+		.ignore_acquire_ts = lib->settings->get_bool(lib->settings,
+										"%s.ignore_acquire_ts", FALSE, lib->ns),
 	);
 	charon->bus->add_listener(charon->bus, &this->listener.listener);
 
diff --git a/src/libcharon/tests/Makefile.am b/src/libcharon/tests/Makefile.am
new file mode 100644
index 0000000..c8be285
--- /dev/null
+++ b/src/libcharon/tests/Makefile.am
@@ -0,0 +1,21 @@
+TESTS = libcharon_tests
+
+check_PROGRAMS = $(TESTS)
+
+libcharon_tests_SOURCES = \
+  suites/test_mem_pool.c \
+  libcharon_tests.h libcharon_tests.c
+
+libcharon_tests_CFLAGS = \
+  -I$(top_srcdir)/src/libcharon \
+  -I$(top_srcdir)/src/libhydra \
+  -I$(top_srcdir)/src/libstrongswan \
+  -I$(top_srcdir)/src/libstrongswan/tests \
+  @COVERAGE_CFLAGS@
+
+libcharon_tests_LDFLAGS = @COVERAGE_LDFLAGS@
+libcharon_tests_LDADD = \
+  $(top_builddir)/src/libcharon/libcharon.la \
+  $(top_builddir)/src/libhydra/libhydra.la \
+  $(top_builddir)/src/libstrongswan/libstrongswan.la \
+  $(top_builddir)/src/libstrongswan/tests/libtest.la
diff --git a/src/libcharon/tests/Makefile.in b/src/libcharon/tests/Makefile.in
new file mode 100644
index 0000000..7f4f4b2
--- /dev/null
+++ b/src/libcharon/tests/Makefile.in
@@ -0,0 +1,874 @@
+# Makefile.in generated by automake 1.14.1 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994-2013 Free Software Foundation, Inc.
+
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+ at SET_MAKE@
+VPATH = @srcdir@
+am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)'
+am__make_running_with_option = \
+  case $${target_option-} in \
+      ?) ;; \
+      *) echo "am__make_running_with_option: internal error: invalid" \
+              "target option '$${target_option-}' specified" >&2; \
+         exit 1;; \
+  esac; \
+  has_opt=no; \
+  sane_makeflags=$$MAKEFLAGS; \
+  if $(am__is_gnu_make); then \
+    sane_makeflags=$$MFLAGS; \
+  else \
+    case $$MAKEFLAGS in \
+      *\\[\ \	]*) \
+        bs=\\; \
+        sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
+          | sed "s/$$bs$$bs[$$bs $$bs	]*//g"`;; \
+    esac; \
+  fi; \
+  skip_next=no; \
+  strip_trailopt () \
+  { \
+    flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
+  }; \
+  for flg in $$sane_makeflags; do \
+    test $$skip_next = yes && { skip_next=no; continue; }; \
+    case $$flg in \
+      *=*|--*) continue;; \
+        -*I) strip_trailopt 'I'; skip_next=yes;; \
+      -*I?*) strip_trailopt 'I';; \
+        -*O) strip_trailopt 'O'; skip_next=yes;; \
+      -*O?*) strip_trailopt 'O';; \
+        -*l) strip_trailopt 'l'; skip_next=yes;; \
+      -*l?*) strip_trailopt 'l';; \
+      -[dEDm]) skip_next=yes;; \
+      -[JT]) skip_next=yes;; \
+    esac; \
+    case $$flg in \
+      *$$target_option*) has_opt=yes; break;; \
+    esac; \
+  done; \
+  test $$has_opt = yes
+am__make_dryrun = (target_option=n; $(am__make_running_with_option))
+am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+TESTS = libcharon_tests$(EXEEXT)
+check_PROGRAMS = $(am__EXEEXT_1)
+subdir = src/libcharon/tests
+DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
+	$(top_srcdir)/depcomp
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/m4/config/libtool.m4 \
+	$(top_srcdir)/m4/config/ltoptions.m4 \
+	$(top_srcdir)/m4/config/ltsugar.m4 \
+	$(top_srcdir)/m4/config/ltversion.m4 \
+	$(top_srcdir)/m4/config/lt~obsolete.m4 \
+	$(top_srcdir)/m4/macros/split-package-version.m4 \
+	$(top_srcdir)/m4/macros/with.m4 \
+	$(top_srcdir)/m4/macros/enable-disable.m4 \
+	$(top_srcdir)/m4/macros/add-plugin.m4 \
+	$(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+	$(ACLOCAL_M4)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+am__EXEEXT_1 = libcharon_tests$(EXEEXT)
+am__dirstamp = $(am__leading_dot)dirstamp
+am_libcharon_tests_OBJECTS =  \
+	suites/libcharon_tests-test_mem_pool.$(OBJEXT) \
+	libcharon_tests-libcharon_tests.$(OBJEXT)
+libcharon_tests_OBJECTS = $(am_libcharon_tests_OBJECTS)
+libcharon_tests_DEPENDENCIES =  \
+	$(top_builddir)/src/libcharon/libcharon.la \
+	$(top_builddir)/src/libhydra/libhydra.la \
+	$(top_builddir)/src/libstrongswan/libstrongswan.la \
+	$(top_builddir)/src/libstrongswan/tests/libtest.la
+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 = 
+libcharon_tests_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \
+	$(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \
+	$(libcharon_tests_CFLAGS) $(CFLAGS) $(libcharon_tests_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
+am__v_P_1 = :
+AM_V_GEN = $(am__v_GEN_ at AM_V@)
+am__v_GEN_ = $(am__v_GEN_ at AM_DEFAULT_V@)
+am__v_GEN_0 = @echo "  GEN     " $@;
+am__v_GEN_1 = 
+AM_V_at = $(am__v_at_ at AM_V@)
+am__v_at_ = $(am__v_at_ at AM_DEFAULT_V@)
+am__v_at_0 = @
+am__v_at_1 = 
+DEFAULT_INCLUDES = -I. at am__isrc@ -I$(top_builddir)
+depcomp = $(SHELL) $(top_srcdir)/depcomp
+am__depfiles_maybe = depfiles
+am__mv = mv -f
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+	$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+	$(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \
+	$(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
+	$(AM_CFLAGS) $(CFLAGS)
+AM_V_CC = $(am__v_CC_ at AM_V@)
+am__v_CC_ = $(am__v_CC_ at AM_DEFAULT_V@)
+am__v_CC_0 = @echo "  CC      " $@;
+am__v_CC_1 = 
+CCLD = $(CC)
+LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+	$(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+	$(AM_LDFLAGS) $(LDFLAGS) -o $@
+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 = $(libcharon_tests_SOURCES)
+DIST_SOURCES = $(libcharon_tests_SOURCES)
+am__can_run_installinfo = \
+  case $$AM_UPDATE_INFO_DIR in \
+    n|no|NO) false;; \
+    *) (install-info --version) >/dev/null 2>&1;; \
+  esac
+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
+# *not* preserved.
+am__uniquify_input = $(AWK) '\
+  BEGIN { nonempty = 0; } \
+  { items[$$0] = 1; nonempty = 1; } \
+  END { if (nonempty) { for (i in items) print i; }; } \
+'
+# Make sure the list of sources is unique.  This is necessary because,
+# e.g., the same source file might be shared among _SOURCES variables
+# for different programs/libraries.
+am__define_uniq_tagged_files = \
+  list='$(am__tagged_files)'; \
+  unique=`for i in $$list; do \
+    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+  done | $(am__uniquify_input)`
+ETAGS = etags
+CTAGS = ctags
+am__tty_colors_dummy = \
+  mgn= red= grn= lgn= blu= brg= std=; \
+  am__color_tests=no
+am__tty_colors = { \
+  $(am__tty_colors_dummy); \
+  if test "X$(AM_COLOR_TESTS)" = Xno; then \
+    am__color_tests=no; \
+  elif test "X$(AM_COLOR_TESTS)" = Xalways; then \
+    am__color_tests=yes; \
+  elif test "X$$TERM" != Xdumb && { test -t 1; } 2>/dev/null; then \
+    am__color_tests=yes; \
+  fi; \
+  if test $$am__color_tests = yes; then \
+    red=''; \
+    grn=''; \
+    lgn=''; \
+    blu=''; \
+    mgn=''; \
+    brg=''; \
+    std=''; \
+  fi; \
+}
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+ALLOCA = @ALLOCA@
+AMTAR = @AMTAR@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+BFDLIB = @BFDLIB@
+BTLIB = @BTLIB@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+COVERAGE_CFLAGS = @COVERAGE_CFLAGS@
+COVERAGE_LDFLAGS = @COVERAGE_LDFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DLLIB = @DLLIB@
+DLLTOOL = @DLLTOOL@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+EASY_INSTALL = @EASY_INSTALL@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+FGREP = @FGREP@
+GEM = @GEM@
+GENHTML = @GENHTML@
+GPERF = @GPERF@
+GPRBUILD = @GPRBUILD@
+GREP = @GREP@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+LCOV = @LCOV@
+LD = @LD@
+LDFLAGS = @LDFLAGS@
+LEX = @LEX@
+LEXLIB = @LEXLIB@
+LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LIPO = @LIPO@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+MAKEINFO = @MAKEINFO@
+MANIFEST_TOOL = @MANIFEST_TOOL@
+MKDIR_P = @MKDIR_P@
+MYSQLCFLAG = @MYSQLCFLAG@
+MYSQLCONFIG = @MYSQLCONFIG@
+MYSQLLIB = @MYSQLLIB@
+NM = @NM@
+NMEDIT = @NMEDIT@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OPENSSL_LIB = @OPENSSL_LIB@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PACKAGE_VERSION_BUILD = @PACKAGE_VERSION_BUILD@
+PACKAGE_VERSION_MAJOR = @PACKAGE_VERSION_MAJOR@
+PACKAGE_VERSION_MINOR = @PACKAGE_VERSION_MINOR@
+PACKAGE_VERSION_REVIEW = @PACKAGE_VERSION_REVIEW@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PERL = @PERL@
+PKG_CONFIG = @PKG_CONFIG@
+PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
+PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
+PLUGIN_CFLAGS = @PLUGIN_CFLAGS@
+PTHREADLIB = @PTHREADLIB@
+PYTHON = @PYTHON@
+PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@
+PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
+PYTHON_PLATFORM = @PYTHON_PLATFORM@
+PYTHON_PREFIX = @PYTHON_PREFIX@
+PYTHON_VERSION = @PYTHON_VERSION@
+PY_TEST = @PY_TEST@
+RANLIB = @RANLIB@
+RTLIB = @RTLIB@
+RUBY = @RUBY@
+RUBYGEMDIR = @RUBYGEMDIR@
+RUBYINCLUDE = @RUBYINCLUDE@
+RUBYLIB = @RUBYLIB@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+SOCKLIB = @SOCKLIB@
+STRIP = @STRIP@
+UNWINDLIB = @UNWINDLIB@
+VERSION = @VERSION@
+YACC = @YACC@
+YFLAGS = @YFLAGS@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+aikgen_plugins = @aikgen_plugins@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+attest_plugins = @attest_plugins@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+c_plugins = @c_plugins@
+charon_natt_port = @charon_natt_port@
+charon_plugins = @charon_plugins@
+charon_udp_port = @charon_udp_port@
+clearsilver_LIBS = @clearsilver_LIBS@
+cmd_plugins = @cmd_plugins@
+datadir = @datadir@
+datarootdir = @datarootdir@
+dbusservicedir = @dbusservicedir@
+dev_headers = @dev_headers@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+fips_mode = @fips_mode@
+gtk_CFLAGS = @gtk_CFLAGS@
+gtk_LIBS = @gtk_LIBS@
+h_plugins = @h_plugins@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+imcvdir = @imcvdir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+ipsec_script = @ipsec_script@
+ipsec_script_upper = @ipsec_script_upper@
+ipsecdir = @ipsecdir@
+ipsecgroup = @ipsecgroup@
+ipseclibdir = @ipseclibdir@
+ipsecuser = @ipsecuser@
+json_CFLAGS = @json_CFLAGS@
+json_LIBS = @json_LIBS@
+libdir = @libdir@
+libexecdir = @libexecdir@
+libiptc_CFLAGS = @libiptc_CFLAGS@
+libiptc_LIBS = @libiptc_LIBS@
+linux_headers = @linux_headers@
+localedir = @localedir@
+localstatedir = @localstatedir@
+maemo_CFLAGS = @maemo_CFLAGS@
+maemo_LIBS = @maemo_LIBS@
+manager_plugins = @manager_plugins@
+mandir = @mandir@
+medsrv_plugins = @medsrv_plugins@
+mkdir_p = @mkdir_p@
+nm_CFLAGS = @nm_CFLAGS@
+nm_LIBS = @nm_LIBS@
+nm_ca_dir = @nm_ca_dir@
+nm_plugins = @nm_plugins@
+oldincludedir = @oldincludedir@
+pcsclite_CFLAGS = @pcsclite_CFLAGS@
+pcsclite_LIBS = @pcsclite_LIBS@
+pdfdir = @pdfdir@
+piddir = @piddir@
+pkgpyexecdir = @pkgpyexecdir@
+pkgpythondir = @pkgpythondir@
+pki_plugins = @pki_plugins@
+plugindir = @plugindir@
+pool_plugins = @pool_plugins@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+pyexecdir = @pyexecdir@
+pythondir = @pythondir@
+random_device = @random_device@
+resolv_conf = @resolv_conf@
+routing_table = @routing_table@
+routing_table_prio = @routing_table_prio@
+s_plugins = @s_plugins@
+sbindir = @sbindir@
+scepclient_plugins = @scepclient_plugins@
+scripts_plugins = @scripts_plugins@
+sharedstatedir = @sharedstatedir@
+soup_CFLAGS = @soup_CFLAGS@
+soup_LIBS = @soup_LIBS@
+srcdir = @srcdir@
+starter_plugins = @starter_plugins@
+strongswan_conf = @strongswan_conf@
+strongswan_options = @strongswan_options@
+swanctldir = @swanctldir@
+sysconfdir = @sysconfdir@
+systemd_daemon_CFLAGS = @systemd_daemon_CFLAGS@
+systemd_daemon_LIBS = @systemd_daemon_LIBS@
+systemd_journal_CFLAGS = @systemd_journal_CFLAGS@
+systemd_journal_LIBS = @systemd_journal_LIBS@
+systemdsystemunitdir = @systemdsystemunitdir@
+t_plugins = @t_plugins@
+target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+urandom_device = @urandom_device@
+xml_CFLAGS = @xml_CFLAGS@
+xml_LIBS = @xml_LIBS@
+libcharon_tests_SOURCES = \
+  suites/test_mem_pool.c \
+  libcharon_tests.h libcharon_tests.c
+
+libcharon_tests_CFLAGS = \
+  -I$(top_srcdir)/src/libcharon \
+  -I$(top_srcdir)/src/libhydra \
+  -I$(top_srcdir)/src/libstrongswan \
+  -I$(top_srcdir)/src/libstrongswan/tests \
+  @COVERAGE_CFLAGS@
+
+libcharon_tests_LDFLAGS = @COVERAGE_LDFLAGS@
+libcharon_tests_LDADD = \
+  $(top_builddir)/src/libcharon/libcharon.la \
+  $(top_builddir)/src/libhydra/libhydra.la \
+  $(top_builddir)/src/libstrongswan/libstrongswan.la \
+  $(top_builddir)/src/libstrongswan/tests/libtest.la
+
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .c .lo .o .obj
+$(srcdir)/Makefile.in:  $(srcdir)/Makefile.am  $(am__configure_deps)
+	@for dep in $?; do \
+	  case '$(am__configure_deps)' in \
+	    *$$dep*) \
+	      ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+	        && { if test -f $@; then exit 0; else break; fi; }; \
+	      exit 1;; \
+	  esac; \
+	done; \
+	echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/libcharon/tests/Makefile'; \
+	$(am__cd) $(top_srcdir) && \
+	  $(AUTOMAKE) --gnu src/libcharon/tests/Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+	@case '$?' in \
+	  *config.status*) \
+	    cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+	  *) \
+	    echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+	    cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+	esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure:  $(am__configure_deps)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4):  $(am__aclocal_m4_deps)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+
+clean-checkPROGRAMS:
+	@list='$(check_PROGRAMS)'; test -n "$$list" || exit 0; \
+	echo " rm -f" $$list; \
+	rm -f $$list || exit $$?; \
+	test -n "$(EXEEXT)" || exit 0; \
+	list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \
+	echo " rm -f" $$list; \
+	rm -f $$list
+suites/$(am__dirstamp):
+	@$(MKDIR_P) suites
+	@: > suites/$(am__dirstamp)
+suites/$(DEPDIR)/$(am__dirstamp):
+	@$(MKDIR_P) suites/$(DEPDIR)
+	@: > suites/$(DEPDIR)/$(am__dirstamp)
+suites/libcharon_tests-test_mem_pool.$(OBJEXT):  \
+	suites/$(am__dirstamp) suites/$(DEPDIR)/$(am__dirstamp)
+
+libcharon_tests$(EXEEXT): $(libcharon_tests_OBJECTS) $(libcharon_tests_DEPENDENCIES) $(EXTRA_libcharon_tests_DEPENDENCIES) 
+	@rm -f libcharon_tests$(EXEEXT)
+	$(AM_V_CCLD)$(libcharon_tests_LINK) $(libcharon_tests_OBJECTS) $(libcharon_tests_LDADD) $(LIBS)
+
+mostlyclean-compile:
+	-rm -f *.$(OBJEXT)
+	-rm -f suites/*.$(OBJEXT)
+
+distclean-compile:
+	-rm -f *.tab.c
+
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libcharon_tests-libcharon_tests.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at suites/$(DEPDIR)/libcharon_tests-test_mem_pool.Po at am__quote@
+
+.c.o:
+ at am__fastdepCC_TRUE@	$(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\
+ at am__fastdepCC_TRUE@	$(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\
+ at am__fastdepCC_TRUE@	$(am__mv) $$depbase.Tpo $$depbase.Po
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(COMPILE) -c -o $@ $<
+
+.c.obj:
+ at am__fastdepCC_TRUE@	$(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\
+ at am__fastdepCC_TRUE@	$(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\
+ at am__fastdepCC_TRUE@	$(am__mv) $$depbase.Tpo $$depbase.Po
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
+
+.c.lo:
+ at am__fastdepCC_TRUE@	$(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\
+ at am__fastdepCC_TRUE@	$(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\
+ at am__fastdepCC_TRUE@	$(am__mv) $$depbase.Tpo $$depbase.Plo
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(LTCOMPILE) -c -o $@ $<
+
+suites/libcharon_tests-test_mem_pool.o: suites/test_mem_pool.c
+ at am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcharon_tests_CFLAGS) $(CFLAGS) -MT suites/libcharon_tests-test_mem_pool.o -MD -MP -MF suites/$(DEPDIR)/libcharon_tests-test_mem_pool.Tpo -c -o suites/libcharon_tests-test_mem_pool.o `test -f 'suites/test_mem_pool.c' || echo '$(srcdir)/'`suites/test_mem_pool.c
+ at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) suites/$(DEPDIR)/libcharon_tests-test_mem_pool.Tpo suites/$(DEPDIR)/libcharon_tests-test_mem_pool.Po
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='suites/test_mem_pool.c' object='suites/libcharon_tests-test_mem_pool.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) $(libcharon_tests_CFLAGS) $(CFLAGS) -c -o suites/libcharon_tests-test_mem_pool.o `test -f 'suites/test_mem_pool.c' || echo '$(srcdir)/'`suites/test_mem_pool.c
+
+suites/libcharon_tests-test_mem_pool.obj: suites/test_mem_pool.c
+ at am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcharon_tests_CFLAGS) $(CFLAGS) -MT suites/libcharon_tests-test_mem_pool.obj -MD -MP -MF suites/$(DEPDIR)/libcharon_tests-test_mem_pool.Tpo -c -o suites/libcharon_tests-test_mem_pool.obj `if test -f 'suites/test_mem_pool.c'; then $(CYGPATH_W) 'suites/test_mem_pool.c'; else $(CYGPATH_W) '$(srcdir)/suites/test_mem_pool.c'; fi`
+ at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) suites/$(DEPDIR)/libcharon_tests-test_mem_pool.Tpo suites/$(DEPDIR)/libcharon_tests-test_mem_pool.Po
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='suites/test_mem_pool.c' object='suites/libcharon_tests-test_mem_pool.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) $(libcharon_tests_CFLAGS) $(CFLAGS) -c -o suites/libcharon_tests-test_mem_pool.obj `if test -f 'suites/test_mem_pool.c'; then $(CYGPATH_W) 'suites/test_mem_pool.c'; else $(CYGPATH_W) '$(srcdir)/suites/test_mem_pool.c'; fi`
+
+libcharon_tests-libcharon_tests.o: libcharon_tests.c
+ at am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcharon_tests_CFLAGS) $(CFLAGS) -MT libcharon_tests-libcharon_tests.o -MD -MP -MF $(DEPDIR)/libcharon_tests-libcharon_tests.Tpo -c -o libcharon_tests-libcharon_tests.o `test -f 'libcharon_tests.c' || echo '$(srcdir)/'`libcharon_tests.c
+ at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/libcharon_tests-libcharon_tests.Tpo $(DEPDIR)/libcharon_tests-libcharon_tests.Po
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='libcharon_tests.c' object='libcharon_tests-libcharon_tests.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) $(libcharon_tests_CFLAGS) $(CFLAGS) -c -o libcharon_tests-libcharon_tests.o `test -f 'libcharon_tests.c' || echo '$(srcdir)/'`libcharon_tests.c
+
+libcharon_tests-libcharon_tests.obj: libcharon_tests.c
+ at am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcharon_tests_CFLAGS) $(CFLAGS) -MT libcharon_tests-libcharon_tests.obj -MD -MP -MF $(DEPDIR)/libcharon_tests-libcharon_tests.Tpo -c -o libcharon_tests-libcharon_tests.obj `if test -f 'libcharon_tests.c'; then $(CYGPATH_W) 'libcharon_tests.c'; else $(CYGPATH_W) '$(srcdir)/libcharon_tests.c'; fi`
+ at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/libcharon_tests-libcharon_tests.Tpo $(DEPDIR)/libcharon_tests-libcharon_tests.Po
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='libcharon_tests.c' object='libcharon_tests-libcharon_tests.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) $(libcharon_tests_CFLAGS) $(CFLAGS) -c -o libcharon_tests-libcharon_tests.obj `if test -f 'libcharon_tests.c'; then $(CYGPATH_W) 'libcharon_tests.c'; else $(CYGPATH_W) '$(srcdir)/libcharon_tests.c'; fi`
+
+mostlyclean-libtool:
+	-rm -f *.lo
+
+clean-libtool:
+	-rm -rf .libs _libs
+
+ID: $(am__tagged_files)
+	$(am__define_uniq_tagged_files); mkid -fID $$unique
+tags: tags-am
+TAGS: tags
+
+tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+	set x; \
+	here=`pwd`; \
+	$(am__define_uniq_tagged_files); \
+	shift; \
+	if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
+	  test -n "$$unique" || unique=$$empty_fix; \
+	  if test $$# -gt 0; then \
+	    $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+	      "$$@" $$unique; \
+	  else \
+	    $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+	      $$unique; \
+	  fi; \
+	fi
+ctags: ctags-am
+
+CTAGS: ctags
+ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+	$(am__define_uniq_tagged_files); \
+	test -z "$(CTAGS_ARGS)$$unique" \
+	  || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+	     $$unique
+
+GTAGS:
+	here=`$(am__cd) $(top_builddir) && pwd` \
+	  && $(am__cd) $(top_srcdir) \
+	  && gtags -i $(GTAGS_ARGS) "$$here"
+cscopelist: cscopelist-am
+
+cscopelist-am: $(am__tagged_files)
+	list='$(am__tagged_files)'; \
+	case "$(srcdir)" in \
+	  [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
+	  *) sdir=$(subdir)/$(srcdir) ;; \
+	esac; \
+	for i in $$list; do \
+	  if test -f "$$i"; then \
+	    echo "$(subdir)/$$i"; \
+	  else \
+	    echo "$$sdir/$$i"; \
+	  fi; \
+	done >> $(top_builddir)/cscope.files
+
+distclean-tags:
+	-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+check-TESTS: $(TESTS)
+	@failed=0; all=0; xfail=0; xpass=0; skip=0; \
+	srcdir=$(srcdir); export srcdir; \
+	list=' $(TESTS) '; \
+	$(am__tty_colors); \
+	if test -n "$$list"; then \
+	  for tst in $$list; do \
+	    if test -f ./$$tst; then dir=./; \
+	    elif test -f $$tst; then dir=; \
+	    else dir="$(srcdir)/"; fi; \
+	    if $(TESTS_ENVIRONMENT) $${dir}$$tst $(AM_TESTS_FD_REDIRECT); then \
+	      all=`expr $$all + 1`; \
+	      case " $(XFAIL_TESTS) " in \
+	      *[\ \	]$$tst[\ \	]*) \
+		xpass=`expr $$xpass + 1`; \
+		failed=`expr $$failed + 1`; \
+		col=$$red; res=XPASS; \
+	      ;; \
+	      *) \
+		col=$$grn; res=PASS; \
+	      ;; \
+	      esac; \
+	    elif test $$? -ne 77; then \
+	      all=`expr $$all + 1`; \
+	      case " $(XFAIL_TESTS) " in \
+	      *[\ \	]$$tst[\ \	]*) \
+		xfail=`expr $$xfail + 1`; \
+		col=$$lgn; res=XFAIL; \
+	      ;; \
+	      *) \
+		failed=`expr $$failed + 1`; \
+		col=$$red; res=FAIL; \
+	      ;; \
+	      esac; \
+	    else \
+	      skip=`expr $$skip + 1`; \
+	      col=$$blu; res=SKIP; \
+	    fi; \
+	    echo "$${col}$$res$${std}: $$tst"; \
+	  done; \
+	  if test "$$all" -eq 1; then \
+	    tests="test"; \
+	    All=""; \
+	  else \
+	    tests="tests"; \
+	    All="All "; \
+	  fi; \
+	  if test "$$failed" -eq 0; then \
+	    if test "$$xfail" -eq 0; then \
+	      banner="$$All$$all $$tests passed"; \
+	    else \
+	      if test "$$xfail" -eq 1; then failures=failure; else failures=failures; fi; \
+	      banner="$$All$$all $$tests behaved as expected ($$xfail expected $$failures)"; \
+	    fi; \
+	  else \
+	    if test "$$xpass" -eq 0; then \
+	      banner="$$failed of $$all $$tests failed"; \
+	    else \
+	      if test "$$xpass" -eq 1; then passes=pass; else passes=passes; fi; \
+	      banner="$$failed of $$all $$tests did not behave as expected ($$xpass unexpected $$passes)"; \
+	    fi; \
+	  fi; \
+	  dashes="$$banner"; \
+	  skipped=""; \
+	  if test "$$skip" -ne 0; then \
+	    if test "$$skip" -eq 1; then \
+	      skipped="($$skip test was not run)"; \
+	    else \
+	      skipped="($$skip tests were not run)"; \
+	    fi; \
+	    test `echo "$$skipped" | wc -c` -le `echo "$$banner" | wc -c` || \
+	      dashes="$$skipped"; \
+	  fi; \
+	  report=""; \
+	  if test "$$failed" -ne 0 && test -n "$(PACKAGE_BUGREPORT)"; then \
+	    report="Please report to $(PACKAGE_BUGREPORT)"; \
+	    test `echo "$$report" | wc -c` -le `echo "$$banner" | wc -c` || \
+	      dashes="$$report"; \
+	  fi; \
+	  dashes=`echo "$$dashes" | sed s/./=/g`; \
+	  if test "$$failed" -eq 0; then \
+	    col="$$grn"; \
+	  else \
+	    col="$$red"; \
+	  fi; \
+	  echo "$${col}$$dashes$${std}"; \
+	  echo "$${col}$$banner$${std}"; \
+	  test -z "$$skipped" || echo "$${col}$$skipped$${std}"; \
+	  test -z "$$report" || echo "$${col}$$report$${std}"; \
+	  echo "$${col}$$dashes$${std}"; \
+	  test "$$failed" -eq 0; \
+	else :; fi
+
+distdir: $(DISTFILES)
+	@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+	topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+	list='$(DISTFILES)'; \
+	  dist_files=`for file in $$list; do echo $$file; done | \
+	  sed -e "s|^$$srcdirstrip/||;t" \
+	      -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+	case $$dist_files in \
+	  */*) $(MKDIR_P) `echo "$$dist_files" | \
+			   sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+			   sort -u` ;; \
+	esac; \
+	for file in $$dist_files; do \
+	  if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+	  if test -d $$d/$$file; then \
+	    dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+	    if test -d "$(distdir)/$$file"; then \
+	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+	    fi; \
+	    if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+	      cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+	    fi; \
+	    cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+	  else \
+	    test -f "$(distdir)/$$file" \
+	    || cp -p $$d/$$file "$(distdir)/$$file" \
+	    || exit 1; \
+	  fi; \
+	done
+check-am: all-am
+	$(MAKE) $(AM_MAKEFLAGS) $(check_PROGRAMS)
+	$(MAKE) $(AM_MAKEFLAGS) check-TESTS
+check: check-am
+all-am: Makefile
+installdirs:
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+	@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+	if test -z '$(STRIP)'; then \
+	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	      install; \
+	else \
+	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	    "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+	fi
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+	-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+	-test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+	-rm -f suites/$(DEPDIR)/$(am__dirstamp)
+	-rm -f suites/$(am__dirstamp)
+
+maintainer-clean-generic:
+	@echo "This command is intended for maintainers to use"
+	@echo "it deletes files that may require special tools to rebuild."
+clean: clean-am
+
+clean-am: clean-checkPROGRAMS clean-generic clean-libtool \
+	mostlyclean-am
+
+distclean: distclean-am
+	-rm -rf ./$(DEPDIR) suites/$(DEPDIR)
+	-rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+	distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+html-am:
+
+info: info-am
+
+info-am:
+
+install-data-am:
+
+install-dvi: install-dvi-am
+
+install-dvi-am:
+
+install-exec-am:
+
+install-html: install-html-am
+
+install-html-am:
+
+install-info: install-info-am
+
+install-info-am:
+
+install-man:
+
+install-pdf: install-pdf-am
+
+install-pdf-am:
+
+install-ps: install-ps-am
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+	-rm -rf ./$(DEPDIR) suites/$(DEPDIR)
+	-rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic \
+	mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am:
+
+.MAKE: check-am install-am install-strip
+
+.PHONY: CTAGS GTAGS TAGS all all-am check check-TESTS check-am clean \
+	clean-checkPROGRAMS 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-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
+
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/src/libcharon/tests/libcharon_tests.c b/src/libcharon/tests/libcharon_tests.c
new file mode 100644
index 0000000..1ed0f0c
--- /dev/null
+++ b/src/libcharon/tests/libcharon_tests.c
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2014 Martin Willi
+ * Copyright (C) 2014 revosec AG
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * for more details.
+ */
+
+#include <test_runner.h>
+#include <hydra.h>
+#include <daemon.h>
+
+/* declare test suite constructors */
+#define TEST_SUITE(x) test_suite_t* x();
+#define TEST_SUITE_DEPEND(x, ...) TEST_SUITE(x)
+#include "libcharon_tests.h"
+#undef TEST_SUITE
+#undef TEST_SUITE_DEPEND
+
+static test_configuration_t tests[] = {
+#define TEST_SUITE(x) \
+	{ .suite = x, },
+#define TEST_SUITE_DEPEND(x, type, args) \
+	{ .suite = x, .feature = PLUGIN_DEPENDS(type, args) },
+#include "libcharon_tests.h"
+	{ .suite = NULL, }
+};
+
+static bool test_runner_init(bool init)
+{
+	if (init)
+	{
+		libhydra_init();
+		libcharon_init();
+	}
+	else
+	{
+		lib->processor->set_threads(lib->processor, 0);
+		lib->processor->cancel(lib->processor);
+		libcharon_deinit();
+		libhydra_deinit();
+	}
+	return TRUE;
+}
+
+int main(int argc, char *argv[])
+{
+	return test_runner_run("libcharon", tests, test_runner_init);
+}
diff --git a/src/libcharon/tests/libcharon_tests.h b/src/libcharon/tests/libcharon_tests.h
new file mode 100644
index 0000000..dc9681a
--- /dev/null
+++ b/src/libcharon/tests/libcharon_tests.h
@@ -0,0 +1,16 @@
+/*
+ * Copyright (C) 2014 Martin Willi
+ * Copyright (C) 2014 revosec AG
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * for more details.
+ */
+
+TEST_SUITE(mem_pool_suite_create)
diff --git a/src/libcharon/tests/suites/test_mem_pool.c b/src/libcharon/tests/suites/test_mem_pool.c
new file mode 100644
index 0000000..4204d4b
--- /dev/null
+++ b/src/libcharon/tests/suites/test_mem_pool.c
@@ -0,0 +1,230 @@
+/*
+ * Copyright (C) 2014 Tobias Brunner
+ * Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * for more details.
+ */
+
+#include "test_suite.h"
+
+#include <attributes/mem_pool.h>
+
+static void assert_host(char *expected, host_t *host)
+{
+	if (!expected)
+	{
+		ck_assert_msg(!host, "not epxecting IP != %+H", host);
+	}
+	else
+	{
+		host_t *verifier;
+		verifier = host_create_from_string(expected, 0);
+		ck_assert_msg(host, "expected IP %+H != NULL", verifier);
+		ck_assert_msg(verifier->ip_equals(verifier, host), "expected IP %+H != "
+					  "%+H", verifier, host);;
+		verifier->destroy(verifier);
+	}
+}
+
+static void assert_acquire(mem_pool_t *pool, char *requested, char *expected,
+						   mem_pool_op_t operation)
+{
+	identification_t *id;
+	host_t *req, *acquired;
+
+	id = identification_create_from_string("tester");
+	req = host_create_from_string(requested, 0);
+
+	acquired = pool->acquire_address(pool, id, req, operation, NULL);
+	assert_host(expected, acquired);
+	DESTROY_IF(acquired);
+
+	req->destroy(req);
+	id->destroy(id);
+}
+
+static void assert_acquires_new(mem_pool_t *pool, char *pattern, int first)
+{
+	char expected[16];
+	int i;
+
+	for (i = 0; i < pool->get_size(pool); i++)
+	{
+		snprintf(expected, sizeof(expected), pattern, first + i);
+		assert_acquire(pool, "0.0.0.0", expected, MEM_POOL_NEW);
+		ck_assert_int_eq(i + 1, pool->get_online(pool));
+	}
+	assert_acquire(pool, "0.0.0.0", NULL, MEM_POOL_NEW);
+}
+
+START_TEST(test_config)
+{
+	mem_pool_t *pool;
+
+	pool = mem_pool_create("test", NULL, 0);
+	ck_assert_int_eq(0, pool->get_size(pool));
+	assert_acquire(pool, "192.168.0.1", "192.168.0.1", MEM_POOL_NEW);
+	assert_acquire(pool, "10.0.1.1", "10.0.1.1", MEM_POOL_NEW);
+	assert_acquire(pool, "0.0.0.0", "0.0.0.0", MEM_POOL_NEW);
+	assert_acquire(pool, "255.255.255.255", "255.255.255.255", MEM_POOL_NEW);
+	ck_assert_int_eq(0, pool->get_online(pool));
+	pool->destroy(pool);
+}
+END_TEST
+
+START_TEST(test_cidr)
+{
+	mem_pool_t *pool;
+	host_t *base;
+
+	base = host_create_from_string("192.168.0.0", 0);
+
+	pool = mem_pool_create("test", base, 32);
+	ck_assert_int_eq(1, pool->get_size(pool));
+	assert_acquires_new(pool, "192.168.0.%d", 0);
+	pool->destroy(pool);
+
+	pool = mem_pool_create("test", base, 31);
+	ck_assert_int_eq(2, pool->get_size(pool));
+	assert_acquires_new(pool, "192.168.0.%d", 0);
+	pool->destroy(pool);
+
+	pool = mem_pool_create("test", base, 30);
+	ck_assert_int_eq(2, pool->get_size(pool));
+	assert_acquires_new(pool, "192.168.0.%d", 1);
+	pool->destroy(pool);
+
+	pool = mem_pool_create("test", base, 29);
+	ck_assert_int_eq(6, pool->get_size(pool));
+	assert_acquires_new(pool, "192.168.0.%d", 1);
+	pool->destroy(pool);
+
+	pool = mem_pool_create("test", base, 24);
+	ck_assert_int_eq(254, pool->get_size(pool));
+	assert_acquires_new(pool, "192.168.0.%d", 1);
+	pool->destroy(pool);
+
+	base->destroy(base);
+}
+END_TEST
+
+START_TEST(test_cidr_offset)
+{
+	mem_pool_t *pool;
+	host_t *base;
+
+	base = host_create_from_string("192.168.0.1", 0);
+	pool = mem_pool_create("test", base, 31);
+	ck_assert_int_eq(1, pool->get_size(pool));
+	assert_acquires_new(pool, "192.168.0.%d", 1);
+	pool->destroy(pool);
+
+	pool = mem_pool_create("test", base, 30);
+	ck_assert_int_eq(2, pool->get_size(pool));
+	assert_acquires_new(pool, "192.168.0.%d", 1);
+	pool->destroy(pool);
+	base->destroy(base);
+
+	base = host_create_from_string("192.168.0.2", 0);
+	pool = mem_pool_create("test", base, 30);
+	ck_assert_int_eq(1, pool->get_size(pool));
+	assert_acquires_new(pool, "192.168.0.%d", 2);
+	pool->destroy(pool);
+
+	pool = mem_pool_create("test", base, 24);
+	ck_assert_int_eq(253, pool->get_size(pool));
+	assert_acquires_new(pool, "192.168.0.%d", 2);
+	pool->destroy(pool);
+	base->destroy(base);
+
+	base = host_create_from_string("192.168.0.254", 0);
+	pool = mem_pool_create("test", base, 24);
+	ck_assert_int_eq(1, pool->get_size(pool));
+	assert_acquires_new(pool, "192.168.0.%d", 254);
+	pool->destroy(pool);
+	base->destroy(base);
+
+	/* due to size == 0 we get the requested IP back */
+	base = host_create_from_string("192.168.0.255", 0);
+	pool = mem_pool_create("test", base, 24);
+	ck_assert_int_eq(0, pool->get_size(pool));
+	assert_acquire(pool, "192.168.0.1", "192.168.0.1", MEM_POOL_NEW);
+	pool->destroy(pool);
+
+	base->destroy(base);
+}
+END_TEST
+
+START_TEST(test_range)
+{
+	mem_pool_t *pool;
+	host_t *from, *to;
+
+	from = host_create_from_string("192.168.0.0", 0);
+	to = host_create_from_string("192.168.0.0", 0);
+	pool = mem_pool_create_range("test", from, to);
+	ck_assert_int_eq(1, pool->get_size(pool));
+	assert_acquires_new(pool, "192.168.0.%d", 0);
+	pool->destroy(pool);
+
+	to->destroy(to);
+	to = host_create_from_string("192.168.0.1", 0);
+	pool = mem_pool_create_range("test", from, to);
+	ck_assert_int_eq(2, pool->get_size(pool));
+	assert_acquires_new(pool, "192.168.0.%d", 0);
+	pool->destroy(pool);
+
+	from->destroy(from);
+	from = host_create_from_string("192.168.0.10", 0);
+	pool = mem_pool_create_range("test", from, to);
+	ck_assert(!pool);
+
+	to->destroy(to);
+	to = host_create_from_string("192.168.0.20", 0);
+	pool = mem_pool_create_range("test", from, to);
+	ck_assert_int_eq(11, pool->get_size(pool));
+	assert_acquires_new(pool, "192.168.0.%d", 10);
+	pool->destroy(pool);
+
+	from->destroy(from);
+	from = host_create_from_string("fec::1", 0);
+	to->destroy(to);
+	to = host_create_from_string("fed::1", 0);
+	pool = mem_pool_create_range("test", from, to);
+	ck_assert(!pool);
+
+	from->destroy(from);
+	to->destroy(to);
+}
+END_TEST
+
+Suite *mem_pool_suite_create()
+{
+	Suite *s;
+	TCase *tc;
+
+	s = suite_create("mem_pool");
+
+	tc = tcase_create("%config-like pool");
+	tcase_add_test(tc, test_config);
+	suite_add_tcase(s, tc);
+
+	tc = tcase_create("cidr constructor");
+	tcase_add_test(tc, test_cidr);
+	tcase_add_test(tc, test_cidr_offset);
+	suite_add_tcase(s, tc);
+
+	tc = tcase_create("range constructor");
+	tcase_add_test(tc, test_range);
+	suite_add_tcase(s, tc);
+
+	return s;
+}
diff --git a/src/libfast/Makefile.in b/src/libfast/Makefile.in
index f0e9cbe..6a3a4eb 100644
--- a/src/libfast/Makefile.in
+++ b/src/libfast/Makefile.in
@@ -230,6 +230,7 @@ DLLIB = @DLLIB@
 DLLTOOL = @DLLTOOL@
 DSYMUTIL = @DSYMUTIL@
 DUMPBIN = @DUMPBIN@
+EASY_INSTALL = @EASY_INSTALL@
 ECHO_C = @ECHO_C@
 ECHO_N = @ECHO_N@
 ECHO_T = @ECHO_T@
@@ -290,10 +291,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
 PLUGIN_CFLAGS = @PLUGIN_CFLAGS@
 PTHREADLIB = @PTHREADLIB@
 PYTHON = @PYTHON@
+PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@
 PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
 PYTHON_PLATFORM = @PYTHON_PLATFORM@
 PYTHON_PREFIX = @PYTHON_PREFIX@
 PYTHON_VERSION = @PYTHON_VERSION@
+PY_TEST = @PY_TEST@
 RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
@@ -367,6 +370,8 @@ json_CFLAGS = @json_CFLAGS@
 json_LIBS = @json_LIBS@
 libdir = @libdir@
 libexecdir = @libexecdir@
+libiptc_CFLAGS = @libiptc_CFLAGS@
+libiptc_LIBS = @libiptc_LIBS@
 linux_headers = @linux_headers@
 localedir = @localedir@
 localstatedir = @localstatedir@
diff --git a/src/libhydra/Android.mk b/src/libhydra/Android.mk
index ff134da..af39f04 100644
--- a/src/libhydra/Android.mk
+++ b/src/libhydra/Android.mk
@@ -4,10 +4,6 @@ include $(CLEAR_VARS)
 # copy-n-paste from Makefile.am
 libhydra_la_SOURCES := \
 hydra.c hydra.h \
-attributes/attributes.c attributes/attributes.h \
-attributes/attribute_provider.h attributes/attribute_handler.h \
-attributes/attribute_manager.c attributes/attribute_manager.h \
-attributes/mem_pool.c attributes/mem_pool.h \
 kernel/kernel_interface.c kernel/kernel_interface.h \
 kernel/kernel_ipsec.c kernel/kernel_ipsec.h \
 kernel/kernel_net.c kernel/kernel_net.h \
@@ -17,8 +13,6 @@ LOCAL_SRC_FILES := $(filter %.c,$(libhydra_la_SOURCES))
 
 # adding the plugin source files
 
-LOCAL_SRC_FILES += $(call add_plugin, attr)
-
 LOCAL_SRC_FILES += $(call add_plugin, kernel-pfkey)
 
 LOCAL_SRC_FILES += $(call add_plugin, kernel-netlink)
@@ -42,4 +36,3 @@ LOCAL_PRELINK_MODULE := false
 LOCAL_SHARED_LIBRARIES += libstrongswan
 
 include $(BUILD_SHARED_LIBRARY)
-
diff --git a/src/libhydra/Makefile.am b/src/libhydra/Makefile.am
index 510f2a1..9cdbc01 100644
--- a/src/libhydra/Makefile.am
+++ b/src/libhydra/Makefile.am
@@ -2,10 +2,6 @@ ipseclib_LTLIBRARIES = libhydra.la
 
 libhydra_la_SOURCES = \
 hydra.c hydra.h \
-attributes/attributes.c attributes/attributes.h \
-attributes/attribute_provider.h attributes/attribute_handler.h \
-attributes/attribute_manager.c attributes/attribute_manager.h \
-attributes/mem_pool.c attributes/mem_pool.h \
 kernel/kernel_interface.c kernel/kernel_interface.h \
 kernel/kernel_ipsec.c kernel/kernel_ipsec.h \
 kernel/kernel_net.c kernel/kernel_net.h \
@@ -37,20 +33,6 @@ else
 SUBDIRS = .
 endif
 
-if USE_ATTR
-  SUBDIRS += plugins/attr
-if MONOLITHIC
-  libhydra_la_LIBADD += plugins/attr/libstrongswan-attr.la
-endif
-endif
-
-if USE_ATTR_SQL
-  SUBDIRS += plugins/attr_sql
-if MONOLITHIC
-  libhydra_la_LIBADD += plugins/attr_sql/libstrongswan-attr-sql.la
-endif
-endif
-
 if USE_KERNEL_PFKEY
   SUBDIRS += plugins/kernel_pfkey
 if MONOLITHIC
@@ -72,9 +54,7 @@ if MONOLITHIC
 endif
 endif
 
-if USE_RESOLVE
-  SUBDIRS += plugins/resolve
 if MONOLITHIC
-  libhydra_la_LIBADD += plugins/resolve/libstrongswan-resolve.la
-endif
+  SUBDIRS += .
 endif
+SUBDIRS += tests
diff --git a/src/libhydra/Makefile.in b/src/libhydra/Makefile.in
index e3ff198..9bb2e83 100644
--- a/src/libhydra/Makefile.in
+++ b/src/libhydra/Makefile.in
@@ -79,18 +79,12 @@ POST_UNINSTALL = :
 build_triplet = @build@
 host_triplet = @host@
 @USE_WINDOWS_TRUE at am__append_1 = -lws2_32
- at USE_ATTR_TRUE@am__append_2 = plugins/attr
- at MONOLITHIC_TRUE@@USE_ATTR_TRUE at am__append_3 = plugins/attr/libstrongswan-attr.la
- at USE_ATTR_SQL_TRUE@am__append_4 = plugins/attr_sql
- at MONOLITHIC_TRUE@@USE_ATTR_SQL_TRUE at am__append_5 = plugins/attr_sql/libstrongswan-attr-sql.la
- at USE_KERNEL_PFKEY_TRUE@am__append_6 = plugins/kernel_pfkey
- at MONOLITHIC_TRUE@@USE_KERNEL_PFKEY_TRUE at am__append_7 = plugins/kernel_pfkey/libstrongswan-kernel-pfkey.la
- at USE_KERNEL_PFROUTE_TRUE@am__append_8 = plugins/kernel_pfroute
- at MONOLITHIC_TRUE@@USE_KERNEL_PFROUTE_TRUE at am__append_9 = plugins/kernel_pfroute/libstrongswan-kernel-pfroute.la
- at USE_KERNEL_NETLINK_TRUE@am__append_10 = plugins/kernel_netlink
- at MONOLITHIC_TRUE@@USE_KERNEL_NETLINK_TRUE at am__append_11 = plugins/kernel_netlink/libstrongswan-kernel-netlink.la
- at USE_RESOLVE_TRUE@am__append_12 = plugins/resolve
- at MONOLITHIC_TRUE@@USE_RESOLVE_TRUE at am__append_13 = plugins/resolve/libstrongswan-resolve.la
+ at USE_KERNEL_PFKEY_TRUE@am__append_2 = plugins/kernel_pfkey
+ at MONOLITHIC_TRUE@@USE_KERNEL_PFKEY_TRUE at am__append_3 = plugins/kernel_pfkey/libstrongswan-kernel-pfkey.la
+ at USE_KERNEL_PFROUTE_TRUE@am__append_4 = plugins/kernel_pfroute
+ at MONOLITHIC_TRUE@@USE_KERNEL_PFROUTE_TRUE at am__append_5 = plugins/kernel_pfroute/libstrongswan-kernel-pfroute.la
+ at USE_KERNEL_NETLINK_TRUE@am__append_6 = plugins/kernel_netlink
+ at MONOLITHIC_TRUE@@USE_KERNEL_NETLINK_TRUE at am__append_7 = plugins/kernel_netlink/libstrongswan-kernel-netlink.la
 subdir = src/libhydra
 DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
 	$(top_srcdir)/depcomp
@@ -144,13 +138,10 @@ am__DEPENDENCIES_1 =
 libhydra_la_DEPENDENCIES =  \
 	$(top_builddir)/src/libstrongswan/libstrongswan.la \
 	$(am__DEPENDENCIES_1) $(am__append_3) $(am__append_5) \
-	$(am__append_7) $(am__append_9) $(am__append_11) \
-	$(am__append_13)
+	$(am__append_7)
 am__dirstamp = $(am__leading_dot)dirstamp
-am_libhydra_la_OBJECTS = hydra.lo attributes/attributes.lo \
-	attributes/attribute_manager.lo attributes/mem_pool.lo \
-	kernel/kernel_interface.lo kernel/kernel_ipsec.lo \
-	kernel/kernel_net.lo
+am_libhydra_la_OBJECTS = hydra.lo kernel/kernel_interface.lo \
+	kernel/kernel_ipsec.lo kernel/kernel_net.lo
 libhydra_la_OBJECTS = $(am_libhydra_la_OBJECTS)
 AM_V_lt = $(am__v_lt_ at AM_V@)
 am__v_lt_ = $(am__v_lt_ at AM_DEFAULT_V@)
@@ -232,8 +223,8 @@ am__define_uniq_tagged_files = \
   done | $(am__uniquify_input)`
 ETAGS = etags
 CTAGS = ctags
-DIST_SUBDIRS = . plugins/attr plugins/attr_sql plugins/kernel_pfkey \
-	plugins/kernel_pfroute plugins/kernel_netlink plugins/resolve
+DIST_SUBDIRS = . plugins/kernel_pfkey plugins/kernel_pfroute \
+	plugins/kernel_netlink tests
 DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
 am__relativize = \
   dir0=`pwd`; \
@@ -285,6 +276,7 @@ DLLIB = @DLLIB@
 DLLTOOL = @DLLTOOL@
 DSYMUTIL = @DSYMUTIL@
 DUMPBIN = @DUMPBIN@
+EASY_INSTALL = @EASY_INSTALL@
 ECHO_C = @ECHO_C@
 ECHO_N = @ECHO_N@
 ECHO_T = @ECHO_T@
@@ -345,10 +337,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
 PLUGIN_CFLAGS = @PLUGIN_CFLAGS@
 PTHREADLIB = @PTHREADLIB@
 PYTHON = @PYTHON@
+PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@
 PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
 PYTHON_PLATFORM = @PYTHON_PLATFORM@
 PYTHON_PREFIX = @PYTHON_PREFIX@
 PYTHON_VERSION = @PYTHON_VERSION@
+PY_TEST = @PY_TEST@
 RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
@@ -422,6 +416,8 @@ json_CFLAGS = @json_CFLAGS@
 json_LIBS = @json_LIBS@
 libdir = @libdir@
 libexecdir = @libexecdir@
+libiptc_CFLAGS = @libiptc_CFLAGS@
+libiptc_LIBS = @libiptc_LIBS@
 linux_headers = @linux_headers@
 localedir = @localedir@
 localstatedir = @localstatedir@
@@ -483,10 +479,6 @@ xml_LIBS = @xml_LIBS@
 ipseclib_LTLIBRARIES = libhydra.la
 libhydra_la_SOURCES = \
 hydra.c hydra.h \
-attributes/attributes.c attributes/attributes.h \
-attributes/attribute_provider.h attributes/attribute_handler.h \
-attributes/attribute_manager.c attributes/attribute_manager.h \
-attributes/mem_pool.c attributes/mem_pool.h \
 kernel/kernel_interface.c kernel/kernel_interface.h \
 kernel/kernel_ipsec.c kernel/kernel_ipsec.h \
 kernel/kernel_net.c kernel/kernel_net.h \
@@ -495,8 +487,7 @@ kernel/kernel_listener.h
 libhydra_la_LIBADD =  \
 	$(top_builddir)/src/libstrongswan/libstrongswan.la \
 	$(am__append_1) $(am__append_3) $(am__append_5) \
-	$(am__append_7) $(am__append_9) $(am__append_11) \
-	$(am__append_13)
+	$(am__append_7)
 AM_CPPFLAGS = \
 	-I$(top_srcdir)/src/libstrongswan \
 	-DIPSEC_DIR=\"${ipsecdir}\" \
@@ -507,14 +498,12 @@ AM_LDFLAGS = \
 
 EXTRA_DIST = Android.mk
 @MONOLITHIC_FALSE at SUBDIRS = . $(am__append_2) $(am__append_4) \
- at MONOLITHIC_FALSE@	$(am__append_6) $(am__append_8) \
- at MONOLITHIC_FALSE@	$(am__append_10) $(am__append_12)
+ at MONOLITHIC_FALSE@	$(am__append_6) tests
 
 # build optional plugins
 ########################
 @MONOLITHIC_TRUE at SUBDIRS = $(am__append_2) $(am__append_4) \
- at MONOLITHIC_TRUE@	$(am__append_6) $(am__append_8) \
- at MONOLITHIC_TRUE@	$(am__append_10) $(am__append_12)
+ at MONOLITHIC_TRUE@	$(am__append_6) . tests
 all: all-recursive
 
 .SUFFIXES:
@@ -584,18 +573,6 @@ clean-ipseclibLTLIBRARIES:
 	  echo rm -f $${locs}; \
 	  rm -f $${locs}; \
 	}
-attributes/$(am__dirstamp):
-	@$(MKDIR_P) attributes
-	@: > attributes/$(am__dirstamp)
-attributes/$(DEPDIR)/$(am__dirstamp):
-	@$(MKDIR_P) attributes/$(DEPDIR)
-	@: > attributes/$(DEPDIR)/$(am__dirstamp)
-attributes/attributes.lo: attributes/$(am__dirstamp) \
-	attributes/$(DEPDIR)/$(am__dirstamp)
-attributes/attribute_manager.lo: attributes/$(am__dirstamp) \
-	attributes/$(DEPDIR)/$(am__dirstamp)
-attributes/mem_pool.lo: attributes/$(am__dirstamp) \
-	attributes/$(DEPDIR)/$(am__dirstamp)
 kernel/$(am__dirstamp):
 	@$(MKDIR_P) kernel
 	@: > kernel/$(am__dirstamp)
@@ -614,8 +591,6 @@ libhydra.la: $(libhydra_la_OBJECTS) $(libhydra_la_DEPENDENCIES) $(EXTRA_libhydra
 
 mostlyclean-compile:
 	-rm -f *.$(OBJEXT)
-	-rm -f attributes/*.$(OBJEXT)
-	-rm -f attributes/*.lo
 	-rm -f kernel/*.$(OBJEXT)
 	-rm -f kernel/*.lo
 
@@ -623,9 +598,6 @@ distclean-compile:
 	-rm -f *.tab.c
 
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/hydra.Plo at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at attributes/$(DEPDIR)/attribute_manager.Plo at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at attributes/$(DEPDIR)/attributes.Plo at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at attributes/$(DEPDIR)/mem_pool.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at kernel/$(DEPDIR)/kernel_interface.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at kernel/$(DEPDIR)/kernel_ipsec.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at kernel/$(DEPDIR)/kernel_net.Plo at am__quote@
@@ -659,7 +631,6 @@ mostlyclean-libtool:
 
 clean-libtool:
 	-rm -rf .libs _libs
-	-rm -rf attributes/.libs attributes/_libs
 	-rm -rf kernel/.libs kernel/_libs
 
 # This directory's subdirectories are mostly independent; you can cd
@@ -850,8 +821,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 attributes/$(DEPDIR)/$(am__dirstamp)
-	-rm -f attributes/$(am__dirstamp)
 	-rm -f kernel/$(DEPDIR)/$(am__dirstamp)
 	-rm -f kernel/$(am__dirstamp)
 
@@ -864,7 +833,7 @@ clean-am: clean-generic clean-ipseclibLTLIBRARIES clean-libtool \
 	mostlyclean-am
 
 distclean: distclean-recursive
-	-rm -rf ./$(DEPDIR) attributes/$(DEPDIR) kernel/$(DEPDIR)
+	-rm -rf ./$(DEPDIR) kernel/$(DEPDIR)
 	-rm -f Makefile
 distclean-am: clean-am distclean-compile distclean-generic \
 	distclean-tags
@@ -910,7 +879,7 @@ install-ps-am:
 installcheck-am:
 
 maintainer-clean: maintainer-clean-recursive
-	-rm -rf ./$(DEPDIR) attributes/$(DEPDIR) kernel/$(DEPDIR)
+	-rm -rf ./$(DEPDIR) kernel/$(DEPDIR)
 	-rm -f Makefile
 maintainer-clean-am: distclean-am maintainer-clean-generic
 
diff --git a/src/libhydra/attributes/attribute_handler.h b/src/libhydra/attributes/attribute_handler.h
deleted file mode 100644
index bc488f6..0000000
--- a/src/libhydra/attributes/attribute_handler.h
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * Copyright (C) 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.
- */
-
-/**
- * @defgroup attribute_handler attribute_handler
- * @{ @ingroup attributes
- */
-
-#ifndef ATTRIBUTE_HANDLER_H_
-#define ATTRIBUTE_HANDLER_H_
-
-#include <utils/chunk.h>
-#include <utils/identification.h>
-#include <collections/linked_list.h>
-
-#include "attributes.h"
-
-typedef struct attribute_handler_t attribute_handler_t;
-
-/**
- * Interface to handle configuration payload attributes.
- */
-struct attribute_handler_t {
-
-	/**
-	 * Handle a configuration attribute.
-	 *
-	 * After receiving a configuration attriubte, it is passed to each
-	 * attribute handler until it is handled.
-	 *
-	 * @param server	server from which the attribute was received
-	 * @param type		type of configuration attribute to handle
-	 * @param data		associated attribute data
-	 * @return			TRUE if attribute handled
-	 */
-	bool (*handle)(attribute_handler_t *this, identification_t *server,
-				   configuration_attribute_type_t type, chunk_t data);
-
-	/**
-	 * Release an attribute handled during handle().
-	 *
-	 * A handler that handle()d an attribute gets a call to release() when the
-	 * connection gets closed. Depending on the implementation, this is required
-	 * to remove the attribute.
-	 */
-	void (*release)(attribute_handler_t *this, identification_t *server,
-					configuration_attribute_type_t type, chunk_t data);
-
-	/**
-	 * Enumerate attributes to request from a server.
-	 *
-	 * @param server		server identity to request attributes from
-	 * @param vips			list of virtual IPs (host_t*) we are requesting
-	 * @return				enumerator (configuration_attribute_type_t, chunk_t)
-	 */
-	enumerator_t* (*create_attribute_enumerator)(attribute_handler_t *this,
-								identification_t *server, linked_list_t *vips);
-};
-
-#endif /** ATTRIBUTE_HANDLER_H_ @}*/
diff --git a/src/libhydra/attributes/attribute_manager.c b/src/libhydra/attributes/attribute_manager.c
deleted file mode 100644
index 5fda8b4..0000000
--- a/src/libhydra/attributes/attribute_manager.c
+++ /dev/null
@@ -1,348 +0,0 @@
-/*
- * Copyright (C) 2008 Martin Willi
- * Hochschule fuer Technik Rapperswil
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * for more details.
- */
-
-#include "attribute_manager.h"
-
-#include <utils/debug.h>
-#include <collections/linked_list.h>
-#include <threading/rwlock.h>
-
-typedef struct private_attribute_manager_t private_attribute_manager_t;
-
-/**
- * private data of attribute_manager
- */
-struct private_attribute_manager_t {
-
-	/**
-	 * public functions
-	 */
-	attribute_manager_t public;
-
-	/**
-	 * list of registered providers
-	 */
-	linked_list_t *providers;
-
-	/**
-	 * list of registered handlers
-	 */
-	linked_list_t *handlers;
-
-	/**
-	 * rwlock provider list
-	 */
-	rwlock_t *lock;
-};
-
-/**
- * Data to pass to enumerator filters
- */
-typedef struct {
-	/** attribute group pools */
-	linked_list_t *pools;
-	/** server/peer identity */
-	identification_t *id;
-	/** requesting/assigned virtual IPs */
-	linked_list_t *vips;
-} enum_data_t;
-
-METHOD(attribute_manager_t, acquire_address, host_t*,
-	private_attribute_manager_t *this, linked_list_t *pools,
-	identification_t *id, host_t *requested)
-{
-	enumerator_t *enumerator;
-	attribute_provider_t *current;
-	host_t *host = NULL;
-
-	this->lock->read_lock(this->lock);
-	enumerator = this->providers->create_enumerator(this->providers);
-	while (enumerator->enumerate(enumerator, &current))
-	{
-		host = current->acquire_address(current, pools, id, requested);
-		if (host)
-		{
-			break;
-		}
-	}
-	enumerator->destroy(enumerator);
-	this->lock->unlock(this->lock);
-
-	return host;
-}
-
-METHOD(attribute_manager_t, release_address, bool,
-	private_attribute_manager_t *this, linked_list_t *pools, host_t *address,
-	identification_t *id)
-{
-	enumerator_t *enumerator;
-	attribute_provider_t *current;
-	bool found = FALSE;
-
-	this->lock->read_lock(this->lock);
-	enumerator = this->providers->create_enumerator(this->providers);
-	while (enumerator->enumerate(enumerator, &current))
-	{
-		if (current->release_address(current, pools, address, id))
-		{
-			found = TRUE;
-			break;
-		}
-	}
-	enumerator->destroy(enumerator);
-	this->lock->unlock(this->lock);
-
-	return found;
-}
-
-/**
- * inner enumerator constructor for responder attributes
- */
-static enumerator_t *responder_enum_create(attribute_provider_t *provider,
-										   enum_data_t *data)
-{
-	return provider->create_attribute_enumerator(provider, data->pools,
-												 data->id, data->vips);
-}
-
-METHOD(attribute_manager_t, create_responder_enumerator, enumerator_t*,
-	private_attribute_manager_t *this, linked_list_t *pools,
-	identification_t *id, linked_list_t *vips)
-{
-	enum_data_t *data;
-
-	INIT(data,
-		.pools = pools,
-		.id = id,
-		.vips = vips,
-	);
-	this->lock->read_lock(this->lock);
-	return enumerator_create_cleaner(
-				enumerator_create_nested(
-					this->providers->create_enumerator(this->providers),
-					(void*)responder_enum_create, data, free),
-				(void*)this->lock->unlock, this->lock);
-}
-
-METHOD(attribute_manager_t, add_provider, void,
-	private_attribute_manager_t *this, attribute_provider_t *provider)
-{
-	this->lock->write_lock(this->lock);
-	this->providers->insert_last(this->providers, provider);
-	this->lock->unlock(this->lock);
-}
-
-METHOD(attribute_manager_t, remove_provider, void,
-	private_attribute_manager_t *this, attribute_provider_t *provider)
-{
-	this->lock->write_lock(this->lock);
-	this->providers->remove(this->providers, provider, NULL);
-	this->lock->unlock(this->lock);
-}
-
-METHOD(attribute_manager_t, handle, attribute_handler_t*,
-	private_attribute_manager_t *this, identification_t *server,
-	attribute_handler_t *handler, configuration_attribute_type_t type,
-	chunk_t data)
-{
-	enumerator_t *enumerator;
-	attribute_handler_t *current, *handled = NULL;
-
-	this->lock->read_lock(this->lock);
-
-	/* try to find the passed handler */
-	enumerator = this->handlers->create_enumerator(this->handlers);
-	while (enumerator->enumerate(enumerator, &current))
-	{
-		if (current == handler && current->handle(current, server, type, data))
-		{
-			handled = current;
-			break;
-		}
-	}
-	enumerator->destroy(enumerator);
-	if (!handled)
-	{	/* handler requesting this attribute not found, try any other */
-		enumerator = this->handlers->create_enumerator(this->handlers);
-		while (enumerator->enumerate(enumerator, &current))
-		{
-			if (current->handle(current, server, type, data))
-			{
-				handled = current;
-				break;
-			}
-		}
-		enumerator->destroy(enumerator);
-	}
-	this->lock->unlock(this->lock);
-
-	if (!handled)
-	{
-		DBG1(DBG_CFG, "handling %N attribute failed",
-			 configuration_attribute_type_names, type);
-	}
-	return handled;
-}
-
-METHOD(attribute_manager_t, release, void,
-	private_attribute_manager_t *this, attribute_handler_t *handler,
-	identification_t *server, configuration_attribute_type_t type, chunk_t data)
-{
-	enumerator_t *enumerator;
-	attribute_handler_t *current;
-
-	this->lock->read_lock(this->lock);
-	enumerator = this->handlers->create_enumerator(this->handlers);
-	while (enumerator->enumerate(enumerator, &current))
-	{
-		if (current == handler)
-		{
-			current->release(current, server, type, data);
-			break;
-		}
-	}
-	enumerator->destroy(enumerator);
-	this->lock->unlock(this->lock);
-}
-
-/**
- * Enumerator implementation to enumerate nested initiator attributes
- */
-typedef struct {
-	/** implements enumerator_t */
-	enumerator_t public;
-	/** back ref */
-	private_attribute_manager_t *this;
-	/** currently processing handler */
-	attribute_handler_t *handler;
-	/** outer enumerator over handlers */
-	enumerator_t *outer;
-	/** inner enumerator over current handlers attributes */
-	enumerator_t *inner;
-	/** server ID we want attributes for */
-	identification_t *id;
-	/** virtual IPs we are requesting along with attriubutes */
-	linked_list_t *vips;
-} initiator_enumerator_t;
-
-/**
- * Enumerator implementation for initiator attributes
- */
-static bool initiator_enumerate(initiator_enumerator_t *this,
-								attribute_handler_t **handler,
-								configuration_attribute_type_t *type,
-								chunk_t *value)
-{
-	/* enumerate inner attributes using outer handler enumerator */
-	while (!this->inner || !this->inner->enumerate(this->inner, type, value))
-	{
-		if (!this->outer->enumerate(this->outer, &this->handler))
-		{
-			return FALSE;
-		}
-		DESTROY_IF(this->inner);
-		this->inner = this->handler->create_attribute_enumerator(this->handler,
-														this->id, this->vips);
-	}
-	/* inject the handler as additional attribute */
-	*handler = this->handler;
-	return TRUE;
-}
-
-/**
- * Cleanup function of initiator attribute enumerator
- */
-static void initiator_destroy(initiator_enumerator_t *this)
-{
-	this->this->lock->unlock(this->this->lock);
-	this->outer->destroy(this->outer);
-	DESTROY_IF(this->inner);
-	free(this);
-}
-
-METHOD(attribute_manager_t, create_initiator_enumerator, enumerator_t*,
-	private_attribute_manager_t *this, identification_t *id, linked_list_t *vips)
-{
-	initiator_enumerator_t *enumerator;
-
-	this->lock->read_lock(this->lock);
-
-	INIT(enumerator,
-		.public = {
-			.enumerate = (void*)initiator_enumerate,
-			.destroy = (void*)initiator_destroy,
-		},
-		.this = this,
-		.id = id,
-		.vips = vips,
-		.outer = this->handlers->create_enumerator(this->handlers),
-	);
-	return &enumerator->public;
-}
-
-METHOD(attribute_manager_t, add_handler, void,
-	private_attribute_manager_t *this, attribute_handler_t *handler)
-{
-	this->lock->write_lock(this->lock);
-	this->handlers->insert_last(this->handlers, handler);
-	this->lock->unlock(this->lock);
-}
-
-METHOD(attribute_manager_t, remove_handler, void,
-	private_attribute_manager_t *this, attribute_handler_t *handler)
-{
-	this->lock->write_lock(this->lock);
-	this->handlers->remove(this->handlers, handler, NULL);
-	this->lock->unlock(this->lock);
-}
-
-METHOD(attribute_manager_t, destroy, void,
-	private_attribute_manager_t *this)
-{
-	this->providers->destroy(this->providers);
-	this->handlers->destroy(this->handlers);
-	this->lock->destroy(this->lock);
-	free(this);
-}
-
-/*
- * see header file
- */
-attribute_manager_t *attribute_manager_create()
-{
-	private_attribute_manager_t *this;
-
-	INIT(this,
-		.public = {
-			.acquire_address = _acquire_address,
-			.release_address = _release_address,
-			.create_responder_enumerator = _create_responder_enumerator,
-			.add_provider = _add_provider,
-			.remove_provider = _remove_provider,
-			.handle = _handle,
-			.release = _release,
-			.create_initiator_enumerator = _create_initiator_enumerator,
-			.add_handler = _add_handler,
-			.remove_handler = _remove_handler,
-			.destroy = _destroy,
-		},
-		.providers = linked_list_create(),
-		.handlers = linked_list_create(),
-		.lock = rwlock_create(RWLOCK_TYPE_DEFAULT),
-	);
-
-	return &this->public;
-}
-
diff --git a/src/libhydra/attributes/attribute_manager.h b/src/libhydra/attributes/attribute_manager.h
deleted file mode 100644
index 99f4177..0000000
--- a/src/libhydra/attributes/attribute_manager.h
+++ /dev/null
@@ -1,153 +0,0 @@
-/*
- * 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.
- */
-
-/**
- * @defgroup attribute_manager attribute_manager
- * @{ @ingroup attributes
- */
-
-#ifndef ATTRIBUTE_MANAGER_H_
-#define ATTRIBUTE_MANAGER_H_
-
-#include "attribute_provider.h"
-#include "attribute_handler.h"
-
-typedef struct attribute_manager_t attribute_manager_t;
-
-/**
- * The attribute manager hands out attributes or handles them.
- *
- * The attribute manager manages both, attribute providers and attribute
- * handlers. Attribute providers are responsible to hand out attributes if
- * a connecting peer requests them. Handlers handle such attributes if they
- * are received on the requesting peer.
- */
-struct attribute_manager_t {
-
-	/**
-	 * Acquire a virtual IP address to assign to a peer.
-	 *
-	 * @param pools			list of pool names (char*) to acquire from
-	 * @param id			peer identity to get address forua
-	 * @param requested		IP in configuration request
-	 * @return				allocated address, NULL to serve none
-	 */
-	host_t* (*acquire_address)(attribute_manager_t *this,
-							   linked_list_t *pool, identification_t *id,
-							   host_t *requested);
-
-	/**
-	 * Release a previously acquired address.
-	 *
-	 * @param pools			list of pool names (char*) to release to
-	 * @param address		address to release
-	 * @param id			peer identity to get address for
-	 * @return				TRUE if address released to pool
-	 */
-	bool (*release_address)(attribute_manager_t *this,
-							linked_list_t *pools, host_t *address,
-							identification_t *id);
-
-	/**
-	 * Create an enumerator over attributes to hand out to a peer.
-	 *
-	 * @param pool			list of pools names (char*) to query attributes from
-	 * @param id			peer identity to hand out attributes to
-	 * @param vip			list of virtual IPs (host_t*) to assign to peer
-	 * @return				enumerator (configuration_attribute_type_t, chunk_t)
-	 */
-	enumerator_t* (*create_responder_enumerator)(attribute_manager_t *this,
-									linked_list_t *pool, identification_t *id,
-									linked_list_t *vips);
-
-	/**
-	 * Register an attribute provider to the manager.
-	 *
-	 * @param provider		attribute provider to register
-	 */
-	void (*add_provider)(attribute_manager_t *this,
-						 attribute_provider_t *provider);
-	/**
-	 * Unregister an attribute provider from the manager.
-	 *
-	 * @param provider		attribute provider to unregister
-	 */
-	void (*remove_provider)(attribute_manager_t *this,
-							attribute_provider_t *provider);
-
-	/**
-	 * Handle a configuration attribute by passing them to the handlers.
-	 *
-	 * @param server		server from which the attribute was received
-	 * @param handler		handler we requested the attribute for, if any
-	 * @param type			type of configuration attribute
-	 * @param data			associated attribute data
-	 * @return				handler which handled this attribute, NULL if none
-	 */
-	attribute_handler_t* (*handle)(attribute_manager_t *this,
-						identification_t *server, attribute_handler_t *handler,
-						configuration_attribute_type_t type, chunk_t data);
-
-	/**
-	 * Release an attribute previously handle()d by a handler.
-	 *
-	 * @param handler		handler returned by handle() for this attribute
-	 * @param server		server from which the attribute was received
-	 * @param type			type of attribute to release
-	 * @param data			associated attribute data
-	 */
-	void (*release)(attribute_manager_t *this, attribute_handler_t *handler,
-						identification_t *server,
-						configuration_attribute_type_t type,
-						chunk_t data);
-
-	/**
-	 * Create an enumerator over attributes to request from server.
-	 *
-	 * @param id			server identity to hand out attributes to
-	 * @param vip			list of virtual IPs (host_t*) going to request
-	 * @return				enumerator (attribute_handler_t, ca_type_t, chunk_t)
-	 */
-	enumerator_t* (*create_initiator_enumerator)(attribute_manager_t *this,
-									identification_t *id, linked_list_t *vips);
-
-	/**
-	 * Register an attribute handler to the manager.
-	 *
-	 * @param handler		attribute handler to register
-	 */
-	void (*add_handler)(attribute_manager_t *this,
-						attribute_handler_t *handler);
-
-	/**
-	 * Unregister an attribute handler from the manager.
-	 *
-	 * @param handler		attribute handler to unregister
-	 */
-	void (*remove_handler)(attribute_manager_t *this,
-						   attribute_handler_t *handler);
-
-	/**
-	 * Destroy a attribute_manager instance.
-	 */
-	void (*destroy)(attribute_manager_t *this);
-};
-
-/**
- * Create a attribute_manager instance.
- */
-attribute_manager_t *attribute_manager_create();
-
-#endif /** ATTRIBUTE_MANAGER_H_ @}*/
diff --git a/src/libhydra/attributes/attribute_provider.h b/src/libhydra/attributes/attribute_provider.h
deleted file mode 100644
index adfd4a5..0000000
--- a/src/libhydra/attributes/attribute_provider.h
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- * Copyright (C) 2008 Martin Willi
- * Hochschule fuer Technik Rapperswil
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * for more details.
- */
-
-/**
- * @defgroup attribute_provider attribute_provider
- * @{ @ingroup attributes
- */
-
-#ifndef ATTRIBUTE_PROVIDER_H_
-#define ATTRIBUTE_PROVIDER_H_
-
-#include <networking/host.h>
-#include <utils/identification.h>
-#include <collections/linked_list.h>
-
-typedef struct attribute_provider_t attribute_provider_t;
-
-/**
- * Interface to provide attributes to peers through attribute manager.
- */
-struct attribute_provider_t {
-
-	/**
-	 * Acquire a virtual IP address to assign to a peer.
-	 *
-	 * @param pools			list of pool names (char*) to acquire from
-	 * @param id			peer ID
-	 * @param requested		IP in configuration request
-	 * @return				allocated address, NULL to serve none
-	 */
-	host_t* (*acquire_address)(attribute_provider_t *this,
-							   linked_list_t *pools, identification_t *id,
-							   host_t *requested);
-	/**
-	 * Release a previously acquired address.
-	 *
-	 * @param pools			list of pool names (char*) to release to
-	 * @param address		address to release
-	 * @param id			peer ID
-	 * @return				TRUE if the address has been released by the provider
-	 */
-	bool (*release_address)(attribute_provider_t *this,
-							linked_list_t *pools, host_t *address,
-							identification_t *id);
-
-	/**
-	 * Create an enumerator over attributes to hand out to a peer.
-	 *
-	 * @param pool			list of pools names (char*) to query attributes from
-	 * @param id			peer ID
-	 * @param vip			list of virtual IPs (host_t*) to assign to peer
-	 * @return				enumerator (configuration_attribute_type_t, chunk_t)
-	 */
-	enumerator_t* (*create_attribute_enumerator)(attribute_provider_t *this,
-									linked_list_t *pools, identification_t *id,
-									linked_list_t *vips);
-};
-
-#endif /** ATTRIBUTE_PROVIDER_H_ @}*/
diff --git a/src/libhydra/attributes/mem_pool.c b/src/libhydra/attributes/mem_pool.c
deleted file mode 100644
index cc45e56..0000000
--- a/src/libhydra/attributes/mem_pool.c
+++ /dev/null
@@ -1,649 +0,0 @@
-/*
- * Copyright (C) 2010 Tobias Brunner
- * Copyright (C) 2008-2010 Martin Willi
- * Hochschule fuer Technik Rapperswil
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * for more details.
- */
-
-#include "mem_pool.h"
-
-#include <library.h>
-#include <hydra.h>
-#include <utils/debug.h>
-#include <collections/hashtable.h>
-#include <collections/array.h>
-#include <threading/mutex.h>
-
-#define POOL_LIMIT (sizeof(u_int)*8 - 1)
-
-typedef struct private_mem_pool_t private_mem_pool_t;
-
-/**
- * private data of mem_pool_t
- */
-struct private_mem_pool_t {
-	/**
-	 * public interface
-	 */
-	mem_pool_t public;
-
-	/**
-	 * name of the pool
-	 */
-	char *name;
-
-	/**
-	 * base address of the pool
-	 */
-	host_t *base;
-
-	/**
-	 * size of the pool
-	 */
-	u_int size;
-
-	/**
-	 * next unused address
-	 */
-	u_int unused;
-
-	/**
-	 * lease hashtable [identity => entry]
-	 */
-	hashtable_t *leases;
-
-	/**
-	 * lock to safely access the pool
-	 */
-	mutex_t *mutex;
-
-	/**
-	 * Do we reassign online leases to the same identity, if requested?
-	 */
-	bool reassign_online;
-};
-
-/**
- * Lease entry.
- */
-typedef struct {
-	/* identitiy reference */
-	identification_t *id;
-	/* array of online leases, as u_int offset */
-	array_t *online;
-	/* array of offline leases, as u_int offset */
-	array_t *offline;
-} entry_t;
-
-/**
- * Create a new entry
- */
-static entry_t* entry_create(identification_t *id)
-{
-	entry_t *entry;
-
-	INIT(entry,
-		.id = id->clone(id),
-		.online = array_create(sizeof(u_int), 0),
-		.offline = array_create(sizeof(u_int), 0),
-	);
-	return entry;
-}
-
-/**
- * hashtable hash function for identities
- */
-static u_int id_hash(identification_t *id)
-{
-	return chunk_hash(id->get_encoding(id));
-}
-
-/**
- * hashtable equals function for identities
- */
-static bool id_equals(identification_t *a, identification_t *b)
-{
-	return a->equals(a, b);
-}
-
-/**
- * convert a pool offset to an address
- */
-static host_t* offset2host(private_mem_pool_t *pool, int offset)
-{
-	chunk_t addr;
-	host_t *host;
-	u_int32_t *pos;
-
-	offset--;
-	if (offset > pool->size)
-	{
-		return NULL;
-	}
-
-	addr = chunk_clone(pool->base->get_address(pool->base));
-	if (pool->base->get_family(pool->base) == AF_INET6)
-	{
-		pos = (u_int32_t*)(addr.ptr + 12);
-	}
-	else
-	{
-		pos = (u_int32_t*)addr.ptr;
-	}
-	*pos = htonl(offset + ntohl(*pos));
-	host = host_create_from_chunk(pool->base->get_family(pool->base), addr, 0);
-	free(addr.ptr);
-	return host;
-}
-
-/**
- * convert a host to a pool offset
- */
-static int host2offset(private_mem_pool_t *pool, host_t *addr)
-{
-	chunk_t host, base;
-	u_int32_t hosti, basei;
-
-	if (addr->get_family(addr) != pool->base->get_family(pool->base))
-	{
-		return -1;
-	}
-	host = addr->get_address(addr);
-	base = pool->base->get_address(pool->base);
-	if (addr->get_family(addr) == AF_INET6)
-	{
-		/* only look at last /32 block */
-		if (!memeq(host.ptr, base.ptr, 12))
-		{
-			return -1;
-		}
-		host = chunk_skip(host, 12);
-		base = chunk_skip(base, 12);
-	}
-	hosti = ntohl(*(u_int32_t*)(host.ptr));
-	basei = ntohl(*(u_int32_t*)(base.ptr));
-	if (hosti > basei + pool->size)
-	{
-		return -1;
-	}
-	return hosti - basei + 1;
-}
-
-METHOD(mem_pool_t, get_name, const char*,
-	private_mem_pool_t *this)
-{
-	return this->name;
-}
-
-METHOD(mem_pool_t, get_base, host_t*,
-	private_mem_pool_t *this)
-{
-	return this->base;
-}
-
-METHOD(mem_pool_t, get_size, u_int,
-	private_mem_pool_t *this)
-{
-	return this->size;
-}
-
-METHOD(mem_pool_t, get_online, u_int,
-	private_mem_pool_t *this)
-{
-	enumerator_t *enumerator;
-	entry_t *entry;
-	u_int count = 0;
-
-	this->mutex->lock(this->mutex);
-	enumerator = this->leases->create_enumerator(this->leases);
-	while (enumerator->enumerate(enumerator, NULL, &entry))
-	{
-		count += array_count(entry->online);
-	}
-	enumerator->destroy(enumerator);
-	this->mutex->unlock(this->mutex);
-
-	return count;
-}
-
-METHOD(mem_pool_t, get_offline, u_int,
-	private_mem_pool_t *this)
-{
-	enumerator_t *enumerator;
-	entry_t *entry;
-	u_int count = 0;
-
-	this->mutex->lock(this->mutex);
-	enumerator = this->leases->create_enumerator(this->leases);
-	while (enumerator->enumerate(enumerator, NULL, &entry))
-	{
-		count += array_count(entry->offline);
-	}
-	enumerator->destroy(enumerator);
-	this->mutex->unlock(this->mutex);
-
-	return count;
-}
-
-/**
- * Get an existing lease for id
- */
-static int get_existing(private_mem_pool_t *this, identification_t *id,
-						host_t *requested)
-{
-	enumerator_t *enumerator;
-	u_int *current;
-	entry_t *entry;
-	int offset = 0;
-
-	entry = this->leases->get(this->leases, id);
-	if (!entry)
-	{
-		return 0;
-	}
-
-	/* check for a valid offline lease, refresh */
-	enumerator = array_create_enumerator(entry->offline);
-	if (enumerator->enumerate(enumerator, &current))
-	{
-		offset = *current;
-		array_insert(entry->online, ARRAY_TAIL, current);
-		array_remove_at(entry->offline, enumerator);
-	}
-	enumerator->destroy(enumerator);
-	if (offset)
-	{
-		DBG1(DBG_CFG, "reassigning offline lease to '%Y'", id);
-		return offset;
-	}
-	if (!this->reassign_online)
-	{
-		return 0;
-	}
-	/* check for a valid online lease to reassign */
-	enumerator = array_create_enumerator(entry->online);
-	while (enumerator->enumerate(enumerator, &current))
-	{
-		if (*current == host2offset(this, requested))
-		{
-			offset = *current;
-			/* add an additional "online" entry */
-			array_insert(entry->online, ARRAY_TAIL, current);
-			break;
-		}
-	}
-	enumerator->destroy(enumerator);
-	if (offset)
-	{
-		DBG1(DBG_CFG, "reassigning online lease to '%Y'", id);
-	}
-	return offset;
-}
-
-/**
- * Get a new lease for id
- */
-static int get_new(private_mem_pool_t *this, identification_t *id)
-{
-	entry_t *entry;
-	u_int offset = 0;
-
-	if (this->unused < this->size)
-	{
-		entry = this->leases->get(this->leases, id);
-		if (!entry)
-		{
-			entry = entry_create(id);
-			this->leases->put(this->leases, entry->id, entry);
-		}
-		/* assigning offset, starting by 1 */
-		offset = ++this->unused;
-		array_insert(entry->online, ARRAY_TAIL, &offset);
-		DBG1(DBG_CFG, "assigning new lease to '%Y'", id);
-	}
-	return offset;
-}
-
-/**
- * Get a reassigned lease for id in case the pool is full
- */
-static int get_reassigned(private_mem_pool_t *this, identification_t *id)
-{
-	enumerator_t *enumerator;
-	entry_t *entry;
-	u_int current, offset = 0;
-
-	enumerator = this->leases->create_enumerator(this->leases);
-	while (enumerator->enumerate(enumerator, NULL, &entry))
-	{
-		if (array_remove(entry->offline, ARRAY_HEAD, &current))
-		{
-			offset = current;
-			DBG1(DBG_CFG, "reassigning existing offline lease by '%Y'"
-				 " to '%Y'", entry->id, id);
-			break;
-		}
-	}
-	enumerator->destroy(enumerator);
-
-	if (offset)
-	{
-		entry = entry_create(id);
-		array_insert(entry->online, ARRAY_TAIL, &offset);
-		this->leases->put(this->leases, entry->id, entry);
-	}
-	return offset;
-}
-
-METHOD(mem_pool_t, acquire_address, host_t*,
-	private_mem_pool_t *this, identification_t *id, host_t *requested,
-	mem_pool_op_t operation)
-{
-	int offset = 0;
-
-	/* if the pool is empty (e.g. in the %config case) we simply return the
-	 * requested address */
-	if (this->size == 0)
-	{
-		return requested->clone(requested);
-	}
-
-	if (requested->get_family(requested) !=
-		this->base->get_family(this->base))
-	{
-		return NULL;
-	}
-
-	this->mutex->lock(this->mutex);
-	switch (operation)
-	{
-		case MEM_POOL_EXISTING:
-			offset = get_existing(this, id, requested);
-			break;
-		case MEM_POOL_NEW:
-			offset = get_new(this, id);
-			break;
-		case MEM_POOL_REASSIGN:
-			offset = get_reassigned(this, id);
-			if (!offset)
-			{
-				DBG1(DBG_CFG, "pool '%s' is full, unable to assign address",
-					 this->name);
-			}
-			break;
-		default:
-			break;
-	}
-	this->mutex->unlock(this->mutex);
-
-	if (offset)
-	{
-		return offset2host(this, offset);
-	}
-	return NULL;
-}
-
-METHOD(mem_pool_t, release_address, bool,
-	private_mem_pool_t *this, host_t *address, identification_t *id)
-{
-	enumerator_t *enumerator;
-	bool found = FALSE, more = FALSE;
-	entry_t *entry;
-	u_int offset, *current;
-
-	if (this->size != 0)
-	{
-		this->mutex->lock(this->mutex);
-		entry = this->leases->get(this->leases, id);
-		if (entry)
-		{
-			offset = host2offset(this, address);
-
-			enumerator = array_create_enumerator(entry->online);
-			while (enumerator->enumerate(enumerator, &current))
-			{
-				if (*current == offset)
-				{
-					if (!found)
-					{	/* remove the first entry only */
-						array_remove_at(entry->online, enumerator);
-						found = TRUE;
-					}
-					else
-					{	/* but check for more entries */
-						more = TRUE;
-						break;
-					}
-				}
-			}
-			enumerator->destroy(enumerator);
-
-			if (found && !more)
-			{
-				/* no tunnels are online anymore for this lease, make offline */
-				array_insert(entry->offline, ARRAY_TAIL, &offset);
-				DBG1(DBG_CFG, "lease %H by '%Y' went offline", address, id);
-			}
-		}
-		this->mutex->unlock(this->mutex);
-	}
-	return found;
-}
-
-/**
- * lease enumerator
- */
-typedef struct {
-	/** implemented enumerator interface */
-	enumerator_t public;
-	/** hash-table enumerator */
-	enumerator_t *entries;
-	/** online enumerator */
-	enumerator_t *online;
-	/** offline enumerator */
-	enumerator_t *offline;
-	/** enumerated pool */
-	private_mem_pool_t *pool;
-	/** currently enumerated entry */
-	entry_t *entry;
-	/** currently enumerated lease address */
-	host_t *addr;
-} lease_enumerator_t;
-
-METHOD(enumerator_t, lease_enumerate, bool,
-	lease_enumerator_t *this, identification_t **id, host_t **addr, bool *online)
-{
-	u_int *offset;
-
-	DESTROY_IF(this->addr);
-	this->addr = NULL;
-
-	while (TRUE)
-	{
-		if (this->entry)
-		{
-			if (this->online->enumerate(this->online, &offset))
-			{
-				*id = this->entry->id;
-				*addr = this->addr = offset2host(this->pool, *offset);
-				*online = TRUE;
-				return TRUE;
-			}
-			if (this->offline->enumerate(this->offline, &offset))
-			{
-				*id = this->entry->id;
-				*addr = this->addr = offset2host(this->pool, *offset);
-				*online = FALSE;
-				return TRUE;
-			}
-			this->online->destroy(this->online);
-			this->offline->destroy(this->offline);
-			this->online = this->offline = NULL;
-		}
-		if (!this->entries->enumerate(this->entries, NULL, &this->entry))
-		{
-			return FALSE;
-		}
-		this->online = array_create_enumerator(this->entry->online);
-		this->offline = array_create_enumerator(this->entry->offline);
-	}
-}
-
-METHOD(enumerator_t, lease_enumerator_destroy, void,
-	lease_enumerator_t *this)
-{
-	DESTROY_IF(this->addr);
-	DESTROY_IF(this->online);
-	DESTROY_IF(this->offline);
-	this->entries->destroy(this->entries);
-	this->pool->mutex->unlock(this->pool->mutex);
-	free(this);
-}
-
-METHOD(mem_pool_t, create_lease_enumerator, enumerator_t*,
-	   private_mem_pool_t *this)
-{
-	lease_enumerator_t *enumerator;
-
-	this->mutex->lock(this->mutex);
-	INIT(enumerator,
-		.public = {
-			.enumerate = (void*)_lease_enumerate,
-			.destroy = _lease_enumerator_destroy,
-		},
-		.pool = this,
-		.entries = this->leases->create_enumerator(this->leases),
-	);
-	return &enumerator->public;
-}
-
-METHOD(mem_pool_t, destroy, void,
-	private_mem_pool_t *this)
-{
-	enumerator_t *enumerator;
-	entry_t *entry;
-
-	enumerator = this->leases->create_enumerator(this->leases);
-	while (enumerator->enumerate(enumerator, NULL, &entry))
-	{
-		entry->id->destroy(entry->id);
-		array_destroy(entry->online);
-		array_destroy(entry->offline);
-		free(entry);
-	}
-	enumerator->destroy(enumerator);
-
-	this->leases->destroy(this->leases);
-	this->mutex->destroy(this->mutex);
-	DESTROY_IF(this->base);
-	free(this->name);
-	free(this);
-}
-
-/**
- * Generic constructor
- */
-static private_mem_pool_t *create_generic(char *name)
-{
-	private_mem_pool_t *this;
-
-	INIT(this,
-		.public = {
-			.get_name = _get_name,
-			.get_base = _get_base,
-			.get_size = _get_size,
-			.get_online = _get_online,
-			.get_offline = _get_offline,
-			.acquire_address = _acquire_address,
-			.release_address = _release_address,
-			.create_lease_enumerator = _create_lease_enumerator,
-			.destroy = _destroy,
-		},
-		.name = strdup(name),
-		.leases = hashtable_create((hashtable_hash_t)id_hash,
-								   (hashtable_equals_t)id_equals, 16),
-		.mutex = mutex_create(MUTEX_TYPE_DEFAULT),
-		.reassign_online = lib->settings->get_bool(lib->settings,
-								"%s.mem-pool.reassign_online", FALSE, lib->ns),
-	);
-
-	return this;
-}
-
-/**
- * Described in header
- */
-mem_pool_t *mem_pool_create(char *name, host_t *base, int bits)
-{
-	private_mem_pool_t *this;
-	int addr_bits;
-
-	this = create_generic(name);
-	if (base)
-	{
-		addr_bits = base->get_family(base) == AF_INET ? 32 : 128;
-		bits = max(0, min(bits, base->get_family(base) == AF_INET ? 32 : 128));
-		/* net bits -> host bits */
-		bits = addr_bits - bits;
-		if (bits > POOL_LIMIT)
-		{
-			bits = POOL_LIMIT;
-			DBG1(DBG_CFG, "virtual IP pool too large, limiting to %H/%d",
-				 base, addr_bits - bits);
-		}
-		this->size = 1 << bits;
-
-		if (this->size > 2)
-		{	/* do not use first and last addresses of a block */
-			this->unused++;
-			this->size -= 2;
-		}
-		this->base = base->clone(base);
-	}
-
-	return &this->public;
-}
-
-/**
- * Described in header
- */
-mem_pool_t *mem_pool_create_range(char *name, host_t *from, host_t *to)
-{
-	private_mem_pool_t *this;
-	chunk_t fromaddr, toaddr;
-	u_int32_t diff;
-
-	fromaddr = from->get_address(from);
-	toaddr = to->get_address(to);
-
-	if (from->get_family(from) != to->get_family(to) ||
-		fromaddr.len != toaddr.len || fromaddr.len < sizeof(diff) ||
-		memcmp(fromaddr.ptr, toaddr.ptr, toaddr.len) > 0)
-	{
-		DBG1(DBG_CFG, "invalid IP address range: %H-%H", from, to);
-		return NULL;
-	}
-	if (fromaddr.len > sizeof(diff) &&
-		!chunk_equals(chunk_create(fromaddr.ptr, fromaddr.len - sizeof(diff)),
-					  chunk_create(toaddr.ptr, toaddr.len - sizeof(diff))))
-	{
-		DBG1(DBG_CFG, "IP address range too large: %H-%H", from, to);
-		return NULL;
-	}
-	this = create_generic(name);
-	this->base = from->clone(from);
-	diff = untoh32(toaddr.ptr + toaddr.len - sizeof(diff)) -
-		   untoh32(fromaddr.ptr + fromaddr.len - sizeof(diff));
-	this->size = diff + 1;
-
-	return &this->public;
-}
diff --git a/src/libhydra/attributes/mem_pool.h b/src/libhydra/attributes/mem_pool.h
deleted file mode 100644
index 7347bb5..0000000
--- a/src/libhydra/attributes/mem_pool.h
+++ /dev/null
@@ -1,146 +0,0 @@
-/*
- * Copyright (C) 2010 Tobias Brunner
- * Hochschule fuer Technik Rapperswil
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * for more details.
- */
-
-/**
- * @defgroup mem_pool mem_pool
- * @{ @ingroup attributes
- */
-
-#ifndef MEM_POOL_H
-#define MEM_POOL_H
-
-typedef struct mem_pool_t mem_pool_t;
-typedef enum mem_pool_op_t mem_pool_op_t;
-
-#include <networking/host.h>
-#include <utils/identification.h>
-
-/**
- * In-memory IP pool acquire operation.
- */
-enum mem_pool_op_t {
-	/** Check for an exsiting lease */
-	MEM_POOL_EXISTING,
-	/** Get a new lease */
-	MEM_POOL_NEW,
-	/** Replace an existing offline lease of another ID */
-	MEM_POOL_REASSIGN,
-};
-
-/**
- * An in-memory IP address pool.
- */
-struct mem_pool_t {
-
-	/**
-	 * Get the name of this pool.
-	 *
-	 * @return			the name of this pool
-	 */
-	const char* (*get_name)(mem_pool_t *this);
-
-	/**
-	 * Get the base (first) address of this pool.
-	 *
-	 * @return			base address, internal host
-	 */
-	host_t* (*get_base)(mem_pool_t *this);
-
-	/**
-	 * Get the size (i.e. number of addresses) of this pool.
-	 *
-	 * @return			the size of this pool
-	 */
-	u_int (*get_size)(mem_pool_t *this);
-
-	/**
-	 * Get the number of online leases.
-	 *
-	 * @return			the number of offline leases
-	 */
-	u_int (*get_online)(mem_pool_t *this);
-
-	/**
-	 * Get the number of offline leases.
-	 *
-	 * @return			the number of online leases
-	 */
-	u_int (*get_offline)(mem_pool_t *this);
-
-	/**
-	 * Acquire an address for the given id from this pool.
-	 *
-	 * This call is usually invoked several times: The first time to find an
-	 * existing lease (MEM_POOL_EXISTING), if none found a second time to
-	 * acquire a new lease (MEM_POOL_NEW), and if the pool is full once again
-	 * to assign an existing offline lease (MEM_POOL_REASSIGN).
-	 *
-	 * @param id		the id to acquire an address for
-	 * @param requested	acquire this address, if possible
-	 * @param operation	acquire operation to perform, see above
-	 * @return			the acquired address
-	 */
-	host_t* (*acquire_address)(mem_pool_t *this, identification_t *id,
-							   host_t *requested, mem_pool_op_t operation);
-
-	/**
-	 * Release a previously acquired address.
-	 *
-	 * @param address	the address to release
-	 * @param id		the id the address was assigned to
-	 * @return			TRUE, if the lease was found
-	 */
-	bool (*release_address)(mem_pool_t *this, host_t *address,
-							identification_t *id);
-
-	/**
-	 * Create an enumerator over the leases of this pool.
-	 *
-	 * Enumerator enumerates over
-	 * identification_t *id, host_t *address, bool online
-	 *
-	 * @return			enumerator
-	 */
-	enumerator_t* (*create_lease_enumerator)(mem_pool_t *this);
-
-	/**
-	 * Destroy a mem_pool_t instance.
-	 */
-	void (*destroy)(mem_pool_t *this);
-};
-
-/**
- * Create an in-memory IP address pool.
- *
- * An empty pool just returns the requested address.
- *
- * @param name		name of this pool
- * @param base		base address of this pool, NULL to create an empty pool
- * @param bits		number of non-network bits in base, as in CIDR notation
- * @return			memory pool instance
- */
-mem_pool_t *mem_pool_create(char *name, host_t *base, int bits);
-
-/**
- * Create an in-memory IP address from a range.
- *
- * @param name		name of this pool
- * @param from		start of ranged pool
- * @param to		end of ranged pool
- * @return			memory pool instance, NULL if range invalid
- */
-mem_pool_t *mem_pool_create_range(char *name, host_t *from, host_t *to);
-
-#endif /** MEM_POOL_H_ @} */
diff --git a/src/libhydra/hydra.c b/src/libhydra/hydra.c
index 1b50650..47ffb59 100644
--- a/src/libhydra/hydra.c
+++ b/src/libhydra/hydra.c
@@ -57,7 +57,6 @@ void libhydra_deinit()
 		return;
 	}
 
-	this->public.attributes->destroy(this->public.attributes);
 	this->public.kernel_interface->destroy(this->public.kernel_interface);
 	free(this);
 	hydra = NULL;
@@ -78,9 +77,6 @@ bool libhydra_init()
 	}
 
 	INIT(this,
-		.public = {
-			.attributes = attribute_manager_create(),
-		},
 		.ref = 1,
 	);
 	hydra = &this->public;
diff --git a/src/libhydra/hydra.h b/src/libhydra/hydra.h
index 94209ff..b23a305 100644
--- a/src/libhydra/hydra.h
+++ b/src/libhydra/hydra.h
@@ -16,9 +16,6 @@
 /**
  * @defgroup libhydra libhydra
  *
- * @defgroup attributes attributes
- * @ingroup libhydra
- *
  * @defgroup hkernel kernel
  * @ingroup libhydra
  *
@@ -34,7 +31,6 @@
 
 typedef struct hydra_t hydra_t;
 
-#include <attributes/attribute_manager.h>
 #include <kernel/kernel_interface.h>
 
 #include <library.h>
@@ -45,11 +41,6 @@ typedef struct hydra_t hydra_t;
 struct hydra_t {
 
 	/**
-	 * manager for payload attributes
-	 */
-	attribute_manager_t *attributes;
-
-	/**
 	 * kernel interface to communicate with kernel
 	 */
 	kernel_interface_t *kernel_interface;
diff --git a/src/libhydra/kernel/kernel_interface.c b/src/libhydra/kernel/kernel_interface.c
index 3fa28e0..ce31bd4 100644
--- a/src/libhydra/kernel/kernel_interface.c
+++ b/src/libhydra/kernel/kernel_interface.c
@@ -43,6 +43,8 @@
 #include <utils/debug.h>
 #include <threading/mutex.h>
 #include <collections/linked_list.h>
+#include <collections/hashtable.h>
+#include <collections/array.h>
 
 typedef struct private_kernel_interface_t private_kernel_interface_t;
 
@@ -115,6 +117,16 @@ struct private_kernel_interface_t {
 	linked_list_t *listeners;
 
 	/**
+	 * Reqid entries indexed by reqids
+	 */
+	hashtable_t *reqids;
+
+	/**
+	 * Reqid entries indexed by traffic selectors
+	 */
+	hashtable_t *reqids_by_ts;
+
+	/**
 	 * mutex for algorithm mappings
 	 */
 	mutex_t *mutex_algs;
@@ -155,24 +167,252 @@ METHOD(kernel_interface_t, get_features, kernel_feature_t,
 
 METHOD(kernel_interface_t, get_spi, status_t,
 	private_kernel_interface_t *this, host_t *src, host_t *dst,
-	u_int8_t protocol, u_int32_t reqid, u_int32_t *spi)
+	u_int8_t protocol, u_int32_t *spi)
 {
 	if (!this->ipsec)
 	{
 		return NOT_SUPPORTED;
 	}
-	return this->ipsec->get_spi(this->ipsec, src, dst, protocol, reqid, spi);
+	return this->ipsec->get_spi(this->ipsec, src, dst, protocol, spi);
 }
 
 METHOD(kernel_interface_t, get_cpi, status_t,
 	private_kernel_interface_t *this, host_t *src, host_t *dst,
-	u_int32_t reqid, u_int16_t *cpi)
+	u_int16_t *cpi)
 {
 	if (!this->ipsec)
 	{
 		return NOT_SUPPORTED;
 	}
-	return this->ipsec->get_cpi(this->ipsec, src, dst, reqid, cpi);
+	return this->ipsec->get_cpi(this->ipsec, src, dst, cpi);
+}
+
+/**
+ * Reqid mapping entry
+ */
+typedef struct {
+	/** allocated reqid */
+	u_int32_t reqid;
+	/** references to this entry */
+	u_int refs;
+	/** inbound mark used for SA */
+	mark_t mark_in;
+	/** outbound mark used for SA */
+	mark_t mark_out;
+	/** local traffic selectors */
+	array_t *local;
+	/** remote traffic selectors */
+	array_t *remote;
+} reqid_entry_t;
+
+/**
+ * Destroy a reqid mapping entry
+ */
+static void reqid_entry_destroy(reqid_entry_t *entry)
+{
+	array_destroy_offset(entry->local, offsetof(traffic_selector_t, destroy));
+	array_destroy_offset(entry->remote, offsetof(traffic_selector_t, destroy));
+	free(entry);
+}
+
+/**
+ * Hashtable hash function for reqid entries using reqid as key
+ */
+static u_int hash_reqid(reqid_entry_t *entry)
+{
+	return chunk_hash_inc(chunk_from_thing(entry->reqid),
+				chunk_hash_inc(chunk_from_thing(entry->mark_in),
+					chunk_hash(chunk_from_thing(entry->mark_out))));
+}
+
+/**
+ * Hashtable equals function for reqid entries using reqid as key
+ */
+static bool equals_reqid(reqid_entry_t *a, reqid_entry_t *b)
+{
+	return a->reqid == b->reqid &&
+		   a->mark_in.value == b->mark_in.value &&
+		   a->mark_in.mask == b->mark_in.mask &&
+		   a->mark_out.value == b->mark_out.value &&
+		   a->mark_out.mask == b->mark_out.mask;
+}
+
+/**
+ * Hash an array of traffic selectors
+ */
+static u_int hash_ts_array(array_t *array, u_int hash)
+{
+	enumerator_t *enumerator;
+	traffic_selector_t *ts;
+
+	enumerator = array_create_enumerator(array);
+	while (enumerator->enumerate(enumerator, &ts))
+	{
+		hash = ts->hash(ts, hash);
+	}
+	enumerator->destroy(enumerator);
+
+	return hash;
+}
+
+/**
+ * Hashtable hash function for reqid entries using traffic selectors as key
+ */
+static u_int hash_reqid_by_ts(reqid_entry_t *entry)
+{
+	return hash_ts_array(entry->local, hash_ts_array(entry->remote,
+			chunk_hash_inc(chunk_from_thing(entry->mark_in),
+				chunk_hash(chunk_from_thing(entry->mark_out)))));
+}
+
+/**
+ * Compare two array with traffic selectors for equality
+ */
+static bool ts_array_equals(array_t *a, array_t *b)
+{
+	traffic_selector_t *tsa, *tsb;
+	enumerator_t *ae, *be;
+	bool equal = TRUE;
+
+	if (array_count(a) != array_count(b))
+	{
+		return FALSE;
+	}
+
+	ae = array_create_enumerator(a);
+	be = array_create_enumerator(b);
+	while (equal && ae->enumerate(ae, &tsa) && be->enumerate(be, &tsb))
+	{
+		equal = tsa->equals(tsa, tsb);
+	}
+	ae->destroy(ae);
+	be->destroy(be);
+
+	return equal;
+}
+
+/**
+ * Hashtable equals function for reqid entries using traffic selectors as key
+ */
+static bool equals_reqid_by_ts(reqid_entry_t *a, reqid_entry_t *b)
+{
+	return ts_array_equals(a->local, b->local) &&
+		   ts_array_equals(a->remote, b->remote) &&
+		   a->mark_in.value == b->mark_in.value &&
+		   a->mark_in.mask == b->mark_in.mask &&
+		   a->mark_out.value == b->mark_out.value &&
+		   a->mark_out.mask == b->mark_out.mask;
+}
+
+/**
+ * Create an array from copied traffic selector list items
+ */
+static array_t *array_from_ts_list(linked_list_t *list)
+{
+	enumerator_t *enumerator;
+	traffic_selector_t *ts;
+	array_t *array;
+
+	array = array_create(0, 0);
+
+	enumerator = list->create_enumerator(list);
+	while (enumerator->enumerate(enumerator, &ts))
+	{
+		array_insert(array, ARRAY_TAIL, ts->clone(ts));
+	}
+	enumerator->destroy(enumerator);
+
+	return array;
+}
+
+METHOD(kernel_interface_t, alloc_reqid, status_t,
+	private_kernel_interface_t *this,
+	linked_list_t *local_ts, linked_list_t *remote_ts,
+	mark_t mark_in, mark_t mark_out, u_int32_t *reqid)
+{
+	static u_int32_t counter = 0;
+	reqid_entry_t *entry = NULL, *tmpl;
+	status_t status = SUCCESS;
+
+	INIT(tmpl,
+		.local = array_from_ts_list(local_ts),
+		.remote = array_from_ts_list(remote_ts),
+		.mark_in = mark_in,
+		.mark_out = mark_out,
+		.reqid = *reqid,
+	);
+
+	this->mutex->lock(this->mutex);
+	if (tmpl->reqid)
+	{
+		/* search by reqid if given */
+		entry = this->reqids->get(this->reqids, tmpl);
+	}
+	if (entry)
+	{
+		/* we don't require a traffic selector match for explicit reqids,
+		 * as we wan't to reuse a reqid for trap-triggered policies that
+		 * got narrowed during negotiation. */
+		reqid_entry_destroy(tmpl);
+	}
+	else
+	{
+		/* search by traffic selectors */
+		entry = this->reqids_by_ts->get(this->reqids_by_ts, tmpl);
+		if (entry)
+		{
+			reqid_entry_destroy(tmpl);
+		}
+		else
+		{
+			/* none found, create a new entry, allocating a reqid */
+			entry = tmpl;
+			entry->reqid = ++counter;
+			this->reqids_by_ts->put(this->reqids_by_ts, entry, entry);
+			this->reqids->put(this->reqids, entry, entry);
+		}
+		*reqid = entry->reqid;
+	}
+	entry->refs++;
+	this->mutex->unlock(this->mutex);
+
+	return status;
+}
+
+METHOD(kernel_interface_t, release_reqid, status_t,
+	private_kernel_interface_t *this, u_int32_t reqid,
+	mark_t mark_in, mark_t mark_out)
+{
+	reqid_entry_t *entry, tmpl = {
+		.reqid = reqid,
+		.mark_in = mark_in,
+		.mark_out = mark_out,
+	};
+
+	this->mutex->lock(this->mutex);
+	entry = this->reqids->remove(this->reqids, &tmpl);
+	if (entry)
+	{
+		if (--entry->refs == 0)
+		{
+			entry = this->reqids_by_ts->remove(this->reqids_by_ts, entry);
+			if (entry)
+			{
+				reqid_entry_destroy(entry);
+			}
+		}
+		else
+		{
+			this->reqids->put(this->reqids, entry, entry);
+		}
+	}
+	this->mutex->unlock(this->mutex);
+
+	if (entry)
+	{
+		return SUCCESS;
+	}
+	return NOT_FOUND;
 }
 
 METHOD(kernel_interface_t, add_sa, status_t,
@@ -181,8 +421,8 @@ METHOD(kernel_interface_t, add_sa, status_t,
 	u_int32_t tfc, lifetime_cfg_t *lifetime, u_int16_t enc_alg, chunk_t enc_key,
 	u_int16_t int_alg, chunk_t int_key, ipsec_mode_t mode,
 	u_int16_t ipcomp, u_int16_t cpi, u_int32_t replay_window,
-	bool initiator, bool encap, bool esn, bool inbound,
-	traffic_selector_t *src_ts, traffic_selector_t *dst_ts)
+	bool initiator, bool encap, bool esn, bool inbound, bool update,
+	linked_list_t *src_ts, linked_list_t *dst_ts)
 {
 	if (!this->ipsec)
 	{
@@ -191,7 +431,7 @@ METHOD(kernel_interface_t, add_sa, status_t,
 	return this->ipsec->add_sa(this->ipsec, src, dst, spi, protocol, reqid,
 				mark, tfc, lifetime, enc_alg, enc_key, int_alg, int_key, mode,
 				ipcomp, cpi, replay_window, initiator, encap, esn, inbound,
-				src_ts, dst_ts);
+				update, src_ts, dst_ts);
 }
 
 METHOD(kernel_interface_t, update_sa, status_t,
@@ -575,17 +815,18 @@ METHOD(kernel_interface_t, acquire, void,
 }
 
 METHOD(kernel_interface_t, expire, void,
-	private_kernel_interface_t *this, u_int32_t reqid, u_int8_t protocol,
-	u_int32_t spi, bool hard)
+	private_kernel_interface_t *this, u_int8_t protocol, u_int32_t spi,
+	host_t *dst, bool hard)
 {
 	kernel_listener_t *listener;
 	enumerator_t *enumerator;
+
 	this->mutex->lock(this->mutex);
 	enumerator = this->listeners->create_enumerator(this->listeners);
 	while (enumerator->enumerate(enumerator, &listener))
 	{
 		if (listener->expire &&
-			!listener->expire(listener, reqid, protocol, spi, hard))
+			!listener->expire(listener, protocol, spi, dst, hard))
 		{
 			this->listeners->remove_at(this->listeners, enumerator);
 		}
@@ -595,17 +836,18 @@ METHOD(kernel_interface_t, expire, void,
 }
 
 METHOD(kernel_interface_t, mapping, void,
-	private_kernel_interface_t *this, u_int32_t reqid, u_int32_t spi,
-	host_t *remote)
+	private_kernel_interface_t *this, u_int8_t protocol, u_int32_t spi,
+	host_t *dst, host_t *remote)
 {
 	kernel_listener_t *listener;
 	enumerator_t *enumerator;
+
 	this->mutex->lock(this->mutex);
 	enumerator = this->listeners->create_enumerator(this->listeners);
 	while (enumerator->enumerate(enumerator, &listener))
 	{
 		if (listener->mapping &&
-			!listener->mapping(listener, reqid, spi, remote))
+			!listener->mapping(listener, protocol, spi, dst, remote))
 		{
 			this->listeners->remove_at(this->listeners, enumerator);
 		}
@@ -733,6 +975,8 @@ METHOD(kernel_interface_t, destroy, void,
 	DESTROY_IF(this->ipsec);
 	DESTROY_IF(this->net);
 	DESTROY_FUNCTION_IF(this->ifaces_filter, (void*)free);
+	this->reqids->destroy(this->reqids);
+	this->reqids_by_ts->destroy(this->reqids_by_ts);
 	this->listeners->destroy(this->listeners);
 	this->mutex->destroy(this->mutex);
 	free(this);
@@ -751,6 +995,8 @@ kernel_interface_t *kernel_interface_create()
 			.get_features = _get_features,
 			.get_spi = _get_spi,
 			.get_cpi = _get_cpi,
+			.alloc_reqid = _alloc_reqid,
+			.release_reqid = _release_reqid,
 			.add_sa = _add_sa,
 			.update_sa = _update_sa,
 			.query_sa = _query_sa,
@@ -795,6 +1041,10 @@ kernel_interface_t *kernel_interface_create()
 		.listeners = linked_list_create(),
 		.mutex_algs = mutex_create(MUTEX_TYPE_DEFAULT),
 		.algorithms = linked_list_create(),
+		.reqids = hashtable_create((hashtable_hash_t)hash_reqid,
+								   (hashtable_equals_t)equals_reqid, 8),
+		.reqids_by_ts = hashtable_create((hashtable_hash_t)hash_reqid_by_ts,
+								   (hashtable_equals_t)equals_reqid_by_ts, 8),
 	);
 
 	ifaces = lib->settings->get_str(lib->settings,
diff --git a/src/libhydra/kernel/kernel_interface.h b/src/libhydra/kernel/kernel_interface.h
index cd55038..96ce9e2 100644
--- a/src/libhydra/kernel/kernel_interface.h
+++ b/src/libhydra/kernel/kernel_interface.h
@@ -104,39 +104,67 @@ struct kernel_interface_t {
 	 * @param src		source address of SA
 	 * @param dst		destination address of SA
 	 * @param protocol	protocol for SA (ESP/AH)
-	 * @param reqid		unique ID for this SA
 	 * @param spi		allocated spi
-	 * @return				SUCCESS if operation completed
+	 * @return			SUCCESS if operation completed
 	 */
 	status_t (*get_spi)(kernel_interface_t *this, host_t *src, host_t *dst,
-						u_int8_t protocol, u_int32_t reqid, u_int32_t *spi);
+						u_int8_t protocol, u_int32_t *spi);
 
 	/**
 	 * Get a Compression Parameter Index (CPI) from the kernel.
 	 *
 	 * @param src		source address of SA
 	 * @param dst		destination address of SA
-	 * @param reqid		unique ID for the corresponding SA
 	 * @param cpi		allocated cpi
-	 * @return				SUCCESS if operation completed
+	 * @return			SUCCESS if operation completed
 	 */
 	status_t (*get_cpi)(kernel_interface_t *this, host_t *src, host_t *dst,
-						u_int32_t reqid, u_int16_t *cpi);
+						u_int16_t *cpi);
+
+	/**
+	 * Allocate or confirm a reqid to use for a given SA pair.
+	 *
+	 * Each returned reqid by a successful call to alloc_reqid() must be
+	 * released using release_reqid().
+	 *
+	 * The reqid parameter is an in/out parameter. If it points to non-zero,
+	 * the reqid is confirmed and registered for use. If it points to zero,
+	 * a reqid is allocated for the given selectors, and returned to reqid.
+	 *
+	 * @param local_ts	traffic selectors of local side for SA
+	 * @param remote_ts	traffic selectors of remote side for SA
+	 * @param mark_in	inbound mark on SA
+	 * @param mark_out	outbound mark on SA
+	 * @param reqid		allocated reqid
+	 * @return			SUCCESS if reqid allocated
+	 */
+	status_t (*alloc_reqid)(kernel_interface_t *this,
+							linked_list_t *local_ts, linked_list_t *remote_ts,
+							mark_t mark_in, mark_t mark_out,
+							u_int32_t *reqid);
+
+	/**
+	 * Release a previously allocated reqid.
+	 *
+	 * @param reqid		reqid to release
+	 * @param mark_in	inbound mark on SA
+	 * @param mark_out	outbound mark on SA
+	 * @return			SUCCESS if reqid released
+	 */
+	status_t (*release_reqid)(kernel_interface_t *this, u_int32_t reqid,
+							  mark_t mark_in, mark_t mark_out);
 
 	/**
 	 * Add an SA to the SAD.
 	 *
-	 * add_sa() may update an already allocated
-	 * SPI (via get_spi). In this case, the replace
-	 * flag must be set.
-	 * This function does install a single SA for a
-	 * single protocol in one direction.
+	 * This function does install a single SA for a single protocol in one
+	 * direction.
 	 *
 	 * @param src			source address for this SA
 	 * @param dst			destination address for this SA
 	 * @param spi			SPI allocated by us or remote peer
 	 * @param protocol		protocol for this SA (ESP/AH)
-	 * @param reqid			unique ID for this SA
+	 * @param reqid			reqid for this SA
 	 * @param mark			optional mark for this SA
 	 * @param tfc			Traffic Flow Confidentiality padding for this SA
 	 * @param lifetime		lifetime_cfg_t for this SA
@@ -152,8 +180,9 @@ struct kernel_interface_t {
 	 * @param encap			enable UDP encapsulation for NAT traversal
 	 * @param esn			TRUE to use Extended Sequence Numbers
 	 * @param inbound		TRUE if this is an inbound SA
-	 * @param src_ts		traffic selector with BEET source address
-	 * @param dst_ts		traffic selector with BEET destination address
+	 * @param update		TRUE if an SPI has already been allocated for SA
+	 * @param src_ts		list of source traffic selectors
+	 * @param dst_ts		list of destination traffic selectors
 	 * @return				SUCCESS if operation completed
 	 */
 	status_t (*add_sa) (kernel_interface_t *this,
@@ -163,9 +192,9 @@ struct kernel_interface_t {
 						u_int16_t enc_alg, chunk_t enc_key,
 						u_int16_t int_alg, chunk_t int_key,
 						ipsec_mode_t mode, u_int16_t ipcomp, u_int16_t cpi,
-						u_int32_t replay_window,
-						bool initiator, bool encap, bool esn, bool inbound,
-						traffic_selector_t *src_ts, traffic_selector_t *dst_ts);
+						u_int32_t replay_window, bool initiator, bool encap,
+						bool esn, bool inbound, bool update,
+						linked_list_t *src_ts, linked_list_t *dst_ts);
 
 	/**
 	 * Update the hosts on an installed SA.
@@ -531,23 +560,24 @@ struct kernel_interface_t {
 	/**
 	 * Raise an expire event.
 	 *
-	 * @param reqid			reqid of the expired SA
 	 * @param protocol		protocol of the expired SA
 	 * @param spi			spi of the expired SA
+	 * @param dst			destination address of expired SA
 	 * @param hard			TRUE if it is a hard expire, FALSE otherwise
 	 */
-	void (*expire)(kernel_interface_t *this, u_int32_t reqid,
-				   u_int8_t protocol, u_int32_t spi, bool hard);
+	void (*expire)(kernel_interface_t *this, u_int8_t protocol, u_int32_t spi,
+				   host_t *dst, bool hard);
 
 	/**
 	 * Raise a mapping event.
 	 *
-	 * @param reqid			reqid of the SA
+	 * @param protocol		protocol of affected SA
 	 * @param spi			spi of the SA
+	 * @param dst			original destination address of SA
 	 * @param remote		new remote host
 	 */
-	void (*mapping)(kernel_interface_t *this, u_int32_t reqid, u_int32_t spi,
-					host_t *remote);
+	void (*mapping)(kernel_interface_t *this, u_int8_t protocol, u_int32_t spi,
+					host_t *dst, host_t *remote);
 
 	/**
 	 * Raise a migrate event.
diff --git a/src/libhydra/kernel/kernel_ipsec.h b/src/libhydra/kernel/kernel_ipsec.h
index eec7401..19caaa4 100644
--- a/src/libhydra/kernel/kernel_ipsec.h
+++ b/src/libhydra/kernel/kernel_ipsec.h
@@ -58,33 +58,28 @@ struct kernel_ipsec_t {
 	 * @param src		source address of SA
 	 * @param dst		destination address of SA
 	 * @param protocol	protocol for SA (ESP/AH)
-	 * @param reqid		unique ID for this SA
 	 * @param spi		allocated spi
-	 * @return				SUCCESS if operation completed
+	 * @return			SUCCESS if operation completed
 	 */
 	status_t (*get_spi)(kernel_ipsec_t *this, host_t *src, host_t *dst,
-						u_int8_t protocol, u_int32_t reqid, u_int32_t *spi);
+						u_int8_t protocol, u_int32_t *spi);
 
 	/**
 	 * Get a Compression Parameter Index (CPI) from the kernel.
 	 *
 	 * @param src		source address of SA
 	 * @param dst		destination address of SA
-	 * @param reqid		unique ID for the corresponding SA
 	 * @param cpi		allocated cpi
-	 * @return				SUCCESS if operation completed
+	 * @return			SUCCESS if operation completed
 	 */
 	status_t (*get_cpi)(kernel_ipsec_t *this, host_t *src, host_t *dst,
-						u_int32_t reqid, u_int16_t *cpi);
+						u_int16_t *cpi);
 
 	/**
 	 * Add an SA to the SAD.
 	 *
-	 * add_sa() may update an already allocated
-	 * SPI (via get_spi). In this case, the replace
-	 * flag must be set.
-	 * This function does install a single SA for a
-	 * single protocol in one direction.
+	 * This function does install a single SA for a single protocol in one
+	 * direction.
 	 *
 	 * @param src			source address for this SA
 	 * @param dst			destination address for this SA
@@ -106,8 +101,9 @@ struct kernel_ipsec_t {
 	 * @param encap			enable UDP encapsulation for NAT traversal
 	 * @param esn			TRUE to use Extended Sequence Numbers
 	 * @param inbound		TRUE if this is an inbound SA
-	 * @param src_ts		traffic selector with BEET source address
-	 * @param dst_ts		traffic selector with BEET destination address
+	 * @param update		TRUE if an SPI has already been allocated for SA
+	 * @param src_ts		list of source traffic selectors
+	 * @param dst_ts		list of destination traffic selectors
 	 * @return				SUCCESS if operation completed
 	 */
 	status_t (*add_sa) (kernel_ipsec_t *this,
@@ -117,9 +113,9 @@ struct kernel_ipsec_t {
 						u_int16_t enc_alg, chunk_t enc_key,
 						u_int16_t int_alg, chunk_t int_key,
 						ipsec_mode_t mode, u_int16_t ipcomp, u_int16_t cpi,
-						u_int32_t replay_window,
-						bool initiator, bool encap, bool esn, bool inbound,
-						traffic_selector_t *src_ts, traffic_selector_t *dst_ts);
+						u_int32_t replay_window, bool initiator, bool encap,
+						bool esn, bool inbound, bool update,
+						linked_list_t *src_ts, linked_list_t *dst_ts);
 
 	/**
 	 * Update the hosts on an installed SA.
diff --git a/src/libhydra/kernel/kernel_listener.h b/src/libhydra/kernel/kernel_listener.h
index 4382a43..8074356 100644
--- a/src/libhydra/kernel/kernel_listener.h
+++ b/src/libhydra/kernel/kernel_listener.h
@@ -49,25 +49,26 @@ struct kernel_listener_t {
 	/**
 	 * Hook called if an exire event for an IPsec SA is received.
 	 *
-	 * @param reqid			reqid of the expired SA
 	 * @param protocol		protocol of the expired SA
 	 * @param spi			spi of the expired SA
+	 * @param dst			destination address of expired SA
 	 * @param hard			TRUE if it is a hard expire, FALSE otherwise
 	 * @return				TRUE to remain registered, FALSE to unregister
 	 */
-	bool (*expire)(kernel_listener_t *this, u_int32_t reqid,
-				   u_int8_t protocol, u_int32_t spi, bool hard);
+	bool (*expire)(kernel_listener_t *this, u_int8_t protocol, u_int32_t spi,
+				   host_t *dst, bool hard);
 
 	/**
 	 * Hook called if the NAT mappings of an IPsec SA changed.
 	 *
-	 * @param reqid			reqid of the SA
+	 * @param protocol		IPsec protocol of affected SA
 	 * @param spi			spi of the SA
+	 * @param dst			old destinatino address of SA
 	 * @param remote		new remote host
 	 * @return				TRUE to remain registered, FALSE to unregister
 	 */
-	bool (*mapping)(kernel_listener_t *this, u_int32_t reqid, u_int32_t spi,
-					host_t *remote);
+	bool (*mapping)(kernel_listener_t *this, u_int8_t protocol, u_int32_t spi,
+					host_t *dst, host_t *remote);
 
 	/**
 	 * Hook called if a migrate event for a policy is received.
diff --git a/src/libhydra/plugins/attr/Makefile.am b/src/libhydra/plugins/attr/Makefile.am
deleted file mode 100644
index 5b899b8..0000000
--- a/src/libhydra/plugins/attr/Makefile.am
+++ /dev/null
@@ -1,18 +0,0 @@
-AM_CPPFLAGS = \
-	-I$(top_srcdir)/src/libstrongswan \
-	-I$(top_srcdir)/src/libhydra
-
-AM_CFLAGS = \
-	$(PLUGIN_CFLAGS)
-
-if MONOLITHIC
-noinst_LTLIBRARIES = libstrongswan-attr.la
-else
-plugin_LTLIBRARIES = libstrongswan-attr.la
-endif
-
-libstrongswan_attr_la_SOURCES = \
-	attr_plugin.h attr_plugin.c \
-	attr_provider.h attr_provider.c
-
-libstrongswan_attr_la_LDFLAGS = -module -avoid-version
diff --git a/src/libhydra/plugins/attr/Makefile.in b/src/libhydra/plugins/attr/Makefile.in
deleted file mode 100644
index 50ea066..0000000
--- a/src/libhydra/plugins/attr/Makefile.in
+++ /dev/null
@@ -1,771 +0,0 @@
-# Makefile.in generated by automake 1.14.1 from Makefile.am.
-# @configure_input@
-
-# Copyright (C) 1994-2013 Free Software Foundation, Inc.
-
-# This Makefile.in is free software; the Free Software Foundation
-# gives unlimited permission to copy and/or distribute it,
-# with or without modifications, as long as this notice is preserved.
-
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
-# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
-# PARTICULAR PURPOSE.
-
- at SET_MAKE@
-
-VPATH = @srcdir@
-am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)'
-am__make_running_with_option = \
-  case $${target_option-} in \
-      ?) ;; \
-      *) echo "am__make_running_with_option: internal error: invalid" \
-              "target option '$${target_option-}' specified" >&2; \
-         exit 1;; \
-  esac; \
-  has_opt=no; \
-  sane_makeflags=$$MAKEFLAGS; \
-  if $(am__is_gnu_make); then \
-    sane_makeflags=$$MFLAGS; \
-  else \
-    case $$MAKEFLAGS in \
-      *\\[\ \	]*) \
-        bs=\\; \
-        sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
-          | sed "s/$$bs$$bs[$$bs $$bs	]*//g"`;; \
-    esac; \
-  fi; \
-  skip_next=no; \
-  strip_trailopt () \
-  { \
-    flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
-  }; \
-  for flg in $$sane_makeflags; do \
-    test $$skip_next = yes && { skip_next=no; continue; }; \
-    case $$flg in \
-      *=*|--*) continue;; \
-        -*I) strip_trailopt 'I'; skip_next=yes;; \
-      -*I?*) strip_trailopt 'I';; \
-        -*O) strip_trailopt 'O'; skip_next=yes;; \
-      -*O?*) strip_trailopt 'O';; \
-        -*l) strip_trailopt 'l'; skip_next=yes;; \
-      -*l?*) strip_trailopt 'l';; \
-      -[dEDm]) skip_next=yes;; \
-      -[JT]) skip_next=yes;; \
-    esac; \
-    case $$flg in \
-      *$$target_option*) has_opt=yes; break;; \
-    esac; \
-  done; \
-  test $$has_opt = yes
-am__make_dryrun = (target_option=n; $(am__make_running_with_option))
-am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
-pkgdatadir = $(datadir)/@PACKAGE@
-pkgincludedir = $(includedir)/@PACKAGE@
-pkglibdir = $(libdir)/@PACKAGE@
-pkglibexecdir = $(libexecdir)/@PACKAGE@
-am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
-install_sh_DATA = $(install_sh) -c -m 644
-install_sh_PROGRAM = $(install_sh) -c
-install_sh_SCRIPT = $(install_sh) -c
-INSTALL_HEADER = $(INSTALL_DATA)
-transform = $(program_transform_name)
-NORMAL_INSTALL = :
-PRE_INSTALL = :
-POST_INSTALL = :
-NORMAL_UNINSTALL = :
-PRE_UNINSTALL = :
-POST_UNINSTALL = :
-build_triplet = @build@
-host_triplet = @host@
-subdir = src/libhydra/plugins/attr
-DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
-	$(top_srcdir)/depcomp
-ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
-am__aclocal_m4_deps = $(top_srcdir)/m4/config/libtool.m4 \
-	$(top_srcdir)/m4/config/ltoptions.m4 \
-	$(top_srcdir)/m4/config/ltsugar.m4 \
-	$(top_srcdir)/m4/config/ltversion.m4 \
-	$(top_srcdir)/m4/config/lt~obsolete.m4 \
-	$(top_srcdir)/m4/macros/split-package-version.m4 \
-	$(top_srcdir)/m4/macros/with.m4 \
-	$(top_srcdir)/m4/macros/enable-disable.m4 \
-	$(top_srcdir)/m4/macros/add-plugin.m4 \
-	$(top_srcdir)/configure.ac
-am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
-	$(ACLOCAL_M4)
-mkinstalldirs = $(install_sh) -d
-CONFIG_HEADER = $(top_builddir)/config.h
-CONFIG_CLEAN_FILES =
-CONFIG_CLEAN_VPATH_FILES =
-am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
-am__vpath_adj = case $$p in \
-    $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
-    *) f=$$p;; \
-  esac;
-am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
-am__install_max = 40
-am__nobase_strip_setup = \
-  srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
-am__nobase_strip = \
-  for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
-am__nobase_list = $(am__nobase_strip_setup); \
-  for p in $$list; do echo "$$p $$p"; done | \
-  sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
-  $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
-    if (++n[$$2] == $(am__install_max)) \
-      { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
-    END { for (dir in files) print dir, files[dir] }'
-am__base_list = \
-  sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
-  sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
-am__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; }; \
-  }
-am__installdirs = "$(DESTDIR)$(plugindir)"
-LTLIBRARIES = $(noinst_LTLIBRARIES) $(plugin_LTLIBRARIES)
-libstrongswan_attr_la_LIBADD =
-am_libstrongswan_attr_la_OBJECTS = attr_plugin.lo attr_provider.lo
-libstrongswan_attr_la_OBJECTS = $(am_libstrongswan_attr_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_attr_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \
-	$(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \
-	$(AM_CFLAGS) $(CFLAGS) $(libstrongswan_attr_la_LDFLAGS) \
-	$(LDFLAGS) -o $@
- at MONOLITHIC_FALSE@am_libstrongswan_attr_la_rpath = -rpath $(plugindir)
- at MONOLITHIC_TRUE@am_libstrongswan_attr_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
-am__v_P_1 = :
-AM_V_GEN = $(am__v_GEN_ at AM_V@)
-am__v_GEN_ = $(am__v_GEN_ at AM_DEFAULT_V@)
-am__v_GEN_0 = @echo "  GEN     " $@;
-am__v_GEN_1 = 
-AM_V_at = $(am__v_at_ at AM_V@)
-am__v_at_ = $(am__v_at_ at AM_DEFAULT_V@)
-am__v_at_0 = @
-am__v_at_1 = 
-DEFAULT_INCLUDES = -I. at am__isrc@ -I$(top_builddir)
-depcomp = $(SHELL) $(top_srcdir)/depcomp
-am__depfiles_maybe = depfiles
-am__mv = mv -f
-COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
-	$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
-LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
-	$(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \
-	$(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
-	$(AM_CFLAGS) $(CFLAGS)
-AM_V_CC = $(am__v_CC_ at AM_V@)
-am__v_CC_ = $(am__v_CC_ at AM_DEFAULT_V@)
-am__v_CC_0 = @echo "  CC      " $@;
-am__v_CC_1 = 
-CCLD = $(CC)
-LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
-	$(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
-	$(AM_LDFLAGS) $(LDFLAGS) -o $@
-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_attr_la_SOURCES)
-DIST_SOURCES = $(libstrongswan_attr_la_SOURCES)
-am__can_run_installinfo = \
-  case $$AM_UPDATE_INFO_DIR in \
-    n|no|NO) false;; \
-    *) (install-info --version) >/dev/null 2>&1;; \
-  esac
-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
-# *not* preserved.
-am__uniquify_input = $(AWK) '\
-  BEGIN { nonempty = 0; } \
-  { items[$$0] = 1; nonempty = 1; } \
-  END { if (nonempty) { for (i in items) print i; }; } \
-'
-# Make sure the list of sources is unique.  This is necessary because,
-# e.g., the same source file might be shared among _SOURCES variables
-# for different programs/libraries.
-am__define_uniq_tagged_files = \
-  list='$(am__tagged_files)'; \
-  unique=`for i in $$list; do \
-    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
-  done | $(am__uniquify_input)`
-ETAGS = etags
-CTAGS = ctags
-DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
-ACLOCAL = @ACLOCAL@
-ALLOCA = @ALLOCA@
-AMTAR = @AMTAR@
-AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
-AR = @AR@
-AUTOCONF = @AUTOCONF@
-AUTOHEADER = @AUTOHEADER@
-AUTOMAKE = @AUTOMAKE@
-AWK = @AWK@
-BFDLIB = @BFDLIB@
-BTLIB = @BTLIB@
-CC = @CC@
-CCDEPMODE = @CCDEPMODE@
-CFLAGS = @CFLAGS@
-COVERAGE_CFLAGS = @COVERAGE_CFLAGS@
-COVERAGE_LDFLAGS = @COVERAGE_LDFLAGS@
-CPP = @CPP@
-CPPFLAGS = @CPPFLAGS@
-CYGPATH_W = @CYGPATH_W@
-DEFS = @DEFS@
-DEPDIR = @DEPDIR@
-DLLIB = @DLLIB@
-DLLTOOL = @DLLTOOL@
-DSYMUTIL = @DSYMUTIL@
-DUMPBIN = @DUMPBIN@
-ECHO_C = @ECHO_C@
-ECHO_N = @ECHO_N@
-ECHO_T = @ECHO_T@
-EGREP = @EGREP@
-EXEEXT = @EXEEXT@
-FGREP = @FGREP@
-GEM = @GEM@
-GENHTML = @GENHTML@
-GPERF = @GPERF@
-GPRBUILD = @GPRBUILD@
-GREP = @GREP@
-INSTALL = @INSTALL@
-INSTALL_DATA = @INSTALL_DATA@
-INSTALL_PROGRAM = @INSTALL_PROGRAM@
-INSTALL_SCRIPT = @INSTALL_SCRIPT@
-INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
-LCOV = @LCOV@
-LD = @LD@
-LDFLAGS = @LDFLAGS@
-LEX = @LEX@
-LEXLIB = @LEXLIB@
-LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@
-LIBOBJS = @LIBOBJS@
-LIBS = @LIBS@
-LIBTOOL = @LIBTOOL@
-LIPO = @LIPO@
-LN_S = @LN_S@
-LTLIBOBJS = @LTLIBOBJS@
-MAKEINFO = @MAKEINFO@
-MANIFEST_TOOL = @MANIFEST_TOOL@
-MKDIR_P = @MKDIR_P@
-MYSQLCFLAG = @MYSQLCFLAG@
-MYSQLCONFIG = @MYSQLCONFIG@
-MYSQLLIB = @MYSQLLIB@
-NM = @NM@
-NMEDIT = @NMEDIT@
-OBJDUMP = @OBJDUMP@
-OBJEXT = @OBJEXT@
-OPENSSL_LIB = @OPENSSL_LIB@
-OTOOL = @OTOOL@
-OTOOL64 = @OTOOL64@
-PACKAGE = @PACKAGE@
-PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
-PACKAGE_NAME = @PACKAGE_NAME@
-PACKAGE_STRING = @PACKAGE_STRING@
-PACKAGE_TARNAME = @PACKAGE_TARNAME@
-PACKAGE_URL = @PACKAGE_URL@
-PACKAGE_VERSION = @PACKAGE_VERSION@
-PACKAGE_VERSION_BUILD = @PACKAGE_VERSION_BUILD@
-PACKAGE_VERSION_MAJOR = @PACKAGE_VERSION_MAJOR@
-PACKAGE_VERSION_MINOR = @PACKAGE_VERSION_MINOR@
-PACKAGE_VERSION_REVIEW = @PACKAGE_VERSION_REVIEW@
-PATH_SEPARATOR = @PATH_SEPARATOR@
-PERL = @PERL@
-PKG_CONFIG = @PKG_CONFIG@
-PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
-PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
-PLUGIN_CFLAGS = @PLUGIN_CFLAGS@
-PTHREADLIB = @PTHREADLIB@
-PYTHON = @PYTHON@
-PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
-PYTHON_PLATFORM = @PYTHON_PLATFORM@
-PYTHON_PREFIX = @PYTHON_PREFIX@
-PYTHON_VERSION = @PYTHON_VERSION@
-RANLIB = @RANLIB@
-RTLIB = @RTLIB@
-RUBY = @RUBY@
-RUBYGEMDIR = @RUBYGEMDIR@
-RUBYINCLUDE = @RUBYINCLUDE@
-RUBYLIB = @RUBYLIB@
-SED = @SED@
-SET_MAKE = @SET_MAKE@
-SHELL = @SHELL@
-SOCKLIB = @SOCKLIB@
-STRIP = @STRIP@
-UNWINDLIB = @UNWINDLIB@
-VERSION = @VERSION@
-YACC = @YACC@
-YFLAGS = @YFLAGS@
-abs_builddir = @abs_builddir@
-abs_srcdir = @abs_srcdir@
-abs_top_builddir = @abs_top_builddir@
-abs_top_srcdir = @abs_top_srcdir@
-ac_ct_AR = @ac_ct_AR@
-ac_ct_CC = @ac_ct_CC@
-ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
-aikgen_plugins = @aikgen_plugins@
-am__include = @am__include@
-am__leading_dot = @am__leading_dot@
-am__quote = @am__quote@
-am__tar = @am__tar@
-am__untar = @am__untar@
-attest_plugins = @attest_plugins@
-bindir = @bindir@
-build = @build@
-build_alias = @build_alias@
-build_cpu = @build_cpu@
-build_os = @build_os@
-build_vendor = @build_vendor@
-builddir = @builddir@
-c_plugins = @c_plugins@
-charon_natt_port = @charon_natt_port@
-charon_plugins = @charon_plugins@
-charon_udp_port = @charon_udp_port@
-clearsilver_LIBS = @clearsilver_LIBS@
-cmd_plugins = @cmd_plugins@
-datadir = @datadir@
-datarootdir = @datarootdir@
-dbusservicedir = @dbusservicedir@
-dev_headers = @dev_headers@
-docdir = @docdir@
-dvidir = @dvidir@
-exec_prefix = @exec_prefix@
-fips_mode = @fips_mode@
-gtk_CFLAGS = @gtk_CFLAGS@
-gtk_LIBS = @gtk_LIBS@
-h_plugins = @h_plugins@
-host = @host@
-host_alias = @host_alias@
-host_cpu = @host_cpu@
-host_os = @host_os@
-host_vendor = @host_vendor@
-htmldir = @htmldir@
-imcvdir = @imcvdir@
-includedir = @includedir@
-infodir = @infodir@
-install_sh = @install_sh@
-ipsec_script = @ipsec_script@
-ipsec_script_upper = @ipsec_script_upper@
-ipsecdir = @ipsecdir@
-ipsecgroup = @ipsecgroup@
-ipseclibdir = @ipseclibdir@
-ipsecuser = @ipsecuser@
-json_CFLAGS = @json_CFLAGS@
-json_LIBS = @json_LIBS@
-libdir = @libdir@
-libexecdir = @libexecdir@
-linux_headers = @linux_headers@
-localedir = @localedir@
-localstatedir = @localstatedir@
-maemo_CFLAGS = @maemo_CFLAGS@
-maemo_LIBS = @maemo_LIBS@
-manager_plugins = @manager_plugins@
-mandir = @mandir@
-medsrv_plugins = @medsrv_plugins@
-mkdir_p = @mkdir_p@
-nm_CFLAGS = @nm_CFLAGS@
-nm_LIBS = @nm_LIBS@
-nm_ca_dir = @nm_ca_dir@
-nm_plugins = @nm_plugins@
-oldincludedir = @oldincludedir@
-pcsclite_CFLAGS = @pcsclite_CFLAGS@
-pcsclite_LIBS = @pcsclite_LIBS@
-pdfdir = @pdfdir@
-piddir = @piddir@
-pkgpyexecdir = @pkgpyexecdir@
-pkgpythondir = @pkgpythondir@
-pki_plugins = @pki_plugins@
-plugindir = @plugindir@
-pool_plugins = @pool_plugins@
-prefix = @prefix@
-program_transform_name = @program_transform_name@
-psdir = @psdir@
-pyexecdir = @pyexecdir@
-pythondir = @pythondir@
-random_device = @random_device@
-resolv_conf = @resolv_conf@
-routing_table = @routing_table@
-routing_table_prio = @routing_table_prio@
-s_plugins = @s_plugins@
-sbindir = @sbindir@
-scepclient_plugins = @scepclient_plugins@
-scripts_plugins = @scripts_plugins@
-sharedstatedir = @sharedstatedir@
-soup_CFLAGS = @soup_CFLAGS@
-soup_LIBS = @soup_LIBS@
-srcdir = @srcdir@
-starter_plugins = @starter_plugins@
-strongswan_conf = @strongswan_conf@
-strongswan_options = @strongswan_options@
-swanctldir = @swanctldir@
-sysconfdir = @sysconfdir@
-systemd_daemon_CFLAGS = @systemd_daemon_CFLAGS@
-systemd_daemon_LIBS = @systemd_daemon_LIBS@
-systemd_journal_CFLAGS = @systemd_journal_CFLAGS@
-systemd_journal_LIBS = @systemd_journal_LIBS@
-systemdsystemunitdir = @systemdsystemunitdir@
-t_plugins = @t_plugins@
-target_alias = @target_alias@
-top_build_prefix = @top_build_prefix@
-top_builddir = @top_builddir@
-top_srcdir = @top_srcdir@
-urandom_device = @urandom_device@
-xml_CFLAGS = @xml_CFLAGS@
-xml_LIBS = @xml_LIBS@
-AM_CPPFLAGS = \
-	-I$(top_srcdir)/src/libstrongswan \
-	-I$(top_srcdir)/src/libhydra
-
-AM_CFLAGS = \
-	$(PLUGIN_CFLAGS)
-
- at MONOLITHIC_TRUE@noinst_LTLIBRARIES = libstrongswan-attr.la
- at MONOLITHIC_FALSE@plugin_LTLIBRARIES = libstrongswan-attr.la
-libstrongswan_attr_la_SOURCES = \
-	attr_plugin.h attr_plugin.c \
-	attr_provider.h attr_provider.c
-
-libstrongswan_attr_la_LDFLAGS = -module -avoid-version
-all: all-am
-
-.SUFFIXES:
-.SUFFIXES: .c .lo .o .obj
-$(srcdir)/Makefile.in:  $(srcdir)/Makefile.am  $(am__configure_deps)
-	@for dep in $?; do \
-	  case '$(am__configure_deps)' in \
-	    *$$dep*) \
-	      ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
-	        && { if test -f $@; then exit 0; else break; fi; }; \
-	      exit 1;; \
-	  esac; \
-	done; \
-	echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/libhydra/plugins/attr/Makefile'; \
-	$(am__cd) $(top_srcdir) && \
-	  $(AUTOMAKE) --gnu src/libhydra/plugins/attr/Makefile
-.PRECIOUS: Makefile
-Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
-	@case '$?' in \
-	  *config.status*) \
-	    cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
-	  *) \
-	    echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
-	    cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
-	esac;
-
-$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
-	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
-
-$(top_srcdir)/configure:  $(am__configure_deps)
-	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
-$(ACLOCAL_M4):  $(am__aclocal_m4_deps)
-	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
-$(am__aclocal_m4_deps):
-
-clean-noinstLTLIBRARIES:
-	-test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES)
-	@list='$(noinst_LTLIBRARIES)'; \
-	locs=`for p in $$list; do echo $$p; done | \
-	      sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \
-	      sort -u`; \
-	test -z "$$locs" || { \
-	  echo rm -f $${locs}; \
-	  rm -f $${locs}; \
-	}
-
-install-pluginLTLIBRARIES: $(plugin_LTLIBRARIES)
-	@$(NORMAL_INSTALL)
-	@list='$(plugin_LTLIBRARIES)'; test -n "$(plugindir)" || list=; \
-	list2=; for p in $$list; do \
-	  if test -f $$p; then \
-	    list2="$$list2 $$p"; \
-	  else :; fi; \
-	done; \
-	test -z "$$list2" || { \
-	  echo " $(MKDIR_P) '$(DESTDIR)$(plugindir)'"; \
-	  $(MKDIR_P) "$(DESTDIR)$(plugindir)" || exit 1; \
-	  echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(plugindir)'"; \
-	  $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(plugindir)"; \
-	}
-
-uninstall-pluginLTLIBRARIES:
-	@$(NORMAL_UNINSTALL)
-	@list='$(plugin_LTLIBRARIES)'; test -n "$(plugindir)" || list=; \
-	for p in $$list; do \
-	  $(am__strip_dir) \
-	  echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(plugindir)/$$f'"; \
-	  $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(plugindir)/$$f"; \
-	done
-
-clean-pluginLTLIBRARIES:
-	-test -z "$(plugin_LTLIBRARIES)" || rm -f $(plugin_LTLIBRARIES)
-	@list='$(plugin_LTLIBRARIES)'; \
-	locs=`for p in $$list; do echo $$p; done | \
-	      sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \
-	      sort -u`; \
-	test -z "$$locs" || { \
-	  echo rm -f $${locs}; \
-	  rm -f $${locs}; \
-	}
-
-libstrongswan-attr.la: $(libstrongswan_attr_la_OBJECTS) $(libstrongswan_attr_la_DEPENDENCIES) $(EXTRA_libstrongswan_attr_la_DEPENDENCIES) 
-	$(AM_V_CCLD)$(libstrongswan_attr_la_LINK) $(am_libstrongswan_attr_la_rpath) $(libstrongswan_attr_la_OBJECTS) $(libstrongswan_attr_la_LIBADD) $(LIBS)
-
-mostlyclean-compile:
-	-rm -f *.$(OBJEXT)
-
-distclean-compile:
-	-rm -f *.tab.c
-
- at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/attr_plugin.Plo at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/attr_provider.Plo at am__quote@
-
-.c.o:
- at am__fastdepCC_TRUE@	$(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\
- at am__fastdepCC_TRUE@	$(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\
- at am__fastdepCC_TRUE@	$(am__mv) $$depbase.Tpo $$depbase.Po
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(COMPILE) -c -o $@ $<
-
-.c.obj:
- at am__fastdepCC_TRUE@	$(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\
- at am__fastdepCC_TRUE@	$(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\
- at am__fastdepCC_TRUE@	$(am__mv) $$depbase.Tpo $$depbase.Po
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
-
-.c.lo:
- at am__fastdepCC_TRUE@	$(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\
- at am__fastdepCC_TRUE@	$(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\
- at am__fastdepCC_TRUE@	$(am__mv) $$depbase.Tpo $$depbase.Plo
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(LTCOMPILE) -c -o $@ $<
-
-mostlyclean-libtool:
-	-rm -f *.lo
-
-clean-libtool:
-	-rm -rf .libs _libs
-
-ID: $(am__tagged_files)
-	$(am__define_uniq_tagged_files); mkid -fID $$unique
-tags: tags-am
-TAGS: tags
-
-tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
-	set x; \
-	here=`pwd`; \
-	$(am__define_uniq_tagged_files); \
-	shift; \
-	if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
-	  test -n "$$unique" || unique=$$empty_fix; \
-	  if test $$# -gt 0; then \
-	    $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
-	      "$$@" $$unique; \
-	  else \
-	    $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
-	      $$unique; \
-	  fi; \
-	fi
-ctags: ctags-am
-
-CTAGS: ctags
-ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
-	$(am__define_uniq_tagged_files); \
-	test -z "$(CTAGS_ARGS)$$unique" \
-	  || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
-	     $$unique
-
-GTAGS:
-	here=`$(am__cd) $(top_builddir) && pwd` \
-	  && $(am__cd) $(top_srcdir) \
-	  && gtags -i $(GTAGS_ARGS) "$$here"
-cscopelist: cscopelist-am
-
-cscopelist-am: $(am__tagged_files)
-	list='$(am__tagged_files)'; \
-	case "$(srcdir)" in \
-	  [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
-	  *) sdir=$(subdir)/$(srcdir) ;; \
-	esac; \
-	for i in $$list; do \
-	  if test -f "$$i"; then \
-	    echo "$(subdir)/$$i"; \
-	  else \
-	    echo "$$sdir/$$i"; \
-	  fi; \
-	done >> $(top_builddir)/cscope.files
-
-distclean-tags:
-	-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
-
-distdir: $(DISTFILES)
-	@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
-	topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
-	list='$(DISTFILES)'; \
-	  dist_files=`for file in $$list; do echo $$file; done | \
-	  sed -e "s|^$$srcdirstrip/||;t" \
-	      -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
-	case $$dist_files in \
-	  */*) $(MKDIR_P) `echo "$$dist_files" | \
-			   sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
-			   sort -u` ;; \
-	esac; \
-	for file in $$dist_files; do \
-	  if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
-	  if test -d $$d/$$file; then \
-	    dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
-	    if test -d "$(distdir)/$$file"; then \
-	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
-	    fi; \
-	    if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
-	      cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
-	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
-	    fi; \
-	    cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
-	  else \
-	    test -f "$(distdir)/$$file" \
-	    || cp -p $$d/$$file "$(distdir)/$$file" \
-	    || exit 1; \
-	  fi; \
-	done
-check-am: all-am
-check: check-am
-all-am: Makefile $(LTLIBRARIES)
-installdirs:
-	for dir in "$(DESTDIR)$(plugindir)"; do \
-	  test -z "$$dir" || $(MKDIR_P) "$$dir"; \
-	done
-install: install-am
-install-exec: install-exec-am
-install-data: install-data-am
-uninstall: uninstall-am
-
-install-am: all-am
-	@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
-
-installcheck: installcheck-am
-install-strip:
-	if test -z '$(STRIP)'; then \
-	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
-	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
-	      install; \
-	else \
-	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
-	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
-	    "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
-	fi
-mostlyclean-generic:
-
-clean-generic:
-
-distclean-generic:
-	-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
-	-test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
-
-maintainer-clean-generic:
-	@echo "This command is intended for maintainers to use"
-	@echo "it deletes files that may require special tools to rebuild."
-clean: clean-am
-
-clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \
-	clean-pluginLTLIBRARIES mostlyclean-am
-
-distclean: distclean-am
-	-rm -rf ./$(DEPDIR)
-	-rm -f Makefile
-distclean-am: clean-am distclean-compile distclean-generic \
-	distclean-tags
-
-dvi: dvi-am
-
-dvi-am:
-
-html: html-am
-
-html-am:
-
-info: info-am
-
-info-am:
-
-install-data-am: install-pluginLTLIBRARIES
-
-install-dvi: install-dvi-am
-
-install-dvi-am:
-
-install-exec-am:
-
-install-html: install-html-am
-
-install-html-am:
-
-install-info: install-info-am
-
-install-info-am:
-
-install-man:
-
-install-pdf: install-pdf-am
-
-install-pdf-am:
-
-install-ps: install-ps-am
-
-install-ps-am:
-
-installcheck-am:
-
-maintainer-clean: maintainer-clean-am
-	-rm -rf ./$(DEPDIR)
-	-rm -f Makefile
-maintainer-clean-am: distclean-am maintainer-clean-generic
-
-mostlyclean: mostlyclean-am
-
-mostlyclean-am: mostlyclean-compile mostlyclean-generic \
-	mostlyclean-libtool
-
-pdf: pdf-am
-
-pdf-am:
-
-ps: ps-am
-
-ps-am:
-
-uninstall-am: uninstall-pluginLTLIBRARIES
-
-.MAKE: install-am install-strip
-
-.PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \
-	clean-libtool clean-noinstLTLIBRARIES clean-pluginLTLIBRARIES \
-	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-man install-pdf \
-	install-pdf-am install-pluginLTLIBRARIES install-ps \
-	install-ps-am install-strip installcheck installcheck-am \
-	installdirs maintainer-clean maintainer-clean-generic \
-	mostlyclean mostlyclean-compile mostlyclean-generic \
-	mostlyclean-libtool pdf pdf-am ps ps-am tags tags-am uninstall \
-	uninstall-am uninstall-pluginLTLIBRARIES
-
-
-# Tell versions [3.59,3.63) of GNU make to not export all variables.
-# Otherwise a system limit (for SysV at least) may be exceeded.
-.NOEXPORT:
diff --git a/src/libhydra/plugins/attr/attr_plugin.c b/src/libhydra/plugins/attr/attr_plugin.c
deleted file mode 100644
index 72fcd6d..0000000
--- a/src/libhydra/plugins/attr/attr_plugin.c
+++ /dev/null
@@ -1,109 +0,0 @@
-/*
- * Copyright (C) 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.
- */
-
-#include "attr_plugin.h"
-#include "attr_provider.h"
-
-#include <hydra.h>
-
-typedef struct private_attr_plugin_t private_attr_plugin_t;
-
-/**
- * private data of attr plugin
- */
-struct private_attr_plugin_t {
-
-	/**
-	 * implements plugin interface
-	 */
-	attr_plugin_t public;
-
-	/**
-	 * CFG attributes provider
-	 */
-	attr_provider_t *provider;
-};
-
-METHOD(plugin_t, get_name, char*,
-	private_attr_plugin_t *this)
-{
-	return "attr";
-}
-
-/**
- * Register provider
- */
-static bool plugin_cb(private_attr_plugin_t *this,
-					  plugin_feature_t *feature, bool reg, void *cb_data)
-{
-	if (reg)
-	{
-		hydra->attributes->add_provider(hydra->attributes,
-										&this->provider->provider);
-	}
-	else
-	{
-		hydra->attributes->remove_provider(hydra->attributes,
-										   &this->provider->provider);
-	}
-	return TRUE;
-}
-
-METHOD(plugin_t, get_features, int,
-	private_attr_plugin_t *this, plugin_feature_t *features[])
-{
-	static plugin_feature_t f[] = {
-		PLUGIN_CALLBACK((plugin_feature_callback_t)plugin_cb, NULL),
-			PLUGIN_PROVIDE(CUSTOM, "attr"),
-	};
-	*features = f;
-	return countof(f);
-}
-
-METHOD(plugin_t, reload, bool,
-	private_attr_plugin_t *this)
-{
-	this->provider->reload(this->provider);
-	return TRUE;
-}
-
-METHOD(plugin_t, destroy, void,
-	private_attr_plugin_t *this)
-{
-	this->provider->destroy(this->provider);
-	free(this);
-}
-
-/*
- * see header file
- */
-plugin_t *attr_plugin_create()
-{
-	private_attr_plugin_t *this;
-
-	INIT(this,
-		.public = {
-			.plugin = {
-				.get_name = _get_name,
-				.get_features = _get_features,
-				.reload = _reload,
-				.destroy = _destroy,
-			},
-		},
-		.provider = attr_provider_create(),
-	);
-
-	return &this->public.plugin;
-}
diff --git a/src/libhydra/plugins/attr/attr_plugin.h b/src/libhydra/plugins/attr/attr_plugin.h
deleted file mode 100644
index 29fb338..0000000
--- a/src/libhydra/plugins/attr/attr_plugin.h
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * Copyright (C) 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.
- */
-
-/**
- * @defgroup attr attr
- * @ingroup hplugins
- *
- * @defgroup attr_plugin attr_plugin
- * @{ @ingroup attr
- */
-
-#ifndef ATTR_PLUGIN_H_
-#define ATTR_PLUGIN_H_
-
-#include <plugins/plugin.h>
-
-typedef struct attr_plugin_t attr_plugin_t;
-
-/**
- * Plugin providing configuration attribute through strongswan.conf.
- */
-struct attr_plugin_t {
-
-	/**
-	 * implements plugin interface
-	 */
-	plugin_t plugin;
-};
-
-#endif /** ATTR_PLUGIN_H_ @}*/
diff --git a/src/libhydra/plugins/attr/attr_provider.c b/src/libhydra/plugins/attr/attr_provider.c
deleted file mode 100644
index c1788df..0000000
--- a/src/libhydra/plugins/attr/attr_provider.c
+++ /dev/null
@@ -1,329 +0,0 @@
-/*
- * Copyright (C) 2010 Tobias Brunner
- * Copyright (C) 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.
- */
-
-#include "attr_provider.h"
-
-#include <time.h>
-
-#include <hydra.h>
-#include <utils/debug.h>
-#include <collections/linked_list.h>
-#include <threading/rwlock.h>
-
-#define SERVER_MAX		2
-
-typedef struct private_attr_provider_t private_attr_provider_t;
-typedef struct attribute_entry_t attribute_entry_t;
-
-/**
- * private data of attr_provider
- */
-struct private_attr_provider_t {
-
-	/**
-	 * public functions
-	 */
-	attr_provider_t public;
-
-	/**
-	 * List of attributes, attribute_entry_t
-	 */
-	linked_list_t *attributes;
-
-	/**
-	 * Lock for attribute list
-	 */
-	rwlock_t *lock;
-};
-
-struct attribute_entry_t {
-	/** type of attribute */
-	configuration_attribute_type_t type;
-	/** attribute value */
-	chunk_t value;
-};
-
-/**
- * Destroy an entry
- */
-static void attribute_destroy(attribute_entry_t *this)
-{
-	free(this->value.ptr);
-	free(this);
-}
-
-/**
- * convert enumerator value from attribute_entry
- */
-static bool attr_enum_filter(void *null, attribute_entry_t **in,
-			configuration_attribute_type_t *type, void* none, chunk_t *value)
-{
-	*type = (*in)->type;
-	*value = (*in)->value;
-	return TRUE;
-}
-
-METHOD(attribute_provider_t, create_attribute_enumerator, enumerator_t*,
-	private_attr_provider_t *this, linked_list_t *pools,
-	identification_t *id, linked_list_t *vips)
-{
-	if (vips->get_count(vips))
-	{
-		this->lock->read_lock(this->lock);
-		return enumerator_create_filter(
-				this->attributes->create_enumerator(this->attributes),
-				(void*)attr_enum_filter, this->lock, (void*)this->lock->unlock);
-	}
-	return enumerator_create_empty();
-}
-
-METHOD(attr_provider_t, destroy, void,
-	private_attr_provider_t *this)
-{
-	this->attributes->destroy_function(this->attributes,
-									   (void*)attribute_destroy);
-	this->lock->destroy(this->lock);
-	free(this);
-}
-
-/**
- * Add an attribute entry to the list
- */
-static void add_legacy_entry(private_attr_provider_t *this, char *key, int nr,
-							 configuration_attribute_type_t type)
-{
-	attribute_entry_t *entry;
-	host_t *host;
-	char *str;
-
-	str = lib->settings->get_str(lib->settings, "%s.%s%d", NULL, lib->ns,
-								 key, nr);
-	if (str)
-	{
-		host = host_create_from_string(str, 0);
-		if (host)
-		{
-			entry = malloc_thing(attribute_entry_t);
-
-			if (host->get_family(host) == AF_INET6)
-			{
-				switch (type)
-				{
-					case INTERNAL_IP4_DNS:
-						type = INTERNAL_IP6_DNS;
-						break;
-					case INTERNAL_IP4_NBNS:
-						type = INTERNAL_IP6_NBNS;
-						break;
-					default:
-						break;
-				}
-			}
-			entry->type = type;
-			entry->value = chunk_clone(host->get_address(host));
-			host->destroy(host);
-			DBG2(DBG_CFG, "loaded legacy entry attribute %N: %#B",
-				 configuration_attribute_type_names, entry->type, &entry->value);
-			this->attributes->insert_last(this->attributes, entry);
-		}
-	}
-}
-
-/**
- * Key to attribute type mappings, for v4 and v6 attributes
- */
-typedef struct {
-	char *name;
-	configuration_attribute_type_t v4;
-	configuration_attribute_type_t v6;
-} attribute_type_key_t;
-
-static attribute_type_key_t keys[] = {
-	{"address",			INTERNAL_IP4_ADDRESS,	INTERNAL_IP6_ADDRESS},
-	{"dns",				INTERNAL_IP4_DNS,		INTERNAL_IP6_DNS},
-	{"nbns",			INTERNAL_IP4_NBNS,		INTERNAL_IP6_NBNS},
-	{"dhcp",			INTERNAL_IP4_DHCP,		INTERNAL_IP6_DHCP},
-	{"netmask",			INTERNAL_IP4_NETMASK,	INTERNAL_IP6_NETMASK},
-	{"server",			INTERNAL_IP4_SERVER,	INTERNAL_IP6_SERVER},
-	{"subnet",			INTERNAL_IP4_SUBNET,	INTERNAL_IP6_SUBNET},
-	{"split-include",	UNITY_SPLIT_INCLUDE,	UNITY_SPLIT_INCLUDE},
-	{"split-exclude",	UNITY_LOCAL_LAN,		UNITY_LOCAL_LAN},
-};
-
-/**
- * Load (numerical) entries from the plugins.attr namespace
- */
-static void load_entries(private_attr_provider_t *this)
-{
-	enumerator_t *enumerator, *tokens;
-	char *key, *value, *token;
-	int i;
-
-	for (i = 1; i <= SERVER_MAX; i++)
-	{
-		add_legacy_entry(this, "dns", i, INTERNAL_IP4_DNS);
-		add_legacy_entry(this, "nbns", i, INTERNAL_IP4_NBNS);
-	}
-
-	enumerator = lib->settings->create_key_value_enumerator(lib->settings,
-													"%s.plugins.attr", lib->ns);
-	while (enumerator->enumerate(enumerator, &key, &value))
-	{
-		configuration_attribute_type_t type;
-		attribute_type_key_t *mapped = NULL;
-		attribute_entry_t *entry;
-		chunk_t data;
-		host_t *host;
-		char *pos;
-		int i, mask = -1, family;
-
-		if (streq(key, "load"))
-		{
-			continue;
-		}
-		type = atoi(key);
-		if (!type)
-		{
-			for (i = 0; i < countof(keys); i++)
-			{
-				if (streq(key, keys[i].name))
-				{
-					mapped = &keys[i];
-					break;
-				}
-			}
-			if (!mapped)
-			{
-				DBG1(DBG_CFG, "mapping attribute type %s failed", key);
-				continue;
-			}
-		}
-		tokens = enumerator_create_token(value, ",", " ");
-		while (tokens->enumerate(tokens, &token))
-		{
-			pos = strchr(token, '/');
-			if (pos)
-			{
-				*(pos++) = '\0';
-				mask = atoi(pos);
-			}
-			host = host_create_from_string(token, 0);
-			if (!host)
-			{
-				if (mapped)
-				{
-					DBG1(DBG_CFG, "invalid host in key %s: %s", key, token);
-					continue;
-				}
-				/* store numeric attributes that are no IP addresses as strings */
-				data = chunk_clone(chunk_from_str(token));
-			}
-			else
-			{
-				family = host->get_family(host);
-				if (mask == -1)
-				{
-					data = chunk_clone(host->get_address(host));
-				}
-				else
-				{
-					if (family == AF_INET)
-					{	/* IPv4 attributes contain a subnet mask */
-						u_int32_t netmask = 0;
-
-						if (mask)
-						{	/* shifting u_int32_t by 32 or more is undefined */
-							mask = 32 - mask;
-							netmask = htonl((0xFFFFFFFF >> mask) << mask);
-						}
-						data = chunk_cat("cc", host->get_address(host),
-										 chunk_from_thing(netmask));
-					}
-					else
-					{	/* IPv6 addresses the prefix only */
-						data = chunk_cat("cc", host->get_address(host),
-										 chunk_from_chars(mask));
-					}
-				}
-				host->destroy(host);
-				if (mapped)
-				{
-					switch (family)
-					{
-						case AF_INET:
-							type = mapped->v4;
-							break;
-						case AF_INET6:
-							type = mapped->v6;
-							break;
-					}
-				}
-			}
-			INIT(entry,
-				.type = type,
-				.value = data,
-			);
-			DBG2(DBG_CFG, "loaded attribute %N: %#B",
-				 configuration_attribute_type_names, entry->type, &entry->value);
-			this->attributes->insert_last(this->attributes, entry);
-		}
-		tokens->destroy(tokens);
-	}
-	enumerator->destroy(enumerator);
-}
-
-METHOD(attr_provider_t, reload, void,
-	private_attr_provider_t *this)
-{
-	this->lock->write_lock(this->lock);
-
-	this->attributes->destroy_function(this->attributes, (void*)attribute_destroy);
-	this->attributes = linked_list_create();
-
-	load_entries(this);
-
-	DBG1(DBG_CFG, "loaded %d entr%s for attr plugin configuration",
-		 this->attributes->get_count(this->attributes),
-		 this->attributes->get_count(this->attributes) == 1 ? "y" : "ies");
-
-	this->lock->unlock(this->lock);
-}
-
-/*
- * see header file
- */
-attr_provider_t *attr_provider_create(database_t *db)
-{
-	private_attr_provider_t *this;
-
-	INIT(this,
-		.public = {
-			.provider = {
-				.acquire_address = (void*)return_null,
-				.release_address = (void*)return_false,
-				.create_attribute_enumerator = _create_attribute_enumerator,
-			},
-			.reload = _reload,
-			.destroy = _destroy,
-		},
-		.attributes = linked_list_create(),
-		.lock = rwlock_create(RWLOCK_TYPE_DEFAULT),
-	);
-
-	load_entries(this);
-
-	return &this->public;
-}
diff --git a/src/libhydra/plugins/attr_sql/Makefile.am b/src/libhydra/plugins/attr_sql/Makefile.am
deleted file mode 100644
index 6e7eae5..0000000
--- a/src/libhydra/plugins/attr_sql/Makefile.am
+++ /dev/null
@@ -1,18 +0,0 @@
-AM_CPPFLAGS = \
-	-I$(top_srcdir)/src/libstrongswan \
-	-I$(top_srcdir)/src/libhydra
-
-AM_CFLAGS = \
-	$(PLUGIN_CFLAGS)
-
-if MONOLITHIC
-noinst_LTLIBRARIES = libstrongswan-attr-sql.la
-else
-plugin_LTLIBRARIES = libstrongswan-attr-sql.la
-endif
-
-libstrongswan_attr_sql_la_SOURCES = \
-	attr_sql_plugin.h attr_sql_plugin.c \
-	sql_attribute.h sql_attribute.c
-
-libstrongswan_attr_sql_la_LDFLAGS = -module -avoid-version
diff --git a/src/libhydra/plugins/attr_sql/Makefile.in b/src/libhydra/plugins/attr_sql/Makefile.in
deleted file mode 100644
index 076e1f8..0000000
--- a/src/libhydra/plugins/attr_sql/Makefile.in
+++ /dev/null
@@ -1,774 +0,0 @@
-# Makefile.in generated by automake 1.14.1 from Makefile.am.
-# @configure_input@
-
-# Copyright (C) 1994-2013 Free Software Foundation, Inc.
-
-# This Makefile.in is free software; the Free Software Foundation
-# gives unlimited permission to copy and/or distribute it,
-# with or without modifications, as long as this notice is preserved.
-
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
-# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
-# PARTICULAR PURPOSE.
-
- at SET_MAKE@
-
-VPATH = @srcdir@
-am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)'
-am__make_running_with_option = \
-  case $${target_option-} in \
-      ?) ;; \
-      *) echo "am__make_running_with_option: internal error: invalid" \
-              "target option '$${target_option-}' specified" >&2; \
-         exit 1;; \
-  esac; \
-  has_opt=no; \
-  sane_makeflags=$$MAKEFLAGS; \
-  if $(am__is_gnu_make); then \
-    sane_makeflags=$$MFLAGS; \
-  else \
-    case $$MAKEFLAGS in \
-      *\\[\ \	]*) \
-        bs=\\; \
-        sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
-          | sed "s/$$bs$$bs[$$bs $$bs	]*//g"`;; \
-    esac; \
-  fi; \
-  skip_next=no; \
-  strip_trailopt () \
-  { \
-    flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
-  }; \
-  for flg in $$sane_makeflags; do \
-    test $$skip_next = yes && { skip_next=no; continue; }; \
-    case $$flg in \
-      *=*|--*) continue;; \
-        -*I) strip_trailopt 'I'; skip_next=yes;; \
-      -*I?*) strip_trailopt 'I';; \
-        -*O) strip_trailopt 'O'; skip_next=yes;; \
-      -*O?*) strip_trailopt 'O';; \
-        -*l) strip_trailopt 'l'; skip_next=yes;; \
-      -*l?*) strip_trailopt 'l';; \
-      -[dEDm]) skip_next=yes;; \
-      -[JT]) skip_next=yes;; \
-    esac; \
-    case $$flg in \
-      *$$target_option*) has_opt=yes; break;; \
-    esac; \
-  done; \
-  test $$has_opt = yes
-am__make_dryrun = (target_option=n; $(am__make_running_with_option))
-am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
-pkgdatadir = $(datadir)/@PACKAGE@
-pkgincludedir = $(includedir)/@PACKAGE@
-pkglibdir = $(libdir)/@PACKAGE@
-pkglibexecdir = $(libexecdir)/@PACKAGE@
-am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
-install_sh_DATA = $(install_sh) -c -m 644
-install_sh_PROGRAM = $(install_sh) -c
-install_sh_SCRIPT = $(install_sh) -c
-INSTALL_HEADER = $(INSTALL_DATA)
-transform = $(program_transform_name)
-NORMAL_INSTALL = :
-PRE_INSTALL = :
-POST_INSTALL = :
-NORMAL_UNINSTALL = :
-PRE_UNINSTALL = :
-POST_UNINSTALL = :
-build_triplet = @build@
-host_triplet = @host@
-subdir = src/libhydra/plugins/attr_sql
-DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
-	$(top_srcdir)/depcomp
-ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
-am__aclocal_m4_deps = $(top_srcdir)/m4/config/libtool.m4 \
-	$(top_srcdir)/m4/config/ltoptions.m4 \
-	$(top_srcdir)/m4/config/ltsugar.m4 \
-	$(top_srcdir)/m4/config/ltversion.m4 \
-	$(top_srcdir)/m4/config/lt~obsolete.m4 \
-	$(top_srcdir)/m4/macros/split-package-version.m4 \
-	$(top_srcdir)/m4/macros/with.m4 \
-	$(top_srcdir)/m4/macros/enable-disable.m4 \
-	$(top_srcdir)/m4/macros/add-plugin.m4 \
-	$(top_srcdir)/configure.ac
-am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
-	$(ACLOCAL_M4)
-mkinstalldirs = $(install_sh) -d
-CONFIG_HEADER = $(top_builddir)/config.h
-CONFIG_CLEAN_FILES =
-CONFIG_CLEAN_VPATH_FILES =
-am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
-am__vpath_adj = case $$p in \
-    $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
-    *) f=$$p;; \
-  esac;
-am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
-am__install_max = 40
-am__nobase_strip_setup = \
-  srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
-am__nobase_strip = \
-  for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
-am__nobase_list = $(am__nobase_strip_setup); \
-  for p in $$list; do echo "$$p $$p"; done | \
-  sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
-  $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
-    if (++n[$$2] == $(am__install_max)) \
-      { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
-    END { for (dir in files) print dir, files[dir] }'
-am__base_list = \
-  sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
-  sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
-am__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; }; \
-  }
-am__installdirs = "$(DESTDIR)$(plugindir)"
-LTLIBRARIES = $(noinst_LTLIBRARIES) $(plugin_LTLIBRARIES)
-libstrongswan_attr_sql_la_LIBADD =
-am_libstrongswan_attr_sql_la_OBJECTS = attr_sql_plugin.lo \
-	sql_attribute.lo
-libstrongswan_attr_sql_la_OBJECTS =  \
-	$(am_libstrongswan_attr_sql_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_attr_sql_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \
-	$(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \
-	$(AM_CFLAGS) $(CFLAGS) $(libstrongswan_attr_sql_la_LDFLAGS) \
-	$(LDFLAGS) -o $@
- at MONOLITHIC_FALSE@am_libstrongswan_attr_sql_la_rpath = -rpath \
- at MONOLITHIC_FALSE@	$(plugindir)
- at MONOLITHIC_TRUE@am_libstrongswan_attr_sql_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
-am__v_P_1 = :
-AM_V_GEN = $(am__v_GEN_ at AM_V@)
-am__v_GEN_ = $(am__v_GEN_ at AM_DEFAULT_V@)
-am__v_GEN_0 = @echo "  GEN     " $@;
-am__v_GEN_1 = 
-AM_V_at = $(am__v_at_ at AM_V@)
-am__v_at_ = $(am__v_at_ at AM_DEFAULT_V@)
-am__v_at_0 = @
-am__v_at_1 = 
-DEFAULT_INCLUDES = -I. at am__isrc@ -I$(top_builddir)
-depcomp = $(SHELL) $(top_srcdir)/depcomp
-am__depfiles_maybe = depfiles
-am__mv = mv -f
-COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
-	$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
-LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
-	$(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \
-	$(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
-	$(AM_CFLAGS) $(CFLAGS)
-AM_V_CC = $(am__v_CC_ at AM_V@)
-am__v_CC_ = $(am__v_CC_ at AM_DEFAULT_V@)
-am__v_CC_0 = @echo "  CC      " $@;
-am__v_CC_1 = 
-CCLD = $(CC)
-LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
-	$(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
-	$(AM_LDFLAGS) $(LDFLAGS) -o $@
-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_attr_sql_la_SOURCES)
-DIST_SOURCES = $(libstrongswan_attr_sql_la_SOURCES)
-am__can_run_installinfo = \
-  case $$AM_UPDATE_INFO_DIR in \
-    n|no|NO) false;; \
-    *) (install-info --version) >/dev/null 2>&1;; \
-  esac
-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
-# *not* preserved.
-am__uniquify_input = $(AWK) '\
-  BEGIN { nonempty = 0; } \
-  { items[$$0] = 1; nonempty = 1; } \
-  END { if (nonempty) { for (i in items) print i; }; } \
-'
-# Make sure the list of sources is unique.  This is necessary because,
-# e.g., the same source file might be shared among _SOURCES variables
-# for different programs/libraries.
-am__define_uniq_tagged_files = \
-  list='$(am__tagged_files)'; \
-  unique=`for i in $$list; do \
-    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
-  done | $(am__uniquify_input)`
-ETAGS = etags
-CTAGS = ctags
-DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
-ACLOCAL = @ACLOCAL@
-ALLOCA = @ALLOCA@
-AMTAR = @AMTAR@
-AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
-AR = @AR@
-AUTOCONF = @AUTOCONF@
-AUTOHEADER = @AUTOHEADER@
-AUTOMAKE = @AUTOMAKE@
-AWK = @AWK@
-BFDLIB = @BFDLIB@
-BTLIB = @BTLIB@
-CC = @CC@
-CCDEPMODE = @CCDEPMODE@
-CFLAGS = @CFLAGS@
-COVERAGE_CFLAGS = @COVERAGE_CFLAGS@
-COVERAGE_LDFLAGS = @COVERAGE_LDFLAGS@
-CPP = @CPP@
-CPPFLAGS = @CPPFLAGS@
-CYGPATH_W = @CYGPATH_W@
-DEFS = @DEFS@
-DEPDIR = @DEPDIR@
-DLLIB = @DLLIB@
-DLLTOOL = @DLLTOOL@
-DSYMUTIL = @DSYMUTIL@
-DUMPBIN = @DUMPBIN@
-ECHO_C = @ECHO_C@
-ECHO_N = @ECHO_N@
-ECHO_T = @ECHO_T@
-EGREP = @EGREP@
-EXEEXT = @EXEEXT@
-FGREP = @FGREP@
-GEM = @GEM@
-GENHTML = @GENHTML@
-GPERF = @GPERF@
-GPRBUILD = @GPRBUILD@
-GREP = @GREP@
-INSTALL = @INSTALL@
-INSTALL_DATA = @INSTALL_DATA@
-INSTALL_PROGRAM = @INSTALL_PROGRAM@
-INSTALL_SCRIPT = @INSTALL_SCRIPT@
-INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
-LCOV = @LCOV@
-LD = @LD@
-LDFLAGS = @LDFLAGS@
-LEX = @LEX@
-LEXLIB = @LEXLIB@
-LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@
-LIBOBJS = @LIBOBJS@
-LIBS = @LIBS@
-LIBTOOL = @LIBTOOL@
-LIPO = @LIPO@
-LN_S = @LN_S@
-LTLIBOBJS = @LTLIBOBJS@
-MAKEINFO = @MAKEINFO@
-MANIFEST_TOOL = @MANIFEST_TOOL@
-MKDIR_P = @MKDIR_P@
-MYSQLCFLAG = @MYSQLCFLAG@
-MYSQLCONFIG = @MYSQLCONFIG@
-MYSQLLIB = @MYSQLLIB@
-NM = @NM@
-NMEDIT = @NMEDIT@
-OBJDUMP = @OBJDUMP@
-OBJEXT = @OBJEXT@
-OPENSSL_LIB = @OPENSSL_LIB@
-OTOOL = @OTOOL@
-OTOOL64 = @OTOOL64@
-PACKAGE = @PACKAGE@
-PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
-PACKAGE_NAME = @PACKAGE_NAME@
-PACKAGE_STRING = @PACKAGE_STRING@
-PACKAGE_TARNAME = @PACKAGE_TARNAME@
-PACKAGE_URL = @PACKAGE_URL@
-PACKAGE_VERSION = @PACKAGE_VERSION@
-PACKAGE_VERSION_BUILD = @PACKAGE_VERSION_BUILD@
-PACKAGE_VERSION_MAJOR = @PACKAGE_VERSION_MAJOR@
-PACKAGE_VERSION_MINOR = @PACKAGE_VERSION_MINOR@
-PACKAGE_VERSION_REVIEW = @PACKAGE_VERSION_REVIEW@
-PATH_SEPARATOR = @PATH_SEPARATOR@
-PERL = @PERL@
-PKG_CONFIG = @PKG_CONFIG@
-PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
-PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
-PLUGIN_CFLAGS = @PLUGIN_CFLAGS@
-PTHREADLIB = @PTHREADLIB@
-PYTHON = @PYTHON@
-PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
-PYTHON_PLATFORM = @PYTHON_PLATFORM@
-PYTHON_PREFIX = @PYTHON_PREFIX@
-PYTHON_VERSION = @PYTHON_VERSION@
-RANLIB = @RANLIB@
-RTLIB = @RTLIB@
-RUBY = @RUBY@
-RUBYGEMDIR = @RUBYGEMDIR@
-RUBYINCLUDE = @RUBYINCLUDE@
-RUBYLIB = @RUBYLIB@
-SED = @SED@
-SET_MAKE = @SET_MAKE@
-SHELL = @SHELL@
-SOCKLIB = @SOCKLIB@
-STRIP = @STRIP@
-UNWINDLIB = @UNWINDLIB@
-VERSION = @VERSION@
-YACC = @YACC@
-YFLAGS = @YFLAGS@
-abs_builddir = @abs_builddir@
-abs_srcdir = @abs_srcdir@
-abs_top_builddir = @abs_top_builddir@
-abs_top_srcdir = @abs_top_srcdir@
-ac_ct_AR = @ac_ct_AR@
-ac_ct_CC = @ac_ct_CC@
-ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
-aikgen_plugins = @aikgen_plugins@
-am__include = @am__include@
-am__leading_dot = @am__leading_dot@
-am__quote = @am__quote@
-am__tar = @am__tar@
-am__untar = @am__untar@
-attest_plugins = @attest_plugins@
-bindir = @bindir@
-build = @build@
-build_alias = @build_alias@
-build_cpu = @build_cpu@
-build_os = @build_os@
-build_vendor = @build_vendor@
-builddir = @builddir@
-c_plugins = @c_plugins@
-charon_natt_port = @charon_natt_port@
-charon_plugins = @charon_plugins@
-charon_udp_port = @charon_udp_port@
-clearsilver_LIBS = @clearsilver_LIBS@
-cmd_plugins = @cmd_plugins@
-datadir = @datadir@
-datarootdir = @datarootdir@
-dbusservicedir = @dbusservicedir@
-dev_headers = @dev_headers@
-docdir = @docdir@
-dvidir = @dvidir@
-exec_prefix = @exec_prefix@
-fips_mode = @fips_mode@
-gtk_CFLAGS = @gtk_CFLAGS@
-gtk_LIBS = @gtk_LIBS@
-h_plugins = @h_plugins@
-host = @host@
-host_alias = @host_alias@
-host_cpu = @host_cpu@
-host_os = @host_os@
-host_vendor = @host_vendor@
-htmldir = @htmldir@
-imcvdir = @imcvdir@
-includedir = @includedir@
-infodir = @infodir@
-install_sh = @install_sh@
-ipsec_script = @ipsec_script@
-ipsec_script_upper = @ipsec_script_upper@
-ipsecdir = @ipsecdir@
-ipsecgroup = @ipsecgroup@
-ipseclibdir = @ipseclibdir@
-ipsecuser = @ipsecuser@
-json_CFLAGS = @json_CFLAGS@
-json_LIBS = @json_LIBS@
-libdir = @libdir@
-libexecdir = @libexecdir@
-linux_headers = @linux_headers@
-localedir = @localedir@
-localstatedir = @localstatedir@
-maemo_CFLAGS = @maemo_CFLAGS@
-maemo_LIBS = @maemo_LIBS@
-manager_plugins = @manager_plugins@
-mandir = @mandir@
-medsrv_plugins = @medsrv_plugins@
-mkdir_p = @mkdir_p@
-nm_CFLAGS = @nm_CFLAGS@
-nm_LIBS = @nm_LIBS@
-nm_ca_dir = @nm_ca_dir@
-nm_plugins = @nm_plugins@
-oldincludedir = @oldincludedir@
-pcsclite_CFLAGS = @pcsclite_CFLAGS@
-pcsclite_LIBS = @pcsclite_LIBS@
-pdfdir = @pdfdir@
-piddir = @piddir@
-pkgpyexecdir = @pkgpyexecdir@
-pkgpythondir = @pkgpythondir@
-pki_plugins = @pki_plugins@
-plugindir = @plugindir@
-pool_plugins = @pool_plugins@
-prefix = @prefix@
-program_transform_name = @program_transform_name@
-psdir = @psdir@
-pyexecdir = @pyexecdir@
-pythondir = @pythondir@
-random_device = @random_device@
-resolv_conf = @resolv_conf@
-routing_table = @routing_table@
-routing_table_prio = @routing_table_prio@
-s_plugins = @s_plugins@
-sbindir = @sbindir@
-scepclient_plugins = @scepclient_plugins@
-scripts_plugins = @scripts_plugins@
-sharedstatedir = @sharedstatedir@
-soup_CFLAGS = @soup_CFLAGS@
-soup_LIBS = @soup_LIBS@
-srcdir = @srcdir@
-starter_plugins = @starter_plugins@
-strongswan_conf = @strongswan_conf@
-strongswan_options = @strongswan_options@
-swanctldir = @swanctldir@
-sysconfdir = @sysconfdir@
-systemd_daemon_CFLAGS = @systemd_daemon_CFLAGS@
-systemd_daemon_LIBS = @systemd_daemon_LIBS@
-systemd_journal_CFLAGS = @systemd_journal_CFLAGS@
-systemd_journal_LIBS = @systemd_journal_LIBS@
-systemdsystemunitdir = @systemdsystemunitdir@
-t_plugins = @t_plugins@
-target_alias = @target_alias@
-top_build_prefix = @top_build_prefix@
-top_builddir = @top_builddir@
-top_srcdir = @top_srcdir@
-urandom_device = @urandom_device@
-xml_CFLAGS = @xml_CFLAGS@
-xml_LIBS = @xml_LIBS@
-AM_CPPFLAGS = \
-	-I$(top_srcdir)/src/libstrongswan \
-	-I$(top_srcdir)/src/libhydra
-
-AM_CFLAGS = \
-	$(PLUGIN_CFLAGS)
-
- at MONOLITHIC_TRUE@noinst_LTLIBRARIES = libstrongswan-attr-sql.la
- at MONOLITHIC_FALSE@plugin_LTLIBRARIES = libstrongswan-attr-sql.la
-libstrongswan_attr_sql_la_SOURCES = \
-	attr_sql_plugin.h attr_sql_plugin.c \
-	sql_attribute.h sql_attribute.c
-
-libstrongswan_attr_sql_la_LDFLAGS = -module -avoid-version
-all: all-am
-
-.SUFFIXES:
-.SUFFIXES: .c .lo .o .obj
-$(srcdir)/Makefile.in:  $(srcdir)/Makefile.am  $(am__configure_deps)
-	@for dep in $?; do \
-	  case '$(am__configure_deps)' in \
-	    *$$dep*) \
-	      ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
-	        && { if test -f $@; then exit 0; else break; fi; }; \
-	      exit 1;; \
-	  esac; \
-	done; \
-	echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/libhydra/plugins/attr_sql/Makefile'; \
-	$(am__cd) $(top_srcdir) && \
-	  $(AUTOMAKE) --gnu src/libhydra/plugins/attr_sql/Makefile
-.PRECIOUS: Makefile
-Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
-	@case '$?' in \
-	  *config.status*) \
-	    cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
-	  *) \
-	    echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
-	    cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
-	esac;
-
-$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
-	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
-
-$(top_srcdir)/configure:  $(am__configure_deps)
-	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
-$(ACLOCAL_M4):  $(am__aclocal_m4_deps)
-	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
-$(am__aclocal_m4_deps):
-
-clean-noinstLTLIBRARIES:
-	-test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES)
-	@list='$(noinst_LTLIBRARIES)'; \
-	locs=`for p in $$list; do echo $$p; done | \
-	      sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \
-	      sort -u`; \
-	test -z "$$locs" || { \
-	  echo rm -f $${locs}; \
-	  rm -f $${locs}; \
-	}
-
-install-pluginLTLIBRARIES: $(plugin_LTLIBRARIES)
-	@$(NORMAL_INSTALL)
-	@list='$(plugin_LTLIBRARIES)'; test -n "$(plugindir)" || list=; \
-	list2=; for p in $$list; do \
-	  if test -f $$p; then \
-	    list2="$$list2 $$p"; \
-	  else :; fi; \
-	done; \
-	test -z "$$list2" || { \
-	  echo " $(MKDIR_P) '$(DESTDIR)$(plugindir)'"; \
-	  $(MKDIR_P) "$(DESTDIR)$(plugindir)" || exit 1; \
-	  echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(plugindir)'"; \
-	  $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(plugindir)"; \
-	}
-
-uninstall-pluginLTLIBRARIES:
-	@$(NORMAL_UNINSTALL)
-	@list='$(plugin_LTLIBRARIES)'; test -n "$(plugindir)" || list=; \
-	for p in $$list; do \
-	  $(am__strip_dir) \
-	  echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(plugindir)/$$f'"; \
-	  $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(plugindir)/$$f"; \
-	done
-
-clean-pluginLTLIBRARIES:
-	-test -z "$(plugin_LTLIBRARIES)" || rm -f $(plugin_LTLIBRARIES)
-	@list='$(plugin_LTLIBRARIES)'; \
-	locs=`for p in $$list; do echo $$p; done | \
-	      sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \
-	      sort -u`; \
-	test -z "$$locs" || { \
-	  echo rm -f $${locs}; \
-	  rm -f $${locs}; \
-	}
-
-libstrongswan-attr-sql.la: $(libstrongswan_attr_sql_la_OBJECTS) $(libstrongswan_attr_sql_la_DEPENDENCIES) $(EXTRA_libstrongswan_attr_sql_la_DEPENDENCIES) 
-	$(AM_V_CCLD)$(libstrongswan_attr_sql_la_LINK) $(am_libstrongswan_attr_sql_la_rpath) $(libstrongswan_attr_sql_la_OBJECTS) $(libstrongswan_attr_sql_la_LIBADD) $(LIBS)
-
-mostlyclean-compile:
-	-rm -f *.$(OBJEXT)
-
-distclean-compile:
-	-rm -f *.tab.c
-
- at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/attr_sql_plugin.Plo at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/sql_attribute.Plo at am__quote@
-
-.c.o:
- at am__fastdepCC_TRUE@	$(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\
- at am__fastdepCC_TRUE@	$(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\
- at am__fastdepCC_TRUE@	$(am__mv) $$depbase.Tpo $$depbase.Po
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(COMPILE) -c -o $@ $<
-
-.c.obj:
- at am__fastdepCC_TRUE@	$(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\
- at am__fastdepCC_TRUE@	$(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\
- at am__fastdepCC_TRUE@	$(am__mv) $$depbase.Tpo $$depbase.Po
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
-
-.c.lo:
- at am__fastdepCC_TRUE@	$(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\
- at am__fastdepCC_TRUE@	$(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\
- at am__fastdepCC_TRUE@	$(am__mv) $$depbase.Tpo $$depbase.Plo
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(LTCOMPILE) -c -o $@ $<
-
-mostlyclean-libtool:
-	-rm -f *.lo
-
-clean-libtool:
-	-rm -rf .libs _libs
-
-ID: $(am__tagged_files)
-	$(am__define_uniq_tagged_files); mkid -fID $$unique
-tags: tags-am
-TAGS: tags
-
-tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
-	set x; \
-	here=`pwd`; \
-	$(am__define_uniq_tagged_files); \
-	shift; \
-	if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
-	  test -n "$$unique" || unique=$$empty_fix; \
-	  if test $$# -gt 0; then \
-	    $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
-	      "$$@" $$unique; \
-	  else \
-	    $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
-	      $$unique; \
-	  fi; \
-	fi
-ctags: ctags-am
-
-CTAGS: ctags
-ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
-	$(am__define_uniq_tagged_files); \
-	test -z "$(CTAGS_ARGS)$$unique" \
-	  || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
-	     $$unique
-
-GTAGS:
-	here=`$(am__cd) $(top_builddir) && pwd` \
-	  && $(am__cd) $(top_srcdir) \
-	  && gtags -i $(GTAGS_ARGS) "$$here"
-cscopelist: cscopelist-am
-
-cscopelist-am: $(am__tagged_files)
-	list='$(am__tagged_files)'; \
-	case "$(srcdir)" in \
-	  [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
-	  *) sdir=$(subdir)/$(srcdir) ;; \
-	esac; \
-	for i in $$list; do \
-	  if test -f "$$i"; then \
-	    echo "$(subdir)/$$i"; \
-	  else \
-	    echo "$$sdir/$$i"; \
-	  fi; \
-	done >> $(top_builddir)/cscope.files
-
-distclean-tags:
-	-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
-
-distdir: $(DISTFILES)
-	@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
-	topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
-	list='$(DISTFILES)'; \
-	  dist_files=`for file in $$list; do echo $$file; done | \
-	  sed -e "s|^$$srcdirstrip/||;t" \
-	      -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
-	case $$dist_files in \
-	  */*) $(MKDIR_P) `echo "$$dist_files" | \
-			   sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
-			   sort -u` ;; \
-	esac; \
-	for file in $$dist_files; do \
-	  if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
-	  if test -d $$d/$$file; then \
-	    dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
-	    if test -d "$(distdir)/$$file"; then \
-	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
-	    fi; \
-	    if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
-	      cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
-	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
-	    fi; \
-	    cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
-	  else \
-	    test -f "$(distdir)/$$file" \
-	    || cp -p $$d/$$file "$(distdir)/$$file" \
-	    || exit 1; \
-	  fi; \
-	done
-check-am: all-am
-check: check-am
-all-am: Makefile $(LTLIBRARIES)
-installdirs:
-	for dir in "$(DESTDIR)$(plugindir)"; do \
-	  test -z "$$dir" || $(MKDIR_P) "$$dir"; \
-	done
-install: install-am
-install-exec: install-exec-am
-install-data: install-data-am
-uninstall: uninstall-am
-
-install-am: all-am
-	@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
-
-installcheck: installcheck-am
-install-strip:
-	if test -z '$(STRIP)'; then \
-	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
-	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
-	      install; \
-	else \
-	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
-	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
-	    "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
-	fi
-mostlyclean-generic:
-
-clean-generic:
-
-distclean-generic:
-	-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
-	-test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
-
-maintainer-clean-generic:
-	@echo "This command is intended for maintainers to use"
-	@echo "it deletes files that may require special tools to rebuild."
-clean: clean-am
-
-clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \
-	clean-pluginLTLIBRARIES mostlyclean-am
-
-distclean: distclean-am
-	-rm -rf ./$(DEPDIR)
-	-rm -f Makefile
-distclean-am: clean-am distclean-compile distclean-generic \
-	distclean-tags
-
-dvi: dvi-am
-
-dvi-am:
-
-html: html-am
-
-html-am:
-
-info: info-am
-
-info-am:
-
-install-data-am: install-pluginLTLIBRARIES
-
-install-dvi: install-dvi-am
-
-install-dvi-am:
-
-install-exec-am:
-
-install-html: install-html-am
-
-install-html-am:
-
-install-info: install-info-am
-
-install-info-am:
-
-install-man:
-
-install-pdf: install-pdf-am
-
-install-pdf-am:
-
-install-ps: install-ps-am
-
-install-ps-am:
-
-installcheck-am:
-
-maintainer-clean: maintainer-clean-am
-	-rm -rf ./$(DEPDIR)
-	-rm -f Makefile
-maintainer-clean-am: distclean-am maintainer-clean-generic
-
-mostlyclean: mostlyclean-am
-
-mostlyclean-am: mostlyclean-compile mostlyclean-generic \
-	mostlyclean-libtool
-
-pdf: pdf-am
-
-pdf-am:
-
-ps: ps-am
-
-ps-am:
-
-uninstall-am: uninstall-pluginLTLIBRARIES
-
-.MAKE: install-am install-strip
-
-.PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \
-	clean-libtool clean-noinstLTLIBRARIES clean-pluginLTLIBRARIES \
-	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-man install-pdf \
-	install-pdf-am install-pluginLTLIBRARIES install-ps \
-	install-ps-am install-strip installcheck installcheck-am \
-	installdirs maintainer-clean maintainer-clean-generic \
-	mostlyclean mostlyclean-compile mostlyclean-generic \
-	mostlyclean-libtool pdf pdf-am ps ps-am tags tags-am uninstall \
-	uninstall-am uninstall-pluginLTLIBRARIES
-
-
-# Tell versions [3.59,3.63) of GNU make to not export all variables.
-# Otherwise a system limit (for SysV at least) may be exceeded.
-.NOEXPORT:
diff --git a/src/libhydra/plugins/attr_sql/attr_sql_plugin.c b/src/libhydra/plugins/attr_sql/attr_sql_plugin.c
deleted file mode 100644
index dde9005..0000000
--- a/src/libhydra/plugins/attr_sql/attr_sql_plugin.c
+++ /dev/null
@@ -1,129 +0,0 @@
-/*
- * Copyright (C) 2013 Tobias Brunner
- * Copyright (C) 2008 Martin Willi
- * Hochschule fuer Technik Rapperswil
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * for more details.
- */
-
-#include <hydra.h>
-#include <utils/debug.h>
-#include <plugins/plugin_feature.h>
-
-#include "attr_sql_plugin.h"
-#include "sql_attribute.h"
-
-typedef struct private_attr_sql_plugin_t private_attr_sql_plugin_t;
-
-/**
- * private data of attr_sql plugin
- */
-struct private_attr_sql_plugin_t {
-
-	/**
-	 * implements plugin interface
-	 */
-	attr_sql_plugin_t public;
-
-	/**
-	 * database connection instance
-	 */
-	database_t *db;
-
-	/**
-	 * configuration attributes
-	 */
-	sql_attribute_t *attribute;
-};
-
-METHOD(plugin_t, get_name, char*,
-	private_attr_sql_plugin_t *this)
-{
-	return "attr-sql";
-}
-
-/**
- * Connect to database
- */
-static bool open_database(private_attr_sql_plugin_t *this,
-						  plugin_feature_t *feature, bool reg, void *cb_data)
-{
-	if (reg)
-	{
-		char *uri;
-
-		uri = lib->settings->get_str(lib->settings,
-								"%s.plugins.attr-sql.database", NULL, lib->ns);
-		if (!uri)
-		{
-			DBG1(DBG_CFG, "attr-sql plugin: database URI not set");
-			return FALSE;
-		}
-
-		this->db = lib->db->create(lib->db, uri);
-		if (!this->db)
-		{
-			DBG1(DBG_CFG, "attr-sql plugin failed to connect to database");
-			return FALSE;
-		}
-		this->attribute = sql_attribute_create(this->db);
-		hydra->attributes->add_provider(hydra->attributes,
-										&this->attribute->provider);
-	}
-	else
-	{
-		hydra->attributes->remove_provider(hydra->attributes,
-										   &this->attribute->provider);
-		this->attribute->destroy(this->attribute);
-		this->db->destroy(this->db);
-	}
-	return TRUE;
-}
-
-METHOD(plugin_t, get_features, int,
-	private_attr_sql_plugin_t *this, plugin_feature_t *features[])
-{
-	static plugin_feature_t f[] = {
-		PLUGIN_CALLBACK((plugin_feature_callback_t)open_database, NULL),
-			PLUGIN_PROVIDE(CUSTOM, "attr-sql"),
-				PLUGIN_DEPENDS(DATABASE, DB_ANY),
-	};
-	*features = f;
-	return countof(f);
-}
-
-METHOD(plugin_t, destroy, void,
-	private_attr_sql_plugin_t *this)
-{
-	free(this);
-}
-
-/*
- * see header file
- */
-plugin_t *attr_sql_plugin_create()
-{
-	private_attr_sql_plugin_t *this;
-
-	INIT(this,
-		.public = {
-			.plugin = {
-				.get_name = _get_name,
-				.get_features = _get_features,
-				.destroy = _destroy,
-			},
-		},
-	);
-	lib->settings->add_fallback(lib->settings, "%s.plugins.attr-sql",
-								"libhydra.plugins.attr-sql", lib->ns);
-
-	return &this->public.plugin;
-}
diff --git a/src/libhydra/plugins/attr_sql/attr_sql_plugin.h b/src/libhydra/plugins/attr_sql/attr_sql_plugin.h
deleted file mode 100644
index ba85a6b..0000000
--- a/src/libhydra/plugins/attr_sql/attr_sql_plugin.h
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * Copyright (C) 2008 Martin Willi
- * Hochschule fuer Technik Rapperswil
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * for more details.
- */
-
-/**
- * @defgroup attr_sql attr_sql
- * @ingroup hplugins
- *
- * @defgroup sql_plugin sql_plugin
- * @{ @ingroup attr_sql
- */
-
-#ifndef ATTR_SQL_PLUGIN_H_
-#define ATTR_SQL_PLUGIN_H_
-
-#include <plugins/plugin.h>
-
-typedef struct attr_sql_plugin_t attr_sql_plugin_t;
-
-/**
- * SQL database attribute configuration plugin
- */
-struct attr_sql_plugin_t {
-
-	/**
-	 * implements plugin interface
-	 */
-	plugin_t plugin;
-};
-
-#endif /** ATTR_SQL_PLUGIN_H_ @}*/
diff --git a/src/libhydra/plugins/attr_sql/sql_attribute.c b/src/libhydra/plugins/attr_sql/sql_attribute.c
deleted file mode 100644
index d527c3f..0000000
--- a/src/libhydra/plugins/attr_sql/sql_attribute.c
+++ /dev/null
@@ -1,475 +0,0 @@
-/*
- * Copyright (C) 2008 Martin Willi
- * Hochschule fuer Technik Rapperswil
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * for more details.
- */
-
-#include <time.h>
-
-#include <utils/debug.h>
-#include <library.h>
-
-#include "sql_attribute.h"
-
-typedef struct private_sql_attribute_t private_sql_attribute_t;
-
-/**
- * private data of sql_attribute
- */
-struct private_sql_attribute_t {
-
-	/**
-	 * public functions
-	 */
-	sql_attribute_t public;
-
-	/**
-	 * database connection
-	 */
-	database_t *db;
-
-	/**
-	 * whether to record lease history in lease table
-	 */
-	bool history;
-};
-
-/**
- * lookup/insert an identity
- */
-static u_int get_identity(private_sql_attribute_t *this, identification_t *id)
-{
-	enumerator_t *e;
-	u_int row;
-
-	this->db->transaction(this->db, TRUE);
-	/* look for peer identity in the identities table */
-	e = this->db->query(this->db,
-						"SELECT id FROM identities WHERE type = ? AND data = ?",
-						DB_INT, id->get_type(id), DB_BLOB, id->get_encoding(id),
-						DB_UINT);
-	if (e && e->enumerate(e, &row))
-	{
-		e->destroy(e);
-		this->db->commit(this->db);
-		return row;
-	}
-	DESTROY_IF(e);
-	/* not found, insert new one */
-	if (this->db->execute(this->db, &row,
-				  "INSERT INTO identities (type, data) VALUES (?, ?)",
-				  DB_INT, id->get_type(id), DB_BLOB, id->get_encoding(id)) == 1)
-	{
-		this->db->commit(this->db);
-		return row;
-	}
-	this->db->rollback(this->db);
-	return 0;
-}
-
-/**
- * Lookup an attribute pool by name
- */
-static u_int get_attr_pool(private_sql_attribute_t *this, char *name)
-{
-	enumerator_t *e;
-	u_int row = 0;
-
-	e = this->db->query(this->db,
-						"SELECT id FROM attribute_pools WHERE name = ?",
-						DB_TEXT, name, DB_UINT);
-	if (e)
-	{
-		e->enumerate(e, &row);
-	}
-	DESTROY_IF(e);
-
-	return row;
-}
-
-/**
- * Lookup pool by name and address family
- */
-static u_int get_pool(private_sql_attribute_t *this, char *name, int family,
-					  u_int *timeout)
-{
-	enumerator_t *e;
-	chunk_t start;
-	u_int pool;
-
-	e = this->db->query(this->db,
-						"SELECT id, start, timeout FROM pools WHERE name = ?",
-						DB_TEXT, name, DB_UINT, DB_BLOB, DB_UINT);
-	if (e && e->enumerate(e, &pool, &start, timeout))
-	{
-		if ((family == AF_INET  && start.len == 4) ||
-			(family == AF_INET6 && start.len == 16))
-		{
-			e->destroy(e);
-			return pool;
-		}
-	}
-	DESTROY_IF(e);
-	return 0;
-}
-
-/**
- * Look up an existing lease
- */
-static host_t* check_lease(private_sql_attribute_t *this, char *name,
-						   u_int pool, u_int identity)
-{
-	while (TRUE)
-	{
-		u_int id;
-		chunk_t address;
-		enumerator_t *e;
-		time_t now = time(NULL);
-
-		e = this->db->query(this->db,
-				"SELECT id, address FROM addresses "
-				"WHERE pool = ? AND identity = ? AND released != 0 LIMIT 1",
-				DB_UINT, pool, DB_UINT, identity, DB_UINT, DB_BLOB);
-		if (!e || !e->enumerate(e, &id, &address))
-		{
-			DESTROY_IF(e);
-			break;
-		}
-		address = chunk_clonea(address);
-		e->destroy(e);
-
-		if (this->db->execute(this->db, NULL,
-				"UPDATE addresses SET acquired = ?, released = 0 "
-				"WHERE id = ? AND identity = ? AND released != 0",
-				DB_UINT, now, DB_UINT, id, DB_UINT, identity) > 0)
-		{
-			host_t *host;
-
-			host = host_create_from_chunk(AF_UNSPEC, address, 0);
-			if (host)
-			{
-				DBG1(DBG_CFG, "acquired existing lease for address %H in"
-					 " pool '%s'", host, name);
-				return host;
-			}
-		}
-	}
-	return NULL;
-}
-
-/**
- * We check for unallocated addresses or expired leases. First we select an
- * address as a candidate, but double check later on if it is still available
- * during the update operation. This allows us to work without locking.
- */
-static host_t* get_lease(private_sql_attribute_t *this, char *name,
-						 u_int pool, u_int timeout, u_int identity)
-{
-	while (TRUE)
-	{
-		u_int id;
-		chunk_t address;
-		enumerator_t *e;
-		time_t now = time(NULL);
-		int hits;
-
-		if (timeout)
-		{
-			/* check for an expired lease */
-			e = this->db->query(this->db,
-				"SELECT id, address FROM addresses "
-				"WHERE pool = ? AND released != 0 AND released < ? LIMIT 1",
-				DB_UINT, pool, DB_UINT, now - timeout, DB_UINT, DB_BLOB);
-		}
-		else
-		{
-			/* with static leases, check for an unallocated address */
-			e = this->db->query(this->db,
-				"SELECT id, address FROM addresses "
-				"WHERE pool = ? AND identity = 0 LIMIT 1",
-				DB_UINT, pool, DB_UINT, DB_BLOB);
-
-		}
-
-		if (!e || !e->enumerate(e, &id, &address))
-		{
-			DESTROY_IF(e);
-			break;
-		}
-		address = chunk_clonea(address);
-		e->destroy(e);
-
-		if (timeout)
-		{
-			hits = this->db->execute(this->db, NULL,
-						"UPDATE addresses SET "
-						"acquired = ?, released = 0, identity = ? "
-						"WHERE id = ? AND released != 0 AND released < ?",
-						DB_UINT, now, DB_UINT, identity,
-						DB_UINT, id, DB_UINT, now - timeout);
-		}
-		else
-		{
-			hits = this->db->execute(this->db, NULL,
-						"UPDATE addresses SET "
-						"acquired = ?, released = 0, identity = ? "
-						"WHERE id = ? AND identity = 0",
-						DB_UINT, now, DB_UINT, identity, DB_UINT, id);
-		}
-		if (hits > 0)
-		{
-			host_t *host;
-
-			host = host_create_from_chunk(AF_UNSPEC, address, 0);
-			if (host)
-			{
-				DBG1(DBG_CFG, "acquired new lease for address %H in pool '%s'",
-					 host, name);
-				return host;
-			}
-		}
-	}
-	DBG1(DBG_CFG, "no available address found in pool '%s'", name);
-	return NULL;
-}
-
-METHOD(attribute_provider_t, acquire_address, host_t*,
-	private_sql_attribute_t *this, linked_list_t *pools, identification_t *id,
-	host_t *requested)
-{
-	enumerator_t *enumerator;
-	host_t *address = NULL;
-	u_int identity, pool, timeout;
-	char *name;
-	int family;
-
-	identity = get_identity(this, id);
-	if (identity)
-	{
-		family = requested->get_family(requested);
-		/* check for an existing lease in all pools */
-		enumerator = pools->create_enumerator(pools);
-		while (enumerator->enumerate(enumerator, &name))
-		{
-			pool = get_pool(this, name, family, &timeout);
-			if (pool)
-			{
-				address = check_lease(this, name, pool, identity);
-				if (address)
-				{
-					break;
-				}
-			}
-		}
-		enumerator->destroy(enumerator);
-
-		if (!address)
-		{
-			/* get an unallocated address or expired lease */
-			enumerator = pools->create_enumerator(pools);
-			while (enumerator->enumerate(enumerator, &name))
-			{
-				pool = get_pool(this, name, family, &timeout);
-				if (pool)
-				{
-					address = get_lease(this, name, pool, timeout, identity);
-					if (address)
-					{
-						break;
-					}
-				}
-			}
-			enumerator->destroy(enumerator);
-		}
-	}
-	return address;
-}
-
-METHOD(attribute_provider_t, release_address, bool,
-	private_sql_attribute_t *this, linked_list_t *pools, host_t *address,
-	identification_t *id)
-{
-	enumerator_t *enumerator;
-	u_int pool, timeout;
-	time_t now = time(NULL);
-	bool found = FALSE;
-	char *name;
-	int family;
-
-	family = address->get_family(address);
-	enumerator = pools->create_enumerator(pools);
-	while (enumerator->enumerate(enumerator, &name))
-	{
-		pool = get_pool(this, name, family, &timeout);
-		if (!pool)
-		{
-			continue;
-		}
-		if (this->db->execute(this->db, NULL,
-				"UPDATE addresses SET released = ? WHERE "
-				"pool = ? AND address = ?", DB_UINT, time(NULL),
-				DB_UINT, pool, DB_BLOB, address->get_address(address)) > 0)
-		{
-			if (this->history)
-			{
-				this->db->execute(this->db, NULL,
-					"INSERT INTO leases (address, identity, acquired, released)"
-					" SELECT id, identity, acquired, ? FROM addresses "
-					" WHERE pool = ? AND address = ?",
-					DB_UINT, now, DB_UINT, pool,
-					DB_BLOB, address->get_address(address));
-			}
-			found = TRUE;
-			break;
-		}
-	}
-	enumerator->destroy(enumerator);
-
-	return found;
-}
-
-METHOD(attribute_provider_t, create_attribute_enumerator, enumerator_t*,
-	private_sql_attribute_t *this, linked_list_t *pools, identification_t *id,
-	linked_list_t *vips)
-{
-	enumerator_t *attr_enumerator = NULL;
-
-	if (vips->get_count(vips))
-	{
-		enumerator_t *pool_enumerator;
-		u_int count;
-		char *name;
-
-		/* in a first step check for attributes that match name and id */
-		if (id)
-		{
-			u_int identity = get_identity(this, id);
-
-			pool_enumerator = pools->create_enumerator(pools);
-			while (pool_enumerator->enumerate(pool_enumerator, &name))
-			{
-				u_int attr_pool = get_attr_pool(this, name);
-				if (!attr_pool)
-				{
-					continue;
-				}
-
-				attr_enumerator = this->db->query(this->db,
-								"SELECT count(*) FROM attributes "
-								"WHERE pool = ? AND identity = ?",
-								DB_UINT, attr_pool, DB_UINT, identity, DB_UINT);
-
-				if (attr_enumerator &&
-					attr_enumerator->enumerate(attr_enumerator, &count) &&
-					count != 0)
-				{
-					attr_enumerator->destroy(attr_enumerator);
-					attr_enumerator = this->db->query(this->db,
-								"SELECT type, value FROM attributes "
-								"WHERE pool = ? AND identity = ?", DB_UINT,
-								attr_pool, DB_UINT, identity, DB_INT, DB_BLOB);
-					break;
-				}
-				DESTROY_IF(attr_enumerator);
-				attr_enumerator = NULL;
-			}
-			pool_enumerator->destroy(pool_enumerator);
-		}
-
-		/* in a second step check for attributes that match name */
-		if (!attr_enumerator)
-		{
-			pool_enumerator = pools->create_enumerator(pools);
-			while (pool_enumerator->enumerate(pool_enumerator, &name))
-			{
-				u_int attr_pool = get_attr_pool(this, name);
-				if (!attr_pool)
-				{
-					continue;
-				}
-
-				attr_enumerator = this->db->query(this->db,
-									"SELECT count(*) FROM attributes "
-									"WHERE pool = ? AND identity = 0",
-									DB_UINT, attr_pool, DB_UINT);
-
-				if (attr_enumerator &&
-					attr_enumerator->enumerate(attr_enumerator, &count) &&
-					count != 0)
-				{
-					attr_enumerator->destroy(attr_enumerator);
-					attr_enumerator = this->db->query(this->db,
-									"SELECT type, value FROM attributes "
-									"WHERE pool = ? AND identity = 0",
-									DB_UINT, attr_pool, DB_INT, DB_BLOB);
-					break;
-				}
-				DESTROY_IF(attr_enumerator);
-				attr_enumerator = NULL;
-			}
-			pool_enumerator->destroy(pool_enumerator);
-		}
-
-		/* lastly try to find global attributes */
-		if (!attr_enumerator)
-		{
-			attr_enumerator = this->db->query(this->db,
-									"SELECT type, value FROM attributes "
-									"WHERE pool = 0 AND identity = 0",
-									DB_INT, DB_BLOB);
-		}
-	}
-
-	return (attr_enumerator ? attr_enumerator : enumerator_create_empty());
-}
-
-METHOD(sql_attribute_t, destroy, void,
-	private_sql_attribute_t *this)
-{
-	free(this);
-}
-
-/*
- * see header file
- */
-sql_attribute_t *sql_attribute_create(database_t *db)
-{
-	private_sql_attribute_t *this;
-	time_t now = time(NULL);
-
-	INIT(this,
-		.public = {
-			.provider = {
-				.acquire_address = _acquire_address,
-				.release_address = _release_address,
-				.create_attribute_enumerator = _create_attribute_enumerator,
-			},
-			.destroy = _destroy,
-		},
-		.db = db,
-		.history = lib->settings->get_bool(lib->settings,
-							"%s.plugins.attr-sql.lease_history", TRUE, lib->ns),
-	);
-
-	/* close any "online" leases in the case we crashed */
-	if (this->history)
-	{
-		this->db->execute(this->db, NULL,
-					"INSERT INTO leases (address, identity, acquired, released)"
-					" SELECT id, identity, acquired, ? FROM addresses "
-					" WHERE released = 0", DB_UINT, now);
-	}
-	this->db->execute(this->db, NULL,
-					  "UPDATE addresses SET released = ? WHERE released = 0",
-					  DB_UINT, now);
-	return &this->public;
-}
diff --git a/src/libhydra/plugins/attr_sql/sql_attribute.h b/src/libhydra/plugins/attr_sql/sql_attribute.h
deleted file mode 100644
index ca87eb2..0000000
--- a/src/libhydra/plugins/attr_sql/sql_attribute.h
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * Copyright (C) 2008 Martin Willi
- * Hochschule fuer Technik Rapperswil
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * for more details.
- */
-
-/**
- * @defgroup sql_attribute sql_attribute
- * @{ @ingroup attr_sql
- */
-
-#ifndef SQL_ATTRIBUTE_H_
-#define SQL_ATTRIBUTE_H_
-
-#include <attributes/attribute_provider.h>
-#include <database/database.h>
-
-typedef struct sql_attribute_t sql_attribute_t;
-
-/**
- * SQL database based IKEv2 cfg attribute provider.
- */
-struct sql_attribute_t {
-
-	/**
-	 * Implements attribute provider interface
-	 */
-	attribute_provider_t provider;
-
-	/**
-	 * Destroy a sql_attribute instance.
-	 */
-	void (*destroy)(sql_attribute_t *this);
-};
-
-/**
- * Create a sql_attribute instance.
- */
-sql_attribute_t *sql_attribute_create(database_t *db);
-
-#endif /** SQL_ATTRIBUTE_H_ @}*/
diff --git a/src/libhydra/plugins/kernel_netlink/Makefile.am b/src/libhydra/plugins/kernel_netlink/Makefile.am
index c91f9a9..cc88554 100644
--- a/src/libhydra/plugins/kernel_netlink/Makefile.am
+++ b/src/libhydra/plugins/kernel_netlink/Makefile.am
@@ -21,3 +21,24 @@ libstrongswan_kernel_netlink_la_SOURCES = \
 	kernel_netlink_shared.h kernel_netlink_shared.c
 
 libstrongswan_kernel_netlink_la_LDFLAGS = -module -avoid-version
+
+
+TESTS = tests
+
+check_PROGRAMS = $(TESTS)
+
+tests_SOURCES = \
+	tests.h tests.c \
+	suites/test_socket.c \
+	kernel_netlink_shared.c
+
+tests_CFLAGS = \
+	-I$(top_srcdir)/src/libstrongswan \
+	-I$(top_srcdir)/src/libstrongswan/tests \
+	-DNETLINK_MSG_LOSS_HOOK=netlink_msg_loss \
+	@COVERAGE_CFLAGS@
+
+tests_LDFLAGS = @COVERAGE_LDFLAGS@
+tests_LDADD = \
+	$(top_builddir)/src/libstrongswan/libstrongswan.la \
+	$(top_builddir)/src/libstrongswan/tests/libtest.la
diff --git a/src/libhydra/plugins/kernel_netlink/Makefile.in b/src/libhydra/plugins/kernel_netlink/Makefile.in
index a9b523e..962fe1b 100644
--- a/src/libhydra/plugins/kernel_netlink/Makefile.in
+++ b/src/libhydra/plugins/kernel_netlink/Makefile.in
@@ -78,6 +78,8 @@ PRE_UNINSTALL = :
 POST_UNINSTALL = :
 build_triplet = @build@
 host_triplet = @host@
+TESTS = tests$(EXEEXT)
+check_PROGRAMS = $(am__EXEEXT_1)
 subdir = src/libhydra/plugins/kernel_netlink
 DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
 	$(top_srcdir)/depcomp
@@ -144,6 +146,18 @@ libstrongswan_kernel_netlink_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \
 @MONOLITHIC_FALSE at am_libstrongswan_kernel_netlink_la_rpath = -rpath \
 @MONOLITHIC_FALSE@	$(plugindir)
 @MONOLITHIC_TRUE at am_libstrongswan_kernel_netlink_la_rpath =
+am__EXEEXT_1 = tests$(EXEEXT)
+am__dirstamp = $(am__leading_dot)dirstamp
+am_tests_OBJECTS = tests-tests.$(OBJEXT) \
+	suites/tests-test_socket.$(OBJEXT) \
+	tests-kernel_netlink_shared.$(OBJEXT)
+tests_OBJECTS = $(am_tests_OBJECTS)
+tests_DEPENDENCIES =  \
+	$(top_builddir)/src/libstrongswan/libstrongswan.la \
+	$(top_builddir)/src/libstrongswan/tests/libtest.la
+tests_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+	$(LIBTOOLFLAGS) --mode=link $(CCLD) $(tests_CFLAGS) $(CFLAGS) \
+	$(tests_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
@@ -178,8 +192,9 @@ 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_kernel_netlink_la_SOURCES)
-DIST_SOURCES = $(libstrongswan_kernel_netlink_la_SOURCES)
+SOURCES = $(libstrongswan_kernel_netlink_la_SOURCES) $(tests_SOURCES)
+DIST_SOURCES = $(libstrongswan_kernel_netlink_la_SOURCES) \
+	$(tests_SOURCES)
 am__can_run_installinfo = \
   case $$AM_UPDATE_INFO_DIR in \
     n|no|NO) false;; \
@@ -204,6 +219,28 @@ am__define_uniq_tagged_files = \
   done | $(am__uniquify_input)`
 ETAGS = etags
 CTAGS = ctags
+am__tty_colors_dummy = \
+  mgn= red= grn= lgn= blu= brg= std=; \
+  am__color_tests=no
+am__tty_colors = { \
+  $(am__tty_colors_dummy); \
+  if test "X$(AM_COLOR_TESTS)" = Xno; then \
+    am__color_tests=no; \
+  elif test "X$(AM_COLOR_TESTS)" = Xalways; then \
+    am__color_tests=yes; \
+  elif test "X$$TERM" != Xdumb && { test -t 1; } 2>/dev/null; then \
+    am__color_tests=yes; \
+  fi; \
+  if test $$am__color_tests = yes; then \
+    red=''; \
+    grn=''; \
+    lgn=''; \
+    blu=''; \
+    mgn=''; \
+    brg=''; \
+    std=''; \
+  fi; \
+}
 DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
 ACLOCAL = @ACLOCAL@
 ALLOCA = @ALLOCA@
@@ -230,6 +267,7 @@ DLLIB = @DLLIB@
 DLLTOOL = @DLLTOOL@
 DSYMUTIL = @DSYMUTIL@
 DUMPBIN = @DUMPBIN@
+EASY_INSTALL = @EASY_INSTALL@
 ECHO_C = @ECHO_C@
 ECHO_N = @ECHO_N@
 ECHO_T = @ECHO_T@
@@ -290,10 +328,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
 PLUGIN_CFLAGS = @PLUGIN_CFLAGS@
 PTHREADLIB = @PTHREADLIB@
 PYTHON = @PYTHON@
+PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@
 PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
 PYTHON_PLATFORM = @PYTHON_PLATFORM@
 PYTHON_PREFIX = @PYTHON_PREFIX@
 PYTHON_VERSION = @PYTHON_VERSION@
+PY_TEST = @PY_TEST@
 RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
@@ -367,6 +407,8 @@ json_CFLAGS = @json_CFLAGS@
 json_LIBS = @json_LIBS@
 libdir = @libdir@
 libexecdir = @libexecdir@
+libiptc_CFLAGS = @libiptc_CFLAGS@
+libiptc_LIBS = @libiptc_LIBS@
 linux_headers = @linux_headers@
 localedir = @localedir@
 localstatedir = @localstatedir@
@@ -444,6 +486,22 @@ libstrongswan_kernel_netlink_la_SOURCES = \
 	kernel_netlink_shared.h kernel_netlink_shared.c
 
 libstrongswan_kernel_netlink_la_LDFLAGS = -module -avoid-version
+tests_SOURCES = \
+	tests.h tests.c \
+	suites/test_socket.c \
+	kernel_netlink_shared.c
+
+tests_CFLAGS = \
+	-I$(top_srcdir)/src/libstrongswan \
+	-I$(top_srcdir)/src/libstrongswan/tests \
+	-DNETLINK_MSG_LOSS_HOOK=netlink_msg_loss \
+	@COVERAGE_CFLAGS@
+
+tests_LDFLAGS = @COVERAGE_LDFLAGS@
+tests_LDADD = \
+	$(top_builddir)/src/libstrongswan/libstrongswan.la \
+	$(top_builddir)/src/libstrongswan/tests/libtest.la
+
 all: all-am
 
 .SUFFIXES:
@@ -528,8 +586,30 @@ clean-pluginLTLIBRARIES:
 libstrongswan-kernel-netlink.la: $(libstrongswan_kernel_netlink_la_OBJECTS) $(libstrongswan_kernel_netlink_la_DEPENDENCIES) $(EXTRA_libstrongswan_kernel_netlink_la_DEPENDENCIES) 
 	$(AM_V_CCLD)$(libstrongswan_kernel_netlink_la_LINK) $(am_libstrongswan_kernel_netlink_la_rpath) $(libstrongswan_kernel_netlink_la_OBJECTS) $(libstrongswan_kernel_netlink_la_LIBADD) $(LIBS)
 
+clean-checkPROGRAMS:
+	@list='$(check_PROGRAMS)'; test -n "$$list" || exit 0; \
+	echo " rm -f" $$list; \
+	rm -f $$list || exit $$?; \
+	test -n "$(EXEEXT)" || exit 0; \
+	list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \
+	echo " rm -f" $$list; \
+	rm -f $$list
+suites/$(am__dirstamp):
+	@$(MKDIR_P) suites
+	@: > suites/$(am__dirstamp)
+suites/$(DEPDIR)/$(am__dirstamp):
+	@$(MKDIR_P) suites/$(DEPDIR)
+	@: > suites/$(DEPDIR)/$(am__dirstamp)
+suites/tests-test_socket.$(OBJEXT): suites/$(am__dirstamp) \
+	suites/$(DEPDIR)/$(am__dirstamp)
+
+tests$(EXEEXT): $(tests_OBJECTS) $(tests_DEPENDENCIES) $(EXTRA_tests_DEPENDENCIES) 
+	@rm -f tests$(EXEEXT)
+	$(AM_V_CCLD)$(tests_LINK) $(tests_OBJECTS) $(tests_LDADD) $(LIBS)
+
 mostlyclean-compile:
 	-rm -f *.$(OBJEXT)
+	-rm -f suites/*.$(OBJEXT)
 
 distclean-compile:
 	-rm -f *.tab.c
@@ -538,6 +618,9 @@ distclean-compile:
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/kernel_netlink_net.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/kernel_netlink_plugin.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/kernel_netlink_shared.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/tests-kernel_netlink_shared.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/tests-tests.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at suites/$(DEPDIR)/tests-test_socket.Po at am__quote@
 
 .c.o:
 @am__fastdepCC_TRUE@	$(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\
@@ -563,6 +646,48 @@ distclean-compile:
 @AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
 @am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(LTCOMPILE) -c -o $@ $<
 
+tests-tests.o: tests.c
+ at am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(tests_CFLAGS) $(CFLAGS) -MT tests-tests.o -MD -MP -MF $(DEPDIR)/tests-tests.Tpo -c -o tests-tests.o `test -f 'tests.c' || echo '$(srcdir)/'`tests.c
+ at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/tests-tests.Tpo $(DEPDIR)/tests-tests.Po
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='tests.c' object='tests-tests.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) $(tests_CFLAGS) $(CFLAGS) -c -o tests-tests.o `test -f 'tests.c' || echo '$(srcdir)/'`tests.c
+
+tests-tests.obj: tests.c
+ at am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(tests_CFLAGS) $(CFLAGS) -MT tests-tests.obj -MD -MP -MF $(DEPDIR)/tests-tests.Tpo -c -o tests-tests.obj `if test -f 'tests.c'; then $(CYGPATH_W) 'tests.c'; else $(CYGPATH_W) '$(srcdir)/tests.c'; fi`
+ at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/tests-tests.Tpo $(DEPDIR)/tests-tests.Po
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='tests.c' object='tests-tests.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) $(tests_CFLAGS) $(CFLAGS) -c -o tests-tests.obj `if test -f 'tests.c'; then $(CYGPATH_W) 'tests.c'; else $(CYGPATH_W) '$(srcdir)/tests.c'; fi`
+
+suites/tests-test_socket.o: suites/test_socket.c
+ at am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(tests_CFLAGS) $(CFLAGS) -MT suites/tests-test_socket.o -MD -MP -MF suites/$(DEPDIR)/tests-test_socket.Tpo -c -o suites/tests-test_socket.o `test -f 'suites/test_socket.c' || echo '$(srcdir)/'`suites/test_socket.c
+ at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) suites/$(DEPDIR)/tests-test_socket.Tpo suites/$(DEPDIR)/tests-test_socket.Po
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='suites/test_socket.c' object='suites/tests-test_socket.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) $(tests_CFLAGS) $(CFLAGS) -c -o suites/tests-test_socket.o `test -f 'suites/test_socket.c' || echo '$(srcdir)/'`suites/test_socket.c
+
+suites/tests-test_socket.obj: suites/test_socket.c
+ at am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(tests_CFLAGS) $(CFLAGS) -MT suites/tests-test_socket.obj -MD -MP -MF suites/$(DEPDIR)/tests-test_socket.Tpo -c -o suites/tests-test_socket.obj `if test -f 'suites/test_socket.c'; then $(CYGPATH_W) 'suites/test_socket.c'; else $(CYGPATH_W) '$(srcdir)/suites/test_socket.c'; fi`
+ at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) suites/$(DEPDIR)/tests-test_socket.Tpo suites/$(DEPDIR)/tests-test_socket.Po
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='suites/test_socket.c' object='suites/tests-test_socket.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) $(tests_CFLAGS) $(CFLAGS) -c -o suites/tests-test_socket.obj `if test -f 'suites/test_socket.c'; then $(CYGPATH_W) 'suites/test_socket.c'; else $(CYGPATH_W) '$(srcdir)/suites/test_socket.c'; fi`
+
+tests-kernel_netlink_shared.o: kernel_netlink_shared.c
+ at am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(tests_CFLAGS) $(CFLAGS) -MT tests-kernel_netlink_shared.o -MD -MP -MF $(DEPDIR)/tests-kernel_netlink_shared.Tpo -c -o tests-kernel_netlink_shared.o `test -f 'kernel_netlink_shared.c' || echo '$(srcdir)/'`kernel_netlink_shared.c
+ at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/tests-kernel_netlink_shared.Tpo $(DEPDIR)/tests-kernel_netlink_shared.Po
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='kernel_netlink_shared.c' object='tests-kernel_netlink_shared.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) $(tests_CFLAGS) $(CFLAGS) -c -o tests-kernel_netlink_shared.o `test -f 'kernel_netlink_shared.c' || echo '$(srcdir)/'`kernel_netlink_shared.c
+
+tests-kernel_netlink_shared.obj: kernel_netlink_shared.c
+ at am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(tests_CFLAGS) $(CFLAGS) -MT tests-kernel_netlink_shared.obj -MD -MP -MF $(DEPDIR)/tests-kernel_netlink_shared.Tpo -c -o tests-kernel_netlink_shared.obj `if test -f 'kernel_netlink_shared.c'; then $(CYGPATH_W) 'kernel_netlink_shared.c'; else $(CYGPATH_W) '$(srcdir)/kernel_netlink_shared.c'; fi`
+ at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/tests-kernel_netlink_shared.Tpo $(DEPDIR)/tests-kernel_netlink_shared.Po
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='kernel_netlink_shared.c' object='tests-kernel_netlink_shared.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) $(tests_CFLAGS) $(CFLAGS) -c -o tests-kernel_netlink_shared.obj `if test -f 'kernel_netlink_shared.c'; then $(CYGPATH_W) 'kernel_netlink_shared.c'; else $(CYGPATH_W) '$(srcdir)/kernel_netlink_shared.c'; fi`
+
 mostlyclean-libtool:
 	-rm -f *.lo
 
@@ -621,6 +746,99 @@ cscopelist-am: $(am__tagged_files)
 distclean-tags:
 	-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
 
+check-TESTS: $(TESTS)
+	@failed=0; all=0; xfail=0; xpass=0; skip=0; \
+	srcdir=$(srcdir); export srcdir; \
+	list=' $(TESTS) '; \
+	$(am__tty_colors); \
+	if test -n "$$list"; then \
+	  for tst in $$list; do \
+	    if test -f ./$$tst; then dir=./; \
+	    elif test -f $$tst; then dir=; \
+	    else dir="$(srcdir)/"; fi; \
+	    if $(TESTS_ENVIRONMENT) $${dir}$$tst $(AM_TESTS_FD_REDIRECT); then \
+	      all=`expr $$all + 1`; \
+	      case " $(XFAIL_TESTS) " in \
+	      *[\ \	]$$tst[\ \	]*) \
+		xpass=`expr $$xpass + 1`; \
+		failed=`expr $$failed + 1`; \
+		col=$$red; res=XPASS; \
+	      ;; \
+	      *) \
+		col=$$grn; res=PASS; \
+	      ;; \
+	      esac; \
+	    elif test $$? -ne 77; then \
+	      all=`expr $$all + 1`; \
+	      case " $(XFAIL_TESTS) " in \
+	      *[\ \	]$$tst[\ \	]*) \
+		xfail=`expr $$xfail + 1`; \
+		col=$$lgn; res=XFAIL; \
+	      ;; \
+	      *) \
+		failed=`expr $$failed + 1`; \
+		col=$$red; res=FAIL; \
+	      ;; \
+	      esac; \
+	    else \
+	      skip=`expr $$skip + 1`; \
+	      col=$$blu; res=SKIP; \
+	    fi; \
+	    echo "$${col}$$res$${std}: $$tst"; \
+	  done; \
+	  if test "$$all" -eq 1; then \
+	    tests="test"; \
+	    All=""; \
+	  else \
+	    tests="tests"; \
+	    All="All "; \
+	  fi; \
+	  if test "$$failed" -eq 0; then \
+	    if test "$$xfail" -eq 0; then \
+	      banner="$$All$$all $$tests passed"; \
+	    else \
+	      if test "$$xfail" -eq 1; then failures=failure; else failures=failures; fi; \
+	      banner="$$All$$all $$tests behaved as expected ($$xfail expected $$failures)"; \
+	    fi; \
+	  else \
+	    if test "$$xpass" -eq 0; then \
+	      banner="$$failed of $$all $$tests failed"; \
+	    else \
+	      if test "$$xpass" -eq 1; then passes=pass; else passes=passes; fi; \
+	      banner="$$failed of $$all $$tests did not behave as expected ($$xpass unexpected $$passes)"; \
+	    fi; \
+	  fi; \
+	  dashes="$$banner"; \
+	  skipped=""; \
+	  if test "$$skip" -ne 0; then \
+	    if test "$$skip" -eq 1; then \
+	      skipped="($$skip test was not run)"; \
+	    else \
+	      skipped="($$skip tests were not run)"; \
+	    fi; \
+	    test `echo "$$skipped" | wc -c` -le `echo "$$banner" | wc -c` || \
+	      dashes="$$skipped"; \
+	  fi; \
+	  report=""; \
+	  if test "$$failed" -ne 0 && test -n "$(PACKAGE_BUGREPORT)"; then \
+	    report="Please report to $(PACKAGE_BUGREPORT)"; \
+	    test `echo "$$report" | wc -c` -le `echo "$$banner" | wc -c` || \
+	      dashes="$$report"; \
+	  fi; \
+	  dashes=`echo "$$dashes" | sed s/./=/g`; \
+	  if test "$$failed" -eq 0; then \
+	    col="$$grn"; \
+	  else \
+	    col="$$red"; \
+	  fi; \
+	  echo "$${col}$$dashes$${std}"; \
+	  echo "$${col}$$banner$${std}"; \
+	  test -z "$$skipped" || echo "$${col}$$skipped$${std}"; \
+	  test -z "$$report" || echo "$${col}$$report$${std}"; \
+	  echo "$${col}$$dashes$${std}"; \
+	  test "$$failed" -eq 0; \
+	else :; fi
+
 distdir: $(DISTFILES)
 	@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
 	topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
@@ -652,6 +870,8 @@ distdir: $(DISTFILES)
 	  fi; \
 	done
 check-am: all-am
+	$(MAKE) $(AM_MAKEFLAGS) $(check_PROGRAMS)
+	$(MAKE) $(AM_MAKEFLAGS) check-TESTS
 check: check-am
 all-am: Makefile $(LTLIBRARIES)
 installdirs:
@@ -684,17 +904,19 @@ 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 suites/$(DEPDIR)/$(am__dirstamp)
+	-rm -f suites/$(am__dirstamp)
 
 maintainer-clean-generic:
 	@echo "This command is intended for maintainers to use"
 	@echo "it deletes files that may require special tools to rebuild."
 clean: clean-am
 
-clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \
-	clean-pluginLTLIBRARIES mostlyclean-am
+clean-am: clean-checkPROGRAMS clean-generic clean-libtool \
+	clean-noinstLTLIBRARIES clean-pluginLTLIBRARIES mostlyclean-am
 
 distclean: distclean-am
-	-rm -rf ./$(DEPDIR)
+	-rm -rf ./$(DEPDIR) suites/$(DEPDIR)
 	-rm -f Makefile
 distclean-am: clean-am distclean-compile distclean-generic \
 	distclean-tags
@@ -740,7 +962,7 @@ install-ps-am:
 installcheck-am:
 
 maintainer-clean: maintainer-clean-am
-	-rm -rf ./$(DEPDIR)
+	-rm -rf ./$(DEPDIR) suites/$(DEPDIR)
 	-rm -f Makefile
 maintainer-clean-am: distclean-am maintainer-clean-generic
 
@@ -759,22 +981,23 @@ ps-am:
 
 uninstall-am: uninstall-pluginLTLIBRARIES
 
-.MAKE: install-am install-strip
-
-.PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \
-	clean-libtool clean-noinstLTLIBRARIES clean-pluginLTLIBRARIES \
-	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-man install-pdf \
-	install-pdf-am install-pluginLTLIBRARIES install-ps \
-	install-ps-am install-strip installcheck installcheck-am \
-	installdirs maintainer-clean maintainer-clean-generic \
-	mostlyclean mostlyclean-compile mostlyclean-generic \
-	mostlyclean-libtool pdf pdf-am ps ps-am tags tags-am uninstall \
-	uninstall-am uninstall-pluginLTLIBRARIES
+.MAKE: check-am install-am install-strip
+
+.PHONY: CTAGS GTAGS TAGS all all-am check check-TESTS check-am clean \
+	clean-checkPROGRAMS clean-generic clean-libtool \
+	clean-noinstLTLIBRARIES clean-pluginLTLIBRARIES 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-man install-pdf install-pdf-am \
+	install-pluginLTLIBRARIES install-ps install-ps-am \
+	install-strip installcheck installcheck-am installdirs \
+	maintainer-clean maintainer-clean-generic mostlyclean \
+	mostlyclean-compile mostlyclean-generic mostlyclean-libtool \
+	pdf pdf-am ps ps-am tags tags-am uninstall uninstall-am \
+	uninstall-pluginLTLIBRARIES
 
 
 # Tell versions [3.59,3.63) of GNU make to not export all variables.
diff --git a/src/libhydra/plugins/kernel_netlink/kernel_netlink_ipsec.c b/src/libhydra/plugins/kernel_netlink/kernel_netlink_ipsec.c
index dfd71f3..03e44e5 100644
--- a/src/libhydra/plugins/kernel_netlink/kernel_netlink_ipsec.c
+++ b/src/libhydra/plugins/kernel_netlink/kernel_netlink_ipsec.c
@@ -38,6 +38,7 @@
 #include <hydra.h>
 #include <utils/debug.h>
 #include <threading/mutex.h>
+#include <collections/array.h>
 #include <collections/hashtable.h>
 #include <collections/linked_list.h>
 
@@ -319,6 +320,16 @@ struct private_kernel_netlink_ipsec_t {
 	 * Whether to track the history of a policy
 	 */
 	bool policy_history;
+
+	/**
+	 * Whether to always use UPDATE to install policies
+	 */
+	bool policy_update;
+
+	/**
+	 * Installed port based IKE bypass policies, as bypass_t
+	 */
+	array_t *bypass;
 };
 
 typedef struct route_entry_t route_entry_t;
@@ -859,25 +870,26 @@ static void process_expire(private_kernel_netlink_ipsec_t *this,
 						   struct nlmsghdr *hdr)
 {
 	struct xfrm_user_expire *expire;
-	u_int32_t spi, reqid;
+	u_int32_t spi;
 	u_int8_t protocol;
+	host_t *dst;
 
 	expire = NLMSG_DATA(hdr);
 	protocol = expire->state.id.proto;
 	spi = expire->state.id.spi;
-	reqid = expire->state.reqid;
 
 	DBG2(DBG_KNL, "received a XFRM_MSG_EXPIRE");
 
-	if (protocol != IPPROTO_ESP && protocol != IPPROTO_AH)
+	if (protocol == IPPROTO_ESP || protocol == IPPROTO_AH)
 	{
-		DBG2(DBG_KNL, "ignoring XFRM_MSG_EXPIRE for SA with SPI %.8x and "
-					  "reqid {%u} which is not a CHILD_SA", ntohl(spi), reqid);
-		return;
+		dst = xfrm2host(expire->state.family, &expire->state.id.daddr, 0);
+		if (dst)
+		{
+			hydra->kernel_interface->expire(hydra->kernel_interface, protocol,
+											spi, dst, expire->hard != 0);
+			dst->destroy(dst);
+		}
 	}
-
-	hydra->kernel_interface->expire(hydra->kernel_interface, reqid, protocol,
-									spi, expire->hard != 0);
 }
 
 /**
@@ -961,23 +973,29 @@ static void process_mapping(private_kernel_netlink_ipsec_t *this,
 							struct nlmsghdr *hdr)
 {
 	struct xfrm_user_mapping *mapping;
-	u_int32_t spi, reqid;
+	u_int32_t spi;
 
 	mapping = NLMSG_DATA(hdr);
 	spi = mapping->id.spi;
-	reqid = mapping->reqid;
 
 	DBG2(DBG_KNL, "received a XFRM_MSG_MAPPING");
 
 	if (mapping->id.proto == IPPROTO_ESP)
 	{
-		host_t *host;
-		host = xfrm2host(mapping->id.family, &mapping->new_saddr,
-						 mapping->new_sport);
-		if (host)
+		host_t *dst, *new;
+
+		dst = xfrm2host(mapping->id.family, &mapping->id.daddr, 0);
+		if (dst)
 		{
-			hydra->kernel_interface->mapping(hydra->kernel_interface, reqid,
-											 spi, host);
+			new = xfrm2host(mapping->id.family, &mapping->new_saddr,
+							mapping->new_sport);
+			if (new)
+			{
+				hydra->kernel_interface->mapping(hydra->kernel_interface,
+												 IPPROTO_ESP, spi, dst, new);
+				new->destroy(new);
+			}
+			dst->destroy(dst);
 		}
 	}
 }
@@ -1055,7 +1073,7 @@ METHOD(kernel_ipsec_t, get_features, kernel_feature_t,
  */
 static status_t get_spi_internal(private_kernel_netlink_ipsec_t *this,
 	host_t *src, host_t *dst, u_int8_t proto, u_int32_t min, u_int32_t max,
-	u_int32_t reqid, u_int32_t *spi)
+	u_int32_t *spi)
 {
 	netlink_buf_t request;
 	struct nlmsghdr *hdr, *out;
@@ -1075,7 +1093,6 @@ static status_t get_spi_internal(private_kernel_netlink_ipsec_t *this,
 	host2xfrm(dst, &userspi->info.id.daddr);
 	userspi->info.id.proto = proto;
 	userspi->info.mode = XFRM_MODE_TUNNEL;
-	userspi->info.reqid = reqid;
 	userspi->info.family = src->get_family(src);
 	userspi->min = min;
 	userspi->max = max;
@@ -1122,39 +1139,35 @@ static status_t get_spi_internal(private_kernel_netlink_ipsec_t *this,
 
 METHOD(kernel_ipsec_t, get_spi, status_t,
 	private_kernel_netlink_ipsec_t *this, host_t *src, host_t *dst,
-	u_int8_t protocol, u_int32_t reqid, u_int32_t *spi)
+	u_int8_t protocol, u_int32_t *spi)
 {
-	DBG2(DBG_KNL, "getting SPI for reqid {%u}", reqid);
-
 	if (get_spi_internal(this, src, dst, protocol,
-						 0xc0000000, 0xcFFFFFFF, reqid, spi) != SUCCESS)
+						 0xc0000000, 0xcFFFFFFF, spi) != SUCCESS)
 	{
-		DBG1(DBG_KNL, "unable to get SPI for reqid {%u}", reqid);
+		DBG1(DBG_KNL, "unable to get SPI");
 		return FAILED;
 	}
 
-	DBG2(DBG_KNL, "got SPI %.8x for reqid {%u}", ntohl(*spi), reqid);
+	DBG2(DBG_KNL, "got SPI %.8x", ntohl(*spi));
 	return SUCCESS;
 }
 
 METHOD(kernel_ipsec_t, get_cpi, status_t,
 	private_kernel_netlink_ipsec_t *this, host_t *src, host_t *dst,
-	u_int32_t reqid, u_int16_t *cpi)
+	u_int16_t *cpi)
 {
 	u_int32_t received_spi = 0;
 
-	DBG2(DBG_KNL, "getting CPI for reqid {%u}", reqid);
-
 	if (get_spi_internal(this, src, dst, IPPROTO_COMP,
-						 0x100, 0xEFFF, reqid, &received_spi) != SUCCESS)
+						 0x100, 0xEFFF, &received_spi) != SUCCESS)
 	{
-		DBG1(DBG_KNL, "unable to get CPI for reqid {%u}", reqid);
+		DBG1(DBG_KNL, "unable to get CPI");
 		return FAILED;
 	}
 
 	*cpi = htons((u_int16_t)ntohl(received_spi));
 
-	DBG2(DBG_KNL, "got CPI %.4x for reqid {%u}", ntohs(*cpi), reqid);
+	DBG2(DBG_KNL, "got CPI %.4x", ntohs(*cpi));
 	return SUCCESS;
 }
 
@@ -1184,8 +1197,8 @@ METHOD(kernel_ipsec_t, add_sa, status_t,
 	u_int32_t tfc, lifetime_cfg_t *lifetime, u_int16_t enc_alg, chunk_t enc_key,
 	u_int16_t int_alg, chunk_t int_key, ipsec_mode_t mode,
 	u_int16_t ipcomp, u_int16_t cpi, u_int32_t replay_window,
-	bool initiator, bool encap, bool esn, bool inbound,
-	traffic_selector_t* src_ts, traffic_selector_t* dst_ts)
+	bool initiator, bool encap, bool esn, bool inbound, bool update,
+	linked_list_t* src_ts, linked_list_t* dst_ts)
 {
 	netlink_buf_t request;
 	char *alg_name;
@@ -1193,6 +1206,7 @@ METHOD(kernel_ipsec_t, add_sa, status_t,
 	struct xfrm_usersa_info *sa;
 	u_int16_t icv_size = 64;
 	ipsec_mode_t original_mode = mode;
+	traffic_selector_t *first_src_ts, *first_dst_ts;
 	status_t status = FAILED;
 
 	/* if IPComp is used, we install an additional IPComp SA. if the cpi is 0
@@ -1203,7 +1217,7 @@ METHOD(kernel_ipsec_t, add_sa, status_t,
 		add_sa(this, src, dst, htonl(ntohs(cpi)), IPPROTO_COMP, reqid, mark,
 			   tfc, &lft, ENCR_UNDEFINED, chunk_empty, AUTH_UNDEFINED,
 			   chunk_empty, mode, ipcomp, 0, 0, initiator, FALSE, FALSE,
-			   inbound, src_ts, dst_ts);
+			   inbound, update, src_ts, dst_ts);
 		ipcomp = IPCOMP_NONE;
 		/* use transport mode ESP SA, IPComp uses tunnel mode */
 		mode = MODE_TRANSPORT;
@@ -1216,7 +1230,7 @@ METHOD(kernel_ipsec_t, add_sa, status_t,
 
 	hdr = &request.hdr;
 	hdr->nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK;
-	hdr->nlmsg_type = inbound ? XFRM_MSG_UPDSA : XFRM_MSG_NEWSA;
+	hdr->nlmsg_type = update ? XFRM_MSG_UPDSA : XFRM_MSG_NEWSA;
 	hdr->nlmsg_len = NLMSG_LENGTH(sizeof(struct xfrm_usersa_info));
 
 	sa = NLMSG_DATA(hdr);
@@ -1238,9 +1252,10 @@ METHOD(kernel_ipsec_t, add_sa, status_t,
 				 * selector can be installed other traffic would get dropped */
 				break;
 			}
-			if (src_ts && dst_ts)
+			if (src_ts->get_first(src_ts, (void**)&first_src_ts) == SUCCESS &&
+				dst_ts->get_first(dst_ts, (void**)&first_dst_ts) == SUCCESS)
 			{
-				sa->sel = ts2selector(src_ts, dst_ts);
+				sa->sel = ts2selector(first_src_ts, first_dst_ts);
 				if (!this->proto_port_transport)
 				{
 					/* don't install proto/port on SA. This would break
@@ -1535,7 +1550,8 @@ static void get_replay_state(private_kernel_netlink_ipsec_t *this,
 							 host_t *dst, mark_t mark,
 							 struct xfrm_replay_state_esn **replay_esn,
 							 u_int32_t *replay_esn_len,
-							 struct xfrm_replay_state **replay)
+							 struct xfrm_replay_state **replay,
+							 struct xfrm_lifetime_cur **lifetime)
 {
 	netlink_buf_t request;
 	struct nlmsghdr *hdr, *out = NULL;
@@ -1603,20 +1619,27 @@ static void get_replay_state(private_kernel_netlink_ipsec_t *this,
 		rtasize = XFRM_PAYLOAD(out, struct xfrm_aevent_id);
 		while (RTA_OK(rta, rtasize))
 		{
+			if (rta->rta_type == XFRMA_LTIME_VAL &&
+				RTA_PAYLOAD(rta) == sizeof(**lifetime))
+			{
+				free(*lifetime);
+				*lifetime = malloc(RTA_PAYLOAD(rta));
+				memcpy(*lifetime, RTA_DATA(rta), RTA_PAYLOAD(rta));
+			}
 			if (rta->rta_type == XFRMA_REPLAY_VAL &&
 				RTA_PAYLOAD(rta) == sizeof(**replay))
 			{
+				free(*replay);
 				*replay = malloc(RTA_PAYLOAD(rta));
 				memcpy(*replay, RTA_DATA(rta), RTA_PAYLOAD(rta));
-				break;
 			}
 			if (rta->rta_type == XFRMA_REPLAY_ESN_VAL &&
 				RTA_PAYLOAD(rta) >= sizeof(**replay_esn))
 			{
+				free(*replay_esn);
 				*replay_esn = malloc(RTA_PAYLOAD(rta));
 				*replay_esn_len = RTA_PAYLOAD(rta);
 				memcpy(*replay_esn, RTA_DATA(rta), RTA_PAYLOAD(rta));
-				break;
 			}
 			rta = RTA_NEXT(rta, rtasize);
 		}
@@ -1798,6 +1821,7 @@ METHOD(kernel_ipsec_t, update_sa, status_t,
 	struct xfrm_encap_tmpl* tmpl = NULL;
 	struct xfrm_replay_state *replay = NULL;
 	struct xfrm_replay_state_esn *replay_esn = NULL;
+	struct xfrm_lifetime_cur *lifetime = NULL;
 	u_int32_t replay_esn_len;
 	status_t status = FAILED;
 
@@ -1863,7 +1887,8 @@ METHOD(kernel_ipsec_t, update_sa, status_t,
 		goto failed;
 	}
 
-	get_replay_state(this, spi, protocol, dst, mark, &replay_esn, &replay_esn_len, &replay);
+	get_replay_state(this, spi, protocol, dst, mark, &replay_esn,
+					 &replay_esn_len, &replay, &lifetime);
 
 	/* delete the old SA (without affecting the IPComp SA) */
 	if (del_sa(this, src, dst, spi, protocol, 0, mark) != SUCCESS)
@@ -1952,8 +1977,25 @@ METHOD(kernel_ipsec_t, update_sa, status_t,
 	}
 	else
 	{
-		DBG1(DBG_KNL, "unable to copy replay state from old SAD entry "
-					  "with SPI %.8x", ntohl(spi));
+		DBG1(DBG_KNL, "unable to copy replay state from old SAD entry with "
+			 "SPI %.8x", ntohl(spi));
+	}
+	if (lifetime)
+	{
+		struct xfrm_lifetime_cur *state;
+
+		state = netlink_reserve(hdr, sizeof(request), XFRMA_LTIME_VAL,
+								sizeof(*state));
+		if (!state)
+		{
+			goto failed;
+		}
+		memcpy(state, lifetime, sizeof(*state));
+	}
+	else
+	{
+		DBG1(DBG_KNL, "unable to copy usage stats from old SAD entry with "
+			 "SPI %.8x", ntohl(spi));
 	}
 
 	if (this->socket_xfrm->send_ack(this->socket_xfrm, hdr) != SUCCESS)
@@ -1966,6 +2008,7 @@ METHOD(kernel_ipsec_t, update_sa, status_t,
 failed:
 	free(replay);
 	free(replay_esn);
+	free(lifetime);
 	memwipe(out, len);
 	memwipe(&request, sizeof(request));
 	free(out);
@@ -2313,6 +2356,11 @@ METHOD(kernel_ipsec_t, add_policy, status_t,
 		return SUCCESS;
 	}
 
+	if (this->policy_update)
+	{
+		found = TRUE;
+	}
+
 	DBG2(DBG_KNL, "%s policy %R === %R %N  (mark %u/0x%08x)",
 				   found ? "updating" : "adding", src_ts, dst_ts,
 				   policy_dir_names, direction, mark.value, mark.mask);
@@ -2576,9 +2624,11 @@ METHOD(kernel_ipsec_t, flush_policies, status_t,
 	return SUCCESS;
 }
 
-
-METHOD(kernel_ipsec_t, bypass_socket, bool,
-	private_kernel_netlink_ipsec_t *this, int fd, int family)
+/**
+ * Bypass socket using a per-socket policy
+ */
+static bool add_socket_bypass(private_kernel_netlink_ipsec_t *this,
+							  int fd, int family)
 {
 	struct xfrm_userpolicy_info policy;
 	u_int sol, ipsec_policy;
@@ -2618,6 +2668,154 @@ METHOD(kernel_ipsec_t, bypass_socket, bool,
 	return TRUE;
 }
 
+/**
+ * Port based IKE bypass policy
+ */
+typedef struct {
+	/** address family */
+	int family;
+	/** layer 4 protocol */
+	int proto;
+	/** port number, network order */
+	u_int16_t port;
+} bypass_t;
+
+/**
+ * Add or remove a bypass policy from/to kernel
+ */
+static bool manage_bypass(private_kernel_netlink_ipsec_t *this,
+						  int type, policy_dir_t dir, bypass_t *bypass)
+{
+	netlink_buf_t request;
+	struct xfrm_selector *sel;
+	struct nlmsghdr *hdr;
+
+	memset(&request, 0, sizeof(request));
+	hdr = &request.hdr;
+	hdr->nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK;
+	hdr->nlmsg_type = type;
+
+	if (type == XFRM_MSG_NEWPOLICY)
+	{
+		struct xfrm_userpolicy_info *policy;
+
+		hdr->nlmsg_len = NLMSG_LENGTH(sizeof(struct xfrm_userpolicy_info));
+
+		policy = NLMSG_DATA(hdr);
+		policy->dir = dir;
+		policy->priority = 32;
+		policy->action = XFRM_POLICY_ALLOW;
+		policy->share = XFRM_SHARE_ANY;
+
+		policy->lft.soft_byte_limit = XFRM_INF;
+		policy->lft.soft_packet_limit = XFRM_INF;
+		policy->lft.hard_byte_limit = XFRM_INF;
+		policy->lft.hard_packet_limit = XFRM_INF;
+
+		sel = &policy->sel;
+	}
+	else /* XFRM_MSG_DELPOLICY */
+	{
+		struct xfrm_userpolicy_id *policy;
+
+		hdr->nlmsg_len = NLMSG_LENGTH(sizeof(struct xfrm_userpolicy_id));
+
+		policy = NLMSG_DATA(hdr);
+		policy->dir = dir;
+
+		sel = &policy->sel;
+	}
+
+	sel->family = bypass->family;
+	sel->proto = bypass->proto;
+	if (dir == POLICY_IN)
+	{
+		sel->dport = bypass->port;
+		sel->dport_mask = 0xffff;
+	}
+	else
+	{
+		sel->sport = bypass->port;
+		sel->sport_mask = 0xffff;
+	}
+	return this->socket_xfrm->send_ack(this->socket_xfrm, hdr) == SUCCESS;
+}
+
+/**
+ * Bypass socket using a port-based bypass policy
+ */
+static bool add_port_bypass(private_kernel_netlink_ipsec_t *this,
+							int fd, int family)
+{
+	union {
+		struct sockaddr sa;
+		struct sockaddr_in in;
+		struct sockaddr_in6 in6;
+	} saddr;
+	socklen_t len;
+	bypass_t bypass = {
+		.family = family,
+	};
+
+	len = sizeof(saddr);
+	if (getsockname(fd, &saddr.sa, &len) != 0)
+	{
+		return FALSE;
+	}
+#ifdef SO_PROTOCOL /* since 2.6.32 */
+	len = sizeof(bypass.proto);
+	if (getsockopt(fd, SOL_SOCKET, SO_PROTOCOL, &bypass.proto, &len) != 0)
+#endif
+	{	/* assume UDP if SO_PROTOCOL not supported */
+		bypass.proto = IPPROTO_UDP;
+	}
+	switch (family)
+	{
+		case AF_INET:
+			bypass.port = saddr.in.sin_port;
+			break;
+		case AF_INET6:
+			bypass.port = saddr.in6.sin6_port;
+			break;
+		default:
+			return FALSE;
+	}
+
+	if (!manage_bypass(this, XFRM_MSG_NEWPOLICY, POLICY_IN, &bypass))
+	{
+		return FALSE;
+	}
+	if (!manage_bypass(this, XFRM_MSG_NEWPOLICY, POLICY_OUT, &bypass))
+	{
+		manage_bypass(this, XFRM_MSG_DELPOLICY, POLICY_IN, &bypass);
+		return FALSE;
+	}
+	array_insert(this->bypass, ARRAY_TAIL, &bypass);
+
+	return TRUE;
+}
+
+/**
+ * Remove installed port based bypass policy
+ */
+static void remove_port_bypass(bypass_t *bypass, int idx,
+							   private_kernel_netlink_ipsec_t *this)
+{
+	manage_bypass(this, XFRM_MSG_DELPOLICY, POLICY_OUT, bypass);
+	manage_bypass(this, XFRM_MSG_DELPOLICY, POLICY_IN, bypass);
+}
+
+METHOD(kernel_ipsec_t, bypass_socket, bool,
+	private_kernel_netlink_ipsec_t *this, int fd, int family)
+{
+	if (lib->settings->get_bool(lib->settings,
+					"%s.plugins.kernel-netlink.port_bypass", FALSE, lib->ns))
+	{
+		return add_port_bypass(this, fd, family);
+	}
+	return add_socket_bypass(this, fd, family);
+}
+
 METHOD(kernel_ipsec_t, enable_udp_decap, bool,
 	private_kernel_netlink_ipsec_t *this, int fd, int family, u_int16_t port)
 {
@@ -2637,6 +2835,8 @@ METHOD(kernel_ipsec_t, destroy, void,
 	enumerator_t *enumerator;
 	policy_entry_t *policy;
 
+	array_destroy_function(this->bypass,
+						   (array_callback_t)remove_port_bypass, this);
 	if (this->socket_xfrm_events > 0)
 	{
 		lib->watcher->remove(lib->watcher, this->socket_xfrm_events);
@@ -2688,8 +2888,11 @@ kernel_netlink_ipsec_t *kernel_netlink_ipsec_create()
 									 (hashtable_equals_t)policy_equals, 32),
 		.sas = hashtable_create((hashtable_hash_t)ipsec_sa_hash,
 								(hashtable_equals_t)ipsec_sa_equals, 32),
+		.bypass = array_create(sizeof(bypass_t), 0),
 		.mutex = mutex_create(MUTEX_TYPE_DEFAULT),
 		.policy_history = TRUE,
+		.policy_update = lib->settings->get_bool(lib->settings,
+					"%s.plugins.kernel-netlink.policy_update", FALSE, lib->ns),
 		.install_routes = lib->settings->get_bool(lib->settings,
 							"%s.install_routes", TRUE, lib->ns),
 		.proto_port_transport = lib->settings->get_bool(lib->settings,
@@ -2711,7 +2914,9 @@ kernel_netlink_ipsec_t *kernel_netlink_ipsec_create()
 		fclose(f);
 	}
 
-	this->socket_xfrm = netlink_socket_create(NETLINK_XFRM, xfrm_msg_names);
+	this->socket_xfrm = netlink_socket_create(NETLINK_XFRM, xfrm_msg_names,
+				lib->settings->get_bool(lib->settings,
+					"%s.plugins.kernel-netlink.parallel_xfrm", FALSE, lib->ns));
 	if (!this->socket_xfrm)
 	{
 		destroy(this);
diff --git a/src/libhydra/plugins/kernel_netlink/kernel_netlink_net.c b/src/libhydra/plugins/kernel_netlink/kernel_netlink_net.c
index 9d9f159..a431e49 100644
--- a/src/libhydra/plugins/kernel_netlink/kernel_netlink_net.c
+++ b/src/libhydra/plugins/kernel_netlink/kernel_netlink_net.c
@@ -1538,6 +1538,7 @@ typedef struct {
 	u_int8_t dst_len;
 	u_int32_t table;
 	u_int32_t oif;
+	u_int32_t priority;
 } rt_entry_t;
 
 /**
@@ -1573,6 +1574,7 @@ static rt_entry_t *parse_route(struct nlmsghdr *hdr, rt_entry_t *route)
 		route->dst_len = msg->rtm_dst_len;
 		route->table = msg->rtm_table;
 		route->oif = 0;
+		route->priority = 0;
 	}
 	else
 	{
@@ -1601,6 +1603,12 @@ static rt_entry_t *parse_route(struct nlmsghdr *hdr, rt_entry_t *route)
 					route->oif = *(u_int32_t*)RTA_DATA(rta);
 				}
 				break;
+			case RTA_PRIORITY:
+				if (RTA_PAYLOAD(rta) == sizeof(route->priority))
+				{
+					route->priority = *(u_int32_t*)RTA_DATA(rta);
+				}
+				break;
 #ifdef HAVE_RTA_TABLE
 			case RTA_TABLE:
 				if (RTA_PAYLOAD(rta) == sizeof(route->table))
@@ -1724,11 +1732,16 @@ static host_t *get_route(private_kernel_netlink_net_t *this, host_t *dest,
 					}
 					route->src_host = src;
 				}
-				/* insert route, sorted by decreasing network prefix */
+				/* insert route, sorted by priority and network prefix */
 				enumerator = routes->create_enumerator(routes);
 				while (enumerator->enumerate(enumerator, &other))
 				{
-					if (route->dst_len > other->dst_len)
+					if (route->priority < other->priority)
+					{
+						break;
+					}
+					if (route->priority == other->priority &&
+						route->dst_len > other->dst_len)
 					{
 						break;
 					}
@@ -1975,6 +1988,8 @@ METHOD(kernel_net_t, add_ip, status_t,
 	if (iface)
 	{
 		addr_entry_t *addr;
+		char *ifname;
+		int ifi;
 
 		INIT(addr,
 			.ip = virtual_ip->clone(virtual_ip),
@@ -1983,26 +1998,30 @@ METHOD(kernel_net_t, add_ip, status_t,
 		);
 		iface->addrs->insert_last(iface->addrs, addr);
 		addr_map_entry_add(this->vips, addr, iface);
+		ifi = iface->ifindex;
+		this->lock->unlock(this->lock);
 		if (manage_ipaddr(this, RTM_NEWADDR, NLM_F_CREATE | NLM_F_EXCL,
-						  iface->ifindex, virtual_ip, prefix) == SUCCESS)
+						  ifi, virtual_ip, prefix) == SUCCESS)
 		{
+			this->lock->write_lock(this->lock);
 			while (!is_vip_installed_or_gone(this, virtual_ip, &entry))
 			{	/* wait until address appears */
 				this->condvar->wait(this->condvar, this->lock);
 			}
 			if (entry)
 			{	/* we fail if the interface got deleted in the meantime */
-				DBG2(DBG_KNL, "virtual IP %H installed on %s", virtual_ip,
-					 entry->iface->ifname);
+				ifname = strdup(entry->iface->ifname);
 				this->lock->unlock(this->lock);
+				DBG2(DBG_KNL, "virtual IP %H installed on %s",
+					 virtual_ip, ifname);
 				/* during IKEv1 reauthentication, children get moved from
 				 * old the new SA before the virtual IP is available. This
 				 * kills the route for our virtual IP, reinstall. */
-				queue_route_reinstall(this, strdup(entry->iface->ifname));
+				queue_route_reinstall(this, ifname);
 				return SUCCESS;
 			}
+			this->lock->unlock(this->lock);
 		}
-		this->lock->unlock(this->lock);
 		DBG1(DBG_KNL, "adding virtual IP %H failed", virtual_ip);
 		return FAILED;
 	}
@@ -2048,20 +2067,23 @@ METHOD(kernel_net_t, del_ip, status_t,
 	if (entry->addr->refcount == 1)
 	{
 		status_t status;
+		int ifi;
 
 		/* we set this flag so that threads calling add_ip will block and wait
 		 * until the entry is gone, also so we can wait below */
 		entry->addr->installed = FALSE;
-		status = manage_ipaddr(this, RTM_DELADDR, 0, entry->iface->ifindex,
-							   virtual_ip, prefix);
+		ifi = entry->iface->ifindex;
+		this->lock->unlock(this->lock);
+		status = manage_ipaddr(this, RTM_DELADDR, 0, ifi, virtual_ip, prefix);
 		if (status == SUCCESS && wait)
 		{	/* wait until the address is really gone */
+			this->lock->write_lock(this->lock);
 			while (is_known_vip(this, virtual_ip))
 			{
 				this->condvar->wait(this->condvar, this->lock);
 			}
+			this->lock->unlock(this->lock);
 		}
-		this->lock->unlock(this->lock);
 		return status;
 	}
 	else
@@ -2490,7 +2512,9 @@ kernel_netlink_net_t *kernel_netlink_net_create()
 				.destroy = _destroy,
 			},
 		},
-		.socket = netlink_socket_create(NETLINK_ROUTE, rt_msg_names),
+		.socket = netlink_socket_create(NETLINK_ROUTE, rt_msg_names,
+			lib->settings->get_bool(lib->settings,
+				"%s.plugins.kernel-netlink.parallel_route", FALSE, lib->ns)),
 		.rt_exclude = linked_list_create(),
 		.routes = hashtable_create((hashtable_hash_t)route_entry_hash,
 								   (hashtable_equals_t)route_entry_equals, 16),
diff --git a/src/libhydra/plugins/kernel_netlink/kernel_netlink_shared.c b/src/libhydra/plugins/kernel_netlink/kernel_netlink_shared.c
index b4cece7..a9adfe0 100644
--- a/src/libhydra/plugins/kernel_netlink/kernel_netlink_shared.c
+++ b/src/libhydra/plugins/kernel_netlink/kernel_netlink_shared.c
@@ -1,4 +1,6 @@
 /*
+ * Copyright (C) 2014 Martin Willi
+ * Copyright (C) 2014 revosec AG
  * Copyright (C) 2008 Tobias Brunner
  * Hochschule fuer Technik Rapperswil
  *
@@ -16,6 +18,7 @@
 #include <sys/socket.h>
 #include <linux/netlink.h>
 #include <linux/rtnetlink.h>
+#include <linux/xfrm.h>
 #include <errno.h>
 #include <unistd.h>
 
@@ -23,6 +26,9 @@
 
 #include <utils/debug.h>
 #include <threading/mutex.h>
+#include <threading/condvar.h>
+#include <collections/array.h>
+#include <collections/hashtable.h>
 
 typedef struct private_netlink_socket_t private_netlink_socket_t;
 
@@ -30,20 +36,26 @@ typedef struct private_netlink_socket_t private_netlink_socket_t;
  * Private variables and functions of netlink_socket_t class.
  */
 struct private_netlink_socket_t {
+
 	/**
 	 * public part of the netlink_socket_t object.
 	 */
 	netlink_socket_t public;
 
 	/**
-	 * mutex to lock access to netlink socket
+	 * mutex to lock access entries
 	 */
 	mutex_t *mutex;
 
 	/**
-	 * current sequence number for netlink request
+	 * Netlink request entries currently active, uintptr_t seq => entry_t
+	 */
+	hashtable_t *entries;
+
+	/**
+	 * Current sequence number for Netlink requests
 	 */
-	int seq;
+	refcount_t seq;
 
 	/**
 	 * netlink socket
@@ -51,119 +63,420 @@ struct private_netlink_socket_t {
 	int socket;
 
 	/**
+	 * Netlink protocol
+	 */
+	int protocol;
+
+	/**
 	 * Enum names for Netlink messages
 	 */
 	enum_name_t *names;
+
+	/**
+	 * Timeout for Netlink replies, in ms
+	 */
+	u_int timeout;
+
+	/**
+	 * Number of times to repeat timed out queries
+	 */
+	u_int retries;
+
+	/**
+	 * Use parallel netlink queries
+	 */
+	bool parallel;
+
+	/**
+	 * Ignore errors potentially resulting from a retransmission
+	 */
+	bool ignore_retransmit_errors;
 };
 
 /**
- * Imported from kernel_netlink_ipsec.c
+ * #definable hook to simulate request message loss
  */
-extern enum_name_t *xfrm_msg_names;
-
-METHOD(netlink_socket_t, netlink_send, status_t,
-	private_netlink_socket_t *this, struct nlmsghdr *in, struct nlmsghdr **out,
-	size_t *out_len)
-{
-	union {
-		struct nlmsghdr hdr;
-		u_char bytes[4096];
-	} response;
-	struct sockaddr_nl addr;
-	chunk_t result = chunk_empty;
-	int len;
+#ifdef NETLINK_MSG_LOSS_HOOK
+bool NETLINK_MSG_LOSS_HOOK(struct nlmsghdr *msg);
+#define msg_loss_hook(msg) NETLINK_MSG_LOSS_HOOK(msg)
+#else
+#define msg_loss_hook(msg) FALSE
+#endif
 
-	this->mutex->lock(this->mutex);
+/**
+ * Request entry the answer for a waiting thread is collected in
+ */
+typedef struct {
+	/** Condition variable thread is waiting */
+	condvar_t *condvar;
+	/** Array of hdrs in a multi-message response, as struct nlmsghdr* */
+	array_t *hdrs;
+	/** All response messages received? */
+	bool complete;
+} entry_t;
 
-	in->nlmsg_seq = ++this->seq;
-	in->nlmsg_pid = getpid();
+/**
+ * Clean up a thread waiting entry
+ */
+static void destroy_entry(entry_t *entry)
+{
+	entry->condvar->destroy(entry->condvar);
+	array_destroy_function(entry->hdrs, (void*)free, NULL);
+	free(entry);
+}
 
-	memset(&addr, 0, sizeof(addr));
-	addr.nl_family = AF_NETLINK;
-	addr.nl_pid = 0;
-	addr.nl_groups = 0;
+/**
+ * Write a Netlink message to socket
+ */
+static bool write_msg(private_netlink_socket_t *this, struct nlmsghdr *msg)
+{
+	struct sockaddr_nl addr = {
+		.nl_family = AF_NETLINK,
+	};
+	int len;
 
-	if (this->names)
+	if (msg_loss_hook(msg))
 	{
-		DBG3(DBG_KNL, "sending %N: %b",
-			 this->names, in->nlmsg_type, in, in->nlmsg_len);
+		return TRUE;
 	}
+
 	while (TRUE)
 	{
-		len = sendto(this->socket, in, in->nlmsg_len, 0,
+		len = sendto(this->socket, msg, msg->nlmsg_len, 0,
 					 (struct sockaddr*)&addr, sizeof(addr));
-
-		if (len != in->nlmsg_len)
+		if (len != msg->nlmsg_len)
 		{
 			if (errno == EINTR)
 			{
-				/* interrupted, try again */
 				continue;
 			}
-			this->mutex->unlock(this->mutex);
-			DBG1(DBG_KNL, "error sending to netlink socket: %s", strerror(errno));
-			return FAILED;
+			DBG1(DBG_KNL, "netlink write error: %s", strerror(errno));
+			return FALSE;
 		}
-		break;
+		return TRUE;
 	}
+}
 
-	while (TRUE)
+/**
+ * Read a single Netlink message from socket, return 0 on error, -1 on timeout
+ */
+static ssize_t read_msg(private_netlink_socket_t *this,
+						char buf[4096], size_t buflen, bool block)
+{
+	ssize_t len;
+
+	if (block)
 	{
-		len = recv(this->socket, &response, sizeof(response), 0);
-		if (len < 0)
+		fd_set set;
+		timeval_t tv = {};
+
+		FD_ZERO(&set);
+		FD_SET(this->socket, &set);
+		timeval_add_ms(&tv, this->timeout);
+
+		if (select(this->socket + 1, &set, NULL, NULL,
+				   this->timeout ? &tv : NULL) <= 0)
 		{
-			if (errno == EINTR)
+			return -1;
+		}
+	}
+	len = recv(this->socket, buf, buflen, block ? 0 : MSG_DONTWAIT);
+	if (len == buflen)
+	{
+		DBG1(DBG_KNL, "netlink response exceeds buffer size");
+		return 0;
+	}
+	if (len < 0)
+	{
+		if (errno != EAGAIN && errno != EWOULDBLOCK && errno != EINTR)
+		{
+			DBG1(DBG_KNL, "netlink read error: %s", strerror(errno));
+		}
+		return 0;
+	}
+	return len;
+}
+
+/**
+ * Queue received response message
+ */
+static bool queue(private_netlink_socket_t *this, struct nlmsghdr *buf)
+{
+	struct nlmsghdr *hdr;
+	entry_t *entry;
+	uintptr_t seq;
+
+	seq = (uintptr_t)buf->nlmsg_seq;
+
+	this->mutex->lock(this->mutex);
+	entry = this->entries->get(this->entries, (void*)seq);
+	if (entry)
+	{
+		hdr = malloc(buf->nlmsg_len);
+		memcpy(hdr, buf, buf->nlmsg_len);
+		array_insert(entry->hdrs, ARRAY_TAIL, hdr);
+		if (hdr->nlmsg_type == NLMSG_DONE || !(hdr->nlmsg_flags & NLM_F_MULTI))
+		{
+			entry->complete = TRUE;
+			entry->condvar->signal(entry->condvar);
+		}
+	}
+	else
+	{
+		DBG1(DBG_KNL, "received unknown netlink seq %u, ignored", seq);
+	}
+	this->mutex->unlock(this->mutex);
+
+	return entry != NULL;
+}
+
+/**
+ * Read and queue response message, optionally blocking, returns TRUE on timeout
+ */
+static bool read_and_queue(private_netlink_socket_t *this, bool block)
+{
+	struct nlmsghdr *hdr;
+	union {
+		struct nlmsghdr hdr;
+		char bytes[4096];
+	} buf;
+	ssize_t len;
+
+	len = read_msg(this, buf.bytes, sizeof(buf.bytes), block);
+	if (len == -1)
+	{
+		return TRUE;
+	}
+	if (len)
+	{
+		hdr = &buf.hdr;
+		while (NLMSG_OK(hdr, len))
+		{
+			if (!queue(this, hdr))
 			{
-				DBG1(DBG_KNL, "got interrupted");
-				/* interrupted, try again */
-				continue;
+				break;
 			}
-			DBG1(DBG_KNL, "error reading from netlink socket: %s", strerror(errno));
-			this->mutex->unlock(this->mutex);
-			free(result.ptr);
-			return FAILED;
+			hdr = NLMSG_NEXT(hdr, len);
 		}
-		if (!NLMSG_OK(&response.hdr, len))
+	}
+	return FALSE;
+}
+
+CALLBACK(watch, bool,
+	private_netlink_socket_t *this, int fd, watcher_event_t event)
+{
+	if (event == WATCHER_READ)
+	{
+		read_and_queue(this, FALSE);
+	}
+	return TRUE;
+}
+
+/**
+ * Send a netlink request, try once
+ */
+static status_t send_once(private_netlink_socket_t *this, struct nlmsghdr *in,
+						  uintptr_t seq, struct nlmsghdr **out, size_t *out_len)
+{
+	struct nlmsghdr *hdr;
+	chunk_t result = {};
+	entry_t *entry;
+
+	in->nlmsg_seq = seq;
+	in->nlmsg_pid = getpid();
+
+	if (this->names)
+	{
+		DBG3(DBG_KNL, "sending %N %u: %b", this->names, in->nlmsg_type,
+			 (u_int)seq, in, in->nlmsg_len);
+	}
+
+	this->mutex->lock(this->mutex);
+	if (!write_msg(this, in))
+	{
+		this->mutex->unlock(this->mutex);
+		return FAILED;
+	}
+
+	INIT(entry,
+		.condvar = condvar_create(CONDVAR_TYPE_DEFAULT),
+		.hdrs = array_create(0, 0),
+	);
+	this->entries->put(this->entries, (void*)seq, entry);
+
+	while (!entry->complete)
+	{
+		if (this->parallel &&
+			lib->watcher->get_state(lib->watcher) == WATCHER_RUNNING)
 		{
-			DBG1(DBG_KNL, "received corrupted netlink message");
-			this->mutex->unlock(this->mutex);
-			free(result.ptr);
-			return FAILED;
+			if (this->timeout)
+			{
+				if (entry->condvar->timed_wait(entry->condvar, this->mutex,
+											   this->timeout))
+				{
+					break;
+				}
+			}
+			else
+			{
+				entry->condvar->wait(entry->condvar, this->mutex);
+			}
 		}
-		if (response.hdr.nlmsg_seq != this->seq)
-		{
-			DBG1(DBG_KNL, "received invalid netlink sequence number");
-			if (response.hdr.nlmsg_seq < this->seq)
+		else
+		{	/* During (de-)initialization, no watcher thread is active.
+			 * collect responses ourselves. */
+			if (read_and_queue(this, TRUE))
 			{
-				continue;
+				break;
 			}
-			this->mutex->unlock(this->mutex);
-			free(result.ptr);
-			return FAILED;
 		}
+	}
+	this->entries->remove(this->entries, (void*)seq);
 
-		result = chunk_cat("mc", result, chunk_create(response.bytes, len));
+	this->mutex->unlock(this->mutex);
 
-		/* NLM_F_MULTI flag does not seem to be set correctly, we use sequence
-		 * numbers to detect multi header messages */
-		len = recv(this->socket, &response.hdr, sizeof(response.hdr),
-				   MSG_PEEK | MSG_DONTWAIT);
-		if (len == sizeof(response.hdr) && response.hdr.nlmsg_seq == this->seq)
+	if (!entry->complete)
+	{	/* timeout */
+		destroy_entry(entry);
+		return OUT_OF_RES;
+	}
+
+	while (array_remove(entry->hdrs, ARRAY_HEAD, &hdr))
+	{
+		if (this->names)
 		{
-			/* seems to be multipart */
-			continue;
+			DBG3(DBG_KNL, "received %N %u: %b", this->names, hdr->nlmsg_type,
+				 hdr->nlmsg_seq, hdr, hdr->nlmsg_len);
 		}
-		break;
+		result = chunk_cat("mm", result,
+						   chunk_create((char*)hdr, hdr->nlmsg_len));
 	}
+	destroy_entry(entry);
 
 	*out_len = result.len;
 	*out = (struct nlmsghdr*)result.ptr;
 
-	this->mutex->unlock(this->mutex);
-
 	return SUCCESS;
 }
 
+/**
+ * Ignore errors for message types that might have completed previously
+ */
+static void ignore_retransmit_error(private_netlink_socket_t *this,
+									struct nlmsgerr *err, int type)
+{
+	switch (err->error)
+	{
+		case -EEXIST:
+			switch (this->protocol)
+			{
+				case NETLINK_XFRM:
+					switch (type)
+					{
+						case XFRM_MSG_NEWPOLICY:
+						case XFRM_MSG_NEWSA:
+							err->error = 0;
+							break;
+					}
+					break;
+				case NETLINK_ROUTE:
+					switch (type)
+					{
+						case RTM_NEWADDR:
+						case RTM_NEWLINK:
+						case RTM_NEWNEIGH:
+						case RTM_NEWROUTE:
+						case RTM_NEWRULE:
+							err->error = 0;
+							break;
+					}
+					break;
+			}
+			break;
+		case -ENOENT:
+			switch (this->protocol)
+			{
+				case NETLINK_XFRM:
+					switch (type)
+					{
+						case XFRM_MSG_DELPOLICY:
+						case XFRM_MSG_DELSA:
+							err->error = 0;
+							break;
+					}
+					break;
+				case NETLINK_ROUTE:
+					switch (type)
+					{
+						case RTM_DELADDR:
+						case RTM_DELLINK:
+						case RTM_DELNEIGH:
+						case RTM_DELROUTE:
+						case RTM_DELRULE:
+							err->error = 0;
+							break;
+					}
+					break;
+			}
+			break;
+	}
+}
+
+METHOD(netlink_socket_t, netlink_send, status_t,
+	private_netlink_socket_t *this, struct nlmsghdr *in, struct nlmsghdr **out,
+	size_t *out_len)
+{
+	uintptr_t seq;
+	u_int try;
+
+	seq = ref_get(&this->seq);
+
+	for (try = 0; try <= this->retries; ++try)
+	{
+		struct nlmsghdr *hdr;
+		status_t status;
+		size_t len;
+
+		if (try > 0)
+		{
+			DBG1(DBG_KNL, "retransmitting Netlink request (%u/%u)",
+				 try, this->retries);
+		}
+		status = send_once(this, in, seq, &hdr, &len);
+		switch (status)
+		{
+			case SUCCESS:
+				break;
+			case OUT_OF_RES:
+				continue;
+			default:
+				return status;
+		}
+		if (hdr->nlmsg_type == NLMSG_ERROR)
+		{
+			struct nlmsgerr* err;
+
+			err = NLMSG_DATA(hdr);
+			if (err->error == -EBUSY)
+			{
+				free(hdr);
+				try--;
+				continue;
+			}
+			if (this->ignore_retransmit_errors && try > 0)
+			{
+				ignore_retransmit_error(this, err, in->nlmsg_type);
+			}
+		}
+		*out = hdr;
+		*out_len = len;
+		return SUCCESS;
+	}
+	DBG1(DBG_KNL, "Netlink request timed out after %u retransmits",
+		 this->retries);
+	return OUT_OF_RES;
+}
+
 METHOD(netlink_socket_t, netlink_send_ack, status_t,
 	private_netlink_socket_t *this, struct nlmsghdr *in)
 {
@@ -221,8 +534,13 @@ METHOD(netlink_socket_t, destroy, void,
 {
 	if (this->socket != -1)
 	{
+		if (this->parallel)
+		{
+			lib->watcher->remove(lib->watcher, this->socket);
+		}
 		close(this->socket);
 	}
+	this->entries->destroy(this->entries);
 	this->mutex->destroy(this->mutex);
 	free(this);
 }
@@ -230,7 +548,8 @@ METHOD(netlink_socket_t, destroy, void,
 /**
  * Described in header.
  */
-netlink_socket_t *netlink_socket_create(int protocol, enum_name_t *names)
+netlink_socket_t *netlink_socket_create(int protocol, enum_name_t *names,
+										bool parallel)
 {
 	private_netlink_socket_t *this;
 	struct sockaddr_nl addr = {
@@ -244,9 +563,19 @@ netlink_socket_t *netlink_socket_create(int protocol, enum_name_t *names)
 			.destroy = _destroy,
 		},
 		.seq = 200,
-		.mutex = mutex_create(MUTEX_TYPE_DEFAULT),
+		.mutex = mutex_create(MUTEX_TYPE_RECURSIVE),
 		.socket = socket(AF_NETLINK, SOCK_RAW, protocol),
+		.entries = hashtable_create(hashtable_hash_ptr, hashtable_equals_ptr, 4),
+		.protocol = protocol,
 		.names = names,
+		.timeout = lib->settings->get_int(lib->settings,
+							"%s.plugins.kernel-netlink.timeout", 0, lib->ns),
+		.retries = lib->settings->get_int(lib->settings,
+							"%s.plugins.kernel-netlink.retries", 0, lib->ns),
+		.ignore_retransmit_errors = lib->settings->get_bool(lib->settings,
+							"%s.plugins.kernel-netlink.ignore_retransmit_errors",
+							FALSE, lib->ns),
+		.parallel = parallel,
 	);
 
 	if (this->socket == -1)
@@ -261,6 +590,10 @@ netlink_socket_t *netlink_socket_create(int protocol, enum_name_t *names)
 		destroy(this);
 		return NULL;
 	}
+	if (this->parallel)
+	{
+		lib->watcher->add(lib->watcher, this->socket, WATCHER_READ, watch, this);
+	}
 
 	return &this->public;
 }
diff --git a/src/libhydra/plugins/kernel_netlink/kernel_netlink_shared.h b/src/libhydra/plugins/kernel_netlink/kernel_netlink_shared.h
index 069f746..6668290 100644
--- a/src/libhydra/plugins/kernel_netlink/kernel_netlink_shared.h
+++ b/src/libhydra/plugins/kernel_netlink/kernel_netlink_shared.h
@@ -66,8 +66,10 @@ struct netlink_socket_t {
  *
  * @param protocol	protocol type (e.g. NETLINK_XFRM or NETLINK_ROUTE)
  * @param names		optional enum names for Netlink messages
+ * @param parallel	support parallel queries on this Netlink socket
  */
-netlink_socket_t *netlink_socket_create(int protocol, enum_name_t *names);
+netlink_socket_t *netlink_socket_create(int protocol, enum_name_t *names,
+										bool parallel);
 
 /**
  * Creates an rtattr and adds it to the given netlink message.
diff --git a/src/libhydra/plugins/kernel_netlink/suites/test_socket.c b/src/libhydra/plugins/kernel_netlink/suites/test_socket.c
new file mode 100644
index 0000000..3e8facd
--- /dev/null
+++ b/src/libhydra/plugins/kernel_netlink/suites/test_socket.c
@@ -0,0 +1,302 @@
+/*
+ * Copyright (C) 2014 Martin Willi
+ * Copyright (C) 2014 revosec AG
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * for more details.
+ */
+
+#include <test_suite.h>
+
+#include <threading/thread.h>
+
+#include "../kernel_netlink_shared.h"
+
+/**
+ * Netlink message drop configuration
+ */
+static int drop_interval = 0;
+
+/**
+ * Netlink message drop hook
+ */
+bool netlink_msg_loss(struct nlmsghdr *hdr)
+{
+	static refcount_t i;
+
+	if (drop_interval)
+	{
+		return ref_get(&i) % drop_interval == drop_interval - 1;
+	}
+	return FALSE;
+}
+
+START_TEST(test_echo)
+{
+	netlink_socket_t *s;
+	struct nlmsghdr *out;
+	struct rtmsg *msg;
+	char dst[] = {
+		127,0,0,1
+	};
+	size_t len;
+	netlink_buf_t request = {
+		.hdr = {
+			.nlmsg_len = NLMSG_LENGTH(sizeof(struct rtmsg)),
+			.nlmsg_flags = NLM_F_REQUEST,
+			.nlmsg_type = RTM_GETROUTE,
+		},
+	};
+
+	msg = NLMSG_DATA(&request.hdr);
+	msg->rtm_family = AF_INET;
+	netlink_add_attribute(&request.hdr, RTA_DST,
+						  chunk_from_thing(dst), sizeof(request));
+
+	s = netlink_socket_create(NETLINK_ROUTE, NULL, _i != 0);
+
+	ck_assert(s->send(s, &request.hdr, &out, &len) == SUCCESS);
+	ck_assert_int_eq(out->nlmsg_type, RTM_NEWROUTE);
+	free(out);
+	s->destroy(s);
+}
+END_TEST
+
+START_TEST(test_echo_dump)
+{
+	netlink_socket_t *s;
+	struct nlmsghdr *out, *current;
+	struct rtgenmsg *msg;
+	size_t len;
+	netlink_buf_t request = {
+		.hdr = {
+			.nlmsg_len = NLMSG_LENGTH(sizeof(struct rtgenmsg)),
+			.nlmsg_flags = NLM_F_REQUEST | NLM_F_MATCH | NLM_F_ROOT,
+			.nlmsg_type = RTM_GETLINK,
+		},
+	};
+
+	s = netlink_socket_create(NETLINK_ROUTE, NULL, _i != 0);
+	msg = NLMSG_DATA(&request.hdr);
+	msg->rtgen_family = AF_UNSPEC;
+
+	ck_assert(s->send(s, &request.hdr, &out, &len) == SUCCESS);
+	current = out;
+	while (TRUE)
+	{
+		ck_assert(NLMSG_OK(current, len));
+		if (current->nlmsg_type == NLMSG_DONE)
+		{
+			break;
+		}
+		ck_assert_int_eq(current->nlmsg_type, RTM_NEWLINK);
+		current = NLMSG_NEXT(current, len);
+	}
+	free(out);
+	s->destroy(s);
+}
+END_TEST
+
+CALLBACK(stress, void*,
+	netlink_socket_t *s)
+{
+	struct nlmsghdr *out;
+	struct rtmsg *msg;
+	char dst[] = {
+		127,0,0,1
+	};
+	size_t len;
+	int i;
+	netlink_buf_t request = {
+		.hdr = {
+			.nlmsg_len = NLMSG_LENGTH(sizeof(struct rtmsg)),
+			.nlmsg_flags = NLM_F_REQUEST,
+			.nlmsg_type = RTM_GETROUTE,
+		},
+	};
+
+	for (i = 0; i < 10; i++)
+	{
+		msg = NLMSG_DATA(&request.hdr);
+		msg->rtm_family = AF_INET;
+		netlink_add_attribute(&request.hdr, RTA_DST,
+							  chunk_from_thing(dst), sizeof(request));
+
+		ck_assert(s->send(s, &request.hdr, &out, &len) == SUCCESS);
+		ck_assert_int_eq(out->nlmsg_type, RTM_NEWROUTE);
+		free(out);
+	}
+	return NULL;
+}
+
+CALLBACK(stress_dump, void*,
+	netlink_socket_t *s)
+{
+	struct nlmsghdr *out, *current;
+	struct rtgenmsg *msg;
+	size_t len;
+	int i;
+	netlink_buf_t request = {
+		.hdr = {
+			.nlmsg_len = NLMSG_LENGTH(sizeof(struct rtgenmsg)),
+			.nlmsg_flags = NLM_F_REQUEST | NLM_F_MATCH | NLM_F_ROOT,
+			.nlmsg_type = RTM_GETLINK,
+		},
+	};
+
+	msg = NLMSG_DATA(&request.hdr);
+	msg->rtgen_family = AF_UNSPEC;
+
+	for (i = 0; i < 10; i++)
+	{
+		ck_assert(s->send(s, &request.hdr, &out, &len) == SUCCESS);
+		current = out;
+		while (TRUE)
+		{
+			ck_assert(NLMSG_OK(current, len));
+			if (current->nlmsg_type == NLMSG_DONE)
+			{
+				break;
+			}
+			ck_assert_int_eq(current->nlmsg_type, RTM_NEWLINK);
+			current = NLMSG_NEXT(current, len);
+		}
+		free(out);
+	}
+	return NULL;
+}
+
+START_TEST(test_stress)
+{
+	thread_t *threads[10];
+	netlink_socket_t *s;
+	int i;
+
+	s = netlink_socket_create(NETLINK_ROUTE, NULL, _i != 0);
+	for (i = 0; i < countof(threads); i++)
+	{
+		threads[i] = thread_create(stress, s);
+	}
+	for (i = 0; i < countof(threads); i++)
+	{
+		threads[i]->join(threads[i]);
+	}
+	s->destroy(s);
+}
+END_TEST
+
+START_TEST(test_stress_dump)
+{
+	thread_t *threads[10];
+	netlink_socket_t *s;
+	int i;
+
+	s = netlink_socket_create(NETLINK_ROUTE, NULL, _i != 0);
+	for (i = 0; i < countof(threads); i++)
+	{
+		threads[i] = thread_create(stress_dump, s);
+	}
+	for (i = 0; i < countof(threads); i++)
+	{
+		threads[i]->join(threads[i]);
+	}
+	s->destroy(s);
+}
+END_TEST
+
+START_TEST(test_retransmit_success)
+{
+	netlink_socket_t *s;
+	struct nlmsghdr *out;
+	struct rtgenmsg *msg;
+	size_t len;
+	netlink_buf_t request = {
+		.hdr = {
+			.nlmsg_len = NLMSG_LENGTH(sizeof(struct rtgenmsg)),
+			.nlmsg_flags = NLM_F_REQUEST | NLM_F_MATCH | NLM_F_ROOT,
+			.nlmsg_type = RTM_GETLINK,
+		},
+	};
+
+	drop_interval = 2;
+
+	lib->settings->set_int(lib->settings,
+							"%s.plugins.kernel-netlink.timeout", 100, lib->ns);
+	lib->settings->set_int(lib->settings,
+							"%s.plugins.kernel-netlink.retries", 1, lib->ns);
+
+	s = netlink_socket_create(NETLINK_ROUTE, NULL, _i != 0);
+	msg = NLMSG_DATA(&request.hdr);
+	msg->rtgen_family = AF_UNSPEC;
+
+	ck_assert(s->send(s, &request.hdr, &out, &len) == SUCCESS);
+	free(out);
+	s->destroy(s);
+
+	drop_interval = 0;
+}
+END_TEST
+
+START_TEST(test_retransmit_fail)
+{
+	netlink_socket_t *s;
+	struct nlmsghdr *out;
+	struct rtgenmsg *msg;
+	size_t len;
+	netlink_buf_t request = {
+		.hdr = {
+			.nlmsg_len = NLMSG_LENGTH(sizeof(struct rtgenmsg)),
+			.nlmsg_flags = NLM_F_REQUEST | NLM_F_MATCH | NLM_F_ROOT,
+			.nlmsg_type = RTM_GETLINK,
+		},
+	};
+
+	drop_interval = 1;
+
+	lib->settings->set_int(lib->settings,
+							"%s.plugins.kernel-netlink.timeout", 50, lib->ns);
+	lib->settings->set_int(lib->settings,
+							"%s.plugins.kernel-netlink.retries", 3, lib->ns);
+
+	s = netlink_socket_create(NETLINK_ROUTE, NULL, _i != 0);
+	msg = NLMSG_DATA(&request.hdr);
+	msg->rtgen_family = AF_UNSPEC;
+
+	ck_assert(s->send(s, &request.hdr, &out, &len) == OUT_OF_RES);
+	s->destroy(s);
+
+	drop_interval = 0;
+}
+END_TEST
+
+Suite *socket_suite_create()
+{
+	Suite *s;
+	TCase *tc;
+
+	s = suite_create("netlink socket");
+
+	tc = tcase_create("echo");
+	tcase_add_loop_test(tc, test_echo, 0, 2);
+	tcase_add_loop_test(tc, test_echo_dump, 0, 2);
+	suite_add_tcase(s, tc);
+
+	tc = tcase_create("stress");
+	tcase_add_loop_test(tc, test_stress, 0, 2);
+	tcase_add_loop_test(tc, test_stress_dump, 0, 2);
+	suite_add_tcase(s, tc);
+
+	tc = tcase_create("retransmit");
+	tcase_add_loop_test(tc, test_retransmit_success, 0, 2);
+	tcase_add_loop_test(tc, test_retransmit_fail, 0, 2);
+	suite_add_tcase(s, tc);
+
+	return s;
+}
diff --git a/src/libhydra/plugins/kernel_netlink/tests.c b/src/libhydra/plugins/kernel_netlink/tests.c
new file mode 100644
index 0000000..136b34d
--- /dev/null
+++ b/src/libhydra/plugins/kernel_netlink/tests.c
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2014 Martin Willi
+ * Copyright (C) 2014 revosec AG
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * for more details.
+ */
+
+#include <test_runner.h>
+
+#include <hydra.h>
+
+/* declare test suite constructors */
+#define TEST_SUITE(x) test_suite_t* x();
+#include "tests.h"
+#undef TEST_SUITE
+
+static test_configuration_t tests[] = {
+#define TEST_SUITE(x) \
+	{ .suite = x, },
+#include "tests.h"
+	{ .suite = NULL, }
+};
+
+static bool test_runner_init(bool init)
+{
+	if (init)
+	{
+		dbg_default_set_level(0);
+		lib->processor->set_threads(lib->processor, 8);
+		dbg_default_set_level(1);
+	}
+	else
+	{
+		lib->processor->set_threads(lib->processor, 0);
+		lib->processor->cancel(lib->processor);
+	}
+	return TRUE;
+}
+
+int main(int argc, char *argv[])
+{
+	return test_runner_run("kernel-netlink", tests, test_runner_init);
+}
diff --git a/src/libhydra/plugins/kernel_netlink/tests.h b/src/libhydra/plugins/kernel_netlink/tests.h
new file mode 100644
index 0000000..2b6715a
--- /dev/null
+++ b/src/libhydra/plugins/kernel_netlink/tests.h
@@ -0,0 +1,16 @@
+/*
+ * Copyright (C) 2014 Martin Willi
+ * Copyright (C) 2014 revosec AG
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * for more details.
+ */
+
+TEST_SUITE(socket_suite_create)
diff --git a/src/libhydra/plugins/kernel_pfkey/Makefile.in b/src/libhydra/plugins/kernel_pfkey/Makefile.in
index 821ad77..177d2f2 100644
--- a/src/libhydra/plugins/kernel_pfkey/Makefile.in
+++ b/src/libhydra/plugins/kernel_pfkey/Makefile.in
@@ -229,6 +229,7 @@ DLLIB = @DLLIB@
 DLLTOOL = @DLLTOOL@
 DSYMUTIL = @DSYMUTIL@
 DUMPBIN = @DUMPBIN@
+EASY_INSTALL = @EASY_INSTALL@
 ECHO_C = @ECHO_C@
 ECHO_N = @ECHO_N@
 ECHO_T = @ECHO_T@
@@ -289,10 +290,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
 PLUGIN_CFLAGS = @PLUGIN_CFLAGS@
 PTHREADLIB = @PTHREADLIB@
 PYTHON = @PYTHON@
+PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@
 PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
 PYTHON_PLATFORM = @PYTHON_PLATFORM@
 PYTHON_PREFIX = @PYTHON_PREFIX@
 PYTHON_VERSION = @PYTHON_VERSION@
+PY_TEST = @PY_TEST@
 RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
@@ -366,6 +369,8 @@ json_CFLAGS = @json_CFLAGS@
 json_LIBS = @json_LIBS@
 libdir = @libdir@
 libexecdir = @libexecdir@
+libiptc_CFLAGS = @libiptc_CFLAGS@
+libiptc_LIBS = @libiptc_LIBS@
 linux_headers = @linux_headers@
 localedir = @localedir@
 localstatedir = @localstatedir@
diff --git a/src/libhydra/plugins/kernel_pfkey/kernel_pfkey_ipsec.c b/src/libhydra/plugins/kernel_pfkey/kernel_pfkey_ipsec.c
index 00ab5ab..3b32ba5 100644
--- a/src/libhydra/plugins/kernel_pfkey/kernel_pfkey_ipsec.c
+++ b/src/libhydra/plugins/kernel_pfkey/kernel_pfkey_ipsec.c
@@ -1296,7 +1296,8 @@ static void process_expire(private_kernel_pfkey_ipsec_t *this,
 {
 	pfkey_msg_t response;
 	u_int8_t protocol;
-	u_int32_t spi, reqid;
+	u_int32_t spi;
+	host_t *dst;
 	bool hard;
 
 	DBG2(DBG_KNL, "received an SADB_EXPIRE");
@@ -1309,18 +1310,18 @@ static void process_expire(private_kernel_pfkey_ipsec_t *this,
 
 	protocol = satype2proto(msg->sadb_msg_satype);
 	spi = response.sa->sadb_sa_spi;
-	reqid = response.x_sa2->sadb_x_sa2_reqid;
 	hard = response.lft_hard != NULL;
 
-	if (protocol != IPPROTO_ESP && protocol != IPPROTO_AH)
+	if (protocol == IPPROTO_ESP || protocol == IPPROTO_AH)
 	{
-		DBG2(DBG_KNL, "ignoring SADB_EXPIRE for SA with SPI %.8x and "
-					  "reqid {%u} which is not a CHILD_SA", ntohl(spi), reqid);
-		return;
+		dst = host_create_from_sockaddr((sockaddr_t*)(response.dst + 1));
+		if (dst)
+		{
+			hydra->kernel_interface->expire(hydra->kernel_interface, protocol,
+											spi, dst, hard);
+			dst->destroy(dst);
+		}
 	}
-
-	hydra->kernel_interface->expire(hydra->kernel_interface, reqid, protocol,
-									spi, hard);
 }
 
 #ifdef SADB_X_MIGRATE
@@ -1387,9 +1388,9 @@ static void process_mapping(private_kernel_pfkey_ipsec_t *this,
 							struct sadb_msg* msg)
 {
 	pfkey_msg_t response;
-	u_int32_t spi, reqid;
+	u_int32_t spi;
 	sockaddr_t *sa;
-	host_t *host;
+	host_t *dst, *new;
 
 	DBG2(DBG_KNL, "received an SADB_X_NAT_T_NEW_MAPPING");
 
@@ -1407,7 +1408,6 @@ static void process_mapping(private_kernel_pfkey_ipsec_t *this,
 	}
 
 	spi = response.sa->sadb_sa_spi;
-	reqid = response.x_sa2->sadb_x_sa2_reqid;
 
 	if (satype2proto(msg->sadb_msg_satype) != IPPROTO_ESP)
 	{
@@ -1415,6 +1415,7 @@ static void process_mapping(private_kernel_pfkey_ipsec_t *this,
 	}
 
 	sa = (sockaddr_t*)(response.dst + 1);
+	dst = host_create_from_sockaddr(sa);
 	switch (sa->sa_family)
 	{
 		case AF_INET:
@@ -1432,12 +1433,16 @@ static void process_mapping(private_kernel_pfkey_ipsec_t *this,
 		default:
 			break;
 	}
-
-	host = host_create_from_sockaddr(sa);
-	if (host)
+	if (dst)
 	{
-		hydra->kernel_interface->mapping(hydra->kernel_interface, reqid,
-										 spi, host);
+		new = host_create_from_sockaddr(sa);
+		if (new)
+		{
+			hydra->kernel_interface->mapping(hydra->kernel_interface,
+											 IPPROTO_ESP, spi, dst, new);
+			new->destroy(new);
+		}
+		dst->destroy(dst);
 	}
 }
 #endif /*SADB_X_NAT_T_NEW_MAPPING*/
@@ -1518,11 +1523,10 @@ static bool receive_events(private_kernel_pfkey_ipsec_t *this, int fd,
 
 static status_t get_spi_internal(private_kernel_pfkey_ipsec_t *this,
 	host_t *src, host_t *dst, u_int8_t proto, u_int32_t min, u_int32_t max,
-	u_int32_t reqid, u_int32_t *spi)
+	u_int32_t *spi)
 {
 	unsigned char request[PFKEY_BUFFER_SIZE];
 	struct sadb_msg *msg, *out;
-	struct sadb_x_sa2 *sa2;
 	struct sadb_spirange *range;
 	pfkey_msg_t response;
 	u_int32_t received_spi = 0;
@@ -1536,12 +1540,6 @@ static status_t get_spi_internal(private_kernel_pfkey_ipsec_t *this,
 	msg->sadb_msg_satype = proto2satype(proto);
 	msg->sadb_msg_len = PFKEY_LEN(sizeof(struct sadb_msg));
 
-	sa2 = (struct sadb_x_sa2*)PFKEY_EXT_ADD_NEXT(msg);
-	sa2->sadb_x_sa2_exttype = SADB_X_EXT_SA2;
-	sa2->sadb_x_sa2_len = PFKEY_LEN(sizeof(struct sadb_spirange));
-	sa2->sadb_x_sa2_reqid = reqid;
-	PFKEY_EXT_ADD(msg, sa2);
-
 	add_addr_ext(msg, src, SADB_EXT_ADDRESS_SRC, 0, 0, FALSE);
 	add_addr_ext(msg, dst, SADB_EXT_ADDRESS_DST, 0, 0, FALSE);
 
@@ -1577,39 +1575,37 @@ static status_t get_spi_internal(private_kernel_pfkey_ipsec_t *this,
 
 METHOD(kernel_ipsec_t, get_spi, status_t,
 	private_kernel_pfkey_ipsec_t *this, host_t *src, host_t *dst,
-	u_int8_t protocol, u_int32_t reqid, u_int32_t *spi)
+	u_int8_t protocol, u_int32_t *spi)
 {
-	DBG2(DBG_KNL, "getting SPI for reqid {%u}", reqid);
-
 	if (get_spi_internal(this, src, dst, protocol,
-						 0xc0000000, 0xcFFFFFFF, reqid, spi) != SUCCESS)
+						 0xc0000000, 0xcFFFFFFF, spi) != SUCCESS)
 	{
-		DBG1(DBG_KNL, "unable to get SPI for reqid {%u}", reqid);
+		DBG1(DBG_KNL, "unable to get SPI");
 		return FAILED;
 	}
 
-	DBG2(DBG_KNL, "got SPI %.8x for reqid {%u}", ntohl(*spi), reqid);
+	DBG2(DBG_KNL, "got SPI %.8x", ntohl(*spi));
 	return SUCCESS;
 }
 
 METHOD(kernel_ipsec_t, get_cpi, status_t,
 	private_kernel_pfkey_ipsec_t *this, host_t *src, host_t *dst,
-	u_int32_t reqid, u_int16_t *cpi)
+	u_int16_t *cpi)
 {
 	u_int32_t received_spi = 0;
 
-	DBG2(DBG_KNL, "getting CPI for reqid {%u}", reqid);
+	DBG2(DBG_KNL, "getting CPI");
 
 	if (get_spi_internal(this, src, dst, IPPROTO_COMP,
-						 0x100, 0xEFFF, reqid, &received_spi) != SUCCESS)
+						 0x100, 0xEFFF, &received_spi) != SUCCESS)
 	{
-		DBG1(DBG_KNL, "unable to get CPI for reqid {%u}", reqid);
+		DBG1(DBG_KNL, "unable to get CPI");
 		return FAILED;
 	}
 
 	*cpi = htons((u_int16_t)ntohl(received_spi));
 
-	DBG2(DBG_KNL, "got CPI %.4x for reqid {%u}", ntohs(*cpi), reqid);
+	DBG2(DBG_KNL, "got CPI %.4x", ntohs(*cpi));
 	return SUCCESS;
 }
 
@@ -1619,8 +1615,8 @@ METHOD(kernel_ipsec_t, add_sa, status_t,
 	lifetime_cfg_t *lifetime, u_int16_t enc_alg, chunk_t enc_key,
 	u_int16_t int_alg, chunk_t int_key, ipsec_mode_t mode,
 	u_int16_t ipcomp, u_int16_t cpi, u_int32_t replay_window,
-	bool initiator, bool encap, bool esn, bool inbound,
-	traffic_selector_t *src_ts, traffic_selector_t *dst_ts)
+	bool initiator, bool encap, bool esn, bool inbound, bool update,
+	linked_list_t *src_ts, linked_list_t *dst_ts)
 {
 	unsigned char request[PFKEY_BUFFER_SIZE];
 	struct sadb_msg *msg, *out;
@@ -1638,12 +1634,29 @@ METHOD(kernel_ipsec_t, add_sa, status_t,
 		add_sa(this, src, dst, htonl(ntohs(cpi)), IPPROTO_COMP, reqid, mark,
 			   tfc, &lft, ENCR_UNDEFINED, chunk_empty, AUTH_UNDEFINED,
 			   chunk_empty, mode, ipcomp, 0, 0, FALSE, FALSE, FALSE, inbound,
-			   NULL, NULL);
+			   update, NULL, NULL);
 		ipcomp = IPCOMP_NONE;
 		/* use transport mode ESP SA, IPComp uses tunnel mode */
 		mode = MODE_TRANSPORT;
 	}
 
+	if (update)
+	{
+		/* As we didn't know the reqid during SPI allocation, we used reqid
+		 * zero. Unfortunately we can't SADB_UPDATE to the new reqid, hence we
+		 * have to delete the SPI allocation state manually. The reqid
+		 * selector does not count for that, therefore we have to delete
+		 * that state before installing the new SA to avoid deleting the
+		 * the new state after installing it. */
+		mark_t zeromark = {0, 0};
+
+		if (this->public.interface.del_sa(&this->public.interface,
+					src, dst, spi, protocol, 0, zeromark) != SUCCESS)
+		{
+			DBG1(DBG_KNL, "deleting SPI allocation SA failed");
+		}
+	}
+
 	memset(&request, 0, sizeof(request));
 
 	DBG2(DBG_KNL, "adding SAD entry with SPI %.8x and reqid {%u}",
@@ -1651,7 +1664,7 @@ METHOD(kernel_ipsec_t, add_sa, status_t,
 
 	msg = (struct sadb_msg*)request;
 	msg->sadb_msg_version = PF_KEY_V2;
-	msg->sadb_msg_type = inbound ? SADB_UPDATE : SADB_ADD;
+	msg->sadb_msg_type = SADB_ADD;
 	msg->sadb_msg_satype = proto2satype(protocol);
 	msg->sadb_msg_len = PFKEY_LEN(sizeof(struct sadb_msg));
 
@@ -1680,7 +1693,13 @@ METHOD(kernel_ipsec_t, add_sa, status_t,
 	}
 	else
 	{
+		/* Linux interprets sadb_sa_replay as number of packets/bits in the
+		 * replay window, whereas on BSD it's the size of the window in bytes */
+#ifdef __linux__
 		sa->sadb_sa_replay = min(replay_window, 32);
+#else
+		sa->sadb_sa_replay = (replay_window + 7) / 8;
+#endif
 		sa->sadb_sa_auth = lookup_algorithm(INTEGRITY_ALGORITHM, int_alg);
 		sa->sadb_sa_encrypt = lookup_algorithm(ENCRYPTION_ALGORITHM, enc_alg);
 	}
@@ -2969,6 +2988,7 @@ kernel_pfkey_ipsec_t *kernel_pfkey_ipsec_create()
 {
 	private_kernel_pfkey_ipsec_t *this;
 	bool register_for_events = TRUE;
+	int rcv_buffer;
 
 	INIT(this,
 		.public = {
@@ -3025,6 +3045,18 @@ kernel_pfkey_ipsec_t *kernel_pfkey_ipsec_create()
 			return NULL;
 		}
 
+		rcv_buffer = lib->settings->get_int(lib->settings,
+					"%s.plugins.kernel-pfkey.events_buffer_size", 0, lib->ns);
+		if (rcv_buffer > 0)
+		{
+			if (setsockopt(this->socket_events, SOL_SOCKET, SO_RCVBUF,
+						   &rcv_buffer, sizeof(rcv_buffer)) == -1)
+			{
+				DBG1(DBG_KNL, "unable to set receive buffer size on PF_KEY "
+					 "event socket: %s", strerror(errno));
+			}
+		}
+
 		/* register the event socket */
 		if (register_pfkey_socket(this, SADB_SATYPE_ESP) != SUCCESS ||
 			register_pfkey_socket(this, SADB_SATYPE_AH) != SUCCESS)
diff --git a/src/libhydra/plugins/kernel_pfroute/Makefile.in b/src/libhydra/plugins/kernel_pfroute/Makefile.in
index 662f2fd..9f676d2 100644
--- a/src/libhydra/plugins/kernel_pfroute/Makefile.in
+++ b/src/libhydra/plugins/kernel_pfroute/Makefile.in
@@ -229,6 +229,7 @@ DLLIB = @DLLIB@
 DLLTOOL = @DLLTOOL@
 DSYMUTIL = @DSYMUTIL@
 DUMPBIN = @DUMPBIN@
+EASY_INSTALL = @EASY_INSTALL@
 ECHO_C = @ECHO_C@
 ECHO_N = @ECHO_N@
 ECHO_T = @ECHO_T@
@@ -289,10 +290,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
 PLUGIN_CFLAGS = @PLUGIN_CFLAGS@
 PTHREADLIB = @PTHREADLIB@
 PYTHON = @PYTHON@
+PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@
 PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
 PYTHON_PLATFORM = @PYTHON_PLATFORM@
 PYTHON_PREFIX = @PYTHON_PREFIX@
 PYTHON_VERSION = @PYTHON_VERSION@
+PY_TEST = @PY_TEST@
 RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
@@ -366,6 +369,8 @@ json_CFLAGS = @json_CFLAGS@
 json_LIBS = @json_LIBS@
 libdir = @libdir@
 libexecdir = @libexecdir@
+libiptc_CFLAGS = @libiptc_CFLAGS@
+libiptc_LIBS = @libiptc_LIBS@
 linux_headers = @linux_headers@
 localedir = @localedir@
 localstatedir = @localstatedir@
diff --git a/src/libhydra/plugins/kernel_pfroute/kernel_pfroute_net.c b/src/libhydra/plugins/kernel_pfroute/kernel_pfroute_net.c
index 26fae0d..0f78022 100644
--- a/src/libhydra/plugins/kernel_pfroute/kernel_pfroute_net.c
+++ b/src/libhydra/plugins/kernel_pfroute/kernel_pfroute_net.c
@@ -830,6 +830,15 @@ static void process_link(private_kernel_pfroute_net_t *this,
 					DBG1(DBG_KNL, "interface %s deactivated", iface->ifname);
 				}
 			}
+#ifdef __APPLE__
+			/* There seems to be a race condition on 10.10, where we get
+			 * the RTM_IFINFO, but getifaddrs() does not return the virtual
+			 * IP installed on a tun device, but we also don't get a
+			 * RTM_NEWADDR. We therefore could miss the new address, letting
+			 * virtual IP installation fail. Delaying getifaddrs() helps,
+			 * but is obviously not a clean fix. */
+			usleep(50000);
+#endif
 			iface->flags = msg->ifm_flags;
 			repopulate_iface(this, iface);
 			found = TRUE;
diff --git a/src/libhydra/plugins/resolve/Makefile.am b/src/libhydra/plugins/resolve/Makefile.am
deleted file mode 100644
index 33c3e70..0000000
--- a/src/libhydra/plugins/resolve/Makefile.am
+++ /dev/null
@@ -1,19 +0,0 @@
-AM_CPPFLAGS = \
-	-I$(top_srcdir)/src/libstrongswan \
-	-I$(top_srcdir)/src/libhydra \
-	-DRESOLV_CONF=\"${resolv_conf}\"
-
-AM_CFLAGS = \
-	$(PLUGIN_CFLAGS)
-
-if MONOLITHIC
-noinst_LTLIBRARIES = libstrongswan-resolve.la
-else
-plugin_LTLIBRARIES = libstrongswan-resolve.la
-endif
-
-libstrongswan_resolve_la_SOURCES = \
-	resolve_plugin.h resolve_plugin.c \
-	resolve_handler.h resolve_handler.c
-
-libstrongswan_resolve_la_LDFLAGS = -module -avoid-version
diff --git a/src/libhydra/plugins/resolve/Makefile.in b/src/libhydra/plugins/resolve/Makefile.in
deleted file mode 100644
index 5b4c7bc..0000000
--- a/src/libhydra/plugins/resolve/Makefile.in
+++ /dev/null
@@ -1,775 +0,0 @@
-# Makefile.in generated by automake 1.14.1 from Makefile.am.
-# @configure_input@
-
-# Copyright (C) 1994-2013 Free Software Foundation, Inc.
-
-# This Makefile.in is free software; the Free Software Foundation
-# gives unlimited permission to copy and/or distribute it,
-# with or without modifications, as long as this notice is preserved.
-
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
-# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
-# PARTICULAR PURPOSE.
-
- at SET_MAKE@
-
-VPATH = @srcdir@
-am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)'
-am__make_running_with_option = \
-  case $${target_option-} in \
-      ?) ;; \
-      *) echo "am__make_running_with_option: internal error: invalid" \
-              "target option '$${target_option-}' specified" >&2; \
-         exit 1;; \
-  esac; \
-  has_opt=no; \
-  sane_makeflags=$$MAKEFLAGS; \
-  if $(am__is_gnu_make); then \
-    sane_makeflags=$$MFLAGS; \
-  else \
-    case $$MAKEFLAGS in \
-      *\\[\ \	]*) \
-        bs=\\; \
-        sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
-          | sed "s/$$bs$$bs[$$bs $$bs	]*//g"`;; \
-    esac; \
-  fi; \
-  skip_next=no; \
-  strip_trailopt () \
-  { \
-    flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
-  }; \
-  for flg in $$sane_makeflags; do \
-    test $$skip_next = yes && { skip_next=no; continue; }; \
-    case $$flg in \
-      *=*|--*) continue;; \
-        -*I) strip_trailopt 'I'; skip_next=yes;; \
-      -*I?*) strip_trailopt 'I';; \
-        -*O) strip_trailopt 'O'; skip_next=yes;; \
-      -*O?*) strip_trailopt 'O';; \
-        -*l) strip_trailopt 'l'; skip_next=yes;; \
-      -*l?*) strip_trailopt 'l';; \
-      -[dEDm]) skip_next=yes;; \
-      -[JT]) skip_next=yes;; \
-    esac; \
-    case $$flg in \
-      *$$target_option*) has_opt=yes; break;; \
-    esac; \
-  done; \
-  test $$has_opt = yes
-am__make_dryrun = (target_option=n; $(am__make_running_with_option))
-am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
-pkgdatadir = $(datadir)/@PACKAGE@
-pkgincludedir = $(includedir)/@PACKAGE@
-pkglibdir = $(libdir)/@PACKAGE@
-pkglibexecdir = $(libexecdir)/@PACKAGE@
-am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
-install_sh_DATA = $(install_sh) -c -m 644
-install_sh_PROGRAM = $(install_sh) -c
-install_sh_SCRIPT = $(install_sh) -c
-INSTALL_HEADER = $(INSTALL_DATA)
-transform = $(program_transform_name)
-NORMAL_INSTALL = :
-PRE_INSTALL = :
-POST_INSTALL = :
-NORMAL_UNINSTALL = :
-PRE_UNINSTALL = :
-POST_UNINSTALL = :
-build_triplet = @build@
-host_triplet = @host@
-subdir = src/libhydra/plugins/resolve
-DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
-	$(top_srcdir)/depcomp
-ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
-am__aclocal_m4_deps = $(top_srcdir)/m4/config/libtool.m4 \
-	$(top_srcdir)/m4/config/ltoptions.m4 \
-	$(top_srcdir)/m4/config/ltsugar.m4 \
-	$(top_srcdir)/m4/config/ltversion.m4 \
-	$(top_srcdir)/m4/config/lt~obsolete.m4 \
-	$(top_srcdir)/m4/macros/split-package-version.m4 \
-	$(top_srcdir)/m4/macros/with.m4 \
-	$(top_srcdir)/m4/macros/enable-disable.m4 \
-	$(top_srcdir)/m4/macros/add-plugin.m4 \
-	$(top_srcdir)/configure.ac
-am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
-	$(ACLOCAL_M4)
-mkinstalldirs = $(install_sh) -d
-CONFIG_HEADER = $(top_builddir)/config.h
-CONFIG_CLEAN_FILES =
-CONFIG_CLEAN_VPATH_FILES =
-am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
-am__vpath_adj = case $$p in \
-    $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
-    *) f=$$p;; \
-  esac;
-am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
-am__install_max = 40
-am__nobase_strip_setup = \
-  srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
-am__nobase_strip = \
-  for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
-am__nobase_list = $(am__nobase_strip_setup); \
-  for p in $$list; do echo "$$p $$p"; done | \
-  sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
-  $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
-    if (++n[$$2] == $(am__install_max)) \
-      { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
-    END { for (dir in files) print dir, files[dir] }'
-am__base_list = \
-  sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
-  sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
-am__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; }; \
-  }
-am__installdirs = "$(DESTDIR)$(plugindir)"
-LTLIBRARIES = $(noinst_LTLIBRARIES) $(plugin_LTLIBRARIES)
-libstrongswan_resolve_la_LIBADD =
-am_libstrongswan_resolve_la_OBJECTS = resolve_plugin.lo \
-	resolve_handler.lo
-libstrongswan_resolve_la_OBJECTS =  \
-	$(am_libstrongswan_resolve_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_resolve_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \
-	$(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \
-	$(AM_CFLAGS) $(CFLAGS) $(libstrongswan_resolve_la_LDFLAGS) \
-	$(LDFLAGS) -o $@
- at MONOLITHIC_FALSE@am_libstrongswan_resolve_la_rpath = -rpath \
- at MONOLITHIC_FALSE@	$(plugindir)
- at MONOLITHIC_TRUE@am_libstrongswan_resolve_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
-am__v_P_1 = :
-AM_V_GEN = $(am__v_GEN_ at AM_V@)
-am__v_GEN_ = $(am__v_GEN_ at AM_DEFAULT_V@)
-am__v_GEN_0 = @echo "  GEN     " $@;
-am__v_GEN_1 = 
-AM_V_at = $(am__v_at_ at AM_V@)
-am__v_at_ = $(am__v_at_ at AM_DEFAULT_V@)
-am__v_at_0 = @
-am__v_at_1 = 
-DEFAULT_INCLUDES = -I. at am__isrc@ -I$(top_builddir)
-depcomp = $(SHELL) $(top_srcdir)/depcomp
-am__depfiles_maybe = depfiles
-am__mv = mv -f
-COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
-	$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
-LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
-	$(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \
-	$(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
-	$(AM_CFLAGS) $(CFLAGS)
-AM_V_CC = $(am__v_CC_ at AM_V@)
-am__v_CC_ = $(am__v_CC_ at AM_DEFAULT_V@)
-am__v_CC_0 = @echo "  CC      " $@;
-am__v_CC_1 = 
-CCLD = $(CC)
-LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
-	$(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
-	$(AM_LDFLAGS) $(LDFLAGS) -o $@
-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_resolve_la_SOURCES)
-DIST_SOURCES = $(libstrongswan_resolve_la_SOURCES)
-am__can_run_installinfo = \
-  case $$AM_UPDATE_INFO_DIR in \
-    n|no|NO) false;; \
-    *) (install-info --version) >/dev/null 2>&1;; \
-  esac
-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
-# *not* preserved.
-am__uniquify_input = $(AWK) '\
-  BEGIN { nonempty = 0; } \
-  { items[$$0] = 1; nonempty = 1; } \
-  END { if (nonempty) { for (i in items) print i; }; } \
-'
-# Make sure the list of sources is unique.  This is necessary because,
-# e.g., the same source file might be shared among _SOURCES variables
-# for different programs/libraries.
-am__define_uniq_tagged_files = \
-  list='$(am__tagged_files)'; \
-  unique=`for i in $$list; do \
-    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
-  done | $(am__uniquify_input)`
-ETAGS = etags
-CTAGS = ctags
-DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
-ACLOCAL = @ACLOCAL@
-ALLOCA = @ALLOCA@
-AMTAR = @AMTAR@
-AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
-AR = @AR@
-AUTOCONF = @AUTOCONF@
-AUTOHEADER = @AUTOHEADER@
-AUTOMAKE = @AUTOMAKE@
-AWK = @AWK@
-BFDLIB = @BFDLIB@
-BTLIB = @BTLIB@
-CC = @CC@
-CCDEPMODE = @CCDEPMODE@
-CFLAGS = @CFLAGS@
-COVERAGE_CFLAGS = @COVERAGE_CFLAGS@
-COVERAGE_LDFLAGS = @COVERAGE_LDFLAGS@
-CPP = @CPP@
-CPPFLAGS = @CPPFLAGS@
-CYGPATH_W = @CYGPATH_W@
-DEFS = @DEFS@
-DEPDIR = @DEPDIR@
-DLLIB = @DLLIB@
-DLLTOOL = @DLLTOOL@
-DSYMUTIL = @DSYMUTIL@
-DUMPBIN = @DUMPBIN@
-ECHO_C = @ECHO_C@
-ECHO_N = @ECHO_N@
-ECHO_T = @ECHO_T@
-EGREP = @EGREP@
-EXEEXT = @EXEEXT@
-FGREP = @FGREP@
-GEM = @GEM@
-GENHTML = @GENHTML@
-GPERF = @GPERF@
-GPRBUILD = @GPRBUILD@
-GREP = @GREP@
-INSTALL = @INSTALL@
-INSTALL_DATA = @INSTALL_DATA@
-INSTALL_PROGRAM = @INSTALL_PROGRAM@
-INSTALL_SCRIPT = @INSTALL_SCRIPT@
-INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
-LCOV = @LCOV@
-LD = @LD@
-LDFLAGS = @LDFLAGS@
-LEX = @LEX@
-LEXLIB = @LEXLIB@
-LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@
-LIBOBJS = @LIBOBJS@
-LIBS = @LIBS@
-LIBTOOL = @LIBTOOL@
-LIPO = @LIPO@
-LN_S = @LN_S@
-LTLIBOBJS = @LTLIBOBJS@
-MAKEINFO = @MAKEINFO@
-MANIFEST_TOOL = @MANIFEST_TOOL@
-MKDIR_P = @MKDIR_P@
-MYSQLCFLAG = @MYSQLCFLAG@
-MYSQLCONFIG = @MYSQLCONFIG@
-MYSQLLIB = @MYSQLLIB@
-NM = @NM@
-NMEDIT = @NMEDIT@
-OBJDUMP = @OBJDUMP@
-OBJEXT = @OBJEXT@
-OPENSSL_LIB = @OPENSSL_LIB@
-OTOOL = @OTOOL@
-OTOOL64 = @OTOOL64@
-PACKAGE = @PACKAGE@
-PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
-PACKAGE_NAME = @PACKAGE_NAME@
-PACKAGE_STRING = @PACKAGE_STRING@
-PACKAGE_TARNAME = @PACKAGE_TARNAME@
-PACKAGE_URL = @PACKAGE_URL@
-PACKAGE_VERSION = @PACKAGE_VERSION@
-PACKAGE_VERSION_BUILD = @PACKAGE_VERSION_BUILD@
-PACKAGE_VERSION_MAJOR = @PACKAGE_VERSION_MAJOR@
-PACKAGE_VERSION_MINOR = @PACKAGE_VERSION_MINOR@
-PACKAGE_VERSION_REVIEW = @PACKAGE_VERSION_REVIEW@
-PATH_SEPARATOR = @PATH_SEPARATOR@
-PERL = @PERL@
-PKG_CONFIG = @PKG_CONFIG@
-PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
-PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
-PLUGIN_CFLAGS = @PLUGIN_CFLAGS@
-PTHREADLIB = @PTHREADLIB@
-PYTHON = @PYTHON@
-PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
-PYTHON_PLATFORM = @PYTHON_PLATFORM@
-PYTHON_PREFIX = @PYTHON_PREFIX@
-PYTHON_VERSION = @PYTHON_VERSION@
-RANLIB = @RANLIB@
-RTLIB = @RTLIB@
-RUBY = @RUBY@
-RUBYGEMDIR = @RUBYGEMDIR@
-RUBYINCLUDE = @RUBYINCLUDE@
-RUBYLIB = @RUBYLIB@
-SED = @SED@
-SET_MAKE = @SET_MAKE@
-SHELL = @SHELL@
-SOCKLIB = @SOCKLIB@
-STRIP = @STRIP@
-UNWINDLIB = @UNWINDLIB@
-VERSION = @VERSION@
-YACC = @YACC@
-YFLAGS = @YFLAGS@
-abs_builddir = @abs_builddir@
-abs_srcdir = @abs_srcdir@
-abs_top_builddir = @abs_top_builddir@
-abs_top_srcdir = @abs_top_srcdir@
-ac_ct_AR = @ac_ct_AR@
-ac_ct_CC = @ac_ct_CC@
-ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
-aikgen_plugins = @aikgen_plugins@
-am__include = @am__include@
-am__leading_dot = @am__leading_dot@
-am__quote = @am__quote@
-am__tar = @am__tar@
-am__untar = @am__untar@
-attest_plugins = @attest_plugins@
-bindir = @bindir@
-build = @build@
-build_alias = @build_alias@
-build_cpu = @build_cpu@
-build_os = @build_os@
-build_vendor = @build_vendor@
-builddir = @builddir@
-c_plugins = @c_plugins@
-charon_natt_port = @charon_natt_port@
-charon_plugins = @charon_plugins@
-charon_udp_port = @charon_udp_port@
-clearsilver_LIBS = @clearsilver_LIBS@
-cmd_plugins = @cmd_plugins@
-datadir = @datadir@
-datarootdir = @datarootdir@
-dbusservicedir = @dbusservicedir@
-dev_headers = @dev_headers@
-docdir = @docdir@
-dvidir = @dvidir@
-exec_prefix = @exec_prefix@
-fips_mode = @fips_mode@
-gtk_CFLAGS = @gtk_CFLAGS@
-gtk_LIBS = @gtk_LIBS@
-h_plugins = @h_plugins@
-host = @host@
-host_alias = @host_alias@
-host_cpu = @host_cpu@
-host_os = @host_os@
-host_vendor = @host_vendor@
-htmldir = @htmldir@
-imcvdir = @imcvdir@
-includedir = @includedir@
-infodir = @infodir@
-install_sh = @install_sh@
-ipsec_script = @ipsec_script@
-ipsec_script_upper = @ipsec_script_upper@
-ipsecdir = @ipsecdir@
-ipsecgroup = @ipsecgroup@
-ipseclibdir = @ipseclibdir@
-ipsecuser = @ipsecuser@
-json_CFLAGS = @json_CFLAGS@
-json_LIBS = @json_LIBS@
-libdir = @libdir@
-libexecdir = @libexecdir@
-linux_headers = @linux_headers@
-localedir = @localedir@
-localstatedir = @localstatedir@
-maemo_CFLAGS = @maemo_CFLAGS@
-maemo_LIBS = @maemo_LIBS@
-manager_plugins = @manager_plugins@
-mandir = @mandir@
-medsrv_plugins = @medsrv_plugins@
-mkdir_p = @mkdir_p@
-nm_CFLAGS = @nm_CFLAGS@
-nm_LIBS = @nm_LIBS@
-nm_ca_dir = @nm_ca_dir@
-nm_plugins = @nm_plugins@
-oldincludedir = @oldincludedir@
-pcsclite_CFLAGS = @pcsclite_CFLAGS@
-pcsclite_LIBS = @pcsclite_LIBS@
-pdfdir = @pdfdir@
-piddir = @piddir@
-pkgpyexecdir = @pkgpyexecdir@
-pkgpythondir = @pkgpythondir@
-pki_plugins = @pki_plugins@
-plugindir = @plugindir@
-pool_plugins = @pool_plugins@
-prefix = @prefix@
-program_transform_name = @program_transform_name@
-psdir = @psdir@
-pyexecdir = @pyexecdir@
-pythondir = @pythondir@
-random_device = @random_device@
-resolv_conf = @resolv_conf@
-routing_table = @routing_table@
-routing_table_prio = @routing_table_prio@
-s_plugins = @s_plugins@
-sbindir = @sbindir@
-scepclient_plugins = @scepclient_plugins@
-scripts_plugins = @scripts_plugins@
-sharedstatedir = @sharedstatedir@
-soup_CFLAGS = @soup_CFLAGS@
-soup_LIBS = @soup_LIBS@
-srcdir = @srcdir@
-starter_plugins = @starter_plugins@
-strongswan_conf = @strongswan_conf@
-strongswan_options = @strongswan_options@
-swanctldir = @swanctldir@
-sysconfdir = @sysconfdir@
-systemd_daemon_CFLAGS = @systemd_daemon_CFLAGS@
-systemd_daemon_LIBS = @systemd_daemon_LIBS@
-systemd_journal_CFLAGS = @systemd_journal_CFLAGS@
-systemd_journal_LIBS = @systemd_journal_LIBS@
-systemdsystemunitdir = @systemdsystemunitdir@
-t_plugins = @t_plugins@
-target_alias = @target_alias@
-top_build_prefix = @top_build_prefix@
-top_builddir = @top_builddir@
-top_srcdir = @top_srcdir@
-urandom_device = @urandom_device@
-xml_CFLAGS = @xml_CFLAGS@
-xml_LIBS = @xml_LIBS@
-AM_CPPFLAGS = \
-	-I$(top_srcdir)/src/libstrongswan \
-	-I$(top_srcdir)/src/libhydra \
-	-DRESOLV_CONF=\"${resolv_conf}\"
-
-AM_CFLAGS = \
-	$(PLUGIN_CFLAGS)
-
- at MONOLITHIC_TRUE@noinst_LTLIBRARIES = libstrongswan-resolve.la
- at MONOLITHIC_FALSE@plugin_LTLIBRARIES = libstrongswan-resolve.la
-libstrongswan_resolve_la_SOURCES = \
-	resolve_plugin.h resolve_plugin.c \
-	resolve_handler.h resolve_handler.c
-
-libstrongswan_resolve_la_LDFLAGS = -module -avoid-version
-all: all-am
-
-.SUFFIXES:
-.SUFFIXES: .c .lo .o .obj
-$(srcdir)/Makefile.in:  $(srcdir)/Makefile.am  $(am__configure_deps)
-	@for dep in $?; do \
-	  case '$(am__configure_deps)' in \
-	    *$$dep*) \
-	      ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
-	        && { if test -f $@; then exit 0; else break; fi; }; \
-	      exit 1;; \
-	  esac; \
-	done; \
-	echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/libhydra/plugins/resolve/Makefile'; \
-	$(am__cd) $(top_srcdir) && \
-	  $(AUTOMAKE) --gnu src/libhydra/plugins/resolve/Makefile
-.PRECIOUS: Makefile
-Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
-	@case '$?' in \
-	  *config.status*) \
-	    cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
-	  *) \
-	    echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
-	    cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
-	esac;
-
-$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
-	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
-
-$(top_srcdir)/configure:  $(am__configure_deps)
-	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
-$(ACLOCAL_M4):  $(am__aclocal_m4_deps)
-	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
-$(am__aclocal_m4_deps):
-
-clean-noinstLTLIBRARIES:
-	-test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES)
-	@list='$(noinst_LTLIBRARIES)'; \
-	locs=`for p in $$list; do echo $$p; done | \
-	      sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \
-	      sort -u`; \
-	test -z "$$locs" || { \
-	  echo rm -f $${locs}; \
-	  rm -f $${locs}; \
-	}
-
-install-pluginLTLIBRARIES: $(plugin_LTLIBRARIES)
-	@$(NORMAL_INSTALL)
-	@list='$(plugin_LTLIBRARIES)'; test -n "$(plugindir)" || list=; \
-	list2=; for p in $$list; do \
-	  if test -f $$p; then \
-	    list2="$$list2 $$p"; \
-	  else :; fi; \
-	done; \
-	test -z "$$list2" || { \
-	  echo " $(MKDIR_P) '$(DESTDIR)$(plugindir)'"; \
-	  $(MKDIR_P) "$(DESTDIR)$(plugindir)" || exit 1; \
-	  echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(plugindir)'"; \
-	  $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(plugindir)"; \
-	}
-
-uninstall-pluginLTLIBRARIES:
-	@$(NORMAL_UNINSTALL)
-	@list='$(plugin_LTLIBRARIES)'; test -n "$(plugindir)" || list=; \
-	for p in $$list; do \
-	  $(am__strip_dir) \
-	  echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(plugindir)/$$f'"; \
-	  $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(plugindir)/$$f"; \
-	done
-
-clean-pluginLTLIBRARIES:
-	-test -z "$(plugin_LTLIBRARIES)" || rm -f $(plugin_LTLIBRARIES)
-	@list='$(plugin_LTLIBRARIES)'; \
-	locs=`for p in $$list; do echo $$p; done | \
-	      sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \
-	      sort -u`; \
-	test -z "$$locs" || { \
-	  echo rm -f $${locs}; \
-	  rm -f $${locs}; \
-	}
-
-libstrongswan-resolve.la: $(libstrongswan_resolve_la_OBJECTS) $(libstrongswan_resolve_la_DEPENDENCIES) $(EXTRA_libstrongswan_resolve_la_DEPENDENCIES) 
-	$(AM_V_CCLD)$(libstrongswan_resolve_la_LINK) $(am_libstrongswan_resolve_la_rpath) $(libstrongswan_resolve_la_OBJECTS) $(libstrongswan_resolve_la_LIBADD) $(LIBS)
-
-mostlyclean-compile:
-	-rm -f *.$(OBJEXT)
-
-distclean-compile:
-	-rm -f *.tab.c
-
- at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/resolve_handler.Plo at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/resolve_plugin.Plo at am__quote@
-
-.c.o:
- at am__fastdepCC_TRUE@	$(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\
- at am__fastdepCC_TRUE@	$(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\
- at am__fastdepCC_TRUE@	$(am__mv) $$depbase.Tpo $$depbase.Po
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(COMPILE) -c -o $@ $<
-
-.c.obj:
- at am__fastdepCC_TRUE@	$(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\
- at am__fastdepCC_TRUE@	$(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\
- at am__fastdepCC_TRUE@	$(am__mv) $$depbase.Tpo $$depbase.Po
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
-
-.c.lo:
- at am__fastdepCC_TRUE@	$(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\
- at am__fastdepCC_TRUE@	$(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\
- at am__fastdepCC_TRUE@	$(am__mv) $$depbase.Tpo $$depbase.Plo
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(LTCOMPILE) -c -o $@ $<
-
-mostlyclean-libtool:
-	-rm -f *.lo
-
-clean-libtool:
-	-rm -rf .libs _libs
-
-ID: $(am__tagged_files)
-	$(am__define_uniq_tagged_files); mkid -fID $$unique
-tags: tags-am
-TAGS: tags
-
-tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
-	set x; \
-	here=`pwd`; \
-	$(am__define_uniq_tagged_files); \
-	shift; \
-	if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
-	  test -n "$$unique" || unique=$$empty_fix; \
-	  if test $$# -gt 0; then \
-	    $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
-	      "$$@" $$unique; \
-	  else \
-	    $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
-	      $$unique; \
-	  fi; \
-	fi
-ctags: ctags-am
-
-CTAGS: ctags
-ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
-	$(am__define_uniq_tagged_files); \
-	test -z "$(CTAGS_ARGS)$$unique" \
-	  || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
-	     $$unique
-
-GTAGS:
-	here=`$(am__cd) $(top_builddir) && pwd` \
-	  && $(am__cd) $(top_srcdir) \
-	  && gtags -i $(GTAGS_ARGS) "$$here"
-cscopelist: cscopelist-am
-
-cscopelist-am: $(am__tagged_files)
-	list='$(am__tagged_files)'; \
-	case "$(srcdir)" in \
-	  [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
-	  *) sdir=$(subdir)/$(srcdir) ;; \
-	esac; \
-	for i in $$list; do \
-	  if test -f "$$i"; then \
-	    echo "$(subdir)/$$i"; \
-	  else \
-	    echo "$$sdir/$$i"; \
-	  fi; \
-	done >> $(top_builddir)/cscope.files
-
-distclean-tags:
-	-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
-
-distdir: $(DISTFILES)
-	@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
-	topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
-	list='$(DISTFILES)'; \
-	  dist_files=`for file in $$list; do echo $$file; done | \
-	  sed -e "s|^$$srcdirstrip/||;t" \
-	      -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
-	case $$dist_files in \
-	  */*) $(MKDIR_P) `echo "$$dist_files" | \
-			   sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
-			   sort -u` ;; \
-	esac; \
-	for file in $$dist_files; do \
-	  if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
-	  if test -d $$d/$$file; then \
-	    dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
-	    if test -d "$(distdir)/$$file"; then \
-	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
-	    fi; \
-	    if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
-	      cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
-	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
-	    fi; \
-	    cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
-	  else \
-	    test -f "$(distdir)/$$file" \
-	    || cp -p $$d/$$file "$(distdir)/$$file" \
-	    || exit 1; \
-	  fi; \
-	done
-check-am: all-am
-check: check-am
-all-am: Makefile $(LTLIBRARIES)
-installdirs:
-	for dir in "$(DESTDIR)$(plugindir)"; do \
-	  test -z "$$dir" || $(MKDIR_P) "$$dir"; \
-	done
-install: install-am
-install-exec: install-exec-am
-install-data: install-data-am
-uninstall: uninstall-am
-
-install-am: all-am
-	@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
-
-installcheck: installcheck-am
-install-strip:
-	if test -z '$(STRIP)'; then \
-	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
-	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
-	      install; \
-	else \
-	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
-	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
-	    "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
-	fi
-mostlyclean-generic:
-
-clean-generic:
-
-distclean-generic:
-	-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
-	-test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
-
-maintainer-clean-generic:
-	@echo "This command is intended for maintainers to use"
-	@echo "it deletes files that may require special tools to rebuild."
-clean: clean-am
-
-clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \
-	clean-pluginLTLIBRARIES mostlyclean-am
-
-distclean: distclean-am
-	-rm -rf ./$(DEPDIR)
-	-rm -f Makefile
-distclean-am: clean-am distclean-compile distclean-generic \
-	distclean-tags
-
-dvi: dvi-am
-
-dvi-am:
-
-html: html-am
-
-html-am:
-
-info: info-am
-
-info-am:
-
-install-data-am: install-pluginLTLIBRARIES
-
-install-dvi: install-dvi-am
-
-install-dvi-am:
-
-install-exec-am:
-
-install-html: install-html-am
-
-install-html-am:
-
-install-info: install-info-am
-
-install-info-am:
-
-install-man:
-
-install-pdf: install-pdf-am
-
-install-pdf-am:
-
-install-ps: install-ps-am
-
-install-ps-am:
-
-installcheck-am:
-
-maintainer-clean: maintainer-clean-am
-	-rm -rf ./$(DEPDIR)
-	-rm -f Makefile
-maintainer-clean-am: distclean-am maintainer-clean-generic
-
-mostlyclean: mostlyclean-am
-
-mostlyclean-am: mostlyclean-compile mostlyclean-generic \
-	mostlyclean-libtool
-
-pdf: pdf-am
-
-pdf-am:
-
-ps: ps-am
-
-ps-am:
-
-uninstall-am: uninstall-pluginLTLIBRARIES
-
-.MAKE: install-am install-strip
-
-.PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \
-	clean-libtool clean-noinstLTLIBRARIES clean-pluginLTLIBRARIES \
-	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-man install-pdf \
-	install-pdf-am install-pluginLTLIBRARIES install-ps \
-	install-ps-am install-strip installcheck installcheck-am \
-	installdirs maintainer-clean maintainer-clean-generic \
-	mostlyclean mostlyclean-compile mostlyclean-generic \
-	mostlyclean-libtool pdf pdf-am ps ps-am tags tags-am uninstall \
-	uninstall-am uninstall-pluginLTLIBRARIES
-
-
-# Tell versions [3.59,3.63) of GNU make to not export all variables.
-# Otherwise a system limit (for SysV at least) may be exceeded.
-.NOEXPORT:
diff --git a/src/libhydra/plugins/resolve/resolve_handler.c b/src/libhydra/plugins/resolve/resolve_handler.c
deleted file mode 100644
index 069466a..0000000
--- a/src/libhydra/plugins/resolve/resolve_handler.c
+++ /dev/null
@@ -1,377 +0,0 @@
-/*
- * Copyright (C) 2012 Tobias Brunner
- * Copyright (C) 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.
- */
-
-#include "resolve_handler.h"
-
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <unistd.h>
-
-#include <hydra.h>
-#include <utils/debug.h>
-#include <threading/mutex.h>
-
-/* path to resolvconf executable */
-#define RESOLVCONF_EXEC "/sbin/resolvconf"
-
-/* default prefix used for resolvconf interfaces (should have high prio) */
-#define RESOLVCONF_PREFIX "lo.inet.ipsec."
-
-typedef struct private_resolve_handler_t private_resolve_handler_t;
-
-/**
- * Private data of an resolve_handler_t object.
- */
-struct private_resolve_handler_t {
-
-	/**
-	 * Public resolve_handler_t interface.
-	 */
-	resolve_handler_t public;
-
-	/**
-	 * resolv.conf file to use
-	 */
-	char *file;
-
-	/**
-	 * use resolvconf instead of writing directly to resolv.conf
-	 */
-	bool use_resolvconf;
-
-	/**
-	 * prefix to be used for interface names sent to resolvconf
-	 */
-	char *iface_prefix;
-
-	/**
-	 * Mutex to access file exclusively
-	 */
-	mutex_t *mutex;
-};
-
-/**
- * Writes the given nameserver to resolv.conf
- */
-static bool write_nameserver(private_resolve_handler_t *this,
-							 identification_t *server, host_t *addr)
-{
-	FILE *in, *out;
-	char buf[1024];
-	size_t len;
-	bool handled = FALSE;
-
-	in = fopen(this->file, "r");
-	/* allows us to stream from in to out */
-	unlink(this->file);
-	out = fopen(this->file, "w");
-	if (out)
-	{
-		fprintf(out, "nameserver %H   # by strongSwan, from %Y\n", addr,
-				server);
-		DBG1(DBG_IKE, "installing DNS server %H to %s", addr, this->file);
-		handled = TRUE;
-
-		/* copy rest of the file */
-		if (in)
-		{
-			while ((len = fread(buf, 1, sizeof(buf), in)))
-			{
-				ignore_result(fwrite(buf, 1, len, out));
-			}
-		}
-		fclose(out);
-	}
-	if (in)
-	{
-		fclose(in);
-	}
-	return handled;
-}
-
-/**
- * Removes the given nameserver from resolv.conf
- */
-static void remove_nameserver(private_resolve_handler_t *this,
-							  identification_t *server, host_t *addr)
-{
-	FILE *in, *out;
-	char line[1024], matcher[512];
-
-	in = fopen(this->file, "r");
-	if (in)
-	{
-		/* allows us to stream from in to out */
-		unlink(this->file);
-		out = fopen(this->file, "w");
-		if (out)
-		{
-			snprintf(matcher, sizeof(matcher),
-					 "nameserver %H   # by strongSwan, from %Y\n",
-					 addr, server);
-
-			/* copy all, but matching line */
-			while (fgets(line, sizeof(line), in))
-			{
-				if (strpfx(line, matcher))
-				{
-					DBG1(DBG_IKE, "removing DNS server %H from %s",
-						 addr, this->file);
-				}
-				else
-				{
-					fputs(line, out);
-				}
-			}
-			fclose(out);
-		}
-		fclose(in);
-	}
-}
-
-/**
- * Add or remove the given nameserver by invoking resolvconf.
- */
-static bool invoke_resolvconf(private_resolve_handler_t *this,
-							  identification_t *server, host_t *addr,
-							  bool install)
-{
-	char cmd[128];
-	bool success = TRUE;
-
-	/* we use the nameserver's IP address as part of the interface name to
-	 * make them unique */
-	if (snprintf(cmd, sizeof(cmd), "%s %s %s%H", RESOLVCONF_EXEC,
-				install ? "-a" : "-d", this->iface_prefix, addr) >= sizeof(cmd))
-	{
-		return FALSE;
-	}
-
-	if (install)
-	{
-		FILE *out;
-
-		out = popen(cmd, "w");
-		if (!out)
-		{
-			return FALSE;
-		}
-		DBG1(DBG_IKE, "installing DNS server %H via resolvconf", addr);
-		fprintf(out, "nameserver %H\n", addr);
-		success = !ferror(out);
-		if (pclose(out))
-		{
-			return FALSE;
-		}
-	}
-	else
-	{
-		ignore_result(system(cmd));
-	}
-	return success;
-}
-
-METHOD(attribute_handler_t, handle, bool,
-	private_resolve_handler_t *this, identification_t *server,
-	configuration_attribute_type_t type, chunk_t data)
-{
-	host_t *addr;
-	bool handled;
-
-	switch (type)
-	{
-		case INTERNAL_IP4_DNS:
-			addr = host_create_from_chunk(AF_INET, data, 0);
-			break;
-		case INTERNAL_IP6_DNS:
-			addr = host_create_from_chunk(AF_INET6, data, 0);
-			break;
-		default:
-			return FALSE;
-	}
-
-	if (!addr || addr->is_anyaddr(addr))
-	{
-		DESTROY_IF(addr);
-		return FALSE;
-	}
-
-	this->mutex->lock(this->mutex);
-	if (this->use_resolvconf)
-	{
-		handled = invoke_resolvconf(this, server, addr, TRUE);
-	}
-	else
-	{
-		handled = write_nameserver(this, server, addr);
-	}
-	this->mutex->unlock(this->mutex);
-	addr->destroy(addr);
-
-	if (!handled)
-	{
-		DBG1(DBG_IKE, "adding DNS server failed");
-	}
-	return handled;
-}
-
-METHOD(attribute_handler_t, release, void,
-	private_resolve_handler_t *this, identification_t *server,
-	configuration_attribute_type_t type, chunk_t data)
-{
-	host_t *addr;
-	int family;
-
-	switch (type)
-	{
-		case INTERNAL_IP4_DNS:
-			family = AF_INET;
-			break;
-		case INTERNAL_IP6_DNS:
-			family = AF_INET6;
-			break;
-		default:
-			return;
-	}
-	addr = host_create_from_chunk(family, data, 0);
-
-	this->mutex->lock(this->mutex);
-	if (this->use_resolvconf)
-	{
-		invoke_resolvconf(this, server, addr, FALSE);
-	}
-	else
-	{
-		remove_nameserver(this, server, addr);
-	}
-	this->mutex->unlock(this->mutex);
-
-	addr->destroy(addr);
-}
-
-/**
- * Attribute enumerator implementation
- */
-typedef struct {
-	/** implements enumerator_t interface */
-	enumerator_t public;
-	/** request IPv4 DNS? */
-	bool v4;
-	/** request IPv6 DNS? */
-	bool v6;
-} attribute_enumerator_t;
-
-static bool attribute_enumerate(attribute_enumerator_t *this,
-								configuration_attribute_type_t *type,
-								chunk_t *data)
-{
-	if (this->v4)
-	{
-		*type = INTERNAL_IP4_DNS;
-		*data = chunk_empty;
-		this->v4 = FALSE;
-		return TRUE;
-	}
-	if (this->v6)
-	{
-		*type = INTERNAL_IP6_DNS;
-		*data = chunk_empty;
-		this->v6 = FALSE;
-		return TRUE;
-	}
-	return FALSE;
-}
-
-/**
- * Check if a list has a host of given family
- */
-static bool has_host_family(linked_list_t *list, int family)
-{
-	enumerator_t *enumerator;
-	host_t *host;
-	bool found = FALSE;
-
-	enumerator = list->create_enumerator(list);
-	while (enumerator->enumerate(enumerator, &host))
-	{
-		if (host->get_family(host) == family)
-		{
-			found = TRUE;
-			break;
-		}
-	}
-	enumerator->destroy(enumerator);
-
-	return found;
-}
-
-METHOD(attribute_handler_t, create_attribute_enumerator, enumerator_t*,
-	private_resolve_handler_t *this, identification_t *server,
-	linked_list_t *vips)
-{
-	attribute_enumerator_t *enumerator;
-
-	INIT(enumerator,
-		.public = {
-			.enumerate = (void*)attribute_enumerate,
-			.destroy = (void*)free,
-		},
-		.v4 = has_host_family(vips, AF_INET),
-		.v6 = has_host_family(vips, AF_INET6),
-	);
-	return &enumerator->public;
-}
-
-METHOD(resolve_handler_t, destroy, void,
-	private_resolve_handler_t *this)
-{
-	this->mutex->destroy(this->mutex);
-	free(this);
-}
-
-/**
- * See header
- */
-resolve_handler_t *resolve_handler_create()
-{
-	private_resolve_handler_t *this;
-	struct stat st;
-
-	INIT(this,
-		.public = {
-			.handler = {
-				.handle = _handle,
-				.release = _release,
-				.create_attribute_enumerator = _create_attribute_enumerator,
-			},
-			.destroy = _destroy,
-		},
-		.mutex = mutex_create(MUTEX_TYPE_DEFAULT),
-		.file = lib->settings->get_str(lib->settings, "%s.plugins.resolve.file",
-									   RESOLV_CONF, lib->ns),
-	);
-
-	if (stat(RESOLVCONF_EXEC, &st) == 0)
-	{
-		this->use_resolvconf = TRUE;
-		this->iface_prefix = lib->settings->get_str(lib->settings,
-								"%s.plugins.resolve.resolvconf.iface_prefix",
-								RESOLVCONF_PREFIX, lib->ns);
-	}
-
-	return &this->public;
-}
-
diff --git a/src/libhydra/plugins/resolve/resolve_plugin.c b/src/libhydra/plugins/resolve/resolve_plugin.c
deleted file mode 100644
index 2fef09a..0000000
--- a/src/libhydra/plugins/resolve/resolve_plugin.c
+++ /dev/null
@@ -1,102 +0,0 @@
-/*
- * Copyright (C) 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.
- */
-
-#include "resolve_plugin.h"
-#include "resolve_handler.h"
-
-#include <hydra.h>
-
-typedef struct private_resolve_plugin_t private_resolve_plugin_t;
-
-/**
- * private data of resolve plugin
- */
-struct private_resolve_plugin_t {
-
-	/**
-	 * implements plugin interface
-	 */
-	resolve_plugin_t public;
-
-	/**
-	 * The registered DNS attribute handler
-	 */
-	resolve_handler_t *handler;
-};
-
-METHOD(plugin_t, get_name, char*,
-	private_resolve_plugin_t *this)
-{
-	return "resolve";
-}
-
-/**
- * Register handler
- */
-static bool plugin_cb(private_resolve_plugin_t *this,
-					  plugin_feature_t *feature, bool reg, void *cb_data)
-{
-	if (reg)
-	{
-		hydra->attributes->add_handler(hydra->attributes,
-									   &this->handler->handler);
-	}
-	else
-	{
-		hydra->attributes->remove_handler(hydra->attributes,
-										  &this->handler->handler);
-	}
-	return TRUE;
-}
-
-METHOD(plugin_t, get_features, int,
-	private_resolve_plugin_t *this, plugin_feature_t *features[])
-{
-	static plugin_feature_t f[] = {
-		PLUGIN_CALLBACK((plugin_feature_callback_t)plugin_cb, NULL),
-			PLUGIN_PROVIDE(CUSTOM, "resolve"),
-	};
-	*features = f;
-	return countof(f);
-}
-
-METHOD(plugin_t, destroy, void,
-	private_resolve_plugin_t *this)
-{
-	this->handler->destroy(this->handler);
-	free(this);
-}
-
-/*
- * see header file
- */
-plugin_t *resolve_plugin_create()
-{
-	private_resolve_plugin_t *this;
-
-	INIT(this,
-		.public = {
-			.plugin = {
-				.get_name = _get_name,
-				.get_features = _get_features,
-				.destroy = _destroy,
-			},
-		},
-		.handler = resolve_handler_create(),
-	);
-
-	return &this->public.plugin;
-}
-
diff --git a/src/libhydra/tests/Makefile.am b/src/libhydra/tests/Makefile.am
new file mode 100644
index 0000000..5acd5c2
--- /dev/null
+++ b/src/libhydra/tests/Makefile.am
@@ -0,0 +1,18 @@
+TESTS = hydra_tests
+
+check_PROGRAMS = $(TESTS)
+
+hydra_tests_SOURCES = \
+  hydra_tests.h hydra_tests.c
+
+hydra_tests_CFLAGS = \
+  -I$(top_srcdir)/src/libhydra \
+  -I$(top_srcdir)/src/libstrongswan \
+  -I$(top_srcdir)/src/libstrongswan/tests \
+  @COVERAGE_CFLAGS@
+
+hydra_tests_LDFLAGS = @COVERAGE_LDFLAGS@
+hydra_tests_LDADD = \
+  $(top_builddir)/src/libhydra/libhydra.la \
+  $(top_builddir)/src/libstrongswan/libstrongswan.la \
+  $(top_builddir)/src/libstrongswan/tests/libtest.la
diff --git a/src/libhydra/tests/Makefile.in b/src/libhydra/tests/Makefile.in
new file mode 100644
index 0000000..1fa889d
--- /dev/null
+++ b/src/libhydra/tests/Makefile.in
@@ -0,0 +1,839 @@
+# Makefile.in generated by automake 1.14.1 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994-2013 Free Software Foundation, Inc.
+
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+ at SET_MAKE@
+VPATH = @srcdir@
+am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)'
+am__make_running_with_option = \
+  case $${target_option-} in \
+      ?) ;; \
+      *) echo "am__make_running_with_option: internal error: invalid" \
+              "target option '$${target_option-}' specified" >&2; \
+         exit 1;; \
+  esac; \
+  has_opt=no; \
+  sane_makeflags=$$MAKEFLAGS; \
+  if $(am__is_gnu_make); then \
+    sane_makeflags=$$MFLAGS; \
+  else \
+    case $$MAKEFLAGS in \
+      *\\[\ \	]*) \
+        bs=\\; \
+        sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
+          | sed "s/$$bs$$bs[$$bs $$bs	]*//g"`;; \
+    esac; \
+  fi; \
+  skip_next=no; \
+  strip_trailopt () \
+  { \
+    flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
+  }; \
+  for flg in $$sane_makeflags; do \
+    test $$skip_next = yes && { skip_next=no; continue; }; \
+    case $$flg in \
+      *=*|--*) continue;; \
+        -*I) strip_trailopt 'I'; skip_next=yes;; \
+      -*I?*) strip_trailopt 'I';; \
+        -*O) strip_trailopt 'O'; skip_next=yes;; \
+      -*O?*) strip_trailopt 'O';; \
+        -*l) strip_trailopt 'l'; skip_next=yes;; \
+      -*l?*) strip_trailopt 'l';; \
+      -[dEDm]) skip_next=yes;; \
+      -[JT]) skip_next=yes;; \
+    esac; \
+    case $$flg in \
+      *$$target_option*) has_opt=yes; break;; \
+    esac; \
+  done; \
+  test $$has_opt = yes
+am__make_dryrun = (target_option=n; $(am__make_running_with_option))
+am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+TESTS = hydra_tests$(EXEEXT)
+check_PROGRAMS = $(am__EXEEXT_1)
+subdir = src/libhydra/tests
+DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
+	$(top_srcdir)/depcomp
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/m4/config/libtool.m4 \
+	$(top_srcdir)/m4/config/ltoptions.m4 \
+	$(top_srcdir)/m4/config/ltsugar.m4 \
+	$(top_srcdir)/m4/config/ltversion.m4 \
+	$(top_srcdir)/m4/config/lt~obsolete.m4 \
+	$(top_srcdir)/m4/macros/split-package-version.m4 \
+	$(top_srcdir)/m4/macros/with.m4 \
+	$(top_srcdir)/m4/macros/enable-disable.m4 \
+	$(top_srcdir)/m4/macros/add-plugin.m4 \
+	$(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+	$(ACLOCAL_M4)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+am__EXEEXT_1 = hydra_tests$(EXEEXT)
+am_hydra_tests_OBJECTS = hydra_tests-hydra_tests.$(OBJEXT)
+hydra_tests_OBJECTS = $(am_hydra_tests_OBJECTS)
+hydra_tests_DEPENDENCIES = $(top_builddir)/src/libhydra/libhydra.la \
+	$(top_builddir)/src/libstrongswan/libstrongswan.la \
+	$(top_builddir)/src/libstrongswan/tests/libtest.la
+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 = 
+hydra_tests_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+	$(LIBTOOLFLAGS) --mode=link $(CCLD) $(hydra_tests_CFLAGS) \
+	$(CFLAGS) $(hydra_tests_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
+am__v_P_1 = :
+AM_V_GEN = $(am__v_GEN_ at AM_V@)
+am__v_GEN_ = $(am__v_GEN_ at AM_DEFAULT_V@)
+am__v_GEN_0 = @echo "  GEN     " $@;
+am__v_GEN_1 = 
+AM_V_at = $(am__v_at_ at AM_V@)
+am__v_at_ = $(am__v_at_ at AM_DEFAULT_V@)
+am__v_at_0 = @
+am__v_at_1 = 
+DEFAULT_INCLUDES = -I. at am__isrc@ -I$(top_builddir)
+depcomp = $(SHELL) $(top_srcdir)/depcomp
+am__depfiles_maybe = depfiles
+am__mv = mv -f
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+	$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+	$(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \
+	$(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
+	$(AM_CFLAGS) $(CFLAGS)
+AM_V_CC = $(am__v_CC_ at AM_V@)
+am__v_CC_ = $(am__v_CC_ at AM_DEFAULT_V@)
+am__v_CC_0 = @echo "  CC      " $@;
+am__v_CC_1 = 
+CCLD = $(CC)
+LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+	$(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+	$(AM_LDFLAGS) $(LDFLAGS) -o $@
+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 = $(hydra_tests_SOURCES)
+DIST_SOURCES = $(hydra_tests_SOURCES)
+am__can_run_installinfo = \
+  case $$AM_UPDATE_INFO_DIR in \
+    n|no|NO) false;; \
+    *) (install-info --version) >/dev/null 2>&1;; \
+  esac
+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
+# *not* preserved.
+am__uniquify_input = $(AWK) '\
+  BEGIN { nonempty = 0; } \
+  { items[$$0] = 1; nonempty = 1; } \
+  END { if (nonempty) { for (i in items) print i; }; } \
+'
+# Make sure the list of sources is unique.  This is necessary because,
+# e.g., the same source file might be shared among _SOURCES variables
+# for different programs/libraries.
+am__define_uniq_tagged_files = \
+  list='$(am__tagged_files)'; \
+  unique=`for i in $$list; do \
+    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+  done | $(am__uniquify_input)`
+ETAGS = etags
+CTAGS = ctags
+am__tty_colors_dummy = \
+  mgn= red= grn= lgn= blu= brg= std=; \
+  am__color_tests=no
+am__tty_colors = { \
+  $(am__tty_colors_dummy); \
+  if test "X$(AM_COLOR_TESTS)" = Xno; then \
+    am__color_tests=no; \
+  elif test "X$(AM_COLOR_TESTS)" = Xalways; then \
+    am__color_tests=yes; \
+  elif test "X$$TERM" != Xdumb && { test -t 1; } 2>/dev/null; then \
+    am__color_tests=yes; \
+  fi; \
+  if test $$am__color_tests = yes; then \
+    red=''; \
+    grn=''; \
+    lgn=''; \
+    blu=''; \
+    mgn=''; \
+    brg=''; \
+    std=''; \
+  fi; \
+}
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+ALLOCA = @ALLOCA@
+AMTAR = @AMTAR@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+BFDLIB = @BFDLIB@
+BTLIB = @BTLIB@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+COVERAGE_CFLAGS = @COVERAGE_CFLAGS@
+COVERAGE_LDFLAGS = @COVERAGE_LDFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DLLIB = @DLLIB@
+DLLTOOL = @DLLTOOL@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+EASY_INSTALL = @EASY_INSTALL@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+FGREP = @FGREP@
+GEM = @GEM@
+GENHTML = @GENHTML@
+GPERF = @GPERF@
+GPRBUILD = @GPRBUILD@
+GREP = @GREP@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+LCOV = @LCOV@
+LD = @LD@
+LDFLAGS = @LDFLAGS@
+LEX = @LEX@
+LEXLIB = @LEXLIB@
+LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LIPO = @LIPO@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+MAKEINFO = @MAKEINFO@
+MANIFEST_TOOL = @MANIFEST_TOOL@
+MKDIR_P = @MKDIR_P@
+MYSQLCFLAG = @MYSQLCFLAG@
+MYSQLCONFIG = @MYSQLCONFIG@
+MYSQLLIB = @MYSQLLIB@
+NM = @NM@
+NMEDIT = @NMEDIT@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OPENSSL_LIB = @OPENSSL_LIB@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PACKAGE_VERSION_BUILD = @PACKAGE_VERSION_BUILD@
+PACKAGE_VERSION_MAJOR = @PACKAGE_VERSION_MAJOR@
+PACKAGE_VERSION_MINOR = @PACKAGE_VERSION_MINOR@
+PACKAGE_VERSION_REVIEW = @PACKAGE_VERSION_REVIEW@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PERL = @PERL@
+PKG_CONFIG = @PKG_CONFIG@
+PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
+PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
+PLUGIN_CFLAGS = @PLUGIN_CFLAGS@
+PTHREADLIB = @PTHREADLIB@
+PYTHON = @PYTHON@
+PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@
+PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
+PYTHON_PLATFORM = @PYTHON_PLATFORM@
+PYTHON_PREFIX = @PYTHON_PREFIX@
+PYTHON_VERSION = @PYTHON_VERSION@
+PY_TEST = @PY_TEST@
+RANLIB = @RANLIB@
+RTLIB = @RTLIB@
+RUBY = @RUBY@
+RUBYGEMDIR = @RUBYGEMDIR@
+RUBYINCLUDE = @RUBYINCLUDE@
+RUBYLIB = @RUBYLIB@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+SOCKLIB = @SOCKLIB@
+STRIP = @STRIP@
+UNWINDLIB = @UNWINDLIB@
+VERSION = @VERSION@
+YACC = @YACC@
+YFLAGS = @YFLAGS@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+aikgen_plugins = @aikgen_plugins@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+attest_plugins = @attest_plugins@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+c_plugins = @c_plugins@
+charon_natt_port = @charon_natt_port@
+charon_plugins = @charon_plugins@
+charon_udp_port = @charon_udp_port@
+clearsilver_LIBS = @clearsilver_LIBS@
+cmd_plugins = @cmd_plugins@
+datadir = @datadir@
+datarootdir = @datarootdir@
+dbusservicedir = @dbusservicedir@
+dev_headers = @dev_headers@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+fips_mode = @fips_mode@
+gtk_CFLAGS = @gtk_CFLAGS@
+gtk_LIBS = @gtk_LIBS@
+h_plugins = @h_plugins@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+imcvdir = @imcvdir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+ipsec_script = @ipsec_script@
+ipsec_script_upper = @ipsec_script_upper@
+ipsecdir = @ipsecdir@
+ipsecgroup = @ipsecgroup@
+ipseclibdir = @ipseclibdir@
+ipsecuser = @ipsecuser@
+json_CFLAGS = @json_CFLAGS@
+json_LIBS = @json_LIBS@
+libdir = @libdir@
+libexecdir = @libexecdir@
+libiptc_CFLAGS = @libiptc_CFLAGS@
+libiptc_LIBS = @libiptc_LIBS@
+linux_headers = @linux_headers@
+localedir = @localedir@
+localstatedir = @localstatedir@
+maemo_CFLAGS = @maemo_CFLAGS@
+maemo_LIBS = @maemo_LIBS@
+manager_plugins = @manager_plugins@
+mandir = @mandir@
+medsrv_plugins = @medsrv_plugins@
+mkdir_p = @mkdir_p@
+nm_CFLAGS = @nm_CFLAGS@
+nm_LIBS = @nm_LIBS@
+nm_ca_dir = @nm_ca_dir@
+nm_plugins = @nm_plugins@
+oldincludedir = @oldincludedir@
+pcsclite_CFLAGS = @pcsclite_CFLAGS@
+pcsclite_LIBS = @pcsclite_LIBS@
+pdfdir = @pdfdir@
+piddir = @piddir@
+pkgpyexecdir = @pkgpyexecdir@
+pkgpythondir = @pkgpythondir@
+pki_plugins = @pki_plugins@
+plugindir = @plugindir@
+pool_plugins = @pool_plugins@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+pyexecdir = @pyexecdir@
+pythondir = @pythondir@
+random_device = @random_device@
+resolv_conf = @resolv_conf@
+routing_table = @routing_table@
+routing_table_prio = @routing_table_prio@
+s_plugins = @s_plugins@
+sbindir = @sbindir@
+scepclient_plugins = @scepclient_plugins@
+scripts_plugins = @scripts_plugins@
+sharedstatedir = @sharedstatedir@
+soup_CFLAGS = @soup_CFLAGS@
+soup_LIBS = @soup_LIBS@
+srcdir = @srcdir@
+starter_plugins = @starter_plugins@
+strongswan_conf = @strongswan_conf@
+strongswan_options = @strongswan_options@
+swanctldir = @swanctldir@
+sysconfdir = @sysconfdir@
+systemd_daemon_CFLAGS = @systemd_daemon_CFLAGS@
+systemd_daemon_LIBS = @systemd_daemon_LIBS@
+systemd_journal_CFLAGS = @systemd_journal_CFLAGS@
+systemd_journal_LIBS = @systemd_journal_LIBS@
+systemdsystemunitdir = @systemdsystemunitdir@
+t_plugins = @t_plugins@
+target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+urandom_device = @urandom_device@
+xml_CFLAGS = @xml_CFLAGS@
+xml_LIBS = @xml_LIBS@
+hydra_tests_SOURCES = \
+  hydra_tests.h hydra_tests.c
+
+hydra_tests_CFLAGS = \
+  -I$(top_srcdir)/src/libhydra \
+  -I$(top_srcdir)/src/libstrongswan \
+  -I$(top_srcdir)/src/libstrongswan/tests \
+  @COVERAGE_CFLAGS@
+
+hydra_tests_LDFLAGS = @COVERAGE_LDFLAGS@
+hydra_tests_LDADD = \
+  $(top_builddir)/src/libhydra/libhydra.la \
+  $(top_builddir)/src/libstrongswan/libstrongswan.la \
+  $(top_builddir)/src/libstrongswan/tests/libtest.la
+
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .c .lo .o .obj
+$(srcdir)/Makefile.in:  $(srcdir)/Makefile.am  $(am__configure_deps)
+	@for dep in $?; do \
+	  case '$(am__configure_deps)' in \
+	    *$$dep*) \
+	      ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+	        && { if test -f $@; then exit 0; else break; fi; }; \
+	      exit 1;; \
+	  esac; \
+	done; \
+	echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/libhydra/tests/Makefile'; \
+	$(am__cd) $(top_srcdir) && \
+	  $(AUTOMAKE) --gnu src/libhydra/tests/Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+	@case '$?' in \
+	  *config.status*) \
+	    cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+	  *) \
+	    echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+	    cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+	esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure:  $(am__configure_deps)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4):  $(am__aclocal_m4_deps)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+
+clean-checkPROGRAMS:
+	@list='$(check_PROGRAMS)'; test -n "$$list" || exit 0; \
+	echo " rm -f" $$list; \
+	rm -f $$list || exit $$?; \
+	test -n "$(EXEEXT)" || exit 0; \
+	list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \
+	echo " rm -f" $$list; \
+	rm -f $$list
+
+hydra_tests$(EXEEXT): $(hydra_tests_OBJECTS) $(hydra_tests_DEPENDENCIES) $(EXTRA_hydra_tests_DEPENDENCIES) 
+	@rm -f hydra_tests$(EXEEXT)
+	$(AM_V_CCLD)$(hydra_tests_LINK) $(hydra_tests_OBJECTS) $(hydra_tests_LDADD) $(LIBS)
+
+mostlyclean-compile:
+	-rm -f *.$(OBJEXT)
+
+distclean-compile:
+	-rm -f *.tab.c
+
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/hydra_tests-hydra_tests.Po at am__quote@
+
+.c.o:
+ at am__fastdepCC_TRUE@	$(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\
+ at am__fastdepCC_TRUE@	$(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\
+ at am__fastdepCC_TRUE@	$(am__mv) $$depbase.Tpo $$depbase.Po
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(COMPILE) -c -o $@ $<
+
+.c.obj:
+ at am__fastdepCC_TRUE@	$(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\
+ at am__fastdepCC_TRUE@	$(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\
+ at am__fastdepCC_TRUE@	$(am__mv) $$depbase.Tpo $$depbase.Po
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
+
+.c.lo:
+ at am__fastdepCC_TRUE@	$(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\
+ at am__fastdepCC_TRUE@	$(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\
+ at am__fastdepCC_TRUE@	$(am__mv) $$depbase.Tpo $$depbase.Plo
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(LTCOMPILE) -c -o $@ $<
+
+hydra_tests-hydra_tests.o: hydra_tests.c
+ at am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(hydra_tests_CFLAGS) $(CFLAGS) -MT hydra_tests-hydra_tests.o -MD -MP -MF $(DEPDIR)/hydra_tests-hydra_tests.Tpo -c -o hydra_tests-hydra_tests.o `test -f 'hydra_tests.c' || echo '$(srcdir)/'`hydra_tests.c
+ at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/hydra_tests-hydra_tests.Tpo $(DEPDIR)/hydra_tests-hydra_tests.Po
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='hydra_tests.c' object='hydra_tests-hydra_tests.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) $(hydra_tests_CFLAGS) $(CFLAGS) -c -o hydra_tests-hydra_tests.o `test -f 'hydra_tests.c' || echo '$(srcdir)/'`hydra_tests.c
+
+hydra_tests-hydra_tests.obj: hydra_tests.c
+ at am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(hydra_tests_CFLAGS) $(CFLAGS) -MT hydra_tests-hydra_tests.obj -MD -MP -MF $(DEPDIR)/hydra_tests-hydra_tests.Tpo -c -o hydra_tests-hydra_tests.obj `if test -f 'hydra_tests.c'; then $(CYGPATH_W) 'hydra_tests.c'; else $(CYGPATH_W) '$(srcdir)/hydra_tests.c'; fi`
+ at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/hydra_tests-hydra_tests.Tpo $(DEPDIR)/hydra_tests-hydra_tests.Po
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='hydra_tests.c' object='hydra_tests-hydra_tests.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) $(hydra_tests_CFLAGS) $(CFLAGS) -c -o hydra_tests-hydra_tests.obj `if test -f 'hydra_tests.c'; then $(CYGPATH_W) 'hydra_tests.c'; else $(CYGPATH_W) '$(srcdir)/hydra_tests.c'; fi`
+
+mostlyclean-libtool:
+	-rm -f *.lo
+
+clean-libtool:
+	-rm -rf .libs _libs
+
+ID: $(am__tagged_files)
+	$(am__define_uniq_tagged_files); mkid -fID $$unique
+tags: tags-am
+TAGS: tags
+
+tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+	set x; \
+	here=`pwd`; \
+	$(am__define_uniq_tagged_files); \
+	shift; \
+	if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
+	  test -n "$$unique" || unique=$$empty_fix; \
+	  if test $$# -gt 0; then \
+	    $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+	      "$$@" $$unique; \
+	  else \
+	    $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+	      $$unique; \
+	  fi; \
+	fi
+ctags: ctags-am
+
+CTAGS: ctags
+ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+	$(am__define_uniq_tagged_files); \
+	test -z "$(CTAGS_ARGS)$$unique" \
+	  || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+	     $$unique
+
+GTAGS:
+	here=`$(am__cd) $(top_builddir) && pwd` \
+	  && $(am__cd) $(top_srcdir) \
+	  && gtags -i $(GTAGS_ARGS) "$$here"
+cscopelist: cscopelist-am
+
+cscopelist-am: $(am__tagged_files)
+	list='$(am__tagged_files)'; \
+	case "$(srcdir)" in \
+	  [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
+	  *) sdir=$(subdir)/$(srcdir) ;; \
+	esac; \
+	for i in $$list; do \
+	  if test -f "$$i"; then \
+	    echo "$(subdir)/$$i"; \
+	  else \
+	    echo "$$sdir/$$i"; \
+	  fi; \
+	done >> $(top_builddir)/cscope.files
+
+distclean-tags:
+	-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+check-TESTS: $(TESTS)
+	@failed=0; all=0; xfail=0; xpass=0; skip=0; \
+	srcdir=$(srcdir); export srcdir; \
+	list=' $(TESTS) '; \
+	$(am__tty_colors); \
+	if test -n "$$list"; then \
+	  for tst in $$list; do \
+	    if test -f ./$$tst; then dir=./; \
+	    elif test -f $$tst; then dir=; \
+	    else dir="$(srcdir)/"; fi; \
+	    if $(TESTS_ENVIRONMENT) $${dir}$$tst $(AM_TESTS_FD_REDIRECT); then \
+	      all=`expr $$all + 1`; \
+	      case " $(XFAIL_TESTS) " in \
+	      *[\ \	]$$tst[\ \	]*) \
+		xpass=`expr $$xpass + 1`; \
+		failed=`expr $$failed + 1`; \
+		col=$$red; res=XPASS; \
+	      ;; \
+	      *) \
+		col=$$grn; res=PASS; \
+	      ;; \
+	      esac; \
+	    elif test $$? -ne 77; then \
+	      all=`expr $$all + 1`; \
+	      case " $(XFAIL_TESTS) " in \
+	      *[\ \	]$$tst[\ \	]*) \
+		xfail=`expr $$xfail + 1`; \
+		col=$$lgn; res=XFAIL; \
+	      ;; \
+	      *) \
+		failed=`expr $$failed + 1`; \
+		col=$$red; res=FAIL; \
+	      ;; \
+	      esac; \
+	    else \
+	      skip=`expr $$skip + 1`; \
+	      col=$$blu; res=SKIP; \
+	    fi; \
+	    echo "$${col}$$res$${std}: $$tst"; \
+	  done; \
+	  if test "$$all" -eq 1; then \
+	    tests="test"; \
+	    All=""; \
+	  else \
+	    tests="tests"; \
+	    All="All "; \
+	  fi; \
+	  if test "$$failed" -eq 0; then \
+	    if test "$$xfail" -eq 0; then \
+	      banner="$$All$$all $$tests passed"; \
+	    else \
+	      if test "$$xfail" -eq 1; then failures=failure; else failures=failures; fi; \
+	      banner="$$All$$all $$tests behaved as expected ($$xfail expected $$failures)"; \
+	    fi; \
+	  else \
+	    if test "$$xpass" -eq 0; then \
+	      banner="$$failed of $$all $$tests failed"; \
+	    else \
+	      if test "$$xpass" -eq 1; then passes=pass; else passes=passes; fi; \
+	      banner="$$failed of $$all $$tests did not behave as expected ($$xpass unexpected $$passes)"; \
+	    fi; \
+	  fi; \
+	  dashes="$$banner"; \
+	  skipped=""; \
+	  if test "$$skip" -ne 0; then \
+	    if test "$$skip" -eq 1; then \
+	      skipped="($$skip test was not run)"; \
+	    else \
+	      skipped="($$skip tests were not run)"; \
+	    fi; \
+	    test `echo "$$skipped" | wc -c` -le `echo "$$banner" | wc -c` || \
+	      dashes="$$skipped"; \
+	  fi; \
+	  report=""; \
+	  if test "$$failed" -ne 0 && test -n "$(PACKAGE_BUGREPORT)"; then \
+	    report="Please report to $(PACKAGE_BUGREPORT)"; \
+	    test `echo "$$report" | wc -c` -le `echo "$$banner" | wc -c` || \
+	      dashes="$$report"; \
+	  fi; \
+	  dashes=`echo "$$dashes" | sed s/./=/g`; \
+	  if test "$$failed" -eq 0; then \
+	    col="$$grn"; \
+	  else \
+	    col="$$red"; \
+	  fi; \
+	  echo "$${col}$$dashes$${std}"; \
+	  echo "$${col}$$banner$${std}"; \
+	  test -z "$$skipped" || echo "$${col}$$skipped$${std}"; \
+	  test -z "$$report" || echo "$${col}$$report$${std}"; \
+	  echo "$${col}$$dashes$${std}"; \
+	  test "$$failed" -eq 0; \
+	else :; fi
+
+distdir: $(DISTFILES)
+	@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+	topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+	list='$(DISTFILES)'; \
+	  dist_files=`for file in $$list; do echo $$file; done | \
+	  sed -e "s|^$$srcdirstrip/||;t" \
+	      -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+	case $$dist_files in \
+	  */*) $(MKDIR_P) `echo "$$dist_files" | \
+			   sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+			   sort -u` ;; \
+	esac; \
+	for file in $$dist_files; do \
+	  if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+	  if test -d $$d/$$file; then \
+	    dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+	    if test -d "$(distdir)/$$file"; then \
+	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+	    fi; \
+	    if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+	      cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+	    fi; \
+	    cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+	  else \
+	    test -f "$(distdir)/$$file" \
+	    || cp -p $$d/$$file "$(distdir)/$$file" \
+	    || exit 1; \
+	  fi; \
+	done
+check-am: all-am
+	$(MAKE) $(AM_MAKEFLAGS) $(check_PROGRAMS)
+	$(MAKE) $(AM_MAKEFLAGS) check-TESTS
+check: check-am
+all-am: Makefile
+installdirs:
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+	@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+	if test -z '$(STRIP)'; then \
+	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	      install; \
+	else \
+	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	    "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+	fi
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+	-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+	-test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+
+maintainer-clean-generic:
+	@echo "This command is intended for maintainers to use"
+	@echo "it deletes files that may require special tools to rebuild."
+clean: clean-am
+
+clean-am: clean-checkPROGRAMS clean-generic clean-libtool \
+	mostlyclean-am
+
+distclean: distclean-am
+	-rm -rf ./$(DEPDIR)
+	-rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+	distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+html-am:
+
+info: info-am
+
+info-am:
+
+install-data-am:
+
+install-dvi: install-dvi-am
+
+install-dvi-am:
+
+install-exec-am:
+
+install-html: install-html-am
+
+install-html-am:
+
+install-info: install-info-am
+
+install-info-am:
+
+install-man:
+
+install-pdf: install-pdf-am
+
+install-pdf-am:
+
+install-ps: install-ps-am
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+	-rm -rf ./$(DEPDIR)
+	-rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic \
+	mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am:
+
+.MAKE: check-am install-am install-strip
+
+.PHONY: CTAGS GTAGS TAGS all all-am check check-TESTS check-am clean \
+	clean-checkPROGRAMS 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-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
+
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/src/libhydra/tests/hydra_tests.c b/src/libhydra/tests/hydra_tests.c
new file mode 100644
index 0000000..90abd83
--- /dev/null
+++ b/src/libhydra/tests/hydra_tests.c
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2014 Tobias Brunner
+ * Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * for more details.
+ */
+
+#include <test_runner.h>
+#include <hydra.h>
+
+/* declare test suite constructors */
+#define TEST_SUITE(x) test_suite_t* x();
+#define TEST_SUITE_DEPEND(x, ...) TEST_SUITE(x)
+#include "hydra_tests.h"
+#undef TEST_SUITE
+#undef TEST_SUITE_DEPEND
+
+static test_configuration_t tests[] = {
+#define TEST_SUITE(x) \
+	{ .suite = x, },
+#define TEST_SUITE_DEPEND(x, type, args) \
+	{ .suite = x, .feature = PLUGIN_DEPENDS(type, args) },
+#include "hydra_tests.h"
+	{ .suite = NULL, }
+};
+
+static bool test_runner_init(bool init)
+{
+	if (init)
+	{
+		libhydra_init();
+	}
+	else
+	{
+		lib->processor->set_threads(lib->processor, 0);
+		lib->processor->cancel(lib->processor);
+		libhydra_deinit();
+	}
+	return TRUE;
+}
+
+int main(int argc, char *argv[])
+{
+	return test_runner_run("libhydra", tests, test_runner_init);
+}
diff --git a/src/libhydra/tests/hydra_tests.h b/src/libhydra/tests/hydra_tests.h
new file mode 100644
index 0000000..6b213d0
--- /dev/null
+++ b/src/libhydra/tests/hydra_tests.h
@@ -0,0 +1,14 @@
+/*
+ * Copyright (C) 2014 Tobias Brunner
+ * Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * for more details.
+ */
diff --git a/src/libimcv/Makefile.am b/src/libimcv/Makefile.am
index d9a5cd5..a613827 100644
--- a/src/libimcv/Makefile.am
+++ b/src/libimcv/Makefile.am
@@ -127,7 +127,8 @@ imv_policy_manager_SOURCES = \
 	imv/imv_policy_manager.c \
 	imv/imv_policy_manager_usage.h imv/imv_policy_manager_usage.c
 imv_policy_manager_LDADD = \
-	$(top_builddir)/src/libstrongswan/libstrongswan.la
+	$(top_builddir)/src/libstrongswan/libstrongswan.la \
+	$(top_builddir)/src/libtncif/libtncif.la
 #imv/imv_policy_manager.o :	$(top_builddir)/config.status
 
 SUBDIRS = .
diff --git a/src/libimcv/Makefile.in b/src/libimcv/Makefile.in
index 239e62a..03778a2 100644
--- a/src/libimcv/Makefile.in
+++ b/src/libimcv/Makefile.in
@@ -237,7 +237,8 @@ am_imv_policy_manager_OBJECTS = imv/imv_policy_manager.$(OBJEXT) \
 	imv/imv_policy_manager_usage.$(OBJEXT)
 imv_policy_manager_OBJECTS = $(am_imv_policy_manager_OBJECTS)
 imv_policy_manager_DEPENDENCIES =  \
-	$(top_builddir)/src/libstrongswan/libstrongswan.la
+	$(top_builddir)/src/libstrongswan/libstrongswan.la \
+	$(top_builddir)/src/libtncif/libtncif.la
 SCRIPTS = $(ipsec_SCRIPTS)
 AM_V_P = $(am__v_P_ at AM_V@)
 am__v_P_ = $(am__v_P_ at AM_DEFAULT_V@)
@@ -395,6 +396,7 @@ DLLIB = @DLLIB@
 DLLTOOL = @DLLTOOL@
 DSYMUTIL = @DSYMUTIL@
 DUMPBIN = @DUMPBIN@
+EASY_INSTALL = @EASY_INSTALL@
 ECHO_C = @ECHO_C@
 ECHO_N = @ECHO_N@
 ECHO_T = @ECHO_T@
@@ -455,10 +457,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
 PLUGIN_CFLAGS = @PLUGIN_CFLAGS@
 PTHREADLIB = @PTHREADLIB@
 PYTHON = @PYTHON@
+PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@
 PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
 PYTHON_PLATFORM = @PYTHON_PLATFORM@
 PYTHON_PREFIX = @PYTHON_PREFIX@
 PYTHON_VERSION = @PYTHON_VERSION@
+PY_TEST = @PY_TEST@
 RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
@@ -532,6 +536,8 @@ json_CFLAGS = @json_CFLAGS@
 json_LIBS = @json_LIBS@
 libdir = @libdir@
 libexecdir = @libexecdir@
+libiptc_CFLAGS = @libiptc_CFLAGS@
+libiptc_LIBS = @libiptc_LIBS@
 linux_headers = @linux_headers@
 localedir = @localedir@
 localstatedir = @localstatedir@
@@ -708,7 +714,8 @@ imv_policy_manager_SOURCES = \
 	imv/imv_policy_manager_usage.h imv/imv_policy_manager_usage.c
 
 imv_policy_manager_LDADD = \
-	$(top_builddir)/src/libstrongswan/libstrongswan.la
+	$(top_builddir)/src/libstrongswan/libstrongswan.la \
+	$(top_builddir)/src/libtncif/libtncif.la
 
 #imv/imv_policy_manager.o :	$(top_builddir)/config.status
 SUBDIRS = . $(am__append_3) $(am__append_4) $(am__append_5) \
diff --git a/src/libimcv/imv/data.sql b/src/libimcv/imv/data.sql
index 425748f..ff61911 100644
--- a/src/libimcv/imv/data.sql
+++ b/src/libimcv/imv/data.sql
@@ -323,6 +323,71 @@ INSERT INTO products (			/* 54 */
  'Debian 7.6 armv6l'
 );
 
+INSERT INTO products (			/* 55 */
+  name
+) VALUES (
+ 'Debian 7.7 i686'
+);
+
+INSERT INTO products (			/* 56 */
+  name
+) VALUES (
+ 'Debian 7.7 x86_64'
+);
+INSERT INTO products (			/* 57 */
+  name
+) VALUES (
+ 'Debian 7.7 armv6l'
+);
+
+INSERT INTO products (			/* 58 */
+  name
+) VALUES (
+ 'Debian 7.8 i686'
+);
+
+INSERT INTO products (			/* 59 */
+  name
+) VALUES (
+ 'Debian 7.8 x86_64'
+);
+
+INSERT INTO products (			/* 60 */
+  name
+) VALUES (
+ 'Debian 7.8 armv6l'
+);
+
+INSERT INTO products (			/* 61 */
+  name
+) VALUES (
+ 'Ubuntu 14.10 i686'
+);
+
+INSERT INTO products (			/* 62 */
+  name
+) VALUES (
+ 'Ubuntu 14.10 x86_64'
+);
+
+INSERT INTO products (			/* 63 */
+  name
+) VALUES (
+ 'Android 5.0'
+);
+
+INSERT INTO products (			/* 64 */
+  name
+) VALUES (
+ 'Android 5.0.1'
+);
+
+INSERT INTO products (			/* 65 */
+  name
+) VALUES (
+ 'Debian 7.8 armv7l'
+);
+
 /* Directories */
 
 INSERT INTO directories (		/*  1 */
@@ -741,6 +806,18 @@ INSERT INTO groups (			/* 14 */
   'Debian armv6l', 2
 );
 
+INSERT INTO groups (			/* 15 */
+  name, parent
+) VALUES (
+  'Debian armv7l', 2
+);
+
+INSERT INTO groups (            /* 16 */
+  name
+) VALUES (
+  'TPM TBOOT'
+);
+
 /* Default Product Groups */
 
 INSERT INTO groups_product_defaults (
@@ -800,6 +877,18 @@ INSERT INTO groups_product_defaults (
 INSERT INTO groups_product_defaults (
   group_id, product_id
 ) VALUES (
+  4, 55
+);
+
+INSERT INTO groups_product_defaults (
+  group_id, product_id
+) VALUES (
+  4, 58
+);
+
+INSERT INTO groups_product_defaults (
+  group_id, product_id
+) VALUES (
   5, 2
 );
 
@@ -854,6 +943,18 @@ INSERT INTO groups_product_defaults (
 INSERT INTO groups_product_defaults (
   group_id, product_id
 ) VALUES (
+  5, 56
+);
+
+INSERT INTO groups_product_defaults (
+  group_id, product_id
+) VALUES (
+  5, 59
+);
+
+INSERT INTO groups_product_defaults (
+  group_id, product_id
+) VALUES (
   6, 9
 );
 
@@ -902,6 +1003,12 @@ INSERT INTO groups_product_defaults (
 INSERT INTO groups_product_defaults (
   group_id, product_id
 ) VALUES (
+  6, 61
+);
+
+INSERT INTO groups_product_defaults (
+  group_id, product_id
+) VALUES (
   7, 8
 );
 
@@ -956,6 +1063,12 @@ INSERT INTO groups_product_defaults (
 INSERT INTO groups_product_defaults (
   group_id, product_id
 ) VALUES (
+  7, 62
+);
+
+INSERT INTO groups_product_defaults (
+  group_id, product_id
+) VALUES (
   3, 21
 );
 
@@ -1016,6 +1129,18 @@ INSERT INTO groups_product_defaults (
 INSERT INTO groups_product_defaults (
   group_id, product_id
 ) VALUES (
+  3, 63
+);
+
+INSERT INTO groups_product_defaults (
+  group_id, product_id
+) VALUES (
+  3, 64
+);
+
+INSERT INTO groups_product_defaults (
+  group_id, product_id
+) VALUES (
   3, 51
 );
 
@@ -1061,6 +1186,24 @@ INSERT INTO groups_product_defaults (
   14, 54
 );
 
+INSERT INTO groups_product_defaults (
+  group_id, product_id
+) VALUES (
+  14, 57
+);
+
+INSERT INTO groups_product_defaults (
+  group_id, product_id
+) VALUES (
+  14, 60
+);
+
+INSERT INTO groups_product_defaults (
+  group_id, product_id
+) VALUES (
+  15, 65
+);
+
 /* Policies */
 
 INSERT INTO policies (			/*  1 */
@@ -1189,6 +1332,12 @@ INSERT INTO policies (          /* 21 */
   16, 'TPM BIOS/IMA Measurements', 'BI', 2, 2
 );
 
+INSERT INTO policies (          /* 22 */
+  type, name, argument, rec_fail, rec_noresult
+) VALUES (
+  16, 'TPM TBOOT Measurements', 'T', 2, 2
+);
+
 /* Enforcements */
 
 INSERT INTO enforcements (		/*  1 */
@@ -1293,6 +1442,12 @@ INSERT INTO enforcements (      /* 17 */
   21, 13, 60
 );
 
+INSERT INTO enforcements (      /* 18 */
+  policy, group_id, max_age
+) VALUES (
+  22, 16, 60
+);
+
 /* swid_entities */
 
 INSERT INTO "swid_entities" (		/*  1 */
diff --git a/src/libimcv/imv/imv_agent.c b/src/libimcv/imv/imv_agent.c
index 6b24f4b..d050862 100644
--- a/src/libimcv/imv/imv_agent.c
+++ b/src/libimcv/imv/imv_agent.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2011-2014 Andreas Steffen
+ * Copyright (C) 2011-2015 Andreas Steffen
  * HSR Hochschule fuer Technik Rapperswil
  *
  * This program is free software; you can redistribute it and/or modify it
@@ -412,14 +412,10 @@ METHOD(imv_agent_t, create_state, TNC_Result,
 {
 	TNC_ConnectionID conn_id;
 	char *tnccs_p = NULL, *tnccs_v = NULL, *t_p = NULL, *t_v = NULL;
-	bool has_long = FALSE, has_excl = FALSE, has_soh = FALSE, first = TRUE;
+	bool has_long = FALSE, has_excl = FALSE, has_soh = FALSE;
 	linked_list_t *ar_identities;
-	enumerator_t *enumerator;
-	tncif_identity_t *tnc_id;
 	imv_session_t *session;
 	uint32_t max_msg_len;
-	uint32_t ar_id_type = TNC_ID_UNKNOWN;
-	chunk_t ar_id_value = chunk_empty;
 
 	conn_id = state->get_connection_id(state);
 	if (find_connection(this, conn_id))
@@ -431,15 +427,24 @@ METHOD(imv_agent_t, create_state, TNC_Result,
 	}
 
 	/* Get and display attributes from TNCS via IF-IMV */
-	has_long = get_bool_attribute(this, conn_id, TNC_ATTRIBUTEID_HAS_LONG_TYPES);
-	has_excl = get_bool_attribute(this, conn_id, TNC_ATTRIBUTEID_HAS_EXCLUSIVE);
-	has_soh  = get_bool_attribute(this, conn_id, TNC_ATTRIBUTEID_HAS_SOH);
-	tnccs_p = get_str_attribute(this, conn_id, TNC_ATTRIBUTEID_IFTNCCS_PROTOCOL);
-	tnccs_v = get_str_attribute(this, conn_id, TNC_ATTRIBUTEID_IFTNCCS_VERSION);
-	t_p = get_str_attribute(this, conn_id, TNC_ATTRIBUTEID_IFT_PROTOCOL);
-	t_v = get_str_attribute(this, conn_id, TNC_ATTRIBUTEID_IFT_VERSION);
-	max_msg_len = get_uint_attribute(this, conn_id, TNC_ATTRIBUTEID_MAX_MESSAGE_SIZE);
-	ar_identities = get_identity_attribute(this, conn_id, TNC_ATTRIBUTEID_AR_IDENTITIES);
+	has_long = get_bool_attribute(this, conn_id,
+									TNC_ATTRIBUTEID_HAS_LONG_TYPES);
+	has_excl = get_bool_attribute(this, conn_id,
+									TNC_ATTRIBUTEID_HAS_EXCLUSIVE);
+	has_soh  = get_bool_attribute(this, conn_id,
+									TNC_ATTRIBUTEID_HAS_SOH);
+	tnccs_p = get_str_attribute(this, conn_id,
+									TNC_ATTRIBUTEID_IFTNCCS_PROTOCOL);
+	tnccs_v = get_str_attribute(this, conn_id,
+									TNC_ATTRIBUTEID_IFTNCCS_VERSION);
+	t_p = get_str_attribute(this, conn_id,
+									TNC_ATTRIBUTEID_IFT_PROTOCOL);
+	t_v = get_str_attribute(this, conn_id,
+									TNC_ATTRIBUTEID_IFT_VERSION);
+	max_msg_len = get_uint_attribute(this, conn_id,
+									TNC_ATTRIBUTEID_MAX_MESSAGE_SIZE);
+	ar_identities = get_identity_attribute(this, conn_id,
+									TNC_ATTRIBUTEID_AR_IDENTITIES);
 
 	state->set_flags(state, has_long, has_excl);
 	state->set_max_msg_len(state, max_msg_len);
@@ -451,48 +456,9 @@ METHOD(imv_agent_t, create_state, TNC_Result,
 	DBG2(DBG_IMV, "  over %s %s with maximum PA-TNC message size of %u bytes",
 				  t_p ? t_p:"?", t_v ? t_v :"?", max_msg_len);
 
-	enumerator = ar_identities->create_enumerator(ar_identities);
-	while (enumerator->enumerate(enumerator, &tnc_id))
-	{
-		pen_type_t id_type, subject_type, auth_type;
-		uint32_t tcg_id_type, tcg_subject_type, tcg_auth_type;
-		chunk_t id_value;
-
-		id_type = tnc_id->get_identity_type(tnc_id);
-		id_value = tnc_id->get_identity_value(tnc_id);
-		subject_type = tnc_id->get_subject_type(tnc_id);
-		auth_type = tnc_id->get_auth_type(tnc_id);
-
-		tcg_id_type =      (id_type.vendor_id == PEN_TCG) ?
-							id_type.type : TNC_ID_UNKNOWN;
-		tcg_subject_type = (subject_type.vendor_id == PEN_TCG) ?
-							subject_type.type : TNC_SUBJECT_UNKNOWN;
-		tcg_auth_type =    (auth_type.vendor_id == PEN_TCG) ?
-							auth_type.type : TNC_AUTH_UNKNOWN;
-
-
-		DBG2(DBG_IMV, "  %N AR identity '%.*s' authenticated by %N",
-			 TNC_Subject_names, tcg_subject_type,
-			 id_value.len, id_value.ptr,
-			 TNC_Authentication_names, tcg_auth_type);
-
-		/* keep the first access requestor ID */
-		if (first)
-		{
-			ar_id_type = tcg_id_type;
-			ar_id_value = id_value;
-			first = FALSE;
-		}
-	}
-	enumerator->destroy(enumerator);
-
-	session = imcv_sessions->add_session(imcv_sessions, conn_id,
-										 ar_id_type, ar_id_value);
+	session = imcv_sessions->add_session(imcv_sessions, conn_id, ar_identities);
 	state->set_session(state, session);
 
-	/* clean up temporary variables */
-	ar_identities->destroy_offset(ar_identities,
-						   offsetof(tncif_identity_t, destroy));
 	free(tnccs_p);
 	free(tnccs_v);
 	free(t_p);
diff --git a/src/libimcv/imv/imv_database.c b/src/libimcv/imv/imv_database.c
index 0c4bb75..0a18cd7 100644
--- a/src/libimcv/imv/imv_database.c
+++ b/src/libimcv/imv/imv_database.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2013-2014 Andreas Steffen
+ * Copyright (C) 2013-2015 Andreas Steffen
  * HSR Hochschule fuer Technik Rapperswil
  *
  * This program is free software; you can redistribute it and/or modify it
@@ -22,6 +22,8 @@
 
 #include "imv_database.h"
 
+#include <tncif_identity.h>
+
 #include <utils/debug.h>
 #include <threading/mutex.h>
 
@@ -60,41 +62,14 @@ METHOD(imv_database_t, get_database, database_t*,
  */
 static bool create_session(private_imv_database_t *this, imv_session_t *session)
 {
-	enumerator_t *e;
+	enumerator_t *enumerator, *e;
 	imv_os_info_t *os_info;
-	chunk_t device_id, ar_id_value;
+	chunk_t device_id;
+	tncif_identity_t *tnc_id;
 	TNC_ConnectionID conn_id;
-	uint32_t ar_id_type;
 	char *product, *device;
-	int session_id = 0, ar_id = 0, pid = 0, did = 0, trusted = 0, created;
-
-	ar_id_value = session->get_ar_id(session, &ar_id_type);
-	if (ar_id_value.len)
-	{
-		/* get primary key of AR identity if it exists */
-		e = this->db->query(this->db,
-				"SELECT id FROM identities WHERE type = ? AND value = ?",
-				DB_INT, ar_id_type, DB_BLOB, ar_id_value, DB_INT);
-		if (e)
-		{
-			e->enumerate(e, &ar_id);
-			e->destroy(e);
-		}
-
-		/* if AR identity has not been found - register it */
-		if (!ar_id)
-		{
-			this->db->execute(this->db, &ar_id,
-				"INSERT INTO identities (type, value) VALUES (?, ?)",
-				 DB_INT, ar_id_type, DB_BLOB, ar_id_value);
-		}
-
-		if (!ar_id)
-		{
-			DBG1(DBG_IMV, "imv_db: registering access requestor failed");
-			return FALSE;
-		}
-	}
+	int session_id = 0, pid = 0, did = 0, trusted = 0, created;
+	bool first = TRUE, success = TRUE;
 
 	/* get product info string */
 	os_info = session->get_os_info(session);
@@ -170,10 +145,9 @@ static bool create_session(private_imv_database_t *this, imv_session_t *session)
 	created = session->get_creation_time(session);
 	conn_id = session->get_connection_id(session);
 	this->db->execute(this->db, &session_id,
-			"INSERT INTO sessions (time, connection, identity, product, device) "
-			"VALUES (?, ?, ?, ?, ?)",
-			DB_INT, created, DB_INT, conn_id, DB_INT, ar_id,
-			DB_INT, pid, DB_INT, did);
+			"INSERT INTO sessions (time, connection, product, device) "
+			"VALUES (?, ?, ?, ?)",
+			DB_INT, created, DB_INT, conn_id, DB_INT, pid, DB_INT, did);
 
 	if (session_id)
 	{
@@ -187,7 +161,68 @@ static bool create_session(private_imv_database_t *this, imv_session_t *session)
 	}
 	session->set_session_id(session, session_id, pid, did);
 
-	return TRUE;
+	enumerator = session->create_ar_identities_enumerator(session);
+	while (enumerator->enumerate(enumerator, &tnc_id))
+	{
+		pen_type_t ar_id_type;
+		chunk_t ar_id_value;
+		int ar_id = 0, si_id = 0;
+
+		ar_id_type = tnc_id->get_identity_type(tnc_id);
+		ar_id_value = tnc_id->get_identity_value(tnc_id);
+
+		if (ar_id_type.vendor_id != PEN_TCG || ar_id_value.len == 0)
+		{
+			continue;
+		}
+
+		/* get primary key of AR identity if it exists */
+		e = this->db->query(this->db,
+				"SELECT id FROM identities WHERE type = ? AND value = ?",
+				DB_INT, ar_id_type.type, DB_BLOB, ar_id_value, DB_INT);
+		if (e)
+		{
+			e->enumerate(e, &ar_id);
+			e->destroy(e);
+		}
+
+		/* if AR identity has not been found - register it */
+		if (!ar_id)
+		{
+			this->db->execute(this->db, &ar_id,
+				"INSERT INTO identities (type, value) VALUES (?, ?)",
+				 DB_INT, ar_id_type.type, DB_BLOB, ar_id_value);
+		}
+		if (!ar_id)
+		{
+			DBG1(DBG_IMV, "imv_db: registering access requestor failed");
+			success = FALSE;
+			break;
+		}
+
+		this->db->execute(this->db, &si_id,
+				"INSERT INTO sessions_identities (session_id, identity_id) "
+				"VALUES (?, ?)",
+				 DB_INT, session_id, DB_INT, ar_id);
+
+		if (!si_id)
+		{
+			DBG1(DBG_IMV, "imv_db: assigning identity to session failed");
+			success = FALSE;
+			break;
+		}
+
+		if (first)
+		{
+			this->db->execute(this->db, NULL,
+				"UPDATE sessions SET identity = ? WHERE id = ?",
+				 DB_INT, ar_id, DB_INT, session_id);
+			first = FALSE;
+		}
+	}
+	enumerator->destroy(enumerator);
+
+	return success;
 }
 
 static bool add_workitems(private_imv_database_t *this, imv_session_t *session)
diff --git a/src/libimcv/imv/imv_policy_manager.c b/src/libimcv/imv/imv_policy_manager.c
index 50f7f2e..9f7e4e8 100644
--- a/src/libimcv/imv/imv_policy_manager.c
+++ b/src/libimcv/imv/imv_policy_manager.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2013 Andreas Steffen
+ * Copyright (C) 2013-2015 Andreas Steffen
  * HSR Hochschule fuer Technik Rapperswil
  *
  * This program is free software; you can redistribute it and/or modify it
@@ -19,6 +19,8 @@
 #include <library.h>
 #include <utils/debug.h>
 
+#include <tncif_names.h>
+
 #include <stdlib.h>
 #include <stdio.h>
 #include <time.h>
@@ -251,9 +253,12 @@ static bool policy_start(database_t *db, int session_id)
 static bool policy_stop(database_t *db, int session_id)
 {
 	enumerator_t *e;
-	int rec, policy;
-	char *result;
+	int rec, policy, final_rec, id_type;
+	chunk_t id_value;
+	char *result, *ip_address = NULL;
+	bool success = TRUE;
 
+	/* store all workitem results for this session in the results table */
 	e = db->query(db,
 			"SELECT w.rec_final, w.result, e.policy FROM workitems AS w "
 			"JOIN enforcements AS e ON w.enforcement = e.id "
@@ -270,9 +275,68 @@ static bool policy_stop(database_t *db, int session_id)
 		}
 		e->destroy(e);
 	}
-	return db->execute(db, NULL,
-				"DELETE FROM workitems WHERE session = ?",
-				DB_UINT, session_id) >= 0;
+	else
+	{
+		success = FALSE;
+	}
+
+	/* delete all workitems for this session from the database */
+	if (db->execute(db, NULL,
+					"DELETE FROM workitems WHERE session = ?",
+					DB_UINT, session_id) < 0)
+	{
+		success = FALSE;
+	}
+
+	final_rec = TNC_IMV_ACTION_RECOMMENDATION_NO_RECOMMENDATION;
+
+	/* retrieve the final recommendation for this session */
+	e = db->query(db,
+			"SELECT rec FROM sessions WHERE id = ?",
+			 DB_INT, session_id, DB_INT);
+	if (e)
+	{
+		if (!e->enumerate(e, &final_rec))
+		{
+			success = FALSE;
+		}
+		e->destroy(e);
+	}
+	else
+	{
+		success = FALSE;
+	}
+
+	/* retrieve client IP address for this session */
+	e = db->query(db,
+			"SELECT i.type, i.value FROM identities AS i "
+			"JOIN sessions_identities AS si ON si.identity_id = i.id "
+			"WHERE si.session_id = ? AND (i.type = ? OR i.type = ?)",
+			 DB_INT, session_id, DB_INT, TNC_ID_IPV4_ADDR, DB_INT,
+			 TNC_ID_IPV6_ADDR, DB_INT, DB_BLOB);
+	if (e)
+	{
+		if (e->enumerate(e, &id_type, &id_value))
+		{
+			ip_address = strndup(id_value.ptr, id_value.len);
+		}
+		else
+		{
+			success = FALSE;
+		}
+		e->destroy(e);
+	}
+	else
+	{
+		success = FALSE;
+	}
+
+	fprintf(stderr, "recommendation for access requestor %s is %N\n",
+			ip_address ? ip_address : "0.0.0.0",
+			TNC_IMV_Action_Recommendation_names, final_rec);
+	free(ip_address);
+
+	return success;
 }
 
 int main(int argc, char *argv[])
diff --git a/src/libimcv/imv/imv_session.c b/src/libimcv/imv/imv_session.c
index 1f0d8cf..bc6b5a8 100644
--- a/src/libimcv/imv/imv_session.c
+++ b/src/libimcv/imv/imv_session.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2013 Andreas Steffen
+ * Copyright (C) 2013-2015 Andreas Steffen
  * HSR Hochschule fuer Technik Rapperswil
  *
  * This program is free software; you can redistribute it and/or modify it
@@ -15,6 +15,8 @@
 
 #include "imv_session.h"
 
+#include <tncif_identity.h>
+
 #include <utils/debug.h>
 
 typedef struct private_imv_session_t private_imv_session_t;
@@ -55,14 +57,9 @@ struct private_imv_session_t {
 	time_t created;
 
 	/**
-	 * Access Requestor ID type
-	 */
-	uint32_t ar_id_type;
-
-	/**
-	 * Access Requestor ID value
+	 * List of Access Requestor identities
 	 */
-	chunk_t ar_id_value;
+	linked_list_t *ar_identities;
 
 	/**
 	 * OS information
@@ -130,14 +127,10 @@ METHOD(imv_session_t, get_creation_time, time_t,
 	return this->created;
 }
 
-METHOD(imv_session_t, get_ar_id, chunk_t,
-	private_imv_session_t *this, uint32_t *ar_id_type)
+METHOD(imv_session_t, create_ar_identities_enumerator, enumerator_t*,
+	private_imv_session_t *this)
 {
-	if (ar_id_type)
-	{
-		*ar_id_type = this->ar_id_type;
-	}
-	return this->ar_id_value;
+	return this->ar_identities->create_enumerator(this->ar_identities);
 }
 
 METHOD(imv_session_t, get_os_info, imv_os_info_t*,
@@ -256,7 +249,8 @@ METHOD(imv_session_t, destroy, void,
 		this->workitems->destroy_offset(this->workitems,
 								 offsetof(imv_workitem_t, destroy));
 		this->os_info->destroy(this->os_info);
-		free(this->ar_id_value.ptr);
+		this->ar_identities->destroy_offset(this->ar_identities,
+									 offsetof(tncif_identity_t, destroy));
 		free(this->device_id.ptr);
 		free(this);
 	}
@@ -266,7 +260,7 @@ METHOD(imv_session_t, destroy, void,
  * See header
  */
 imv_session_t *imv_session_create(TNC_ConnectionID conn_id, time_t created,
-								  uint32_t ar_id_type, chunk_t ar_id_value)
+								  linked_list_t *ar_identities)
 {
 	private_imv_session_t *this;
 
@@ -276,7 +270,7 @@ imv_session_t *imv_session_create(TNC_ConnectionID conn_id, time_t created,
 			.get_session_id = _get_session_id,
 			.get_connection_id = _get_connection_id,
 			.get_creation_time = _get_creation_time,
-			.get_ar_id = _get_ar_id,
+			.create_ar_identities_enumerator = _create_ar_identities_enumerator,
 			.get_os_info = _get_os_info,
 			.set_device_id = _set_device_id,
 			.get_device_id = _get_device_id,
@@ -293,8 +287,7 @@ imv_session_t *imv_session_create(TNC_ConnectionID conn_id, time_t created,
 		},
 		.conn_id = conn_id,
 		.created = created,
-		.ar_id_type = ar_id_type,
-		.ar_id_value = chunk_clone(ar_id_value),
+		.ar_identities = ar_identities,
 		.os_info = imv_os_info_create(),
 		.workitems = linked_list_create(),
 		.ref = 1,
diff --git a/src/libimcv/imv/imv_session.h b/src/libimcv/imv/imv_session.h
index 42b9118..107716f 100644
--- a/src/libimcv/imv/imv_session.h
+++ b/src/libimcv/imv/imv_session.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2013-2014 Andreas Steffen
+ * Copyright (C) 2013-2015 Andreas Steffen
  * HSR Hochschule fuer Technik Rapperswil
  *
  * This program is free software; you can redistribute it and/or modify it
@@ -70,12 +70,11 @@ struct imv_session_t {
 	time_t (*get_creation_time)(imv_session_t *this);
 
 	/**
-	 * Get Access Requestor ID
+	 * Get list of Access Requestor identities
 	 *
-	 * @param id_type		Access Requestor TCG Standard ID Type
-	 * @return				Access Requestor TCG Standard ID Value
+	 * @return				List of Access Requestor identities
 	 */
-	chunk_t (*get_ar_id)(imv_session_t *this, uint32_t *id_type);
+	enumerator_t* (*create_ar_identities_enumerator)(imv_session_t *this);
 
 	/**
 	 * Get OS Information
@@ -172,10 +171,9 @@ struct imv_session_t {
  *
  * @param id				Associated Connection ID
  * @param created			Session creation time
- * @param ar_id_type		Access Requestor ID type
- * @param ar_id_value		Access Requestor ID value
+ * @param ar_identities		List of Access Requestor identities
  */
 imv_session_t* imv_session_create(TNC_ConnectionID id, time_t created,
-								  uint32_t ar_id_type, chunk_t ar_id_value);
+								  linked_list_t *ar_identities);
 
 #endif /**  IMV_SESSION_H_ @}*/
diff --git a/src/libimcv/imv/imv_session_manager.c b/src/libimcv/imv/imv_session_manager.c
index 0fb8de4..c976029 100644
--- a/src/libimcv/imv/imv_session_manager.c
+++ b/src/libimcv/imv/imv_session_manager.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2014 Andreas Steffen
+ * Copyright (C) 2014-2015 Andreas Steffen
  * HSR Hochschule fuer Technik Rapperswil
  *
  * This program is free software; you can redistribute it and/or modify it
@@ -15,6 +15,9 @@
 
 #include "imv_session_manager.h"
 
+#include <tncif_names.h>
+#include <tncif_identity.h>
+
 #include <threading/mutex.h>
 
 typedef struct private_imv_session_manager_t private_imv_session_manager_t;
@@ -43,9 +46,10 @@ struct private_imv_session_manager_t {
 
 METHOD(imv_session_manager_t, add_session, imv_session_t*,
 	private_imv_session_manager_t *this, TNC_ConnectionID conn_id,
-	uint32_t ar_id_type, chunk_t ar_id_value)
+	linked_list_t *ar_identities)
 {
 	enumerator_t *enumerator;
+	tncif_identity_t *tnc_id;
 	imv_session_t *current, *session = NULL;
 	time_t created;
 
@@ -66,13 +70,43 @@ METHOD(imv_session_manager_t, add_session, imv_session_t*,
 	/* session already exists */
 	if (session)
 	{
+		ar_identities->destroy_offset(ar_identities,
+							   offsetof(tncif_identity_t, destroy));
 		this->mutex->unlock(this->mutex);
 		return session->get_ref(session);
 	}
 
+	/* Output list of Access Requestor identities */
+	enumerator = ar_identities->create_enumerator(ar_identities);
+	while (enumerator->enumerate(enumerator, &tnc_id))
+	{
+		pen_type_t id_type, subject_type, auth_type;
+		uint32_t tcg_id_type, tcg_subject_type, tcg_auth_type;
+		chunk_t id_value;
+
+		id_type = tnc_id->get_identity_type(tnc_id);
+		id_value = tnc_id->get_identity_value(tnc_id);
+		subject_type = tnc_id->get_subject_type(tnc_id);
+		auth_type = tnc_id->get_auth_type(tnc_id);
+
+		tcg_id_type = (subject_type.vendor_id == PEN_TCG) ?
+							id_type.type : TNC_SUBJECT_UNKNOWN;
+		tcg_subject_type = (subject_type.vendor_id == PEN_TCG) ?
+							subject_type.type : TNC_SUBJECT_UNKNOWN;
+		tcg_auth_type =    (auth_type.vendor_id == PEN_TCG) ?
+							auth_type.type : TNC_AUTH_UNKNOWN;
+
+		DBG2(DBG_IMV, "  %N AR identity '%.*s' of type %N authenticated by %N",
+			 TNC_Subject_names, tcg_subject_type,
+			 id_value.len, id_value.ptr,
+			 TNC_Identity_names, tcg_id_type,
+			 TNC_Authentication_names, tcg_auth_type);
+	}
+	enumerator->destroy(enumerator);
+
 	/* create a new session entry */
 	created = time(NULL);
-	session = imv_session_create(conn_id, created, ar_id_type, ar_id_value);
+	session = imv_session_create(conn_id, created, ar_identities);
 	this->sessions->insert_last(this->sessions, session);
 
 	this->mutex->unlock(this->mutex);
diff --git a/src/libimcv/imv/imv_session_manager.h b/src/libimcv/imv/imv_session_manager.h
index 8a733ac..cfae23b 100644
--- a/src/libimcv/imv/imv_session_manager.h
+++ b/src/libimcv/imv/imv_session_manager.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2014 Andreas Steffen
+ * Copyright (C) 2014-2015 Andreas Steffen
  * HSR Hochschule fuer Technik Rapperswil
  *
  * This program is free software; you can redistribute it and/or modify it
@@ -39,13 +39,12 @@ struct imv_session_manager_t {
 	 * Create or get a session associated with a TNCCS connection
 	 *
 	 * @param conn_id		TNCCS Connection ID
-	 * @param ar_id_type	Access Requestor identity type
-	 * @param ar_id_value	Access Requestor identity value
+	 * @param ar_identities	List of Access Requestor identities
 	 * @return				Session associated with TNCCS Connection
 	 */
 	 imv_session_t* (*add_session)(imv_session_manager_t *this,
 								   TNC_ConnectionID conn_id,
-								   uint32_t ar_id_type, chunk_t ar_id_value);
+								   linked_list_t *ar_identities);
 
 	/**
 	 * Remove a session
diff --git a/src/libimcv/imv/tables-mysql.sql b/src/libimcv/imv/tables-mysql.sql
index 47ee41c..cf50742 100644
--- a/src/libimcv/imv/tables-mysql.sql
+++ b/src/libimcv/imv/tables-mysql.sql
@@ -99,6 +99,14 @@ CREATE TABLE `sessions` (
   `rec` INTEGER DEFAULT 3
 );
 
+DROP TABLE IF EXISTS `sessions_identities`;
+CREATE TABLE `sessions_identities` (
+  `id` INTEGER NOT NULL PRIMARY KEY AUTO_INCREMENT,
+  `session_id` INTEGER NOT NULL REFERENCES `sessions`(`id`),
+  `identity_id` INTEGER NOT NULL REFERENCES `identities`(`id`),
+  UNIQUE (`session_id`, `identity_id`)
+);
+
 DROP TABLE IF EXISTS `workitems`;
 CREATE TABLE `workitems` (
   `id` INTEGER NOT NULL PRIMARY KEY AUTO_INCREMENT,
diff --git a/src/libimcv/imv/tables.sql b/src/libimcv/imv/tables.sql
index f732489..5c2a656 100644
--- a/src/libimcv/imv/tables.sql
+++ b/src/libimcv/imv/tables.sql
@@ -104,6 +104,14 @@ CREATE TABLE sessions (
   rec INTEGER DEFAULT 3
 );
 
+DROP TABLE IF EXISTS sessions_identities;
+CREATE TABLE sessions_identities (
+  id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
+  session_id INTEGER NOT NULL REFERENCES sessions(id),
+  identity_id INTEGER NOT NULL REFERENCES identities(id),
+  UNIQUE (session_id, identity_id)
+);
+
 DROP TABLE IF EXISTS workitems;
 CREATE TABLE workitems (
   id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
diff --git a/src/libimcv/plugins/imc_attestation/Makefile.in b/src/libimcv/plugins/imc_attestation/Makefile.in
index 3c5017f..8ad5618 100644
--- a/src/libimcv/plugins/imc_attestation/Makefile.in
+++ b/src/libimcv/plugins/imc_attestation/Makefile.in
@@ -227,6 +227,7 @@ DLLIB = @DLLIB@
 DLLTOOL = @DLLTOOL@
 DSYMUTIL = @DSYMUTIL@
 DUMPBIN = @DUMPBIN@
+EASY_INSTALL = @EASY_INSTALL@
 ECHO_C = @ECHO_C@
 ECHO_N = @ECHO_N@
 ECHO_T = @ECHO_T@
@@ -287,10 +288,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
 PLUGIN_CFLAGS = @PLUGIN_CFLAGS@
 PTHREADLIB = @PTHREADLIB@
 PYTHON = @PYTHON@
+PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@
 PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
 PYTHON_PLATFORM = @PYTHON_PLATFORM@
 PYTHON_PREFIX = @PYTHON_PREFIX@
 PYTHON_VERSION = @PYTHON_VERSION@
+PY_TEST = @PY_TEST@
 RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
@@ -364,6 +367,8 @@ json_CFLAGS = @json_CFLAGS@
 json_LIBS = @json_LIBS@
 libdir = @libdir@
 libexecdir = @libexecdir@
+libiptc_CFLAGS = @libiptc_CFLAGS@
+libiptc_LIBS = @libiptc_LIBS@
 linux_headers = @linux_headers@
 localedir = @localedir@
 localstatedir = @localstatedir@
diff --git a/src/libimcv/plugins/imc_attestation/imc_attestation_process.c b/src/libimcv/plugins/imc_attestation/imc_attestation_process.c
index 2fc2998..f24aec8 100644
--- a/src/libimcv/plugins/imc_attestation/imc_attestation_process.c
+++ b/src/libimcv/plugins/imc_attestation/imc_attestation_process.c
@@ -137,7 +137,11 @@ bool imc_attestation_process(pa_tnc_attr_t *attr, imc_msg_t *msg,
 			{
 				return FALSE;
 			}
-			pts->get_my_public_value(pts, &responder_value, &responder_nonce);
+			if (!pts->get_my_public_value(pts, &responder_value,
+										  &responder_nonce))
+			{
+				return FALSE;
+			}
 
 			/* Send DH Nonce Parameters Response attribute */
 			attr = tcg_pts_attr_dh_nonce_params_resp_create(selected_dh_group,
@@ -174,8 +178,10 @@ bool imc_attestation_process(pa_tnc_attr_t *attr, imc_msg_t *msg,
 				return FALSE;
 			}
 
-			pts->set_peer_public_value(pts, initiator_value, initiator_nonce);
-			if (!pts->calculate_secret(pts))
+
+			if (!pts->set_peer_public_value(pts, initiator_value,
+											initiator_nonce) ||
+				!pts->calculate_secret(pts))
 			{
 				return FALSE;
 			}
diff --git a/src/libimcv/plugins/imc_os/Makefile.in b/src/libimcv/plugins/imc_os/Makefile.in
index 3f4cf41..3b75386 100644
--- a/src/libimcv/plugins/imc_os/Makefile.in
+++ b/src/libimcv/plugins/imc_os/Makefile.in
@@ -224,6 +224,7 @@ DLLIB = @DLLIB@
 DLLTOOL = @DLLTOOL@
 DSYMUTIL = @DSYMUTIL@
 DUMPBIN = @DUMPBIN@
+EASY_INSTALL = @EASY_INSTALL@
 ECHO_C = @ECHO_C@
 ECHO_N = @ECHO_N@
 ECHO_T = @ECHO_T@
@@ -284,10 +285,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
 PLUGIN_CFLAGS = @PLUGIN_CFLAGS@
 PTHREADLIB = @PTHREADLIB@
 PYTHON = @PYTHON@
+PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@
 PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
 PYTHON_PLATFORM = @PYTHON_PLATFORM@
 PYTHON_PREFIX = @PYTHON_PREFIX@
 PYTHON_VERSION = @PYTHON_VERSION@
+PY_TEST = @PY_TEST@
 RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
@@ -361,6 +364,8 @@ json_CFLAGS = @json_CFLAGS@
 json_LIBS = @json_LIBS@
 libdir = @libdir@
 libexecdir = @libexecdir@
+libiptc_CFLAGS = @libiptc_CFLAGS@
+libiptc_LIBS = @libiptc_LIBS@
 linux_headers = @linux_headers@
 localedir = @localedir@
 localstatedir = @localstatedir@
diff --git a/src/libimcv/plugins/imc_scanner/Makefile.in b/src/libimcv/plugins/imc_scanner/Makefile.in
index a192b0a..7b69689 100644
--- a/src/libimcv/plugins/imc_scanner/Makefile.in
+++ b/src/libimcv/plugins/imc_scanner/Makefile.in
@@ -225,6 +225,7 @@ DLLIB = @DLLIB@
 DLLTOOL = @DLLTOOL@
 DSYMUTIL = @DSYMUTIL@
 DUMPBIN = @DUMPBIN@
+EASY_INSTALL = @EASY_INSTALL@
 ECHO_C = @ECHO_C@
 ECHO_N = @ECHO_N@
 ECHO_T = @ECHO_T@
@@ -285,10 +286,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
 PLUGIN_CFLAGS = @PLUGIN_CFLAGS@
 PTHREADLIB = @PTHREADLIB@
 PYTHON = @PYTHON@
+PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@
 PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
 PYTHON_PLATFORM = @PYTHON_PLATFORM@
 PYTHON_PREFIX = @PYTHON_PREFIX@
 PYTHON_VERSION = @PYTHON_VERSION@
+PY_TEST = @PY_TEST@
 RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
@@ -362,6 +365,8 @@ json_CFLAGS = @json_CFLAGS@
 json_LIBS = @json_LIBS@
 libdir = @libdir@
 libexecdir = @libexecdir@
+libiptc_CFLAGS = @libiptc_CFLAGS@
+libiptc_LIBS = @libiptc_LIBS@
 linux_headers = @linux_headers@
 localedir = @localedir@
 localstatedir = @localstatedir@
diff --git a/src/libimcv/plugins/imc_swid/Makefile.in b/src/libimcv/plugins/imc_swid/Makefile.in
index f1859a2..2847f09 100644
--- a/src/libimcv/plugins/imc_swid/Makefile.in
+++ b/src/libimcv/plugins/imc_swid/Makefile.in
@@ -227,6 +227,7 @@ DLLIB = @DLLIB@
 DLLTOOL = @DLLTOOL@
 DSYMUTIL = @DSYMUTIL@
 DUMPBIN = @DUMPBIN@
+EASY_INSTALL = @EASY_INSTALL@
 ECHO_C = @ECHO_C@
 ECHO_N = @ECHO_N@
 ECHO_T = @ECHO_T@
@@ -287,10 +288,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
 PLUGIN_CFLAGS = @PLUGIN_CFLAGS@
 PTHREADLIB = @PTHREADLIB@
 PYTHON = @PYTHON@
+PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@
 PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
 PYTHON_PLATFORM = @PYTHON_PLATFORM@
 PYTHON_PREFIX = @PYTHON_PREFIX@
 PYTHON_VERSION = @PYTHON_VERSION@
+PY_TEST = @PY_TEST@
 RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
@@ -364,6 +367,8 @@ json_CFLAGS = @json_CFLAGS@
 json_LIBS = @json_LIBS@
 libdir = @libdir@
 libexecdir = @libexecdir@
+libiptc_CFLAGS = @libiptc_CFLAGS@
+libiptc_LIBS = @libiptc_LIBS@
 linux_headers = @linux_headers@
 localedir = @localedir@
 localstatedir = @localstatedir@
diff --git a/src/libimcv/plugins/imc_test/Makefile.in b/src/libimcv/plugins/imc_test/Makefile.in
index 3e1d023..2048caa 100644
--- a/src/libimcv/plugins/imc_test/Makefile.in
+++ b/src/libimcv/plugins/imc_test/Makefile.in
@@ -224,6 +224,7 @@ DLLIB = @DLLIB@
 DLLTOOL = @DLLTOOL@
 DSYMUTIL = @DSYMUTIL@
 DUMPBIN = @DUMPBIN@
+EASY_INSTALL = @EASY_INSTALL@
 ECHO_C = @ECHO_C@
 ECHO_N = @ECHO_N@
 ECHO_T = @ECHO_T@
@@ -284,10 +285,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
 PLUGIN_CFLAGS = @PLUGIN_CFLAGS@
 PTHREADLIB = @PTHREADLIB@
 PYTHON = @PYTHON@
+PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@
 PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
 PYTHON_PLATFORM = @PYTHON_PLATFORM@
 PYTHON_PREFIX = @PYTHON_PREFIX@
 PYTHON_VERSION = @PYTHON_VERSION@
+PY_TEST = @PY_TEST@
 RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
@@ -361,6 +364,8 @@ json_CFLAGS = @json_CFLAGS@
 json_LIBS = @json_LIBS@
 libdir = @libdir@
 libexecdir = @libexecdir@
+libiptc_CFLAGS = @libiptc_CFLAGS@
+libiptc_LIBS = @libiptc_LIBS@
 linux_headers = @linux_headers@
 localedir = @localedir@
 localstatedir = @localstatedir@
diff --git a/src/libimcv/plugins/imv_attestation/Makefile.in b/src/libimcv/plugins/imv_attestation/Makefile.in
index 3ba7c8c..09a0ab0 100644
--- a/src/libimcv/plugins/imv_attestation/Makefile.in
+++ b/src/libimcv/plugins/imv_attestation/Makefile.in
@@ -236,6 +236,7 @@ DLLIB = @DLLIB@
 DLLTOOL = @DLLTOOL@
 DSYMUTIL = @DSYMUTIL@
 DUMPBIN = @DUMPBIN@
+EASY_INSTALL = @EASY_INSTALL@
 ECHO_C = @ECHO_C@
 ECHO_N = @ECHO_N@
 ECHO_T = @ECHO_T@
@@ -296,10 +297,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
 PLUGIN_CFLAGS = @PLUGIN_CFLAGS@
 PTHREADLIB = @PTHREADLIB@
 PYTHON = @PYTHON@
+PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@
 PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
 PYTHON_PLATFORM = @PYTHON_PLATFORM@
 PYTHON_PREFIX = @PYTHON_PREFIX@
 PYTHON_VERSION = @PYTHON_VERSION@
+PY_TEST = @PY_TEST@
 RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
@@ -373,6 +376,8 @@ json_CFLAGS = @json_CFLAGS@
 json_LIBS = @json_LIBS@
 libdir = @libdir@
 libexecdir = @libexecdir@
+libiptc_CFLAGS = @libiptc_CFLAGS@
+libiptc_LIBS = @libiptc_LIBS@
 linux_headers = @linux_headers@
 localedir = @localedir@
 localstatedir = @localstatedir@
diff --git a/src/libimcv/plugins/imv_attestation/attest_db.c b/src/libimcv/plugins/imv_attestation/attest_db.c
index f85a02b..f1a1f92 100644
--- a/src/libimcv/plugins/imv_attestation/attest_db.c
+++ b/src/libimcv/plugins/imv_attestation/attest_db.c
@@ -849,29 +849,31 @@ METHOD(attest_db_t, list_devices, void,
 {
 	enumerator_t *e, *e_ar;
 	chunk_t ar_id_value = chunk_empty;
-	char *product, *device;
+	char *product, *device, *description;
 	time_t timestamp;
-	int id, last_id = 0, ar_id = 0, last_ar_id = 0, device_count = 0;
+	int id, last_id = 0, ar_id = 0, last_ar_id = 0, device_count = 0, trusted;
 	int session_id, rec;
 	u_int32_t ar_id_type;
 	u_int tstamp;
 
 	e = this->db->query(this->db,
-			"SELECT d.id, d.value, s.id, s.time, s.identity, s.rec, p.name "
+			"SELECT d.id, d.value, d.trusted, d.description, "
+			"s.id, s.time, s.identity, s.rec, p.name "
 			"FROM devices AS d "
 			"JOIN sessions AS s ON d.id = s.device "
 			"JOIN products AS p ON p.id = s.product "
-			"ORDER BY d.value, s.time DESC", DB_INT, DB_TEXT, DB_INT, DB_UINT,
-			 DB_INT, DB_INT, DB_TEXT);
+			"ORDER BY d.value, s.time DESC", DB_INT, DB_TEXT, DB_INT, DB_TEXT,
+			 DB_INT, DB_UINT, DB_INT, DB_INT, DB_TEXT);
 
 	if (e)
 	{
-		while (e->enumerate(e, &id, &device, &session_id, &tstamp, &ar_id, &rec,
-							   &product))
+		while (e->enumerate(e, &id, &device, &trusted, &description,
+							   &session_id, &tstamp, &ar_id, &rec, &product))
 		{
 			if (id != last_id)
 			{
-				printf("%4d: %s - %s\n", id, device, product);
+				printf("%4d: %s %s - %s - %s\n", id, trusted ? "+" : "-",
+												 device, product, description);
 				device_count++;
 				last_id = id;
 			}
diff --git a/src/libimcv/plugins/imv_attestation/build-database.sh b/src/libimcv/plugins/imv_attestation/build-database.sh
index ca2939b..0babb53 100755
--- a/src/libimcv/plugins/imv_attestation/build-database.sh
+++ b/src/libimcv/plugins/imv_attestation/build-database.sh
@@ -2,7 +2,7 @@
 
 p="Ubuntu 14.04 x86_64"
 a="x86_64-linux-gnu"
-k="3.13.0-37-generic"
+k="3.13.0-46-generic"
 
 for hash in sha1 sha256
 do
diff --git a/src/libimcv/plugins/imv_attestation/imv_attestation_build.c b/src/libimcv/plugins/imv_attestation/imv_attestation_build.c
index c39fe8d..db93ac4 100644
--- a/src/libimcv/plugins/imv_attestation/imv_attestation_build.c
+++ b/src/libimcv/plugins/imv_attestation/imv_attestation_build.c
@@ -69,7 +69,11 @@ bool imv_attestation_build(imv_msg_t *out_msg, imv_state_t *state,
 
 			/* Send DH nonce finish attribute */
 			selected_algorithm = pts->get_meas_algorithm(pts);
-			pts->get_my_public_value(pts, &initiator_value, &initiator_nonce);
+			if (!pts->get_my_public_value(pts, &initiator_value,
+										  &initiator_nonce))
+			{
+				return FALSE;
+			}
 			attr = tcg_pts_attr_dh_nonce_finish_create(selected_algorithm,
 											initiator_value, initiator_nonce);
 			attr->set_noskip_flag(attr, TRUE);
diff --git a/src/libimcv/plugins/imv_attestation/imv_attestation_process.c b/src/libimcv/plugins/imv_attestation/imv_attestation_process.c
index 89a1f02..fbeb661 100644
--- a/src/libimcv/plugins/imv_attestation/imv_attestation_process.c
+++ b/src/libimcv/plugins/imv_attestation/imv_attestation_process.c
@@ -134,11 +134,11 @@ bool imv_attestation_process(pa_tnc_attr_t *attr, imv_msg_t *out_msg,
 			}
 
 			responder_value = attr_cast->get_responder_value(attr_cast);
-			pts->set_peer_public_value(pts, responder_value,
-											responder_nonce);
 
 			/* Calculate secret assessment value */
-			if (!pts->calculate_secret(pts))
+			if (!pts->set_peer_public_value(pts, responder_value,
+											responder_nonce) ||
+				!pts->calculate_secret(pts))
 			{
 				return FALSE;
 			}
@@ -198,7 +198,7 @@ bool imv_attestation_process(pa_tnc_attr_t *attr, imv_msg_t *out_msg,
 
 				e = pts_credmgr->create_trusted_enumerator(pts_credmgr,
 							KEY_ANY, aik->get_issuer(aik), FALSE);
-				while (e->enumerate(e, &issuer))
+				while (e->enumerate(e, &issuer, NULL))
 				{
 					if (aik->issued_by(aik, issuer, NULL))
 					{
diff --git a/src/libimcv/plugins/imv_os/Makefile.in b/src/libimcv/plugins/imv_os/Makefile.in
index 36e708f..ec34889 100644
--- a/src/libimcv/plugins/imv_os/Makefile.in
+++ b/src/libimcv/plugins/imv_os/Makefile.in
@@ -232,6 +232,7 @@ DLLIB = @DLLIB@
 DLLTOOL = @DLLTOOL@
 DSYMUTIL = @DSYMUTIL@
 DUMPBIN = @DUMPBIN@
+EASY_INSTALL = @EASY_INSTALL@
 ECHO_C = @ECHO_C@
 ECHO_N = @ECHO_N@
 ECHO_T = @ECHO_T@
@@ -292,10 +293,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
 PLUGIN_CFLAGS = @PLUGIN_CFLAGS@
 PTHREADLIB = @PTHREADLIB@
 PYTHON = @PYTHON@
+PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@
 PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
 PYTHON_PLATFORM = @PYTHON_PLATFORM@
 PYTHON_PREFIX = @PYTHON_PREFIX@
 PYTHON_VERSION = @PYTHON_VERSION@
+PY_TEST = @PY_TEST@
 RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
@@ -369,6 +372,8 @@ json_CFLAGS = @json_CFLAGS@
 json_LIBS = @json_LIBS@
 libdir = @libdir@
 libexecdir = @libexecdir@
+libiptc_CFLAGS = @libiptc_CFLAGS@
+libiptc_LIBS = @libiptc_LIBS@
 linux_headers = @linux_headers@
 localedir = @localedir@
 localstatedir = @localstatedir@
diff --git a/src/libimcv/plugins/imv_scanner/Makefile.in b/src/libimcv/plugins/imv_scanner/Makefile.in
index 2677b33..08abbf5 100644
--- a/src/libimcv/plugins/imv_scanner/Makefile.in
+++ b/src/libimcv/plugins/imv_scanner/Makefile.in
@@ -226,6 +226,7 @@ DLLIB = @DLLIB@
 DLLTOOL = @DLLTOOL@
 DSYMUTIL = @DSYMUTIL@
 DUMPBIN = @DUMPBIN@
+EASY_INSTALL = @EASY_INSTALL@
 ECHO_C = @ECHO_C@
 ECHO_N = @ECHO_N@
 ECHO_T = @ECHO_T@
@@ -286,10 +287,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
 PLUGIN_CFLAGS = @PLUGIN_CFLAGS@
 PTHREADLIB = @PTHREADLIB@
 PYTHON = @PYTHON@
+PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@
 PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
 PYTHON_PLATFORM = @PYTHON_PLATFORM@
 PYTHON_PREFIX = @PYTHON_PREFIX@
 PYTHON_VERSION = @PYTHON_VERSION@
+PY_TEST = @PY_TEST@
 RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
@@ -363,6 +366,8 @@ json_CFLAGS = @json_CFLAGS@
 json_LIBS = @json_LIBS@
 libdir = @libdir@
 libexecdir = @libexecdir@
+libiptc_CFLAGS = @libiptc_CFLAGS@
+libiptc_LIBS = @libiptc_LIBS@
 linux_headers = @linux_headers@
 localedir = @localedir@
 localstatedir = @localstatedir@
diff --git a/src/libimcv/plugins/imv_swid/Makefile.in b/src/libimcv/plugins/imv_swid/Makefile.in
index 815722f..936bee8 100644
--- a/src/libimcv/plugins/imv_swid/Makefile.in
+++ b/src/libimcv/plugins/imv_swid/Makefile.in
@@ -227,6 +227,7 @@ DLLIB = @DLLIB@
 DLLTOOL = @DLLTOOL@
 DSYMUTIL = @DSYMUTIL@
 DUMPBIN = @DUMPBIN@
+EASY_INSTALL = @EASY_INSTALL@
 ECHO_C = @ECHO_C@
 ECHO_N = @ECHO_N@
 ECHO_T = @ECHO_T@
@@ -287,10 +288,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
 PLUGIN_CFLAGS = @PLUGIN_CFLAGS@
 PTHREADLIB = @PTHREADLIB@
 PYTHON = @PYTHON@
+PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@
 PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
 PYTHON_PLATFORM = @PYTHON_PLATFORM@
 PYTHON_PREFIX = @PYTHON_PREFIX@
 PYTHON_VERSION = @PYTHON_VERSION@
+PY_TEST = @PY_TEST@
 RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
@@ -364,6 +367,8 @@ json_CFLAGS = @json_CFLAGS@
 json_LIBS = @json_LIBS@
 libdir = @libdir@
 libexecdir = @libexecdir@
+libiptc_CFLAGS = @libiptc_CFLAGS@
+libiptc_LIBS = @libiptc_LIBS@
 linux_headers = @linux_headers@
 localedir = @localedir@
 localstatedir = @localstatedir@
diff --git a/src/libimcv/plugins/imv_test/Makefile.in b/src/libimcv/plugins/imv_test/Makefile.in
index 66da75a..8e0e223 100644
--- a/src/libimcv/plugins/imv_test/Makefile.in
+++ b/src/libimcv/plugins/imv_test/Makefile.in
@@ -225,6 +225,7 @@ DLLIB = @DLLIB@
 DLLTOOL = @DLLTOOL@
 DSYMUTIL = @DSYMUTIL@
 DUMPBIN = @DUMPBIN@
+EASY_INSTALL = @EASY_INSTALL@
 ECHO_C = @ECHO_C@
 ECHO_N = @ECHO_N@
 ECHO_T = @ECHO_T@
@@ -285,10 +286,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
 PLUGIN_CFLAGS = @PLUGIN_CFLAGS@
 PTHREADLIB = @PTHREADLIB@
 PYTHON = @PYTHON@
+PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@
 PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
 PYTHON_PLATFORM = @PYTHON_PLATFORM@
 PYTHON_PREFIX = @PYTHON_PREFIX@
 PYTHON_VERSION = @PYTHON_VERSION@
+PY_TEST = @PY_TEST@
 RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
@@ -362,6 +365,8 @@ json_CFLAGS = @json_CFLAGS@
 json_LIBS = @json_LIBS@
 libdir = @libdir@
 libexecdir = @libexecdir@
+libiptc_CFLAGS = @libiptc_CFLAGS@
+libiptc_LIBS = @libiptc_LIBS@
 linux_headers = @linux_headers@
 localedir = @localedir@
 localstatedir = @localstatedir@
diff --git a/src/libimcv/pts/components/ita/ita_comp_tboot.c b/src/libimcv/pts/components/ita/ita_comp_tboot.c
index 273c18f..ce318ec 100644
--- a/src/libimcv/pts/components/ita/ita_comp_tboot.c
+++ b/src/libimcv/pts/components/ita/ita_comp_tboot.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2011-2014 Andreas Steffen
+ * Copyright (C) 2011-2015 Andreas Steffen
  * HSR Hochschule fuer Technik Rapperswil
  *
  * This program is free software; you can redistribute it and/or modify it
@@ -61,11 +61,6 @@ struct pts_ita_comp_tboot_t {
 	int cid;
 
 	/**
-	 * Primary key for AIK database entry
-	 */
-	int kid;
-
-	/**
 	 * Component is registering measurements
 	 */
 	bool is_registering;
@@ -243,7 +238,7 @@ METHOD(pts_component_t, verify, status_t,
 	else
 	{
 		status = this->pts_db->check_comp_measurement(this->pts_db,
-								measurement, this->cid, this->kid,
+								measurement, this->cid, this->aik_id,
 								++this->seq_no, extended_pcr, algo);
 		if (status != SUCCESS)
 		{
diff --git a/src/libimcv/pts/pts.c b/src/libimcv/pts/pts.c
index 2fff4c9..1ca7209 100644
--- a/src/libimcv/pts/pts.c
+++ b/src/libimcv/pts/pts.c
@@ -224,17 +224,24 @@ METHOD(pts_t, create_dh_nonce, bool,
 	return TRUE;
 }
 
-METHOD(pts_t, get_my_public_value, void,
+METHOD(pts_t, get_my_public_value, bool,
 	private_pts_t *this, chunk_t *value, chunk_t *nonce)
 {
-	this->dh->get_my_public_value(this->dh, value);
+	if (!this->dh->get_my_public_value(this->dh, value))
+	{
+		return FALSE;
+	}
 	*nonce = this->is_imc ? this->responder_nonce : this->initiator_nonce;
+	return TRUE;
 }
 
-METHOD(pts_t, set_peer_public_value, void,
+METHOD(pts_t, set_peer_public_value, bool,
 	private_pts_t *this, chunk_t value, chunk_t nonce)
 {
-	this->dh->set_other_public_value(this->dh, value);
+	if (!this->dh->set_other_public_value(this->dh, value))
+	{
+		return FALSE;
+	}
 
 	nonce = chunk_clone(nonce);
 	if (this->is_imc)
@@ -245,6 +252,7 @@ METHOD(pts_t, set_peer_public_value, void,
 	{
 		this->responder_nonce = nonce;
 	}
+	return TRUE;
 }
 
 METHOD(pts_t, calculate_secret, bool,
@@ -264,7 +272,7 @@ METHOD(pts_t, calculate_secret, bool,
 	DBG3(DBG_PTS, "responder nonce: %B", &this->responder_nonce);
 
 	/* Calculate the DH secret */
-	if (this->dh->get_shared_secret(this->dh, &shared_secret) != SUCCESS)
+	if (!this->dh->get_shared_secret(this->dh, &shared_secret))
 	{
 		DBG1(DBG_PTS, "shared DH secret computation failed");
 		return FALSE;
diff --git a/src/libimcv/pts/pts.h b/src/libimcv/pts/pts.h
index be32a34..d525306 100644
--- a/src/libimcv/pts/pts.h
+++ b/src/libimcv/pts/pts.h
@@ -143,16 +143,18 @@ struct pts_t {
 	 *
 	 * @param value				My public DH value
 	 * @param nonce				My DH nonce
+	 * @return					TRUE if public value retrieved successfully
 	 */
-	void (*get_my_public_value)(pts_t *this, chunk_t *value, chunk_t *nonce);
+	bool (*get_my_public_value)(pts_t *this, chunk_t *value, chunk_t *nonce);
 
 	/**
 	 * Set peer Diffie.Hellman public value
 	 *
 	 * @param value				Peer public DH value
 	 * @param nonce				Peer DH nonce
+	 * @return					TRUE if public value set successfully
 	 */
-	void (*set_peer_public_value) (pts_t *this, chunk_t value, chunk_t nonce);
+	bool (*set_peer_public_value) (pts_t *this, chunk_t value, chunk_t nonce);
 
 	/**
 	 * Calculates assessment secret to be used for TPM Quote as ExternalData
diff --git a/src/libimcv/seg/seg_env.c b/src/libimcv/seg/seg_env.c
index c47ce29..f384192 100644
--- a/src/libimcv/seg/seg_env.c
+++ b/src/libimcv/seg/seg_env.c
@@ -219,6 +219,7 @@ seg_env_t *seg_env_create(uint32_t base_attr_id, pa_tnc_attr_t *base_attr,
 	if (max_seg_size <  PA_TNC_ATTR_HEADER_SIZE ||
 		max_seg_size >= PA_TNC_ATTR_HEADER_SIZE + value.len)
 	{
+		base_attr->destroy(base_attr);
 		return NULL;
 	}
 
@@ -233,7 +234,7 @@ seg_env_t *seg_env_create(uint32_t base_attr_id, pa_tnc_attr_t *base_attr,
 			.destroy = _destroy,
 		},
 		.base_attr_id = base_attr_id,
-		.base_attr = base_attr->get_ref(base_attr),
+		.base_attr = base_attr,
 		.max_seg_size = max_seg_size,
 		.data = base_attr->get_value(base_attr),
 	);
diff --git a/src/libimcv/seg/seg_env.h b/src/libimcv/seg/seg_env.h
index 08d33d7..611f9a9 100644
--- a/src/libimcv/seg/seg_env.h
+++ b/src/libimcv/seg/seg_env.h
@@ -98,7 +98,7 @@ struct seg_env_t {
  * Create a PA-TNC attribute segment envelope object
  *
  * @param base_attr_id		Base Attribute ID
- * @param base_attr			Base Attribute to be segmented
+ * @param base_attr			Base Attribute to be segmented, owned by seg_env_t
  * @param max_seg_size		Maximum segment size
  */
 seg_env_t* seg_env_create(uint32_t base_attr_id, pa_tnc_attr_t *base_attr,
diff --git a/src/libimcv/suites/test_imcv_seg.c b/src/libimcv/suites/test_imcv_seg.c
index 469b111..8b51eda 100644
--- a/src/libimcv/suites/test_imcv_seg.c
+++ b/src/libimcv/suites/test_imcv_seg.c
@@ -64,10 +64,11 @@ START_TEST(test_imcv_seg_env)
 	libimcv_init(FALSE);
 	max_seg_size  = seg_env_tests[_i].max_seg_size;
 	last_seg_size = seg_env_tests[_i].last_seg_size;
+
 	base_attr = ita_attr_command_create(command);
 	base_attr->build(base_attr);
-
 	seg_env = seg_env_create(id, base_attr, max_seg_size);
+
 	if (seg_env_tests[_i].next_segs == 0)
 	{
 		ck_assert(seg_env == NULL);
@@ -156,7 +157,6 @@ START_TEST(test_imcv_seg_env)
 		seg_env1->destroy(seg_env1);
 		base_attr1->destroy(base_attr1);
 	}
-	base_attr->destroy(base_attr);
 	libimcv_deinit();
 }
 END_TEST
@@ -226,7 +226,6 @@ START_TEST(test_imcv_seg_env_special)
 	/* cleanup */
 	attr->destroy(attr);
 	seg_env->destroy(seg_env);
-	base_attr->destroy(base_attr);
 }
 END_TEST
 
@@ -306,7 +305,8 @@ START_TEST(test_imcv_seg_contract)
 									 TRUE, issuer_id, FALSE);
 	contract_r = seg_contract_create(msg_type, max_attr_size, max_seg_size,
 									 FALSE, issuer_id, TRUE);
-	attr = contract_r->first_segment(contract_r, base_attr_r);
+	attr = contract_r->first_segment(contract_r,
+									 base_attr_r->get_ref(base_attr_r));
 
 	if (seg_env_tests[_i].next_segs == 0)
 	{
@@ -422,8 +422,8 @@ START_TEST(test_imcv_seg_contract_special)
 	ck_assert(!oversize);
 
 	/* get first segment of each base attribute */
-	attr1_f = contract_r->first_segment(contract_r, base_attr1_r);
-	attr2_f = contract_r->first_segment(contract_r, base_attr2_r);
+	attr1_f = contract_r->first_segment(contract_r, base_attr1_r->get_ref(base_attr1_r));
+	attr2_f = contract_r->first_segment(contract_r, base_attr2_r->get_ref(base_attr2_r));
 	ck_assert(attr1_f);
 	ck_assert(attr2_f);
 	seg_env_attr1 = (tcg_seg_attr_seg_env_t*)attr1_f;
diff --git a/src/libimcv/tcg/pts/tcg_pts_attr_file_meas.c b/src/libimcv/tcg/pts/tcg_pts_attr_file_meas.c
index 5b4cc27..3978829 100644
--- a/src/libimcv/tcg/pts/tcg_pts_attr_file_meas.c
+++ b/src/libimcv/tcg/pts/tcg_pts_attr_file_meas.c
@@ -242,6 +242,8 @@ METHOD(pa_tnc_attr_t, process, status_t,
 		this->count--;
 	}
 
+	status = SUCCESS;
+
 	if (this->length != this->offset)
 	{
 		DBG1(DBG_TNC, "inconsistent length for %N/%N", pen_names, PEN_TCG,
@@ -249,7 +251,6 @@ METHOD(pa_tnc_attr_t, process, status_t,
 		*offset = this->offset;
 		status = FAILED;
 	}
-	status = SUCCESS;
 
 end:
 	reader->destroy(reader);
diff --git a/src/libipsec/Makefile.in b/src/libipsec/Makefile.in
index 3663cf8..a80d28a 100644
--- a/src/libipsec/Makefile.in
+++ b/src/libipsec/Makefile.in
@@ -266,6 +266,7 @@ DLLIB = @DLLIB@
 DLLTOOL = @DLLTOOL@
 DSYMUTIL = @DSYMUTIL@
 DUMPBIN = @DUMPBIN@
+EASY_INSTALL = @EASY_INSTALL@
 ECHO_C = @ECHO_C@
 ECHO_N = @ECHO_N@
 ECHO_T = @ECHO_T@
@@ -326,10 +327,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
 PLUGIN_CFLAGS = @PLUGIN_CFLAGS@
 PTHREADLIB = @PTHREADLIB@
 PYTHON = @PYTHON@
+PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@
 PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
 PYTHON_PLATFORM = @PYTHON_PLATFORM@
 PYTHON_PREFIX = @PYTHON_PREFIX@
 PYTHON_VERSION = @PYTHON_VERSION@
+PY_TEST = @PY_TEST@
 RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
@@ -403,6 +406,8 @@ json_CFLAGS = @json_CFLAGS@
 json_LIBS = @json_LIBS@
 libdir = @libdir@
 libexecdir = @libexecdir@
+libiptc_CFLAGS = @libiptc_CFLAGS@
+libiptc_LIBS = @libiptc_LIBS@
 linux_headers = @linux_headers@
 localedir = @localedir@
 localstatedir = @localstatedir@
diff --git a/src/libipsec/ip_packet.c b/src/libipsec/ip_packet.c
index 0998efa..21dbd5e 100644
--- a/src/libipsec/ip_packet.c
+++ b/src/libipsec/ip_packet.c
@@ -443,7 +443,7 @@ ip_packet_t *ip_packet_create_from_data(host_t *src, host_t *dst,
 		{
 			struct ip6_hdr ip = {
 				.ip6_flow = htonl(6),
-				.ip6_plen = htons(40 + data.len),
+				.ip6_plen = htons(data.len),
 				.ip6_nxt = next_header,
 				.ip6_hlim = 0x80,
 			};
diff --git a/src/libipsec/ipsec_event_listener.h b/src/libipsec/ipsec_event_listener.h
index c5c39b0..f15f6fe 100644
--- a/src/libipsec/ipsec_event_listener.h
+++ b/src/libipsec/ipsec_event_listener.h
@@ -35,14 +35,12 @@ struct ipsec_event_listener_t {
 	/**
 	 * Called when the lifetime of an IPsec SA expired
 	 *
-	 * @param reqid			reqid of the expired SA
 	 * @param protocol		protocol of the expired SA
 	 * @param spi			spi of the expired SA
+	 * @param dst			destination address of expired SA
 	 * @param hard			TRUE if this is a hard expire, FALSE otherwise
 	 */
-	void (*expire)(u_int32_t reqid, u_int8_t protocol, u_int32_t spi,
-				   bool hard);
-
+	void (*expire)(u_int8_t protocol, u_int32_t spi, host_t *dst, bool hard);
 };
 
 #endif /** IPSEC_EVENT_LISTENER_H_ @}*/
diff --git a/src/libipsec/ipsec_event_relay.c b/src/libipsec/ipsec_event_relay.c
index c6b2a55..0480630 100644
--- a/src/libipsec/ipsec_event_relay.c
+++ b/src/libipsec/ipsec_event_relay.c
@@ -65,9 +65,9 @@ typedef struct {
 	} type;
 
 	/**
-	 * Reqid of the SA, if any
+	 * Protocol of the SA
 	 */
-	u_int32_t reqid;
+	u_int8_t protocol;
 
 	/**
 	 * SPI of the SA, if any
@@ -75,13 +75,16 @@ typedef struct {
 	u_int32_t spi;
 
 	/**
+	 * SA destination address
+	 */
+	host_t *dst;
+
+	/**
 	 * Additional data for specific event types
 	 */
 	union {
 
 		struct {
-			/** Protocol of the SA */
-			u_int8_t protocol;
 			/** TRUE in case of a hard expire */
 			bool hard;
 		} expire;
@@ -91,6 +94,15 @@ typedef struct {
 } ipsec_event_t;
 
 /**
+ * Destroy IPsec event data
+ */
+static void ipsec_event_destroy(ipsec_event_t *event)
+{
+	event->dst->destroy(event->dst);
+	free(event);
+}
+
+/**
  * Dequeue events and relay them to listeners
  */
 static job_requeue_t handle_events(private_ipsec_event_relay_t *this)
@@ -110,31 +122,31 @@ static job_requeue_t handle_events(private_ipsec_event_relay_t *this)
 			case IPSEC_EVENT_EXPIRE:
 				if (current->expire)
 				{
-					current->expire(event->reqid, event->data.expire.protocol,
-									event->spi, event->data.expire.hard);
+					current->expire(event->protocol, event->spi, event->dst,
+									event->data.expire.hard);
 				}
 				break;
 		}
 	}
 	enumerator->destroy(enumerator);
 	this->lock->unlock(this->lock);
-	free(event);
+	ipsec_event_destroy(event);
 	return JOB_REQUEUE_DIRECT;
 }
 
 METHOD(ipsec_event_relay_t, expire, void,
-	private_ipsec_event_relay_t *this, u_int32_t reqid, u_int8_t protocol,
-	u_int32_t spi, bool hard)
+	private_ipsec_event_relay_t *this, u_int8_t protocol, u_int32_t spi,
+	host_t *dst, bool hard)
 {
 	ipsec_event_t *event;
 
 	INIT(event,
 		.type = IPSEC_EVENT_EXPIRE,
-		.reqid = reqid,
+		.protocol = protocol,
 		.spi = spi,
+		.dst = dst->clone(dst),
 		.data = {
 			.expire = {
-				.protocol = protocol,
 				.hard = hard,
 			},
 		},
diff --git a/src/libipsec/ipsec_event_relay.h b/src/libipsec/ipsec_event_relay.h
index c6935d5..1dddf12 100644
--- a/src/libipsec/ipsec_event_relay.h
+++ b/src/libipsec/ipsec_event_relay.h
@@ -38,13 +38,13 @@ struct ipsec_event_relay_t {
 	/**
 	 * Raise an expire event.
 	 *
-	 * @param reqid			reqid of the expired IPsec SA
 	 * @param protocol		protocol (e.g ESP) of the expired SA
 	 * @param spi			SPI of the expired SA
+	 * @param dst			destination address of expired SA
 	 * @param hard			TRUE for a hard expire, FALSE otherwise
 	 */
-	void (*expire)(ipsec_event_relay_t *this, u_int32_t reqid,
-				   u_int8_t protocol, u_int32_t spi, bool hard);
+	void (*expire)(ipsec_event_relay_t *this, u_int8_t protocol, u_int32_t spi,
+				   host_t *dst, bool hard);
 
 	/**
 	 * Register a listener to events raised by this manager
diff --git a/src/libipsec/ipsec_sa.c b/src/libipsec/ipsec_sa.c
index 6ec8bd2..ccbbb1b 100644
--- a/src/libipsec/ipsec_sa.c
+++ b/src/libipsec/ipsec_sa.c
@@ -194,8 +194,8 @@ METHOD(ipsec_sa_t, expire, void,
 		if (!this->hard_expired)
 		{
 			this->hard_expired = TRUE;
-			ipsec->events->expire(ipsec->events, this->reqid, this->protocol,
-								  this->spi, TRUE);
+			ipsec->events->expire(ipsec->events, this->protocol, this->spi,
+								  this->dst, TRUE);
 		}
 	}
 	else
@@ -203,8 +203,8 @@ METHOD(ipsec_sa_t, expire, void,
 		if (!this->hard_expired && !this->soft_expired)
 		{
 			this->soft_expired = TRUE;
-			ipsec->events->expire(ipsec->events, this->reqid, this->protocol,
-								  this->spi, FALSE);
+			ipsec->events->expire(ipsec->events, this->protocol, this->spi,
+								  this->dst, FALSE);
 		}
 	}
 }
@@ -275,8 +275,7 @@ ipsec_sa_t *ipsec_sa_create(u_int32_t spi, host_t *src, host_t *dst,
 		u_int8_t protocol, u_int32_t reqid, mark_t mark, u_int32_t tfc,
 		lifetime_cfg_t *lifetime, u_int16_t enc_alg, chunk_t enc_key,
 		u_int16_t int_alg, chunk_t int_key, ipsec_mode_t mode,
-		u_int16_t ipcomp, u_int16_t cpi, bool encap, bool esn, bool inbound,
-		traffic_selector_t *src_ts,	traffic_selector_t *dst_ts)
+		u_int16_t ipcomp, u_int16_t cpi, bool encap, bool esn, bool inbound)
 {
 	private_ipsec_sa_t *this;
 
diff --git a/src/libipsec/ipsec_sa.h b/src/libipsec/ipsec_sa.h
index 5e69f18..8dad29a 100644
--- a/src/libipsec/ipsec_sa.h
+++ b/src/libipsec/ipsec_sa.h
@@ -197,8 +197,6 @@ struct ipsec_sa_t {
  * @param encap			enable UDP encapsulation (must be TRUE)
  * @param esn			Extended Sequence Numbers (currently not supported)
  * @param inbound		TRUE if this is an inbound SA, FALSE otherwise
- * @param src_ts		source traffic selector
- * @param dst_ts		destination traffic selector
  * @return				the IPsec SA, or NULL if the creation failed
  */
 ipsec_sa_t *ipsec_sa_create(u_int32_t spi, host_t *src, host_t *dst,
@@ -207,8 +205,6 @@ ipsec_sa_t *ipsec_sa_create(u_int32_t spi, host_t *src, host_t *dst,
 							u_int16_t enc_alg, chunk_t enc_key,
 							u_int16_t int_alg, chunk_t int_key,
 							ipsec_mode_t mode, u_int16_t ipcomp, u_int16_t cpi,
-							bool encap, bool esn, bool inbound,
-							traffic_selector_t *src_ts,
-							traffic_selector_t *dst_ts);
+							bool encap, bool esn, bool inbound);
 
 #endif /** IPSEC_SA_H_ @}*/
diff --git a/src/libipsec/ipsec_sa_mgr.c b/src/libipsec/ipsec_sa_mgr.c
index 1db1776..07ffa9e 100644
--- a/src/libipsec/ipsec_sa_mgr.c
+++ b/src/libipsec/ipsec_sa_mgr.c
@@ -396,12 +396,10 @@ static bool allocate_spi(private_ipsec_sa_mgr_t *this, u_int32_t spi)
 
 METHOD(ipsec_sa_mgr_t, get_spi, status_t,
 	private_ipsec_sa_mgr_t *this, host_t *src, host_t *dst, u_int8_t protocol,
-	u_int32_t reqid, u_int32_t *spi)
+	u_int32_t *spi)
 {
 	u_int32_t spi_new;
 
-	DBG2(DBG_ESP, "allocating SPI for reqid {%u}", reqid);
-
 	this->mutex->lock(this->mutex);
 	if (!this->rng)
 	{
@@ -420,7 +418,7 @@ METHOD(ipsec_sa_mgr_t, get_spi, status_t,
 								 (u_int8_t*)&spi_new))
 		{
 			this->mutex->unlock(this->mutex);
-			DBG1(DBG_ESP, "failed to allocate SPI for reqid {%u}", reqid);
+			DBG1(DBG_ESP, "failed to allocate SPI");
 			return FAILED;
 		}
 		/* make sure the SPI is valid (not in range 0-255) */
@@ -432,7 +430,7 @@ METHOD(ipsec_sa_mgr_t, get_spi, status_t,
 
 	*spi = spi_new;
 
-	DBG2(DBG_ESP, "allocated SPI %.8x for reqid {%u}", ntohl(*spi), reqid);
+	DBG2(DBG_ESP, "allocated SPI %.8x", ntohl(*spi));
 	return SUCCESS;
 }
 
@@ -442,7 +440,7 @@ METHOD(ipsec_sa_mgr_t, add_sa, status_t,
 	lifetime_cfg_t *lifetime, u_int16_t enc_alg, chunk_t enc_key,
 	u_int16_t int_alg, chunk_t int_key, ipsec_mode_t mode, u_int16_t ipcomp,
 	u_int16_t cpi, bool initiator, bool encap, bool esn, bool inbound,
-	traffic_selector_t *src_ts, traffic_selector_t *dst_ts)
+	bool update)
 {
 	ipsec_sa_entry_t *entry;
 	ipsec_sa_t *sa_new;
@@ -456,7 +454,7 @@ METHOD(ipsec_sa_mgr_t, add_sa, status_t,
 
 	sa_new = ipsec_sa_create(spi, src, dst, protocol, reqid, mark, tfc,
 							 lifetime, enc_alg, enc_key, int_alg, int_key, mode,
-							 ipcomp, cpi, encap, esn, inbound, src_ts, dst_ts);
+							 ipcomp, cpi, encap, esn, inbound);
 	if (!sa_new)
 	{
 		DBG1(DBG_ESP, "failed to create SAD entry");
@@ -465,7 +463,7 @@ METHOD(ipsec_sa_mgr_t, add_sa, status_t,
 
 	this->mutex->lock(this->mutex);
 
-	if (inbound)
+	if (update)
 	{	/* remove any pre-allocated SPIs */
 		u_int32_t *spi_alloc;
 
diff --git a/src/libipsec/ipsec_sa_mgr.h b/src/libipsec/ipsec_sa_mgr.h
index 8c234ce..a57eab4 100644
--- a/src/libipsec/ipsec_sa_mgr.h
+++ b/src/libipsec/ipsec_sa_mgr.h
@@ -45,12 +45,11 @@ struct ipsec_sa_mgr_t {
 	 * @param src			source address of the SA
 	 * @param dst			destination address of the SA
 	 * @param protocol		protocol of the SA (only ESP supported)
-	 * @param reqid			reqid for the SA
 	 * @param spi			the allocated SPI
 	 * @return				SUCCESS of operation successful
 	 */
 	status_t (*get_spi)(ipsec_sa_mgr_t *this, host_t *src, host_t *dst,
-						u_int8_t protocol, u_int32_t reqid, u_int32_t *spi);
+						u_int8_t protocol, u_int32_t *spi);
 
 	/**
 	 * Add a new SA
@@ -74,8 +73,7 @@ struct ipsec_sa_mgr_t {
 	 * @param encap			enable UDP encapsulation (must be TRUE)
 	 * @param esn			Extended Sequence Numbers (currently not supported)
 	 * @param inbound		TRUE if this is an inbound SA, FALSE otherwise
-	 * @param src_ts		source traffic selector
-	 * @param dst_ts		destination traffic selector
+	 * @param update		TRUE if an SPI has already been allocated for SA
 	 * @return				SUCCESS if operation completed
 	 */
 	status_t (*add_sa)(ipsec_sa_mgr_t *this, host_t *src, host_t *dst,
@@ -84,8 +82,7 @@ struct ipsec_sa_mgr_t {
 					   u_int16_t enc_alg, chunk_t enc_key, u_int16_t int_alg,
 					   chunk_t int_key, ipsec_mode_t mode, u_int16_t ipcomp,
 					   u_int16_t cpi, bool initiator, bool encap, bool esn,
-					   bool inbound, traffic_selector_t *src_ts,
-					   traffic_selector_t *dst_ts);
+					   bool inbound, bool update);
 
 	/**
 	 * Update the hosts on an installed SA.
diff --git a/src/libpttls/Makefile.in b/src/libpttls/Makefile.in
index 74cd808..96d1ae4 100644
--- a/src/libpttls/Makefile.in
+++ b/src/libpttls/Makefile.in
@@ -227,6 +227,7 @@ DLLIB = @DLLIB@
 DLLTOOL = @DLLTOOL@
 DSYMUTIL = @DSYMUTIL@
 DUMPBIN = @DUMPBIN@
+EASY_INSTALL = @EASY_INSTALL@
 ECHO_C = @ECHO_C@
 ECHO_N = @ECHO_N@
 ECHO_T = @ECHO_T@
@@ -287,10 +288,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
 PLUGIN_CFLAGS = @PLUGIN_CFLAGS@
 PTHREADLIB = @PTHREADLIB@
 PYTHON = @PYTHON@
+PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@
 PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
 PYTHON_PLATFORM = @PYTHON_PLATFORM@
 PYTHON_PREFIX = @PYTHON_PREFIX@
 PYTHON_VERSION = @PYTHON_VERSION@
+PY_TEST = @PY_TEST@
 RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
@@ -364,6 +367,8 @@ json_CFLAGS = @json_CFLAGS@
 json_LIBS = @json_LIBS@
 libdir = @libdir@
 libexecdir = @libexecdir@
+libiptc_CFLAGS = @libiptc_CFLAGS@
+libiptc_LIBS = @libiptc_LIBS@
 linux_headers = @linux_headers@
 localedir = @localedir@
 localstatedir = @localstatedir@
diff --git a/src/libradius/Makefile.in b/src/libradius/Makefile.in
index faaae70..5dd8ac5 100644
--- a/src/libradius/Makefile.in
+++ b/src/libradius/Makefile.in
@@ -222,6 +222,7 @@ DLLIB = @DLLIB@
 DLLTOOL = @DLLTOOL@
 DSYMUTIL = @DSYMUTIL@
 DUMPBIN = @DUMPBIN@
+EASY_INSTALL = @EASY_INSTALL@
 ECHO_C = @ECHO_C@
 ECHO_N = @ECHO_N@
 ECHO_T = @ECHO_T@
@@ -282,10 +283,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
 PLUGIN_CFLAGS = @PLUGIN_CFLAGS@
 PTHREADLIB = @PTHREADLIB@
 PYTHON = @PYTHON@
+PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@
 PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
 PYTHON_PLATFORM = @PYTHON_PLATFORM@
 PYTHON_PREFIX = @PYTHON_PREFIX@
 PYTHON_VERSION = @PYTHON_VERSION@
+PY_TEST = @PY_TEST@
 RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
@@ -359,6 +362,8 @@ json_CFLAGS = @json_CFLAGS@
 json_LIBS = @json_LIBS@
 libdir = @libdir@
 libexecdir = @libexecdir@
+libiptc_CFLAGS = @libiptc_CFLAGS@
+libiptc_LIBS = @libiptc_LIBS@
 linux_headers = @linux_headers@
 localedir = @localedir@
 localstatedir = @localstatedir@
diff --git a/src/libradius/radius_socket.c b/src/libradius/radius_socket.c
index f432151..fe9cf3c 100644
--- a/src/libradius/radius_socket.c
+++ b/src/libradius/radius_socket.c
@@ -129,7 +129,7 @@ METHOD(radius_socket_t, request, radius_message_t*,
 	private_radius_socket_t *this, radius_message_t *request)
 {
 	chunk_t data;
-	int i, *fd;
+	int i, *fd, retransmit = 0;
 	u_int16_t port;
 	rng_t *rng = NULL;
 
@@ -166,64 +166,59 @@ METHOD(radius_socket_t, request, radius_message_t*,
 	for (i = 2; i <= 5; i++)
 	{
 		radius_message_t *response;
-		bool retransmit = FALSE;
-		struct timeval tv;
 		char buf[4096];
-		fd_set fds;
 		int res;
+		struct pollfd pfd = {
+			.fd = *fd,
+			.events = POLLIN,
+		};
 
+		if (retransmit)
+		{
+			DBG1(DBG_CFG, "retransmitting RADIUS %N (attempt %d)",
+				 radius_message_code_names, request->get_code(request),
+				 retransmit);
+		}
 		if (send(*fd, data.ptr, data.len, 0) != data.len)
 		{
 			DBG1(DBG_CFG, "sending RADIUS message failed: %s", strerror(errno));
 			return NULL;
 		}
-		tv.tv_sec = i;
-		tv.tv_usec = 0;
-
-		while (TRUE)
+		res = poll(&pfd, 1, i * 1000);
+		if (res < 0)
 		{
-			FD_ZERO(&fds);
-			FD_SET(*fd, &fds);
-			res = select((*fd) + 1, &fds, NULL, NULL, &tv);
-			/* TODO: updated tv to time not waited. Linux does this for us. */
-			if (res < 0)
-			{	/* failed */
-				DBG1(DBG_CFG, "waiting for RADIUS message failed: %s",
-					 strerror(errno));
-				break;
-			}
-			if (res == 0)
-			{	/* timeout */
-				DBG1(DBG_CFG, "retransmitting RADIUS message");
-				retransmit = TRUE;
-				break;
-			}
-			res = recv(*fd, buf, sizeof(buf), MSG_DONTWAIT);
-			if (res <= 0)
-			{
-				DBG1(DBG_CFG, "receiving RADIUS message failed: %s",
-					 strerror(errno));
-				break;
-			}
-			response = radius_message_parse(chunk_create(buf, res));
-			if (response)
-			{
-				if (response->verify(response,
-							request->get_authenticator(request), this->secret,
-							this->hasher, this->signer))
-				{
-					return response;
-				}
-				response->destroy(response);
-			}
-			DBG1(DBG_CFG, "received invalid RADIUS message, ignored");
+			DBG1(DBG_CFG, "waiting for RADIUS message failed: %s",
+				 strerror(errno));
+			return NULL;
+		}
+		if (res == 0)
+		{	/* timeout */
+			retransmit++;
+			continue;
 		}
-		if (!retransmit)
+		res = recv(*fd, buf, sizeof(buf), MSG_DONTWAIT);
+		if (res <= 0)
 		{
-			break;
+			DBG1(DBG_CFG, "receiving RADIUS message failed: %s",
+				 strerror(errno));
+			return NULL;
 		}
+		response = radius_message_parse(chunk_create(buf, res));
+		if (response)
+		{
+			if (response->verify(response,
+						request->get_authenticator(request), this->secret,
+						this->hasher, this->signer))
+			{
+				return response;
+			}
+			response->destroy(response);
+		}
+		DBG1(DBG_CFG, "received invalid RADIUS message, ignored");
+		return NULL;
 	}
-	DBG1(DBG_CFG, "RADIUS server is not responding");
+	DBG1(DBG_CFG, "RADIUS %N timed out after %d retransmits",
+		 radius_message_code_names, request->get_code(request), retransmit - 1);
 	return NULL;
 }
 
diff --git a/src/libsimaka/Makefile.in b/src/libsimaka/Makefile.in
index a169919..79962d3 100644
--- a/src/libsimaka/Makefile.in
+++ b/src/libsimaka/Makefile.in
@@ -222,6 +222,7 @@ DLLIB = @DLLIB@
 DLLTOOL = @DLLTOOL@
 DSYMUTIL = @DSYMUTIL@
 DUMPBIN = @DUMPBIN@
+EASY_INSTALL = @EASY_INSTALL@
 ECHO_C = @ECHO_C@
 ECHO_N = @ECHO_N@
 ECHO_T = @ECHO_T@
@@ -282,10 +283,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
 PLUGIN_CFLAGS = @PLUGIN_CFLAGS@
 PTHREADLIB = @PTHREADLIB@
 PYTHON = @PYTHON@
+PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@
 PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
 PYTHON_PLATFORM = @PYTHON_PLATFORM@
 PYTHON_PREFIX = @PYTHON_PREFIX@
 PYTHON_VERSION = @PYTHON_VERSION@
+PY_TEST = @PY_TEST@
 RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
@@ -359,6 +362,8 @@ json_CFLAGS = @json_CFLAGS@
 json_LIBS = @json_LIBS@
 libdir = @libdir@
 libexecdir = @libexecdir@
+libiptc_CFLAGS = @libiptc_CFLAGS@
+libiptc_LIBS = @libiptc_LIBS@
 linux_headers = @linux_headers@
 localedir = @localedir@
 localstatedir = @localstatedir@
diff --git a/src/libstrongswan/Android.mk b/src/libstrongswan/Android.mk
index 9b775f9..2a8894b 100644
--- a/src/libstrongswan/Android.mk
+++ b/src/libstrongswan/Android.mk
@@ -8,12 +8,14 @@ asn1/asn1.c asn1/asn1_parser.c asn1/oid.c bio/bio_reader.c bio/bio_writer.c \
 collections/blocking_queue.c collections/enumerator.c collections/hashtable.c \
 collections/array.c \
 collections/linked_list.c crypto/crypters/crypter.c crypto/hashers/hasher.c \
+crypto/hashers/hash_algorithm_set.c \
 crypto/proposal/proposal_keywords.c crypto/proposal/proposal_keywords_static.c \
 crypto/prfs/prf.c crypto/prfs/mac_prf.c crypto/pkcs5.c \
 crypto/rngs/rng.c crypto/prf_plus.c crypto/signers/signer.c \
 crypto/signers/mac_signer.c crypto/crypto_factory.c crypto/crypto_tester.c \
 crypto/diffie_hellman.c crypto/aead.c crypto/transform.c \
 crypto/iv/iv_gen_rand.c crypto/iv/iv_gen_seq.c \
+crypto/mgf1/mgf1.c crypto/mgf1/mgf1_bitspender.c \
 credentials/credential_factory.c credentials/builder.c \
 credentials/cred_encoding.c credentials/keys/private_key.c \
 credentials/keys/public_key.c credentials/keys/shared_key.c \
diff --git a/src/libstrongswan/Makefile.am b/src/libstrongswan/Makefile.am
index 0083ffe..fbc7526 100644
--- a/src/libstrongswan/Makefile.am
+++ b/src/libstrongswan/Makefile.am
@@ -6,12 +6,14 @@ asn1/asn1.c asn1/asn1_parser.c asn1/oid.c bio/bio_reader.c bio/bio_writer.c \
 collections/blocking_queue.c collections/enumerator.c collections/hashtable.c \
 collections/array.c \
 collections/linked_list.c crypto/crypters/crypter.c crypto/hashers/hasher.c \
+crypto/hashers/hash_algorithm_set.c \
 crypto/proposal/proposal_keywords.c crypto/proposal/proposal_keywords_static.c \
 crypto/prfs/prf.c crypto/prfs/mac_prf.c crypto/pkcs5.c \
 crypto/rngs/rng.c crypto/prf_plus.c crypto/signers/signer.c \
 crypto/signers/mac_signer.c crypto/crypto_factory.c crypto/crypto_tester.c \
 crypto/diffie_hellman.c crypto/aead.c crypto/transform.c \
 crypto/iv/iv_gen_rand.c crypto/iv/iv_gen_seq.c \
+crypto/mgf1/mgf1.c crypto/mgf1/mgf1_bitspender.c \
 credentials/credential_factory.c credentials/builder.c \
 credentials/cred_encoding.c credentials/keys/private_key.c \
 credentials/keys/public_key.c credentials/keys/shared_key.c \
@@ -60,13 +62,15 @@ library.h \
 asn1/asn1.h asn1/asn1_parser.h asn1/oid.h bio/bio_reader.h bio/bio_writer.h \
 collections/blocking_queue.h collections/enumerator.h collections/hashtable.h \
 collections/linked_list.h collections/array.h collections/dictionary.h \
-crypto/crypters/crypter.h crypto/hashers/hasher.h crypto/mac.h \
+crypto/crypters/crypter.h crypto/hashers/hasher.h \
+crypto/hashers/hash_algorithm_set.h crypto/mac.h \
 crypto/proposal/proposal_keywords.h crypto/proposal/proposal_keywords_static.h \
 crypto/prfs/prf.h crypto/prfs/mac_prf.h crypto/rngs/rng.h crypto/nonce_gen.h \
 crypto/prf_plus.h crypto/signers/signer.h crypto/signers/mac_signer.h \
 crypto/crypto_factory.h crypto/crypto_tester.h crypto/diffie_hellman.h \
 crypto/aead.h crypto/transform.h crypto/pkcs5.h crypto/iv/iv_gen.h \
 crypto/iv/iv_gen_rand.h crypto/iv/iv_gen_seq.h \
+crypto/mgf1/mgf1.h crypto/mgf1/mgf1_bitspender.h \
 credentials/credential_factory.h credentials/builder.h \
 credentials/cred_encoding.h credentials/keys/private_key.h \
 credentials/keys/public_key.h credentials/keys/shared_key.h \
@@ -101,8 +105,8 @@ utils/utils.h utils/chunk.h utils/debug.h utils/enum.h utils/identification.h \
 utils/lexparser.h utils/optionsfrom.h utils/capabilities.h utils/backtrace.h \
 utils/leak_detective.h utils/printf_hook/printf_hook.h \
 utils/printf_hook/printf_hook_vstr.h utils/printf_hook/printf_hook_builtin.h \
-utils/parser_helper.h utils/test.h utils/integrity_checker.h utils/windows.h \
-utils/process.h utils/utils/strerror.h
+utils/parser_helper.h utils/test.h utils/integrity_checker.h utils/process.h \
+utils/utils/strerror.h utils/compat/windows.h utils/compat/apple.h
 endif
 
 library.lo :	$(top_builddir)/config.status
@@ -133,7 +137,7 @@ if USE_WINDOWS
     threading/windows/rwlock.c \
     threading/windows/spinlock.c \
     threading/windows/semaphore.c \
-    utils/windows.c
+    utils/compat/windows.c
 else
   libstrongswan_la_LIBADD += $(PTHREADLIB)
 endif
@@ -425,6 +429,13 @@ if MONOLITHIC
 endif
 endif
 
+if USE_FILES
+  SUBDIRS += plugins/files
+if MONOLITHIC
+  libstrongswan_la_LIBADD += plugins/files/libstrongswan-files.la
+endif
+endif
+
 if USE_WINHTTP
   SUBDIRS += plugins/winhttp
 if MONOLITHIC
@@ -544,6 +555,13 @@ if MONOLITHIC
 endif
 endif
 
+if USE_BLISS
+  SUBDIRS += plugins/bliss
+if MONOLITHIC
+  libstrongswan_la_LIBADD += plugins/bliss/libstrongswan-bliss.la
+endif
+endif
+
 if USE_TEST_VECTORS
   SUBDIRS += plugins/test_vectors
 if MONOLITHIC
@@ -555,3 +573,6 @@ if MONOLITHIC
   SUBDIRS += .
 endif
 SUBDIRS += tests
+if USE_BLISS
+  SUBDIRS += plugins/bliss/tests
+endif
diff --git a/src/libstrongswan/Makefile.in b/src/libstrongswan/Makefile.in
index 40678cb..99b18a7 100644
--- a/src/libstrongswan/Makefile.in
+++ b/src/libstrongswan/Makefile.in
@@ -97,7 +97,7 @@ host_triplet = @host@
 @USE_WINDOWS_TRUE@    threading/windows/rwlock.c \
 @USE_WINDOWS_TRUE@    threading/windows/spinlock.c \
 @USE_WINDOWS_TRUE@    threading/windows/semaphore.c \
- at USE_WINDOWS_TRUE@    utils/windows.c
+ at USE_WINDOWS_TRUE@    utils/compat/windows.c
 
 @USE_WINDOWS_FALSE at am__append_4 = $(PTHREADLIB)
 @USE_DBGHELP_TRUE at am__append_5 = -ldbghelp
@@ -173,42 +173,47 @@ host_triplet = @host@
 @MONOLITHIC_TRUE@@USE_PEM_TRUE at am__append_75 = plugins/pem/libstrongswan-pem.la
 @USE_CURL_TRUE at am__append_76 = plugins/curl
 @MONOLITHIC_TRUE@@USE_CURL_TRUE at am__append_77 = plugins/curl/libstrongswan-curl.la
- at USE_WINHTTP_TRUE@am__append_78 = plugins/winhttp
- at MONOLITHIC_TRUE@@USE_WINHTTP_TRUE at am__append_79 = plugins/winhttp/libstrongswan-winhttp.la
- at USE_UNBOUND_TRUE@am__append_80 = plugins/unbound
- at MONOLITHIC_TRUE@@USE_UNBOUND_TRUE at am__append_81 = plugins/unbound/libstrongswan-unbound.la
- at USE_SOUP_TRUE@am__append_82 = plugins/soup
- at MONOLITHIC_TRUE@@USE_SOUP_TRUE at am__append_83 = plugins/soup/libstrongswan-soup.la
- at USE_LDAP_TRUE@am__append_84 = plugins/ldap
- at MONOLITHIC_TRUE@@USE_LDAP_TRUE at am__append_85 = plugins/ldap/libstrongswan-ldap.la
- at USE_MYSQL_TRUE@am__append_86 = plugins/mysql
- at MONOLITHIC_TRUE@@USE_MYSQL_TRUE at am__append_87 = plugins/mysql/libstrongswan-mysql.la
- at USE_SQLITE_TRUE@am__append_88 = plugins/sqlite
- at MONOLITHIC_TRUE@@USE_SQLITE_TRUE at am__append_89 = plugins/sqlite/libstrongswan-sqlite.la
- at USE_PADLOCK_TRUE@am__append_90 = plugins/padlock
- at MONOLITHIC_TRUE@@USE_PADLOCK_TRUE at am__append_91 = plugins/padlock/libstrongswan-padlock.la
- at USE_OPENSSL_TRUE@am__append_92 = plugins/openssl
- at MONOLITHIC_TRUE@@USE_OPENSSL_TRUE at am__append_93 = plugins/openssl/libstrongswan-openssl.la
- at USE_GCRYPT_TRUE@am__append_94 = plugins/gcrypt
- at MONOLITHIC_TRUE@@USE_GCRYPT_TRUE at am__append_95 = plugins/gcrypt/libstrongswan-gcrypt.la
- at USE_FIPS_PRF_TRUE@am__append_96 = plugins/fips_prf
- at MONOLITHIC_TRUE@@USE_FIPS_PRF_TRUE at am__append_97 = plugins/fips_prf/libstrongswan-fips-prf.la
- at USE_AGENT_TRUE@am__append_98 = plugins/agent
- at MONOLITHIC_TRUE@@USE_AGENT_TRUE at am__append_99 = plugins/agent/libstrongswan-agent.la
- at USE_KEYCHAIN_TRUE@am__append_100 = plugins/keychain
- at MONOLITHIC_TRUE@@USE_KEYCHAIN_TRUE at am__append_101 = plugins/keychain/libstrongswan-keychain.la
- at USE_PKCS11_TRUE@am__append_102 = plugins/pkcs11
- at MONOLITHIC_TRUE@@USE_PKCS11_TRUE at am__append_103 = plugins/pkcs11/libstrongswan-pkcs11.la
- at USE_CTR_TRUE@am__append_104 = plugins/ctr
- at MONOLITHIC_TRUE@@USE_CTR_TRUE at am__append_105 = plugins/ctr/libstrongswan-ctr.la
- at USE_CCM_TRUE@am__append_106 = plugins/ccm
- at MONOLITHIC_TRUE@@USE_CCM_TRUE at am__append_107 = plugins/ccm/libstrongswan-ccm.la
- at USE_GCM_TRUE@am__append_108 = plugins/gcm
- at MONOLITHIC_TRUE@@USE_GCM_TRUE at am__append_109 = plugins/gcm/libstrongswan-gcm.la
- at USE_NTRU_TRUE@am__append_110 = plugins/ntru
- at MONOLITHIC_TRUE@@USE_NTRU_TRUE at am__append_111 = plugins/ntru/libstrongswan-ntru.la
- at USE_TEST_VECTORS_TRUE@am__append_112 = plugins/test_vectors
- at MONOLITHIC_TRUE@@USE_TEST_VECTORS_TRUE at am__append_113 = plugins/test_vectors/libstrongswan-test-vectors.la
+ at USE_FILES_TRUE@am__append_78 = plugins/files
+ at MONOLITHIC_TRUE@@USE_FILES_TRUE at am__append_79 = plugins/files/libstrongswan-files.la
+ at USE_WINHTTP_TRUE@am__append_80 = plugins/winhttp
+ at MONOLITHIC_TRUE@@USE_WINHTTP_TRUE at am__append_81 = plugins/winhttp/libstrongswan-winhttp.la
+ at USE_UNBOUND_TRUE@am__append_82 = plugins/unbound
+ at MONOLITHIC_TRUE@@USE_UNBOUND_TRUE at am__append_83 = plugins/unbound/libstrongswan-unbound.la
+ at USE_SOUP_TRUE@am__append_84 = plugins/soup
+ at MONOLITHIC_TRUE@@USE_SOUP_TRUE at am__append_85 = plugins/soup/libstrongswan-soup.la
+ at USE_LDAP_TRUE@am__append_86 = plugins/ldap
+ at MONOLITHIC_TRUE@@USE_LDAP_TRUE at am__append_87 = plugins/ldap/libstrongswan-ldap.la
+ at USE_MYSQL_TRUE@am__append_88 = plugins/mysql
+ at MONOLITHIC_TRUE@@USE_MYSQL_TRUE at am__append_89 = plugins/mysql/libstrongswan-mysql.la
+ at USE_SQLITE_TRUE@am__append_90 = plugins/sqlite
+ at MONOLITHIC_TRUE@@USE_SQLITE_TRUE at am__append_91 = plugins/sqlite/libstrongswan-sqlite.la
+ at USE_PADLOCK_TRUE@am__append_92 = plugins/padlock
+ at MONOLITHIC_TRUE@@USE_PADLOCK_TRUE at am__append_93 = plugins/padlock/libstrongswan-padlock.la
+ at USE_OPENSSL_TRUE@am__append_94 = plugins/openssl
+ at MONOLITHIC_TRUE@@USE_OPENSSL_TRUE at am__append_95 = plugins/openssl/libstrongswan-openssl.la
+ at USE_GCRYPT_TRUE@am__append_96 = plugins/gcrypt
+ at MONOLITHIC_TRUE@@USE_GCRYPT_TRUE at am__append_97 = plugins/gcrypt/libstrongswan-gcrypt.la
+ at USE_FIPS_PRF_TRUE@am__append_98 = plugins/fips_prf
+ at MONOLITHIC_TRUE@@USE_FIPS_PRF_TRUE at am__append_99 = plugins/fips_prf/libstrongswan-fips-prf.la
+ at USE_AGENT_TRUE@am__append_100 = plugins/agent
+ at MONOLITHIC_TRUE@@USE_AGENT_TRUE at am__append_101 = plugins/agent/libstrongswan-agent.la
+ at USE_KEYCHAIN_TRUE@am__append_102 = plugins/keychain
+ at MONOLITHIC_TRUE@@USE_KEYCHAIN_TRUE at am__append_103 = plugins/keychain/libstrongswan-keychain.la
+ at USE_PKCS11_TRUE@am__append_104 = plugins/pkcs11
+ at MONOLITHIC_TRUE@@USE_PKCS11_TRUE at am__append_105 = plugins/pkcs11/libstrongswan-pkcs11.la
+ at USE_CTR_TRUE@am__append_106 = plugins/ctr
+ at MONOLITHIC_TRUE@@USE_CTR_TRUE at am__append_107 = plugins/ctr/libstrongswan-ctr.la
+ at USE_CCM_TRUE@am__append_108 = plugins/ccm
+ at MONOLITHIC_TRUE@@USE_CCM_TRUE at am__append_109 = plugins/ccm/libstrongswan-ccm.la
+ at USE_GCM_TRUE@am__append_110 = plugins/gcm
+ at MONOLITHIC_TRUE@@USE_GCM_TRUE at am__append_111 = plugins/gcm/libstrongswan-gcm.la
+ at USE_NTRU_TRUE@am__append_112 = plugins/ntru
+ at MONOLITHIC_TRUE@@USE_NTRU_TRUE at am__append_113 = plugins/ntru/libstrongswan-ntru.la
+ at USE_BLISS_TRUE@am__append_114 = plugins/bliss
+ at MONOLITHIC_TRUE@@USE_BLISS_TRUE at am__append_115 = plugins/bliss/libstrongswan-bliss.la
+ at USE_TEST_VECTORS_TRUE@am__append_116 = plugins/test_vectors
+ at MONOLITHIC_TRUE@@USE_TEST_VECTORS_TRUE at am__append_117 = plugins/test_vectors/libstrongswan-test-vectors.la
+ at USE_BLISS_TRUE@am__append_118 = plugins/bliss/tests
 subdir = src/libstrongswan
 DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
 	settings/settings_parser.h settings/settings_parser.c \
@@ -287,13 +292,14 @@ libstrongswan_la_DEPENDENCIES = $(am__DEPENDENCIES_1) \
 	$(am__append_95) $(am__append_97) $(am__append_99) \
 	$(am__append_101) $(am__append_103) $(am__append_105) \
 	$(am__append_107) $(am__append_109) $(am__append_111) \
-	$(am__append_113)
+	$(am__append_113) $(am__append_115) $(am__append_117)
 am__libstrongswan_la_SOURCES_DIST = library.c asn1/asn1.c \
 	asn1/asn1_parser.c asn1/oid.c bio/bio_reader.c \
 	bio/bio_writer.c collections/blocking_queue.c \
 	collections/enumerator.c collections/hashtable.c \
 	collections/array.c collections/linked_list.c \
 	crypto/crypters/crypter.c crypto/hashers/hasher.c \
+	crypto/hashers/hash_algorithm_set.c \
 	crypto/proposal/proposal_keywords.c \
 	crypto/proposal/proposal_keywords_static.c crypto/prfs/prf.c \
 	crypto/prfs/mac_prf.c crypto/pkcs5.c crypto/rngs/rng.c \
@@ -301,7 +307,8 @@ am__libstrongswan_la_SOURCES_DIST = library.c asn1/asn1.c \
 	crypto/signers/mac_signer.c crypto/crypto_factory.c \
 	crypto/crypto_tester.c crypto/diffie_hellman.c crypto/aead.c \
 	crypto/transform.c crypto/iv/iv_gen_rand.c \
-	crypto/iv/iv_gen_seq.c credentials/credential_factory.c \
+	crypto/iv/iv_gen_seq.c crypto/mgf1/mgf1.c \
+	crypto/mgf1/mgf1_bitspender.c credentials/credential_factory.c \
 	credentials/builder.c credentials/cred_encoding.c \
 	credentials/keys/private_key.c credentials/keys/public_key.c \
 	credentials/keys/shared_key.c \
@@ -342,7 +349,7 @@ am__libstrongswan_la_SOURCES_DIST = library.c asn1/asn1.c \
 	threading/windows/thread.c threading/windows/thread_value.c \
 	threading/windows/mutex.c threading/windows/rwlock.c \
 	threading/windows/spinlock.c threading/windows/semaphore.c \
-	utils/windows.c utils/leak_detective.c \
+	utils/compat/windows.c utils/leak_detective.c \
 	utils/integrity_checker.c utils/printf_hook/printf_hook_vstr.c \
 	utils/printf_hook/printf_hook_builtin.c \
 	utils/printf_hook/printf_hook_glibc.c
@@ -360,7 +367,7 @@ am__dirstamp = $(am__leading_dot)dirstamp
 @USE_WINDOWS_TRUE@	threading/windows/rwlock.lo \
 @USE_WINDOWS_TRUE@	threading/windows/spinlock.lo \
 @USE_WINDOWS_TRUE@	threading/windows/semaphore.lo \
- at USE_WINDOWS_TRUE@	utils/windows.lo
+ at USE_WINDOWS_TRUE@	utils/compat/windows.lo
 @USE_LEAK_DETECTIVE_TRUE at am__objects_3 = utils/leak_detective.lo
 @USE_INTEGRITY_TEST_TRUE at am__objects_4 = utils/integrity_checker.lo
 @USE_VSTR_TRUE at am__objects_5 = utils/printf_hook/printf_hook_vstr.lo
@@ -372,6 +379,7 @@ am_libstrongswan_la_OBJECTS = library.lo asn1/asn1.lo \
 	collections/enumerator.lo collections/hashtable.lo \
 	collections/array.lo collections/linked_list.lo \
 	crypto/crypters/crypter.lo crypto/hashers/hasher.lo \
+	crypto/hashers/hash_algorithm_set.lo \
 	crypto/proposal/proposal_keywords.lo \
 	crypto/proposal/proposal_keywords_static.lo crypto/prfs/prf.lo \
 	crypto/prfs/mac_prf.lo crypto/pkcs5.lo crypto/rngs/rng.lo \
@@ -379,10 +387,11 @@ am_libstrongswan_la_OBJECTS = library.lo asn1/asn1.lo \
 	crypto/signers/mac_signer.lo crypto/crypto_factory.lo \
 	crypto/crypto_tester.lo crypto/diffie_hellman.lo \
 	crypto/aead.lo crypto/transform.lo crypto/iv/iv_gen_rand.lo \
-	crypto/iv/iv_gen_seq.lo credentials/credential_factory.lo \
-	credentials/builder.lo credentials/cred_encoding.lo \
-	credentials/keys/private_key.lo credentials/keys/public_key.lo \
-	credentials/keys/shared_key.lo \
+	crypto/iv/iv_gen_seq.lo crypto/mgf1/mgf1.lo \
+	crypto/mgf1/mgf1_bitspender.lo \
+	credentials/credential_factory.lo credentials/builder.lo \
+	credentials/cred_encoding.lo credentials/keys/private_key.lo \
+	credentials/keys/public_key.lo credentials/keys/shared_key.lo \
 	credentials/certificates/certificate.lo \
 	credentials/certificates/crl.lo \
 	credentials/certificates/ocsp_response.lo \
@@ -493,8 +502,8 @@ am__nobase_strongswan_include_HEADERS_DIST = library.h asn1/asn1.h \
 	collections/enumerator.h collections/hashtable.h \
 	collections/linked_list.h collections/array.h \
 	collections/dictionary.h crypto/crypters/crypter.h \
-	crypto/hashers/hasher.h crypto/mac.h \
-	crypto/proposal/proposal_keywords.h \
+	crypto/hashers/hasher.h crypto/hashers/hash_algorithm_set.h \
+	crypto/mac.h crypto/proposal/proposal_keywords.h \
 	crypto/proposal/proposal_keywords_static.h crypto/prfs/prf.h \
 	crypto/prfs/mac_prf.h crypto/rngs/rng.h crypto/nonce_gen.h \
 	crypto/prf_plus.h crypto/signers/signer.h \
@@ -502,6 +511,7 @@ am__nobase_strongswan_include_HEADERS_DIST = library.h asn1/asn1.h \
 	crypto/crypto_tester.h crypto/diffie_hellman.h crypto/aead.h \
 	crypto/transform.h crypto/pkcs5.h crypto/iv/iv_gen.h \
 	crypto/iv/iv_gen_rand.h crypto/iv/iv_gen_seq.h \
+	crypto/mgf1/mgf1.h crypto/mgf1/mgf1_bitspender.h \
 	credentials/credential_factory.h credentials/builder.h \
 	credentials/cred_encoding.h credentials/keys/private_key.h \
 	credentials/keys/public_key.h credentials/keys/shared_key.h \
@@ -548,8 +558,9 @@ am__nobase_strongswan_include_HEADERS_DIST = library.h asn1/asn1.h \
 	utils/printf_hook/printf_hook.h \
 	utils/printf_hook/printf_hook_vstr.h \
 	utils/printf_hook/printf_hook_builtin.h utils/parser_helper.h \
-	utils/test.h utils/integrity_checker.h utils/windows.h \
-	utils/process.h utils/utils/strerror.h
+	utils/test.h utils/integrity_checker.h utils/process.h \
+	utils/utils/strerror.h utils/compat/windows.h \
+	utils/compat/apple.h
 HEADERS = $(nobase_strongswan_include_HEADERS) $(noinst_HEADERS)
 RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive	\
   distclean-recursive maintainer-clean-recursive
@@ -586,11 +597,12 @@ DIST_SUBDIRS = . plugins/af_alg plugins/aes plugins/des \
 	plugins/constraints plugins/acert plugins/pubkey plugins/pkcs1 \
 	plugins/pkcs7 plugins/pkcs8 plugins/pkcs12 plugins/pgp \
 	plugins/dnskey plugins/sshkey plugins/pem plugins/curl \
-	plugins/winhttp plugins/unbound plugins/soup plugins/ldap \
-	plugins/mysql plugins/sqlite plugins/padlock plugins/openssl \
-	plugins/gcrypt plugins/fips_prf plugins/agent plugins/keychain \
-	plugins/pkcs11 plugins/ctr plugins/ccm plugins/gcm \
-	plugins/ntru plugins/test_vectors tests
+	plugins/files plugins/winhttp plugins/unbound plugins/soup \
+	plugins/ldap plugins/mysql plugins/sqlite plugins/padlock \
+	plugins/openssl plugins/gcrypt plugins/fips_prf plugins/agent \
+	plugins/keychain plugins/pkcs11 plugins/ctr plugins/ccm \
+	plugins/gcm plugins/ntru plugins/bliss plugins/test_vectors \
+	tests plugins/bliss/tests
 DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
 am__relativize = \
   dir0=`pwd`; \
@@ -642,6 +654,7 @@ DLLIB = @DLLIB@
 DLLTOOL = @DLLTOOL@
 DSYMUTIL = @DSYMUTIL@
 DUMPBIN = @DUMPBIN@
+EASY_INSTALL = @EASY_INSTALL@
 ECHO_C = @ECHO_C@
 ECHO_N = @ECHO_N@
 ECHO_T = @ECHO_T@
@@ -702,10 +715,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
 PLUGIN_CFLAGS = @PLUGIN_CFLAGS@
 PTHREADLIB = @PTHREADLIB@
 PYTHON = @PYTHON@
+PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@
 PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
 PYTHON_PLATFORM = @PYTHON_PLATFORM@
 PYTHON_PREFIX = @PYTHON_PREFIX@
 PYTHON_VERSION = @PYTHON_VERSION@
+PY_TEST = @PY_TEST@
 RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
@@ -779,6 +794,8 @@ json_CFLAGS = @json_CFLAGS@
 json_LIBS = @json_LIBS@
 libdir = @libdir@
 libexecdir = @libexecdir@
+libiptc_CFLAGS = @libiptc_CFLAGS@
+libiptc_LIBS = @libiptc_LIBS@
 linux_headers = @linux_headers@
 localedir = @localedir@
 localstatedir = @localstatedir@
@@ -843,14 +860,16 @@ libstrongswan_la_SOURCES = library.c asn1/asn1.c asn1/asn1_parser.c \
 	collections/blocking_queue.c collections/enumerator.c \
 	collections/hashtable.c collections/array.c \
 	collections/linked_list.c crypto/crypters/crypter.c \
-	crypto/hashers/hasher.c crypto/proposal/proposal_keywords.c \
+	crypto/hashers/hasher.c crypto/hashers/hash_algorithm_set.c \
+	crypto/proposal/proposal_keywords.c \
 	crypto/proposal/proposal_keywords_static.c crypto/prfs/prf.c \
 	crypto/prfs/mac_prf.c crypto/pkcs5.c crypto/rngs/rng.c \
 	crypto/prf_plus.c crypto/signers/signer.c \
 	crypto/signers/mac_signer.c crypto/crypto_factory.c \
 	crypto/crypto_tester.c crypto/diffie_hellman.c crypto/aead.c \
 	crypto/transform.c crypto/iv/iv_gen_rand.c \
-	crypto/iv/iv_gen_seq.c credentials/credential_factory.c \
+	crypto/iv/iv_gen_seq.c crypto/mgf1/mgf1.c \
+	crypto/mgf1/mgf1_bitspender.c credentials/credential_factory.c \
 	credentials/builder.c credentials/cred_encoding.c \
 	credentials/keys/private_key.c credentials/keys/public_key.c \
 	credentials/keys/shared_key.c \
@@ -898,13 +917,15 @@ settings/settings_types.h
 @USE_DEV_HEADERS_TRUE at asn1/asn1.h asn1/asn1_parser.h asn1/oid.h bio/bio_reader.h bio/bio_writer.h \
 @USE_DEV_HEADERS_TRUE at collections/blocking_queue.h collections/enumerator.h collections/hashtable.h \
 @USE_DEV_HEADERS_TRUE at collections/linked_list.h collections/array.h collections/dictionary.h \
- at USE_DEV_HEADERS_TRUE@crypto/crypters/crypter.h crypto/hashers/hasher.h crypto/mac.h \
+ at USE_DEV_HEADERS_TRUE@crypto/crypters/crypter.h crypto/hashers/hasher.h \
+ at USE_DEV_HEADERS_TRUE@crypto/hashers/hash_algorithm_set.h crypto/mac.h \
 @USE_DEV_HEADERS_TRUE at crypto/proposal/proposal_keywords.h crypto/proposal/proposal_keywords_static.h \
 @USE_DEV_HEADERS_TRUE at crypto/prfs/prf.h crypto/prfs/mac_prf.h crypto/rngs/rng.h crypto/nonce_gen.h \
 @USE_DEV_HEADERS_TRUE at crypto/prf_plus.h crypto/signers/signer.h crypto/signers/mac_signer.h \
 @USE_DEV_HEADERS_TRUE at crypto/crypto_factory.h crypto/crypto_tester.h crypto/diffie_hellman.h \
 @USE_DEV_HEADERS_TRUE at crypto/aead.h crypto/transform.h crypto/pkcs5.h crypto/iv/iv_gen.h \
 @USE_DEV_HEADERS_TRUE at crypto/iv/iv_gen_rand.h crypto/iv/iv_gen_seq.h \
+ at USE_DEV_HEADERS_TRUE@crypto/mgf1/mgf1.h crypto/mgf1/mgf1_bitspender.h \
 @USE_DEV_HEADERS_TRUE at credentials/credential_factory.h credentials/builder.h \
 @USE_DEV_HEADERS_TRUE at credentials/cred_encoding.h credentials/keys/private_key.h \
 @USE_DEV_HEADERS_TRUE at credentials/keys/public_key.h credentials/keys/shared_key.h \
@@ -939,8 +960,8 @@ settings/settings_types.h
 @USE_DEV_HEADERS_TRUE at utils/lexparser.h utils/optionsfrom.h utils/capabilities.h utils/backtrace.h \
 @USE_DEV_HEADERS_TRUE at utils/leak_detective.h utils/printf_hook/printf_hook.h \
 @USE_DEV_HEADERS_TRUE at utils/printf_hook/printf_hook_vstr.h utils/printf_hook/printf_hook_builtin.h \
- at USE_DEV_HEADERS_TRUE@utils/parser_helper.h utils/test.h utils/integrity_checker.h utils/windows.h \
- at USE_DEV_HEADERS_TRUE@utils/process.h utils/utils/strerror.h
+ at USE_DEV_HEADERS_TRUE@utils/parser_helper.h utils/test.h utils/integrity_checker.h utils/process.h \
+ at USE_DEV_HEADERS_TRUE@utils/utils/strerror.h utils/compat/windows.h utils/compat/apple.h
 
 libstrongswan_la_LIBADD = $(DLLIB) $(BTLIB) $(SOCKLIB) $(RTLIB) \
 	$(BFDLIB) $(UNWINDLIB) $(am__append_2) $(am__append_4) \
@@ -961,7 +982,7 @@ libstrongswan_la_LIBADD = $(DLLIB) $(BTLIB) $(SOCKLIB) $(RTLIB) \
 	$(am__append_95) $(am__append_97) $(am__append_99) \
 	$(am__append_101) $(am__append_103) $(am__append_105) \
 	$(am__append_107) $(am__append_109) $(am__append_111) \
-	$(am__append_113)
+	$(am__append_113) $(am__append_115) $(am__append_117)
 AM_CPPFLAGS = -I$(top_srcdir)/src/libstrongswan \
 	-DIPSEC_DIR=\"${ipsecdir}\" -DIPSEC_LIB_DIR=\"${ipseclibdir}\" \
 	-DPLUGINDIR=\"${plugindir}\" \
@@ -1011,7 +1032,9 @@ $(srcdir)/crypto/proposal/proposal_keywords_static.c
 @MONOLITHIC_FALSE@	$(am__append_98) $(am__append_100) \
 @MONOLITHIC_FALSE@	$(am__append_102) $(am__append_104) \
 @MONOLITHIC_FALSE@	$(am__append_106) $(am__append_108) \
- at MONOLITHIC_FALSE@	$(am__append_110) $(am__append_112) tests
+ at MONOLITHIC_FALSE@	$(am__append_110) $(am__append_112) \
+ at MONOLITHIC_FALSE@	$(am__append_114) $(am__append_116) tests \
+ at MONOLITHIC_FALSE@	$(am__append_118)
 
 # build plugins with their own Makefile
 #######################################
@@ -1038,7 +1061,9 @@ $(srcdir)/crypto/proposal/proposal_keywords_static.c
 @MONOLITHIC_TRUE@	$(am__append_98) $(am__append_100) \
 @MONOLITHIC_TRUE@	$(am__append_102) $(am__append_104) \
 @MONOLITHIC_TRUE@	$(am__append_106) $(am__append_108) \
- at MONOLITHIC_TRUE@	$(am__append_110) $(am__append_112) . tests
+ at MONOLITHIC_TRUE@	$(am__append_110) $(am__append_112) \
+ at MONOLITHIC_TRUE@	$(am__append_114) $(am__append_116) . tests \
+ at MONOLITHIC_TRUE@	$(am__append_118)
 all: $(BUILT_SOURCES)
 	$(MAKE) $(AM_MAKEFLAGS) all-recursive
 
@@ -1159,6 +1184,8 @@ crypto/hashers/$(DEPDIR)/$(am__dirstamp):
 	@: > crypto/hashers/$(DEPDIR)/$(am__dirstamp)
 crypto/hashers/hasher.lo: crypto/hashers/$(am__dirstamp) \
 	crypto/hashers/$(DEPDIR)/$(am__dirstamp)
+crypto/hashers/hash_algorithm_set.lo: crypto/hashers/$(am__dirstamp) \
+	crypto/hashers/$(DEPDIR)/$(am__dirstamp)
 crypto/proposal/$(am__dirstamp):
 	@$(MKDIR_P) crypto/proposal
 	@: > crypto/proposal/$(am__dirstamp)
@@ -1228,6 +1255,16 @@ crypto/iv/iv_gen_rand.lo: crypto/iv/$(am__dirstamp) \
 	crypto/iv/$(DEPDIR)/$(am__dirstamp)
 crypto/iv/iv_gen_seq.lo: crypto/iv/$(am__dirstamp) \
 	crypto/iv/$(DEPDIR)/$(am__dirstamp)
+crypto/mgf1/$(am__dirstamp):
+	@$(MKDIR_P) crypto/mgf1
+	@: > crypto/mgf1/$(am__dirstamp)
+crypto/mgf1/$(DEPDIR)/$(am__dirstamp):
+	@$(MKDIR_P) crypto/mgf1/$(DEPDIR)
+	@: > crypto/mgf1/$(DEPDIR)/$(am__dirstamp)
+crypto/mgf1/mgf1.lo: crypto/mgf1/$(am__dirstamp) \
+	crypto/mgf1/$(DEPDIR)/$(am__dirstamp)
+crypto/mgf1/mgf1_bitspender.lo: crypto/mgf1/$(am__dirstamp) \
+	crypto/mgf1/$(DEPDIR)/$(am__dirstamp)
 credentials/$(am__dirstamp):
 	@$(MKDIR_P) credentials
 	@: > credentials/$(am__dirstamp)
@@ -1517,8 +1554,14 @@ threading/windows/spinlock.lo: threading/windows/$(am__dirstamp) \
 	threading/windows/$(DEPDIR)/$(am__dirstamp)
 threading/windows/semaphore.lo: threading/windows/$(am__dirstamp) \
 	threading/windows/$(DEPDIR)/$(am__dirstamp)
-utils/windows.lo: utils/$(am__dirstamp) \
-	utils/$(DEPDIR)/$(am__dirstamp)
+utils/compat/$(am__dirstamp):
+	@$(MKDIR_P) utils/compat
+	@: > utils/compat/$(am__dirstamp)
+utils/compat/$(DEPDIR)/$(am__dirstamp):
+	@$(MKDIR_P) utils/compat/$(DEPDIR)
+	@: > utils/compat/$(DEPDIR)/$(am__dirstamp)
+utils/compat/windows.lo: utils/compat/$(am__dirstamp) \
+	utils/compat/$(DEPDIR)/$(am__dirstamp)
 utils/leak_detective.lo: utils/$(am__dirstamp) \
 	utils/$(DEPDIR)/$(am__dirstamp)
 utils/integrity_checker.lo: utils/$(am__dirstamp) \
@@ -1568,6 +1611,8 @@ mostlyclean-compile:
 	-rm -f crypto/hashers/*.lo
 	-rm -f crypto/iv/*.$(OBJEXT)
 	-rm -f crypto/iv/*.lo
+	-rm -f crypto/mgf1/*.$(OBJEXT)
+	-rm -f crypto/mgf1/*.lo
 	-rm -f crypto/prfs/*.$(OBJEXT)
 	-rm -f crypto/prfs/*.lo
 	-rm -f crypto/proposal/*.$(OBJEXT)
@@ -1608,6 +1653,8 @@ mostlyclean-compile:
 	-rm -f threading/windows/*.lo
 	-rm -f utils/*.$(OBJEXT)
 	-rm -f utils/*.lo
+	-rm -f utils/compat/*.$(OBJEXT)
+	-rm -f utils/compat/*.lo
 	-rm -f utils/printf_hook/*.$(OBJEXT)
 	-rm -f utils/printf_hook/*.lo
 	-rm -f utils/utils/*.$(OBJEXT)
@@ -1653,9 +1700,12 @@ distclean-compile:
 @AMDEP_TRUE@@am__include@ @am__quote at crypto/$(DEPDIR)/prf_plus.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at crypto/$(DEPDIR)/transform.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at crypto/crypters/$(DEPDIR)/crypter.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at crypto/hashers/$(DEPDIR)/hash_algorithm_set.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at crypto/hashers/$(DEPDIR)/hasher.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at crypto/iv/$(DEPDIR)/iv_gen_rand.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at crypto/iv/$(DEPDIR)/iv_gen_seq.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at crypto/mgf1/$(DEPDIR)/mgf1.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at crypto/mgf1/$(DEPDIR)/mgf1_bitspender.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at crypto/prfs/$(DEPDIR)/mac_prf.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at crypto/prfs/$(DEPDIR)/prf.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at crypto/proposal/$(DEPDIR)/proposal_keywords.Plo at am__quote@
@@ -1721,7 +1771,7 @@ distclean-compile:
 @AMDEP_TRUE@@am__include@ @am__quote at utils/$(DEPDIR)/process.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at utils/$(DEPDIR)/test.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at utils/$(DEPDIR)/utils.Plo at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at utils/$(DEPDIR)/windows.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at utils/compat/$(DEPDIR)/windows.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at utils/printf_hook/$(DEPDIR)/printf_hook_builtin.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at utils/printf_hook/$(DEPDIR)/printf_hook_glibc.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at utils/printf_hook/$(DEPDIR)/printf_hook_vstr.Plo at am__quote@
@@ -1774,6 +1824,7 @@ clean-libtool:
 	-rm -rf crypto/crypters/.libs crypto/crypters/_libs
 	-rm -rf crypto/hashers/.libs crypto/hashers/_libs
 	-rm -rf crypto/iv/.libs crypto/iv/_libs
+	-rm -rf crypto/mgf1/.libs crypto/mgf1/_libs
 	-rm -rf crypto/prfs/.libs crypto/prfs/_libs
 	-rm -rf crypto/proposal/.libs crypto/proposal/_libs
 	-rm -rf crypto/rngs/.libs crypto/rngs/_libs
@@ -1794,6 +1845,7 @@ clean-libtool:
 	-rm -rf threading/.libs threading/_libs
 	-rm -rf threading/windows/.libs threading/windows/_libs
 	-rm -rf utils/.libs utils/_libs
+	-rm -rf utils/compat/.libs utils/compat/_libs
 	-rm -rf utils/printf_hook/.libs utils/printf_hook/_libs
 	-rm -rf utils/utils/.libs utils/utils/_libs
 install-nobase_strongswan_includeHEADERS: $(nobase_strongswan_include_HEADERS)
@@ -2035,6 +2087,8 @@ distclean-generic:
 	-rm -f crypto/hashers/$(am__dirstamp)
 	-rm -f crypto/iv/$(DEPDIR)/$(am__dirstamp)
 	-rm -f crypto/iv/$(am__dirstamp)
+	-rm -f crypto/mgf1/$(DEPDIR)/$(am__dirstamp)
+	-rm -f crypto/mgf1/$(am__dirstamp)
 	-rm -f crypto/prfs/$(DEPDIR)/$(am__dirstamp)
 	-rm -f crypto/prfs/$(am__dirstamp)
 	-rm -f crypto/proposal/$(DEPDIR)/$(am__dirstamp)
@@ -2075,6 +2129,8 @@ distclean-generic:
 	-rm -f threading/windows/$(am__dirstamp)
 	-rm -f utils/$(DEPDIR)/$(am__dirstamp)
 	-rm -f utils/$(am__dirstamp)
+	-rm -f utils/compat/$(DEPDIR)/$(am__dirstamp)
+	-rm -f utils/compat/$(am__dirstamp)
 	-rm -f utils/printf_hook/$(DEPDIR)/$(am__dirstamp)
 	-rm -f utils/printf_hook/$(am__dirstamp)
 	-rm -f utils/utils/$(DEPDIR)/$(am__dirstamp)
@@ -2094,7 +2150,7 @@ clean-am: clean-generic clean-ipseclibLTLIBRARIES clean-libtool \
 	mostlyclean-am
 
 distclean: distclean-recursive
-	-rm -rf ./$(DEPDIR) asn1/$(DEPDIR) bio/$(DEPDIR) collections/$(DEPDIR) credentials/$(DEPDIR) credentials/certificates/$(DEPDIR) credentials/containers/$(DEPDIR) credentials/keys/$(DEPDIR) credentials/sets/$(DEPDIR) crypto/$(DEPDIR) crypto/crypters/$(DEPDIR) crypto/hashers/$(DEPDIR) crypto/iv/$(DEPDIR) crypto/prfs/$(DEPDIR) crypto/proposal/$(DEPDIR) crypto/rngs/$(DEPDIR) crypto/signers/$(DEPDIR) database/$(DEPDIR) eap/$(DEPDIR) fetcher/$(DEPDIR) ipsec/$(DEPDIR) networking/$(DEPDIR) netwo [...]
+	-rm -rf ./$(DEPDIR) asn1/$(DEPDIR) bio/$(DEPDIR) collections/$(DEPDIR) credentials/$(DEPDIR) credentials/certificates/$(DEPDIR) credentials/containers/$(DEPDIR) credentials/keys/$(DEPDIR) credentials/sets/$(DEPDIR) crypto/$(DEPDIR) crypto/crypters/$(DEPDIR) crypto/hashers/$(DEPDIR) crypto/iv/$(DEPDIR) crypto/mgf1/$(DEPDIR) crypto/prfs/$(DEPDIR) crypto/proposal/$(DEPDIR) crypto/rngs/$(DEPDIR) crypto/signers/$(DEPDIR) database/$(DEPDIR) eap/$(DEPDIR) fetcher/$(DEPDIR) ipsec/$(DEPDIR) netw [...]
 	-rm -f Makefile
 distclean-am: clean-am distclean-compile distclean-generic \
 	distclean-tags
@@ -2141,7 +2197,7 @@ install-ps-am:
 installcheck-am:
 
 maintainer-clean: maintainer-clean-recursive
-	-rm -rf ./$(DEPDIR) asn1/$(DEPDIR) bio/$(DEPDIR) collections/$(DEPDIR) credentials/$(DEPDIR) credentials/certificates/$(DEPDIR) credentials/containers/$(DEPDIR) credentials/keys/$(DEPDIR) credentials/sets/$(DEPDIR) crypto/$(DEPDIR) crypto/crypters/$(DEPDIR) crypto/hashers/$(DEPDIR) crypto/iv/$(DEPDIR) crypto/prfs/$(DEPDIR) crypto/proposal/$(DEPDIR) crypto/rngs/$(DEPDIR) crypto/signers/$(DEPDIR) database/$(DEPDIR) eap/$(DEPDIR) fetcher/$(DEPDIR) ipsec/$(DEPDIR) networking/$(DEPDIR) netwo [...]
+	-rm -rf ./$(DEPDIR) asn1/$(DEPDIR) bio/$(DEPDIR) collections/$(DEPDIR) credentials/$(DEPDIR) credentials/certificates/$(DEPDIR) credentials/containers/$(DEPDIR) credentials/keys/$(DEPDIR) credentials/sets/$(DEPDIR) crypto/$(DEPDIR) crypto/crypters/$(DEPDIR) crypto/hashers/$(DEPDIR) crypto/iv/$(DEPDIR) crypto/mgf1/$(DEPDIR) crypto/prfs/$(DEPDIR) crypto/proposal/$(DEPDIR) crypto/rngs/$(DEPDIR) crypto/signers/$(DEPDIR) database/$(DEPDIR) eap/$(DEPDIR) fetcher/$(DEPDIR) ipsec/$(DEPDIR) netw [...]
 	-rm -f Makefile
 maintainer-clean-am: distclean-am maintainer-clean-generic
 
diff --git a/src/libstrongswan/asn1/oid.c b/src/libstrongswan/asn1/oid.c
index b479b0f..a750f7f 100644
--- a/src/libstrongswan/asn1/oid.c
+++ b/src/libstrongswan/asn1/oid.c
@@ -199,12 +199,12 @@ const oid_t oid_names[] = {
  {              0x02,         187, 0,  7, "ecdsa-with-SHA256"              }, /* 186 */
  {              0x03,         188, 0,  7, "ecdsa-with-SHA384"              }, /* 187 */
  {              0x04,           0, 0,  7, "ecdsa-with-SHA512"              }, /* 188 */
- {0x2B,                       391, 1,  0, ""                               }, /* 189 */
- {  0x06,                     305, 1,  1, "dod"                            }, /* 190 */
+ {0x2B,                       413, 1,  0, ""                               }, /* 189 */
+ {  0x06,                     327, 1,  1, "dod"                            }, /* 190 */
  {    0x01,                     0, 1,  2, "internet"                       }, /* 191 */
- {      0x04,                 256, 1,  3, "private"                        }, /* 192 */
+ {      0x04,                 278, 1,  3, "private"                        }, /* 192 */
  {        0x01,                 0, 1,  4, "enterprise"                     }, /* 193 */
- {          0x82,             210, 1,  5, ""                               }, /* 194 */
+ {          0x82,             228, 1,  5, ""                               }, /* 194 */
  {            0x37,           207, 1,  6, "Microsoft"                      }, /* 195 */
  {              0x0A,         200, 1,  7, ""                               }, /* 196 */
  {                0x03,         0, 1,  8, ""                               }, /* 197 */
@@ -219,248 +219,270 @@ const oid_t oid_names[] = {
  {                0x0A,         0, 0,  8, "msApplicationCertPolicies"      }, /* 206 */
  {            0xA0,             0, 1,  6, ""                               }, /* 207 */
  {              0x2A,           0, 1,  7, "ITA"                            }, /* 208 */
- {                0x01,         0, 0,  8, "strongSwan"                     }, /* 209 */
- {          0x89,             217, 1,  5, ""                               }, /* 210 */
- {            0x31,             0, 1,  6, ""                               }, /* 211 */
- {              0x01,           0, 1,  7, ""                               }, /* 212 */
- {                0x01,         0, 1,  8, ""                               }, /* 213 */
- {                  0x02,       0, 1,  9, ""                               }, /* 214 */
- {                    0x02,     0, 1, 10, ""                               }, /* 215 */
- {                      0x4B,   0, 0, 11, "TCGID"                          }, /* 216 */
- {          0xC1,               0, 1,  5, ""                               }, /* 217 */
- {            0x16,             0, 1,  6, "ntruCryptosystems"              }, /* 218 */
- {              0x01,           0, 1,  7, "eess"                           }, /* 219 */
- {                0x01,         0, 1,  8, "eess1"                          }, /* 220 */
- {                  0x01,     225, 1,  9, "eess1-algs"                     }, /* 221 */
- {                    0x01,   223, 0, 10, "ntru-EESS1v1-SVES"              }, /* 222 */
- {                    0x02,   224, 0, 10, "ntru-EESS1v1-SVSSA"             }, /* 223 */
- {                    0x03,     0, 0, 10, "ntru-EESS1v1-NTRUSign"          }, /* 224 */
- {                  0x02,     255, 1,  9, "eess1-params"                   }, /* 225 */
- {                    0x01,   227, 0, 10, "ees251ep1"                      }, /* 226 */
- {                    0x02,   228, 0, 10, "ees347ep1"                      }, /* 227 */
- {                    0x03,   229, 0, 10, "ees503ep1"                      }, /* 228 */
- {                    0x07,   230, 0, 10, "ees251sp2"                      }, /* 229 */
- {                    0x0C,   231, 0, 10, "ees251ep4"                      }, /* 230 */
- {                    0x0D,   232, 0, 10, "ees251ep5"                      }, /* 231 */
- {                    0x0E,   233, 0, 10, "ees251sp3"                      }, /* 232 */
- {                    0x0F,   234, 0, 10, "ees251sp4"                      }, /* 233 */
- {                    0x10,   235, 0, 10, "ees251sp5"                      }, /* 234 */
- {                    0x11,   236, 0, 10, "ees251sp6"                      }, /* 235 */
- {                    0x12,   237, 0, 10, "ees251sp7"                      }, /* 236 */
- {                    0x13,   238, 0, 10, "ees251sp8"                      }, /* 237 */
- {                    0x14,   239, 0, 10, "ees251sp9"                      }, /* 238 */
- {                    0x22,   240, 0, 10, "ees401ep1"                      }, /* 239 */
- {                    0x23,   241, 0, 10, "ees449ep1"                      }, /* 240 */
- {                    0x24,   242, 0, 10, "ees677ep1"                      }, /* 241 */
- {                    0x25,   243, 0, 10, "ees1087ep2"                     }, /* 242 */
- {                    0x26,   244, 0, 10, "ees541ep1"                      }, /* 243 */
- {                    0x27,   245, 0, 10, "ees613ep1"                      }, /* 244 */
- {                    0x28,   246, 0, 10, "ees887ep1"                      }, /* 245 */
- {                    0x29,   247, 0, 10, "ees1171ep1"                     }, /* 246 */
- {                    0x2A,   248, 0, 10, "ees659ep1"                      }, /* 247 */
- {                    0x2B,   249, 0, 10, "ees761ep1"                      }, /* 248 */
- {                    0x2C,   250, 0, 10, "ees1087ep1"                     }, /* 249 */
- {                    0x2D,   251, 0, 10, "ees1499ep1"                     }, /* 250 */
- {                    0x2E,   252, 0, 10, "ees401ep2"                      }, /* 251 */
- {                    0x2F,   253, 0, 10, "ees439ep1"                      }, /* 252 */
- {                    0x30,   254, 0, 10, "ees593ep1"                      }, /* 253 */
- {                    0x31,     0, 0, 10, "ees743ep1"                      }, /* 254 */
- {                  0x03,       0, 0,  9, "eess1-encodingMethods"          }, /* 255 */
- {      0x05,                   0, 1,  3, "security"                       }, /* 256 */
- {        0x05,                 0, 1,  4, "mechanisms"                     }, /* 257 */
- {          0x07,             302, 1,  5, "id-pkix"                        }, /* 258 */
- {            0x01,           263, 1,  6, "id-pe"                          }, /* 259 */
- {              0x01,         261, 0,  7, "authorityInfoAccess"            }, /* 260 */
- {              0x03,         262, 0,  7, "qcStatements"                   }, /* 261 */
- {              0x07,           0, 0,  7, "ipAddrBlocks"                   }, /* 262 */
- {            0x02,           266, 1,  6, "id-qt"                          }, /* 263 */
- {              0x01,         265, 0,  7, "cps"                            }, /* 264 */
- {              0x02,           0, 0,  7, "unotice"                        }, /* 265 */
- {            0x03,           276, 1,  6, "id-kp"                          }, /* 266 */
- {              0x01,         268, 0,  7, "serverAuth"                     }, /* 267 */
- {              0x02,         269, 0,  7, "clientAuth"                     }, /* 268 */
- {              0x03,         270, 0,  7, "codeSigning"                    }, /* 269 */
- {              0x04,         271, 0,  7, "emailProtection"                }, /* 270 */
- {              0x05,         272, 0,  7, "ipsecEndSystem"                 }, /* 271 */
- {              0x06,         273, 0,  7, "ipsecTunnel"                    }, /* 272 */
- {              0x07,         274, 0,  7, "ipsecUser"                      }, /* 273 */
- {              0x08,         275, 0,  7, "timeStamping"                   }, /* 274 */
- {              0x09,           0, 0,  7, "ocspSigning"                    }, /* 275 */
- {            0x08,           284, 1,  6, "id-otherNames"                  }, /* 276 */
- {              0x01,         278, 0,  7, "personalData"                   }, /* 277 */
- {              0x02,         279, 0,  7, "userGroup"                      }, /* 278 */
- {              0x03,         280, 0,  7, "id-on-permanentIdentifier"      }, /* 279 */
- {              0x04,         281, 0,  7, "id-on-hardwareModuleName"       }, /* 280 */
- {              0x05,         282, 0,  7, "xmppAddr"                       }, /* 281 */
- {              0x06,         283, 0,  7, "id-on-SIM"                      }, /* 282 */
- {              0x07,           0, 0,  7, "id-on-dnsSRV"                   }, /* 283 */
- {            0x0A,           289, 1,  6, "id-aca"                         }, /* 284 */
- {              0x01,         286, 0,  7, "authenticationInfo"             }, /* 285 */
- {              0x02,         287, 0,  7, "accessIdentity"                 }, /* 286 */
- {              0x03,         288, 0,  7, "chargingIdentity"               }, /* 287 */
- {              0x04,           0, 0,  7, "group"                          }, /* 288 */
- {            0x0B,           290, 0,  6, "subjectInfoAccess"              }, /* 289 */
- {            0x30,             0, 1,  6, "id-ad"                          }, /* 290 */
- {              0x01,         299, 1,  7, "ocsp"                           }, /* 291 */
- {                0x01,       293, 0,  8, "basic"                          }, /* 292 */
- {                0x02,       294, 0,  8, "nonce"                          }, /* 293 */
- {                0x03,       295, 0,  8, "crl"                            }, /* 294 */
- {                0x04,       296, 0,  8, "response"                       }, /* 295 */
- {                0x05,       297, 0,  8, "noCheck"                        }, /* 296 */
- {                0x06,       298, 0,  8, "archiveCutoff"                  }, /* 297 */
- {                0x07,         0, 0,  8, "serviceLocator"                 }, /* 298 */
- {              0x02,         300, 0,  7, "caIssuers"                      }, /* 299 */
- {              0x03,         301, 0,  7, "timeStamping"                   }, /* 300 */
- {              0x05,           0, 0,  7, "caRepository"                   }, /* 301 */
- {          0x08,               0, 1,  5, "ipsec"                          }, /* 302 */
- {            0x02,             0, 1,  6, "certificate"                    }, /* 303 */
- {              0x02,           0, 0,  7, "iKEIntermediate"                }, /* 304 */
- {  0x0E,                     311, 1,  1, "oiw"                            }, /* 305 */
- {    0x03,                     0, 1,  2, "secsig"                         }, /* 306 */
- {      0x02,                   0, 1,  3, "algorithms"                     }, /* 307 */
- {        0x07,               309, 0,  4, "des-cbc"                        }, /* 308 */
- {        0x1A,               310, 0,  4, "sha-1"                          }, /* 309 */
- {        0x1D,                 0, 0,  4, "sha-1WithRSASignature"          }, /* 310 */
- {  0x24,                     357, 1,  1, "TeleTrusT"                      }, /* 311 */
- {    0x03,                     0, 1,  2, "algorithm"                      }, /* 312 */
- {      0x03,                   0, 1,  3, "signatureAlgorithm"             }, /* 313 */
- {        0x01,               318, 1,  4, "rsaSignature"                   }, /* 314 */
- {          0x02,             316, 0,  5, "rsaSigWithripemd160"            }, /* 315 */
- {          0x03,             317, 0,  5, "rsaSigWithripemd128"            }, /* 316 */
- {          0x04,               0, 0,  5, "rsaSigWithripemd256"            }, /* 317 */
- {        0x02,                 0, 1,  4, "ecSign"                         }, /* 318 */
- {          0x01,             320, 0,  5, "ecSignWithsha1"                 }, /* 319 */
- {          0x02,             321, 0,  5, "ecSignWithripemd160"            }, /* 320 */
- {          0x03,             322, 0,  5, "ecSignWithmd2"                  }, /* 321 */
- {          0x04,             323, 0,  5, "ecSignWithmd5"                  }, /* 322 */
- {          0x05,             340, 1,  5, "ttt-ecg"                        }, /* 323 */
- {            0x01,           328, 1,  6, "fieldType"                      }, /* 324 */
- {              0x01,           0, 1,  7, "characteristictwoField"         }, /* 325 */
- {                0x01,         0, 1,  8, "basisType"                      }, /* 326 */
- {                  0x01,       0, 0,  9, "ipBasis"                        }, /* 327 */
- {            0x02,           330, 1,  6, "keyType"                        }, /* 328 */
- {              0x01,           0, 0,  7, "ecgPublicKey"                   }, /* 329 */
- {            0x03,           331, 0,  6, "curve"                          }, /* 330 */
- {            0x04,           338, 1,  6, "signatures"                     }, /* 331 */
- {              0x01,         333, 0,  7, "ecgdsa-with-RIPEMD160"          }, /* 332 */
- {              0x02,         334, 0,  7, "ecgdsa-with-SHA1"               }, /* 333 */
- {              0x03,         335, 0,  7, "ecgdsa-with-SHA224"             }, /* 334 */
- {              0x04,         336, 0,  7, "ecgdsa-with-SHA256"             }, /* 335 */
- {              0x05,         337, 0,  7, "ecgdsa-with-SHA384"             }, /* 336 */
- {              0x06,           0, 0,  7, "ecgdsa-with-SHA512"             }, /* 337 */
- {            0x05,             0, 1,  6, "module"                         }, /* 338 */
- {              0x01,           0, 0,  7, "1"                              }, /* 339 */
- {          0x08,               0, 1,  5, "ecStdCurvesAndGeneration"       }, /* 340 */
- {            0x01,             0, 1,  6, "ellipticCurve"                  }, /* 341 */
- {              0x01,           0, 1,  7, "versionOne"                     }, /* 342 */
- {                0x01,       344, 0,  8, "brainpoolP160r1"                }, /* 343 */
- {                0x02,       345, 0,  8, "brainpoolP160t1"                }, /* 344 */
- {                0x03,       346, 0,  8, "brainpoolP192r1"                }, /* 345 */
- {                0x04,       347, 0,  8, "brainpoolP192t1"                }, /* 346 */
- {                0x05,       348, 0,  8, "brainpoolP224r1"                }, /* 347 */
- {                0x06,       349, 0,  8, "brainpoolP224t1"                }, /* 348 */
- {                0x07,       350, 0,  8, "brainpoolP256r1"                }, /* 349 */
- {                0x08,       351, 0,  8, "brainpoolP256t1"                }, /* 350 */
- {                0x09,       352, 0,  8, "brainpoolP320r1"                }, /* 351 */
- {                0x0A,       353, 0,  8, "brainpoolP320t1"                }, /* 352 */
- {                0x0B,       354, 0,  8, "brainpoolP384r1"                }, /* 353 */
- {                0x0C,       355, 0,  8, "brainpoolP384t1"                }, /* 354 */
- {                0x0D,       356, 0,  8, "brainpoolP512r1"                }, /* 355 */
- {                0x0E,         0, 0,  8, "brainpoolP512t1"                }, /* 356 */
- {  0x81,                       0, 1,  1, ""                               }, /* 357 */
- {    0x04,                     0, 1,  2, "Certicom"                       }, /* 358 */
- {      0x00,                   0, 1,  3, "curve"                          }, /* 359 */
- {        0x01,               361, 0,  4, "sect163k1"                      }, /* 360 */
- {        0x02,               362, 0,  4, "sect163r1"                      }, /* 361 */
- {        0x03,               363, 0,  4, "sect239k1"                      }, /* 362 */
- {        0x04,               364, 0,  4, "sect113r1"                      }, /* 363 */
- {        0x05,               365, 0,  4, "sect113r2"                      }, /* 364 */
- {        0x06,               366, 0,  4, "secp112r1"                      }, /* 365 */
- {        0x07,               367, 0,  4, "secp112r2"                      }, /* 366 */
- {        0x08,               368, 0,  4, "secp160r1"                      }, /* 367 */
- {        0x09,               369, 0,  4, "secp160k1"                      }, /* 368 */
- {        0x0A,               370, 0,  4, "secp256k1"                      }, /* 369 */
- {        0x0F,               371, 0,  4, "sect163r2"                      }, /* 370 */
- {        0x10,               372, 0,  4, "sect283k1"                      }, /* 371 */
- {        0x11,               373, 0,  4, "sect283r1"                      }, /* 372 */
- {        0x16,               374, 0,  4, "sect131r1"                      }, /* 373 */
- {        0x17,               375, 0,  4, "sect131r2"                      }, /* 374 */
- {        0x18,               376, 0,  4, "sect193r1"                      }, /* 375 */
- {        0x19,               377, 0,  4, "sect193r2"                      }, /* 376 */
- {        0x1A,               378, 0,  4, "sect233k1"                      }, /* 377 */
- {        0x1B,               379, 0,  4, "sect233r1"                      }, /* 378 */
- {        0x1C,               380, 0,  4, "secp128r1"                      }, /* 379 */
- {        0x1D,               381, 0,  4, "secp128r2"                      }, /* 380 */
- {        0x1E,               382, 0,  4, "secp160r2"                      }, /* 381 */
- {        0x1F,               383, 0,  4, "secp192k1"                      }, /* 382 */
- {        0x20,               384, 0,  4, "secp224k1"                      }, /* 383 */
- {        0x21,               385, 0,  4, "secp224r1"                      }, /* 384 */
- {        0x22,               386, 0,  4, "secp384r1"                      }, /* 385 */
- {        0x23,               387, 0,  4, "secp521r1"                      }, /* 386 */
- {        0x24,               388, 0,  4, "sect409k1"                      }, /* 387 */
- {        0x25,               389, 0,  4, "sect409r1"                      }, /* 388 */
- {        0x26,               390, 0,  4, "sect571k1"                      }, /* 389 */
- {        0x27,                 0, 0,  4, "sect571r1"                      }, /* 390 */
- {0x60,                       445, 1,  0, ""                               }, /* 391 */
- {  0x86,                       0, 1,  1, ""                               }, /* 392 */
- {    0x48,                     0, 1,  2, ""                               }, /* 393 */
- {      0x01,                   0, 1,  3, "organization"                   }, /* 394 */
- {        0x65,               421, 1,  4, "gov"                            }, /* 395 */
- {          0x03,               0, 1,  5, "csor"                           }, /* 396 */
- {            0x04,             0, 1,  6, "nistalgorithm"                  }, /* 397 */
- {              0x01,         408, 1,  7, "aes"                            }, /* 398 */
- {                0x02,       400, 0,  8, "id-aes128-CBC"                  }, /* 399 */
- {                0x06,       401, 0,  8, "id-aes128-GCM"                  }, /* 400 */
- {                0x07,       402, 0,  8, "id-aes128-CCM"                  }, /* 401 */
- {                0x16,       403, 0,  8, "id-aes192-CBC"                  }, /* 402 */
- {                0x1A,       404, 0,  8, "id-aes192-GCM"                  }, /* 403 */
- {                0x1B,       405, 0,  8, "id-aes192-CCM"                  }, /* 404 */
- {                0x2A,       406, 0,  8, "id-aes256-CBC"                  }, /* 405 */
- {                0x2E,       407, 0,  8, "id-aes256-GCM"                  }, /* 406 */
- {                0x2F,         0, 0,  8, "id-aes256-CCM"                  }, /* 407 */
- {              0x02,           0, 1,  7, "hashalgs"                       }, /* 408 */
- {                0x01,       410, 0,  8, "id-sha256"                      }, /* 409 */
- {                0x02,       411, 0,  8, "id-sha384"                      }, /* 410 */
- {                0x03,       412, 0,  8, "id-sha512"                      }, /* 411 */
- {                0x04,       413, 0,  8, "id-sha224"                      }, /* 412 */
- {                0x05,       414, 0,  8, "id-sha512-224"                  }, /* 413 */
- {                0x06,       415, 0,  8, "id-sha512-256"                  }, /* 414 */
- {                0x07,       416, 0,  8, "id-sha3-224"                    }, /* 415 */
- {                0x08,       417, 0,  8, "id-sha3-256"                    }, /* 416 */
- {                0x09,       418, 0,  8, "id-sha3-384"                    }, /* 417 */
- {                0x0A,       419, 0,  8, "id-sha3-512"                    }, /* 418 */
- {                0x0B,       420, 0,  8, "id-shake128"                    }, /* 419 */
- {                0x0C,         0, 0,  8, "id-shake256"                    }, /* 420 */
- {        0x86,                 0, 1,  4, ""                               }, /* 421 */
- {          0xf8,               0, 1,  5, ""                               }, /* 422 */
- {            0x42,           435, 1,  6, "netscape"                       }, /* 423 */
- {              0x01,         430, 1,  7, ""                               }, /* 424 */
- {                0x01,       426, 0,  8, "nsCertType"                     }, /* 425 */
- {                0x03,       427, 0,  8, "nsRevocationUrl"                }, /* 426 */
- {                0x04,       428, 0,  8, "nsCaRevocationUrl"              }, /* 427 */
- {                0x08,       429, 0,  8, "nsCaPolicyUrl"                  }, /* 428 */
- {                0x0d,         0, 0,  8, "nsComment"                      }, /* 429 */
- {              0x03,         433, 1,  7, "directory"                      }, /* 430 */
- {                0x01,         0, 1,  8, ""                               }, /* 431 */
- {                  0x03,       0, 0,  9, "employeeNumber"                 }, /* 432 */
- {              0x04,           0, 1,  7, "policy"                         }, /* 433 */
- {                0x01,         0, 0,  8, "nsSGC"                          }, /* 434 */
- {            0x45,             0, 1,  6, "verisign"                       }, /* 435 */
- {              0x01,           0, 1,  7, "pki"                            }, /* 436 */
- {                0x09,         0, 1,  8, "attributes"                     }, /* 437 */
- {                  0x02,     439, 0,  9, "messageType"                    }, /* 438 */
- {                  0x03,     440, 0,  9, "pkiStatus"                      }, /* 439 */
- {                  0x04,     441, 0,  9, "failInfo"                       }, /* 440 */
- {                  0x05,     442, 0,  9, "senderNonce"                    }, /* 441 */
- {                  0x06,     443, 0,  9, "recipientNonce"                 }, /* 442 */
- {                  0x07,     444, 0,  9, "transID"                        }, /* 443 */
- {                  0x08,       0, 0,  9, "extensionReq"                   }, /* 444 */
- {0x67,                         0, 1,  0, ""                               }, /* 445 */
- {  0x81,                       0, 1,  1, ""                               }, /* 446 */
- {    0x05,                     0, 1,  2, ""                               }, /* 447 */
- {      0x02,                   0, 1,  3, "tcg-attribute"                  }, /* 448 */
- {        0x01,               450, 0,  4, "tcg-at-tpmManufacturer"         }, /* 449 */
- {        0x02,               451, 0,  4, "tcg-at-tpmModel"                }, /* 450 */
- {        0x03,               452, 0,  4, "tcg-at-tpmVersion"              }, /* 451 */
- {        0x0F,                 0, 0,  4, "tcg-at-tpmIdLabel"              }  /* 452 */
+ {                0x01,       210, 0,  8, "strongSwan"                     }, /* 209 */
+ {                0x02,       211, 0,  8, "cps"                            }, /* 210 */
+ {                0x03,       212, 0,  8, "e-voting"                       }, /* 211 */
+ {                0x05,         0, 1,  8, "BLISS"                          }, /* 212 */
+ {                  0x01,     215, 1,  9, "keyType"                        }, /* 213 */
+ {                    0x01,     0, 0, 10, "blissPublicKey"                 }, /* 214 */
+ {                  0x02,     224, 1,  9, "parameters"                     }, /* 215 */
+ {                    0x01,   217, 0, 10, "BLISS-I"                        }, /* 216 */
+ {                    0x02,   218, 0, 10, "BLISS-II"                       }, /* 217 */
+ {                    0x03,   219, 0, 10, "BLISS-III"                      }, /* 218 */
+ {                    0x04,   220, 0, 10, "BLISS-IV"                       }, /* 219 */
+ {                    0x05,   221, 0, 10, "BLISS-B-I"                      }, /* 220 */
+ {                    0x06,   222, 0, 10, "BLISS-B-II"                     }, /* 221 */
+ {                    0x07,   223, 0, 10, "BLISS-B-III"                    }, /* 222 */
+ {                    0x08,     0, 0, 10, "BLISS-B-IV"                     }, /* 223 */
+ {                  0x03,       0, 1,  9, "blissSigType"                   }, /* 224 */
+ {                    0x01,   226, 0, 10, "BLISS-with-SHA512"              }, /* 225 */
+ {                    0x02,   227, 0, 10, "BLISS-with-SHA384"              }, /* 226 */
+ {                    0x03,     0, 0, 10, "BLISS-with-SHA256"              }, /* 227 */
+ {          0x89,             235, 1,  5, ""                               }, /* 228 */
+ {            0x31,             0, 1,  6, ""                               }, /* 229 */
+ {              0x01,           0, 1,  7, ""                               }, /* 230 */
+ {                0x01,         0, 1,  8, ""                               }, /* 231 */
+ {                  0x02,       0, 1,  9, ""                               }, /* 232 */
+ {                    0x02,     0, 1, 10, ""                               }, /* 233 */
+ {                      0x4B,   0, 0, 11, "TCGID"                          }, /* 234 */
+ {          0x97,             239, 1,  5, ""                               }, /* 235 */
+ {            0x55,             0, 1,  6, ""                               }, /* 236 */
+ {              0x01,           0, 1,  7, ""                               }, /* 237 */
+ {                0x02,         0, 0,  8, "blowfish-cbc"                   }, /* 238 */
+ {          0xC1,               0, 1,  5, ""                               }, /* 239 */
+ {            0x16,             0, 1,  6, "ntruCryptosystems"              }, /* 240 */
+ {              0x01,           0, 1,  7, "eess"                           }, /* 241 */
+ {                0x01,         0, 1,  8, "eess1"                          }, /* 242 */
+ {                  0x01,     247, 1,  9, "eess1-algs"                     }, /* 243 */
+ {                    0x01,   245, 0, 10, "ntru-EESS1v1-SVES"              }, /* 244 */
+ {                    0x02,   246, 0, 10, "ntru-EESS1v1-SVSSA"             }, /* 245 */
+ {                    0x03,     0, 0, 10, "ntru-EESS1v1-NTRUSign"          }, /* 246 */
+ {                  0x02,     277, 1,  9, "eess1-params"                   }, /* 247 */
+ {                    0x01,   249, 0, 10, "ees251ep1"                      }, /* 248 */
+ {                    0x02,   250, 0, 10, "ees347ep1"                      }, /* 249 */
+ {                    0x03,   251, 0, 10, "ees503ep1"                      }, /* 250 */
+ {                    0x07,   252, 0, 10, "ees251sp2"                      }, /* 251 */
+ {                    0x0C,   253, 0, 10, "ees251ep4"                      }, /* 252 */
+ {                    0x0D,   254, 0, 10, "ees251ep5"                      }, /* 253 */
+ {                    0x0E,   255, 0, 10, "ees251sp3"                      }, /* 254 */
+ {                    0x0F,   256, 0, 10, "ees251sp4"                      }, /* 255 */
+ {                    0x10,   257, 0, 10, "ees251sp5"                      }, /* 256 */
+ {                    0x11,   258, 0, 10, "ees251sp6"                      }, /* 257 */
+ {                    0x12,   259, 0, 10, "ees251sp7"                      }, /* 258 */
+ {                    0x13,   260, 0, 10, "ees251sp8"                      }, /* 259 */
+ {                    0x14,   261, 0, 10, "ees251sp9"                      }, /* 260 */
+ {                    0x22,   262, 0, 10, "ees401ep1"                      }, /* 261 */
+ {                    0x23,   263, 0, 10, "ees449ep1"                      }, /* 262 */
+ {                    0x24,   264, 0, 10, "ees677ep1"                      }, /* 263 */
+ {                    0x25,   265, 0, 10, "ees1087ep2"                     }, /* 264 */
+ {                    0x26,   266, 0, 10, "ees541ep1"                      }, /* 265 */
+ {                    0x27,   267, 0, 10, "ees613ep1"                      }, /* 266 */
+ {                    0x28,   268, 0, 10, "ees887ep1"                      }, /* 267 */
+ {                    0x29,   269, 0, 10, "ees1171ep1"                     }, /* 268 */
+ {                    0x2A,   270, 0, 10, "ees659ep1"                      }, /* 269 */
+ {                    0x2B,   271, 0, 10, "ees761ep1"                      }, /* 270 */
+ {                    0x2C,   272, 0, 10, "ees1087ep1"                     }, /* 271 */
+ {                    0x2D,   273, 0, 10, "ees1499ep1"                     }, /* 272 */
+ {                    0x2E,   274, 0, 10, "ees401ep2"                      }, /* 273 */
+ {                    0x2F,   275, 0, 10, "ees439ep1"                      }, /* 274 */
+ {                    0x30,   276, 0, 10, "ees593ep1"                      }, /* 275 */
+ {                    0x31,     0, 0, 10, "ees743ep1"                      }, /* 276 */
+ {                  0x03,       0, 0,  9, "eess1-encodingMethods"          }, /* 277 */
+ {      0x05,                   0, 1,  3, "security"                       }, /* 278 */
+ {        0x05,                 0, 1,  4, "mechanisms"                     }, /* 279 */
+ {          0x07,             324, 1,  5, "id-pkix"                        }, /* 280 */
+ {            0x01,           285, 1,  6, "id-pe"                          }, /* 281 */
+ {              0x01,         283, 0,  7, "authorityInfoAccess"            }, /* 282 */
+ {              0x03,         284, 0,  7, "qcStatements"                   }, /* 283 */
+ {              0x07,           0, 0,  7, "ipAddrBlocks"                   }, /* 284 */
+ {            0x02,           288, 1,  6, "id-qt"                          }, /* 285 */
+ {              0x01,         287, 0,  7, "cps"                            }, /* 286 */
+ {              0x02,           0, 0,  7, "unotice"                        }, /* 287 */
+ {            0x03,           298, 1,  6, "id-kp"                          }, /* 288 */
+ {              0x01,         290, 0,  7, "serverAuth"                     }, /* 289 */
+ {              0x02,         291, 0,  7, "clientAuth"                     }, /* 290 */
+ {              0x03,         292, 0,  7, "codeSigning"                    }, /* 291 */
+ {              0x04,         293, 0,  7, "emailProtection"                }, /* 292 */
+ {              0x05,         294, 0,  7, "ipsecEndSystem"                 }, /* 293 */
+ {              0x06,         295, 0,  7, "ipsecTunnel"                    }, /* 294 */
+ {              0x07,         296, 0,  7, "ipsecUser"                      }, /* 295 */
+ {              0x08,         297, 0,  7, "timeStamping"                   }, /* 296 */
+ {              0x09,           0, 0,  7, "ocspSigning"                    }, /* 297 */
+ {            0x08,           306, 1,  6, "id-otherNames"                  }, /* 298 */
+ {              0x01,         300, 0,  7, "personalData"                   }, /* 299 */
+ {              0x02,         301, 0,  7, "userGroup"                      }, /* 300 */
+ {              0x03,         302, 0,  7, "id-on-permanentIdentifier"      }, /* 301 */
+ {              0x04,         303, 0,  7, "id-on-hardwareModuleName"       }, /* 302 */
+ {              0x05,         304, 0,  7, "xmppAddr"                       }, /* 303 */
+ {              0x06,         305, 0,  7, "id-on-SIM"                      }, /* 304 */
+ {              0x07,           0, 0,  7, "id-on-dnsSRV"                   }, /* 305 */
+ {            0x0A,           311, 1,  6, "id-aca"                         }, /* 306 */
+ {              0x01,         308, 0,  7, "authenticationInfo"             }, /* 307 */
+ {              0x02,         309, 0,  7, "accessIdentity"                 }, /* 308 */
+ {              0x03,         310, 0,  7, "chargingIdentity"               }, /* 309 */
+ {              0x04,           0, 0,  7, "group"                          }, /* 310 */
+ {            0x0B,           312, 0,  6, "subjectInfoAccess"              }, /* 311 */
+ {            0x30,             0, 1,  6, "id-ad"                          }, /* 312 */
+ {              0x01,         321, 1,  7, "ocsp"                           }, /* 313 */
+ {                0x01,       315, 0,  8, "basic"                          }, /* 314 */
+ {                0x02,       316, 0,  8, "nonce"                          }, /* 315 */
+ {                0x03,       317, 0,  8, "crl"                            }, /* 316 */
+ {                0x04,       318, 0,  8, "response"                       }, /* 317 */
+ {                0x05,       319, 0,  8, "noCheck"                        }, /* 318 */
+ {                0x06,       320, 0,  8, "archiveCutoff"                  }, /* 319 */
+ {                0x07,         0, 0,  8, "serviceLocator"                 }, /* 320 */
+ {              0x02,         322, 0,  7, "caIssuers"                      }, /* 321 */
+ {              0x03,         323, 0,  7, "timeStamping"                   }, /* 322 */
+ {              0x05,           0, 0,  7, "caRepository"                   }, /* 323 */
+ {          0x08,               0, 1,  5, "ipsec"                          }, /* 324 */
+ {            0x02,             0, 1,  6, "certificate"                    }, /* 325 */
+ {              0x02,           0, 0,  7, "iKEIntermediate"                }, /* 326 */
+ {  0x0E,                     333, 1,  1, "oiw"                            }, /* 327 */
+ {    0x03,                     0, 1,  2, "secsig"                         }, /* 328 */
+ {      0x02,                   0, 1,  3, "algorithms"                     }, /* 329 */
+ {        0x07,               331, 0,  4, "des-cbc"                        }, /* 330 */
+ {        0x1A,               332, 0,  4, "sha-1"                          }, /* 331 */
+ {        0x1D,                 0, 0,  4, "sha-1WithRSASignature"          }, /* 332 */
+ {  0x24,                     379, 1,  1, "TeleTrusT"                      }, /* 333 */
+ {    0x03,                     0, 1,  2, "algorithm"                      }, /* 334 */
+ {      0x03,                   0, 1,  3, "signatureAlgorithm"             }, /* 335 */
+ {        0x01,               340, 1,  4, "rsaSignature"                   }, /* 336 */
+ {          0x02,             338, 0,  5, "rsaSigWithripemd160"            }, /* 337 */
+ {          0x03,             339, 0,  5, "rsaSigWithripemd128"            }, /* 338 */
+ {          0x04,               0, 0,  5, "rsaSigWithripemd256"            }, /* 339 */
+ {        0x02,                 0, 1,  4, "ecSign"                         }, /* 340 */
+ {          0x01,             342, 0,  5, "ecSignWithsha1"                 }, /* 341 */
+ {          0x02,             343, 0,  5, "ecSignWithripemd160"            }, /* 342 */
+ {          0x03,             344, 0,  5, "ecSignWithmd2"                  }, /* 343 */
+ {          0x04,             345, 0,  5, "ecSignWithmd5"                  }, /* 344 */
+ {          0x05,             362, 1,  5, "ttt-ecg"                        }, /* 345 */
+ {            0x01,           350, 1,  6, "fieldType"                      }, /* 346 */
+ {              0x01,           0, 1,  7, "characteristictwoField"         }, /* 347 */
+ {                0x01,         0, 1,  8, "basisType"                      }, /* 348 */
+ {                  0x01,       0, 0,  9, "ipBasis"                        }, /* 349 */
+ {            0x02,           352, 1,  6, "keyType"                        }, /* 350 */
+ {              0x01,           0, 0,  7, "ecgPublicKey"                   }, /* 351 */
+ {            0x03,           353, 0,  6, "curve"                          }, /* 352 */
+ {            0x04,           360, 1,  6, "signatures"                     }, /* 353 */
+ {              0x01,         355, 0,  7, "ecgdsa-with-RIPEMD160"          }, /* 354 */
+ {              0x02,         356, 0,  7, "ecgdsa-with-SHA1"               }, /* 355 */
+ {              0x03,         357, 0,  7, "ecgdsa-with-SHA224"             }, /* 356 */
+ {              0x04,         358, 0,  7, "ecgdsa-with-SHA256"             }, /* 357 */
+ {              0x05,         359, 0,  7, "ecgdsa-with-SHA384"             }, /* 358 */
+ {              0x06,           0, 0,  7, "ecgdsa-with-SHA512"             }, /* 359 */
+ {            0x05,             0, 1,  6, "module"                         }, /* 360 */
+ {              0x01,           0, 0,  7, "1"                              }, /* 361 */
+ {          0x08,               0, 1,  5, "ecStdCurvesAndGeneration"       }, /* 362 */
+ {            0x01,             0, 1,  6, "ellipticCurve"                  }, /* 363 */
+ {              0x01,           0, 1,  7, "versionOne"                     }, /* 364 */
+ {                0x01,       366, 0,  8, "brainpoolP160r1"                }, /* 365 */
+ {                0x02,       367, 0,  8, "brainpoolP160t1"                }, /* 366 */
+ {                0x03,       368, 0,  8, "brainpoolP192r1"                }, /* 367 */
+ {                0x04,       369, 0,  8, "brainpoolP192t1"                }, /* 368 */
+ {                0x05,       370, 0,  8, "brainpoolP224r1"                }, /* 369 */
+ {                0x06,       371, 0,  8, "brainpoolP224t1"                }, /* 370 */
+ {                0x07,       372, 0,  8, "brainpoolP256r1"                }, /* 371 */
+ {                0x08,       373, 0,  8, "brainpoolP256t1"                }, /* 372 */
+ {                0x09,       374, 0,  8, "brainpoolP320r1"                }, /* 373 */
+ {                0x0A,       375, 0,  8, "brainpoolP320t1"                }, /* 374 */
+ {                0x0B,       376, 0,  8, "brainpoolP384r1"                }, /* 375 */
+ {                0x0C,       377, 0,  8, "brainpoolP384t1"                }, /* 376 */
+ {                0x0D,       378, 0,  8, "brainpoolP512r1"                }, /* 377 */
+ {                0x0E,         0, 0,  8, "brainpoolP512t1"                }, /* 378 */
+ {  0x81,                       0, 1,  1, ""                               }, /* 379 */
+ {    0x04,                     0, 1,  2, "Certicom"                       }, /* 380 */
+ {      0x00,                   0, 1,  3, "curve"                          }, /* 381 */
+ {        0x01,               383, 0,  4, "sect163k1"                      }, /* 382 */
+ {        0x02,               384, 0,  4, "sect163r1"                      }, /* 383 */
+ {        0x03,               385, 0,  4, "sect239k1"                      }, /* 384 */
+ {        0x04,               386, 0,  4, "sect113r1"                      }, /* 385 */
+ {        0x05,               387, 0,  4, "sect113r2"                      }, /* 386 */
+ {        0x06,               388, 0,  4, "secp112r1"                      }, /* 387 */
+ {        0x07,               389, 0,  4, "secp112r2"                      }, /* 388 */
+ {        0x08,               390, 0,  4, "secp160r1"                      }, /* 389 */
+ {        0x09,               391, 0,  4, "secp160k1"                      }, /* 390 */
+ {        0x0A,               392, 0,  4, "secp256k1"                      }, /* 391 */
+ {        0x0F,               393, 0,  4, "sect163r2"                      }, /* 392 */
+ {        0x10,               394, 0,  4, "sect283k1"                      }, /* 393 */
+ {        0x11,               395, 0,  4, "sect283r1"                      }, /* 394 */
+ {        0x16,               396, 0,  4, "sect131r1"                      }, /* 395 */
+ {        0x17,               397, 0,  4, "sect131r2"                      }, /* 396 */
+ {        0x18,               398, 0,  4, "sect193r1"                      }, /* 397 */
+ {        0x19,               399, 0,  4, "sect193r2"                      }, /* 398 */
+ {        0x1A,               400, 0,  4, "sect233k1"                      }, /* 399 */
+ {        0x1B,               401, 0,  4, "sect233r1"                      }, /* 400 */
+ {        0x1C,               402, 0,  4, "secp128r1"                      }, /* 401 */
+ {        0x1D,               403, 0,  4, "secp128r2"                      }, /* 402 */
+ {        0x1E,               404, 0,  4, "secp160r2"                      }, /* 403 */
+ {        0x1F,               405, 0,  4, "secp192k1"                      }, /* 404 */
+ {        0x20,               406, 0,  4, "secp224k1"                      }, /* 405 */
+ {        0x21,               407, 0,  4, "secp224r1"                      }, /* 406 */
+ {        0x22,               408, 0,  4, "secp384r1"                      }, /* 407 */
+ {        0x23,               409, 0,  4, "secp521r1"                      }, /* 408 */
+ {        0x24,               410, 0,  4, "sect409k1"                      }, /* 409 */
+ {        0x25,               411, 0,  4, "sect409r1"                      }, /* 410 */
+ {        0x26,               412, 0,  4, "sect571k1"                      }, /* 411 */
+ {        0x27,                 0, 0,  4, "sect571r1"                      }, /* 412 */
+ {0x60,                       467, 1,  0, ""                               }, /* 413 */
+ {  0x86,                       0, 1,  1, ""                               }, /* 414 */
+ {    0x48,                     0, 1,  2, ""                               }, /* 415 */
+ {      0x01,                   0, 1,  3, "organization"                   }, /* 416 */
+ {        0x65,               443, 1,  4, "gov"                            }, /* 417 */
+ {          0x03,               0, 1,  5, "csor"                           }, /* 418 */
+ {            0x04,             0, 1,  6, "nistalgorithm"                  }, /* 419 */
+ {              0x01,         430, 1,  7, "aes"                            }, /* 420 */
+ {                0x02,       422, 0,  8, "id-aes128-CBC"                  }, /* 421 */
+ {                0x06,       423, 0,  8, "id-aes128-GCM"                  }, /* 422 */
+ {                0x07,       424, 0,  8, "id-aes128-CCM"                  }, /* 423 */
+ {                0x16,       425, 0,  8, "id-aes192-CBC"                  }, /* 424 */
+ {                0x1A,       426, 0,  8, "id-aes192-GCM"                  }, /* 425 */
+ {                0x1B,       427, 0,  8, "id-aes192-CCM"                  }, /* 426 */
+ {                0x2A,       428, 0,  8, "id-aes256-CBC"                  }, /* 427 */
+ {                0x2E,       429, 0,  8, "id-aes256-GCM"                  }, /* 428 */
+ {                0x2F,         0, 0,  8, "id-aes256-CCM"                  }, /* 429 */
+ {              0x02,           0, 1,  7, "hashalgs"                       }, /* 430 */
+ {                0x01,       432, 0,  8, "id-sha256"                      }, /* 431 */
+ {                0x02,       433, 0,  8, "id-sha384"                      }, /* 432 */
+ {                0x03,       434, 0,  8, "id-sha512"                      }, /* 433 */
+ {                0x04,       435, 0,  8, "id-sha224"                      }, /* 434 */
+ {                0x05,       436, 0,  8, "id-sha512-224"                  }, /* 435 */
+ {                0x06,       437, 0,  8, "id-sha512-256"                  }, /* 436 */
+ {                0x07,       438, 0,  8, "id-sha3-224"                    }, /* 437 */
+ {                0x08,       439, 0,  8, "id-sha3-256"                    }, /* 438 */
+ {                0x09,       440, 0,  8, "id-sha3-384"                    }, /* 439 */
+ {                0x0A,       441, 0,  8, "id-sha3-512"                    }, /* 440 */
+ {                0x0B,       442, 0,  8, "id-shake128"                    }, /* 441 */
+ {                0x0C,         0, 0,  8, "id-shake256"                    }, /* 442 */
+ {        0x86,                 0, 1,  4, ""                               }, /* 443 */
+ {          0xf8,               0, 1,  5, ""                               }, /* 444 */
+ {            0x42,           457, 1,  6, "netscape"                       }, /* 445 */
+ {              0x01,         452, 1,  7, ""                               }, /* 446 */
+ {                0x01,       448, 0,  8, "nsCertType"                     }, /* 447 */
+ {                0x03,       449, 0,  8, "nsRevocationUrl"                }, /* 448 */
+ {                0x04,       450, 0,  8, "nsCaRevocationUrl"              }, /* 449 */
+ {                0x08,       451, 0,  8, "nsCaPolicyUrl"                  }, /* 450 */
+ {                0x0d,         0, 0,  8, "nsComment"                      }, /* 451 */
+ {              0x03,         455, 1,  7, "directory"                      }, /* 452 */
+ {                0x01,         0, 1,  8, ""                               }, /* 453 */
+ {                  0x03,       0, 0,  9, "employeeNumber"                 }, /* 454 */
+ {              0x04,           0, 1,  7, "policy"                         }, /* 455 */
+ {                0x01,         0, 0,  8, "nsSGC"                          }, /* 456 */
+ {            0x45,             0, 1,  6, "verisign"                       }, /* 457 */
+ {              0x01,           0, 1,  7, "pki"                            }, /* 458 */
+ {                0x09,         0, 1,  8, "attributes"                     }, /* 459 */
+ {                  0x02,     461, 0,  9, "messageType"                    }, /* 460 */
+ {                  0x03,     462, 0,  9, "pkiStatus"                      }, /* 461 */
+ {                  0x04,     463, 0,  9, "failInfo"                       }, /* 462 */
+ {                  0x05,     464, 0,  9, "senderNonce"                    }, /* 463 */
+ {                  0x06,     465, 0,  9, "recipientNonce"                 }, /* 464 */
+ {                  0x07,     466, 0,  9, "transID"                        }, /* 465 */
+ {                  0x08,       0, 0,  9, "extensionReq"                   }, /* 466 */
+ {0x67,                         0, 1,  0, ""                               }, /* 467 */
+ {  0x81,                       0, 1,  1, ""                               }, /* 468 */
+ {    0x05,                     0, 1,  2, ""                               }, /* 469 */
+ {      0x02,                   0, 1,  3, "tcg-attribute"                  }, /* 470 */
+ {        0x01,               472, 0,  4, "tcg-at-tpmManufacturer"         }, /* 471 */
+ {        0x02,               473, 0,  4, "tcg-at-tpmModel"                }, /* 472 */
+ {        0x03,               474, 0,  4, "tcg-at-tpmVersion"              }, /* 473 */
+ {        0x0F,                 0, 0,  4, "tcg-at-tpmIdLabel"              }  /* 474 */
 };
diff --git a/src/libstrongswan/asn1/oid.h b/src/libstrongswan/asn1/oid.h
index 0933f23..0f7c5d6 100644
--- a/src/libstrongswan/asn1/oid.h
+++ b/src/libstrongswan/asn1/oid.h
@@ -141,99 +141,112 @@ extern const oid_t oid_names[];
 #define OID_MS_SMARTCARD_LOGON				202
 #define OID_USER_PRINCIPAL_NAME				203
 #define OID_STRONGSWAN						209
-#define OID_TCGID							216
-#define OID_AUTHORITY_INFO_ACCESS			260
-#define OID_IP_ADDR_BLOCKS					262
-#define OID_POLICY_QUALIFIER_CPS			264
-#define OID_POLICY_QUALIFIER_UNOTICE		265
-#define OID_SERVER_AUTH						267
-#define OID_CLIENT_AUTH						268
-#define OID_OCSP_SIGNING					275
-#define OID_XMPP_ADDR						281
-#define OID_AUTHENTICATION_INFO				285
-#define OID_ACCESS_IDENTITY					286
-#define OID_CHARGING_IDENTITY				287
-#define OID_GROUP							288
-#define OID_OCSP							291
-#define OID_BASIC							292
-#define OID_NONCE							293
-#define OID_CRL								294
-#define OID_RESPONSE						295
-#define OID_NO_CHECK						296
-#define OID_ARCHIVE_CUTOFF					297
-#define OID_SERVICE_LOCATOR					298
-#define OID_CA_ISSUERS						299
-#define OID_IKE_INTERMEDIATE				304
-#define OID_DES_CBC							308
-#define OID_SHA1							309
-#define OID_SHA1_WITH_RSA_OIW				310
-#define OID_ECGDSA_PUBKEY					329
-#define OID_ECGDSA_SIG_WITH_RIPEMD160		332
-#define OID_ECGDSA_SIG_WITH_SHA1			333
-#define OID_ECGDSA_SIG_WITH_SHA224			334
-#define OID_ECGDSA_SIG_WITH_SHA256			335
-#define OID_ECGDSA_SIG_WITH_SHA384			336
-#define OID_ECGDSA_SIG_WITH_SHA512			337
-#define OID_SECT163K1						360
-#define OID_SECT163R1						361
-#define OID_SECT239K1						362
-#define OID_SECT113R1						363
-#define OID_SECT113R2						364
-#define OID_SECT112R1						365
-#define OID_SECT112R2						366
-#define OID_SECT160R1						367
-#define OID_SECT160K1						368
-#define OID_SECT256K1						369
-#define OID_SECT163R2						370
-#define OID_SECT283K1						371
-#define OID_SECT283R1						372
-#define OID_SECT131R1						373
-#define OID_SECT131R2						374
-#define OID_SECT193R1						375
-#define OID_SECT193R2						376
-#define OID_SECT233K1						377
-#define OID_SECT233R1						378
-#define OID_SECT128R1						379
-#define OID_SECT128R2						380
-#define OID_SECT160R2						381
-#define OID_SECT192K1						382
-#define OID_SECT224K1						383
-#define OID_SECT224R1						384
-#define OID_SECT384R1						385
-#define OID_SECT521R1						386
-#define OID_SECT409K1						387
-#define OID_SECT409R1						388
-#define OID_SECT571K1						389
-#define OID_SECT571R1						390
-#define OID_AES128_CBC						399
-#define OID_AES128_GCM						400
-#define OID_AES128_CCM						401
-#define OID_AES192_CBC						402
-#define OID_AES192_GCM						403
-#define OID_AES192_CCM						404
-#define OID_AES256_CBC						405
-#define OID_AES256_GCM						406
-#define OID_AES256_CCM						407
-#define OID_SHA256							409
-#define OID_SHA384							410
-#define OID_SHA512							411
-#define OID_SHA224							412
-#define OID_NS_REVOCATION_URL				426
-#define OID_NS_CA_REVOCATION_URL			427
-#define OID_NS_CA_POLICY_URL				428
-#define OID_NS_COMMENT						429
-#define OID_EMPLOYEE_NUMBER					432
-#define OID_PKI_MESSAGE_TYPE				438
-#define OID_PKI_STATUS						439
-#define OID_PKI_FAIL_INFO					440
-#define OID_PKI_SENDER_NONCE				441
-#define OID_PKI_RECIPIENT_NONCE				442
-#define OID_PKI_TRANS_ID					443
-#define OID_TPM_MANUFACTURER				449
-#define OID_TPM_MODEL						450
-#define OID_TPM_VERSION						451
-#define OID_TPM_ID_LABEL					452
+#define OID_BLISS_PUBLICKEY					214
+#define OID_BLISS_I							216
+#define OID_BLISS_II						217
+#define OID_BLISS_III						218
+#define OID_BLISS_IV						219
+#define OID_BLISS_B_I						220
+#define OID_BLISS_B_II						221
+#define OID_BLISS_B_III						222
+#define OID_BLISS_B_IV						223
+#define OID_BLISS_WITH_SHA512				225
+#define OID_BLISS_WITH_SHA384				226
+#define OID_BLISS_WITH_SHA256				227
+#define OID_TCGID							234
+#define OID_BLOWFISH_CBC					238
+#define OID_AUTHORITY_INFO_ACCESS			282
+#define OID_IP_ADDR_BLOCKS					284
+#define OID_POLICY_QUALIFIER_CPS			286
+#define OID_POLICY_QUALIFIER_UNOTICE		287
+#define OID_SERVER_AUTH						289
+#define OID_CLIENT_AUTH						290
+#define OID_OCSP_SIGNING					297
+#define OID_XMPP_ADDR						303
+#define OID_AUTHENTICATION_INFO				307
+#define OID_ACCESS_IDENTITY					308
+#define OID_CHARGING_IDENTITY				309
+#define OID_GROUP							310
+#define OID_OCSP							313
+#define OID_BASIC							314
+#define OID_NONCE							315
+#define OID_CRL								316
+#define OID_RESPONSE						317
+#define OID_NO_CHECK						318
+#define OID_ARCHIVE_CUTOFF					319
+#define OID_SERVICE_LOCATOR					320
+#define OID_CA_ISSUERS						321
+#define OID_IKE_INTERMEDIATE				326
+#define OID_DES_CBC							330
+#define OID_SHA1							331
+#define OID_SHA1_WITH_RSA_OIW				332
+#define OID_ECGDSA_PUBKEY					351
+#define OID_ECGDSA_SIG_WITH_RIPEMD160		354
+#define OID_ECGDSA_SIG_WITH_SHA1			355
+#define OID_ECGDSA_SIG_WITH_SHA224			356
+#define OID_ECGDSA_SIG_WITH_SHA256			357
+#define OID_ECGDSA_SIG_WITH_SHA384			358
+#define OID_ECGDSA_SIG_WITH_SHA512			359
+#define OID_SECT163K1						382
+#define OID_SECT163R1						383
+#define OID_SECT239K1						384
+#define OID_SECT113R1						385
+#define OID_SECT113R2						386
+#define OID_SECT112R1						387
+#define OID_SECT112R2						388
+#define OID_SECT160R1						389
+#define OID_SECT160K1						390
+#define OID_SECT256K1						391
+#define OID_SECT163R2						392
+#define OID_SECT283K1						393
+#define OID_SECT283R1						394
+#define OID_SECT131R1						395
+#define OID_SECT131R2						396
+#define OID_SECT193R1						397
+#define OID_SECT193R2						398
+#define OID_SECT233K1						399
+#define OID_SECT233R1						400
+#define OID_SECT128R1						401
+#define OID_SECT128R2						402
+#define OID_SECT160R2						403
+#define OID_SECT192K1						404
+#define OID_SECT224K1						405
+#define OID_SECT224R1						406
+#define OID_SECT384R1						407
+#define OID_SECT521R1						408
+#define OID_SECT409K1						409
+#define OID_SECT409R1						410
+#define OID_SECT571K1						411
+#define OID_SECT571R1						412
+#define OID_AES128_CBC						421
+#define OID_AES128_GCM						422
+#define OID_AES128_CCM						423
+#define OID_AES192_CBC						424
+#define OID_AES192_GCM						425
+#define OID_AES192_CCM						426
+#define OID_AES256_CBC						427
+#define OID_AES256_GCM						428
+#define OID_AES256_CCM						429
+#define OID_SHA256							431
+#define OID_SHA384							432
+#define OID_SHA512							433
+#define OID_SHA224							434
+#define OID_NS_REVOCATION_URL				448
+#define OID_NS_CA_REVOCATION_URL			449
+#define OID_NS_CA_POLICY_URL				450
+#define OID_NS_COMMENT						451
+#define OID_EMPLOYEE_NUMBER					454
+#define OID_PKI_MESSAGE_TYPE				460
+#define OID_PKI_STATUS						461
+#define OID_PKI_FAIL_INFO					462
+#define OID_PKI_SENDER_NONCE				463
+#define OID_PKI_RECIPIENT_NONCE				464
+#define OID_PKI_TRANS_ID					465
+#define OID_TPM_MANUFACTURER				471
+#define OID_TPM_MODEL						472
+#define OID_TPM_VERSION						473
+#define OID_TPM_ID_LABEL					474
 
-#define OID_MAX								453
+#define OID_MAX								475
 
 #endif /* OID_H_ */
diff --git a/src/libstrongswan/asn1/oid.txt b/src/libstrongswan/asn1/oid.txt
index e545188..919d24c 100644
--- a/src/libstrongswan/asn1/oid.txt
+++ b/src/libstrongswan/asn1/oid.txt
@@ -208,6 +208,24 @@
             0xA0             ""
               0x2A           "ITA"
                 0x01         "strongSwan"				OID_STRONGSWAN
+                0x02         "cps"
+                0x03         "e-voting"
+                0x05         "BLISS"
+                  0x01       "keyType"
+                    0x01     "blissPublicKey"			OID_BLISS_PUBLICKEY
+                  0x02       "parameters"
+                    0x01     "BLISS-I"					OID_BLISS_I
+                    0x02     "BLISS-II"					OID_BLISS_II
+                    0x03     "BLISS-III"				OID_BLISS_III
+                    0x04     "BLISS-IV"					OID_BLISS_IV
+                    0x05     "BLISS-B-I"				OID_BLISS_B_I
+                    0x06     "BLISS-B-II"				OID_BLISS_B_II
+                    0x07     "BLISS-B-III"				OID_BLISS_B_III
+                    0x08     "BLISS-B-IV"				OID_BLISS_B_IV
+                  0x03       "blissSigType"
+                    0x01     "BLISS-with-SHA512"		OID_BLISS_WITH_SHA512
+                    0x02     "BLISS-with-SHA384"		OID_BLISS_WITH_SHA384
+                    0x03     "BLISS-with-SHA256"		OID_BLISS_WITH_SHA256
           0x89               ""
             0x31             ""
               0x01           ""
@@ -215,6 +233,10 @@
                   0x02       ""
                     0x02     ""
                       0x4B   "TCGID"					OID_TCGID
+          0x97               ""
+            0x55             ""
+              0x01           ""
+                0x02         "blowfish-cbc"				OID_BLOWFISH_CBC
           0xC1               ""
             0x16             "ntruCryptosystems"
               0x01           "eess"
diff --git a/src/libstrongswan/credentials/auth_cfg.c b/src/libstrongswan/credentials/auth_cfg.c
index db08c6b..0ca45a1 100644
--- a/src/libstrongswan/credentials/auth_cfg.c
+++ b/src/libstrongswan/credentials/auth_cfg.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2008-2012 Tobias Brunner
+ * Copyright (C) 2008-2015 Tobias Brunner
  * Copyright (C) 2007-2009 Martin Willi
  * Hochschule fuer Technik Rapperswil
  *
@@ -49,6 +49,7 @@ ENUM(auth_rule_names, AUTH_RULE_IDENTITY, AUTH_HELPER_AC_CERT,
 	"RULE_GROUP",
 	"RULE_RSA_STRENGTH",
 	"RULE_ECDSA_STRENGTH",
+	"RULE_BLISS_STRENGTH",
 	"RULE_SIGNATURE_SCHEME",
 	"RULE_CERT_POLICY",
 	"HELPER_IM_CERT",
@@ -71,6 +72,7 @@ static inline bool is_multi_value_rule(auth_rule_t type)
 		case AUTH_RULE_EAP_VENDOR:
 		case AUTH_RULE_RSA_STRENGTH:
 		case AUTH_RULE_ECDSA_STRENGTH:
+		case AUTH_RULE_BLISS_STRENGTH:
 		case AUTH_RULE_IDENTITY:
 		case AUTH_RULE_IDENTITY_LOOSE:
 		case AUTH_RULE_EAP_IDENTITY:
@@ -207,6 +209,7 @@ static void init_entry(entry_t *this, auth_rule_t type, va_list args)
 		case AUTH_RULE_OCSP_VALIDATION:
 		case AUTH_RULE_RSA_STRENGTH:
 		case AUTH_RULE_ECDSA_STRENGTH:
+		case AUTH_RULE_BLISS_STRENGTH:
 		case AUTH_RULE_SIGNATURE_SCHEME:
 			/* integer type */
 			this->value = (void*)(uintptr_t)va_arg(args, u_int);
@@ -255,6 +258,7 @@ static bool entry_equals(entry_t *e1, entry_t *e2)
 		case AUTH_RULE_OCSP_VALIDATION:
 		case AUTH_RULE_RSA_STRENGTH:
 		case AUTH_RULE_ECDSA_STRENGTH:
+		case AUTH_RULE_BLISS_STRENGTH:
 		case AUTH_RULE_SIGNATURE_SCHEME:
 		{
 			return e1->value == e2->value;
@@ -345,6 +349,7 @@ static void destroy_entry_value(entry_t *entry)
 		case AUTH_RULE_OCSP_VALIDATION:
 		case AUTH_RULE_RSA_STRENGTH:
 		case AUTH_RULE_ECDSA_STRENGTH:
+		case AUTH_RULE_BLISS_STRENGTH:
 		case AUTH_RULE_SIGNATURE_SCHEME:
 		case AUTH_RULE_MAX:
 			break;
@@ -376,6 +381,7 @@ static void replace(private_auth_cfg_t *this, entry_enumerator_t *enumerator,
 			case AUTH_RULE_OCSP_VALIDATION:
 			case AUTH_RULE_RSA_STRENGTH:
 			case AUTH_RULE_ECDSA_STRENGTH:
+			case AUTH_RULE_BLISS_STRENGTH:
 			case AUTH_RULE_SIGNATURE_SCHEME:
 				/* integer type */
 				entry->value = (void*)(uintptr_t)va_arg(args, u_int);
@@ -450,6 +456,7 @@ METHOD(auth_cfg_t, get, void*,
 		case AUTH_RULE_EAP_VENDOR:
 		case AUTH_RULE_RSA_STRENGTH:
 		case AUTH_RULE_ECDSA_STRENGTH:
+		case AUTH_RULE_BLISS_STRENGTH:
 			return (void*)0;
 		case AUTH_RULE_SIGNATURE_SCHEME:
 			return (void*)HASH_UNKNOWN;
@@ -513,6 +520,7 @@ METHOD(auth_cfg_t, complies, bool,
 	signature_scheme_t scheme = SIGN_UNKNOWN;
 	u_int strength = 0;
 	auth_rule_t t1, t2;
+	char *key_type;
 	void *value;
 
 	e1 = constraints->create_enumerator(constraints);
@@ -703,6 +711,7 @@ METHOD(auth_cfg_t, complies, bool,
 			}
 			case AUTH_RULE_RSA_STRENGTH:
 			case AUTH_RULE_ECDSA_STRENGTH:
+			case AUTH_RULE_BLISS_STRENGTH:
 			{
 				strength = (uintptr_t)value;
 				break;
@@ -797,30 +806,39 @@ METHOD(auth_cfg_t, complies, bool,
 		e2 = create_enumerator(this);
 		while (e2->enumerate(e2, &t2, &strength))
 		{
-			if (t2 == AUTH_RULE_RSA_STRENGTH ||
-				t2 == AUTH_RULE_ECDSA_STRENGTH)
+			switch (t2)
 			{
-				success = FALSE;
-				e1 = constraints->create_enumerator(constraints);
-				while (e1->enumerate(e1, &t1, &value))
+				default:
+					continue;
+				case AUTH_RULE_RSA_STRENGTH:
+					key_type = "RSA";
+					break;
+				case AUTH_RULE_ECDSA_STRENGTH:
+					key_type = "ECDSA";
+					break;
+				case AUTH_RULE_BLISS_STRENGTH:
+					key_type = "BLISS";
+					break;
+			}
+			success = FALSE;
+			e1 = constraints->create_enumerator(constraints);
+			while (e1->enumerate(e1, &t1, &value))
+			{
+				if (t1 == t2 && (uintptr_t)value <= strength)
 				{
-					if (t1 == t2 && (uintptr_t)value <= strength)
-					{
-						success = TRUE;
-						break;
-					}
+					success = TRUE;
+					break;
 				}
-				e1->destroy(e1);
-				if (!success)
+			}
+			e1->destroy(e1);
+			if (!success)
+			{
+				if (log_error)
 				{
-					if (log_error)
-					{
-						DBG1(DBG_CFG, "%s-%d signatures not acceptable",
-							 t2 == AUTH_RULE_RSA_STRENGTH ? "RSA" : "ECDSA",
-							 strength);
-					}
-					break;
+					DBG1(DBG_CFG, "%s-%d signatures not acceptable",
+						 key_type, strength);
 				}
+				break;
 			}
 		}
 		e2->destroy(e2);
@@ -891,6 +909,7 @@ static void merge(private_auth_cfg_t *this, private_auth_cfg_t *other, bool copy
 				case AUTH_RULE_EAP_VENDOR:
 				case AUTH_RULE_RSA_STRENGTH:
 				case AUTH_RULE_ECDSA_STRENGTH:
+				case AUTH_RULE_BLISS_STRENGTH:
 				case AUTH_RULE_SIGNATURE_SCHEME:
 				{
 					add(this, type, (uintptr_t)value);
@@ -1060,6 +1079,7 @@ METHOD(auth_cfg_t, clone_, auth_cfg_t*,
 			case AUTH_RULE_OCSP_VALIDATION:
 			case AUTH_RULE_RSA_STRENGTH:
 			case AUTH_RULE_ECDSA_STRENGTH:
+			case AUTH_RULE_BLISS_STRENGTH:
 			case AUTH_RULE_SIGNATURE_SCHEME:
 				clone->add(clone, type, (uintptr_t)value);
 				break;
diff --git a/src/libstrongswan/credentials/auth_cfg.h b/src/libstrongswan/credentials/auth_cfg.h
index 95b36d7..53f1b38 100644
--- a/src/libstrongswan/credentials/auth_cfg.h
+++ b/src/libstrongswan/credentials/auth_cfg.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2008-2012 Tobias Brunner
+ * Copyright (C) 2008-2015 Tobias Brunner
  * Copyright (C) 2007-2009 Martin Willi
  * Hochschule fuer Technik Rapperswil
  *
@@ -102,6 +102,8 @@ enum auth_rule_t {
 	AUTH_RULE_RSA_STRENGTH,
 	/** required ECDSA public key strength, u_int in bits */
 	AUTH_RULE_ECDSA_STRENGTH,
+	/** required BLISS public key strength, u_int in bits */
+	AUTH_RULE_BLISS_STRENGTH,
 	/** required signature scheme, signature_scheme_t */
 	AUTH_RULE_SIGNATURE_SCHEME,
 	/** certificatePolicy constraint, numerical OID as char* */
diff --git a/src/libstrongswan/credentials/cred_encoding.h b/src/libstrongswan/credentials/cred_encoding.h
index a6c9c30..b4d1f4c 100644
--- a/src/libstrongswan/credentials/cred_encoding.h
+++ b/src/libstrongswan/credentials/cred_encoding.h
@@ -144,6 +144,10 @@ enum cred_encoding_part_t {
 	CRED_PART_PKCS10_ASN1_DER,
 	/** a PGP encoded certificate */
 	CRED_PART_PGP_CERT,
+	/** a DER encoded BLISS public key */
+	CRED_PART_BLISS_PUB_ASN1_DER,
+	/** a DER encoded BLISS private key */
+	CRED_PART_BLISS_PRIV_ASN1_DER,
 
 	CRED_PART_END,
 };
diff --git a/src/libstrongswan/credentials/credential_manager.c b/src/libstrongswan/credentials/credential_manager.c
index b0c8e48..371e640 100644
--- a/src/libstrongswan/credentials/credential_manager.c
+++ b/src/libstrongswan/credentials/credential_manager.c
@@ -698,6 +698,9 @@ static void get_key_strength(certificate_t *cert, auth_cfg_t *auth)
 			case KEY_ECDSA:
 				auth->add(auth, AUTH_RULE_ECDSA_STRENGTH, strength);
 				break;
+			case KEY_BLISS:
+				auth->add(auth, AUTH_RULE_BLISS_STRENGTH, strength);
+				break;
 			default:
 				break;
 		}
diff --git a/src/libstrongswan/credentials/keys/public_key.c b/src/libstrongswan/credentials/keys/public_key.c
index 37bba77..bd5915e 100644
--- a/src/libstrongswan/credentials/keys/public_key.c
+++ b/src/libstrongswan/credentials/keys/public_key.c
@@ -1,6 +1,8 @@
 /*
+ * Copyright (C) 2015 Tobias Brunner
  * Copyright (C) 2007 Martin Willi
- * Hochschule fuer Technik Rapperswil
+ * 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
@@ -17,14 +19,15 @@
 
 #include "public_key.h"
 
-ENUM(key_type_names, KEY_ANY, KEY_DSA,
+ENUM(key_type_names, KEY_ANY, KEY_BLISS,
 	"ANY",
 	"RSA",
 	"ECDSA",
-	"DSA"
+	"DSA",
+	"BLISS"
 );
 
-ENUM(signature_scheme_names, SIGN_UNKNOWN, SIGN_ECDSA_521,
+ENUM(signature_scheme_names, SIGN_UNKNOWN, SIGN_BLISS_WITH_SHA512,
 	"UNKNOWN",
 	"RSA_EMSA_PKCS1_NULL",
 	"RSA_EMSA_PKCS1_MD5",
@@ -41,6 +44,9 @@ ENUM(signature_scheme_names, SIGN_UNKNOWN, SIGN_ECDSA_521,
 	"ECDSA-256",
 	"ECDSA-384",
 	"ECDSA-521",
+	"BLISS_WITH_SHA256",
+	"BLISS_WITH_SHA384",
+	"BLISS_WITH_SHA512",
 );
 
 ENUM(encryption_scheme_names, ENCRYPT_UNKNOWN, ENCRYPT_RSA_OAEP_SHA512,
@@ -130,8 +136,158 @@ signature_scheme_t signature_scheme_from_oid(int oid)
 			return SIGN_ECDSA_WITH_SHA384_DER;
 		case OID_ECDSA_WITH_SHA512:
 			return SIGN_ECDSA_WITH_SHA512_DER;
-		default:
-			return SIGN_UNKNOWN;
+		case OID_BLISS_PUBLICKEY:
+		case OID_BLISS_WITH_SHA512:
+			return SIGN_BLISS_WITH_SHA512;
+		case OID_BLISS_WITH_SHA256:
+			return SIGN_BLISS_WITH_SHA256;
+		case OID_BLISS_WITH_SHA384:
+			return SIGN_BLISS_WITH_SHA384;
 	}
+	return SIGN_UNKNOWN;
 }
 
+/*
+ * Defined in header.
+ */
+int signature_scheme_to_oid(signature_scheme_t scheme)
+{
+	switch (scheme)
+	{
+		case SIGN_UNKNOWN:
+		case SIGN_RSA_EMSA_PKCS1_NULL:
+		case SIGN_ECDSA_WITH_NULL:
+		case SIGN_ECDSA_256:
+		case SIGN_ECDSA_384:
+		case SIGN_ECDSA_521:
+			break;
+		case SIGN_RSA_EMSA_PKCS1_MD5:
+			return OID_MD5_WITH_RSA;
+		case SIGN_RSA_EMSA_PKCS1_SHA1:
+			return OID_SHA1_WITH_RSA;
+		case SIGN_RSA_EMSA_PKCS1_SHA224:
+			return OID_SHA224_WITH_RSA;
+		case SIGN_RSA_EMSA_PKCS1_SHA256:
+			return OID_SHA256_WITH_RSA;
+		case SIGN_RSA_EMSA_PKCS1_SHA384:
+			return OID_SHA384_WITH_RSA;
+		case SIGN_RSA_EMSA_PKCS1_SHA512:
+			return OID_SHA512_WITH_RSA;
+		case SIGN_ECDSA_WITH_SHA1_DER:
+			return OID_ECDSA_WITH_SHA1;
+		case SIGN_ECDSA_WITH_SHA256_DER:
+			return OID_ECDSA_WITH_SHA256;
+		case SIGN_ECDSA_WITH_SHA384_DER:
+			return OID_ECDSA_WITH_SHA384;
+		case SIGN_ECDSA_WITH_SHA512_DER:
+			return OID_ECDSA_WITH_SHA512;
+		case SIGN_BLISS_WITH_SHA256:
+			return OID_BLISS_WITH_SHA256;
+		case SIGN_BLISS_WITH_SHA384:
+			return OID_BLISS_WITH_SHA384;
+		case SIGN_BLISS_WITH_SHA512:
+			return OID_BLISS_WITH_SHA512;
+	}
+	return OID_UNKNOWN;
+}
+
+/**
+ * Map for signature schemes to the key type and maximum key size allowed.
+ * We only cover schemes with hash algorithms supported by IKEv2 signature
+ * authentication.
+ */
+static struct {
+	signature_scheme_t scheme;
+	key_type_t type;
+	int max_keysize;
+} scheme_map[] = {
+	{ SIGN_RSA_EMSA_PKCS1_SHA256, KEY_RSA,   3072 },
+	{ SIGN_RSA_EMSA_PKCS1_SHA384, KEY_RSA,   7680 },
+	{ SIGN_RSA_EMSA_PKCS1_SHA512, KEY_RSA,   0 },
+	{ SIGN_ECDSA_WITH_SHA256_DER, KEY_ECDSA, 256 },
+	{ SIGN_ECDSA_WITH_SHA384_DER, KEY_ECDSA, 384 },
+	{ SIGN_ECDSA_WITH_SHA512_DER, KEY_ECDSA, 0 },
+	{ SIGN_BLISS_WITH_SHA256,     KEY_BLISS, 128 },
+	{ SIGN_BLISS_WITH_SHA384,     KEY_BLISS, 192 },
+	{ SIGN_BLISS_WITH_SHA512,     KEY_BLISS, 0 },
+};
+
+/**
+ * Private data for signature scheme enumerator
+ */
+typedef struct  {
+	enumerator_t public;
+	int index;
+	key_type_t type;
+	int size;
+} private_enumerator_t;
+
+METHOD(enumerator_t, signature_schemes_enumerate, bool,
+	private_enumerator_t *this, signature_scheme_t *scheme)
+{
+	while (++this->index < countof(scheme_map))
+	{
+		if (this->type == scheme_map[this->index].type &&
+		   (this->size <= scheme_map[this->index].max_keysize ||
+			!scheme_map[this->index].max_keysize))
+		{
+			*scheme = scheme_map[this->index].scheme;
+			return TRUE;
+		}
+	}
+	return FALSE;
+}
+
+/*
+ * Defined in header.
+ */
+enumerator_t *signature_schemes_for_key(key_type_t type, int size)
+{
+	private_enumerator_t *this;
+
+	INIT(this,
+		.public = {
+			.enumerate = (void*)_signature_schemes_enumerate,
+			.destroy = (void*)free,
+		},
+		.index = -1,
+		.type = type,
+		.size = size,
+	);
+
+	return &this->public;
+}
+
+/*
+ * Defined in header.
+ */
+key_type_t key_type_from_signature_scheme(signature_scheme_t scheme)
+{
+	switch (scheme)
+	{
+		case SIGN_UNKNOWN:
+			break;
+		case SIGN_RSA_EMSA_PKCS1_NULL:
+		case SIGN_RSA_EMSA_PKCS1_MD5:
+		case SIGN_RSA_EMSA_PKCS1_SHA1:
+		case SIGN_RSA_EMSA_PKCS1_SHA224:
+		case SIGN_RSA_EMSA_PKCS1_SHA256:
+		case SIGN_RSA_EMSA_PKCS1_SHA384:
+		case SIGN_RSA_EMSA_PKCS1_SHA512:
+			return KEY_RSA;
+		case SIGN_ECDSA_WITH_SHA1_DER:
+		case SIGN_ECDSA_WITH_SHA256_DER:
+		case SIGN_ECDSA_WITH_SHA384_DER:
+		case SIGN_ECDSA_WITH_SHA512_DER:
+		case SIGN_ECDSA_WITH_NULL:
+		case SIGN_ECDSA_256:
+		case SIGN_ECDSA_384:
+		case SIGN_ECDSA_521:
+			return KEY_ECDSA;
+		case SIGN_BLISS_WITH_SHA256:
+		case SIGN_BLISS_WITH_SHA384:
+		case SIGN_BLISS_WITH_SHA512:
+			return KEY_BLISS;
+	}
+	return KEY_ANY;
+}
diff --git a/src/libstrongswan/credentials/keys/public_key.h b/src/libstrongswan/credentials/keys/public_key.h
index 2afcf83..66e98b2 100644
--- a/src/libstrongswan/credentials/keys/public_key.h
+++ b/src/libstrongswan/credentials/keys/public_key.h
@@ -1,6 +1,8 @@
 /*
+ * Copyright (C) 2015 Tobias Brunner
  * Copyright (C) 2007 Martin Willi
- * Hochschule fuer Technik Rapperswil
+ * 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
@@ -42,6 +44,8 @@ enum key_type_t {
 	KEY_ECDSA = 2,
 	/** DSA */
 	KEY_DSA   = 3,
+	/** BLISS */
+	KEY_BLISS = 4,
 	/** ElGamal, ... */
 };
 
@@ -90,6 +94,12 @@ enum signature_scheme_t {
 	SIGN_ECDSA_384,
 	/** ECDSA on the P-521 curve with SHA-512 as in RFC 4754           */
 	SIGN_ECDSA_521,
+	/** BLISS with SHA-256                                             */
+	SIGN_BLISS_WITH_SHA256,
+	/** BLISS with SHA-384                                             */
+	SIGN_BLISS_WITH_SHA384,
+	/** BLISS with SHA-512                                             */
+	SIGN_BLISS_WITH_SHA512,
 };
 
 /**
@@ -234,8 +244,35 @@ bool public_key_has_fingerprint(public_key_t *public, chunk_t fingerprint);
  * Conversion of ASN.1 signature or hash OID to signature scheme.
  *
  * @param oid			ASN.1 OID
- * @return				signature_scheme, SIGN_UNKNOWN if OID is unsupported
+ * @return				signature scheme, SIGN_UNKNOWN if OID is unsupported
  */
 signature_scheme_t signature_scheme_from_oid(int oid);
 
+/**
+ * Conversion of signature scheme to ASN.1 signature OID.
+ *
+ * @param scheme		signature scheme
+ * @return				ASN.1 OID, OID_UNKNOWN if not supported
+ */
+int signature_scheme_to_oid(signature_scheme_t scheme);
+
+/**
+ * Enumerate signature schemes that are appropriate for a key of the given type
+ * and size|strength.
+ *
+ * @param type			type of the key
+ * @param size			size or strength of the key
+ * @return				enumerator over signature_scheme_t (increasing strength)
+ */
+enumerator_t *signature_schemes_for_key(key_type_t type, int size);
+
+/**
+ * Determine the type of key associated with a given signature scheme.
+ *
+ * @param scheme		signature scheme
+ * @return				key type (could be KEY_ANY)
+ */
+key_type_t key_type_from_signature_scheme(signature_scheme_t scheme);
+
+
 #endif /** PUBLIC_KEY_H_ @}*/
diff --git a/src/libstrongswan/credentials/sets/cert_cache.c b/src/libstrongswan/credentials/sets/cert_cache.c
index 563f4bd..60720dc 100644
--- a/src/libstrongswan/credentials/sets/cert_cache.c
+++ b/src/libstrongswan/credentials/sets/cert_cache.c
@@ -143,6 +143,7 @@ METHOD(cert_cache_t, issued_by, bool,
 	private_cert_cache_t *this, certificate_t *subject, certificate_t *issuer,
 	signature_scheme_t *schemep)
 {
+	certificate_t *cached_issuer = NULL;
 	relation_t *found = NULL, *current;
 	signature_scheme_t scheme;
 	int i;
@@ -154,39 +155,41 @@ METHOD(cert_cache_t, issued_by, bool,
 		current->lock->read_lock(current->lock);
 		if (current->subject)
 		{
-			/* check for equal issuer */
 			if (issuer->equals(issuer, current->issuer))
 			{
-				/* reuse issuer instance in cache() */
-				issuer = current->issuer;
 				if (subject->equals(subject, current->subject))
 				{
-					/* write hit counter is not locked, but not critical */
 					current->hits++;
-					found = current;;
+					found = current;
 					if (schemep)
 					{
 						*schemep = current->scheme;
 					}
 				}
+				else if (!cached_issuer)
+				{
+					cached_issuer = current->issuer->get_ref(current->issuer);
+				}
 			}
 		}
 		current->lock->unlock(current->lock);
 		if (found)
 		{
+			DESTROY_IF(cached_issuer);
 			return TRUE;
 		}
 	}
-	/* no cache hit, check and cache signature */
 	if (subject->issued_by(subject, issuer, &scheme))
 	{
-		cache(this, subject, issuer, scheme);
+		cache(this, subject, cached_issuer ?: issuer, scheme);
 		if (schemep)
 		{
 			*schemep = scheme;
 		}
+		DESTROY_IF(cached_issuer);
 		return TRUE;
 	}
+	DESTROY_IF(cached_issuer);
 	return FALSE;
 }
 
diff --git a/src/libstrongswan/credentials/sets/mem_cred.c b/src/libstrongswan/credentials/sets/mem_cred.c
index d8f568d..7ad011b 100644
--- a/src/libstrongswan/credentials/sets/mem_cred.c
+++ b/src/libstrongswan/credentials/sets/mem_cred.c
@@ -192,6 +192,24 @@ METHOD(mem_cred_t, add_cert_ref, certificate_t*,
 	return add_cert_internal(this, trusted, cert);
 }
 
+METHOD(mem_cred_t, get_cert_ref, certificate_t*,
+	private_mem_cred_t *this, certificate_t *cert)
+{
+	certificate_t *cached;
+
+	this->lock->write_lock(this->lock);
+	if (this->untrusted->find_first(this->untrusted,
+									(linked_list_match_t)certificate_equals,
+									(void**)&cached, cert) == SUCCESS)
+	{
+		cert->destroy(cert);
+		cert = cached->get_ref(cached);
+	}
+	this->lock->unlock(this->lock);
+
+	return cert;
+}
+
 METHOD(mem_cred_t, add_crl, bool,
 	private_mem_cred_t *this, crl_t *crl)
 {
@@ -736,6 +754,7 @@ mem_cred_t *mem_cred_create()
 			},
 			.add_cert = _add_cert,
 			.add_cert_ref = _add_cert_ref,
+			.get_cert_ref = _get_cert_ref,
 			.add_crl = _add_crl,
 			.add_key = _add_key,
 			.add_shared = _add_shared,
diff --git a/src/libstrongswan/credentials/sets/mem_cred.h b/src/libstrongswan/credentials/sets/mem_cred.h
index d0dd51d..3ce815a 100644
--- a/src/libstrongswan/credentials/sets/mem_cred.h
+++ b/src/libstrongswan/credentials/sets/mem_cred.h
@@ -59,6 +59,18 @@ struct mem_cred_t {
 								   certificate_t *cert);
 
 	/**
+	 * Get an existing reference to the same certificate.
+	 *
+	 * Searches for the same certficate in the set, and returns a reference
+	 * to it, destroying the passed certificate. If the passed certificate
+	 * is not found, it is just returned.
+	 *
+	 * @param cert			certificate to look up
+	 * @return				the same certificate, potentially different instance
+	 */
+	certificate_t* (*get_cert_ref)(mem_cred_t *this, certificate_t *cert);
+
+	/**
 	 * Add an X.509 CRL to the credential set.
 	 *
 	 * @param crl			CRL, gets owned by set
diff --git a/src/libstrongswan/crypto/crypters/crypter.c b/src/libstrongswan/crypto/crypters/crypter.c
index 8123add..1e73baa 100644
--- a/src/libstrongswan/crypto/crypters/crypter.c
+++ b/src/libstrongswan/crypto/crypters/crypter.c
@@ -96,6 +96,10 @@ encryption_algorithm_t encryption_algorithm_from_oid(int oid, size_t *key_size)
 			alg = ENCR_CAMELLIA_CBC;
 			alg_key_size = 256;
 			break;
+		case OID_BLOWFISH_CBC:
+			alg = ENCR_BLOWFISH;
+			alg_key_size = 0;
+			break;
 		default:
 			alg = ENCR_UNDEFINED;
 			alg_key_size = 0;
@@ -154,6 +158,9 @@ int encryption_algorithm_to_oid(encryption_algorithm_t alg, size_t key_size)
 					oid = OID_UNKNOWN;
 			}
 			break;
+		case ENCR_BLOWFISH:
+			oid = OID_BLOWFISH_CBC;
+			break;
 		default:
 			oid = OID_UNKNOWN;
 	}
diff --git a/src/libstrongswan/crypto/crypto_tester.c b/src/libstrongswan/crypto/crypto_tester.c
index d09844b..15ed173 100644
--- a/src/libstrongswan/crypto/crypto_tester.c
+++ b/src/libstrongswan/crypto/crypto_tester.c
@@ -580,13 +580,22 @@ METHOD(crypto_tester_t, test_signer, bool,
 			break;
 		}
 
+		data = chunk_create(vector->data, vector->len);
 		key = chunk_create(vector->key, signer->get_key_size(signer));
 		if (!signer->set_key(signer, key))
 		{
 			goto failure;
 		}
+		/* do partial append mode and check if key gets set correctly */
+		if (!signer->get_signature(signer, data, NULL))
+		{
+			goto failure;
+		}
+		if (!signer->set_key(signer, key))
+		{
+			goto failure;
+		}
 		/* allocated signature */
-		data = chunk_create(vector->data, vector->len);
 		if (!signer->allocate_signature(signer, data, &mac))
 		{
 			goto failure;
@@ -905,13 +914,25 @@ METHOD(crypto_tester_t, test_prf, bool,
 			break;
 		}
 
+		seed = chunk_create(vector->seed, vector->len);
 		key = chunk_create(vector->key, vector->key_size);
 		if (!prf->set_key(prf, key))
 		{
 			goto failure;
 		}
+		if (alg != PRF_FIPS_SHA1_160)
+		{
+			/* do partial append mode and check if key gets set correctly */
+			if (!prf->get_bytes(prf, seed, NULL))
+			{
+				goto failure;
+			}
+			if (!prf->set_key(prf, key))
+			{
+				goto failure;
+			}
+		}
 		/* allocated bytes */
-		seed = chunk_create(vector->seed, vector->len);
 		if (!prf->allocate_bytes(prf, seed, &out))
 		{
 			goto failure;
@@ -942,7 +963,7 @@ METHOD(crypto_tester_t, test_prf, bool,
 			goto failure;
 		}
 		/* bytes to existing buffer, using append mode */
-		if (seed.len > 2)
+		if (alg != PRF_FIPS_SHA1_160 && seed.len > 2)
 		{
 			memset(out.ptr, 0, out.len);
 			if (vector->stateful)
diff --git a/src/libstrongswan/crypto/diffie_hellman.c b/src/libstrongswan/crypto/diffie_hellman.c
index 87c9b21..0d4cd91 100644
--- a/src/libstrongswan/crypto/diffie_hellman.c
+++ b/src/libstrongswan/crypto/diffie_hellman.c
@@ -42,15 +42,16 @@ ENUM_NEXT(diffie_hellman_group_names, MODP_1024_160, ECP_512_BP, ECP_521_BIT,
 	"ECP_256_BP",
 	"ECP_384_BP",
 	"ECP_512_BP");
-ENUM_NEXT(diffie_hellman_group_names, MODP_NULL, MODP_CUSTOM, ECP_512_BP,
-	"MODP_NULL",
-	"MODP_CUSTOM");
-ENUM_NEXT(diffie_hellman_group_names, NTRU_112_BIT, NTRU_256_BIT, MODP_CUSTOM,
+ENUM_NEXT(diffie_hellman_group_names, MODP_NULL, MODP_NULL, ECP_512_BP,
+	"MODP_NULL");
+ENUM_NEXT(diffie_hellman_group_names, NTRU_112_BIT, NTRU_256_BIT, MODP_NULL,
 	"NTRU_112",
 	"NTRU_128",
 	"NTRU_192",
 	"NTRU_256");
-ENUM_END(diffie_hellman_group_names, NTRU_256_BIT);
+ENUM_NEXT(diffie_hellman_group_names, MODP_CUSTOM, MODP_CUSTOM, NTRU_256_BIT,
+	"MODP_CUSTOM");
+ENUM_END(diffie_hellman_group_names, MODP_CUSTOM);
 
 
 /**
@@ -439,7 +440,7 @@ void diffie_hellman_init()
 {
 	int i;
 
-	if (lib->settings->get_int(lib->settings,
+	if (lib->settings->get_bool(lib->settings,
 					"%s.dh_exponent_ansi_x9_42", TRUE, lib->ns))
 	{
 		for (i = 0; i < countof(dh_params); i++)
@@ -463,7 +464,7 @@ diffie_hellman_params_t *diffie_hellman_get_params(diffie_hellman_group_t group)
 			if (!dh_params[i].public.exp_len)
 			{
 				if (!dh_params[i].public.subgroup.len &&
-					lib->settings->get_int(lib->settings,
+					lib->settings->get_bool(lib->settings,
 									"%s.dh_exponent_ansi_x9_42", TRUE, lib->ns))
 				{
 					dh_params[i].public.exp_len = dh_params[i].public.prime.len;
@@ -500,3 +501,75 @@ bool diffie_hellman_group_is_ec(diffie_hellman_group_t group)
 			return FALSE;
 	}
 }
+
+/**
+ * See header.
+ */
+bool diffie_hellman_verify_value(diffie_hellman_group_t group, chunk_t value)
+{
+	diffie_hellman_params_t *params;
+	bool valid = FALSE;
+
+	switch (group)
+	{
+		case MODP_768_BIT:
+		case MODP_1024_BIT:
+		case MODP_1536_BIT:
+		case MODP_2048_BIT:
+		case MODP_3072_BIT:
+		case MODP_4096_BIT:
+		case MODP_6144_BIT:
+		case MODP_8192_BIT:
+		case MODP_1024_160:
+		case MODP_2048_224:
+		case MODP_2048_256:
+			params = diffie_hellman_get_params(group);
+			if (params)
+			{
+				valid = value.len == params->prime.len;
+			}
+			break;
+		case ECP_192_BIT:
+			valid = value.len == 48;
+			break;
+		case ECP_224_BIT:
+		case ECP_224_BP:
+			valid = value.len == 56;
+			break;
+		case ECP_256_BIT:
+		case ECP_256_BP:
+			valid = value.len == 64;
+			break;
+		case ECP_384_BIT:
+		case ECP_384_BP:
+			valid = value.len == 96;
+			break;
+		case ECP_512_BP:
+			valid = value.len == 128;
+			break;
+		case ECP_521_BIT:
+			valid = value.len == 132;
+			break;
+		case NTRU_112_BIT:
+		case NTRU_128_BIT:
+		case NTRU_192_BIT:
+		case NTRU_256_BIT:
+			/* verification currently not supported, do in plugin */
+			valid = FALSE;
+			break;
+		case MODP_NULL:
+		case MODP_CUSTOM:
+			valid = TRUE;
+			break;
+		case MODP_NONE:
+			/* fail */
+			break;
+		/* compile-warn unhandled groups, fail verification */
+	}
+	if (!valid)
+	{
+		DBG1(DBG_ENC, "invalid DH public value size (%zu bytes) for %N",
+			 value.len, diffie_hellman_group_names, group);
+	}
+	return valid;
+}
diff --git a/src/libstrongswan/crypto/diffie_hellman.h b/src/libstrongswan/crypto/diffie_hellman.h
index 105db22..4704cd0 100644
--- a/src/libstrongswan/crypto/diffie_hellman.h
+++ b/src/libstrongswan/crypto/diffie_hellman.h
@@ -63,12 +63,14 @@ enum diffie_hellman_group_t {
 	/** insecure NULL diffie hellman group for testing, in PRIVATE USE */
 	MODP_NULL = 1024,
 	/** MODP group with custom generator/prime */
-	MODP_CUSTOM = 1025,
 	/** Parameters defined by IEEE 1363.1, in PRIVATE USE */
 	NTRU_112_BIT = 1030,
 	NTRU_128_BIT = 1031,
 	NTRU_192_BIT = 1032,
-	NTRU_256_BIT = 1033
+	NTRU_256_BIT = 1033,
+	/** internally used DH group with additional parameters g and p, outside
+	 * of PRIVATE USE (i.e. IKEv2 DH group range) so it can't be negotiated */
+	MODP_CUSTOM = 65536,
 };
 
 /**
@@ -87,9 +89,10 @@ struct diffie_hellman_t {
 	 * Space for returned secret is allocated and must be freed by the caller.
 	 *
 	 * @param secret	shared secret will be written into this chunk
-	 * @return			SUCCESS, FAILED if not both DH values are set
+	 * @return			TRUE if shared secret computed successfully
 	 */
-	status_t (*get_shared_secret) (diffie_hellman_t *this, chunk_t *secret);
+	bool (*get_shared_secret)(diffie_hellman_t *this, chunk_t *secret)
+		__attribute__((warn_unused_result));
 
 	/**
 	 * Sets the public value of partner.
@@ -97,8 +100,10 @@ struct diffie_hellman_t {
 	 * Chunk gets cloned and can be destroyed afterwards.
 	 *
 	 * @param value		public value of partner
+	 * @return			TRUE if other public value verified and set
 	 */
-	void (*set_other_public_value) (diffie_hellman_t *this, chunk_t value);
+	bool (*set_other_public_value)(diffie_hellman_t *this, chunk_t value)
+		__attribute__((warn_unused_result));
 
 	/**
 	 * Gets the own public value to transmit.
@@ -106,8 +111,10 @@ struct diffie_hellman_t {
 	 * Space for returned chunk is allocated and must be freed by the caller.
 	 *
 	 * @param value		public value of caller is stored at this location
+	 * @return			TRUE if public value retrieved
 	 */
-	void (*get_my_public_value) (diffie_hellman_t *this, chunk_t *value);
+	bool (*get_my_public_value) (diffie_hellman_t *this, chunk_t *value)
+		__attribute__((warn_unused_result));
 
 	/**
 	 * Get the DH group used.
@@ -168,8 +175,17 @@ diffie_hellman_params_t *diffie_hellman_get_params(diffie_hellman_group_t group)
  * Check if a given DH group is an ECDH group
  *
  * @param group			group to check
- * @return				TUE if group is an ECP group
+ * @return				TRUE if group is an ECP group
  */
 bool diffie_hellman_group_is_ec(diffie_hellman_group_t group);
 
+/**
+ * Check if a diffie hellman public value is valid for given group.
+ *
+ * @param group			group the value is used in
+ * @param value			public DH value to check
+ * @return				TRUE if value looks valid for group
+ */
+bool diffie_hellman_verify_value(diffie_hellman_group_t group, chunk_t value);
+
 #endif /** DIFFIE_HELLMAN_H_ @}*/
diff --git a/src/libstrongswan/crypto/hashers/hash_algorithm_set.c b/src/libstrongswan/crypto/hashers/hash_algorithm_set.c
new file mode 100644
index 0000000..93b67cb
--- /dev/null
+++ b/src/libstrongswan/crypto/hashers/hash_algorithm_set.c
@@ -0,0 +1,113 @@
+/*
+ * Copyright (C) 2015 Tobias Brunner
+ * Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * for more details.
+ */
+
+#include "hash_algorithm_set.h"
+
+#include <collections/array.h>
+
+typedef struct private_hash_algorithm_set_t private_hash_algorithm_set_t;
+
+struct private_hash_algorithm_set_t {
+
+	/**
+	 * Public interface
+	 */
+	hash_algorithm_set_t public;
+
+	/**
+	 * Algorithms contained in the set
+	 */
+	array_t *algorithms;
+};
+
+/**
+ * Sort hash algorithms
+ */
+static int hash_sort(const void *a, const void *b, void *user)
+{
+	const hash_algorithm_t *ha = a, *hb = b;
+	return *ha - *hb;
+}
+
+/**
+ * Find a hash algorithm
+ */
+static int hash_find(const void *a, const void *b)
+{
+	return hash_sort(a, b, NULL);
+}
+
+METHOD(hash_algorithm_set_t, contains, bool,
+	private_hash_algorithm_set_t *this, hash_algorithm_t hash)
+{
+	return array_bsearch(this->algorithms, &hash, hash_find, NULL) != -1;
+}
+
+METHOD(hash_algorithm_set_t, add, void,
+	private_hash_algorithm_set_t *this, hash_algorithm_t hash)
+{
+	if (!contains(this, hash))
+	{
+		array_insert(this->algorithms, ARRAY_TAIL, &hash);
+		array_sort(this->algorithms, hash_sort, NULL);
+	}
+}
+
+METHOD(hash_algorithm_set_t, count, int,
+	private_hash_algorithm_set_t *this)
+{
+	return array_count(this->algorithms);
+}
+
+static bool hash_filter(void *data, void **in, hash_algorithm_t *out)
+{
+	*out = **(hash_algorithm_t**)in;
+	return TRUE;
+}
+
+METHOD(hash_algorithm_set_t, create_enumerator, enumerator_t*,
+	private_hash_algorithm_set_t *this)
+{
+	return enumerator_create_filter(array_create_enumerator(this->algorithms),
+									(void*)hash_filter, NULL, NULL);
+}
+
+METHOD(hash_algorithm_set_t, destroy, void,
+	private_hash_algorithm_set_t *this)
+{
+	array_destroy(this->algorithms);
+	free(this);
+}
+
+/**
+ * Described in header
+ */
+hash_algorithm_set_t *hash_algorithm_set_create()
+{
+	private_hash_algorithm_set_t *this;
+
+	INIT(this,
+		.public = {
+			.add = _add,
+			.contains = _contains,
+			.count = _count,
+			.create_enumerator = _create_enumerator,
+			.destroy = _destroy,
+		},
+		.algorithms = array_create(sizeof(hash_algorithm_t), 0),
+	);
+
+	return &this->public;
+}
\ No newline at end of file
diff --git a/src/libstrongswan/crypto/hashers/hash_algorithm_set.h b/src/libstrongswan/crypto/hashers/hash_algorithm_set.h
new file mode 100644
index 0000000..00e90cc
--- /dev/null
+++ b/src/libstrongswan/crypto/hashers/hash_algorithm_set.h
@@ -0,0 +1,76 @@
+/*
+ * Copyright (C) 2015 Tobias Brunner
+ * Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * for more details.
+ */
+
+/**
+ * @defgroup hash_algorithm_set hash_algorithm_set
+ * @{ @ingroup crypto
+ */
+
+#ifndef HASH_ALGORITHM_SET_H_
+#define HASH_ALGORITHM_SET_H_
+
+typedef struct hash_algorithm_set_t hash_algorithm_set_t;
+
+#include <library.h>
+#include <crypto/hashers/hasher.h>
+
+/**
+ * A set of hash algorithms
+ */
+struct hash_algorithm_set_t {
+
+	/**
+	 * Add the given algorithm to the set.
+	 *
+	 * @param alg		hash algorithm
+	 */
+	void (*add)(hash_algorithm_set_t *this, hash_algorithm_t alg);
+
+	/**
+	 * Check if the given algorithm is contained in the set.
+	 *
+	 * @param alg		hash algorithm
+	 * @return			TRUE if contained in set
+	 */
+	bool (*contains)(hash_algorithm_set_t *this, hash_algorithm_t alg);
+
+	/**
+	 * Number of hash algorithms contained in the set.
+	 *
+	 * @return			number of algorithms
+	 */
+	int (*count)(hash_algorithm_set_t *this);
+
+	/**
+	 * Enumerate the algorithms contained in the set.
+	 *
+	 * @return			enumerator over hash_algorithm_t (sorted by identifier)
+	 */
+	enumerator_t *(*create_enumerator)(hash_algorithm_set_t *this);
+
+	/**
+	 * Destroy a hash_algorithm_set_t instance
+	 */
+	void (*destroy)(hash_algorithm_set_t *this);
+};
+
+/**
+ * Create a set of hash algorithms.
+ *
+ * @return				hash_algorithm_set_t instance
+ */
+hash_algorithm_set_t *hash_algorithm_set_create();
+
+#endif /** HASH_ALGORITHM_SET_H_ @}*/
diff --git a/src/libstrongswan/crypto/hashers/hasher.c b/src/libstrongswan/crypto/hashers/hasher.c
index 13cbb5a..38eebea 100644
--- a/src/libstrongswan/crypto/hashers/hasher.c
+++ b/src/libstrongswan/crypto/hashers/hasher.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2012 Tobias Brunner
+ * Copyright (C) 2012-2015 Tobias Brunner
  * Copyright (C) 2005-2006 Martin Willi
  * Copyright (C) 2005 Jan Hutter
  * Hochschule fuer Technik Rapperswil
@@ -19,29 +19,31 @@
 
 #include <asn1/oid.h>
 
-ENUM(hash_algorithm_names, HASH_UNKNOWN, HASH_SHA512,
+ENUM_BEGIN(hash_algorithm_names, HASH_SHA1, HASH_SHA512,
+	"HASH_SHA1",
+	"HASH_SHA256",
+	"HASH_SHA384",
+	"HASH_SHA512");
+ENUM_NEXT(hash_algorithm_names, HASH_UNKNOWN, HASH_SHA224, HASH_SHA512,
 	"HASH_UNKNOWN",
 	"HASH_MD2",
 	"HASH_MD4",
 	"HASH_MD5",
-	"HASH_SHA1",
-	"HASH_SHA224",
-	"HASH_SHA256",
-	"HASH_SHA384",
-	"HASH_SHA512"
-);
+	"HASH_SHA224");
+ENUM_END(hash_algorithm_names, HASH_SHA224);
 
-ENUM(hash_algorithm_short_names, HASH_UNKNOWN, HASH_SHA512,
+ENUM_BEGIN(hash_algorithm_short_names, HASH_SHA1, HASH_SHA512,
+	"sha1",
+	"sha256",
+	"sha384",
+	"sha512");
+ENUM_NEXT(hash_algorithm_short_names, HASH_UNKNOWN, HASH_SHA224, HASH_SHA512,
 	"unknown",
 	"md2",
 	"md4",
 	"md5",
-	"sha1",
-	"sha224",
-	"sha256",
-	"sha384",
-	"sha512"
-);
+	"sha224");
+ENUM_END(hash_algorithm_short_names, HASH_SHA224);
 
 /*
  * Described in header.
@@ -249,6 +251,28 @@ integrity_algorithm_t hasher_algorithm_to_integrity(hash_algorithm_t alg,
 /*
  * Described in header.
  */
+bool hasher_algorithm_for_ikev2(hash_algorithm_t alg)
+{
+	switch (alg)
+	{
+		case HASH_SHA1:
+		case HASH_SHA256:
+		case HASH_SHA384:
+		case HASH_SHA512:
+			return TRUE;
+		case HASH_UNKNOWN:
+		case HASH_MD2:
+		case HASH_MD4:
+		case HASH_MD5:
+		case HASH_SHA224:
+			break;
+	}
+	return FALSE;
+}
+
+/*
+ * Described in header.
+ */
 int hasher_algorithm_to_oid(hash_algorithm_t alg)
 {
 	int oid;
@@ -323,8 +347,56 @@ int hasher_signature_algorithm_to_oid(hash_algorithm_t alg, key_type_t key)
 				default:
 					return OID_UNKNOWN;
 			}
+		case KEY_BLISS:
+			switch (alg)
+			{
+				case HASH_SHA256:
+					return OID_BLISS_WITH_SHA256;
+				case HASH_SHA384:
+					return OID_BLISS_WITH_SHA384;
+				case HASH_SHA512:
+					return OID_BLISS_WITH_SHA512;
+				default:
+					return OID_UNKNOWN;
+			}
 		default:
 			return OID_UNKNOWN;
 	}
 }
 
+/*
+ * Defined in header.
+ */
+hash_algorithm_t hasher_from_signature_scheme(signature_scheme_t scheme)
+{
+	switch (scheme)
+	{
+		case SIGN_UNKNOWN:
+		case SIGN_RSA_EMSA_PKCS1_NULL:
+		case SIGN_ECDSA_WITH_NULL:
+			break;
+		case SIGN_RSA_EMSA_PKCS1_MD5:
+			return HASH_MD5;
+		case SIGN_RSA_EMSA_PKCS1_SHA1:
+		case SIGN_ECDSA_WITH_SHA1_DER:
+			return HASH_SHA1;
+		case SIGN_RSA_EMSA_PKCS1_SHA224:
+			return HASH_SHA224;
+		case SIGN_RSA_EMSA_PKCS1_SHA256:
+		case SIGN_ECDSA_WITH_SHA256_DER:
+		case SIGN_ECDSA_256:
+		case SIGN_BLISS_WITH_SHA256:
+			return HASH_SHA256;
+		case SIGN_RSA_EMSA_PKCS1_SHA384:
+		case SIGN_ECDSA_WITH_SHA384_DER:
+		case SIGN_ECDSA_384:
+		case SIGN_BLISS_WITH_SHA384:
+			return HASH_SHA384;
+		case SIGN_RSA_EMSA_PKCS1_SHA512:
+		case SIGN_ECDSA_WITH_SHA512_DER:
+		case SIGN_ECDSA_521:
+		case SIGN_BLISS_WITH_SHA512:
+			return HASH_SHA512;
+	}
+	return HASH_UNKNOWN;
+}
diff --git a/src/libstrongswan/crypto/hashers/hasher.h b/src/libstrongswan/crypto/hashers/hasher.h
index 37ef0b6..7725863 100644
--- a/src/libstrongswan/crypto/hashers/hasher.h
+++ b/src/libstrongswan/crypto/hashers/hasher.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2012 Tobias Brunner
+ * Copyright (C) 2012-2015 Tobias Brunner
  * Copyright (C) 2005-2006 Martin Willi
  * Copyright (C) 2005 Jan Hutter
  * Hochschule fuer Technik Rapperswil
@@ -32,19 +32,19 @@ typedef struct hasher_t hasher_t;
 #include <credentials/keys/public_key.h>
 
 /**
- * Algorithms to use for hashing.
+ * Hash algorithms as defined for IKEv2 by RFC 7427
  */
 enum hash_algorithm_t {
-	/** not specified hash function */
-	HASH_UNKNOWN 		= 0,
-	HASH_MD2 			= 1,
-	HASH_MD4			= 2,
-	HASH_MD5 			= 3,
-	HASH_SHA1 			= 4,
-	HASH_SHA224			= 5,
-	HASH_SHA256 		= 6,
-	HASH_SHA384 		= 7,
-	HASH_SHA512 		= 8
+	HASH_SHA1 			= 1,
+	HASH_SHA256			= 2,
+	HASH_SHA384			= 3,
+	HASH_SHA512			= 4,
+	/* use private use range for algorithms not defined/permitted by RFC 7427 */
+	HASH_UNKNOWN 		= 1024,
+	HASH_MD2 			= 1025,
+	HASH_MD4			= 1026,
+	HASH_MD5 			= 1027,
+	HASH_SHA224			= 1028,
 };
 
 #define HASH_SIZE_MD2		16
@@ -163,6 +163,14 @@ integrity_algorithm_t hasher_algorithm_to_integrity(hash_algorithm_t alg,
 													size_t length);
 
 /**
+ * Check if the given algorithm may be used for IKEv2 signature authentication.
+ *
+ * @param alg			hash algorithm
+ * @return				TRUE if algorithm may be used, FALSE otherwise
+ */
+bool hasher_algorithm_for_ikev2(hash_algorithm_t alg);
+
+/**
  * Conversion of hash algorithm into ASN.1 OID.
  *
  * @param alg			hash algorithm
@@ -179,4 +187,12 @@ int hasher_algorithm_to_oid(hash_algorithm_t alg);
  */
 int hasher_signature_algorithm_to_oid(hash_algorithm_t alg, key_type_t key);
 
+/**
+ * Determine the hash algorithm associated with a given signature scheme.
+ *
+ * @param scheme		signature scheme
+ * @return				hash algorithm (could be HASH_UNKNOWN)
+ */
+hash_algorithm_t hasher_from_signature_scheme(signature_scheme_t scheme);
+
 #endif /** HASHER_H_ @}*/
diff --git a/src/libstrongswan/crypto/mgf1/mgf1.c b/src/libstrongswan/crypto/mgf1/mgf1.c
new file mode 100644
index 0000000..4bbcd6e
--- /dev/null
+++ b/src/libstrongswan/crypto/mgf1/mgf1.c
@@ -0,0 +1,180 @@
+/*
+ * Copyright (C) 2013-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.
+ */
+
+#include "mgf1.h"
+
+#include "crypto/hashers/hasher.h"
+#include "utils/debug.h"
+#include "utils/test.h"
+
+typedef struct private_mgf1_t private_mgf1_t;
+
+/**
+ * Private data of an mgf1_t object.
+ */
+struct private_mgf1_t {
+
+	/**
+	 * Public mgf1_t interface.
+	 */
+	mgf1_t public;
+
+	/**
+	 * Hasher the MGF1 Mask Generation Function is based on
+	 */
+	hasher_t *hasher;
+
+	/**
+	 * Counter
+	 */
+	u_int32_t counter;
+
+	/**
+	 * Set if counter has reached 2^32
+	 */
+	bool overflow;
+
+	/**
+	 * Current state to be hashed
+	 */
+	chunk_t state;
+
+	/**
+	 * Position of the 4 octet counter string
+	 */
+	u_char *ctr_str;
+
+};
+
+METHOD(mgf1_t, get_hash_size, size_t,
+	private_mgf1_t *this)
+{
+	return this->hasher->get_hash_size(this->hasher);
+}
+
+METHOD(mgf1_t, get_mask, bool,
+	private_mgf1_t *this, size_t mask_len, u_char *mask)
+{
+	u_char buf[HASH_SIZE_SHA512];
+	size_t hash_len;
+
+	hash_len = this->hasher->get_hash_size(this->hasher);
+
+	while (mask_len > 0)
+	{
+		/* detect overflow, set counter string and increment counter */
+		if (this->overflow)
+		{
+			return FALSE;
+		}
+		htoun32(this->ctr_str, this->counter++);
+		if (this->counter == 0)
+		{
+			this->overflow = TRUE;
+		}
+
+		/* get the next or final mask block from the hash function */
+		if (!this->hasher->get_hash(this->hasher, this->state,
+								   (mask_len < hash_len) ? buf : mask))
+		{
+			return FALSE;
+		}
+		if (mask_len < hash_len)
+		{
+			memcpy(mask, buf, mask_len);
+			return TRUE;
+		}
+		mask_len -= hash_len;
+		mask += hash_len;
+	}
+	return TRUE;
+}
+
+METHOD(mgf1_t, allocate_mask, bool,
+	private_mgf1_t *this, size_t mask_len, chunk_t *mask)
+{
+	if (mask_len == 0)
+	{
+		*mask = chunk_empty;
+		return TRUE;
+	}
+	*mask = chunk_alloc(mask_len);
+
+	return get_mask(this, mask_len, mask->ptr);
+}
+
+METHOD(mgf1_t, destroy, void,
+	private_mgf1_t *this)
+{
+	this->hasher->destroy(this->hasher);
+	chunk_clear(&this->state);
+	free(this);
+}
+
+/*
+ * Described in header.
+ */
+mgf1_t *mgf1_create(hash_algorithm_t alg, chunk_t seed,
+							  bool hash_seed)
+{
+	private_mgf1_t *this;
+	hasher_t *hasher;
+	size_t state_len;
+
+	if (seed.len == 0)
+	{
+		DBG1(DBG_LIB, "empty seed for MGF1");
+		return NULL;
+	}
+
+	hasher = lib->crypto->create_hasher(lib->crypto, alg);
+	if (!hasher)
+	{
+		DBG1(DBG_LIB, "failed to create %N hasher for MGF1",
+			 hash_algorithm_names, alg);
+		return NULL;
+	}
+	state_len = (hash_seed ? hasher->get_hash_size(hasher) : seed.len) + 4;
+	
+	INIT(this,
+		.public = {
+			.get_hash_size = _get_hash_size,
+			.allocate_mask = _allocate_mask,
+			.get_mask = _get_mask,
+			.destroy = _destroy,
+		},
+		.hasher = hasher,
+		.state = chunk_alloc(state_len),
+	);
+
+	/* determine position of the 4 octet counter string */
+	this->ctr_str = this->state.ptr + state_len - 4;
+
+	if (hash_seed)
+	{
+		if (!hasher->get_hash(hasher, seed, this->state.ptr))
+		{
+			DBG1(DBG_LIB, "failed to hash seed for MGF1");
+			destroy(this);
+			return NULL;
+		}
+	}
+	else
+	{
+		memcpy(this->state.ptr, seed.ptr, seed.len);
+	}
+
+	return &this->public;
+}
diff --git a/src/libstrongswan/crypto/mgf1/mgf1.h b/src/libstrongswan/crypto/mgf1/mgf1.h
new file mode 100644
index 0000000..592d315
--- /dev/null
+++ b/src/libstrongswan/crypto/mgf1/mgf1.h
@@ -0,0 +1,77 @@
+/*
+ * Copyright (C) 2013-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.
+ */
+
+/**
+ * @defgroup mgf1 mgf1
+ * @{ @ingroup crypto
+ */
+
+#ifndef MGF1_H_
+#define MGF1_H_
+
+typedef struct mgf1_t mgf1_t;
+
+#include <library.h>
+
+/**
+ * Implements the PKCS#1 MGF1 Mask Generation Function based on a hash function
+ * defined in section 10.2.1 of RFC 2437
+ */
+struct mgf1_t {
+
+	/**
+	 * Get the hash size of the underlying hash function
+	 *
+	 * @return			hash size in bytes
+	 */
+	size_t (*get_hash_size)(mgf1_t *this);
+
+	/**
+	 * Generate a mask pattern and copy it to an output buffer
+	 * If the maximum number of requests has been reached, reseeding occurs
+	 *
+	 * @param mask_len	number of mask bytes to generate
+	 * @param mask		output buffer of minimum size mask_len
+	 * @return			TRUE if successful
+	 */
+	bool (*get_mask)(mgf1_t *this, size_t mask_len, u_char *mask);
+
+	/**
+	 * Generate a mask pattern and return it in an allocated chunk
+	 *
+	 * @param mask_len	number of mask bytes to generate
+	 * @param mask		chunk containing generated mask
+	 * @return			TRUE if successful
+	 */
+	bool (*allocate_mask)(mgf1_t *this, size_t mask_len, chunk_t *mask);
+
+	/**
+	 * Destroy the MGF1 object
+	 */
+	void (*destroy)(mgf1_t *this);
+};
+
+/**
+ * Create an MGF1 object
+ *
+ * @param alg			hash algorithm to be used by MGF1
+ * @param seed			seed used by MGF1 to generate mask from
+ * @param hash_seed		hash seed before using it as a seed for MGF1
+ */
+mgf1_t *mgf1_create(hash_algorithm_t alg, chunk_t seed,
+							  bool hash_seed);
+
+#endif /** MGF1_H_ @}*/
+
diff --git a/src/libstrongswan/crypto/mgf1/mgf1_bitspender.c b/src/libstrongswan/crypto/mgf1/mgf1_bitspender.c
new file mode 100644
index 0000000..ef0a2bd
--- /dev/null
+++ b/src/libstrongswan/crypto/mgf1/mgf1_bitspender.c
@@ -0,0 +1,208 @@
+/*
+ * 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.
+ */
+
+#include "mgf1_bitspender.h"
+
+#include <crypto/mgf1/mgf1.h>
+
+typedef struct private_mgf1_bitspender_t private_mgf1_bitspender_t;
+
+/**
+ * Private data structure for mgf1_bitspender_t object
+ */
+struct private_mgf1_bitspender_t {
+	/**
+	 * Public interface.
+	 */
+	mgf1_bitspender_t public;
+
+	/**
+	 * MGF1 bit mask generator
+	 */
+	mgf1_t *mgf1;
+
+	/**
+	 * Octet storage (accommodates up to 64 octets)
+	 */
+	uint8_t octets[HASH_SIZE_SHA512];
+
+	/**
+	 * Length of the returned hash value in octets
+	 */
+	int hash_len;
+
+	/**
+	 * Number of generated octets
+	 */
+	int octets_count;
+
+	/**
+	 * Number of available octets
+	 */
+	int octets_left;
+
+	/**
+	 * Bit storage (accommodates up to 32 bits)
+	 */
+	uint32_t bits;
+
+	/**
+	 * Number of available bits
+	 */
+	int bits_left;
+
+	/**
+	 * Byte storage (accommodates up to 4 bytes)
+	 */
+	uint8_t bytes[4];
+
+	/**
+	 * Number of available bytes
+	 */
+	int bytes_left;
+
+};
+
+METHOD(mgf1_bitspender_t, get_bits, bool,
+	private_mgf1_bitspender_t *this, int bits_needed, uint32_t *bits)
+{
+	int bits_now;
+
+	*bits = 0x00000000;
+
+	if (bits_needed == 0)
+	{
+		/* trivial */
+		return TRUE;
+	}
+	if (bits_needed > 32)
+	{
+		/* too many bits requested */
+		return FALSE;
+	}
+
+	while (bits_needed)
+	{
+		if (this->bits_left == 0)
+		{
+			if (this->octets_left == 0)
+			{
+				/* get another block from MGF1 */
+				if (!this->mgf1->get_mask(this->mgf1, this->hash_len,
+													  this->octets))
+				{
+					/* no block available */
+					return FALSE;
+				}
+				this->octets_left = this->hash_len;
+				this->octets_count += this->hash_len;
+			}
+			this->bits = untoh32(this->octets + this->hash_len -
+												this->octets_left);
+			this->bits_left = 32;
+			this->octets_left -= 4;
+		}
+		if (bits_needed > this->bits_left)
+		{
+			bits_now = this->bits_left;
+			this->bits_left = 0;
+			bits_needed -= bits_now;
+		}
+		else
+		{
+			bits_now = bits_needed;
+			this->bits_left -= bits_needed;
+			bits_needed = 0;
+		}
+		if (bits_now == 32)
+		{
+			*bits = this->bits;
+		}
+		else
+		{
+			*bits <<= bits_now;
+			*bits |= this->bits >> this->bits_left;
+			if (this->bits_left)
+			{
+				this->bits &= 0xffffffff >> (32 - this->bits_left);
+			}
+		}
+	}
+	return TRUE;
+}
+
+METHOD(mgf1_bitspender_t, get_byte, bool,
+	private_mgf1_bitspender_t *this, uint8_t *byte)
+{
+	if (this->bytes_left == 0)
+	{
+		if (this->octets_left == 0)
+		{
+			/* get another block from MGF1 */
+			if (!this->mgf1->get_mask(this->mgf1, this->hash_len, this->octets))
+			{
+				/* no block available */
+				return FALSE;
+			}
+			this->octets_left = this->hash_len;
+			this->octets_count += this->hash_len;
+		}
+		memcpy(this->bytes, this->octets + this->hash_len -	this->octets_left, 4);
+		this->bytes_left = 4;
+		this->octets_left -= 4;
+	}
+	*byte = this->bytes[4 - this->bytes_left--];
+
+	return TRUE;
+}
+
+METHOD(mgf1_bitspender_t, destroy, void,
+	private_mgf1_bitspender_t *this)
+{
+	DBG2(DBG_LIB, "mgf1 generated %u octets", this->octets_count);
+	memwipe(this->octets, sizeof(this->octets));
+	this->mgf1->destroy(this->mgf1);
+	free(this);
+}
+
+/**
+ * See header.
+ */
+mgf1_bitspender_t *mgf1_bitspender_create(hash_algorithm_t alg, chunk_t seed,
+										  bool hash_seed)
+{
+	private_mgf1_bitspender_t *this;
+	mgf1_t *mgf1;
+
+	mgf1 = mgf1_create(alg, seed, hash_seed);
+	if (!mgf1)
+	{
+	    return NULL;
+	}
+	DBG2(DBG_LIB, "mgf1 based on %N is seeded with %u octets",
+				   hash_algorithm_short_names, alg, seed.len);
+
+	INIT(this,
+		.public = {
+			.get_bits = _get_bits,
+			.get_byte = _get_byte,
+			.destroy = _destroy,
+		},
+		.mgf1 = mgf1,
+		.hash_len = mgf1->get_hash_size(mgf1),
+	);
+
+	return &this->public;
+}
diff --git a/src/libstrongswan/crypto/mgf1/mgf1_bitspender.h b/src/libstrongswan/crypto/mgf1/mgf1_bitspender.h
new file mode 100644
index 0000000..f7df8e8
--- /dev/null
+++ b/src/libstrongswan/crypto/mgf1/mgf1_bitspender.h
@@ -0,0 +1,67 @@
+/*
+ * 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.
+ */
+
+/**
+ * @defgroup mgf1_bitspender mgf1_bitspender
+ * @{ @ingroup mgf1
+ */
+
+#ifndef MGF1_BITSPENDER_H_
+#define MGF1_BITSPENDER_H_
+
+#include <library.h>
+#include <crypto/hashers/hasher.h>
+
+typedef struct mgf1_bitspender_t mgf1_bitspender_t;
+
+/**
+ * Generates a given number of pseudo-random bits at a time using MGF1
+ */
+struct mgf1_bitspender_t {
+
+	/**
+	 * Get pseudo-random bits
+	 *
+	 * @param bits_needed	Number of needed bits (1..32)
+	 * @param bits			Pseudo-random bits
+	 * @result				FALSE if internal MGF1 error occurred
+	 */
+	bool (*get_bits)(mgf1_bitspender_t *this, int bits_needed, uint32_t *bits);
+
+	/**
+	 * Get a pseudo-random byte
+	 *
+	 * @param byte			Pseudo-random byte
+	 * @result				FALSE if internal MGF1 error occurred
+	 */
+	bool (*get_byte)(mgf1_bitspender_t *this, uint8_t *byte);
+
+	/**
+	 * Destroy mgf1_bitspender_t object
+	 */
+	void (*destroy)(mgf1_bitspender_t *this);
+};
+
+/**
+ * Create a mgf1_bitspender_t object
+ *
+ * @param alg				Hash algorithm to be used with MGF1
+ * @param seed				Seed used to initialize MGF1
+ * @param hash_seed			Hash seed before using it as a seed for MFG1
+ */
+mgf1_bitspender_t *mgf1_bitspender_create(hash_algorithm_t alg, chunk_t seed,
+										  bool hash_seed);
+
+#endif /** MGF1_BITSPENDER_H_ @}*/
diff --git a/src/libstrongswan/crypto/pkcs5.c b/src/libstrongswan/crypto/pkcs5.c
index 3b4df0e..478926f 100644
--- a/src/libstrongswan/crypto/pkcs5.c
+++ b/src/libstrongswan/crypto/pkcs5.c
@@ -108,13 +108,13 @@ struct private_pkcs5_t {
  * Verify padding of decrypted blob.
  * Length of blob is adjusted accordingly.
  */
-static bool verify_padding(chunk_t *blob)
+static bool verify_padding(crypter_t *crypter, chunk_t *blob)
 {
 	u_int8_t padding, count;
 
 	padding = count = blob->ptr[blob->len - 1];
 
-	if (padding > 8)
+	if (padding > crypter->get_block_size(crypter))
 	{
 		return FALSE;
 	}
@@ -153,7 +153,7 @@ static bool decrypt_generic(private_pkcs5_t *this, chunk_t password,
 		return FALSE;
 	}
 	memwipe(keymat.ptr, keymat.len);
-	if (verify_padding(decrypted))
+	if (verify_padding(this->crypter, decrypted))
 	{
 		return TRUE;
 	}
@@ -504,6 +504,7 @@ static bool parse_pbes2_params(private_pkcs5_t *this, chunk_t blob, int level0)
 {
 	asn1_parser_t *parser;
 	chunk_t object, params;
+	size_t keylen;
 	int objectID;
 	bool success = FALSE;
 
@@ -533,20 +534,35 @@ static bool parse_pbes2_params(private_pkcs5_t *this, chunk_t blob, int level0)
 			{
 				int oid = asn1_parse_algorithmIdentifier(object,
 									parser->get_level(parser) + 1, &params);
-				if (oid != OID_3DES_EDE_CBC)
+				this->encr = encryption_algorithm_from_oid(oid, &keylen);
+				if (this->encr == ENCR_UNDEFINED)
 				{	/* unsupported encryption scheme */
 					goto end;
 				}
-				if (this->keylen <= 0)
-				{	/* default key length for DES-EDE3-CBC-Pad */
-					this->keylen = 24;
+				/* prefer encoded key length */
+				this->keylen = this->keylen ?: keylen / 8;
+				if (!this->keylen)
+				{	/* set default key length for known algorithms */
+					switch (this->encr)
+					{
+						case ENCR_DES:
+							this->keylen = 8;
+							break;
+						case ENCR_3DES:
+							this->keylen = 24;
+							break;
+						case ENCR_BLOWFISH:
+							this->keylen = 16;
+							break;
+						default:
+							goto end;
+					}
 				}
 				if (!asn1_parse_simple_object(&params, ASN1_OCTET_STRING,
 									parser->get_level(parser) + 1, "IV"))
 				{
 					goto end;
 				}
-				this->encr = ENCR_3DES;
 				this->data.pbes2.iv = chunk_clone(params);
 				break;
 			}
diff --git a/src/libstrongswan/ipsec/ipsec_types.c b/src/libstrongswan/ipsec/ipsec_types.c
index 4bbd918..f2ee11e 100644
--- a/src/libstrongswan/ipsec/ipsec_types.c
+++ b/src/libstrongswan/ipsec/ipsec_types.c
@@ -48,7 +48,15 @@ bool mark_from_string(const char *value, mark_t *mark)
 	{
 		return FALSE;
 	}
-	mark->value = strtoul(value, &endptr, 0);
+	if (strcasepfx(value, "%unique"))
+	{
+		mark->value = MARK_UNIQUE;
+		endptr = (char*)value + strlen("%unique");
+	}
+	else
+	{
+		mark->value = strtoul(value, &endptr, 0);
+	}
 	if (*endptr)
 	{
 		if (*endptr != '/')
diff --git a/src/libstrongswan/ipsec/ipsec_types.h b/src/libstrongswan/ipsec/ipsec_types.h
index c1465e0..fa122af 100644
--- a/src/libstrongswan/ipsec/ipsec_types.h
+++ b/src/libstrongswan/ipsec/ipsec_types.h
@@ -169,9 +169,9 @@ struct mark_t {
 };
 
 /**
- * Special mark value that uses the reqid of the CHILD_SA as mark
+ * Special mark value that uses a unique mark for each CHILD_SA
  */
-#define MARK_REQID (0xFFFFFFFF)
+#define MARK_UNIQUE (0xFFFFFFFF)
 
 /**
  * Try to parse a mark_t from the given string of the form mark[/mask].
diff --git a/src/libstrongswan/library.h b/src/libstrongswan/library.h
index 2bd5e35..3a6dd1b 100644
--- a/src/libstrongswan/library.h
+++ b/src/libstrongswan/library.h
@@ -79,6 +79,9 @@
  *
  * @defgroup utils utils
  * @ingroup libstrongswan
+ *
+ * @defgroup compat compat
+ * @ingroup utils
  */
 
 /**
diff --git a/src/libstrongswan/networking/host.c b/src/libstrongswan/networking/host.c
index 8d04a4e..07da3ef 100644
--- a/src/libstrongswan/networking/host.c
+++ b/src/libstrongswan/networking/host.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2006-2012 Tobias Brunner
+ * Copyright (C) 2006-2014 Tobias Brunner
  * Copyright (C) 2006 Daniel Roethlisberger
  * Copyright (C) 2005-2006 Martin Willi
  * Copyright (C) 2005 Jan Hutter
@@ -528,6 +528,42 @@ host_t *host_create_from_chunk(int family, chunk_t address, u_int16_t port)
 /*
  * Described in header.
  */
+bool host_create_from_range(char *string, host_t **from, host_t **to)
+{
+	char *sep, *pos;
+
+	sep = strchr(string, '-');
+	if (!sep)
+	{
+		return FALSE;
+	}
+	for (pos = sep+1; *pos && *pos == ' '; pos++)
+	{
+		/* trim spaces before to address*/
+	}
+	*to = host_create_from_string(pos, 0);
+	if (!*to)
+	{
+		return FALSE;
+	}
+	for (pos = sep-1; pos > string && *pos == ' '; pos--)
+	{
+		/* trim spaces behind from address */
+	}
+	pos = strndup(string, pos - string + 1);
+	*from = host_create_from_string_and_family(pos, (*to)->get_family(*to), 0);
+	free(pos);
+	if (!*from)
+	{
+		(*to)->destroy(*to);
+		return FALSE;
+	}
+	return TRUE;
+}
+
+/*
+ * Described in header.
+ */
 host_t *host_create_from_subnet(char *string, int *bits)
 {
 	char *pos, buf[64];
diff --git a/src/libstrongswan/networking/host.h b/src/libstrongswan/networking/host.h
index 9c9b503..db6f4dd 100644
--- a/src/libstrongswan/networking/host.h
+++ b/src/libstrongswan/networking/host.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2006-2009 Tobias Brunner
+ * Copyright (C) 2006-2014 Tobias Brunner
  * Copyright (C) 2006 Daniel Roethlisberger
  * Copyright (C) 2005-2008 Martin Willi
  * Copyright (C) 2005 Jan Hutter
@@ -24,6 +24,9 @@
 #ifndef HOST_H_
 #define HOST_H_
 
+#include <utils/utils.h>
+#include <utils/chunk.h>
+
 typedef enum host_diff_t host_diff_t;
 typedef struct host_t host_t;
 
@@ -31,9 +34,6 @@ typedef struct host_t host_t;
 #include <stdio.h>
 #include <sys/types.h>
 
-#include <utils/utils.h>
-#include <utils/chunk.h>
-
 /**
  * Representates a Host
  *
@@ -181,6 +181,19 @@ host_t *host_create_from_chunk(int family, chunk_t address, u_int16_t port);
 host_t *host_create_from_sockaddr(sockaddr_t *sockaddr);
 
 /**
+ * Parse a range definition (1.2.3.0-1.2.3.5), return the two hosts.
+ *
+ * The two hosts are not ordered, from is simply the first, to is the second,
+ * from is not necessarily smaller.
+ *
+ * @param string		string to parse
+ * @param from			returns the first address (out)
+ * @param to			returns the second address (out)
+ * @return				TRUE if parsed successfully, FALSE otherwise
+ */
+bool host_create_from_range(char *string, host_t **from, host_t **to);
+
+/**
  * Create a host from a CIDR subnet definition (1.2.3.0/24), return bits.
  *
  * @param string		string to parse
diff --git a/src/libstrongswan/networking/host_resolver.c b/src/libstrongswan/networking/host_resolver.c
index a7524ac..bad87e4 100644
--- a/src/libstrongswan/networking/host_resolver.c
+++ b/src/libstrongswan/networking/host_resolver.c
@@ -163,20 +163,25 @@ static void *resolve_hosts(private_host_resolver_t *this)
 	int error;
 	bool old, timed_out;
 
+	/* default resolver threads to non-cancellable */
+	thread_cancelability(FALSE);
+
 	while (TRUE)
 	{
 		this->mutex->lock(this->mutex);
-		thread_cleanup_push((thread_cleanup_t)this->mutex->unlock, this->mutex);
 		while (this->queue->remove_first(this->queue,
 										(void**)&query) != SUCCESS)
 		{
-			old = thread_cancelability(TRUE);
+			if (this->disabled)
+			{
+				this->mutex->unlock(this->mutex);
+				return NULL;
+			}
 			timed_out = this->new_query->timed_wait(this->new_query,
 									this->mutex, NEW_QUERY_WAIT_TIMEOUT * 1000);
-			thread_cancelability(old);
 			if (this->disabled)
 			{
-				thread_cleanup_pop(TRUE);
+				this->mutex->unlock(this->mutex);
 				return NULL;
 			}
 			else if (timed_out && (this->threads > this->min_threads))
@@ -185,13 +190,13 @@ static void *resolve_hosts(private_host_resolver_t *this)
 
 				this->threads--;
 				this->pool->remove(this->pool, thread, NULL);
-				thread_cleanup_pop(TRUE);
+				this->mutex->unlock(this->mutex);
 				thread->detach(thread);
 				return NULL;
 			}
 		}
 		this->busy_threads++;
-		thread_cleanup_pop(TRUE);
+		this->mutex->unlock(this->mutex);
 
 		memset(&hints, 0, sizeof(hints));
 		hints.ai_family = query->family;
diff --git a/src/libstrongswan/networking/tun_device.c b/src/libstrongswan/networking/tun_device.c
index ff2c4a3..81d2156 100644
--- a/src/libstrongswan/networking/tun_device.c
+++ b/src/libstrongswan/networking/tun_device.c
@@ -346,40 +346,27 @@ METHOD(tun_device_t, write_packet, bool,
 METHOD(tun_device_t, read_packet, bool,
 	private_tun_device_t *this, chunk_t *packet)
 {
+	chunk_t data;
 	ssize_t len;
-	fd_set set;
 	bool old;
 
-	FD_ZERO(&set);
-	FD_SET(this->tunfd, &set);
+	data = chunk_alloca(get_mtu(this));
 
 	old = thread_cancelability(TRUE);
-	len = select(this->tunfd + 1, &set, NULL, NULL, NULL);
+	len = read(this->tunfd, data.ptr, data.len);
 	thread_cancelability(old);
-
-	if (len < 0)
-	{
-		DBG1(DBG_LIB, "select on TUN device %s failed: %s", this->if_name,
-			 strerror(errno));
-		return FALSE;
-	}
-	/* FIXME: this is quite expensive for lots of small packets, copy from
-	 * local buffer instead? */
-	*packet = chunk_alloc(get_mtu(this));
-	len = read(this->tunfd, packet->ptr, packet->len);
 	if (len < 0)
 	{
 		DBG1(DBG_LIB, "reading from TUN device %s failed: %s", this->if_name,
 			 strerror(errno));
-		chunk_free(packet);
 		return FALSE;
 	}
-	packet->len = len;
+	data.len = len;
 #ifdef __APPLE__
 	/* UTUN's prepend packets with a 32-bit protocol number */
-	packet->len -= sizeof(u_int32_t);
-	memmove(packet->ptr, packet->ptr + sizeof(u_int32_t), packet->len);
+	data = chunk_skip(data, sizeof(u_int32_t));
 #endif
+	*packet = chunk_clone(data);
 	return TRUE;
 }
 
diff --git a/src/libstrongswan/networking/tun_device.h b/src/libstrongswan/networking/tun_device.h
index 543125b..880369b 100644
--- a/src/libstrongswan/networking/tun_device.h
+++ b/src/libstrongswan/networking/tun_device.h
@@ -31,8 +31,6 @@ typedef struct tun_device_t tun_device_t;
  * Class to create TUN devices
  *
  * Creating such a device requires the CAP_NET_ADMIN capability.
- *
- * @note The implementation is currently very Linux specific
  */
 struct tun_device_t {
 
@@ -42,7 +40,7 @@ struct tun_device_t {
 	 * @note This call blocks until a packet is available. It is a thread
 	 * cancellation point.
 	 *
-	 * @param packet		the packet read from the device
+	 * @param packet		the packet read from the device, allocated
 	 * @return				TRUE if successful
 	 */
 	bool (*read_packet)(tun_device_t *this, chunk_t *packet);
diff --git a/src/libstrongswan/plugins/acert/Makefile.in b/src/libstrongswan/plugins/acert/Makefile.in
index 425e8f1..65542ea 100644
--- a/src/libstrongswan/plugins/acert/Makefile.in
+++ b/src/libstrongswan/plugins/acert/Makefile.in
@@ -227,6 +227,7 @@ DLLIB = @DLLIB@
 DLLTOOL = @DLLTOOL@
 DSYMUTIL = @DSYMUTIL@
 DUMPBIN = @DUMPBIN@
+EASY_INSTALL = @EASY_INSTALL@
 ECHO_C = @ECHO_C@
 ECHO_N = @ECHO_N@
 ECHO_T = @ECHO_T@
@@ -287,10 +288,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
 PLUGIN_CFLAGS = @PLUGIN_CFLAGS@
 PTHREADLIB = @PTHREADLIB@
 PYTHON = @PYTHON@
+PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@
 PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
 PYTHON_PLATFORM = @PYTHON_PLATFORM@
 PYTHON_PREFIX = @PYTHON_PREFIX@
 PYTHON_VERSION = @PYTHON_VERSION@
+PY_TEST = @PY_TEST@
 RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
@@ -364,6 +367,8 @@ json_CFLAGS = @json_CFLAGS@
 json_LIBS = @json_LIBS@
 libdir = @libdir@
 libexecdir = @libexecdir@
+libiptc_CFLAGS = @libiptc_CFLAGS@
+libiptc_LIBS = @libiptc_LIBS@
 linux_headers = @linux_headers@
 localedir = @localedir@
 localstatedir = @localstatedir@
diff --git a/src/libstrongswan/plugins/aes/Makefile.in b/src/libstrongswan/plugins/aes/Makefile.in
index 11dcf29..9d79c81 100644
--- a/src/libstrongswan/plugins/aes/Makefile.in
+++ b/src/libstrongswan/plugins/aes/Makefile.in
@@ -226,6 +226,7 @@ DLLIB = @DLLIB@
 DLLTOOL = @DLLTOOL@
 DSYMUTIL = @DSYMUTIL@
 DUMPBIN = @DUMPBIN@
+EASY_INSTALL = @EASY_INSTALL@
 ECHO_C = @ECHO_C@
 ECHO_N = @ECHO_N@
 ECHO_T = @ECHO_T@
@@ -286,10 +287,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
 PLUGIN_CFLAGS = @PLUGIN_CFLAGS@
 PTHREADLIB = @PTHREADLIB@
 PYTHON = @PYTHON@
+PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@
 PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
 PYTHON_PLATFORM = @PYTHON_PLATFORM@
 PYTHON_PREFIX = @PYTHON_PREFIX@
 PYTHON_VERSION = @PYTHON_VERSION@
+PY_TEST = @PY_TEST@
 RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
@@ -363,6 +366,8 @@ json_CFLAGS = @json_CFLAGS@
 json_LIBS = @json_LIBS@
 libdir = @libdir@
 libexecdir = @libexecdir@
+libiptc_CFLAGS = @libiptc_CFLAGS@
+libiptc_LIBS = @libiptc_LIBS@
 linux_headers = @linux_headers@
 localedir = @localedir@
 localstatedir = @localstatedir@
diff --git a/src/libstrongswan/plugins/af_alg/Makefile.in b/src/libstrongswan/plugins/af_alg/Makefile.in
index 279000d..4a86f96 100644
--- a/src/libstrongswan/plugins/af_alg/Makefile.in
+++ b/src/libstrongswan/plugins/af_alg/Makefile.in
@@ -230,6 +230,7 @@ DLLIB = @DLLIB@
 DLLTOOL = @DLLTOOL@
 DSYMUTIL = @DSYMUTIL@
 DUMPBIN = @DUMPBIN@
+EASY_INSTALL = @EASY_INSTALL@
 ECHO_C = @ECHO_C@
 ECHO_N = @ECHO_N@
 ECHO_T = @ECHO_T@
@@ -290,10 +291,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
 PLUGIN_CFLAGS = @PLUGIN_CFLAGS@
 PTHREADLIB = @PTHREADLIB@
 PYTHON = @PYTHON@
+PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@
 PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
 PYTHON_PLATFORM = @PYTHON_PLATFORM@
 PYTHON_PREFIX = @PYTHON_PREFIX@
 PYTHON_VERSION = @PYTHON_VERSION@
+PY_TEST = @PY_TEST@
 RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
@@ -367,6 +370,8 @@ json_CFLAGS = @json_CFLAGS@
 json_LIBS = @json_LIBS@
 libdir = @libdir@
 libexecdir = @libexecdir@
+libiptc_CFLAGS = @libiptc_CFLAGS@
+libiptc_LIBS = @libiptc_LIBS@
 linux_headers = @linux_headers@
 localedir = @localedir@
 localstatedir = @localstatedir@
diff --git a/src/libstrongswan/plugins/af_alg/af_alg_prf.c b/src/libstrongswan/plugins/af_alg/af_alg_prf.c
index 720738a..2b7d513 100644
--- a/src/libstrongswan/plugins/af_alg/af_alg_prf.c
+++ b/src/libstrongswan/plugins/af_alg/af_alg_prf.c
@@ -139,6 +139,7 @@ METHOD(prf_t, set_key, bool,
 {
 	char buf[this->block_size];
 
+	this->ops->reset(this->ops);
 	if (this->xcbc)
 	{
 		/* The kernel currently does not support variable length XCBC keys,
diff --git a/src/libstrongswan/plugins/af_alg/af_alg_signer.c b/src/libstrongswan/plugins/af_alg/af_alg_signer.c
index 6ee3806..9ad0110 100644
--- a/src/libstrongswan/plugins/af_alg/af_alg_signer.c
+++ b/src/libstrongswan/plugins/af_alg/af_alg_signer.c
@@ -156,6 +156,7 @@ METHOD(signer_t, get_block_size, size_t,
 METHOD(signer_t, set_key, bool,
 	private_af_alg_signer_t *this, chunk_t key)
 {
+	this->ops->reset(this->ops);
 	return this->ops->set_key(this->ops, key);
 }
 
diff --git a/src/libstrongswan/plugins/agent/Makefile.in b/src/libstrongswan/plugins/agent/Makefile.in
index c8e8112..292c2fd 100644
--- a/src/libstrongswan/plugins/agent/Makefile.in
+++ b/src/libstrongswan/plugins/agent/Makefile.in
@@ -228,6 +228,7 @@ DLLIB = @DLLIB@
 DLLTOOL = @DLLTOOL@
 DSYMUTIL = @DSYMUTIL@
 DUMPBIN = @DUMPBIN@
+EASY_INSTALL = @EASY_INSTALL@
 ECHO_C = @ECHO_C@
 ECHO_N = @ECHO_N@
 ECHO_T = @ECHO_T@
@@ -288,10 +289,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
 PLUGIN_CFLAGS = @PLUGIN_CFLAGS@
 PTHREADLIB = @PTHREADLIB@
 PYTHON = @PYTHON@
+PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@
 PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
 PYTHON_PLATFORM = @PYTHON_PLATFORM@
 PYTHON_PREFIX = @PYTHON_PREFIX@
 PYTHON_VERSION = @PYTHON_VERSION@
+PY_TEST = @PY_TEST@
 RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
@@ -365,6 +368,8 @@ json_CFLAGS = @json_CFLAGS@
 json_LIBS = @json_LIBS@
 libdir = @libdir@
 libexecdir = @libexecdir@
+libiptc_CFLAGS = @libiptc_CFLAGS@
+libiptc_LIBS = @libiptc_LIBS@
 linux_headers = @linux_headers@
 localedir = @localedir@
 localstatedir = @localstatedir@
diff --git a/src/libstrongswan/plugins/bliss/Makefile.am b/src/libstrongswan/plugins/bliss/Makefile.am
new file mode 100644
index 0000000..e2aaaf5
--- /dev/null
+++ b/src/libstrongswan/plugins/bliss/Makefile.am
@@ -0,0 +1,54 @@
+AM_CPPFLAGS = \
+	-I$(top_srcdir)/src/libstrongswan
+
+AM_CFLAGS = \
+	$(PLUGIN_CFLAGS) \
+	@COVERAGE_CFLAGS@
+
+# these file are also used by bliss_huffman
+noinst_LTLIBRARIES = libbliss-params.la
+libbliss_params_la_SOURCES = \
+	bliss_param_set.h bliss_param_set.c \
+	bliss_fft_params.h bliss_fft_params.c
+
+# 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
+noinst_LTLIBRARIES += libbliss.la
+libbliss_la_SOURCES = \
+	bliss_private_key.h bliss_private_key.c \
+	bliss_public_key.h bliss_public_key.c \
+	bliss_signature.h bliss_signature.c \
+	bliss_utils.h bliss_utils.c \
+	bliss_bitpacker.h bliss_bitpacker.c \
+	bliss_fft.h bliss_fft.c \
+	bliss_huffman_code.h bliss_huffman_code.c \
+	bliss_huffman_code_1.c bliss_huffman_code_3.c bliss_huffman_code_4.c \
+	bliss_huffman_coder.h bliss_huffman_coder.c \
+	bliss_sampler.h bliss_sampler.c
+libbliss_la_LIBADD = libbliss-params.la
+
+if MONOLITHIC
+noinst_LTLIBRARIES += libstrongswan-bliss.la
+else
+plugin_LTLIBRARIES = libstrongswan-bliss.la
+endif
+
+libstrongswan_bliss_la_SOURCES = \
+	bliss_plugin.h bliss_plugin.c
+
+libstrongswan_bliss_la_LDFLAGS = -module -avoid-version
+
+libstrongswan_bliss_la_LIBADD = libbliss.la
+
+noinst_PROGRAMS = bliss_huffman
+
+bliss_huffman_SOURCES = bliss_huffman.c
+bliss_huffman_LDADD = -lm libbliss-params.la
+
+recreate-bliss-huffman :	bliss_huffman bliss_huffman_code.h
+	$(AM_V_GEN) \
+	./bliss_huffman 1  8 > $(srcdir)/bliss_huffman_code_1.c 2>/dev/null
+	$(AM_V_GEN) \
+	./bliss_huffman 3 16 > $(srcdir)/bliss_huffman_code_3.c 2>/dev/null
+	$(AM_V_GEN) \
+	./bliss_huffman 4 32 > $(srcdir)/bliss_huffman_code_4.c 2>/dev/null
diff --git a/src/libstrongswan/plugins/bliss/Makefile.in b/src/libstrongswan/plugins/bliss/Makefile.in
new file mode 100644
index 0000000..1361dd3
--- /dev/null
+++ b/src/libstrongswan/plugins/bliss/Makefile.in
@@ -0,0 +1,862 @@
+# Makefile.in generated by automake 1.14.1 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994-2013 Free Software Foundation, Inc.
+
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+ at SET_MAKE@
+
+
+VPATH = @srcdir@
+am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)'
+am__make_running_with_option = \
+  case $${target_option-} in \
+      ?) ;; \
+      *) echo "am__make_running_with_option: internal error: invalid" \
+              "target option '$${target_option-}' specified" >&2; \
+         exit 1;; \
+  esac; \
+  has_opt=no; \
+  sane_makeflags=$$MAKEFLAGS; \
+  if $(am__is_gnu_make); then \
+    sane_makeflags=$$MFLAGS; \
+  else \
+    case $$MAKEFLAGS in \
+      *\\[\ \	]*) \
+        bs=\\; \
+        sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
+          | sed "s/$$bs$$bs[$$bs $$bs	]*//g"`;; \
+    esac; \
+  fi; \
+  skip_next=no; \
+  strip_trailopt () \
+  { \
+    flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
+  }; \
+  for flg in $$sane_makeflags; do \
+    test $$skip_next = yes && { skip_next=no; continue; }; \
+    case $$flg in \
+      *=*|--*) continue;; \
+        -*I) strip_trailopt 'I'; skip_next=yes;; \
+      -*I?*) strip_trailopt 'I';; \
+        -*O) strip_trailopt 'O'; skip_next=yes;; \
+      -*O?*) strip_trailopt 'O';; \
+        -*l) strip_trailopt 'l'; skip_next=yes;; \
+      -*l?*) strip_trailopt 'l';; \
+      -[dEDm]) skip_next=yes;; \
+      -[JT]) skip_next=yes;; \
+    esac; \
+    case $$flg in \
+      *$$target_option*) has_opt=yes; break;; \
+    esac; \
+  done; \
+  test $$has_opt = yes
+am__make_dryrun = (target_option=n; $(am__make_running_with_option))
+am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+ at MONOLITHIC_TRUE@am__append_1 = libstrongswan-bliss.la
+noinst_PROGRAMS = bliss_huffman$(EXEEXT)
+subdir = src/libstrongswan/plugins/bliss
+DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
+	$(top_srcdir)/depcomp
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/m4/config/libtool.m4 \
+	$(top_srcdir)/m4/config/ltoptions.m4 \
+	$(top_srcdir)/m4/config/ltsugar.m4 \
+	$(top_srcdir)/m4/config/ltversion.m4 \
+	$(top_srcdir)/m4/config/lt~obsolete.m4 \
+	$(top_srcdir)/m4/macros/split-package-version.m4 \
+	$(top_srcdir)/m4/macros/with.m4 \
+	$(top_srcdir)/m4/macros/enable-disable.m4 \
+	$(top_srcdir)/m4/macros/add-plugin.m4 \
+	$(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+	$(ACLOCAL_M4)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
+am__vpath_adj = case $$p in \
+    $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
+    *) f=$$p;; \
+  esac;
+am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
+am__install_max = 40
+am__nobase_strip_setup = \
+  srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
+am__nobase_strip = \
+  for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
+am__nobase_list = $(am__nobase_strip_setup); \
+  for p in $$list; do echo "$$p $$p"; done | \
+  sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
+  $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
+    if (++n[$$2] == $(am__install_max)) \
+      { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
+    END { for (dir in files) print dir, files[dir] }'
+am__base_list = \
+  sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
+  sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
+am__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; }; \
+  }
+am__installdirs = "$(DESTDIR)$(plugindir)"
+LTLIBRARIES = $(noinst_LTLIBRARIES) $(plugin_LTLIBRARIES)
+libbliss_params_la_LIBADD =
+am_libbliss_params_la_OBJECTS = bliss_param_set.lo bliss_fft_params.lo
+libbliss_params_la_OBJECTS = $(am_libbliss_params_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 = 
+libbliss_la_DEPENDENCIES = libbliss-params.la
+am_libbliss_la_OBJECTS = bliss_private_key.lo bliss_public_key.lo \
+	bliss_signature.lo bliss_utils.lo bliss_bitpacker.lo \
+	bliss_fft.lo bliss_huffman_code.lo bliss_huffman_code_1.lo \
+	bliss_huffman_code_3.lo bliss_huffman_code_4.lo \
+	bliss_huffman_coder.lo bliss_sampler.lo
+libbliss_la_OBJECTS = $(am_libbliss_la_OBJECTS)
+libstrongswan_bliss_la_DEPENDENCIES = libbliss.la
+am_libstrongswan_bliss_la_OBJECTS = bliss_plugin.lo
+libstrongswan_bliss_la_OBJECTS = $(am_libstrongswan_bliss_la_OBJECTS)
+libstrongswan_bliss_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \
+	$(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \
+	$(AM_CFLAGS) $(CFLAGS) $(libstrongswan_bliss_la_LDFLAGS) \
+	$(LDFLAGS) -o $@
+ at MONOLITHIC_FALSE@am_libstrongswan_bliss_la_rpath = -rpath \
+ at MONOLITHIC_FALSE@	$(plugindir)
+ at MONOLITHIC_TRUE@am_libstrongswan_bliss_la_rpath =
+PROGRAMS = $(noinst_PROGRAMS)
+am_bliss_huffman_OBJECTS = bliss_huffman.$(OBJEXT)
+bliss_huffman_OBJECTS = $(am_bliss_huffman_OBJECTS)
+bliss_huffman_DEPENDENCIES = libbliss-params.la
+AM_V_P = $(am__v_P_ at AM_V@)
+am__v_P_ = $(am__v_P_ at AM_DEFAULT_V@)
+am__v_P_0 = false
+am__v_P_1 = :
+AM_V_GEN = $(am__v_GEN_ at AM_V@)
+am__v_GEN_ = $(am__v_GEN_ at AM_DEFAULT_V@)
+am__v_GEN_0 = @echo "  GEN     " $@;
+am__v_GEN_1 = 
+AM_V_at = $(am__v_at_ at AM_V@)
+am__v_at_ = $(am__v_at_ at AM_DEFAULT_V@)
+am__v_at_0 = @
+am__v_at_1 = 
+DEFAULT_INCLUDES = -I. at am__isrc@ -I$(top_builddir)
+depcomp = $(SHELL) $(top_srcdir)/depcomp
+am__depfiles_maybe = depfiles
+am__mv = mv -f
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+	$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+	$(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \
+	$(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
+	$(AM_CFLAGS) $(CFLAGS)
+AM_V_CC = $(am__v_CC_ at AM_V@)
+am__v_CC_ = $(am__v_CC_ at AM_DEFAULT_V@)
+am__v_CC_0 = @echo "  CC      " $@;
+am__v_CC_1 = 
+CCLD = $(CC)
+LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+	$(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+	$(AM_LDFLAGS) $(LDFLAGS) -o $@
+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 = $(libbliss_params_la_SOURCES) $(libbliss_la_SOURCES) \
+	$(libstrongswan_bliss_la_SOURCES) $(bliss_huffman_SOURCES)
+DIST_SOURCES = $(libbliss_params_la_SOURCES) $(libbliss_la_SOURCES) \
+	$(libstrongswan_bliss_la_SOURCES) $(bliss_huffman_SOURCES)
+am__can_run_installinfo = \
+  case $$AM_UPDATE_INFO_DIR in \
+    n|no|NO) false;; \
+    *) (install-info --version) >/dev/null 2>&1;; \
+  esac
+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
+# *not* preserved.
+am__uniquify_input = $(AWK) '\
+  BEGIN { nonempty = 0; } \
+  { items[$$0] = 1; nonempty = 1; } \
+  END { if (nonempty) { for (i in items) print i; }; } \
+'
+# Make sure the list of sources is unique.  This is necessary because,
+# e.g., the same source file might be shared among _SOURCES variables
+# for different programs/libraries.
+am__define_uniq_tagged_files = \
+  list='$(am__tagged_files)'; \
+  unique=`for i in $$list; do \
+    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+  done | $(am__uniquify_input)`
+ETAGS = etags
+CTAGS = ctags
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+ALLOCA = @ALLOCA@
+AMTAR = @AMTAR@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+BFDLIB = @BFDLIB@
+BTLIB = @BTLIB@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+COVERAGE_CFLAGS = @COVERAGE_CFLAGS@
+COVERAGE_LDFLAGS = @COVERAGE_LDFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DLLIB = @DLLIB@
+DLLTOOL = @DLLTOOL@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+EASY_INSTALL = @EASY_INSTALL@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+FGREP = @FGREP@
+GEM = @GEM@
+GENHTML = @GENHTML@
+GPERF = @GPERF@
+GPRBUILD = @GPRBUILD@
+GREP = @GREP@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+LCOV = @LCOV@
+LD = @LD@
+LDFLAGS = @LDFLAGS@
+LEX = @LEX@
+LEXLIB = @LEXLIB@
+LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LIPO = @LIPO@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+MAKEINFO = @MAKEINFO@
+MANIFEST_TOOL = @MANIFEST_TOOL@
+MKDIR_P = @MKDIR_P@
+MYSQLCFLAG = @MYSQLCFLAG@
+MYSQLCONFIG = @MYSQLCONFIG@
+MYSQLLIB = @MYSQLLIB@
+NM = @NM@
+NMEDIT = @NMEDIT@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OPENSSL_LIB = @OPENSSL_LIB@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PACKAGE_VERSION_BUILD = @PACKAGE_VERSION_BUILD@
+PACKAGE_VERSION_MAJOR = @PACKAGE_VERSION_MAJOR@
+PACKAGE_VERSION_MINOR = @PACKAGE_VERSION_MINOR@
+PACKAGE_VERSION_REVIEW = @PACKAGE_VERSION_REVIEW@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PERL = @PERL@
+PKG_CONFIG = @PKG_CONFIG@
+PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
+PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
+PLUGIN_CFLAGS = @PLUGIN_CFLAGS@
+PTHREADLIB = @PTHREADLIB@
+PYTHON = @PYTHON@
+PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@
+PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
+PYTHON_PLATFORM = @PYTHON_PLATFORM@
+PYTHON_PREFIX = @PYTHON_PREFIX@
+PYTHON_VERSION = @PYTHON_VERSION@
+PY_TEST = @PY_TEST@
+RANLIB = @RANLIB@
+RTLIB = @RTLIB@
+RUBY = @RUBY@
+RUBYGEMDIR = @RUBYGEMDIR@
+RUBYINCLUDE = @RUBYINCLUDE@
+RUBYLIB = @RUBYLIB@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+SOCKLIB = @SOCKLIB@
+STRIP = @STRIP@
+UNWINDLIB = @UNWINDLIB@
+VERSION = @VERSION@
+YACC = @YACC@
+YFLAGS = @YFLAGS@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+aikgen_plugins = @aikgen_plugins@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+attest_plugins = @attest_plugins@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+c_plugins = @c_plugins@
+charon_natt_port = @charon_natt_port@
+charon_plugins = @charon_plugins@
+charon_udp_port = @charon_udp_port@
+clearsilver_LIBS = @clearsilver_LIBS@
+cmd_plugins = @cmd_plugins@
+datadir = @datadir@
+datarootdir = @datarootdir@
+dbusservicedir = @dbusservicedir@
+dev_headers = @dev_headers@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+fips_mode = @fips_mode@
+gtk_CFLAGS = @gtk_CFLAGS@
+gtk_LIBS = @gtk_LIBS@
+h_plugins = @h_plugins@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+imcvdir = @imcvdir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+ipsec_script = @ipsec_script@
+ipsec_script_upper = @ipsec_script_upper@
+ipsecdir = @ipsecdir@
+ipsecgroup = @ipsecgroup@
+ipseclibdir = @ipseclibdir@
+ipsecuser = @ipsecuser@
+json_CFLAGS = @json_CFLAGS@
+json_LIBS = @json_LIBS@
+libdir = @libdir@
+libexecdir = @libexecdir@
+libiptc_CFLAGS = @libiptc_CFLAGS@
+libiptc_LIBS = @libiptc_LIBS@
+linux_headers = @linux_headers@
+localedir = @localedir@
+localstatedir = @localstatedir@
+maemo_CFLAGS = @maemo_CFLAGS@
+maemo_LIBS = @maemo_LIBS@
+manager_plugins = @manager_plugins@
+mandir = @mandir@
+medsrv_plugins = @medsrv_plugins@
+mkdir_p = @mkdir_p@
+nm_CFLAGS = @nm_CFLAGS@
+nm_LIBS = @nm_LIBS@
+nm_ca_dir = @nm_ca_dir@
+nm_plugins = @nm_plugins@
+oldincludedir = @oldincludedir@
+pcsclite_CFLAGS = @pcsclite_CFLAGS@
+pcsclite_LIBS = @pcsclite_LIBS@
+pdfdir = @pdfdir@
+piddir = @piddir@
+pkgpyexecdir = @pkgpyexecdir@
+pkgpythondir = @pkgpythondir@
+pki_plugins = @pki_plugins@
+plugindir = @plugindir@
+pool_plugins = @pool_plugins@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+pyexecdir = @pyexecdir@
+pythondir = @pythondir@
+random_device = @random_device@
+resolv_conf = @resolv_conf@
+routing_table = @routing_table@
+routing_table_prio = @routing_table_prio@
+s_plugins = @s_plugins@
+sbindir = @sbindir@
+scepclient_plugins = @scepclient_plugins@
+scripts_plugins = @scripts_plugins@
+sharedstatedir = @sharedstatedir@
+soup_CFLAGS = @soup_CFLAGS@
+soup_LIBS = @soup_LIBS@
+srcdir = @srcdir@
+starter_plugins = @starter_plugins@
+strongswan_conf = @strongswan_conf@
+strongswan_options = @strongswan_options@
+swanctldir = @swanctldir@
+sysconfdir = @sysconfdir@
+systemd_daemon_CFLAGS = @systemd_daemon_CFLAGS@
+systemd_daemon_LIBS = @systemd_daemon_LIBS@
+systemd_journal_CFLAGS = @systemd_journal_CFLAGS@
+systemd_journal_LIBS = @systemd_journal_LIBS@
+systemdsystemunitdir = @systemdsystemunitdir@
+t_plugins = @t_plugins@
+target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+urandom_device = @urandom_device@
+xml_CFLAGS = @xml_CFLAGS@
+xml_LIBS = @xml_LIBS@
+AM_CPPFLAGS = \
+	-I$(top_srcdir)/src/libstrongswan
+
+AM_CFLAGS = \
+	$(PLUGIN_CFLAGS) \
+	@COVERAGE_CFLAGS@
+
+
+# these file are also used by bliss_huffman
+
+# 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
+noinst_LTLIBRARIES = libbliss-params.la libbliss.la $(am__append_1)
+libbliss_params_la_SOURCES = \
+	bliss_param_set.h bliss_param_set.c \
+	bliss_fft_params.h bliss_fft_params.c
+
+libbliss_la_SOURCES = \
+	bliss_private_key.h bliss_private_key.c \
+	bliss_public_key.h bliss_public_key.c \
+	bliss_signature.h bliss_signature.c \
+	bliss_utils.h bliss_utils.c \
+	bliss_bitpacker.h bliss_bitpacker.c \
+	bliss_fft.h bliss_fft.c \
+	bliss_huffman_code.h bliss_huffman_code.c \
+	bliss_huffman_code_1.c bliss_huffman_code_3.c bliss_huffman_code_4.c \
+	bliss_huffman_coder.h bliss_huffman_coder.c \
+	bliss_sampler.h bliss_sampler.c
+
+libbliss_la_LIBADD = libbliss-params.la
+ at MONOLITHIC_FALSE@plugin_LTLIBRARIES = libstrongswan-bliss.la
+libstrongswan_bliss_la_SOURCES = \
+	bliss_plugin.h bliss_plugin.c
+
+libstrongswan_bliss_la_LDFLAGS = -module -avoid-version
+libstrongswan_bliss_la_LIBADD = libbliss.la
+bliss_huffman_SOURCES = bliss_huffman.c
+bliss_huffman_LDADD = -lm libbliss-params.la
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .c .lo .o .obj
+$(srcdir)/Makefile.in:  $(srcdir)/Makefile.am  $(am__configure_deps)
+	@for dep in $?; do \
+	  case '$(am__configure_deps)' in \
+	    *$$dep*) \
+	      ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+	        && { if test -f $@; then exit 0; else break; fi; }; \
+	      exit 1;; \
+	  esac; \
+	done; \
+	echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/libstrongswan/plugins/bliss/Makefile'; \
+	$(am__cd) $(top_srcdir) && \
+	  $(AUTOMAKE) --gnu src/libstrongswan/plugins/bliss/Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+	@case '$?' in \
+	  *config.status*) \
+	    cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+	  *) \
+	    echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+	    cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+	esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure:  $(am__configure_deps)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4):  $(am__aclocal_m4_deps)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+
+clean-noinstLTLIBRARIES:
+	-test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES)
+	@list='$(noinst_LTLIBRARIES)'; \
+	locs=`for p in $$list; do echo $$p; done | \
+	      sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \
+	      sort -u`; \
+	test -z "$$locs" || { \
+	  echo rm -f $${locs}; \
+	  rm -f $${locs}; \
+	}
+
+install-pluginLTLIBRARIES: $(plugin_LTLIBRARIES)
+	@$(NORMAL_INSTALL)
+	@list='$(plugin_LTLIBRARIES)'; test -n "$(plugindir)" || list=; \
+	list2=; for p in $$list; do \
+	  if test -f $$p; then \
+	    list2="$$list2 $$p"; \
+	  else :; fi; \
+	done; \
+	test -z "$$list2" || { \
+	  echo " $(MKDIR_P) '$(DESTDIR)$(plugindir)'"; \
+	  $(MKDIR_P) "$(DESTDIR)$(plugindir)" || exit 1; \
+	  echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(plugindir)'"; \
+	  $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(plugindir)"; \
+	}
+
+uninstall-pluginLTLIBRARIES:
+	@$(NORMAL_UNINSTALL)
+	@list='$(plugin_LTLIBRARIES)'; test -n "$(plugindir)" || list=; \
+	for p in $$list; do \
+	  $(am__strip_dir) \
+	  echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(plugindir)/$$f'"; \
+	  $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(plugindir)/$$f"; \
+	done
+
+clean-pluginLTLIBRARIES:
+	-test -z "$(plugin_LTLIBRARIES)" || rm -f $(plugin_LTLIBRARIES)
+	@list='$(plugin_LTLIBRARIES)'; \
+	locs=`for p in $$list; do echo $$p; done | \
+	      sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \
+	      sort -u`; \
+	test -z "$$locs" || { \
+	  echo rm -f $${locs}; \
+	  rm -f $${locs}; \
+	}
+
+libbliss-params.la: $(libbliss_params_la_OBJECTS) $(libbliss_params_la_DEPENDENCIES) $(EXTRA_libbliss_params_la_DEPENDENCIES) 
+	$(AM_V_CCLD)$(LINK)  $(libbliss_params_la_OBJECTS) $(libbliss_params_la_LIBADD) $(LIBS)
+
+libbliss.la: $(libbliss_la_OBJECTS) $(libbliss_la_DEPENDENCIES) $(EXTRA_libbliss_la_DEPENDENCIES) 
+	$(AM_V_CCLD)$(LINK)  $(libbliss_la_OBJECTS) $(libbliss_la_LIBADD) $(LIBS)
+
+libstrongswan-bliss.la: $(libstrongswan_bliss_la_OBJECTS) $(libstrongswan_bliss_la_DEPENDENCIES) $(EXTRA_libstrongswan_bliss_la_DEPENDENCIES) 
+	$(AM_V_CCLD)$(libstrongswan_bliss_la_LINK) $(am_libstrongswan_bliss_la_rpath) $(libstrongswan_bliss_la_OBJECTS) $(libstrongswan_bliss_la_LIBADD) $(LIBS)
+
+clean-noinstPROGRAMS:
+	@list='$(noinst_PROGRAMS)'; test -n "$$list" || exit 0; \
+	echo " rm -f" $$list; \
+	rm -f $$list || exit $$?; \
+	test -n "$(EXEEXT)" || exit 0; \
+	list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \
+	echo " rm -f" $$list; \
+	rm -f $$list
+
+bliss_huffman$(EXEEXT): $(bliss_huffman_OBJECTS) $(bliss_huffman_DEPENDENCIES) $(EXTRA_bliss_huffman_DEPENDENCIES) 
+	@rm -f bliss_huffman$(EXEEXT)
+	$(AM_V_CCLD)$(LINK) $(bliss_huffman_OBJECTS) $(bliss_huffman_LDADD) $(LIBS)
+
+mostlyclean-compile:
+	-rm -f *.$(OBJEXT)
+
+distclean-compile:
+	-rm -f *.tab.c
+
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/bliss_bitpacker.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/bliss_fft.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/bliss_fft_params.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/bliss_huffman.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/bliss_huffman_code.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/bliss_huffman_code_1.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/bliss_huffman_code_3.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/bliss_huffman_code_4.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/bliss_huffman_coder.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/bliss_param_set.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/bliss_plugin.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/bliss_private_key.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/bliss_public_key.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/bliss_sampler.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/bliss_signature.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/bliss_utils.Plo at am__quote@
+
+.c.o:
+ at am__fastdepCC_TRUE@	$(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\
+ at am__fastdepCC_TRUE@	$(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\
+ at am__fastdepCC_TRUE@	$(am__mv) $$depbase.Tpo $$depbase.Po
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(COMPILE) -c -o $@ $<
+
+.c.obj:
+ at am__fastdepCC_TRUE@	$(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\
+ at am__fastdepCC_TRUE@	$(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\
+ at am__fastdepCC_TRUE@	$(am__mv) $$depbase.Tpo $$depbase.Po
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
+
+.c.lo:
+ at am__fastdepCC_TRUE@	$(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\
+ at am__fastdepCC_TRUE@	$(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\
+ at am__fastdepCC_TRUE@	$(am__mv) $$depbase.Tpo $$depbase.Plo
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(LTCOMPILE) -c -o $@ $<
+
+mostlyclean-libtool:
+	-rm -f *.lo
+
+clean-libtool:
+	-rm -rf .libs _libs
+
+ID: $(am__tagged_files)
+	$(am__define_uniq_tagged_files); mkid -fID $$unique
+tags: tags-am
+TAGS: tags
+
+tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+	set x; \
+	here=`pwd`; \
+	$(am__define_uniq_tagged_files); \
+	shift; \
+	if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
+	  test -n "$$unique" || unique=$$empty_fix; \
+	  if test $$# -gt 0; then \
+	    $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+	      "$$@" $$unique; \
+	  else \
+	    $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+	      $$unique; \
+	  fi; \
+	fi
+ctags: ctags-am
+
+CTAGS: ctags
+ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+	$(am__define_uniq_tagged_files); \
+	test -z "$(CTAGS_ARGS)$$unique" \
+	  || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+	     $$unique
+
+GTAGS:
+	here=`$(am__cd) $(top_builddir) && pwd` \
+	  && $(am__cd) $(top_srcdir) \
+	  && gtags -i $(GTAGS_ARGS) "$$here"
+cscopelist: cscopelist-am
+
+cscopelist-am: $(am__tagged_files)
+	list='$(am__tagged_files)'; \
+	case "$(srcdir)" in \
+	  [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
+	  *) sdir=$(subdir)/$(srcdir) ;; \
+	esac; \
+	for i in $$list; do \
+	  if test -f "$$i"; then \
+	    echo "$(subdir)/$$i"; \
+	  else \
+	    echo "$$sdir/$$i"; \
+	  fi; \
+	done >> $(top_builddir)/cscope.files
+
+distclean-tags:
+	-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+distdir: $(DISTFILES)
+	@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+	topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+	list='$(DISTFILES)'; \
+	  dist_files=`for file in $$list; do echo $$file; done | \
+	  sed -e "s|^$$srcdirstrip/||;t" \
+	      -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+	case $$dist_files in \
+	  */*) $(MKDIR_P) `echo "$$dist_files" | \
+			   sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+			   sort -u` ;; \
+	esac; \
+	for file in $$dist_files; do \
+	  if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+	  if test -d $$d/$$file; then \
+	    dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+	    if test -d "$(distdir)/$$file"; then \
+	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+	    fi; \
+	    if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+	      cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+	    fi; \
+	    cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+	  else \
+	    test -f "$(distdir)/$$file" \
+	    || cp -p $$d/$$file "$(distdir)/$$file" \
+	    || exit 1; \
+	  fi; \
+	done
+check-am: all-am
+check: check-am
+all-am: Makefile $(LTLIBRARIES) $(PROGRAMS)
+installdirs:
+	for dir in "$(DESTDIR)$(plugindir)"; do \
+	  test -z "$$dir" || $(MKDIR_P) "$$dir"; \
+	done
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+	@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+	if test -z '$(STRIP)'; then \
+	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	      install; \
+	else \
+	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	    "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+	fi
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+	-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+	-test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+
+maintainer-clean-generic:
+	@echo "This command is intended for maintainers to use"
+	@echo "it deletes files that may require special tools to rebuild."
+clean: clean-am
+
+clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \
+	clean-noinstPROGRAMS clean-pluginLTLIBRARIES mostlyclean-am
+
+distclean: distclean-am
+	-rm -rf ./$(DEPDIR)
+	-rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+	distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+html-am:
+
+info: info-am
+
+info-am:
+
+install-data-am: install-pluginLTLIBRARIES
+
+install-dvi: install-dvi-am
+
+install-dvi-am:
+
+install-exec-am:
+
+install-html: install-html-am
+
+install-html-am:
+
+install-info: install-info-am
+
+install-info-am:
+
+install-man:
+
+install-pdf: install-pdf-am
+
+install-pdf-am:
+
+install-ps: install-ps-am
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+	-rm -rf ./$(DEPDIR)
+	-rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic \
+	mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am: uninstall-pluginLTLIBRARIES
+
+.MAKE: install-am install-strip
+
+.PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \
+	clean-libtool clean-noinstLTLIBRARIES clean-noinstPROGRAMS \
+	clean-pluginLTLIBRARIES 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-man \
+	install-pdf install-pdf-am install-pluginLTLIBRARIES \
+	install-ps install-ps-am install-strip installcheck \
+	installcheck-am installdirs maintainer-clean \
+	maintainer-clean-generic mostlyclean mostlyclean-compile \
+	mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
+	tags tags-am uninstall uninstall-am \
+	uninstall-pluginLTLIBRARIES
+
+
+recreate-bliss-huffman :	bliss_huffman bliss_huffman_code.h
+	$(AM_V_GEN) \
+	./bliss_huffman 1  8 > $(srcdir)/bliss_huffman_code_1.c 2>/dev/null
+	$(AM_V_GEN) \
+	./bliss_huffman 3 16 > $(srcdir)/bliss_huffman_code_3.c 2>/dev/null
+	$(AM_V_GEN) \
+	./bliss_huffman 4 32 > $(srcdir)/bliss_huffman_code_4.c 2>/dev/null
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/src/libstrongswan/plugins/bliss/bliss_bitpacker.c b/src/libstrongswan/plugins/bliss/bliss_bitpacker.c
new file mode 100644
index 0000000..4d84461
--- /dev/null
+++ b/src/libstrongswan/plugins/bliss/bliss_bitpacker.c
@@ -0,0 +1,207 @@
+/*
+ * 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;https://www.hsr.ch/HSR-intern-Anmeldung.4409.0.html?&no_cache=1 without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * for more details.
+ */
+
+#include "bliss_bitpacker.h"
+
+typedef struct private_bliss_bitpacker_t private_bliss_bitpacker_t;
+
+/**
+ * Private data structure for bliss_bitpacker_t object
+ */
+struct private_bliss_bitpacker_t {
+	/**
+	 * Public interface.
+	 */
+	bliss_bitpacker_t public;
+
+	/**
+	 * Current number of bits written to buffer
+	 */
+	size_t bits;
+
+	/**
+	 * Bit buffer for up to 32 bits
+	 */
+	uint32_t bits_buf;
+
+	/**
+	 * Bits left in the bit buffer
+	 */
+	size_t bits_left;
+
+	/**
+	 * Buffer
+	 */
+	chunk_t buf;
+
+	/**
+	 * Read/Write pointer into buffer
+	 */
+	chunk_t pos;
+
+};
+
+METHOD(bliss_bitpacker_t, get_bits, size_t,
+	private_bliss_bitpacker_t *this)
+{
+	return this->bits;
+}
+
+METHOD(bliss_bitpacker_t, write_bits, bool,
+	private_bliss_bitpacker_t *this, uint32_t value, size_t bits)
+{
+	if (bits == 0)
+	{
+		return TRUE;
+	}
+	if (bits > 32)
+	{
+		return FALSE;
+	}
+	if (bits < 32)
+	{
+		value &= (1 << bits) - 1;
+	}
+	this->bits += bits;
+
+	while (TRUE)
+	{
+		if (bits <= this->bits_left)
+		{
+			this->bits_buf |= value << (this->bits_left - bits);
+			this->bits_left -= bits;
+			return TRUE;
+		}
+
+		this->bits_buf |= value >> (bits - this->bits_left);
+		value &= (1 << (bits - this->bits_left)) - 1;
+		bits -= this->bits_left;
+
+		if (this->pos.len < 8)
+		{
+			return FALSE;
+		}
+		htoun32(this->pos.ptr, this->bits_buf);
+		this->pos = chunk_skip(this->pos, 4);
+		this->bits_buf = 0;
+		this->bits_left = 32;
+	}
+}
+
+METHOD(bliss_bitpacker_t, read_bits, bool,
+	private_bliss_bitpacker_t *this, uint32_t *value, size_t bits)
+{
+	if (bits > 32)
+	{
+		return FALSE;
+	}
+	*value = 0;
+
+	while (TRUE)
+	{
+		if (this->bits_left == 0)
+		{
+			if (this->pos.len < 4)
+			{
+				return FALSE;
+			}
+			this->bits_buf = untoh32(this->pos.ptr);
+			this->pos = chunk_skip(this->pos, 4);
+			this->bits_left = 32;
+		}
+		if (bits <= this->bits_left)
+		{
+			*value |= this->bits_buf >> (this->bits_left - bits);
+			this->bits_buf &= (1 << (this->bits_left - bits)) - 1;
+			this->bits_left -= bits;
+
+			return TRUE;
+		}
+		*value |= this->bits_buf << (bits - this->bits_left);
+		bits -= this->bits_left;
+		this->bits_left = 0;
+	}
+}
+
+METHOD(bliss_bitpacker_t, extract_buf, chunk_t,
+	private_bliss_bitpacker_t *this)
+{
+	chunk_t buf;
+
+	htoun32(this->pos.ptr, this->bits_buf);
+	this->pos.len -= 4;
+	buf = this->buf;
+	buf.len = this->buf.len - this->pos.len - this->bits_left/8;
+	this->buf = this->pos = chunk_empty;
+
+	return buf;
+}
+
+METHOD(bliss_bitpacker_t, destroy, void,
+	private_bliss_bitpacker_t *this)
+{
+	free(this->buf.ptr);
+	free(this);
+}
+
+/**
+ * See header.
+ */
+bliss_bitpacker_t *bliss_bitpacker_create(uint16_t max_bits)
+{
+	private_bliss_bitpacker_t *this;
+
+	INIT(this,
+		.public = {
+			.get_bits = _get_bits,
+			.write_bits = _write_bits,
+			.read_bits = _read_bits,
+			.extract_buf = _extract_buf,
+			.destroy = _destroy,
+		},
+		.bits_left = 32,
+		.buf = chunk_alloc(round_up(max_bits, 32)/8),
+	);
+
+	this->pos = this->buf;
+
+	return &this->public;
+}
+
+/**
+ * See header.
+ */
+bliss_bitpacker_t *bliss_bitpacker_create_from_data(chunk_t data)
+{
+	private_bliss_bitpacker_t *this;
+
+	INIT(this,
+		.public = {
+			.get_bits = _get_bits,
+			.write_bits = _write_bits,
+			.read_bits = _read_bits,
+			.extract_buf = _extract_buf,
+			.destroy = _destroy,
+		},
+		.bits = 8 * data.len,
+		.buf = chunk_alloc(round_up(data.len, 4)),
+	);
+
+	memset(this->buf.ptr + this->buf.len - 4, 0x00, 4);
+	memcpy(this->buf.ptr, data.ptr, data.len);
+	this->pos = this->buf;
+
+	return &this->public;
+}
diff --git a/src/libstrongswan/plugins/bliss/bliss_bitpacker.h b/src/libstrongswan/plugins/bliss/bliss_bitpacker.h
new file mode 100644
index 0000000..2fe6cba
--- /dev/null
+++ b/src/libstrongswan/plugins/bliss/bliss_bitpacker.h
@@ -0,0 +1,85 @@
+/*
+ * 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.
+ */
+
+/**
+ * @defgroup bliss_bitpacker bliss_bitpacker
+ * @{ @ingroup bliss_p
+ */
+
+#ifndef BLISS_BITPACKER_H_
+#define BLISS_BITPACKER_H_
+
+#include <library.h>
+
+typedef struct bliss_bitpacker_t bliss_bitpacker_t;
+
+/**
+ * Reads and writes a variable number of bits in packed format
+ * from and to an octet buffer
+ */
+struct bliss_bitpacker_t {
+
+	/**
+	 * Get the number of bits written into buffer
+	 *
+	 * @result			Number of bits written
+	 */
+	size_t (*get_bits)(bliss_bitpacker_t *this);
+
+	/**
+	 * Get the prime modulus of the Number Theoretic Transform
+	 *
+	 * @param value		Value to be written
+	 * @param bits		Number of bits to be written
+	 * @result			TRUE if value could be written into buffer
+	 */
+	bool (*write_bits)(bliss_bitpacker_t *this, uint32_t value, size_t bits);
+
+
+	/**
+	 * Get the prime modulus of the Number Theoretic Transform
+	 *
+	 * @param value		Value returned
+	 * @param bits		Number of bits to be read
+	 * @result			TRUE if value could be read from buffer
+	 */
+	bool (*read_bits)(bliss_bitpacker_t *this, uint32_t *value, size_t bits);
+
+	/**
+	 * Detach the internal octet buffer and return it
+	 */
+	chunk_t (*extract_buf)(bliss_bitpacker_t *this);
+
+	/**
+	 * Destroy bliss_bitpacker_t object
+	 */
+	void (*destroy)(bliss_bitpacker_t *this);
+};
+
+/**
+ * Create a bliss_bitpacker_t object for writing
+ *
+ * @param max_bits		Total number of bits to be stored
+ */
+bliss_bitpacker_t* bliss_bitpacker_create(uint16_t max_bits);
+
+/**
+ * Create a bliss_bitpacker_t object for reading
+ *
+ * @param data			Packed array of bits
+ */
+bliss_bitpacker_t* bliss_bitpacker_create_from_data(chunk_t data);
+
+#endif /** BLISS_BITPACKER_H_ @}*/
diff --git a/src/libstrongswan/plugins/bliss/bliss_fft.c b/src/libstrongswan/plugins/bliss/bliss_fft.c
new file mode 100644
index 0000000..033c214
--- /dev/null
+++ b/src/libstrongswan/plugins/bliss/bliss_fft.c
@@ -0,0 +1,199 @@
+/*
+ * 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.
+ */
+
+#include "bliss_fft.h"
+
+typedef struct private_bliss_fft_t private_bliss_fft_t;
+
+/**
+ * Private data structure for bliss_fft_t object
+ */
+struct private_bliss_fft_t {
+	/**
+	 * Public interface.
+	 */
+	bliss_fft_t public;
+
+	/**
+	 * FFT parameter set used as constants
+	 */
+	bliss_fft_params_t *p;
+
+};
+
+METHOD(bliss_fft_t, get_size, uint16_t,
+	private_bliss_fft_t *this)
+{
+	return this->p->n;
+}
+
+METHOD(bliss_fft_t, get_modulus, uint16_t,
+	private_bliss_fft_t *this)
+{
+	return this->p->q;
+}
+
+/**
+ * Do an FFT butterfly operation
+ *
+ * x[i1] ---|+|------- x[i1]
+ *        \/
+ *        /\    w[iw]  
+ * x[i2] ---|-|--|*|-- x[i2]
+ *
+ */
+static void butterfly(private_bliss_fft_t *this, uint32_t *x, int i1,int i2,
+															  int iw)
+{
+	uint32_t xp, xm;
+
+	xp = x[i1] + x[i2];
+	xm = x[i1] + (this->p->q - x[i2]);
+	if (xp >= this->p->q)
+	{
+		xp -= this->p->q;
+	}
+	x[i1] =  xp;
+	x[i2] = (xm * this->p->w[iw]) % this->p->q;
+}
+
+/**
+ * Trivial butterfly operation of last FFT stage
+ */
+static void butterfly_last(private_bliss_fft_t *this, uint32_t *x, int i1)
+{
+	uint32_t xp, xm;
+	int i2 = i1 + 1;
+
+	xp = x[i1] + x[i2];
+	xm = x[i1] + (this->p->q - x[i2]);
+	if (xp >= this->p->q)
+	{
+		xp -= this->p->q;
+	}
+	if (xm >= this->p->q)
+	{
+		xm -= this->p->q;
+	}
+	x[i1] = xp;
+	x[i2] = xm;
+}
+
+METHOD(bliss_fft_t, transform, void,
+	private_bliss_fft_t *this, uint32_t *a, uint32_t *b, bool inverse)
+{
+	int stage, i, j, k, m, n, t, iw, i_rev;
+	uint16_t q;
+	uint32_t tmp;
+
+	/* we are going to use the transform size n and the modulus q a lot */
+	n = this->p->n;
+	q = this->p->q;
+
+	if (!inverse)
+	{
+		/* apply linear phase needed for negative wrapped convolution */
+		for (i = 0; i < n; i++)
+		{
+			b[i] = (a[i] * this->p->w[i]) % q;
+		}
+	}
+	else if (a != b)
+	{
+		/* copy if input and output array are not the same */
+		for (i = 0; i < n; i++)
+		{
+			b[i] = a[i];
+		}
+	}
+
+	m = n;
+	k = 1;
+
+	for (stage = this->p->stages; stage > 0; stage--)
+	{
+		m >>= 1;
+		t = 0;
+
+		for (j = 0; j < k; j++)
+		{
+			if (stage == 1)
+			{
+				butterfly_last(this, b, t);
+			}
+			else
+			{
+				for (i = 0; i < m; i++)
+				{
+					iw = 2 * (inverse ? (n - i * k) : (i * k));
+					butterfly(this, b, t + i, t + i + m, iw);
+				}				
+			}
+			t += 2*m;
+		}
+		k <<= 1;
+	}
+
+	/* Sort output in bit-reverse order */
+	for (i = 0; i < n; i++)
+	{
+		i_rev = this->p->rev[i];
+
+		if (i_rev > i)
+		{
+			tmp = b[i];
+			b[i] = b[i_rev];
+			b[i_rev] = tmp;
+		}
+	}
+
+	/**
+	 * Compensate the linear phase needed for negative wrapped convolution
+	 * and normalize the output array with 1/n mod q after the inverse FFT. 
+	 */
+	if (inverse)
+	{
+		for (i = 0; i < n; i++)
+		{
+			b[i] = (((b[i] * this->p->w[2*n - i]) % q) * this->p->n_inv) % q;
+		}
+	}
+}
+
+METHOD(bliss_fft_t, destroy, void,
+	private_bliss_fft_t *this)
+{
+	free(this);
+}
+
+/**
+ * See header.
+ */
+bliss_fft_t *bliss_fft_create(bliss_fft_params_t *params)
+{
+	private_bliss_fft_t *this;
+
+	INIT(this,
+		.public = {
+			.get_size = _get_size,
+			.get_modulus = _get_modulus,
+			.transform = _transform,
+			.destroy = _destroy,
+		},
+		.p = params,
+	);
+
+	return &this->public;
+}
diff --git a/src/libstrongswan/plugins/bliss/bliss_fft.h b/src/libstrongswan/plugins/bliss/bliss_fft.h
new file mode 100644
index 0000000..a79edd2
--- /dev/null
+++ b/src/libstrongswan/plugins/bliss/bliss_fft.h
@@ -0,0 +1,71 @@
+/*
+ * 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.
+ */
+
+/**
+ * @defgroup bliss_fft bliss_fft
+ * @{ @ingroup bliss_p
+ */
+
+#ifndef BLISS_FFT_H_
+#define BLISS_FFT_H_
+
+#include "bliss_fft_params.h"
+
+#include <library.h>
+
+typedef struct bliss_fft_t bliss_fft_t;
+
+/**
+ * Implements a Number Theoretic Transform (NTT) via the FFT algorithm
+ */
+struct bliss_fft_t {
+
+	/**
+	 * Get the size of the Number Theoretic Transform
+	 *
+	 * @result			Transform size
+	 */
+	uint16_t (*get_size)(bliss_fft_t *this);
+
+	/**
+	 * Get the prime modulus of the Number Theoretic Transform
+	 *
+	 * @result			Prime modulus
+	 */
+	uint16_t (*get_modulus)(bliss_fft_t *this);
+
+	/**
+	 * Compute the [inverse] NTT of a polynomial
+	 *
+	 * @param a			Coefficient of input polynomial
+	 * @param b			Coefficient of output polynomial
+	 * @param inverse	TRUE if the inverse NTT has to be computed
+	 */
+	void (*transform)(bliss_fft_t *this, uint32_t *a, uint32_t *b, bool inverse);
+
+	/**
+	 * Destroy bliss_fft_t object
+	 */
+	void (*destroy)(bliss_fft_t *this);
+};
+
+/**
+ * Create a bliss_fft_t object for a given FFT parameter set
+ *
+ * @param params		FFT parameters
+ */
+bliss_fft_t *bliss_fft_create(bliss_fft_params_t *params);
+
+#endif /** BLISS_FFT_H_ @}*/
diff --git a/src/libstrongswan/plugins/bliss/bliss_fft_params.c b/src/libstrongswan/plugins/bliss/bliss_fft_params.c
new file mode 100644
index 0000000..c892c06
--- /dev/null
+++ b/src/libstrongswan/plugins/bliss/bliss_fft_params.c
@@ -0,0 +1,215 @@
+/*
+ * 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.
+ */
+
+#include "bliss_fft_params.h"
+
+/**
+ * FFT parameters for q = 12289 and 2n = 1024
+ */
+static uint16_t w_12289_1024[] = {
+	    1,    49,  2401,  7048,  1260,   295,  2166,  7822,  2319,  3030,
+	 1002, 12231,  9447,  8210,  9042,   654,  7468,  9551,  1017,   677,
+	 8595,  3329,  3364,  5079,  3091,  3991, 11224,  9260, 11336,  2459,
+	 9890,  5339,  3542,  1512,   354,  5057,  2013,   325,  3636,  6118,
+	 4846,  3963,  9852,  3477, 10616,  4046,  1630,  6136,  5728, 10314,
+	 1537,  1579,  3637,  6167,  7247, 11011, 11112,  3772,   493, 11868,
+	 3949,  9166,  6730, 10256, 10984,  9789,   390,  6821,  2426,  8273,
+	12129,  4449,  9088,  2908,  7313,  1956,  9821,  1958,  9919,  6760,
+	11726,  9280,    27,  1323,  3382,  5961,  9442,  7965,  9326,  2281,
+	 1168,  8076,  2476, 10723,  9289,   468, 10643,  5369,  5012, 12097,
+
+	 2881,  5990, 10863,  3860,  4805,  1954,  9723,  9445,  8112,  4240,
+	11136,  4948,  8961,  8974,  9611,  3957,  9558,  1360,  5195,  8775,
+	12149,  5429,  7952,  8689,  7935,  7856,  3985, 10930,  7143,  5915,
+	 7188,  8120,  4632,  5766, 12176,  6752, 11334,  2361,  5088,  3532,
+	 1022,   922,  8311,  1702,  9664,  6554,  1632,  6234, 10530, 12121,
+	 4057,  2169,  7969,  9522, 11885,  4782,   827,  3656,  7098,  3710,
+	 9744, 10474,  9377,  4780,   729, 11143,  5291,  1190,  9154,  6142,
+	 6022,   142,  6958,  9139,  5407,  6874,  5023,   347,  4714,  9784,
+	  145,  7105,  4053,  1973, 10654,  5908,  6845,  3602,  4452,  9235,
+	10111,  3879,  5736, 10706,  8456,  8807,  1428,  8527, 12286, 12142,
+
+	 5086,  3434,  8509, 11404,  5791,  1112,  5332,  3199,  9283,   174,
+	 8526, 12237,  9741, 10327,  2174,  8214,  9238, 10258, 11082,  2302,
+	 2197,  9341,  3016,   316,  3195,  9087,  2859,  4912,  7197,  8561,
+	 1663,  7753, 11227,  9407,  6250, 11314,  1381,  6224, 10040,   400,
+     7311,  1858,  5019,   151,  7399,  6170,  7394,  5925,  7678,  7552,
+	 1378,  6077,  2837,  3834,  3531,   973, 10810,  1263,   442,  9369,
+	 4388,  6099,  3915,  7500, 11119,  4115,  5011, 12048,   480, 11231,
+	 9603,  3565,  2639,  6421,  7404,  6415,  7110,  4298,  1689,  9027,
+	12208,  8320,  2143,  6695,  8541,   683,  8889,  5446,  8785,   350,
+	 4861,  4698,  9000, 10885,  4938,  8471,  9542,   576,  3646,  6608,
+
+	 4278,   709, 10163,  6427,  7698,  8532,   242, 11858,  3459,  9734,
+	 9984,  9945,  8034,   418,  8193,  8209,  8993, 10542,   420,  8291,
+	  722, 10800,   773,  1010,   334,  4077,  3149,  6833,  3014,   218,
+	10682,  7280,   339,  4322,  2865,  5206,  9314,  1693,  9223,  9523,
+	11934,  7183,  7875,  4916,  7393,  5876,  5277,   504,   118,  5782,
+	  671,  8301,  1212, 10232,  9808,  1321,  3284,  1159,  7635,  5445,
+	 8736, 10238, 10102,  3438,  8705,  8719,  9405,  6152,  6512, 11863,
+	 3704,  9450,  8357,  3956,  9509, 11248, 10436,  7515, 11854,  3263,
+	  130,  6370,  4905,  6854,  4043,  1483, 11222,  9162,  6534,   652,
+	 7370,  4749, 11499, 10446,  8005, 11286,     9,   441,  9320,  1987,
+
+	11340,  2655,  7205,  8953,  8582,  2692,  9018, 11767, 11289,   156,
+	 7644,  5886,  5767, 12225,  9153,  6093,  3621,  5383,  5698,  8844,
+	 3241, 11341,  2704,  9606,  3712,  9842,  2987, 11184,  7300,  1319,
+	 3186,  8646,  5828,  2925,  8146,  5906,  6747, 11089,  2645,  6715,
+	 9521, 11836,  2381,  6068,  2396,  6803,  1544,  1922,  8155,  6347,
+	 3778,   787,  1696,  9370,  4437,  8500, 10963,  8760, 11414,  6281,
+	  544,  2078,  3510, 12233,  9545,   723, 10849,  3174,  8058,  1594,
+	 4372,  5315,  2366,  5333,  3248, 11684,  7222,  9786,   243, 11907,
+	 5860,  4493, 11244, 10240, 10200,  8240, 10512, 11239,  9995, 10484,
+	 9867,  4212,  9764, 11454,  8241, 10561,  1351,  4754, 11744, 10162,
+
+	 6378,  5297,  1484, 11271, 11563,  1293,  1912,  7665,  6915,  7032,
+	  476, 11035, 12288, 12240,  9888,  5241, 11029, 11994, 10123,  4467,
+	 9970,  9259, 11287,    58,  2842,  4079,  3247, 11635,  4821,  2738,
+	11272, 11612,  3694,  8960,  8925,  7210,  9198,  8298,  1065,  3029,
+	  953,  9830,  2399,  6950,  8747, 10777, 11935,  7232, 10276, 11964,
+	 8653,  6171,  7443,  8326,  2437,  8812,  1673,  8243, 10659,  6153,
+	 6561,  1975, 10752, 10710,  8652,  6122,  5042,  1278,  1177,  8517,
+	11796,   421,  8340,  3123,  5559,  2033,  1305,  2500, 11899,  5468,
+	 9863,  4016,   160,  7840,  3201,  9381,  4976, 10333,  2468, 10331,
+	 2370,  5529,  563,   3009, 12262, 10966,  8907,  6328,  2847,  4324,
+
+	 2963, 10008, 11121,  4213,  9813,  1566,  3000, 11821,  1646,  6920,
+	 7277,   192,  9408,  6299,  1426,  8429,  7484, 10335,  2566,  2844,
+	 4177,  8049,  1153,  7341,  3328,  3315,  2678,  8332,  2731, 10929,
+	 7094,  3514,   140,  6860,  4337,  3600,  4354,  4433,  8304,  1359,
+	 5146,  6374,  5101,  4169,  7657,  6523,   113,  5537,   955,  9928,
+	 7201,  8757, 11267, 11367,  3978, 10587,  2625,  5735, 10657,  6055,
+	 1759,   168,  8232, 10120,  4320,  2767,   404,  7507, 11462,  8633,
+	 5191,  8579,  2545,  1815,  2912,  7509, 11560,  1146,  6998, 11099,
+	 3135,  6147,  6267, 12147,  5331,  3150,  6882,  5415,  7266, 11942,
+	 7575,  2505, 12144,  5184,  8236, 10316,  1635,  6381,  5444,  8687,
+
+	 7837,  3054,  2178,  8410,  6553,  1583,  3833,  3482, 10861,  3762,
+	    3,   147,  7203,  8855,  3780,   885,  6498, 11177,  6957,  9090,
+	 3006, 12115,  3763,    52,  2548,  1962, 10115,  4075,  3051,  2031,
+	 1207,  9987, 10092,  2948,  9273, 11973,  9094,  3202,  9430,  7377,
+	 5092,  3728, 10626,  4536,  1062,  2882,  6039,   975, 10908,  6065,
+	 2249, 11889,  4978, 10431,  7270, 12138,  4890,  6119,  4895,  6364,
+	 4611,  4737, 10911,  6212,  9452,  8455,  8758, 11316,  1479, 11026,
+	11847,  2920,  7901,  6190,  8374,  4789,  1170,  8174,  7278,   241,
+	11809,  1058,  2686,  8724,  9650,  5868,  4885,  5874,  5179,  7991,
+	10600,  3262,    81,  3969, 10146,  5594,  3748, 11606,  3400,  6843,
+
+	 3504, 11939,  7428,  7591,  3289,  1404,  7351,  3818,  2747, 11713,
+	 8643,  5681,  8011, 11580,  2126,  5862,  4591,  3757, 12047,   431,
+	 8830,  2555,  2305,  2344,  4255, 11871,  4096,  4080,  3296,  1747,
+	11869,  3998, 11567,  1489, 11516, 11279, 11955,  8212,  9140,  5456,
+	 9275, 12071,  1607,  5009, 11950,  7967,  9424,  7083,  2975, 10596,
+	 3066,  2766,   355,  5106,  4414,  7373,  4896,  6413,  7012, 11785,
+	12171,  6507, 11618,  3988, 11077,  2057,  2481, 10968,  9005, 11130,
+	 4654,  6844,  3553,  2051,  2187,  8851,  3584,  3570,  2884,  6137,
+	 5777, 	 426,  8585,  2839,  3932,  8333,  2780,  1041,  1853,  4774,
+	  435,  9026, 12159,  5919,  7384,  5435,  8246, 10806,  1067,  3127,
+
+	 5755, 11637,  4919,  7540,   790,  1843,  4284,  1003, 12280, 11848,
+	 2969, 10302,   949,  9634,  5084,  3336,  3707,  9597,  3271,   522,
+	 1000, 12133,  4645,  6403,  6522,    64,  3136,  6196,  8668,  6906,
+	 6591,  3445,  9048,   948,  9585,  2683,  8577,  2447,  9302,  1105,
+	 4989, 10970,  9103,  3643,  6461,  9364,  4143,  6383,  5542,  1200,
+	 9644,  5574,  2768,   453,  9908,  6221,  9893,  5486, 10745, 10367,
+	 4134,  5942,  8511, 11502, 10593,  2919,  7852,  3789,  1326,  3529,
+	  875,  6008, 11745, 10211,  8779,    56,  2744, 11566,  1440,  9115,
+	 4231, 10695,  7917,  6974,  9923,  6956,  9041,   605,  5067,  2503,
+	12046,   382,  6429,  7796,  1045,  2049,  2089,  4049,  1777,  1050,
+
+	 2294,  1805,  2422,  8077,  2525,   835,  4048,  1728, 10938,  7535,
+	  545,  2127,  5911,  6992, 10805,  1018,   726, 10996, 10377,  4624,
+	  5374, 5257, 11813,  1254,     1
+};
+
+/**
+ * Bit-reversed indices for n = 512
+ */
+static uint16_t rev_512[] = {
+	  0, 256, 128, 384,  64, 320, 192, 448,  32, 288, 
+	160, 416,  96, 352, 224, 480,  16, 272, 144, 400,
+	 80, 336, 208, 464,  48, 304, 176, 432, 112, 368,
+	240, 496,   8, 264, 136, 392,  72, 328, 200, 456,
+	 40, 296, 168, 424, 104, 360, 232, 488,  24, 280,
+	152, 408,  88, 344, 216, 472,  56, 312, 184, 440,
+	120, 376, 248, 504,   4, 260, 132, 388,  68, 324,
+	196, 452,  36, 292, 164, 420, 100, 356, 228, 484,
+	 20, 276, 148, 404,  84, 340, 212, 468,  52, 308,
+	180, 436, 116, 372, 244, 500,  12, 268, 140, 396,
+
+	 76, 332, 204, 460,  44, 300, 172, 428, 108, 364,
+	236, 492,  28, 284, 156, 412,  92, 348, 220, 476,
+	 60, 316, 188, 444, 124, 380, 252, 508,   2, 258,
+	130, 386,  66, 322, 194, 450,  34, 290, 162, 418,
+	 98, 354, 226, 482,  18, 274, 146, 402,  82, 338,
+	210, 466,  50, 306, 178, 434, 114, 370, 242, 498,
+	 10, 266, 138, 394,  74, 330, 202, 458,  42, 298,
+	170, 426, 106, 362, 234, 490,  26, 282, 154, 410,
+	 90, 346, 218, 474,  58, 314, 186, 442, 122, 378,
+	250, 506,   6, 262, 134, 390,  70, 326, 198, 454,
+
+	 38, 294, 166, 422, 102, 358, 230, 486,  22, 278,
+	150, 406,  86, 342, 214, 470,  54, 310, 182, 438,
+	118, 374, 246, 502,  14, 270, 142, 398,  78, 334,
+	206, 462,  46, 302, 174, 430, 110, 366, 238, 494,
+	 30, 286, 158, 414,  94, 350, 222, 478,  62, 318,
+	190, 446, 126, 382, 254, 510,   1, 257, 129, 385,
+	 65, 321, 193, 449,  33, 289, 161, 417,  97, 353,
+	225, 481,  17, 273, 145, 401,  81, 337, 209, 465,
+	 49, 305, 177, 433, 113, 369, 241, 497,   9, 265,
+	137, 393,  73, 329, 201, 457,  41, 297, 169, 425,
+
+	105, 361, 233, 489,  25, 281, 153, 409,  89, 345,
+	217, 473,  57, 313, 185, 441, 121, 377, 249, 505,
+	  5, 261, 133, 389,  69, 325, 197, 453,  37, 293,
+	165, 421, 101, 357, 229, 485,  21, 277, 149, 405,
+	 85, 341, 213, 469,  53, 309, 181, 437, 117, 373,
+	245, 501,  13, 269, 141, 397,  77, 333, 205, 461,
+	 45, 301, 173, 429, 109, 365, 237, 493,  29, 285,
+	157, 413,  93, 349, 221, 477,  61, 317, 189, 445,
+	125, 381, 253, 509,   3, 259, 131, 387,  67, 323,
+	195, 451,  35, 291, 163, 419,  99, 355, 227, 483,
+
+	 19, 275, 147, 403,  83, 339, 211, 467,  51, 307,
+	179, 435, 115, 371, 243, 499,  11, 267, 139, 395,
+	 75, 331, 203, 459,  43, 299, 171, 427, 107, 363,
+	235, 491,  27, 283, 155, 411,  91, 347, 219, 475,
+	 59, 315, 187, 443, 123, 379, 251, 507,   7, 263,
+	135, 391,  71, 327, 199, 455,  39, 295, 167, 423,
+	103, 359, 231, 487,  23, 279, 151, 407,  87, 343,
+	215, 471,  55, 311, 183, 439, 119, 375, 247, 503,
+	 15, 271, 143, 399,  79, 335, 207, 463,  47, 303,
+	175, 431, 111, 367, 239, 495,  31, 287, 159, 415,
+
+	 95, 351, 223, 479,  63, 319, 191, 447, 127, 383,
+	255, 511
+};
+
+bliss_fft_params_t bliss_fft_12289_512 = {
+	12289, 512, 12265, 9, w_12289_1024, rev_512
+};
+
+/**
+ * FFT parameters for q = 17 and n = 16
+ */
+static uint16_t w_17_16[] = {
+	1, 3, 9, 10, 13, 5, 15, 11, 16, 14, 8, 7, 4, 12, 2, 6, 1 };
+
+/**
+ * Bit-reversed indices for n = 8
+ */
+static uint16_t rev_8[] = { 0, 4, 2, 6, 1, 5, 3, 7 };
+
+bliss_fft_params_t bliss_fft_17_8 = { 17, 8, 15, 3, w_17_16, rev_8 };
diff --git a/src/libstrongswan/plugins/bliss/bliss_fft_params.h b/src/libstrongswan/plugins/bliss/bliss_fft_params.h
new file mode 100644
index 0000000..31b151b
--- /dev/null
+++ b/src/libstrongswan/plugins/bliss/bliss_fft_params.h
@@ -0,0 +1,75 @@
+/*
+ * 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.
+ */
+
+/**
+ * @defgroup bliss_fft_params bliss_fft_params
+ * @{ @ingroup bliss_p
+ */
+
+#ifndef BLISS_FFT_PARAMS_H_
+#define BLISS_FFT_PARAMS_H_
+
+#include <library.h>
+
+typedef struct bliss_fft_params_t bliss_fft_params_t;
+
+/**
+ * Defines the parameters for an NTT computed via the FFT algorithm
+ */
+struct bliss_fft_params_t {
+
+	/**
+	 * Prime modulus
+	 */
+	uint16_t q;
+
+	/**
+	 * Size of the FFT with the condition k * n = q-1
+	 */
+	uint16_t n;
+
+	/**
+	 * Inverse of n mod q used for normalization of the FFT
+	 */
+	uint16_t n_inv;
+
+	/**
+	 * Number of FFT stages  stages = log2(n)
+	 */
+	uint16_t stages;
+
+	/**
+	 * FFT twiddle factors (n-th roots of unity)
+	 */
+	uint16_t *w;
+
+	/**
+	 * FFT bit reversal
+	 */
+	uint16_t *rev;
+
+};
+
+/**
+ * FFT parameters for q = 12289 and n = 512
+ */
+extern bliss_fft_params_t bliss_fft_12289_512;
+
+/**
+ * FFT parameters for q = 17 and n = 8
+ */
+extern bliss_fft_params_t bliss_fft_17_8;
+
+#endif /** BLISS_FFT_PARAMS_H_ @}*/
diff --git a/src/libstrongswan/plugins/bliss/bliss_huffman.c b/src/libstrongswan/plugins/bliss/bliss_huffman.c
new file mode 100644
index 0000000..647234f
--- /dev/null
+++ b/src/libstrongswan/plugins/bliss/bliss_huffman.c
@@ -0,0 +1,433 @@
+/*
+ * Copyright (C) 2014 Tobias Brunner
+ * 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.
+ */
+
+#include "bliss_param_set.h"
+
+#include <library.h>
+
+#include <stdio.h>
+#include <math.h>
+
+typedef struct tuple_t tuple_t;
+
+struct tuple_t {
+	int8_t z1;
+	int8_t z2;
+	uint16_t index;
+	uint16_t bits;
+	uint32_t code;
+};
+
+typedef struct node_t node_t;
+
+struct node_t {
+	node_t *next;
+	node_t *l;
+	node_t *r;
+	tuple_t *tuple;
+	double p;
+	uint16_t depth;
+	uint16_t index;
+};
+
+static void print_node(node_t *node)
+{
+	if (node->tuple)
+	{
+		fprintf(stderr, "(%1d,%2d)", node->tuple->z1, node->tuple->z2);
+	}
+	else
+	{
+		fprintf(stderr, "      ");
+	}
+	fprintf(stderr, "  %18.16f\n", node->p);
+}
+
+static double code_node(node_t *node, int *index, uint8_t bits, uint32_t code)
+{
+	double code_length = 0;
+
+	node->index = (*index)++;
+
+	if (node->tuple)
+	{
+		node->tuple->code = code;
+		node->tuple->bits = bits;
+		code_length += node->p * bits;
+	}
+	if (node->l)
+	{
+		code_length += code_node(node->l, index, bits + 1, (code << 1));
+	}
+	if (node->r)
+	{
+		code_length += code_node(node->r, index, bits + 1, (code << 1) + 1);
+	}
+
+	return code_length;
+
+}
+
+static void write_node(node_t *node)
+{
+	int16_t node_0, node_1, tuple;
+
+	node_0 = node->l ? node->l->index : BLISS_HUFFMAN_CODE_NO_NODE;
+	node_1 = node->r ? node->r->index : BLISS_HUFFMAN_CODE_NO_NODE;
+	tuple = node->tuple ? node->tuple->index : BLISS_HUFFMAN_CODE_NO_TUPLE;
+
+	printf("\t{ %3d, %3d, %3d },  /* %3d: ", node_0, node_1, tuple, node->index);
+
+	if (node->tuple)
+	{
+		printf("(%d,%2d) %2u bit%s ", node->tuple->z1, node->tuple->z2,
+			   node->tuple->bits, (node->tuple->bits == 1) ? " " : "s");
+	}
+	printf("*/\n");
+
+	if (node->l)
+	{
+		write_node(node->l);
+	}
+	if (node->r)
+	{
+		write_node(node->r);
+	}
+}
+
+static void write_header(void)
+{
+	printf("/*\n");
+	printf(" * Copyright (C) 2014 Andreas Steffen\n");
+	printf(" * HSR Hochschule fuer Technik Rapperswil\n");
+	printf(" *\n");
+	printf(" * Optimum Huffman code for BLISS-X signatures\n");
+	printf(" *\n");
+	printf(" * This file has been automatically generated by the"
+		   " bliss_huffman utility\n");
+	printf(" * Do not edit manually!\n");
+	printf(" */\n\n");
+};
+
+static void write_code_tables(int bliss_type, int n_z1, int n_z2, node_t *nodes,
+							  tuple_t **tuples)
+{
+	int index, i, k;
+	uint32_t bit;
+	double code_length;
+
+	printf("#include \"bliss_huffman_code.h\"\n\n");
+
+	printf("static bliss_huffman_code_node_t nodes[] = {\n");
+	index = 0;
+	code_length = code_node(nodes, &index, 0, 0);
+	write_node(nodes);
+	printf("};\n\n");
+
+	printf("static bliss_huffman_code_tuple_t tuples[] = {\n");
+	index = 0;
+	for (i = 0; i < n_z1; i++)
+	{
+		if (i > 0)
+		{
+			printf("\n");
+		}
+		for (k = 1 - n_z2; k < n_z2; k++)
+		{
+			printf("\t{ %5u, %2u },  /* %3d: (%1d,%2d) ",
+						tuples[index]->code, tuples[index]->bits, index, i, k);
+			bit = 1 << (tuples[index]->bits - 1);
+			while (bit)
+			{
+				printf("%s", (tuples[index]->code & bit) ? "1" : "0");
+				bit >>= 1;
+			}
+			printf(" */\n");
+			index++;
+		}
+	}
+	printf("};\n\n");
+	printf("/* code_length = %6.4f bits/tuple (%d bits) */\n\n",
+			   code_length, (int)(512 * code_length + 1));
+
+	printf("bliss_huffman_code_t bliss_huffman_code_%d = {\n", bliss_type);
+	printf("\t.n_z1 = %d,\n", n_z1);
+	printf("\t.n_z2 = %d,\n", n_z2);
+	printf("\t.tuples = tuples,\n");
+	printf("\t.nodes  = nodes\n");
+	printf("};\n");
+}
+
+static void destroy_node(node_t *node)
+{
+	if (node->l)
+	{
+		destroy_node(node->l);
+	}
+	if (node->r)
+	{
+		destroy_node(node->r);
+	}
+	free(node->tuple);
+	free(node);
+}
+
+static void remove_node(node_t *list, node_t **last, node_t *node)
+{
+	node_t *current, *prev;
+
+	for (current = list->next, prev = list; current;
+		 prev = current, current = current->next)
+	{
+		if (current == node)
+		{
+			prev->next = current->next;
+			if (*last == current)
+			{
+				*last = prev->next ?: prev;
+			}
+			break;
+		}
+	}
+}
+
+/**
+ * Generate a Huffman code for the optimum encoding of BLISS signatures
+ */
+int main(int argc, char *argv[])
+{
+	bliss_param_set_t *set;
+	int dx, bliss_type, depth = 1, groups, groups_left, pairs = 1;
+	int i_max = 9, k_max = 8, index_max = (2*k_max - 1) * i_max;
+	int i, i_top, k, k_top;
+	uint16_t index;
+	double p, p_z1[i_max], p_z2[k_max], x_z1[i_max], x_z2[k_max];
+	double t, x, x0, p_sum, entropy = 0, erf_i, erf_k, erf_0 = 0;
+	tuple_t *tuple, *tuples[index_max];
+	node_t *node, *node_l, *node_r, *nodes = NULL;
+	node_t *node_list, *node_last;
+
+	if (argc < 2)
+	{
+		fprintf(stderr, "usage: bliss_huffman <bliss type> [<pairs>]\n");
+		exit(1);
+	}
+	if (argc > 2)
+	{
+		pairs = atoi(argv[2]);
+	}
+	fprintf(stderr, "%d code pairs with constant length\n\n", pairs);
+	groups_left = groups = pairs >> 1;
+
+	bliss_type = atoi(argv[1]);
+	set = bliss_param_set_get_by_id(bliss_type);
+	if (!set)
+	{
+		fprintf(stderr, "bliss type %d unsupported\n", bliss_type);
+		exit(1);
+	}
+	write_header();
+	printf("/*\n");
+	printf(" * Design: sigma = %u\n", set->sigma);
+	printf(" *\n");
+
+	t = 1/(sqrt(2) * set->sigma);
+
+	/* Probability distribution for z1 */
+	i_top = (set->B_inf + 255) / 256;
+	p_sum = 0;
+	x = 0;
+
+	for (i = 0; i < i_top; i++)
+	{
+		x = min(x + 256, set->B_inf);
+		erf_i = erf(t*x);
+		p_z1[i] = erf_i - erf_0;
+		p_sum += p_z1[i];
+		erf_0 = erf_i;
+		x_z1[i] = x;
+	}
+
+	/* Normalize and print the probability distribution for z1 */
+	printf(" *   i  p_z1[i]\n");
+	x0 = 0;
+
+	for (i = 0; i < i_top; i++)
+	{
+		p_z1[i] /= p_sum;
+		printf(" *  %2d  %18.16f      %4.0f .. %4.0f\n", i, p_z1[i], x0, x_z1[i]);
+		x0 = x_z1[i];
+	}
+	printf(" *\n");
+
+	/* Probability distribution for z2 */
+	dx = 1 << set->d;
+	k_top = 1 + set->B_inf / dx;
+	x = (dx >> 1) - 0.5;
+	p_sum = 0;
+
+	for (k = 0; k < k_top; k++)
+	{
+
+		erf_k = erf(t*x) / 2;
+		p_z2[k] = (k == 0) ? 2*erf_k : erf_k - erf_0;
+		p_sum +=  (k == 0) ? p_z2[k] : 2*p_z2[k];
+		erf_0 = erf_k;
+		x_z2[k] = x;
+		x += dx;
+	}
+
+	/* Normalize the probability distribution for z2 */
+	for (k = 0; k < k_top; k++)
+	{
+		p_z2[k] /= p_sum;
+	}
+
+	/* Print the probability distribution for z2 */
+	printf(" *   k  p_z2[k]  dx = %d\n", dx);
+
+	for (k = 1 - k_top; k < k_top; k++)
+	{
+
+		printf(" *  %2d  %18.16f  ",k, p_z2[abs(k)]);
+		if (k < 0)
+		{
+			printf(" %7.1f ..%7.1f\n", -x_z2[-k], -x_z2[-k-1]);
+		}
+		else if (k == 0)
+		{
+			printf(" %7.1f ..%7.1f\n", -x_z2[k], x_z2[k]);
+		}
+		else
+		{
+			printf(" %7.1f ..%7.1f\n", x_z2[k-1], x_z2[k]);
+		}
+	}
+	printf(" *\n");
+
+	/* Compute probabilities of tuples (z1, z2) */
+	INIT(node_list);
+	node_last = node_list;
+	printf(" *  (i, k)  p\n");
+	p_sum =0;
+	index = 0;
+
+	for (i = 0; i < i_top; i++)
+	{
+		for (k = 1 - k_top; k < k_top; k++)
+		{
+			p = p_z1[i] * p_z2[abs(k)];
+			printf(" *  (%1d,%2d)  %18.16f\n", i, k, p);
+			p_sum += p;
+			entropy += -log(p) * p;
+
+			INIT(tuple,
+				.z1 = i,
+				.z2 = k,
+				.index = index,
+			);
+			tuples[index++] = tuple;
+
+			INIT(node,
+				.p = p,
+				.tuple = tuple,
+			);
+			node_last->next = node;
+			node_last = node;
+		}
+		printf(" *\n");
+	}
+	entropy /= log(2);
+	printf(" *  p_sum   %18.16f\n", p_sum);
+	printf(" *\n");
+	printf(" * entropy = %6.4f bits/tuple (%d bits)\n",
+			   entropy, (int)(512 * entropy));
+	printf(" */\n\n");
+
+	/* Build Huffman tree */
+	while (node_list->next != node_last)
+	{
+		node_r = node_l = NULL;
+
+		for (node = node_list->next; node; node = node->next)
+		{
+			if (pairs > 0)
+			{
+				if (!node->tuple)
+				{
+					continue;
+				}
+			}
+			else if (groups_left > 0)
+			{
+				if (node->tuple || node->depth != depth)
+				{
+					continue;
+				}
+			}
+			if (node_r == NULL || node->p < node_r->p)
+			{
+				node_l = node_r;
+				node_r = node;
+			}
+			else if (node_l == NULL || node->p < node_l->p)
+			{
+				node_l = node;
+			}
+		}
+
+		INIT(node,
+			.l = node_l,
+			.r = node_r,
+			.p = node_l->p + node_r->p,
+			.depth = 1 + max(node_l->depth, node_r->depth),
+			.tuple = NULL,
+		);
+		print_node(node_r);
+		print_node(node_l);
+		fprintf(stderr, "        %18.16f", node->p);
+
+		remove_node(node_list, &node_last, node_l);
+		remove_node(node_list, &node_last, node_r);
+		node_last->next = node;
+		node_last = node;
+
+		if (pairs > 0)
+		{
+			pairs--;
+		}
+		else if (groups > 0)
+		{
+			if (--groups_left == 0)
+			{
+				groups >>= 1;
+				groups_left = groups;
+				depth++;
+			}
+		}
+		fprintf(stderr, "\n\n");
+	}
+
+
+	nodes = node_list->next;
+
+	write_code_tables(bliss_type, i_top, k_top, nodes, tuples);
+
+	destroy_node(nodes);
+	destroy_node(node_list);
+	exit(0);
+}
+
diff --git a/src/libstrongswan/plugins/bliss/bliss_huffman_code.c b/src/libstrongswan/plugins/bliss/bliss_huffman_code.c
new file mode 100644
index 0000000..e31cd9d
--- /dev/null
+++ b/src/libstrongswan/plugins/bliss/bliss_huffman_code.c
@@ -0,0 +1,42 @@
+/*
+ * 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.
+ */
+
+#include "bliss_huffman_code.h"
+
+extern bliss_huffman_code_t bliss_huffman_code_1;
+extern bliss_huffman_code_t bliss_huffman_code_3;
+extern bliss_huffman_code_t bliss_huffman_code_4;
+
+/**
+ * See header.
+ */
+bliss_huffman_code_t* bliss_huffman_code_get_by_id(bliss_param_set_id_t id)
+{
+	switch (id)
+	{
+		case BLISS_I:
+		case BLISS_B_I:
+			return &bliss_huffman_code_1;
+		case BLISS_III:
+		case BLISS_B_III:
+			return &bliss_huffman_code_3;
+		case BLISS_IV:
+		case BLISS_B_IV:
+			return &bliss_huffman_code_4;
+		default:
+			return NULL;
+	}
+}
+
diff --git a/src/libstrongswan/plugins/bliss/bliss_huffman_code.h b/src/libstrongswan/plugins/bliss/bliss_huffman_code.h
new file mode 100644
index 0000000..df8511b
--- /dev/null
+++ b/src/libstrongswan/plugins/bliss/bliss_huffman_code.h
@@ -0,0 +1,80 @@
+/*
+ * 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.
+ */
+
+/**
+ * @defgroup bliss_huffman_code bliss_huffman_code
+ * @{ @ingroup bliss_p
+ */
+
+#ifndef BLISS_HUFFMAN_CODE_H_
+#define BLISS_HUFFMAN_CODE_H_
+
+#include "bliss_param_set.h"
+
+#include <library.h>
+
+typedef struct bliss_huffman_code_t bliss_huffman_code_t;
+typedef struct bliss_huffman_code_tuple_t bliss_huffman_code_tuple_t;
+typedef struct bliss_huffman_code_node_t bliss_huffman_code_node_t;
+
+struct bliss_huffman_code_tuple_t {
+	uint32_t code;
+	uint16_t bits;
+};
+
+#define BLISS_HUFFMAN_CODE_NO_TUPLE		-1
+#define BLISS_HUFFMAN_CODE_NO_NODE		-1
+
+struct bliss_huffman_code_node_t {
+	int16_t node_0;
+	int16_t node_1;
+	int16_t tuple;
+};
+
+/**
+ * Defines the Huffman code for the optimum encoding of a BLISS signature
+ */
+struct bliss_huffman_code_t {
+
+	/**
+	 * Range of z1:  0..n_z1-1
+	 */
+	uint16_t n_z1;
+
+	/**
+	 * Range of z2:  -n_z2..n_z2
+	 */
+	uint16_t n_z2;
+
+	/**
+	 * Table of tuple codewords
+	 */
+	bliss_huffman_code_tuple_t *tuples;
+
+	/**
+	 * Table of binary decision nodes
+	 */
+	bliss_huffman_code_node_t *nodes;
+};
+
+/**
+ * Get Optimum Huffman code for BLISS signature given by BLISS parameter set ID
+ *
+ * @param id	BLISS parameter set ID
+ * @return		Optimum Huffman code for BLISS signature
+*/
+bliss_huffman_code_t* bliss_huffman_code_get_by_id(bliss_param_set_id_t id);
+
+#endif /** BLISS_HUFFMAN_CODE_H_ @}*/
diff --git a/src/libstrongswan/plugins/bliss/bliss_huffman_code_1.c b/src/libstrongswan/plugins/bliss/bliss_huffman_code_1.c
new file mode 100644
index 0000000..1bf433f
--- /dev/null
+++ b/src/libstrongswan/plugins/bliss/bliss_huffman_code_1.c
@@ -0,0 +1,160 @@
+/*
+ * Copyright (C) 2014 Andreas Steffen
+ * HSR Hochschule fuer Technik Rapperswil
+ *
+ * Optimum Huffman code for BLISS-X signatures
+ *
+ * This file has been automatically generated by the bliss_huffman utility
+ * Do not edit manually!
+ */
+
+/*
+ * Design: sigma = 215
+ *
+ *   i  p_z1[i]
+ *   0  0.7662277087816564         0 ..  256
+ *   1  0.2165251006508514       256 ..  512
+ *   2  0.0168930510015114       512 ..  768
+ *   3  0.0003522302274478       768 .. 1024
+ *   4  0.0000019067136680      1024 .. 1280
+ *   5  0.0000000026239598      1280 .. 1536
+ *   6  0.0000000000009052      1536 .. 1792
+ *   7  0.0000000000000001      1792 .. 2047
+ *
+ *   k  p_z2[k]  dx = 1024
+ *  -1  0.0086781953089156   -1535.5 .. -511.5
+ *   0  0.9826436093821688    -511.5 ..  511.5
+ *   1  0.0086781953089156     511.5 .. 1535.5
+ *
+ *  (i, k)  p
+ *  (0,-1)  0.0066494737079101
+ *  (0, 0)  0.7529287613658361
+ *  (0, 1)  0.0066494737079101
+ *
+ *  (1,-1)  0.0018790471127307
+ *  (1, 0)  0.2127670064253900
+ *  (1, 1)  0.0018790471127307
+ *
+ *  (2,-1)  0.0001466011959546
+ *  (2, 0)  0.0165998486096022
+ *  (2, 1)  0.0001466011959546
+ *
+ *  (3,-1)  0.0000030567227075
+ *  (3, 0)  0.0003461167820328
+ *  (3, 1)  0.0000030567227075
+ *
+ *  (4,-1)  0.0000000165468336
+ *  (4, 0)  0.0000018736200007
+ *  (4, 1)  0.0000000165468336
+ *
+ *  (5,-1)  0.0000000000227712
+ *  (5, 0)  0.0000000025784174
+ *  (5, 1)  0.0000000000227712
+ *
+ *  (6,-1)  0.0000000000000079
+ *  (6, 0)  0.0000000000008895
+ *  (6, 1)  0.0000000000000079
+ *
+ *  (7,-1)  0.0000000000000000
+ *  (7, 0)  0.0000000000000001
+ *  (7, 1)  0.0000000000000000
+ *
+ *  p_sum   0.9999999999999998
+ *
+ * entropy = 1.0195 bits/tuple (521 bits)
+ */
+
+#include "bliss_huffman_code.h"
+
+static bliss_huffman_code_node_t nodes[] = {
+	{   1,   2,  -1 },  /*   0: */
+	{  -1,  -1,   1 },  /*   1: (0, 0)  1 bit  */
+	{   3,   4,  -1 },  /*   2: */
+	{  -1,  -1,   4 },  /*   3: (1, 0)  2 bits */
+	{   5,  46,  -1 },  /*   4: */
+	{   6,  45,  -1 },  /*   5: */
+	{   7,   8,  -1 },  /*   6: */
+	{  -1,  -1,   0 },  /*   7: (0,-1)  5 bits */
+	{   9,  44,  -1 },  /*   8: */
+	{  10,  11,  -1 },  /*   9: */
+	{  -1,  -1,   3 },  /*  10: (1,-1)  7 bits */
+	{  12,  13,  -1 },  /*  11: */
+	{  -1,  -1,  10 },  /*  12: (3, 0)  8 bits */
+	{  14,  29,  -1 },  /*  13: */
+	{  15,  22,  -1 },  /*  14: */
+	{  16,  19,  -1 },  /*  15: */
+	{  17,  18,  -1 },  /*  16: */
+	{  -1,  -1,   8 },  /*  17: (2, 1) 12 bits */
+	{  -1,  -1,   6 },  /*  18: (2,-1) 12 bits */
+	{  20,  21,  -1 },  /*  19: */
+	{  -1,  -1,  11 },  /*  20: (3, 1) 12 bits */
+	{  -1,  -1,   9 },  /*  21: (3,-1) 12 bits */
+	{  23,  26,  -1 },  /*  22: */
+	{  24,  25,  -1 },  /*  23: */
+	{  -1,  -1,  13 },  /*  24: (4, 0) 12 bits */
+	{  -1,  -1,  14 },  /*  25: (4, 1) 12 bits */
+	{  27,  28,  -1 },  /*  26: */
+	{  -1,  -1,  12 },  /*  27: (4,-1) 12 bits */
+	{  -1,  -1,  16 },  /*  28: (5, 0) 12 bits */
+	{  30,  37,  -1 },  /*  29: */
+	{  31,  34,  -1 },  /*  30: */
+	{  32,  33,  -1 },  /*  31: */
+	{  -1,  -1,  17 },  /*  32: (5, 1) 12 bits */
+	{  -1,  -1,  15 },  /*  33: (5,-1) 12 bits */
+	{  35,  36,  -1 },  /*  34: */
+	{  -1,  -1,  19 },  /*  35: (6, 0) 12 bits */
+	{  -1,  -1,  20 },  /*  36: (6, 1) 12 bits */
+	{  38,  41,  -1 },  /*  37: */
+	{  39,  40,  -1 },  /*  38: */
+	{  -1,  -1,  18 },  /*  39: (6,-1) 12 bits */
+	{  -1,  -1,  22 },  /*  40: (7, 0) 12 bits */
+	{  42,  43,  -1 },  /*  41: */
+	{  -1,  -1,  23 },  /*  42: (7, 1) 12 bits */
+	{  -1,  -1,  21 },  /*  43: (7,-1) 12 bits */
+	{  -1,  -1,   5 },  /*  44: (1, 1)  6 bits */
+	{  -1,  -1,   2 },  /*  45: (0, 1)  4 bits */
+	{  -1,  -1,   7 },  /*  46: (2, 0)  3 bits */
+};
+
+static bliss_huffman_code_tuple_t tuples[] = {
+	{    24,  5 },  /*   0: (0,-1) 11000 */
+	{     0,  1 },  /*   1: (0, 0) 0 */
+	{    13,  4 },  /*   2: (0, 1) 1101 */
+
+	{   100,  7 },  /*   3: (1,-1) 1100100 */
+	{     2,  2 },  /*   4: (1, 0) 10 */
+	{    51,  6 },  /*   5: (1, 1) 110011 */
+
+	{  3249, 12 },  /*   6: (2,-1) 110010110001 */
+	{     7,  3 },  /*   7: (2, 0) 111 */
+	{  3248, 12 },  /*   8: (2, 1) 110010110000 */
+
+	{  3251, 12 },  /*   9: (3,-1) 110010110011 */
+	{   202,  8 },  /*  10: (3, 0) 11001010 */
+	{  3250, 12 },  /*  11: (3, 1) 110010110010 */
+
+	{  3254, 12 },  /*  12: (4,-1) 110010110110 */
+	{  3252, 12 },  /*  13: (4, 0) 110010110100 */
+	{  3253, 12 },  /*  14: (4, 1) 110010110101 */
+
+	{  3257, 12 },  /*  15: (5,-1) 110010111001 */
+	{  3255, 12 },  /*  16: (5, 0) 110010110111 */
+	{  3256, 12 },  /*  17: (5, 1) 110010111000 */
+
+	{  3260, 12 },  /*  18: (6,-1) 110010111100 */
+	{  3258, 12 },  /*  19: (6, 0) 110010111010 */
+	{  3259, 12 },  /*  20: (6, 1) 110010111011 */
+
+	{  3263, 12 },  /*  21: (7,-1) 110010111111 */
+	{  3261, 12 },  /*  22: (7, 0) 110010111101 */
+	{  3262, 12 },  /*  23: (7, 1) 110010111110 */
+};
+
+/* code_length = 1.3189 bits/tuple (676 bits) */
+
+bliss_huffman_code_t bliss_huffman_code_1 = {
+	.n_z1 = 8,
+	.n_z2 = 2,
+	.tuples = tuples,
+	.nodes  = nodes
+};
diff --git a/src/libstrongswan/plugins/bliss/bliss_huffman_code_3.c b/src/libstrongswan/plugins/bliss/bliss_huffman_code_3.c
new file mode 100644
index 0000000..37a8084
--- /dev/null
+++ b/src/libstrongswan/plugins/bliss/bliss_huffman_code_3.c
@@ -0,0 +1,261 @@
+/*
+ * Copyright (C) 2014 Andreas Steffen
+ * HSR Hochschule fuer Technik Rapperswil
+ *
+ * Optimum Huffman code for BLISS-X signatures
+ *
+ * This file has been automatically generated by the bliss_huffman utility
+ * Do not edit manually!
+ */
+
+/*
+ * Design: sigma = 250
+ *
+ *   i  p_z1[i]
+ *   0  0.6941647250930416         0 ..  256
+ *   1  0.2652752755116807       256 ..  512
+ *   2  0.0384337021454129       512 ..  768
+ *   3  0.0020842622589255       768 .. 1024
+ *   4  0.0000417294572050      1024 .. 1280
+ *   5  0.0000003047309681      1280 .. 1536
+ *   6  0.0000000008027661      1536 .. 1760
+ *
+ *   k  p_z2[k]  dx = 512
+ *  -3  0.0000001543959154   -1791.5 ..-1279.5
+ *  -2  0.0010701394583782   -1279.5 .. -767.5
+ *  -1  0.1523201563502276    -767.5 .. -255.5
+ *   0  0.6932190995909575    -255.5 ..  255.5
+ *   1  0.1523201563502276     255.5 ..  767.5
+ *   2  0.0010701394583782     767.5 .. 1279.5
+ *   3  0.0000001543959154    1279.5 .. 1791.5
+ *
+ *  (i, k)  p
+ *  (0,-3)  0.0000001071761982
+ *  (0,-2)  0.0007428530629363
+ *  (0,-1)  0.1057352794589848
+ *  (0, 0)  0.4812082456968029
+ *  (0, 1)  0.1057352794589848
+ *  (0, 2)  0.0007428530629363
+ *  (0, 3)  0.0000001071761982
+ *
+ *  (1,-3)  0.0000000409574190
+ *  (1,-2)  0.0002838815396572
+ *  (1,-1)  0.0404067714417889
+ *  (1, 0)  0.1838938876339505
+ *  (1, 1)  0.0404067714417889
+ *  (1, 2)  0.0002838815396572
+ *  (1, 3)  0.0000000409574190
+ *
+ *  (2,-3)  0.0000000059340066
+ *  (2,-2)  0.0000411294211974
+ *  (2,-1)  0.0058542275199074
+ *  (2, 0)  0.0266429763951902
+ *  (2, 1)  0.0058542275199074
+ *  (2, 2)  0.0000411294211974
+ *  (2, 3)  0.0000000059340066
+ *
+ *  (3,-3)  0.0000000003218016
+ *  (3,-2)  0.0000022304512849
+ *  (3,-1)  0.0003174751531544
+ *  (3, 0)  0.0014448504064437
+ *  (3, 1)  0.0003174751531544
+ *  (3, 2)  0.0000022304512849
+ *  (3, 3)  0.0000000003218016
+ *
+ *  (4,-3)  0.0000000000064429
+ *  (4,-2)  0.0000000446563387
+ *  (4,-1)  0.0000063562374459
+ *  (4, 0)  0.0000289276567501
+ *  (4, 1)  0.0000063562374459
+ *  (4, 2)  0.0000000446563387
+ *  (4, 3)  0.0000000000064429
+ *
+ *  (5,-3)  0.0000000000000470
+ *  (5,-2)  0.0000000003261046
+ *  (5,-1)  0.0000000464166687
+ *  (5, 0)  0.0000002112453273
+ *  (5, 1)  0.0000000464166687
+ *  (5, 2)  0.0000000003261046
+ *  (5, 3)  0.0000000000000470
+ *
+ *  (6,-3)  0.0000000000000001
+ *  (6,-2)  0.0000000000008591
+ *  (6,-1)  0.0000000001222775
+ *  (6, 0)  0.0000000005564928
+ *  (6, 1)  0.0000000001222775
+ *  (6, 2)  0.0000000000008591
+ *  (6, 3)  0.0000000000000001
+ *
+ *  p_sum   0.9999999999999999
+ *
+ * entropy = 2.2879 bits/tuple (1171 bits)
+ */
+
+#include "bliss_huffman_code.h"
+
+static bliss_huffman_code_node_t nodes[] = {
+	{   1,  96,  -1 },  /*   0: */
+	{   2,  93,  -1 },  /*   1: */
+	{   3,   4,  -1 },  /*   2: */
+	{  -1,  -1,  10 },  /*   3: (1, 0)  3 bits */
+	{   5,   8,  -1 },  /*   4: */
+	{   6,   7,  -1 },  /*   5: */
+	{  -1,  -1,  11 },  /*   6: (1, 1)  5 bits */
+	{  -1,  -1,   9 },  /*   7: (1,-1)  5 bits */
+	{   9,  10,  -1 },  /*   8: */
+	{  -1,  -1,  17 },  /*   9: (2, 0)  5 bits */
+	{  11,  92,  -1 },  /*  10: */
+	{  12,  13,  -1 },  /*  11: */
+	{  -1,  -1,  16 },  /*  12: (2,-1)  7 bits */
+	{  14,  89,  -1 },  /*  13: */
+	{  15,  16,  -1 },  /*  14: */
+	{  -1,  -1,  24 },  /*  15: (3, 0)  9 bits */
+	{  17,  86,  -1 },  /*  16: */
+	{  18,  85,  -1 },  /*  17: */
+	{  19,  20,  -1 },  /*  18: */
+	{  -1,  -1,   8 },  /*  19: (1,-2) 12 bits */
+	{  21,  84,  -1 },  /*  20: */
+	{  22,  53,  -1 },  /*  21: */
+	{  23,  38,  -1 },  /*  22: */
+	{  24,  31,  -1 },  /*  23: */
+	{  25,  28,  -1 },  /*  24: */
+	{  26,  27,  -1 },  /*  25: */
+	{  -1,  -1,  15 },  /*  26: (2,-2) 18 bits */
+	{  -1,  -1,  31 },  /*  27: (4, 0) 18 bits */
+	{  29,  30,  -1 },  /*  28: */
+	{  -1,  -1,  32 },  /*  29: (4, 1) 18 bits */
+	{  -1,  -1,  30 },  /*  30: (4,-1) 18 bits */
+	{  32,  35,  -1 },  /*  31: */
+	{  33,  34,  -1 },  /*  32: */
+	{  -1,  -1,  26 },  /*  33: (3, 2) 18 bits */
+	{  -1,  -1,  22 },  /*  34: (3,-2) 18 bits */
+	{  36,  37,  -1 },  /*  35: */
+	{  -1,  -1,  38 },  /*  36: (5, 0) 18 bits */
+	{  -1,  -1,   6 },  /*  37: (0, 3) 18 bits */
+	{  39,  46,  -1 },  /*  38: */
+	{  40,  43,  -1 },  /*  39: */
+	{  41,  42,  -1 },  /*  40: */
+	{  -1,  -1,   0 },  /*  41: (0,-3) 18 bits */
+	{  -1,  -1,  39 },  /*  42: (5, 1) 18 bits */
+	{  44,  45,  -1 },  /*  43: */
+	{  -1,  -1,  37 },  /*  44: (5,-1) 18 bits */
+	{  -1,  -1,  33 },  /*  45: (4, 2) 18 bits */
+	{  47,  50,  -1 },  /*  46: */
+	{  48,  49,  -1 },  /*  47: */
+	{  -1,  -1,  29 },  /*  48: (4,-2) 18 bits */
+	{  -1,  -1,  13 },  /*  49: (1, 3) 18 bits */
+	{  51,  52,  -1 },  /*  50: */
+	{  -1,  -1,   7 },  /*  51: (1,-3) 18 bits */
+	{  -1,  -1,  20 },  /*  52: (2, 3) 18 bits */
+	{  54,  69,  -1 },  /*  53: */
+	{  55,  62,  -1 },  /*  54: */
+	{  56,  59,  -1 },  /*  55: */
+	{  57,  58,  -1 },  /*  56: */
+	{  -1,  -1,  14 },  /*  57: (2,-3) 18 bits */
+	{  -1,  -1,  45 },  /*  58: (6, 0) 18 bits */
+	{  60,  61,  -1 },  /*  59: */
+	{  -1,  -1,  40 },  /*  60: (5, 2) 18 bits */
+	{  -1,  -1,  36 },  /*  61: (5,-2) 18 bits */
+	{  63,  66,  -1 },  /*  62: */
+	{  64,  65,  -1 },  /*  63: */
+	{  -1,  -1,  27 },  /*  64: (3, 3) 18 bits */
+	{  -1,  -1,  21 },  /*  65: (3,-3) 18 bits */
+	{  67,  68,  -1 },  /*  66: */
+	{  -1,  -1,  46 },  /*  67: (6, 1) 18 bits */
+	{  -1,  -1,  44 },  /*  68: (6,-1) 18 bits */
+	{  70,  77,  -1 },  /*  69: */
+	{  71,  74,  -1 },  /*  70: */
+	{  72,  73,  -1 },  /*  71: */
+	{  -1,  -1,  34 },  /*  72: (4, 3) 18 bits */
+	{  -1,  -1,  28 },  /*  73: (4,-3) 18 bits */
+	{  75,  76,  -1 },  /*  74: */
+	{  -1,  -1,  47 },  /*  75: (6, 2) 18 bits */
+	{  -1,  -1,  43 },  /*  76: (6,-2) 18 bits */
+	{  78,  81,  -1 },  /*  77: */
+	{  79,  80,  -1 },  /*  78: */
+	{  -1,  -1,  41 },  /*  79: (5, 3) 18 bits */
+	{  -1,  -1,  35 },  /*  80: (5,-3) 18 bits */
+	{  82,  83,  -1 },  /*  81: */
+	{  -1,  -1,  48 },  /*  82: (6, 3) 18 bits */
+	{  -1,  -1,  42 },  /*  83: (6,-3) 18 bits */
+	{  -1,  -1,  19 },  /*  84: (2, 2) 13 bits */
+	{  -1,  -1,  25 },  /*  85: (3, 1) 11 bits */
+	{  87,  88,  -1 },  /*  86: */
+	{  -1,  -1,  23 },  /*  87: (3,-1) 11 bits */
+	{  -1,  -1,  12 },  /*  88: (1, 2) 11 bits */
+	{  90,  91,  -1 },  /*  89: */
+	{  -1,  -1,   5 },  /*  90: (0, 2)  9 bits */
+	{  -1,  -1,   1 },  /*  91: (0,-2)  9 bits */
+	{  -1,  -1,  18 },  /*  92: (2, 1)  6 bits */
+	{  94,  95,  -1 },  /*  93: */
+	{  -1,  -1,   4 },  /*  94: (0, 1)  3 bits */
+	{  -1,  -1,   2 },  /*  95: (0,-1)  3 bits */
+	{  -1,  -1,   3 },  /*  96: (0, 0)  1 bit  */
+};
+
+static bliss_huffman_code_tuple_t tuples[] = {
+	{ 59976, 18 },  /*   0: (0,-3) 001110101001001000 */
+	{   119,  9 },  /*   1: (0,-2) 001110111 */
+	{     3,  3 },  /*   2: (0,-1) 011 */
+	{     1,  1 },  /*   3: (0, 0) 1 */
+	{     2,  3 },  /*   4: (0, 1) 010 */
+	{   118,  9 },  /*   5: (0, 2) 001110110 */
+	{ 59975, 18 },  /*   6: (0, 3) 001110101001000111 */
+
+	{ 59982, 18 },  /*   7: (1,-3) 001110101001001110 */
+	{   936, 12 },  /*   8: (1,-2) 001110101000 */
+	{     5,  5 },  /*   9: (1,-1) 00101 */
+	{     0,  3 },  /*  10: (1, 0) 000 */
+	{     4,  5 },  /*  11: (1, 1) 00100 */
+	{   471, 11 },  /*  12: (1, 2) 00111010111 */
+	{ 59981, 18 },  /*  13: (1, 3) 001110101001001101 */
+
+	{ 59984, 18 },  /*  14: (2,-3) 001110101001010000 */
+	{ 59968, 18 },  /*  15: (2,-2) 001110101001000000 */
+	{    28,  7 },  /*  16: (2,-1) 0011100 */
+	{     6,  5 },  /*  17: (2, 0) 00110 */
+	{    15,  6 },  /*  18: (2, 1) 001111 */
+	{  1875, 13 },  /*  19: (2, 2) 0011101010011 */
+	{ 59983, 18 },  /*  20: (2, 3) 001110101001001111 */
+
+	{ 59989, 18 },  /*  21: (3,-3) 001110101001010101 */
+	{ 59973, 18 },  /*  22: (3,-2) 001110101001000101 */
+	{   470, 11 },  /*  23: (3,-1) 00111010110 */
+	{   116,  9 },  /*  24: (3, 0) 001110100 */
+	{   469, 11 },  /*  25: (3, 1) 00111010101 */
+	{ 59972, 18 },  /*  26: (3, 2) 001110101001000100 */
+	{ 59988, 18 },  /*  27: (3, 3) 001110101001010100 */
+
+	{ 59993, 18 },  /*  28: (4,-3) 001110101001011001 */
+	{ 59980, 18 },  /*  29: (4,-2) 001110101001001100 */
+	{ 59971, 18 },  /*  30: (4,-1) 001110101001000011 */
+	{ 59969, 18 },  /*  31: (4, 0) 001110101001000001 */
+	{ 59970, 18 },  /*  32: (4, 1) 001110101001000010 */
+	{ 59979, 18 },  /*  33: (4, 2) 001110101001001011 */
+	{ 59992, 18 },  /*  34: (4, 3) 001110101001011000 */
+
+	{ 59997, 18 },  /*  35: (5,-3) 001110101001011101 */
+	{ 59987, 18 },  /*  36: (5,-2) 001110101001010011 */
+	{ 59978, 18 },  /*  37: (5,-1) 001110101001001010 */
+	{ 59974, 18 },  /*  38: (5, 0) 001110101001000110 */
+	{ 59977, 18 },  /*  39: (5, 1) 001110101001001001 */
+	{ 59986, 18 },  /*  40: (5, 2) 001110101001010010 */
+	{ 59996, 18 },  /*  41: (5, 3) 001110101001011100 */
+
+	{ 59999, 18 },  /*  42: (6,-3) 001110101001011111 */
+	{ 59995, 18 },  /*  43: (6,-2) 001110101001011011 */
+	{ 59991, 18 },  /*  44: (6,-1) 001110101001010111 */
+	{ 59985, 18 },  /*  45: (6, 0) 001110101001010001 */
+	{ 59990, 18 },  /*  46: (6, 1) 001110101001010110 */
+	{ 59994, 18 },  /*  47: (6, 2) 001110101001011010 */
+	{ 59998, 18 },  /*  48: (6, 3) 001110101001011110 */
+};
+
+/* code_length = 2.3227 bits/tuple (1190 bits) */
+
+bliss_huffman_code_t bliss_huffman_code_3 = {
+	.n_z1 = 7,
+	.n_z2 = 4,
+	.tuples = tuples,
+	.nodes  = nodes
+};
diff --git a/src/libstrongswan/plugins/bliss/bliss_huffman_code_4.c b/src/libstrongswan/plugins/bliss/bliss_huffman_code_4.c
new file mode 100644
index 0000000..c4f709c
--- /dev/null
+++ b/src/libstrongswan/plugins/bliss/bliss_huffman_code_4.c
@@ -0,0 +1,435 @@
+/*
+ * Copyright (C) 2014 Andreas Steffen
+ * HSR Hochschule fuer Technik Rapperswil
+ *
+ * Optimum Huffman code for BLISS-X signatures
+ *
+ * This file has been automatically generated by the bliss_huffman utility
+ * Do not edit manually!
+ */
+
+/*
+ * Design: sigma = 271
+ *
+ *   i  p_z1[i]
+ *   0  0.6551621276225426         0 ..  256
+ *   1  0.2859860850630749       256 ..  512
+ *   2  0.0542541135599810       512 ..  768
+ *   3  0.0044399624814222       768 .. 1024
+ *   4  0.0001553928373912      1024 .. 1280
+ *   5  0.0000023066278552      1280 .. 1536
+ *   6  0.0000000118077330      1536 .. 1613
+ *
+ *   k  p_z2[k]  dx = 256
+ *  -6  0.0000001026458579   -1663.5 ..-1407.5
+ *  -5  0.0000106295703648   -1407.5 ..-1151.5
+ *  -4  0.0004651193817805   -1151.5 .. -895.5
+ *  -3  0.0086670703658387    -895.5 .. -639.5
+ *  -2  0.0693723939195647    -639.5 .. -383.5
+ *  -1  0.2404908493690626    -383.5 .. -127.5
+ *   0  0.3619876694950614    -127.5 ..  127.5
+ *   1  0.2404908493690626     127.5 ..  383.5
+ *   2  0.0693723939195647     383.5 ..  639.5
+ *   3  0.0086670703658387     639.5 ..  895.5
+ *   4  0.0004651193817805     895.5 .. 1151.5
+ *   5  0.0000106295703648    1151.5 .. 1407.5
+ *   6  0.0000001026458579    1407.5 .. 1663.5
+ *
+ *  (i, k)  p
+ *  (0,-6)  0.0000000672496787
+ *  (0,-5)  0.0000069640919359
+ *  (0,-4)  0.0003047286037658
+ *  (0,-3)  0.0056783362611372
+ *  (0,-2)  0.0454501651986111
+ *  (0,-1)  0.1575604965463875
+ *  (0, 0)  0.2371606117195102
+ *  (0, 1)  0.1575604965463875
+ *  (0, 2)  0.0454501651986111
+ *  (0, 3)  0.0056783362611372
+ *  (0, 4)  0.0003047286037658
+ *  (0, 5)  0.0000069640919359
+ *  (0, 6)  0.0000000672496787
+ *
+ *  (1,-6)  0.0000000293552870
+ *  (1,-5)  0.0000030399092145
+ *  (1,-4)  0.0001330176710824
+ *  (1,-3)  0.0024786615228924
+ *  (1,-2)  0.0198395393485098
+ *  (1,-1)  0.0687770365045519
+ *  (1, 0)  0.1035234364399989
+ *  (1, 1)  0.0687770365045519
+ *  (1, 2)  0.0198395393485098
+ *  (1, 3)  0.0024786615228924
+ *  (1, 4)  0.0001330176710824
+ *  (1, 5)  0.0000030399092145
+ *  (1, 6)  0.0000000293552870
+ *
+ *  (2,-6)  0.0000000055689600
+ *  (2,-5)  0.0000005766979177
+ *  (2,-4)  0.0000252346397581
+ *  (2,-3)  0.0004702242198606
+ *  (2,-2)  0.0037637377376398
+ *  (2,-1)  0.0130476178518054
+ *  (2, 0)  0.0196393201280979
+ *  (2, 1)  0.0130476178518054
+ *  (2, 2)  0.0037637377376398
+ *  (2, 3)  0.0004702242198606
+ *  (2, 4)  0.0000252346397581
+ *  (2, 5)  0.0000005766979177
+ *  (2, 6)  0.0000000055689600
+ *
+ *  (3,-6)  0.0000000004557438
+ *  (3,-5)  0.0000000471948936
+ *  (3,-4)  0.0000020651126045
+ *  (3,-3)  0.0000384814672482
+ *  (3,-2)  0.0003080108262493
+ *  (3,-1)  0.0010677703483240
+ *  (3, 0)  0.0016072116712955
+ *  (3, 1)  0.0010677703483240
+ *  (3, 2)  0.0003080108262493
+ *  (3, 3)  0.0000384814672482
+ *  (3, 4)  0.0000020651126045
+ *  (3, 5)  0.0000000471948936
+ *  (3, 6)  0.0000000004557438
+ *
+ *  (4,-6)  0.0000000000159504
+ *  (4,-5)  0.0000000016517591
+ *  (4,-4)  0.0000000722762205
+ *  (4,-3)  0.0000013468006560
+ *  (4,-2)  0.0000107799731278
+ *  (4,-1)  0.0000373705554501
+ *  (4, 0)  0.0000562502910635
+ *  (4, 1)  0.0000373705554501
+ *  (4, 2)  0.0000107799731278
+ *  (4, 3)  0.0000013468006560
+ *  (4, 4)  0.0000000722762205
+ *  (4, 5)  0.0000000016517591
+ *  (4, 6)  0.0000000000159504
+ *
+ *  (5,-6)  0.0000000000002368
+ *  (5,-5)  0.0000000000245185
+ *  (5,-4)  0.0000000010728573
+ *  (5,-3)  0.0000000199917059
+ *  (5,-2)  0.0000001600162962
+ *  (5,-1)  0.0000005547228921
+ *  (5, 0)  0.0000008349708417
+ *  (5, 1)  0.0000005547228921
+ *  (5, 2)  0.0000001600162962
+ *  (5, 3)  0.0000000199917059
+ *  (5, 4)  0.0000000010728573
+ *  (5, 5)  0.0000000000245185
+ *  (5, 6)  0.0000000000002368
+ *
+ *  (6,-6)  0.0000000000000012
+ *  (6,-5)  0.0000000000001255
+ *  (6,-4)  0.0000000000054920
+ *  (6,-3)  0.0000000001023385
+ *  (6,-2)  0.0000000008191307
+ *  (6,-1)  0.0000000028396517
+ *  (6, 0)  0.0000000042742538
+ *  (6, 1)  0.0000000028396517
+ *  (6, 2)  0.0000000008191307
+ *  (6, 3)  0.0000000001023385
+ *  (6, 4)  0.0000000000054920
+ *  (6, 5)  0.0000000000001255
+ *  (6, 6)  0.0000000000000012
+ *
+ *  p_sum   1.0000000000000011
+ *
+ * entropy = 3.3640 bits/tuple (1722 bits)
+ */
+
+#include "bliss_huffman_code.h"
+
+static bliss_huffman_code_node_t nodes[] = {
+	{   1, 160,  -1 },  /*   0: */
+	{   2,   5,  -1 },  /*   1: */
+	{   3,   4,  -1 },  /*   2: */
+	{  -1,  -1,   7 },  /*   3: (0, 1)  3 bits */
+	{  -1,  -1,   5 },  /*   4: (0,-1)  3 bits */
+	{   6, 157,  -1 },  /*   5: */
+	{   7, 156,  -1 },  /*   6: */
+	{   8,  11,  -1 },  /*   7: */
+	{   9,  10,  -1 },  /*   8: */
+	{  -1,  -1,  17 },  /*   9: (1,-2)  6 bits */
+	{  -1,  -1,  32 },  /*  10: (2, 0)  6 bits */
+	{  12, 155,  -1 },  /*  11: */
+	{  13,  18,  -1 },  /*  12: */
+	{  14,  15,  -1 },  /*  13: */
+	{  -1,  -1,   3 },  /*  14: (0,-3)  8 bits */
+	{  16,  17,  -1 },  /*  15: */
+	{  -1,  -1,  22 },  /*  16: (1, 3)  9 bits */
+	{  -1,  -1,  16 },  /*  17: (1,-3)  9 bits */
+	{  19, 154,  -1 },  /*  18: */
+	{  20,  23,  -1 },  /*  19: */
+	{  21,  22,  -1 },  /*  20: */
+	{  -1,  -1,  46 },  /*  21: (3, 1) 10 bits */
+	{  -1,  -1,  44 },  /*  22: (3,-1) 10 bits */
+	{  24, 151,  -1 },  /*  23: */
+	{  25,  88,  -1 },  /*  24: */
+	{  26,  57,  -1 },  /*  25: */
+	{  27,  42,  -1 },  /*  26: */
+	{  28,  35,  -1 },  /*  27: */
+	{  29,  32,  -1 },  /*  28: */
+	{  30,  31,  -1 },  /*  29: */
+	{  -1,  -1,   2 },  /*  30: (0,-4) 16 bits */
+	{  -1,  -1,  23 },  /*  31: (1, 4) 16 bits */
+	{  33,  34,  -1 },  /*  32: */
+	{  -1,  -1,  15 },  /*  33: (1,-4) 16 bits */
+	{  -1,  -1,  58 },  /*  34: (4, 0) 16 bits */
+	{  36,  39,  -1 },  /*  35: */
+	{  37,  38,  -1 },  /*  36: */
+	{  -1,  -1,  48 },  /*  37: (3, 3) 16 bits */
+	{  -1,  -1,  42 },  /*  38: (3,-3) 16 bits */
+	{  40,  41,  -1 },  /*  39: */
+	{  -1,  -1,  59 },  /*  40: (4, 1) 16 bits */
+	{  -1,  -1,  57 },  /*  41: (4,-1) 16 bits */
+	{  43,  50,  -1 },  /*  42: */
+	{  44,  47,  -1 },  /*  43: */
+	{  45,  46,  -1 },  /*  44: */
+	{  -1,  -1,  36 },  /*  45: (2, 4) 16 bits */
+	{  -1,  -1,  28 },  /*  46: (2,-4) 16 bits */
+	{  48,  49,  -1 },  /*  47: */
+	{  -1,  -1,  60 },  /*  48: (4, 2) 16 bits */
+	{  -1,  -1,  56 },  /*  49: (4,-2) 16 bits */
+	{  51,  54,  -1 },  /*  50: */
+	{  52,  53,  -1 },  /*  51: */
+	{  -1,  -1,  11 },  /*  52: (0, 5) 16 bits */
+	{  -1,  -1,   1 },  /*  53: (0,-5) 16 bits */
+	{  55,  56,  -1 },  /*  54: */
+	{  -1,  -1,  24 },  /*  55: (1, 5) 16 bits */
+	{  -1,  -1,  14 },  /*  56: (1,-5) 16 bits */
+	{  58,  73,  -1 },  /*  57: */
+	{  59,  66,  -1 },  /*  58: */
+	{  60,  63,  -1 },  /*  59: */
+	{  61,  62,  -1 },  /*  60: */
+	{  -1,  -1,  49 },  /*  61: (3, 4) 16 bits */
+	{  -1,  -1,  41 },  /*  62: (3,-4) 16 bits */
+	{  64,  65,  -1 },  /*  63: */
+	{  -1,  -1,  61 },  /*  64: (4, 3) 16 bits */
+	{  -1,  -1,  55 },  /*  65: (4,-3) 16 bits */
+	{  67,  70,  -1 },  /*  66: */
+	{  68,  69,  -1 },  /*  67: */
+	{  -1,  -1,  71 },  /*  68: (5, 0) 16 bits */
+	{  -1,  -1,  37 },  /*  69: (2, 5) 16 bits */
+	{  71,  72,  -1 },  /*  70: */
+	{  -1,  -1,  27 },  /*  71: (2,-5) 16 bits */
+	{  -1,  -1,  72 },  /*  72: (5, 1) 16 bits */
+	{  74,  81,  -1 },  /*  73: */
+	{  75,  78,  -1 },  /*  74: */
+	{  76,  77,  -1 },  /*  75: */
+	{  -1,  -1,  70 },  /*  76: (5,-1) 16 bits */
+	{  -1,  -1,  73 },  /*  77: (5, 2) 16 bits */
+	{  79,  80,  -1 },  /*  78: */
+	{  -1,  -1,  69 },  /*  79: (5,-2) 16 bits */
+	{  -1,  -1,  62 },  /*  80: (4, 4) 16 bits */
+	{  82,  85,  -1 },  /*  81: */
+	{  83,  84,  -1 },  /*  82: */
+	{  -1,  -1,  54 },  /*  83: (4,-4) 16 bits */
+	{  -1,  -1,  12 },  /*  84: (0, 6) 16 bits */
+	{  86,  87,  -1 },  /*  85: */
+	{  -1,  -1,   0 },  /*  86: (0,-6) 16 bits */
+	{  -1,  -1,  50 },  /*  87: (3, 5) 16 bits */
+	{  89, 120,  -1 },  /*  88: */
+	{  90, 105,  -1 },  /*  89: */
+	{  91,  98,  -1 },  /*  90: */
+	{  92,  95,  -1 },  /*  91: */
+	{  93,  94,  -1 },  /*  92: */
+	{  -1,  -1,  40 },  /*  93: (3,-5) 16 bits */
+	{  -1,  -1,  25 },  /*  94: (1, 6) 16 bits */
+	{  96,  97,  -1 },  /*  95: */
+	{  -1,  -1,  13 },  /*  96: (1,-6) 16 bits */
+	{  -1,  -1,  74 },  /*  97: (5, 3) 16 bits */
+	{  99, 102,  -1 },  /*  98: */
+	{ 100, 101,  -1 },  /*  99: */
+	{  -1,  -1,  68 },  /* 100: (5,-3) 16 bits */
+	{  -1,  -1,  38 },  /* 101: (2, 6) 16 bits */
+	{ 103, 104,  -1 },  /* 102: */
+	{  -1,  -1,  26 },  /* 103: (2,-6) 16 bits */
+	{  -1,  -1,  84 },  /* 104: (6, 0) 16 bits */
+	{ 106, 113,  -1 },  /* 105: */
+	{ 107, 110,  -1 },  /* 106: */
+	{ 108, 109,  -1 },  /* 107: */
+	{  -1,  -1,  85 },  /* 108: (6, 1) 16 bits */
+	{  -1,  -1,  83 },  /* 109: (6,-1) 16 bits */
+	{ 111, 112,  -1 },  /* 110: */
+	{  -1,  -1,  63 },  /* 111: (4, 5) 16 bits */
+	{  -1,  -1,  53 },  /* 112: (4,-5) 16 bits */
+	{ 114, 117,  -1 },  /* 113: */
+	{ 115, 116,  -1 },  /* 114: */
+	{  -1,  -1,  75 },  /* 115: (5, 4) 16 bits */
+	{  -1,  -1,  67 },  /* 116: (5,-4) 16 bits */
+	{ 118, 119,  -1 },  /* 117: */
+	{  -1,  -1,  86 },  /* 118: (6, 2) 16 bits */
+	{  -1,  -1,  82 },  /* 119: (6,-2) 16 bits */
+	{ 121, 136,  -1 },  /* 120: */
+	{ 122, 129,  -1 },  /* 121: */
+	{ 123, 126,  -1 },  /* 122: */
+	{ 124, 125,  -1 },  /* 123: */
+	{  -1,  -1,  51 },  /* 124: (3, 6) 16 bits */
+	{  -1,  -1,  39 },  /* 125: (3,-6) 16 bits */
+	{ 127, 128,  -1 },  /* 126: */
+	{  -1,  -1,  87 },  /* 127: (6, 3) 16 bits */
+	{  -1,  -1,  81 },  /* 128: (6,-3) 16 bits */
+	{ 130, 133,  -1 },  /* 129: */
+	{ 131, 132,  -1 },  /* 130: */
+	{  -1,  -1,  76 },  /* 131: (5, 5) 16 bits */
+	{  -1,  -1,  66 },  /* 132: (5,-5) 16 bits */
+	{ 134, 135,  -1 },  /* 133: */
+	{  -1,  -1,  64 },  /* 134: (4, 6) 16 bits */
+	{  -1,  -1,  52 },  /* 135: (4,-6) 16 bits */
+	{ 137, 144,  -1 },  /* 136: */
+	{ 138, 141,  -1 },  /* 137: */
+	{ 139, 140,  -1 },  /* 138: */
+	{  -1,  -1,  88 },  /* 139: (6, 4) 16 bits */
+	{  -1,  -1,  80 },  /* 140: (6,-4) 16 bits */
+	{ 142, 143,  -1 },  /* 141: */
+	{  -1,  -1,  77 },  /* 142: (5, 6) 16 bits */
+	{  -1,  -1,  65 },  /* 143: (5,-6) 16 bits */
+	{ 145, 148,  -1 },  /* 144: */
+	{ 146, 147,  -1 },  /* 145: */
+	{  -1,  -1,  89 },  /* 146: (6, 5) 16 bits */
+	{  -1,  -1,  79 },  /* 147: (6,-5) 16 bits */
+	{ 149, 150,  -1 },  /* 148: */
+	{  -1,  -1,  90 },  /* 149: (6, 6) 16 bits */
+	{  -1,  -1,  78 },  /* 150: (6,-6) 16 bits */
+	{ 152, 153,  -1 },  /* 151: */
+	{  -1,  -1,  29 },  /* 152: (2,-3) 11 bits */
+	{  -1,  -1,  47 },  /* 153: (3, 2) 11 bits */
+	{  -1,  -1,  34 },  /* 154: (2, 2)  8 bits */
+	{  -1,  -1,  33 },  /* 155: (2, 1)  6 bits */
+	{  -1,  -1,  20 },  /* 156: (1, 1)  4 bits */
+	{ 158, 159,  -1 },  /* 157: */
+	{  -1,  -1,  18 },  /* 158: (1,-1)  4 bits */
+	{  -1,  -1,   8 },  /* 159: (0, 2)  4 bits */
+	{ 161, 162,  -1 },  /* 160: */
+	{  -1,  -1,   6 },  /* 161: (0, 0)  2 bits */
+	{ 163, 164,  -1 },  /* 162: */
+	{  -1,  -1,  19 },  /* 163: (1, 0)  3 bits */
+	{ 165, 166,  -1 },  /* 164: */
+	{  -1,  -1,   4 },  /* 165: (0,-2)  4 bits */
+	{ 167, 180,  -1 },  /* 166: */
+	{ 168, 169,  -1 },  /* 167: */
+	{  -1,  -1,  31 },  /* 168: (2,-1)  6 bits */
+	{ 170, 179,  -1 },  /* 169: */
+	{ 171, 172,  -1 },  /* 170: */
+	{  -1,  -1,  30 },  /* 171: (2,-2)  8 bits */
+	{ 173, 174,  -1 },  /* 172: */
+	{  -1,  -1,  45 },  /* 173: (3, 0)  9 bits */
+	{ 175, 178,  -1 },  /* 174: */
+	{ 176, 177,  -1 },  /* 175: */
+	{  -1,  -1,  43 },  /* 176: (3,-2) 11 bits */
+	{  -1,  -1,  10 },  /* 177: (0, 4) 11 bits */
+	{  -1,  -1,  35 },  /* 178: (2, 3) 10 bits */
+	{  -1,  -1,   9 },  /* 179: (0, 3)  7 bits */
+	{  -1,  -1,  21 },  /* 180: (1, 2)  5 bits */
+};
+
+static bliss_huffman_code_tuple_t tuples[] = {
+	{ 19102, 16 },  /*   0: (0,-6) 0100101010011110 */
+	{ 19085, 16 },  /*   1: (0,-5) 0100101010001101 */
+	{ 19072, 16 },  /*   2: (0,-4) 0100101010000000 */
+	{    72,  8 },  /*   3: (0,-3) 01001000 */
+	{    14,  4 },  /*   4: (0,-2) 1110 */
+	{     1,  3 },  /*   5: (0,-1) 001 */
+	{     2,  2 },  /*   6: (0, 0) 10 */
+	{     0,  3 },  /*   7: (0, 1) 000 */
+	{     7,  4 },  /*   8: (0, 2) 0111 */
+	{   123,  7 },  /*   9: (0, 3) 1111011 */
+	{  1965, 11 },  /*  10: (0, 4) 11110101101 */
+	{ 19084, 16 },  /*  11: (0, 5) 0100101010001100 */
+	{ 19101, 16 },  /*  12: (0, 6) 0100101010011101 */
+
+	{ 19106, 16 },  /*  13: (1,-6) 0100101010100010 */
+	{ 19087, 16 },  /*  14: (1,-5) 0100101010001111 */
+	{ 19074, 16 },  /*  15: (1,-4) 0100101010000010 */
+	{   147,  9 },  /*  16: (1,-3) 010010011 */
+	{    16,  6 },  /*  17: (1,-2) 010000 */
+	{     6,  4 },  /*  18: (1,-1) 0110 */
+	{     6,  3 },  /*  19: (1, 0) 110 */
+	{     5,  4 },  /*  20: (1, 1) 0101 */
+	{    31,  5 },  /*  21: (1, 2) 11111 */
+	{   146,  9 },  /*  22: (1, 3) 010010010 */
+	{ 19073, 16 },  /*  23: (1, 4) 0100101010000001 */
+	{ 19086, 16 },  /*  24: (1, 5) 0100101010001110 */
+	{ 19105, 16 },  /*  25: (1, 6) 0100101010100001 */
+
+	{ 19110, 16 },  /*  26: (2,-6) 0100101010100110 */
+	{ 19094, 16 },  /*  27: (2,-5) 0100101010010110 */
+	{ 19081, 16 },  /*  28: (2,-4) 0100101010001001 */
+	{   598, 11 },  /*  29: (2,-3) 01001010110 */
+	{   244,  8 },  /*  30: (2,-2) 11110100 */
+	{    60,  6 },  /*  31: (2,-1) 111100 */
+	{    17,  6 },  /*  32: (2, 0) 010001 */
+	{    19,  6 },  /*  33: (2, 1) 010011 */
+	{    75,  8 },  /*  34: (2, 2) 01001011 */
+	{   983, 10 },  /*  35: (2, 3) 1111010111 */
+	{ 19080, 16 },  /*  36: (2, 4) 0100101010001000 */
+	{ 19093, 16 },  /*  37: (2, 5) 0100101010010101 */
+	{ 19109, 16 },  /*  38: (2, 6) 0100101010100101 */
+
+	{ 19121, 16 },  /*  39: (3,-6) 0100101010110001 */
+	{ 19104, 16 },  /*  40: (3,-5) 0100101010100000 */
+	{ 19089, 16 },  /*  41: (3,-4) 0100101010010001 */
+	{ 19077, 16 },  /*  42: (3,-3) 0100101010000101 */
+	{  1964, 11 },  /*  43: (3,-2) 11110101100 */
+	{   297, 10 },  /*  44: (3,-1) 0100101001 */
+	{   490,  9 },  /*  45: (3, 0) 111101010 */
+	{   296, 10 },  /*  46: (3, 1) 0100101000 */
+	{   599, 11 },  /*  47: (3, 2) 01001010111 */
+	{ 19076, 16 },  /*  48: (3, 3) 0100101010000100 */
+	{ 19088, 16 },  /*  49: (3, 4) 0100101010010000 */
+	{ 19103, 16 },  /*  50: (3, 5) 0100101010011111 */
+	{ 19120, 16 },  /*  51: (3, 6) 0100101010110000 */
+
+	{ 19127, 16 },  /*  52: (4,-6) 0100101010110111 */
+	{ 19115, 16 },  /*  53: (4,-5) 0100101010101011 */
+	{ 19100, 16 },  /*  54: (4,-4) 0100101010011100 */
+	{ 19091, 16 },  /*  55: (4,-3) 0100101010010011 */
+	{ 19083, 16 },  /*  56: (4,-2) 0100101010001011 */
+	{ 19079, 16 },  /*  57: (4,-1) 0100101010000111 */
+	{ 19075, 16 },  /*  58: (4, 0) 0100101010000011 */
+	{ 19078, 16 },  /*  59: (4, 1) 0100101010000110 */
+	{ 19082, 16 },  /*  60: (4, 2) 0100101010001010 */
+	{ 19090, 16 },  /*  61: (4, 3) 0100101010010010 */
+	{ 19099, 16 },  /*  62: (4, 4) 0100101010011011 */
+	{ 19114, 16 },  /*  63: (4, 5) 0100101010101010 */
+	{ 19126, 16 },  /*  64: (4, 6) 0100101010110110 */
+
+	{ 19131, 16 },  /*  65: (5,-6) 0100101010111011 */
+	{ 19125, 16 },  /*  66: (5,-5) 0100101010110101 */
+	{ 19117, 16 },  /*  67: (5,-4) 0100101010101101 */
+	{ 19108, 16 },  /*  68: (5,-3) 0100101010100100 */
+	{ 19098, 16 },  /*  69: (5,-2) 0100101010011010 */
+	{ 19096, 16 },  /*  70: (5,-1) 0100101010011000 */
+	{ 19092, 16 },  /*  71: (5, 0) 0100101010010100 */
+	{ 19095, 16 },  /*  72: (5, 1) 0100101010010111 */
+	{ 19097, 16 },  /*  73: (5, 2) 0100101010011001 */
+	{ 19107, 16 },  /*  74: (5, 3) 0100101010100011 */
+	{ 19116, 16 },  /*  75: (5, 4) 0100101010101100 */
+	{ 19124, 16 },  /*  76: (5, 5) 0100101010110100 */
+	{ 19130, 16 },  /*  77: (5, 6) 0100101010111010 */
+
+	{ 19135, 16 },  /*  78: (6,-6) 0100101010111111 */
+	{ 19133, 16 },  /*  79: (6,-5) 0100101010111101 */
+	{ 19129, 16 },  /*  80: (6,-4) 0100101010111001 */
+	{ 19123, 16 },  /*  81: (6,-3) 0100101010110011 */
+	{ 19119, 16 },  /*  82: (6,-2) 0100101010101111 */
+	{ 19113, 16 },  /*  83: (6,-1) 0100101010101001 */
+	{ 19111, 16 },  /*  84: (6, 0) 0100101010100111 */
+	{ 19112, 16 },  /*  85: (6, 1) 0100101010101000 */
+	{ 19118, 16 },  /*  86: (6, 2) 0100101010101110 */
+	{ 19122, 16 },  /*  87: (6, 3) 0100101010110010 */
+	{ 19128, 16 },  /*  88: (6, 4) 0100101010111000 */
+	{ 19132, 16 },  /*  89: (6, 5) 0100101010111100 */
+	{ 19134, 16 },  /*  90: (6, 6) 0100101010111110 */
+};
+
+/* code_length = 3.3967 bits/tuple (1740 bits) */
+
+bliss_huffman_code_t bliss_huffman_code_4 = {
+	.n_z1 = 7,
+	.n_z2 = 7,
+	.tuples = tuples,
+	.nodes  = nodes
+};
diff --git a/src/libstrongswan/plugins/bliss/bliss_huffman_coder.c b/src/libstrongswan/plugins/bliss/bliss_huffman_coder.c
new file mode 100644
index 0000000..018ae0e
--- /dev/null
+++ b/src/libstrongswan/plugins/bliss/bliss_huffman_coder.c
@@ -0,0 +1,138 @@
+/*
+ * 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;https://www.hsr.ch/HSR-intern-Anmeldung.4409.0.html?&no_cache=1 without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * for more details.
+ */
+
+#include "bliss_huffman_coder.h"
+
+typedef struct private_bliss_huffman_coder_t private_bliss_huffman_coder_t;
+
+/**
+ * Private data structure for bliss_huffman_coder_t object
+ */
+struct private_bliss_huffman_coder_t {
+	/**
+	 * Public interface.
+	 */
+	bliss_huffman_coder_t public;
+
+	/**
+	 * Bitpacker to write to or read from
+	 */
+	bliss_bitpacker_t *packer;
+
+	/**
+	 * Huffman code table to be used
+	 */
+	bliss_huffman_code_t *code;
+
+	/**
+     * Maximum index into tuples table
+	 */
+	int index_max;
+
+	/**
+     * Number of encoded or decoded bits
+	 */
+	size_t bits;
+
+};
+
+METHOD(bliss_huffman_coder_t, get_bits, size_t,
+	private_bliss_huffman_coder_t *this)
+{
+	return this->bits;
+}
+
+METHOD(bliss_huffman_coder_t, encode, bool,
+	private_bliss_huffman_coder_t *this, int32_t z1, int16_t z2)
+{
+	uint32_t code;
+	uint16_t bits;
+	int index;
+
+	index = z1 * (2*this->code->n_z2 - 1) + z2 + this->code->n_z2 - 1;
+	if (index >= this->index_max)
+	{
+		DBG1(DBG_LIB, "index exceeded in Huffman encoding table");
+		return FALSE;
+	}
+	code = this->code->tuples[index].code;
+	bits = this->code->tuples[index].bits;
+	if (!this->packer->write_bits(this->packer, code, bits))
+	{
+		DBG1(DBG_LIB, "bitpacker exceeded its buffer");
+		return FALSE;
+	}
+	this->bits += bits;
+
+	return TRUE;
+}
+
+METHOD(bliss_huffman_coder_t, decode, bool,
+	private_bliss_huffman_coder_t *this, int32_t *z1, int16_t *z2)
+{
+	bliss_huffman_code_node_t *node;
+	uint32_t bit;
+
+	node = this->code->nodes;
+	while (node->tuple == BLISS_HUFFMAN_CODE_NO_TUPLE)
+	{
+		if (node->node_0 == BLISS_HUFFMAN_CODE_NO_NODE ||
+			node->node_1 == BLISS_HUFFMAN_CODE_NO_NODE)
+		{
+			DBG1(DBG_LIB, "error in Huffman decoding table");
+			return FALSE;
+		}
+		if (!this->packer->read_bits(this->packer, &bit, 1))
+		{
+			DBG1(DBG_LIB, "bitpacker depleted its buffer");
+			return FALSE;
+		}
+		node = &this->code->nodes[bit ? node->node_1 : node->node_0];
+		this->bits++;
+	}
+	*z1 = node->tuple / (2*this->code->n_z2 - 1);
+	*z2 = node->tuple - (2*this->code->n_z2 - 1) * (*z1) - this->code->n_z2 + 1;
+
+	return TRUE;
+}
+
+METHOD(bliss_huffman_coder_t, destroy, void,
+	private_bliss_huffman_coder_t *this)
+{
+	free(this);
+}
+
+/**
+ * See header.
+ */
+bliss_huffman_coder_t *bliss_huffman_coder_create(bliss_huffman_code_t *code,
+												  bliss_bitpacker_t *packer)
+{
+	private_bliss_huffman_coder_t *this;
+
+	INIT(this,
+		.public = {
+			.get_bits = _get_bits,
+			.encode = _encode,
+			.decode = _decode,
+			.destroy = _destroy,
+		},
+		.packer = packer,
+		.code = code,
+		.index_max = (2*code->n_z2 - 1) * code->n_z1,		
+	);
+
+	return &this->public;
+}
diff --git a/src/libstrongswan/plugins/bliss/bliss_huffman_coder.h b/src/libstrongswan/plugins/bliss/bliss_huffman_coder.h
new file mode 100644
index 0000000..59abc49
--- /dev/null
+++ b/src/libstrongswan/plugins/bliss/bliss_huffman_coder.h
@@ -0,0 +1,77 @@
+/*
+ * 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.
+ */
+
+/**
+ * @defgroup bliss_huffman_coder bliss_huffman_coder
+ * @{ @ingroup bliss_p
+ */
+
+#ifndef BLISS_HUFFMAN_CODER_H_
+#define BLISS_HUFFMAN_CODER_H_
+
+#include "bliss_huffman_code.h"
+#include "bliss_bitpacker.h"
+
+#include <library.h>
+
+typedef struct bliss_huffman_coder_t bliss_huffman_coder_t;
+
+/**
+ * Encodes and decodes binary Huffman codes
+ */
+struct bliss_huffman_coder_t {
+
+	/**
+	 * Get number of encoded or decoded bits
+	 *
+	 * @result			Number of bits
+	 */
+	size_t (*get_bits)(bliss_huffman_coder_t *this);
+
+	/**
+	 * Encode a (z1, z2) tuple using a Huffman code
+	 *
+	 * @param z1		z1 value to be encoded
+	 * @param z2		z2 value to be encoded
+	 * @result			TRUE if value could be encoded
+	 */
+	bool (*encode)(bliss_huffman_coder_t *this, int32_t z1, int16_t z2);
+
+
+	/**
+	 * Decode a (z1, z2) tuple using a Huffman code
+	 *
+	 * @param z1		Decoded z1 value returned
+	 * @param z2		Decoded z2 value returned
+	 * @result			TRUE if value could be decoded from bitpacker
+	 */
+	bool (*decode)(bliss_huffman_coder_t *this, int32_t *z1, int16_t *z2);
+
+	/**
+	 * Destroy bliss_huffman_coder_t object
+	 */
+	void (*destroy)(bliss_huffman_coder_t *this);
+};
+
+/**
+ * Create a bliss_huffman_coder_t object
+ *
+ * @param code			Huffman code table
+ * @param packer		Bitpacker to write to or read from
+ */
+bliss_huffman_coder_t* bliss_huffman_coder_create(bliss_huffman_code_t *code,
+												  bliss_bitpacker_t *packer);
+
+#endif /** BLISS_HUFFMAN_CODER_H_ @}*/
diff --git a/src/libstrongswan/plugins/bliss/bliss_param_set.c b/src/libstrongswan/plugins/bliss/bliss_param_set.c
new file mode 100644
index 0000000..3781a58
--- /dev/null
+++ b/src/libstrongswan/plugins/bliss/bliss_param_set.c
@@ -0,0 +1,339 @@
+/*
+ * 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.
+ */
+
+#include "bliss_param_set.h"
+
+#include <asn1/oid.h>
+
+ENUM(bliss_param_set_id_names, BLISS_I, BLISS_B_IV,
+	"BLISS-I",
+	"BLISS-II",
+	"BLISS-III",
+	"BLISS-IV",
+	"BLISS-B-I",
+	"BLISS-B-II",
+	"BLISS-B-III",
+	"BLISS-B-IV"
+);
+
+/**
+ * sigma = 215, k_sigma = ceiling[ sqrt(2*ln 2) * sigma ] = 254
+ *
+ * c[i] = exp(-2^i/f), i = 0..20, with f = k_sigma^2 / ln 2 = 93'076.9
+ */
+static uint8_t c_bliss_i[] = {
+	255, 255,  75, 191, 247,  94,  30,  51, 147, 246,  89,  59,  99, 248,  26, 128,
+	255, 254, 151, 128, 109, 166,  88, 143,  30, 175, 149,  20, 240,  81, 138, 111,
+	255, 253,  47,   2, 214, 243, 188,  76, 236, 235,  40,  62,  54,  35,  33, 205,
+	255, 250,  94,  13, 156, 120, 121, 216, 255, 120,  90,  11,  39, 232, 120, 111,
+	255, 244, 188,  58, 242, 219, 157, 174,   6,  31, 131,  75,  88, 109, 112, 107,
+	255, 233, 120, 244, 202, 151,  25,  10, 197, 109, 113, 255, 157,  89, 182, 141,
+	255, 210, 243, 229,  18,  88,  50, 239, 130, 192,  12, 167,  62, 254, 211, 202,
+	255, 165, 239, 183, 102, 186, 123, 249, 251,  59, 116, 143,  50, 174, 125, 198,
+	255,  75, 255,  30,  65, 137, 228, 148,  14,  17, 113, 251,  81, 177, 151, 168,
+	254, 152, 124, 205, 192, 136, 102,  79,   5,  62, 214,  95,  36, 223,   7,  20,
+	253,  50, 242, 124, 187,  59,  68, 224,  90, 156,  53, 202,   9,  44, 191, 226,
+	250, 109, 189, 110,  40, 124,  88,  12,  83,  78, 176,  86,  12, 102,  13,  41,
+	244, 250, 133,   6,   3,  13,  45,   9, 120, 121, 150, 237,  69, 190,  62,  16,
+	234, 110, 130, 187, 138, 174,  82, 229, 217, 154,  88, 138, 228, 153, 230,  13,
+	214, 174,  54, 179, 117, 116, 223, 152,  97,  84,  31,  99,  68, 150, 122, 244,
+	180,   7, 186,   2, 112,   3,  68,  13, 123, 133, 244, 184, 232, 216, 133,  18,
+	126, 154, 221, 207,  32, 206,  66, 171,  94, 100, 164, 194, 117, 191,   1, 209,
+	 62, 156, 208,   7, 129, 173, 200,   3,  23, 248, 140,  60,  69, 217, 195, 235,
+	 15,  80,  84, 209, 213,   2, 107, 160,   1, 152,  43, 130,  93,  95, 241, 218,
+	  0, 234, 131,  37, 182,  53, 201, 231,  26,   2, 151, 161,  13, 214, 150, 145,
+	  0,   0, 214, 212,   4,  32, 184,  94,  84,  90, 244, 139,  48,  69,  33,  38
+};
+
+/**
+ * sigma = 250, k_sigma = ceiling[ sqrt(2*ln 2) * sigma ] = 295
+ *
+ * c[i] = exp(-2^i/f), i = 0..20, with f = k_sigma^2 / ln 2 = 125'550.5
+ */
+static uint8_t c_bliss_iii[] = {
+	255, 255, 122,  95,  16, 128,  14, 195,  60,  90, 166, 191, 205,  26, 144, 204,
+	255, 254, 244, 190, 102, 192, 187, 141, 169,  92,  33,  30, 170, 141, 184,  56,
+	255, 253, 233, 125, 228, 131,  93, 148, 121,  92,  52, 122, 149,  96,  29,  66,
+	255, 251, 211,   0,  37,   9, 199, 244, 213, 217, 122, 205, 171, 200, 198,   5,
+	255, 247, 166,  17, 185, 251,  90, 150,   1,  28,   7, 205, 125,  46,  84, 201,
+	255, 239,  76, 105,  50, 114, 159, 235, 215, 165, 204, 182, 125, 143, 228, 222,
+	255, 222, 153, 233,  85, 187,  45, 204, 236, 229,  38, 180,  20, 161,   7, 167,
+	255, 189,  56,  46,  38,   4,  83,   8, 151, 137, 136,   1,   9, 180,  58, 204,
+	255, 122, 129, 199, 240,  52, 248, 193,  76,  26, 160,  32, 195, 250, 217,  25,
+	254, 245,  73,  44,  68, 229, 150,  74, 228,  74, 124, 249, 123,  94, 108, 127,
+	253, 235, 168,  56, 252,  93, 188, 160, 249, 137, 236,  65,  62, 182, 153,  63,
+	251, 219, 163, 110, 233, 251, 114, 216, 230,  35,  59, 210, 107, 100, 184,  16,
+	247, 200, 110, 236, 134, 237, 213, 111, 240, 149, 109,  22, 216, 213, 237, 145,
+	239, 212,  98, 249, 238,   1, 227, 248, 242,  51, 211, 134, 154, 115, 189,  83,
+	224, 174,  65,   2, 190, 158,   9,   6, 184,  13, 130, 104, 247, 102,  38, 160,
+	197,  49, 104,  97,  61, 210,  19, 115, 208,  54,  91,  27, 209, 227,  33,  26,
+	151, 229,  20,  46, 200, 238,  35, 134,  72, 183, 253, 160, 193, 155, 117, 103,
+	 90,  32,  10, 204,  78,  83, 191, 230,   0, 221, 219,   6,  43, 252, 185,  95,
+	 31, 186, 139, 154,  90, 155,  17,   9,  42, 139,  40, 111, 246, 175,   4,  15,
+	  3, 238, 181, 190, 138,  94,  50, 234, 128, 193,  95,  36,  65, 236, 170, 208,
+	  0,  15, 118, 216, 230, 142, 121, 211,  13, 168, 207, 126, 145, 176,  24, 201
+};
+
+/**
+ * sigma = 271, k_sigma = ceiling[ sqrt(2*ln 2) * sigma ] = 320
+ *
+ * c[i] = exp(-2^i/f), i = 0..21, with f = k_sigma^2 / ln 2 = 147'732.0
+ */
+static uint8_t c_bliss_iv[] = {
+	255, 255, 142, 111, 102,   2, 141,  87, 150,  42,  18,  70,   6, 224,  18,  70,
+	255, 255,  28, 222, 254, 102,  20,  78, 133,  78, 189, 107,  29,   7,  23, 193,
+	255, 254,  57, 190, 198,  79, 181, 181, 108,  75, 142, 145,  45, 238, 193,  29,
+	255, 252, 115, 128, 178, 170, 212, 166, 120, 157,  85,  96, 209, 180, 211,  83,
+	255, 248, 231,  13, 253, 108, 245,  46, 238, 155,  30,  99, 141, 228, 149, 239,
+	255, 241, 206,  78,  90, 132,  83, 172, 228, 179, 119, 115, 240,  51, 216,   6,
+	255, 227, 157, 102,  46,  28,  61, 128,  58, 114, 174, 136,   8, 224, 133,  84,
+	255, 199,  61, 242,  19, 216, 133, 241, 240,  22, 146,  43,  92,  57,  82, 248,
+	255, 142, 136, 121, 160, 225, 119, 214, 241,  44, 159,  34, 133, 118,  96,  60,
+	255,  29,  67,  61, 254,  49,  27, 152,  48, 124, 184,  87,  66, 214,  63, 133,
+	254,  59,  79,  77, 206,  26, 238,  42,  69,  81, 191, 149, 146,  76, 255, 232,
+	252, 121, 191,  28,  11, 107, 141, 223, 234,  42, 226,  50, 138, 102,  16,  97,
+	248, 255, 234,  37, 109, 169, 103,  25, 240, 109,  93, 165, 177,  22, 133, 100,
+	242,  48, 213, 124, 209,  49,  33,  48,  57, 237, 202,  62, 102, 132, 219,  48,
+	229,  32,  92, 240, 188,  88,  70,  34, 179,  94, 244,  70,  25, 123,  76, 140,
+	205,  18, 234,  94,  14, 226, 237,  76, 192,  18, 240,  50,  79,  63,  34,  96,
+	164,  71,  76, 192, 111, 161, 157, 188,  19, 189, 133, 246,  67, 127,   6,  28,
+	105, 107, 110,  50,  56, 199, 208, 174,  16,  95, 153, 106, 217, 198, 194, 179,
+	 43, 105,  77, 122, 127, 254, 146, 221,  44, 235,  61,  22, 179,   9, 113, 118,
+	  7,  92, 139,  87, 204, 239, 111, 200,  41, 129, 122,  49,  69, 113, 122, 239,
+	  0,  54,  49,  19,  64,  40, 218, 222,  60,  82, 186, 246,  64, 155, 184,  47,
+	  0,   0,  11, 120, 189, 135, 113,  62, 143, 175, 118, 239, 190, 120, 189, 250
+};
+
+/**
+ * BLISS signature parameter set definitions
+ */
+static bliss_param_set_t bliss_param_sets[] = {
+
+	/* BLISS-I scheme */
+	{
+		.id = BLISS_I,
+		.oid = OID_BLISS_I,
+		.strength = 128,
+		.q = 12289,
+		.q_bits = 14,
+		.q2_inv = 6145,
+		.n = 512,
+		.n_bits = 9,
+		.fft_params = &bliss_fft_12289_512,
+		.non_zero1 = 154,
+		.non_zero2 = 0,
+		.kappa = 23,
+		.nks_max = 46479,
+		.p_max = 0,     /* not needed */
+		.sigma = 215,
+		.k_sigma = 254,
+		.k_sigma_bits = 8,
+		.c = c_bliss_i,
+		.c_cols = 16,
+		.c_rows = 21,
+		.z1_bits = 12,
+		.d = 10,
+		.p = 24,
+		.M = 46539,     /* with alpha = 1.000 */
+		.B_inf = 2047,  /* reduced from 2100 due to 12 bit z1 encoding */
+		.B_l2 = 12872 * 12872
+	},
+
+	/* BLISS-III scheme */
+	{
+		.id = BLISS_III,
+		.oid = OID_BLISS_III,
+		.strength = 160,
+		.q = 12289,
+		.q_bits = 14,
+		.q2_inv = 6145,
+		.n = 512,
+		.n_bits = 9,
+		.fft_params = &bliss_fft_12289_512,
+		.non_zero1 = 216,
+		.non_zero2 = 16,
+		.kappa = 30,
+		.nks_max = 128626,
+		.p_max = 0,     /* not needed */
+		.sigma = 250,
+		.k_sigma = 295,
+		.k_sigma_bits = 9,
+		.c = c_bliss_iii,
+		.c_cols = 16,
+		.c_rows = 21,
+		.z1_bits = 12,
+		.d = 9,
+		.p = 48,
+		.M = 128113,    /* with alpha = 0.700 */
+		.B_inf = 1760,
+		.B_l2 = 10206 * 10206
+	},
+
+	/* BLISS-IV scheme */
+	{
+		.id = BLISS_IV,
+		.oid = OID_BLISS_IV,
+		.strength = 192,
+		.q = 12289,
+		.q_bits = 14,
+		.q2_inv = 6145,
+		.n = 512,
+		.n_bits = 9,
+		.fft_params = &bliss_fft_12289_512,
+		.non_zero1 = 231,
+		.non_zero2 = 31,
+		.kappa = 39,
+		.nks_max = 244669,
+		.p_max = 0,     /* not needed */
+		.sigma = 271,
+		.k_sigma = 320,
+		.k_sigma_bits = 9,
+		.c = c_bliss_iv,
+		.c_cols = 16,
+		.c_rows = 22,
+		.z1_bits = 12,
+		.d = 8,
+		.p = 96,
+		.M = 244186,    /* with alpha = 0.550 */
+		.B_inf = 1613,
+		.B_l2 = 9901 * 9901
+	},
+
+	/* BLISS-B-I scheme */
+	{
+		.id = BLISS_B_I,
+		.oid = OID_BLISS_B_I,
+		.strength = 128,
+		.q = 12289,
+		.q_bits = 14,
+		.q2_inv = 6145,
+		.n = 512,
+		.n_bits = 9,
+		.fft_params = &bliss_fft_12289_512,
+		.non_zero1 = 154,
+		.non_zero2 = 0,
+		.kappa = 23,
+		.nks_max = 0,   /* not needed */
+		.p_max = 17825,
+		.sigma = 215,
+		.k_sigma = 254,
+		.k_sigma_bits = 8,
+		.c = c_bliss_i,
+		.c_cols = 16,
+		.c_rows = 21,
+		.z1_bits = 12,
+		.d = 10,
+		.p = 24,
+		.M = 17954,     /* with alpha = 1.610 */
+		.B_inf = 2047,  /* reduced from 2100 due to 12 bit z1 encoding */
+		.B_l2 = 12872 * 12872
+	},
+
+	/* BLISS-B-III scheme */
+	{
+		.id = BLISS_B_III,
+		.oid = OID_BLISS_B_III,
+		.strength = 160,
+		.q = 12289,
+		.q_bits = 14,
+		.q2_inv = 6145,
+		.n = 512,
+		.n_bits = 9,
+		.fft_params = &bliss_fft_12289_512,
+		.non_zero1 = 216,
+		.non_zero2 = 16,
+		.kappa = 30,
+		.nks_max = 0,   /* not needed */
+		.p_max = 42270,
+		.sigma = 250,
+		.k_sigma = 295,
+		.k_sigma_bits = 9,
+		.c = c_bliss_iii,
+		.c_cols = 16,
+		.c_rows = 21,
+		.z1_bits = 12,
+		.d = 9,
+		.p = 48,
+		.M = 42455,     /* with alpha = 1.216 */
+		.B_inf = 1760,
+		.B_l2 = 10206 * 10206
+	},
+
+	/* BLISS-B-IV scheme */
+	{
+		.id = BLISS_B_IV,
+		.oid = OID_BLISS_B_IV,
+		.strength = 192,
+		.q = 12289,
+		.q_bits = 14,
+		.q2_inv = 6145,
+		.n = 512,
+		.n_bits = 9,
+		.fft_params = &bliss_fft_12289_512,
+		.non_zero1 = 231,
+		.non_zero2 = 31,
+		.kappa = 39,
+		.nks_max = 0,   /* not needed */
+		.p_max = 69576,
+		.sigma = 271,
+		.k_sigma = 320,
+		.k_sigma_bits = 9,
+		.c = c_bliss_iv,
+		.c_cols = 16,
+		.c_rows = 22,
+		.z1_bits = 12,
+		.d = 8,
+		.p = 96,
+		.M = 70034,     /* with alpha = 1.027 */
+		.B_inf = 1613,
+		.B_l2 = 9901 * 9901
+	}
+
+};
+
+/**
+ * See header.
+ */
+bliss_param_set_t* bliss_param_set_get_by_id(bliss_param_set_id_t id)
+{
+	int i;
+
+	for (i = 0; i < countof(bliss_param_sets); i++)
+	{
+		if (bliss_param_sets[i].id == id)
+		{
+			return &bliss_param_sets[i];
+		}
+	}
+	return NULL;
+}
+
+
+/**
+ * See header.
+ */
+bliss_param_set_t* bliss_param_set_get_by_oid(int oid)
+{
+	int i;
+
+	for (i = 0; i < countof(bliss_param_sets); i++)
+	{
+		if (bliss_param_sets[i].oid == oid)
+		{
+			return &bliss_param_sets[i];
+		}
+	}
+	return NULL;
+}
diff --git a/src/libstrongswan/plugins/bliss/bliss_param_set.h b/src/libstrongswan/plugins/bliss/bliss_param_set.h
new file mode 100644
index 0000000..33a8009
--- /dev/null
+++ b/src/libstrongswan/plugins/bliss/bliss_param_set.h
@@ -0,0 +1,201 @@
+/*
+ * 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.
+ */
+
+/**
+ * @defgroup bliss_param_set bliss_param_set
+ * @{ @ingroup bliss_p
+ */
+
+#ifndef BLISS_PARAM_SET_H_
+#define BLISS_PARAM_SET_H_
+
+typedef enum bliss_param_set_id_t bliss_param_set_id_t;
+typedef struct bliss_param_set_t bliss_param_set_t;
+
+#include "bliss_fft_params.h"
+#include "bliss_huffman_code.h"
+
+#include <library.h>
+
+/**
+ * BLISS signature parameter set ID list
+ */
+enum bliss_param_set_id_t {
+	BLISS_I =     1,
+	BLISS_II =    2,
+	BLISS_III =   3,
+	BLISS_IV =    4,
+	BLISS_B_I =   5,
+	BLISS_B_II =  6,
+	BLISS_B_III = 7,
+	BLISS_B_IV =  8
+};
+
+extern enum_name_t *bliss_param_set_id_names;
+
+/**
+ * BLISS
+ */
+struct bliss_param_set_t {
+
+	/**
+	 * BLISS parameter set ID
+	 */
+	bliss_param_set_id_t id;
+
+	/**
+	 * BLISS parameter set OID
+	 */
+	int oid;
+
+	/**
+	 * Security strength in bits
+	 */
+	uint16_t strength;
+
+	/**
+	 * Prime modulus
+	 */
+	uint16_t q;
+
+	/**
+	 * Number of bits in q
+	 */
+	uint16_t q_bits;
+
+	/**
+	 * Inverse of (q + 2) mod 2q
+	 */
+	uint16_t q2_inv;
+
+	/**
+	 * Ring dimension equal to the number of polynomial coefficients
+	 */
+	uint16_t n;
+
+	/**
+	 * Number of bits in n
+	 */
+	uint16_t n_bits;
+
+	/**
+	 * FFT parameters
+	 */
+	bliss_fft_params_t *fft_params;
+
+	/**
+	 * Number of [-1, +1] secret key coefficients
+	 */
+	uint16_t non_zero1;
+
+	/**
+	 * Number of [-2, +2] secret key coefficients
+	 */
+	uint16_t non_zero2;
+
+	/**
+	 * Number of secret key terms that go into Nk(S) norm
+	 */
+	uint16_t kappa;
+
+	/**
+	 * Maximum Nk(S) tolerable NK(S) norm (BLISS only)
+	 */
+	uint32_t nks_max;
+
+	/**
+	 * Maximum value Pmax for ||Sc'||^2 norm (BLISS-B only)
+	 */
+	uint32_t p_max;
+
+	/**
+	 * Standard deviation sigma
+	 */
+	uint16_t sigma;
+
+	/**
+	 *  k_sigma = ceiling[ sqrt(2*ln 2) * sigma ]
+	 */
+	uint16_t k_sigma;
+
+	/**
+	 *  Number of bits in k_sigma
+	 */
+	uint16_t k_sigma_bits;
+
+	/**
+	 * Coefficients for Bernoulli sampling with exponential biases
+	 */
+	uint8_t *c;
+
+	/**
+	 * Number of columns in Bernoulli coefficient table
+	 */
+	size_t c_cols;
+
+	/**
+	 * Number of rows in Bernoulli coefficient table
+	 */
+	size_t c_rows;
+
+	/**
+	 * Number of bits in z1
+	 */
+	uint16_t z1_bits;
+
+	/**
+	 * Number of z2 bits to be dropped after rounding
+	 */
+	uint16_t d;
+
+	/**
+	 * Modulus p = floor(2q / 2^d) applied after bit dropping
+	 */
+	uint16_t p;
+
+	/**
+	 * M = sigma^2 / alpha_rejection^2
+	 */
+	uint32_t M;
+
+	/**
+	 * B_infinity bound
+	 */
+	uint16_t B_inf;
+
+	/**
+	 * B_verify bound
+	 */
+	uint32_t B_l2;
+
+};
+
+/**
+ * Get BLISS signature parameter set by BLISS parameter set ID
+ *
+ * @param id	BLISS parameter set ID
+ * @return		BLISS parameter set
+*/
+bliss_param_set_t* bliss_param_set_get_by_id(bliss_param_set_id_t id);
+
+/**
+ * Get BLISS signature parameter set by BLISS parameter set OID
+ *
+ * @param oid	BLISS parameter set OID
+ * @return		BLISS parameter set
+*/
+bliss_param_set_t* bliss_param_set_get_by_oid(int oid);
+
+#endif /** BLISS_PARAM_SET_H_ @}*/
diff --git a/src/libstrongswan/plugins/bliss/bliss_plugin.c b/src/libstrongswan/plugins/bliss/bliss_plugin.c
new file mode 100644
index 0000000..07597c3
--- /dev/null
+++ b/src/libstrongswan/plugins/bliss/bliss_plugin.c
@@ -0,0 +1,101 @@
+/*
+ * 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.
+ */
+
+#include "bliss_plugin.h"
+#include "bliss_private_key.h"
+#include "bliss_public_key.h"
+
+#include <library.h>
+
+typedef struct private_bliss_plugin_t private_bliss_plugin_t;
+
+/**
+ * private data of bliss_plugin
+ */
+struct private_bliss_plugin_t {
+
+	/**
+	 * public functions
+	 */
+	bliss_plugin_t public;
+};
+
+METHOD(plugin_t, get_name, char*,
+	private_bliss_plugin_t *this)
+{
+	return "bliss";
+}
+
+METHOD(plugin_t, get_features, int,
+	private_bliss_plugin_t *this, plugin_feature_t *features[])
+{
+	static plugin_feature_t f[] = {
+		/* private/public keys */
+		PLUGIN_REGISTER(PRIVKEY, bliss_private_key_load, TRUE),
+			PLUGIN_PROVIDE(PRIVKEY, KEY_BLISS),
+		PLUGIN_REGISTER(PRIVKEY, bliss_private_key_load, TRUE),
+			PLUGIN_PROVIDE(PRIVKEY, KEY_ANY),
+		PLUGIN_REGISTER(PRIVKEY_GEN, bliss_private_key_gen, FALSE),
+			PLUGIN_PROVIDE(PRIVKEY_GEN, KEY_BLISS),
+				PLUGIN_DEPENDS(RNG, RNG_TRUE),
+		PLUGIN_REGISTER(PUBKEY, bliss_public_key_load, TRUE),
+			PLUGIN_PROVIDE(PUBKEY, KEY_BLISS),
+		PLUGIN_REGISTER(PUBKEY, bliss_public_key_load, TRUE),
+			PLUGIN_PROVIDE(PUBKEY, KEY_ANY),
+		/* signature schemes, private */
+		PLUGIN_PROVIDE(PRIVKEY_SIGN, SIGN_BLISS_WITH_SHA256),
+			PLUGIN_DEPENDS(HASHER, HASH_SHA256),
+		PLUGIN_PROVIDE(PRIVKEY_SIGN, SIGN_BLISS_WITH_SHA384),
+			PLUGIN_DEPENDS(HASHER, HASH_SHA384),
+		PLUGIN_PROVIDE(PRIVKEY_SIGN, SIGN_BLISS_WITH_SHA512),
+			PLUGIN_DEPENDS(HASHER, HASH_SHA512),
+		/* signature verification schemes */
+		PLUGIN_PROVIDE(PUBKEY_VERIFY, SIGN_BLISS_WITH_SHA256),
+			PLUGIN_DEPENDS(HASHER, HASH_SHA256),
+		PLUGIN_PROVIDE(PUBKEY_VERIFY, SIGN_BLISS_WITH_SHA384),
+			PLUGIN_DEPENDS(HASHER, HASH_SHA384),
+		PLUGIN_PROVIDE(PUBKEY_VERIFY, SIGN_BLISS_WITH_SHA512),
+			PLUGIN_DEPENDS(HASHER, HASH_SHA512),
+	};
+	*features = f;
+
+	return countof(f);
+}
+
+METHOD(plugin_t, destroy, void,
+	private_bliss_plugin_t *this)
+{
+	free(this);
+}
+
+/*
+ * see header file
+ */
+plugin_t *bliss_plugin_create()
+{
+	private_bliss_plugin_t *this;
+
+	INIT(this,
+		.public = {
+			.plugin = {
+				.get_name = _get_name,
+				.get_features = _get_features,
+				.destroy = _destroy,
+			},
+		},
+	);
+
+	return &this->public.plugin;
+}
diff --git a/src/libstrongswan/plugins/bliss/bliss_plugin.h b/src/libstrongswan/plugins/bliss/bliss_plugin.h
new file mode 100644
index 0000000..d3d80ac
--- /dev/null
+++ b/src/libstrongswan/plugins/bliss/bliss_plugin.h
@@ -0,0 +1,42 @@
+/*
+ * 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.
+ */
+
+/**
+ * @defgroup bliss_p bliss
+ * @ingroup plugins
+ *
+ * @defgroup bliss_plugin bliss_plugin
+ * @{ @ingroup bliss_p
+ */
+
+#ifndef BLISS_PLUGIN_H_
+#define BLISS_PLUGIN_H_
+
+#include <plugins/plugin.h>
+
+typedef struct bliss_plugin_t bliss_plugin_t;
+
+/**
+ * Plugin implementing the BLISS post-quantu authentication algorithm
+ */
+struct bliss_plugin_t {
+
+	/**
+	 * implements plugin interface
+	 */
+	plugin_t plugin;
+};
+
+#endif /** BLISS_PLUGIN_H_ @}*/
diff --git a/src/libstrongswan/plugins/bliss/bliss_private_key.c b/src/libstrongswan/plugins/bliss/bliss_private_key.c
new file mode 100644
index 0000000..e1064d2
--- /dev/null
+++ b/src/libstrongswan/plugins/bliss/bliss_private_key.c
@@ -0,0 +1,1316 @@
+/*
+ * Copyright (C) 2014-2015 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 "bliss_private_key.h"
+#include "bliss_public_key.h"
+#include "bliss_param_set.h"
+#include "bliss_utils.h"
+#include "bliss_sampler.h"
+#include "bliss_signature.h"
+#include "bliss_bitpacker.h"
+#include "bliss_fft.h"
+
+#include <crypto/mgf1/mgf1_bitspender.h>
+#include <asn1/asn1.h>
+#include <asn1/asn1_parser.h>
+#include <asn1/oid.h>
+
+#define _GNU_SOURCE
+#include <stdlib.h>
+
+typedef struct private_bliss_private_key_t private_bliss_private_key_t;
+
+#define SECRET_KEY_TRIALS_MAX	50
+
+/**
+ * Private data of a bliss_private_key_t object.
+ */
+struct private_bliss_private_key_t {
+	/**
+	 * Public interface for this signer.
+	 */
+	bliss_private_key_t public;
+
+	/**
+	 * BLISS signature parameter set
+	 */
+	bliss_param_set_t *set;
+
+	/**
+	 * BLISS secret key S1 (coefficients of polynomial f)
+	 */
+	int8_t *s1;
+
+	/**
+	 * BLISS secret key S2 (coefficients of polynomial 2g + 1)
+	 */
+	int8_t *s2;
+
+	/**
+	 * NTT of BLISS public key a (coefficients of polynomial (2g + 1)/f)
+	 */
+	uint32_t *A;
+
+	/**
+	 * reference count
+	 */
+	refcount_t ref;
+};
+
+METHOD(private_key_t, get_type, key_type_t,
+	private_bliss_private_key_t *this)
+{
+	return KEY_BLISS;
+}
+
+/**
+ * Multiply secret vector s with binary challenge vector c
+ */
+static void multiply_by_c(int8_t *s, int n, uint16_t *c_indices,
+						  uint16_t kappa, int32_t *product)
+{
+	int i, j, index;
+
+	for (i = 0; i < n; i++)
+	{
+		product[i] = 0;
+
+		for (j = 0; j < kappa; j++)
+		{
+			index = c_indices[j];
+			if (i - index < 0)
+			{
+				product[i] -= s[i - index + n];
+			}
+			else
+			{
+				product[i] += s[i - index];
+			}
+		}
+	}
+}
+
+/**
+ * BLISS-B GreedySC algorithm
+ */
+static void greedy_sc(int8_t *s1, int8_t *s2, int n, uint16_t *c_indices,
+					  uint16_t kappa, int32_t *v1, int32_t *v2)
+{
+	int i, j, index;
+	int32_t sign;
+
+	for (i = 0; i < n; i++)
+	{
+		v1[i] = v2[i] = 0;
+	}
+	for (j = 0; j < kappa; j++)
+	{
+		index = c_indices[j];
+		sign = 0;
+
+		for (i = 0; i < index; i++)
+		{
+			sign -= (v1[i] * s1[i - index + n] + v2[i] * s2[i - index + n]);
+		}
+		for (i = index; i < n; i++)
+		{
+			sign += (v1[i] * s1[i - index] + v2[i] * s2[i - index]);
+		}
+		for (i = 0; i < index; i++)
+		{
+			if (sign > 0)
+			{
+				v1[i] += s1[i - index + n];
+				v2[i] += s2[i - index + n];
+			}
+			else
+			{
+				v1[i] -= s1[i - index + n];
+				v2[i] -= s2[i - index + n];
+			}
+		}
+		for (i = index; i < n; i++)
+		{
+			if (sign > 0)
+			{
+				v1[i] -= s1[i - index];
+				v2[i] -= s2[i - index];
+			}
+			else
+			{
+				v1[i] += s1[i - index];
+				v2[i] += s2[i - index];
+			}
+		}
+	}
+}
+
+/**
+ * Compute a BLISS signature
+ */
+static bool sign_bliss(private_bliss_private_key_t *this, hash_algorithm_t alg,
+					   chunk_t data, chunk_t *signature)
+{
+	bliss_fft_t *fft;
+	bliss_signature_t *sig;
+	bliss_sampler_t *sampler = NULL;
+	rng_t *rng;
+	hasher_t *hasher;
+	hash_algorithm_t mgf1_alg;
+	size_t mgf1_seed_len;
+	uint8_t mgf1_seed_buf[HASH_SIZE_SHA512], data_hash_buf[HASH_SIZE_SHA512];
+	chunk_t mgf1_seed, data_hash;
+	uint16_t q, q2, p, p2, *c_indices, tests = 0;
+	uint32_t *ay;
+	int32_t *y1, *y2, *z1, *z2, *u, *s1c, *s2c;
+	int32_t y1_min = 0, y1i, y1_max = 0, y2_min = 0, y2i, y2_max = 0;
+	int32_t scalar, norm, ui;
+	int16_t *ud, *uz2d, *z2d, value;
+	int i, n;
+	double mean1 = 0, mean2 = 0, sigma1 = 0, sigma2 = 0;
+	bool accepted, positive, success = FALSE, use_bliss_b;
+
+	/* Initialize signature */
+	*signature = chunk_empty;
+
+	/* Create data hash */
+	hasher = lib->crypto->create_hasher(lib->crypto, alg);
+	if (!hasher)
+	{
+		return FALSE;
+	}
+	data_hash = chunk_create(data_hash_buf, hasher->get_hash_size(hasher));
+
+	if (!hasher->get_hash(hasher, data, data_hash_buf))
+	{
+		hasher->destroy(hasher);
+		return FALSE;
+	}
+	hasher->destroy(hasher);
+
+	/* Create SHA512 hasher for c_indices oracle */
+	hasher = lib->crypto->create_hasher(lib->crypto, HASH_SHA512);
+	if (!hasher)
+	{
+		return FALSE;
+	}
+
+	/* Set MGF1 hash algorithm and seed length based on security strength */
+	if (this->set->strength > 160)
+	{
+		mgf1_alg = HASH_SHA256;
+		mgf1_seed_len = HASH_SIZE_SHA256;
+	}
+	else
+	{
+		mgf1_alg = HASH_SHA1;
+		mgf1_seed_len = HASH_SIZE_SHA1;
+	}
+	mgf1_seed = chunk_create(mgf1_seed_buf, mgf1_seed_len);
+
+	rng = lib->crypto->create_rng(lib->crypto, RNG_STRONG);
+	if (!rng)
+	{
+		hasher->destroy(hasher);
+		return FALSE;
+	}
+
+	/* Initialize a couple of needed variables */
+	n  = this->set->n;
+	q  = this->set->q;
+	p  = this->set->p;
+	q2 = 2 * q;
+	p2 = p / 2;
+	ay   = malloc(n * sizeof(uint32_t));
+	z2   = malloc(n * sizeof(int32_t));
+	s1c  = malloc(n * sizeof(int32_t));
+	s2c  = malloc(n * sizeof(int32_t));
+	u    = malloc(n * sizeof(int32_t));
+	uz2d = malloc(n * sizeof(int16_t));
+
+	sig = bliss_signature_create(this->set);
+	sig->get_parameters(sig, &z1, &z2d, &c_indices);
+	y1 = z1;
+	y2 = z2;
+	ud = z2d;
+
+	fft = bliss_fft_create(this->set->fft_params);
+
+	/* Use of the enhanced BLISS-B signature algorithm? */
+	switch (this->set->id)
+	{
+		default:
+		case BLISS_I:
+		case BLISS_II:
+		case BLISS_III:
+		case BLISS_IV:
+			use_bliss_b = FALSE;
+			break;
+		case BLISS_B_I:
+		case BLISS_B_II:
+		case BLISS_B_III:
+		case BLISS_B_IV:
+			use_bliss_b = TRUE;
+			break;
+	}
+
+	while (true)
+	{
+		tests++;
+
+		if (!rng->get_bytes(rng, mgf1_seed_len, mgf1_seed_buf))
+		{
+			goto end;
+		}
+		DESTROY_IF(sampler);
+
+		sampler = bliss_sampler_create(mgf1_alg, mgf1_seed, this->set);
+		if (!sampler)
+		{
+			goto end;
+		}
+
+		/* Gaussian sampling for vectors y1 and y2 */
+		for (i = 0; i < n; i++)
+		{
+			if (!sampler->gaussian(sampler, &y1i) ||
+				!sampler->gaussian(sampler, &y2i))
+			{
+				goto end;
+			}
+			y1[i] = y1i;
+			y2[i] = y2i;
+
+			/* Collect statistical data on rejection sampling */
+			if (i == 0)
+			{
+				y1_min = y1_max = y1i;
+				y2_min = y2_max = y2i;
+			}
+			else
+			{
+				if (y1i < y1_min)
+				{
+					y1_min = y1i;
+				}
+				else if (y1i > y1_max)
+				{
+					y1_max = y1i;
+				}
+				if (y2i < y2_min)
+				{
+					y2_min = y2i;
+				}
+				else if (y2i > y2_max)
+				{
+					y2_max = y2i;
+				}
+			}
+			mean1 += y1i;
+			mean2 += y2i;
+			sigma1 += y1i * y1i;
+			sigma2 += y2i * y2i;
+
+			ay[i] = y1i < 0 ? q + y1i : y1i;
+		}
+
+		/* Compute statistics on vectors y1 and y2 */
+		mean1 /= n;
+		mean2 /= n;
+		sigma1 /= n;
+		sigma2 /= n;
+		sigma2 -= mean1 * mean1;
+		sigma2 -= mean2 * mean2;
+		DBG2(DBG_LIB, "y1 = %d..%d (sigma2 = %5.0f, mean = %4.1f)",
+					   y1_min, y1_max, sigma1, mean1);
+		DBG2(DBG_LIB, "y2 = %d..%d (sigma2 = %5.0f, mean = %4.1f)",
+					   y2_min, y2_max, sigma2, mean2);
+
+		fft->transform(fft, ay, ay, FALSE);
+
+		for (i = 0; i < n; i++)
+		{
+			ay[i] = (this->A[i] * ay[i]) % q;
+		}
+		fft->transform(fft, ay, ay, TRUE);
+
+		for (i = 0; i < n; i++)
+		{
+			ui = 2 * this->set->q2_inv * (int32_t)ay[i] + y2[i];
+			u[i] = ((ui < 0) ? q2 + ui : ui) % q2;
+		}
+		bliss_utils_round_and_drop(this->set, u, ud);
+
+		/* Detailed debugging information */
+		DBG3(DBG_LIB, "  i    u[i]  ud[i]");
+		for (i = 0; i < n; i++)
+		{
+			DBG3(DBG_LIB, "%3d  %6d   %4d", i, u[i], ud[i]);
+		}
+
+		if (!bliss_utils_generate_c(hasher, data_hash, ud, n, this->set->kappa,
+									c_indices))
+		{
+			goto end;
+		}
+
+		if (use_bliss_b)
+		{
+			/* Compute v = (s1c, s2c) with the GreedySC algorithm */
+			greedy_sc(this->s1, this->s2, n, c_indices, this->set->kappa,
+					  s1c, s2c);
+
+			/* Compute norm = ||v||^2 = ||Sc'||^2 */
+			norm = bliss_utils_scalar_product(s1c, s1c, n) +
+				   bliss_utils_scalar_product(s2c, s2c, n);
+
+			/* Just in case. ||v||^2 <= P_max should always be fulfilled */
+			if (norm > this->set->p_max)
+			{
+				goto end;
+			}
+		}
+		else
+		{
+			/* Compute s*c */
+			multiply_by_c(this->s1, n, c_indices, this->set->kappa, s1c);
+			multiply_by_c(this->s2, n, c_indices, this->set->kappa, s2c);
+
+			/* Compute norm = |Sc||^2 */
+			norm = bliss_utils_scalar_product(s1c, s1c, n) +
+				   bliss_utils_scalar_product(s2c, s2c, n);
+		}
+
+		if (!sampler->bernoulli_exp(sampler, this->set->M - norm, &accepted))
+		{
+			goto end;
+		}
+		if (use_bliss_b)
+		{
+			DBG2(DBG_LIB, "norm2(s1*c') + norm2(s2*c') = %u (%u max), %s",
+				 norm, this->set->p_max, accepted ? "accepted" : "rejected");
+
+		}
+		else
+		{
+			DBG2(DBG_LIB, "norm2(s1*c) + norm2(s2*c) = %u, %s",
+				 norm, accepted ? "accepted" : "rejected");
+		}
+		if (!accepted)
+		{
+			continue;
+		}
+
+		/* Compute z */
+		if (!sampler->sign(sampler, &positive))
+		{
+			goto end;
+		}
+		for (i = 0; i < n; i++)
+		{
+			if (positive)
+			{
+				z1[i] = y1[i] + s1c[i];
+				z2[i] = y2[i] + s2c[i];
+			}
+			else
+			{
+				z1[i] = y1[i] - s1c[i];
+				z2[i] = y2[i] - s2c[i];
+			}
+		}
+		/* Reject with probability 1/cosh(scalar/sigma^2) */
+		scalar = bliss_utils_scalar_product(z1, s1c, n) +
+				 bliss_utils_scalar_product(z2, s2c, n);
+
+		if (!sampler->bernoulli_cosh(sampler, scalar, &accepted))
+		{
+			goto end;
+		}
+		DBG2(DBG_LIB, "scalar(z1,s1*c) + scalar(z2,s2*c) = %d, %s",
+					   scalar, accepted ? "accepted" : "rejected");
+		if (!accepted)
+		{
+			continue;
+		}
+
+		/* Compute z2 with dropped bits */
+		for (i = 0; i < n; i++)
+		{
+			u[i] -= z2[i];
+			if (u[i] < 0)
+			{
+				u[i] += q2;
+			}
+			else if (u[i] >= q2)
+			{
+				u[i] -= q2;
+			}
+		}
+		bliss_utils_round_and_drop(this->set, u, uz2d);
+
+		for (i = 0; i < n; i++)
+		{
+			value = ud[i] - uz2d[i];
+			if (value <= -p2)
+			{
+				value += p;
+			}
+			else if (value > p2)
+			{
+				value -= p;
+			}
+			z2d[i] = value;
+		}
+
+		if (!bliss_utils_check_norms(this->set, z1, z2d))
+		{
+			continue;
+		}
+
+		*signature = sig->get_encoding(sig);
+		if (signature->len == 0)
+		{
+			DBG1(DBG_LIB, "inefficient Huffman coding of signature");
+			continue;
+		}
+		DBG2(DBG_LIB, "signature generation needed %u round%s", tests,
+					  (tests == 1) ? "" : "s");
+		break;
+	}
+	success = TRUE;
+
+end:
+	/* cleanup */
+	DESTROY_IF(sampler);
+	hasher->destroy(hasher);
+	sig->destroy(sig);
+	fft->destroy(fft);
+	rng->destroy(rng);
+	memwipe(s1c, n * sizeof(int32_t));
+	memwipe(s2c, n * sizeof(int32_t));
+	free(s1c);
+	free(s2c);
+	free(ay);
+	free(z2);
+	free(u);
+	free(uz2d);
+
+	return success;
+}
+
+METHOD(private_key_t, sign, bool,
+	private_bliss_private_key_t *this, signature_scheme_t scheme,
+	chunk_t data, chunk_t *signature)
+{
+	switch (scheme)
+	{
+		case SIGN_BLISS_WITH_SHA256:
+			return sign_bliss(this, HASH_SHA256, data, signature);
+		case SIGN_BLISS_WITH_SHA384:
+			return sign_bliss(this, HASH_SHA384, data, signature);
+		case SIGN_BLISS_WITH_SHA512:
+			return sign_bliss(this, HASH_SHA512, data, signature);
+		default:
+			DBG1(DBG_LIB, "signature scheme %N not supported with BLISS",
+				 signature_scheme_names, scheme);
+			return FALSE;
+	}
+}
+
+METHOD(private_key_t, decrypt, bool,
+	private_bliss_private_key_t *this, encryption_scheme_t scheme,
+	chunk_t crypto, chunk_t *plain)
+{
+	DBG1(DBG_LIB, "encryption scheme %N not supported",
+				   encryption_scheme_names, scheme);
+	return FALSE;
+}
+
+METHOD(private_key_t, get_keysize, int,
+	private_bliss_private_key_t *this)
+{
+	return this->set->strength;
+}
+
+METHOD(private_key_t, get_public_key, public_key_t*,
+	private_bliss_private_key_t *this)
+{
+	public_key_t *public;
+	chunk_t pubkey;
+
+	pubkey = bliss_public_key_info_encode(this->set->oid, this->A, this->set);
+	public = lib->creds->create(lib->creds, CRED_PUBLIC_KEY, KEY_BLISS,
+								BUILD_BLOB_ASN1_DER, pubkey, BUILD_END);
+	free(pubkey.ptr);
+
+	return public;
+}
+
+METHOD(private_key_t, get_encoding, bool,
+	private_bliss_private_key_t *this, cred_encoding_type_t type,
+	chunk_t *encoding)
+{
+	switch (type)
+	{
+		case PRIVKEY_ASN1_DER:
+		case PRIVKEY_PEM:
+		{
+			chunk_t s1, s2, pubkey;
+			bliss_bitpacker_t *packer;
+			size_t s_bits;
+			int8_t value;
+			bool success = TRUE;
+			int i;
+
+			pubkey = bliss_public_key_encode(this->A, this->set);
+
+			/* Use either 2 or 3 bits per array element */
+			s_bits = 2 + (this->set->non_zero2 > 0);
+
+			/* Encode secret s1 */
+			packer = bliss_bitpacker_create(s_bits * this->set->n);
+			for (i = 0; i < this->set->n; i++)
+			{
+				packer->write_bits(packer, this->s1[i], s_bits);
+			}
+			s1 = packer->extract_buf(packer);
+			packer->destroy(packer);
+
+			/* Encode secret s2 */
+			packer = bliss_bitpacker_create(s_bits * this->set->n);
+			for (i = 0; i < this->set->n; i++)
+			{
+				value = this->s2[i];
+				if (i == 0)
+				{
+					value -= 1;
+				}
+				value /= 2;
+				packer->write_bits(packer, value, s_bits);
+			}
+			s2 = packer->extract_buf(packer);
+			packer->destroy(packer);
+
+			*encoding = asn1_wrap(ASN1_SEQUENCE, "mmss",
+							asn1_build_known_oid(this->set->oid),
+							asn1_bitstring("m", pubkey),
+							asn1_bitstring("m", s1),
+							asn1_bitstring("m", s2)
+						);
+			if (type == PRIVKEY_PEM)
+			{
+				chunk_t asn1_encoding = *encoding;
+
+				success = lib->encoding->encode(lib->encoding, PRIVKEY_PEM,
+								NULL, encoding, CRED_PART_BLISS_PRIV_ASN1_DER,
+								asn1_encoding, CRED_PART_END);
+				chunk_clear(&asn1_encoding);
+			}
+			return success;
+		}
+		default:
+			return FALSE;
+	}
+}
+
+METHOD(private_key_t, get_fingerprint, bool,
+	private_bliss_private_key_t *this, cred_encoding_type_t type, chunk_t *fp)
+{
+	bool success;
+
+	if (lib->encoding->get_cache(lib->encoding, type, this, fp))
+	{
+		return TRUE;
+	}
+	success = bliss_public_key_fingerprint(this->set->oid, this->A,
+										   this->set, type, fp);
+	if (success)
+	{
+		lib->encoding->cache(lib->encoding, type, this, *fp);
+	}
+	return success;
+}
+
+METHOD(private_key_t, get_ref, private_key_t*,
+	private_bliss_private_key_t *this)
+{
+	ref_get(&this->ref);
+	return &this->public.key;
+}
+
+METHOD(private_key_t, destroy, void,
+	private_bliss_private_key_t *this)
+{
+	if (ref_put(&this->ref))
+	{
+		lib->encoding->clear_cache(lib->encoding, this);
+		if (this->s1)
+		{
+			memwipe(this->s1, this->set->n * sizeof(int8_t));
+			free(this->s1);
+		}
+		if (this->s2)
+		{
+			memwipe(this->s2, this->set->n * sizeof(int8_t));
+			free(this->s2);
+		}
+		free(this->A);
+		free(this);
+	}
+}
+
+/**
+ * Internal generic constructor
+ */
+static private_bliss_private_key_t *bliss_private_key_create_empty(void)
+{
+	private_bliss_private_key_t *this;
+
+	INIT(this,
+		.public = {
+			.key = {
+				.get_type = _get_type,
+				.sign = _sign,
+				.decrypt = _decrypt,
+				.get_keysize = _get_keysize,
+				.get_public_key = _get_public_key,
+				.equals = private_key_equals,
+				.belongs_to = private_key_belongs_to,
+				.get_fingerprint = _get_fingerprint,
+				.has_fingerprint = private_key_has_fingerprint,
+				.get_encoding = _get_encoding,
+				.get_ref = _get_ref,
+				.destroy = _destroy,
+			},
+		},
+		.ref = 1,
+	);
+	return this;
+}
+
+/**
+ * Compute the scalar product of a vector x with a negative wrapped vector y
+ */
+static int16_t wrapped_product(int8_t *x, int8_t *y, int n, int shift)
+{
+	int16_t product = 0;
+	int i;
+
+	for (i = 0; i < n - shift; i++)
+	{
+		product += x[i] * y[i + shift];
+	}
+	for (i = n - shift; i < n; i++)
+	{
+		product -= x[i] * y[i + shift - n];
+	}
+	return product;
+}
+
+/**
+ * Apply a negative wrapped rotation to a vector x
+ */
+static void wrap(int16_t *x, int n, int shift, int16_t *x_wrapped)
+{
+	int i;
+
+	for (i = 0; i < n - shift; i++)
+	{
+		x_wrapped[i + shift] = x[i];
+	}
+	for (i = n - shift; i < n; i++)
+	{
+		x_wrapped[i + shift - n] = -x[i];
+	}
+}
+
+/**
+ * int16_t compare function needed for qsort()
+ */
+static int compare(const int16_t *a, const int16_t *b)
+{
+	int16_t temp = *a - *b;
+
+	if (temp > 0)
+	{
+		return 1;
+	}
+	else if (temp < 0)
+	{
+		return -1;
+	}
+	else
+	{
+		return 0;
+	}
+}
+
+/**
+ * Compute the Nk(S) norm of S = (s1, s2)
+ */
+static uint32_t nks_norm(int8_t *s1, int8_t *s2, int n, uint16_t kappa)
+{
+	int16_t t[n], t_wrapped[n], max_kappa[n];
+	uint32_t nks = 0;
+	int i, j;
+
+	for (i = 0; i < n; i++)
+	{
+		t[i] = wrapped_product(s1, s1, n, i) + wrapped_product(s2, s2, n, i);
+	}
+
+	for (i = 0; i < n; i++)
+	{
+		wrap(t, n, i, t_wrapped);
+		qsort(t_wrapped, n, sizeof(int16_t), (__compar_fn_t)compare);
+		max_kappa[i] = 0;
+
+		for (j = 1; j <= kappa; j++)
+		{
+			max_kappa[i] += t_wrapped[n - j];
+		}
+	}
+	qsort(max_kappa, n, sizeof(int16_t), (__compar_fn_t)compare);
+
+	for (i = 1; i <= kappa; i++)
+	{
+		nks += max_kappa[n - i];
+	}
+	return nks;
+}
+
+/**
+ * Compute the inverse x1 of x modulo q as x^(-1) = x^(q-2) mod q
+ */
+static uint32_t invert(uint32_t x, uint16_t q)
+{
+	uint32_t x1, x2;
+	uint16_t q2;
+	int i, i_max;
+
+	q2 = q - 2;
+	x1 = (q2 & 1) ? x : 1;
+	x2 = x;
+	i_max = 15;
+
+	while ((q2 & (1 << i_max)) == 0)
+	{
+		i_max--;
+	}
+	for (i = 1; i <= i_max; i++)
+	{
+		x2 = (x2 * x2) % q;
+
+		if (q2 & (1 << i))
+		{
+			x1 = (x1 * x2) % q;
+		}
+	}
+
+	return x1;
+}
+
+/**
+ * Create a vector with sparse and small coefficients from seed
+ */
+static int8_t* create_vector_from_seed(private_bliss_private_key_t *this,
+									   hash_algorithm_t alg, chunk_t seed)
+{
+	mgf1_bitspender_t *bitspender;
+	uint32_t index, sign;
+	int8_t *vector;
+	int non_zero;
+
+	bitspender = mgf1_bitspender_create(alg, seed, FALSE);
+	if (!bitspender)
+	{
+	    return NULL;
+	}
+
+	vector = malloc(sizeof(int8_t) * this->set->n);
+	memset(vector, 0x00, this->set->n);
+
+	non_zero = this->set->non_zero1;
+	while (non_zero)
+	{
+		if (!bitspender->get_bits(bitspender, this->set->n_bits, &index))
+		{
+			free(vector);
+			return NULL;
+		}
+		if (vector[index] != 0)
+		{
+			continue;
+		}
+
+		if (!bitspender->get_bits(bitspender, 1, &sign))
+		{
+			free(vector);
+			return NULL;
+		}
+		vector[index] = sign ? 1 : -1;
+		non_zero--;
+	}
+
+	non_zero = this->set->non_zero2;
+	while (non_zero)
+	{
+		if (!bitspender->get_bits(bitspender, this->set->n_bits, &index))
+		{
+			free(vector);
+			return NULL;
+		}
+		if (vector[index] != 0)
+		{
+			continue;
+		}
+
+		if (!bitspender->get_bits(bitspender, 1, &sign))
+		{
+			free(vector);
+			return NULL;
+		}
+		vector[index] = sign ? 2 : -2;
+		non_zero--;
+	}
+	bitspender->destroy(bitspender);
+
+	return vector;
+}
+
+/**
+ * Generate the secret key S = (s1, s2) fulfilling the Nk(S) norm
+ */
+static bool create_secret(private_bliss_private_key_t *this, rng_t *rng,
+						 int8_t **s1, int8_t **s2, int *trials)
+{
+	uint8_t seed_buf[32];
+	uint8_t *f, *g;
+	uint32_t l2_norm, nks;
+	int i, n;
+	chunk_t seed;
+	size_t seed_len;
+	hash_algorithm_t alg;
+
+	n = this->set->n;
+	*s1 = NULL;
+	*s2 = NULL;
+
+	/* Set MGF1 hash algorithm and seed length based on security strength */
+	if (this->set->strength > 160)
+	{
+		alg = HASH_SHA256;
+		seed_len = HASH_SIZE_SHA256;
+	}
+	else
+	{
+		alg = HASH_SHA1;
+		seed_len = HASH_SIZE_SHA1;
+	}
+	seed = chunk_create(seed_buf, seed_len);
+
+	while (*trials < SECRET_KEY_TRIALS_MAX)
+	{
+		(*trials)++;
+
+		if (!rng->get_bytes(rng, seed_len, seed_buf))
+		{
+			return FALSE;
+		}
+		f = create_vector_from_seed(this, alg, seed);
+		if (f == NULL)
+		{
+			return FALSE;
+		}
+		if (!rng->get_bytes(rng, seed_len, seed_buf))
+		{
+			free(f);
+			return FALSE;
+		}
+		g = create_vector_from_seed(this, alg, seed);
+		if (g == NULL)
+		{
+			free(f);
+			return FALSE;
+		}
+
+		/* Compute 2g + 1 */
+		for (i = 0; i < n; i++)
+		{
+			g[i] *= 2;
+		}
+		g[0] += 1;
+
+		l2_norm = wrapped_product(f, f, n, 0) +  wrapped_product(g, g, n, 0);
+		nks = nks_norm(f, g, n, this->set->kappa);
+
+		switch (this->set->id)
+		{
+			case BLISS_I:
+			case BLISS_II:
+			case BLISS_III:
+			case BLISS_IV:
+				DBG2(DBG_LIB, "l2 norm of s1||s2: %d, Nk(S): %u (%u max)",
+							   l2_norm, nks, this->set->nks_max);
+				if (nks < this->set->nks_max)
+				{
+					*s1 = f;
+					*s2 = g;
+					return TRUE;
+				}
+				free(f);
+				free(g);
+				break;
+			case BLISS_B_I:
+			case BLISS_B_II:
+			case BLISS_B_III:
+			case BLISS_B_IV:
+				DBG2(DBG_LIB, "l2 norm of s1||s2: %d, Nk(S): %u",
+							   l2_norm, nks);
+				*s1 = f;
+				*s2 = g;
+				return TRUE;
+		}
+	}
+
+	return FALSE;
+}
+
+/**
+ * See header.
+ */
+bliss_private_key_t *bliss_private_key_gen(key_type_t type, va_list args)
+{
+	private_bliss_private_key_t *this;
+	u_int key_size = BLISS_B_I;
+	int i, n, trials = 0;
+	uint32_t *S1, *S2, *a;
+	uint16_t q;
+	bool success = FALSE;
+	bliss_param_set_t *set;
+	bliss_fft_t *fft;
+	rng_t *rng;
+
+	while (TRUE)
+	{
+		switch (va_arg(args, builder_part_t))
+		{
+			case BUILD_KEY_SIZE:
+				key_size = va_arg(args, u_int);
+				continue;
+			case BUILD_END:
+				break;
+			default:
+				return NULL;
+		}
+		break;
+	}
+
+	if (lib->settings->get_bool(lib->settings, "%s.plugins.bliss.use_bliss_b",
+								TRUE, lib->ns))
+	{
+		switch (key_size)
+		{
+			case BLISS_I:
+				key_size = BLISS_B_I;
+				break;
+			case BLISS_II:
+				key_size = BLISS_B_II;
+				break;
+			case BLISS_III:
+				key_size = BLISS_B_III;
+				break;
+			case BLISS_IV:
+				key_size = BLISS_B_IV;
+				break;
+			default:
+				break;
+		}
+	}
+
+	/* Only BLISS or BLISS-B types I, III, or IV are currently supported */
+	set = bliss_param_set_get_by_id(key_size);
+	if (!set)
+	{
+		DBG1(DBG_LIB, "BLISS parameter set %u not supported", key_size);
+		return NULL;
+	}
+
+	/* Some shortcuts for often used variables */
+	n = set->n;
+	q = set->q;
+
+	if (set->fft_params->n != n || set->fft_params->q != q)
+	{
+		DBG1(DBG_LIB, "FFT parameters do not match BLISS parameters");
+		return NULL;
+	}
+	this = bliss_private_key_create_empty();
+	this->set = set;
+
+	/* We derive the public key from the private key using the FFT */
+	fft = bliss_fft_create(set->fft_params);
+
+	/* Some vectors needed to derive the publi key */
+	S1 = malloc(n * sizeof(uint32_t));
+	S2 = malloc(n * sizeof(uint32_t));
+	a  = malloc(n * sizeof(uint32_t));
+	this->A = malloc(n * sizeof(uint32_t));
+
+	/* Instantiate a true random generator */
+	rng = lib->crypto->create_rng(lib->crypto, RNG_TRUE);
+
+	/* Loop until we have an invertible polynomial s1 */
+	do
+	{
+		if (!create_secret(this, rng, &this->s1, &this->s2, &trials))
+		{
+			break;
+		}
+
+		/* Convert signed arrays to unsigned arrays before FFT */
+		for (i = 0; i < n; i++)
+		{
+			S1[i] = (this->s1[i] < 0) ? this->s1[i] + q :  this->s1[i];
+			S2[i] = (this->s2[i] > 0) ? q - this->s2[i] : -this->s2[i];
+		}
+		fft->transform(fft, S1, S1, FALSE);
+		fft->transform(fft, S2, S2, FALSE);
+
+		success = TRUE;
+		for (i = 0; i < n; i++)
+		{
+			if (S1[i] == 0)
+			{
+				DBG1(DBG_LIB, "S1[%d] is zero - s1 is not invertible", i);
+				free(this->s1);
+				free(this->s2);
+				this->s1 = NULL;
+				this->s2 = NULL;
+				success = FALSE;
+				break;
+			}
+			this->A[i] = invert(S1[i], q);
+			this->A[i] = (S2[i] * this->A[i]) % q;
+		}
+	}
+	while (!success && trials < SECRET_KEY_TRIALS_MAX);
+
+	DBG1(DBG_LIB, "secret key generation %s after %d trial%s",
+		 success ? "succeeded" : "failed", trials, (trials == 1) ? "" : "s");
+
+	if (success)
+	{
+		fft->transform(fft, this->A, a, TRUE);
+
+		DBG4(DBG_LIB, "   i   f   g     a     F     G     A");
+		for (i = 0; i < n; i++)
+		{
+			DBG4(DBG_LIB, "%4d %3d %3d %5u %5u %5u %5u",
+				 i, this->s1[i], this->s2[i], a[i], S1[i], S2[i], this->A[i]);
+		}
+	}
+	else
+	{
+		destroy(this);
+	}
+
+	/* Cleanup */
+	fft->destroy(fft);
+	rng->destroy(rng);
+	memwipe(S1, n * sizeof(uint32_t));
+	memwipe(S2, n * sizeof(uint32_t));
+	free(S1);
+	free(S2);
+	free(a);
+
+	return success ? &this->public : NULL;
+}
+
+/**
+ * ASN.1 definition of a BLISS private key
+ */
+static const asn1Object_t privkeyObjects[] = {
+	{ 0, "BLISSPrivateKey",		ASN1_SEQUENCE,   ASN1_NONE }, /*  0 */
+	{ 1,   "keyType",			ASN1_OID,        ASN1_BODY }, /*  1 */
+	{ 1,   "public",			ASN1_BIT_STRING, ASN1_BODY }, /*  2 */
+	{ 1,   "secret1",			ASN1_BIT_STRING, ASN1_BODY }, /*  3 */
+	{ 1,   "secret2",			ASN1_BIT_STRING, ASN1_BODY }, /*  4 */
+	{ 0, "exit",				ASN1_EOC,        ASN1_EXIT }
+};
+#define PRIV_KEY_TYPE			1
+#define PRIV_KEY_PUBLIC			2
+#define PRIV_KEY_SECRET1		3
+#define PRIV_KEY_SECRET2		4
+
+/**
+ * See header.
+ */
+bliss_private_key_t *bliss_private_key_load(key_type_t type, va_list args)
+{
+	private_bliss_private_key_t *this;
+	chunk_t key = chunk_empty, object;
+	bliss_bitpacker_t *packer;
+	asn1_parser_t *parser;
+	size_t s_bits = 0;
+	int8_t s, s_min = 0, s_max = 0;
+	uint32_t s_sign = 0x02, s_mask = 0xfffffffc, value;
+	bool success = FALSE;
+	int objectID, oid, i;
+
+	while (TRUE)
+	{
+		switch (va_arg(args, builder_part_t))
+		{
+			case BUILD_BLOB_ASN1_DER:
+				key = va_arg(args, chunk_t);
+				continue;
+			case BUILD_END:
+				break;
+			default:
+				return NULL;
+		}
+		break;
+	}
+
+	if (key.len == 0)
+	{
+		return NULL;
+	}
+	this = bliss_private_key_create_empty();
+
+	parser = asn1_parser_create(privkeyObjects, key);
+	parser->set_flags(parser, FALSE, TRUE);
+
+	while (parser->iterate(parser, &objectID, &object))
+	{
+		switch (objectID)
+		{
+			case PRIV_KEY_TYPE:
+				oid = asn1_known_oid(object);
+				if (oid == OID_UNKNOWN)
+				{
+					goto end;
+				}
+				this->set = bliss_param_set_get_by_oid(oid);
+				if (this->set == NULL)
+				{
+					goto end;
+				}
+				if (lib->settings->get_bool(lib->settings,
+							"%s.plugins.bliss.use_bliss_b",TRUE, lib->ns))
+				{
+					switch (this->set->id)
+					{
+						case BLISS_I:
+							this->set = bliss_param_set_get_by_id(BLISS_B_I);
+							break;
+						case BLISS_III:
+							this->set = bliss_param_set_get_by_id(BLISS_B_III);
+							break;
+						case BLISS_IV:
+							this->set = bliss_param_set_get_by_id(BLISS_B_IV);
+							break;
+						default:
+							break;
+					}
+				}
+				if (this->set->non_zero2)
+				{
+					s_min = -2;
+					s_max =  2;
+					s_bits = 3;
+				}
+				else
+				{
+					s_min = -1;
+					s_max =  1;
+					s_bits = 2;
+				}
+				s_sign = 1 << (s_bits - 1);
+				s_mask = ((1 << (32 - s_bits)) - 1) << s_bits;
+				break;
+			case PRIV_KEY_PUBLIC:
+				if (!bliss_public_key_from_asn1(object, this->set, &this->A))
+				{
+					goto end;
+				}
+				break;
+			case PRIV_KEY_SECRET1:
+				if (object.len != 1 + (s_bits * this->set->n + 7)/8)
+				{
+					goto end;
+				}
+				this->s1 = malloc(this->set->n);
+
+				/* Skip unused bits octet */
+				object = chunk_skip(object, 1);
+				packer = bliss_bitpacker_create_from_data(object);
+				for (i = 0; i < this->set->n; i++)
+				{
+					packer->read_bits(packer, &value, s_bits);
+					s = (value & s_sign) ? value | s_mask : value;
+					if (s < s_min || s > s_max)
+					{
+						packer->destroy(packer);
+						goto end;
+					}
+					this->s1[i] = s;
+				}
+				packer->destroy(packer);
+				break;
+			case PRIV_KEY_SECRET2:
+				if (object.len != 1 + (s_bits * this->set->n + 7)/8)
+				{
+					goto end;
+				}
+				this->s2 = malloc(this->set->n);
+
+				/* Skip unused bits octet */
+				object = chunk_skip(object, 1);
+				packer = bliss_bitpacker_create_from_data(object);
+				for (i = 0; i < this->set->n; i++)
+				{
+					packer->read_bits(packer, &value, s_bits);
+					s = (value & s_sign) ? value | s_mask : value;
+					if (s < s_min || s > s_max)
+					{
+						packer->destroy(packer);
+						goto end;
+					}
+					this->s2[i] = 2 * s;
+					if (i == 0)
+					{
+						this->s2[0] += 1;
+					}
+				}
+				packer->destroy(packer);
+				break;
+		}
+	}
+	success = parser->success(parser);
+
+end:
+	parser->destroy(parser);
+	if (!success)
+	{
+		destroy(this);
+		return NULL;
+	}
+
+	return &this->public;
+}
+
diff --git a/src/libstrongswan/plugins/bliss/bliss_private_key.h b/src/libstrongswan/plugins/bliss/bliss_private_key.h
new file mode 100644
index 0000000..cb4ff80
--- /dev/null
+++ b/src/libstrongswan/plugins/bliss/bliss_private_key.h
@@ -0,0 +1,62 @@
+/*
+ * 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.
+ */
+
+/**
+ * @defgroup bliss_private_key bliss_private_key
+ * @{ @ingroup bliss_p
+ */
+
+#ifndef BLISS_PRIVATE_KEY_H_
+#define BLISS_PRIVATE_KEY_H_
+
+#include <credentials/builder.h>
+#include <credentials/keys/private_key.h>
+
+typedef struct bliss_private_key_t bliss_private_key_t;
+
+/**
+ * Private_key_t implementation of BLISS signature algorithm.
+ */
+struct bliss_private_key_t {
+
+	/**
+	 * Implements private_key_t interface
+	 */
+	private_key_t key;
+};
+
+/**
+ * Generate a BLISS private key.
+ *
+ * Accepts the BUILD_KEY_SIZE argument.
+ *
+ * @param type		type of the key, must be KEY_BLISS
+ * @param args		builder_part_t argument list
+ * @return 			generated key, NULL on failure
+ */
+bliss_private_key_t *bliss_private_key_gen(key_type_t type, va_list args);
+
+/**
+ * Load a BLISS private key.
+ *
+ * Accepts BUILD_BLISS_* components.
+ *
+ * @param type		type of the key, must be KEY_BLISS
+ * @param args		builder_part_t argument list
+ * @return 			loaded key, NULL on failure
+ */
+bliss_private_key_t *bliss_private_key_load(key_type_t type, va_list args);
+
+#endif /** BLISS_PRIVATE_KEY_H_ @}*/
diff --git a/src/libstrongswan/plugins/bliss/bliss_public_key.c b/src/libstrongswan/plugins/bliss/bliss_public_key.c
new file mode 100644
index 0000000..0175b0f
--- /dev/null
+++ b/src/libstrongswan/plugins/bliss/bliss_public_key.c
@@ -0,0 +1,515 @@
+/*
+ * 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.
+ */
+
+#include "bliss_public_key.h"
+#include "bliss_signature.h"
+#include "bliss_bitpacker.h"
+#include "bliss_fft.h"
+#include "bliss_utils.h"
+
+#include <asn1/asn1.h>
+#include <asn1/asn1_parser.h>
+#include <asn1/oid.h>
+
+typedef struct private_bliss_public_key_t private_bliss_public_key_t;
+
+/**
+ * Private data structure with signing context.
+ */
+struct private_bliss_public_key_t {
+	/**
+	 * Public interface for this signer.
+	 */
+	bliss_public_key_t public;
+
+	/**
+	 * BLISS signature parameter set
+	 */
+	bliss_param_set_t *set;
+
+	/**
+	 * NTT of BLISS public key a (coefficients of polynomial (2g + 1)/f)
+	 */
+	uint32_t *A;
+
+	/**
+	 * reference counter
+	 */
+	refcount_t ref;
+};
+
+METHOD(public_key_t, get_type, key_type_t,
+	private_bliss_public_key_t *this)
+{
+	return KEY_BLISS;
+}
+
+/**
+ * Verify a BLISS signature based on a SHA-512 hash
+ */
+static bool verify_bliss(private_bliss_public_key_t *this, hash_algorithm_t alg,
+						 chunk_t data, chunk_t signature)
+{
+	int i, n;
+	int32_t *z1, *u;
+	int16_t *ud, *z2d;
+	uint16_t q, q2, p, *c_indices, *indices;
+	uint32_t *az;
+	uint8_t data_hash_buf[HASH_SIZE_SHA512];
+	chunk_t data_hash;
+	hasher_t *hasher;
+	bliss_fft_t *fft;
+	bliss_signature_t *sig;
+	bool success = FALSE;
+
+	/* Create data hash */
+	hasher = lib->crypto->create_hasher(lib->crypto, alg);
+	if (!hasher )
+	{
+		return FALSE;
+	}
+	data_hash = chunk_create(data_hash_buf, hasher->get_hash_size(hasher));
+
+	if (!hasher->get_hash(hasher, data, data_hash_buf))
+	{
+		hasher->destroy(hasher);
+		return FALSE;
+	}
+	hasher->destroy(hasher);
+
+	/* Create SHA512 hasher for c_indices oracle */
+	hasher = lib->crypto->create_hasher(lib->crypto, HASH_SHA512);
+	if (!hasher)
+	{
+		return FALSE;
+	}
+
+	sig = bliss_signature_create_from_data(this->set, signature);
+	if (!sig)
+	{
+		hasher->destroy(hasher);
+		return FALSE;
+	}
+	sig->get_parameters(sig, &z1, &z2d, &c_indices);
+
+	if (!bliss_utils_check_norms(this->set, z1, z2d))
+	{
+		hasher->destroy(hasher);
+		sig->destroy(sig);
+		return FALSE;
+	}
+
+	/* Initialize a couple of needed variables */
+	n  = this->set->n;
+	q  = this->set->q;
+	p  = this->set->p;
+	q2 = 2 * q;
+	az  = malloc(n * sizeof(uint32_t));
+	u   = malloc(n * sizeof(int32_t));
+	ud  = malloc(n * sizeof(int16_t));
+	indices   = malloc(this->set->kappa * sizeof(uint16_t));
+
+	for (i = 0; i < n; i++)
+	{
+		az[i] = z1[i] < 0 ? q + z1[i] : z1[i];
+	}
+	fft = bliss_fft_create(this->set->fft_params);
+	fft->transform(fft, az, az, FALSE);
+
+	for (i = 0; i < n; i++)
+	{
+		az[i] = (this->A[i] * az[i]) % q;
+	}
+	fft->transform(fft, az, az, TRUE);
+
+	for (i = 0; i < n; i++)
+	{
+		u[i] = (2 * this->set->q2_inv * az[i]) % q2;
+	}
+
+	for (i = 0; i < this->set->kappa; i++)
+	{
+		u[c_indices[i]] = (u[c_indices[i]] + q * this->set->q2_inv) % q2;
+	}
+	bliss_utils_round_and_drop(this->set, u, ud);
+
+	for (i = 0; i < n; i++)
+	{
+		ud[i] += z2d[i];
+		if (ud[i] < 0)
+		{
+			ud[i] += p;
+		}
+		else if (ud[i] >= p)
+		{
+			ud[i] -= p;
+		}
+	}
+
+	/* Detailed debugging information */
+	DBG3(DBG_LIB, "  i    u[i]  ud[i] z2d[i]");
+	for (i = 0; i < n; i++)
+	{
+		DBG3(DBG_LIB, "%3d  %6d   %4d  %4d", i, u[i], ud[i], z2d[i]);
+	}
+
+	if (!bliss_utils_generate_c(hasher, data_hash, ud, n, this->set->kappa,
+								indices))
+	{
+		goto end;
+	}
+
+	for (i = 0; i < this->set->kappa; i++)
+	{
+		if (indices[i] != c_indices[i])
+		{
+			DBG1(DBG_LIB, "signature verification failed");
+			goto end;
+		}
+	}
+	success = TRUE;
+
+end:
+	/* cleanup */
+	hasher->destroy(hasher);
+	sig->destroy(sig);
+	fft->destroy(fft);
+	free(az);
+	free(u);
+	free(ud);
+	free(indices);
+
+	return success;
+}
+
+METHOD(public_key_t, verify, bool,
+	private_bliss_public_key_t *this, signature_scheme_t scheme,
+	chunk_t data, chunk_t signature)
+{
+	switch (scheme)
+	{
+		case SIGN_BLISS_WITH_SHA256:
+			return verify_bliss(this, HASH_SHA256, data, signature);
+		case SIGN_BLISS_WITH_SHA384:
+			return verify_bliss(this, HASH_SHA384, data, signature);
+		case SIGN_BLISS_WITH_SHA512:
+			return verify_bliss(this, HASH_SHA512, data, signature);
+		default:
+			DBG1(DBG_LIB, "signature scheme %N not supported by BLISS",
+				 signature_scheme_names, scheme);
+			return FALSE;
+	}
+}
+
+METHOD(public_key_t, encrypt_, bool,
+	private_bliss_public_key_t *this, encryption_scheme_t scheme,
+	chunk_t plain, chunk_t *crypto)
+{
+	DBG1(DBG_LIB, "encryption scheme %N not supported",
+				   encryption_scheme_names, scheme);
+	return FALSE;
+}
+
+METHOD(public_key_t, get_keysize, int,
+	private_bliss_public_key_t *this)
+{
+	return this->set->strength;
+}
+
+METHOD(public_key_t, get_encoding, bool,
+	private_bliss_public_key_t *this, cred_encoding_type_t type,
+	chunk_t *encoding)
+{
+	bool success = TRUE;
+
+	*encoding = bliss_public_key_info_encode(this->set->oid, this->A, this->set);
+
+	if (type != PUBKEY_SPKI_ASN1_DER)
+	{
+		chunk_t asn1_encoding = *encoding;
+
+		success = lib->encoding->encode(lib->encoding, type,
+						NULL, encoding, CRED_PART_BLISS_PUB_ASN1_DER,
+						asn1_encoding, CRED_PART_END);
+		chunk_clear(&asn1_encoding);
+	}
+	return success;
+}
+
+METHOD(public_key_t, get_fingerprint, bool,
+	private_bliss_public_key_t *this, cred_encoding_type_t type, chunk_t *fp)
+{
+	bool success;
+
+	if (lib->encoding->get_cache(lib->encoding, type, this, fp))
+	{
+		return TRUE;
+	}
+	success = bliss_public_key_fingerprint(this->set->oid, this->A,
+										   this->set, type, fp);
+	if (success)
+	{
+		lib->encoding->cache(lib->encoding, type, this, *fp);
+	}
+	return success;
+}
+
+METHOD(public_key_t, get_ref, public_key_t*,
+	private_bliss_public_key_t *this)
+{
+	ref_get(&this->ref);
+	return &this->public.key;
+}
+
+METHOD(public_key_t, destroy, void,
+	private_bliss_public_key_t *this)
+{
+	if (ref_put(&this->ref))
+	{
+		lib->encoding->clear_cache(lib->encoding, this);
+		free(this->A);
+		free(this);
+	}
+}
+
+/**
+ * ASN.1 definition of a BLISS public key
+ */
+static const asn1Object_t pubkeyObjects[] = {
+	{ 0, "subjectPublicKeyInfo",ASN1_SEQUENCE,		ASN1_OBJ  }, /*  0 */
+	{ 1,   "algorithm",			ASN1_EOC,			ASN1_RAW  }, /*  1 */
+	{ 1,   "subjectPublicKey",	ASN1_BIT_STRING,	ASN1_BODY }, /*  2 */
+	{ 0, "exit",				ASN1_EOC,			ASN1_EXIT }
+};
+#define BLISS_SUBJECT_PUBLIC_KEY_ALGORITHM	1
+#define BLISS_SUBJECT_PUBLIC_KEY			2
+
+/**
+ * See header.
+ */
+bliss_public_key_t *bliss_public_key_load(key_type_t type, va_list args)
+{
+	private_bliss_public_key_t *this;
+	chunk_t blob = chunk_empty, object, param;
+	asn1_parser_t *parser;
+	bool success = FALSE;
+	int objectID, oid;
+
+	while (TRUE)
+	{
+		switch (va_arg(args, builder_part_t))
+		{
+			case BUILD_BLOB_ASN1_DER:
+				blob = va_arg(args, chunk_t);
+				continue;
+			case BUILD_END:
+				break;
+			default:
+				return NULL;
+		}
+		break;
+	}
+
+	if (blob.len == 0)
+	{
+		return NULL;
+	}
+
+	INIT(this,
+		.public = {
+			.key = {
+				.get_type = _get_type,
+				.verify = _verify,
+				.encrypt = _encrypt_,
+				.equals = public_key_equals,
+				.get_keysize = _get_keysize,
+				.get_fingerprint = _get_fingerprint,
+				.has_fingerprint = public_key_has_fingerprint,
+				.get_encoding = _get_encoding,
+				.get_ref = _get_ref,
+				.destroy = _destroy,
+			},
+		},
+		.ref = 1,
+	);
+
+	parser = asn1_parser_create(pubkeyObjects, blob);
+
+	while (parser->iterate(parser, &objectID, &object))
+	{
+		switch (objectID)
+		{
+			case BLISS_SUBJECT_PUBLIC_KEY_ALGORITHM:
+			{
+				oid = asn1_parse_algorithmIdentifier(object,
+								parser->get_level(parser)+1, &param);
+				if (oid != OID_BLISS_PUBLICKEY)
+				{
+					goto end;
+				}
+				if (!asn1_parse_simple_object(&param, ASN1_OID,
+								parser->get_level(parser)+3, "blissKeyType"))
+				{
+					goto end;
+				}
+				oid = asn1_known_oid(param);
+				if (oid == OID_UNKNOWN)
+				{
+					goto end;
+				}
+				this->set = bliss_param_set_get_by_oid(oid);
+				if (this->set == NULL)
+				{
+					goto end;
+				}
+				break;
+			}
+			case BLISS_SUBJECT_PUBLIC_KEY:
+				if (!bliss_public_key_from_asn1(object, this->set, &this->A))
+				{
+					goto end;
+				}
+				break;
+		}
+	}
+	success = parser->success(parser);
+
+end:
+	parser->destroy(parser);
+	if (!success)
+	{
+		destroy(this);
+		return NULL;
+	}
+
+	return &this->public;
+}
+
+/**
+ * See header.
+ */
+bool bliss_public_key_from_asn1(chunk_t object, bliss_param_set_t *set,
+								uint32_t **pubkey)
+{
+	bliss_bitpacker_t *packer;
+	uint32_t coefficient;
+	uint16_t needed_bits;
+	int i;
+
+	/* skip initial bit string octet defining unused bits */
+	object = chunk_skip(object, 1);
+
+	needed_bits = set->n * set->q_bits;
+
+	if (8 * object.len < needed_bits)
+	{
+		return FALSE;
+	}
+	*pubkey = malloc(set->n * sizeof(uint32_t));
+
+	packer = bliss_bitpacker_create_from_data(object);
+
+	for (i = 0; i < set->n; i++)
+	{
+		packer->read_bits(packer, &coefficient, set->q_bits);
+		if (coefficient >= set->q)
+		{
+			packer->destroy(packer);
+			return FALSE;
+		}
+		(*pubkey)[i] = coefficient;
+	}
+	packer->destroy(packer);
+
+	return TRUE;
+}
+
+/**
+ * See header.
+ */
+chunk_t bliss_public_key_encode(uint32_t *pubkey, bliss_param_set_t *set)
+{
+	bliss_bitpacker_t *packer;
+	chunk_t encoding;
+	int i;
+
+	packer = bliss_bitpacker_create(set->n * set->q_bits);
+
+	for (i = 0; i < set->n; i++)
+	{
+		packer->write_bits(packer, pubkey[i], set->q_bits);
+	}
+	encoding = packer->extract_buf(packer);
+	packer->destroy(packer);
+
+	return encoding;
+}
+
+/**
+ * See header.
+ */
+chunk_t bliss_public_key_info_encode(int oid, uint32_t *pubkey,
+									 bliss_param_set_t *set)
+{
+	chunk_t encoding, pubkey_encoding;
+
+	pubkey_encoding = bliss_public_key_encode(pubkey, set);
+
+	encoding = asn1_wrap(ASN1_SEQUENCE, "mm",
+					asn1_wrap(ASN1_SEQUENCE, "mm",
+						asn1_build_known_oid(OID_BLISS_PUBLICKEY),
+						asn1_build_known_oid(oid)),
+					asn1_bitstring("m", pubkey_encoding));
+
+	return encoding;
+}
+
+/**
+ * See header.
+ */
+bool bliss_public_key_fingerprint(int oid, uint32_t *pubkey,
+								  bliss_param_set_t *set,
+								  cred_encoding_type_t type, chunk_t *fp)
+{
+	hasher_t *hasher;
+	chunk_t key;
+
+	switch (type)
+	{
+		case KEYID_PUBKEY_SHA1:
+			key = bliss_public_key_encode(pubkey, set);
+			break;
+		case KEYID_PUBKEY_INFO_SHA1:
+			key = bliss_public_key_info_encode(oid, pubkey, set);
+			break;
+		default:
+			return FALSE;
+	}
+
+	hasher = lib->crypto->create_hasher(lib->crypto, HASH_SHA1);
+	if (!hasher || !hasher->allocate_hash(hasher, key, fp))
+	{
+		DBG1(DBG_LIB, "SHA1 hash algorithm not supported, fingerprinting failed");
+		DESTROY_IF(hasher);
+		free(key.ptr);
+
+		return FALSE;
+	}
+	hasher->destroy(hasher);
+	free(key.ptr);
+
+	return TRUE;
+}
+
diff --git a/src/libstrongswan/plugins/bliss/bliss_public_key.h b/src/libstrongswan/plugins/bliss/bliss_public_key.h
new file mode 100644
index 0000000..cd8f231
--- /dev/null
+++ b/src/libstrongswan/plugins/bliss/bliss_public_key.h
@@ -0,0 +1,101 @@
+/*
+ * 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.
+ */
+
+/**
+ * @defgroup bliss_public_key bliss_public_key
+ * @{ @ingroup bliss_p
+ */
+
+#ifndef BLISS_PUBLIC_KEY_H_
+#define BLISS_PUBLIC_KEY_H_
+
+#include "bliss_param_set.h"
+
+#include <credentials/builder.h>
+#include <credentials/cred_encoding.h>
+#include <credentials/keys/public_key.h>
+
+typedef struct bliss_public_key_t bliss_public_key_t;
+
+/**
+ * public_key_t implementation of BLISS signature algorithm
+ */
+struct bliss_public_key_t {
+
+	/**
+	 * Implements the public_key_t interface
+	 */
+	public_key_t key;
+};
+
+/**
+ * Load a BLISS public key.
+ *
+ * Accepts BUILD_BLISS_* components.
+ *
+ * @param type		type of the key, must be KEY_BLISS
+ * @param args		builder_part_t argument list
+ * @return 			loaded key, NULL on failure
+ */
+bliss_public_key_t *bliss_public_key_load(key_type_t type, va_list args);
+
+/* The following functions are shared with the bliss_private_key class */
+
+/**
+ * Parse an ASN.1 BIT STRING into an array of public key coefficients
+ *
+ * @param object	packed subjectPublicKey
+ * @param set		BLISS parameter set for public key vector
+ * @param pubkey	coefficients of public key vector
+ * @return			TRUE if parsing successful
+ */
+bool bliss_public_key_from_asn1(chunk_t object, bliss_param_set_t *set,
+								uint32_t **pubkey);
+
+/**
+ * Encode a raw BLISS subjectPublicKey in ASN.1 DER format
+ *
+ * @param pubkey	coefficients of public key vector
+ * @param set		BLISS parameter set for the public key vector
+ * @result			ASN.1 encoded subjectPublicKey
+ */
+chunk_t bliss_public_key_encode(uint32_t *pubkey, bliss_param_set_t *set);
+
+/**
+ * Encode a BLISS subjectPublicKeyInfo record in ASN.1 DER format
+ *
+ * @param oid		BLISS public key type OID
+ * @param pubkey	coefficients of public key vector
+ * @param set		BLISS parameter set for the public key vector
+ * @result			ASN.1 encoded subjectPublicKeyInfo record
+ */
+chunk_t bliss_public_key_info_encode(int oid, uint32_t *pubkey,
+									 bliss_param_set_t *set);
+
+/**
+ * Generate a BLISS public key fingerprint
+ *
+ * @param oid		BLISS public key type OID
+ * @param pubkey	coefficients of public key vector
+ * @param set		BLISS parameter set for the public key vector
+ * @param type		type of fingerprint to be generated
+ * @param fp		generated fingerprint (must be freed by caller)
+ * @result			TRUE if generation was successful
+ */
+bool bliss_public_key_fingerprint(int oid, uint32_t *pubkey,
+								  bliss_param_set_t *set,
+								  cred_encoding_type_t type, chunk_t *fp);
+
+#endif /** BLISS_PUBLIC_KEY_H_ @}*/
diff --git a/src/libstrongswan/plugins/bliss/bliss_sampler.c b/src/libstrongswan/plugins/bliss/bliss_sampler.c
new file mode 100644
index 0000000..fa45a2f
--- /dev/null
+++ b/src/libstrongswan/plugins/bliss/bliss_sampler.c
@@ -0,0 +1,250 @@
+/*
+ * 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.
+ */
+
+#include "bliss_sampler.h"
+
+typedef struct private_bliss_sampler_t private_bliss_sampler_t;
+
+#include <crypto/mgf1/mgf1_bitspender.h>
+
+/**
+ * Private data of a bliss_sampler_t object.
+ */
+struct private_bliss_sampler_t {
+
+	/**
+	 * Public interface.
+	 */
+	bliss_sampler_t public;
+
+	/**
+	 * BLISS parameter the rejection sampling is to be based on
+	 */
+	bliss_param_set_t *set;
+
+	/**
+	 * Bitspender used for random rejection sampling
+	 */
+	mgf1_bitspender_t *bitspender;
+
+};
+
+METHOD(bliss_sampler_t, bernoulli_exp, bool,
+	private_bliss_sampler_t *this, uint32_t x, bool *accepted)
+{
+	uint32_t x_mask;
+	uint8_t *c, u;
+	int i;
+
+	x_mask = 1 << (this->set->c_rows - 1);
+	c = this->set->c;
+	c += (this->set->c_rows - 1) * this->set->c_cols;
+
+	while (x_mask > 0)
+	{
+		if (x & x_mask)
+		{
+			for (i = 0; i < this->set->c_cols; i++)
+			{
+				if (!this->bitspender->get_byte(this->bitspender, &u))
+				{
+					return FALSE;
+				}
+				if (u < c[i])
+				{
+					break;
+				}
+				else if (u > c[i])
+				{
+					*accepted = FALSE;
+					return TRUE;
+				}
+			}
+		}
+		x_mask >>= 1;
+		c -= this->set->c_cols;
+	}
+
+	*accepted = TRUE;
+	return TRUE;
+}
+
+METHOD(bliss_sampler_t, bernoulli_cosh, bool,
+	private_bliss_sampler_t *this, int32_t x, bool *accepted)
+{
+	uint32_t u;
+
+	x = 2 * (x < 0 ? -x : x);
+
+	while (TRUE)
+	{
+		if (!bernoulli_exp(this, x, accepted))
+		{
+			return FALSE;
+		}
+		if (*accepted)
+		{
+			return TRUE;
+		}
+		if (!this->bitspender->get_bits(this->bitspender, 1, &u))
+		{
+			return FALSE;
+		}
+		if (u)
+		{
+			continue;
+		}
+		if (!bernoulli_exp(this, x, accepted))
+		{
+			return FALSE;
+		}
+		if (!(*accepted))
+		{
+			return TRUE;
+		}
+	}
+}
+
+#define MAX_SAMPLE_INDEX	16
+
+METHOD(bliss_sampler_t, pos_binary, bool,
+	private_bliss_sampler_t *this, uint32_t *x)
+{
+	uint32_t u, i;
+
+	while (TRUE)
+	{
+		for (i = 0; i <= MAX_SAMPLE_INDEX; i++)
+		{
+			if (!this->bitspender->get_bits(this->bitspender,
+											i ? (2*i - 1) : 1, &u))
+			{
+				return FALSE;
+			}
+			if (u == 0)
+			{
+				*x = i;
+				return TRUE;
+			}
+			if ((u >> 1) != 0)
+			{
+				break;
+			}
+		}
+		if (i > MAX_SAMPLE_INDEX)
+		{
+			return FALSE;
+		}
+	}
+}
+
+METHOD(bliss_sampler_t, gaussian, bool,
+	private_bliss_sampler_t *this, int32_t *z)
+{
+	uint32_t u, x, y, z_pos;
+	bool accepted;
+
+	while (TRUE)
+	{
+		if (!pos_binary(this, &x))
+		{
+			return FALSE;
+		}
+
+		do
+		{
+			if (!this->bitspender->get_bits(this->bitspender,
+											this->set->k_sigma_bits, &y))
+			{
+				return FALSE;
+			}
+		}
+		while (y >= this->set->k_sigma);
+
+		if (!bernoulli_exp(this, y * (y + 2*this->set->k_sigma * x), &accepted))
+		{
+			return FALSE;
+		}
+		if (accepted)
+		{
+			if (!this->bitspender->get_bits(this->bitspender, 1, &u))
+			{
+				return FALSE;
+			}
+			if (x || y || u)
+			{ 
+				break;
+			}
+		}
+	}
+
+	z_pos = this->set->k_sigma * x + y;
+	*z = u ? z_pos : -z_pos;
+
+	return TRUE;
+}
+
+METHOD(bliss_sampler_t, sign, bool,
+	private_bliss_sampler_t *this, bool *positive)
+{
+	uint32_t u;
+
+	if (!this->bitspender->get_bits(this->bitspender, 1, &u))
+	{
+		return FALSE;
+	}
+	*positive = u;
+
+	return TRUE;
+}
+
+METHOD(bliss_sampler_t, destroy, void,
+	private_bliss_sampler_t *this)
+{
+	this->bitspender->destroy(this->bitspender);
+	free(this);
+}
+
+
+/**
+ * See header.
+ */
+bliss_sampler_t *bliss_sampler_create(hash_algorithm_t alg, chunk_t seed,
+									  bliss_param_set_t *set)
+{
+	private_bliss_sampler_t *this;
+	mgf1_bitspender_t *bitspender;
+
+	bitspender = mgf1_bitspender_create(alg, seed, FALSE);
+	if (!bitspender)
+	{
+		return NULL;
+	}
+
+	INIT(this,
+		.public = {
+			.bernoulli_exp = _bernoulli_exp,
+			.bernoulli_cosh = _bernoulli_cosh,
+			.pos_binary = _pos_binary,
+			.gaussian = _gaussian,
+			.sign = _sign,
+			.destroy = _destroy,
+		},
+		.set = set,
+		.bitspender = bitspender,
+	);
+
+	return &this->public;
+}
diff --git a/src/libstrongswan/plugins/bliss/bliss_sampler.h b/src/libstrongswan/plugins/bliss/bliss_sampler.h
new file mode 100644
index 0000000..2c75d44
--- /dev/null
+++ b/src/libstrongswan/plugins/bliss/bliss_sampler.h
@@ -0,0 +1,94 @@
+/*
+ * 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.
+ */
+
+/**
+ * @defgroup bliss_sampler bliss_sampler
+ * @{ @ingroup bliss_p
+ */
+
+#ifndef BLISS_SAMPLER_H_
+#define BLISS_SAMPLER_H_
+
+typedef struct bliss_sampler_t bliss_sampler_t;
+
+#include "bliss_param_set.h"
+
+#include <library.h>
+#include <crypto/hashers/hasher.h>
+
+/**
+ * Implementation various rejection sampling algorithms.
+ */
+struct bliss_sampler_t {
+
+	/**
+	 * Sample according to exp(-x/(2*sigma^2))
+	 *
+	 * @param x			Value to be sampled
+	 * @param accepted	TRUE if value is accepted, FALSE if rejected
+	 * @result			TRUE if sampling was successful
+	 */
+	bool (*bernoulli_exp)(bliss_sampler_t *this, uint32_t x, bool *accepted);
+
+	/**
+	 * Sample according to 1/cosh(x/sigma^2)
+	 *
+	 * @param x			Value to be sampled
+	 * @param accepted	TRUE if value is accepted, FALSE if rejected
+	 * @result			TRUE if sampling was successful
+	 */
+	bool (*bernoulli_cosh)(bliss_sampler_t *this, int32_t x, bool *accepted);
+
+	/**
+	 * Sample according to 2^(-x^2) for positive x
+	 *
+	 * @param x			Generated value
+	 * @result			TRUE if sampling was successful
+	 */
+	bool (*pos_binary)(bliss_sampler_t *this, uint32_t *x);
+
+	/**
+	 * Sample according to the Gaussian distribution exp(-x^2/(2*sigma^2))
+	 *
+	 * @param z			Generated value with Gaussian distribution
+	 * @result			TRUE if sampling was successful
+	 */
+	bool (*gaussian)(bliss_sampler_t *this, int32_t *z);
+
+	/**
+	 * Sample the sign according to the binary distribution
+	 *
+	 * @param positive	TRUE if positive
+	 * @result			TRUE if sampling was successful
+	 */
+	bool (*sign)(bliss_sampler_t *this, bool *positive);
+
+	/**
+	 * Destroy bliss_sampler_t object
+	 */
+	void (*destroy)(bliss_sampler_t *this);
+};
+
+/**
+ * Create a bliss_sampler_t object.
+ *
+ * @param alg		Hash algorithm to be used for the internal bitspender
+ * @param seed		Seed used to initialize the internal bitspender
+ * @param set		BLISS parameter set to be used
+ */
+bliss_sampler_t *bliss_sampler_create(hash_algorithm_t alg, chunk_t seed,
+									  bliss_param_set_t *set);
+
+#endif /** BLISS_SAMPLER_H_ @}*/
diff --git a/src/libstrongswan/plugins/bliss/bliss_signature.c b/src/libstrongswan/plugins/bliss/bliss_signature.c
new file mode 100644
index 0000000..e603da3
--- /dev/null
+++ b/src/libstrongswan/plugins/bliss/bliss_signature.c
@@ -0,0 +1,233 @@
+/*
+ * 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.
+ */
+
+#include "bliss_signature.h"
+#include "bliss_bitpacker.h"
+#include "bliss_huffman_coder.h"
+
+
+typedef struct private_bliss_signature_t private_bliss_signature_t;
+
+/**
+ * Private data of a bliss_signature_t object.
+ */
+struct private_bliss_signature_t {
+	/**
+	 * Public interface for this signer.
+	 */
+	bliss_signature_t public;
+
+	/**
+	 * BLISS signature parameter set
+	 */
+	bliss_param_set_t *set;
+
+	/**
+	 * BLISS signature vector z1 of size n
+	 */
+	int32_t *z1;
+
+	/**
+	 * BLISS signature vector z2d of size n
+	 */
+	int16_t *z2d;
+
+	/**
+	 * Indices of sparse BLISS challenge vector c of size kappa
+	 */
+	uint16_t *c_indices;
+
+};
+
+METHOD(bliss_signature_t, get_encoding, chunk_t,
+	private_bliss_signature_t *this)
+{
+	bliss_bitpacker_t *packer;
+	bliss_huffman_coder_t *coder;
+	bliss_huffman_code_t *code;
+	int32_t z1;
+	uint32_t z1_sign;
+	uint16_t z2d_bits;
+	chunk_t encoding = chunk_empty;
+	int i;
+
+	z2d_bits = this->set->z1_bits - this->set->d;
+
+	/* Get Huffman code for this BLISS parameter set */
+	code = bliss_huffman_code_get_by_id(this->set->id);
+	if (!code)
+	{
+		DBG1(DBG_LIB, "no Huffman code found for parameter set %N",
+			 bliss_param_set_id_names, this->set->id);
+		return chunk_empty;
+	}
+
+	packer = bliss_bitpacker_create(this->set->n * this->set->z1_bits +
+									this->set->n * z2d_bits +
+									this->set->kappa * this->set->n_bits);
+	coder = bliss_huffman_coder_create(code, packer);
+
+	for (i = 0; i < this->set->n; i++)
+	{
+		/* determine and remove the sign of z1[i]*/
+		z1_sign = this->z1[i] < 0;
+		z1 = z1_sign ? -this->z1[i] : this->z1[i];
+
+		if (!packer->write_bits(packer, z1_sign, 1) ||
+			!packer->write_bits(packer, z1 & 0xff, 8) ||
+			!coder->encode(coder, z1 >> 8, this->z2d[i]))
+		{
+			goto end;
+		}
+	}
+	for (i = 0; i < this->set->kappa; i++)
+	{
+		if (!packer->write_bits(packer, this->c_indices[i], this->set->n_bits))
+		{
+			goto end;
+		}
+	}
+	encoding = packer->extract_buf(packer);
+
+	DBG2(DBG_LIB, "efficiency of Huffman coder is %6.4f bits/tuple (%u bits)",
+				   coder->get_bits(coder)/(double)(this->set->n), 
+				   coder->get_bits(coder));
+	DBG2(DBG_LIB, "generated BLISS signature (%u bits encoded in %u bytes)",
+				   packer->get_bits(packer), encoding.len);
+
+	end:
+	coder->destroy(coder);
+	packer->destroy(packer);
+	return encoding;
+}
+
+METHOD(bliss_signature_t, get_parameters, void,
+	private_bliss_signature_t *this, int32_t **z1, int16_t **z2d,
+	uint16_t **c_indices)
+{
+	*z1 = this->z1;
+	*z2d = this->z2d;
+	*c_indices = this->c_indices;
+}
+
+METHOD(bliss_signature_t, destroy, void,
+	private_bliss_signature_t *this)
+{
+	free(this->z1);
+	free(this->z2d);
+	free(this->c_indices);
+	free(this);
+}
+
+/**
+ * See header.
+ */
+bliss_signature_t *bliss_signature_create(bliss_param_set_t *set)
+{
+	private_bliss_signature_t *this;
+
+	INIT(this,
+		.public = {
+			.get_encoding = _get_encoding,
+			.get_parameters = _get_parameters,
+			.destroy = _destroy,
+		},
+		.set = set,
+		.z1  = malloc(set->n * sizeof(int32_t)),
+		.z2d = malloc(set->n * sizeof(int16_t)),
+		.c_indices = malloc(set->n * sizeof(uint16_t)),
+	);
+
+	return &this->public;
+}
+
+/**
+ * See header.
+ */
+bliss_signature_t *bliss_signature_create_from_data(bliss_param_set_t *set,
+													chunk_t encoding)
+{
+	private_bliss_signature_t *this;
+	bliss_bitpacker_t *packer;
+	bliss_huffman_coder_t *coder;
+	bliss_huffman_code_t *code;
+	uint32_t z1_sign, z1_low, value;
+	int32_t z1;
+	int16_t z2;
+	int i;
+
+	/* Get Huffman code for this BLISS parameter set */
+	code = bliss_huffman_code_get_by_id(set->id);
+	if (!code)
+	{
+		DBG1(DBG_LIB, "no Huffman code found for parameter set %N",
+			 bliss_param_set_id_names, set->id);
+		return NULL;
+	}
+
+	if (encoding.len == 0)
+	{
+		DBG1(DBG_LIB, "zero length BLISS signature");
+		return NULL;
+	}
+
+	INIT(this,
+		.public = {
+			.get_encoding = _get_encoding,
+			.get_parameters = _get_parameters,
+			.destroy = _destroy,
+		},
+		.set = set,
+		.z1  = malloc(set->n * sizeof(int32_t)),
+		.z2d = malloc(set->n * sizeof(int16_t)),
+		.c_indices = malloc(set->n * sizeof(uint16_t)),
+	);
+
+	packer = bliss_bitpacker_create_from_data(encoding);
+	coder = bliss_huffman_coder_create(code, packer);
+
+	for (i = 0; i < set->n; i++)
+	{
+		if (!packer->read_bits(packer, &z1_sign, 1) ||
+			!packer->read_bits(packer, &z1_low, 8) ||
+			!coder->decode(coder, &z1, &z2))
+		{
+			DBG1(DBG_LIB, "truncated BLISS signature encoding of z1/z2");
+			coder->destroy(coder);
+			packer->destroy(packer);
+			destroy(this);
+			return NULL;
+		}
+		z1 = (z1 << 8) + z1_low;
+		this->z1[i] = z1_sign ? -z1 : z1;
+		this->z2d[i] = z2;
+	}
+	coder->destroy(coder);
+
+	for (i = 0; i < set->kappa; i++)
+	{
+		if (!packer->read_bits(packer, &value, set->n_bits))
+		{
+			DBG1(DBG_LIB, "truncated BLISS signature encoding of c_indices");
+			packer->destroy(packer);
+			destroy(this);
+			return NULL;
+		}
+		this->c_indices[i] = value;
+	}
+	packer->destroy(packer);
+
+	return &this->public;
+}
diff --git a/src/libstrongswan/plugins/bliss/bliss_signature.h b/src/libstrongswan/plugins/bliss/bliss_signature.h
new file mode 100644
index 0000000..d37f539
--- /dev/null
+++ b/src/libstrongswan/plugins/bliss/bliss_signature.h
@@ -0,0 +1,75 @@
+/*
+ * 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.
+ */
+
+/**
+ * @defgroup bliss_signature bliss_signature
+ * @{ @ingroup bliss_p
+ */
+
+#ifndef BLISS_SIGNATURE_H_
+#define BLISS_SIGNATURE_H_
+
+typedef struct bliss_signature_t bliss_signature_t;
+
+#include "bliss_param_set.h"
+
+#include <library.h>
+
+/**
+ * Public interface of BLISS signature object
+ */
+struct bliss_signature_t {
+
+	/**
+	 * Get compressed binary encoding of BLISS signature
+	 *
+	 * @result			binary encoding of BLISS signature
+	 */
+	chunk_t (*get_encoding)(bliss_signature_t *this);
+
+	/**
+	 * Get signature parameters extracted from compressd binary encoding
+	 *
+	 * @param z1		signature vector z1 of size n
+	 * @param z2d		signature vector z2d of size n
+	 * @param c_indices	indices of sparse binary challenge vector of size kappa
+	 */
+	void (*get_parameters)(bliss_signature_t *this, int32_t **z1, int16_t **z2d,
+						   uint16_t **c_indices);
+
+	/**
+	 * Destroy bliss_signature_t object
+	 */
+	void (*destroy)(bliss_signature_t *this);
+
+};
+
+/**
+ * Create a BLISS signature object.
+ *
+ * @param set			BLISS parameter set
+ */
+bliss_signature_t *bliss_signature_create(bliss_param_set_t *set);
+
+/**
+ * Create a BLISS signature object from encoding.
+ *
+ * @param set			BLISS parameter set
+ * @param encoding		binary signature encoding
+ */
+bliss_signature_t *bliss_signature_create_from_data(bliss_param_set_t *set,
+													chunk_t encoding);
+
+#endif /** BLISS_SIGNATURE_H_ @}*/
diff --git a/src/libstrongswan/plugins/bliss/bliss_utils.c b/src/libstrongswan/plugins/bliss/bliss_utils.c
new file mode 100644
index 0000000..5a06998
--- /dev/null
+++ b/src/libstrongswan/plugins/bliss/bliss_utils.c
@@ -0,0 +1,167 @@
+/*
+ * 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.
+ */
+
+#include "bliss_utils.h"
+
+#include <asn1/asn1.h>
+#include <crypto/hashers/hasher.h>
+#include <utils/debug.h>
+
+/**
+ * See header.
+ */
+int32_t bliss_utils_scalar_product(int32_t *x, int32_t *y, int n)
+{
+	int32_t product = 0;
+	int i;
+
+	for (i = 0; i < n; i++)
+	{
+		product += x[i] * y[i];
+	}
+
+	return product;
+}
+
+/**
+ * See header.
+ */
+void bliss_utils_round_and_drop(bliss_param_set_t *set, int32_t *x, int16_t *xd)
+{
+	int32_t factor;
+	int i;
+
+	factor = 1 << set->d;
+
+	for (i = 0; i < set->n; i++)
+	{
+		xd[i] = ((x[i] + (factor >> 1)) / factor) % set->p;
+	}
+}
+
+/**
+ * See header.
+ */
+bool bliss_utils_generate_c(hasher_t *hasher, chunk_t data_hash, uint16_t *ud,
+							int n, uint16_t kappa, uint16_t *c_indices)
+{
+	int i, j;
+	uint64_t extra_bits;
+	uint16_t index, rounds = 0;
+	uint8_t hash[HASH_SIZE_SHA512], un16_buf[2];
+	chunk_t un16 = { un16_buf, 2 };
+	bool index_taken[n];
+
+	while (TRUE)
+	{
+		if (!hasher->get_hash(hasher, data_hash, NULL))
+		{
+			return FALSE;
+		}
+
+		for (i = 0; i < n; i++)
+		{
+			htoun16(un16_buf, ud[i]);
+			if (!hasher->get_hash(hasher, un16, NULL))
+			{
+				return FALSE;
+			}
+			index_taken[i] = FALSE;
+		}
+
+		htoun16(un16_buf, rounds++);
+		if (!hasher->get_hash(hasher, un16, hash))
+		{
+			return FALSE;
+		}
+
+		extra_bits = untoh64(hash + sizeof(hash) - sizeof(uint64_t));
+
+		for (i = 0, j = 0; j < sizeof(hash); j++)
+		{
+			index = 2 * (uint16_t)hash[i] + (extra_bits & 1);
+			if (!index_taken[index])
+			{
+				c_indices[i++] = index;
+				index_taken[index] = TRUE;
+			}
+			if (i == kappa)
+			{
+				return TRUE;
+			}
+		}
+	}
+}
+
+/**
+ * See header.
+ */
+bool bliss_utils_check_norms(bliss_param_set_t *set, int32_t *z1, int16_t *z2d)
+{
+	int32_t z2ds[set->n];
+	int32_t z1_min, z1_max, norm;
+	int16_t z2d_min, z2d_max;
+	int i;
+
+	/* some statistics on the values of z1 and z2d */
+	z1_min  = z1_max  = z1[0];
+	z2d_min = z2d_max = z2d[0];
+
+	for (i = 1; i < set->n; i++)
+	{
+		if (z1[i] < z1_min)
+		{
+			z1_min = z1[i];
+		}
+		else if (z1[i] > z1_max)
+		{
+			z1_max = z1[i];
+		}
+		if (z2d[i] < z2d_min)
+		{
+			z2d_min = z2d[i];
+		}
+		else if (z2d[i] > z2d_max)
+		{
+			z2d_max = z2d[i];
+		}
+	}
+	DBG2(DBG_LIB, "z1 = %d..%d, z2d = %d..%d", z1_min, z1_max, z2d_min, z2d_max);
+
+	/* Restriction on infinite norm */
+	for (i = 0; i < set->n; i++)
+	{
+		z2ds[i] = (1 << set->d) * z2d[i];
+
+		if (z1[i] >=  set->B_inf || z2ds[i] >=  set->B_inf ||
+			z1[i] <= -set->B_inf || z2ds[i] <= -set->B_inf)
+		{
+			DBG2(DBG_LIB, "signature rejected due to excessive infinite norm");
+			return FALSE;
+		}
+	}
+
+	/* Restriction on l2-norm */
+	norm = bliss_utils_scalar_product(z1, z1, set->n) +
+		   bliss_utils_scalar_product(z2ds, z2ds, set->n);
+
+	if (norm >= set->B_l2)
+	{
+		DBG2(DBG_LIB, "signature rejected due to excessive l2-norm");
+		return FALSE;
+	}
+
+	return TRUE;
+}
diff --git a/src/libstrongswan/plugins/bliss/bliss_utils.h b/src/libstrongswan/plugins/bliss/bliss_utils.h
new file mode 100644
index 0000000..063fd91
--- /dev/null
+++ b/src/libstrongswan/plugins/bliss/bliss_utils.h
@@ -0,0 +1,70 @@
+/*
+ * 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.
+ */
+
+/**
+ * @defgroup bliss_utils bliss_utils
+ * @{ @ingroup bliss_p
+ */
+
+#ifndef BLISS_UTILS_H_
+#define BLISS_UTILS_H_
+
+#include "bliss_param_set.h"
+
+#include <library.h>
+
+/**
+ * Compute the scalar product of two vectors of size n
+ *
+ * @param x			input vector of size n
+ * @param y			input vector of size n
+ * @param n			size of input vectors x and y
+ * @result			scalar product of x and y
+ */
+int32_t bliss_utils_scalar_product(int32_t *x, int32_t *y, int n);
+
+/**
+ * Drop d bits but round first
+ *
+ * @param set		BLISS parameter set
+ * @param x			input vector x of size n
+ * @param xd		rounded vector x with d bits dropped
+ */
+void bliss_utils_round_and_drop(bliss_param_set_t *set,	int32_t *x, int16_t *xd);
+
+/**
+ * Generate the binary challenge vector c as an array of kappa indices
+ *
+ * @param hasher	hasher used as an oracle
+ * @param data_hash	hash of the data to be signed
+ * @param ud		input vector ud of size n
+ * @param n			size of input vector ud
+ * @param kappa		parameter kappa
+ * @param c_indices	indexes of non-zero challenge coefficients
+ */
+bool bliss_utils_generate_c(hasher_t *hasher, chunk_t data_hash, uint16_t *ud,
+							int n, uint16_t kappa, uint16_t *c_indices);
+
+/**
+ * Check the infinity and l2 norms of the vectors z1 and z2d << d
+ *
+ * @param set	BLISS parameter set
+ * @param z1	input vector
+ * @param z2d	input vector
+ * @result		TRUE if infinite and l2 norms do not exceed boundaries
+ */
+bool bliss_utils_check_norms(bliss_param_set_t *set, int32_t *z1, int16_t *z2d);
+
+#endif /** BLISS_UTILS_H_ @}*/
diff --git a/src/libstrongswan/plugins/bliss/tests/Makefile.am b/src/libstrongswan/plugins/bliss/tests/Makefile.am
new file mode 100644
index 0000000..bd87753
--- /dev/null
+++ b/src/libstrongswan/plugins/bliss/tests/Makefile.am
@@ -0,0 +1,27 @@
+TESTS = bliss_tests
+
+check_PROGRAMS = $(TESTS)
+
+bliss_tests_SOURCES = \
+	suites/test_bliss_fft.c \
+	suites/test_bliss_bitpacker.c \
+	suites/test_bliss_huffman.c \
+	suites/test_bliss_keys.c \
+	suites/test_bliss_sampler.c \
+	suites/test_bliss_signature.c \
+	suites/test_bliss_sign.c \
+	bliss_tests.h bliss_tests.c
+
+bliss_tests_CFLAGS = \
+	-I$(top_srcdir)/src/libstrongswan \
+	-I$(top_srcdir)/src/libstrongswan/tests \
+	-I$(top_srcdir)/src/libstrongswan/plugins/bliss \
+	-DPLUGINDIR=\""$(abs_top_builddir)/src/libstrongswan/plugins\"" \
+	-DPLUGINS=\""${s_plugins}\"" \
+	@COVERAGE_CFLAGS@
+
+bliss_tests_LDFLAGS = @COVERAGE_LDFLAGS@
+bliss_tests_LDADD = \
+	$(top_builddir)/src/libstrongswan/libstrongswan.la \
+	$(top_builddir)/src/libstrongswan/tests/libtest.la \
+	../libbliss.la
diff --git a/src/libstrongswan/plugins/bliss/tests/Makefile.in b/src/libstrongswan/plugins/bliss/tests/Makefile.in
new file mode 100644
index 0000000..5a1ce3d
--- /dev/null
+++ b/src/libstrongswan/plugins/bliss/tests/Makefile.in
@@ -0,0 +1,985 @@
+# Makefile.in generated by automake 1.14.1 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994-2013 Free Software Foundation, Inc.
+
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+ at SET_MAKE@
+VPATH = @srcdir@
+am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)'
+am__make_running_with_option = \
+  case $${target_option-} in \
+      ?) ;; \
+      *) echo "am__make_running_with_option: internal error: invalid" \
+              "target option '$${target_option-}' specified" >&2; \
+         exit 1;; \
+  esac; \
+  has_opt=no; \
+  sane_makeflags=$$MAKEFLAGS; \
+  if $(am__is_gnu_make); then \
+    sane_makeflags=$$MFLAGS; \
+  else \
+    case $$MAKEFLAGS in \
+      *\\[\ \	]*) \
+        bs=\\; \
+        sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
+          | sed "s/$$bs$$bs[$$bs $$bs	]*//g"`;; \
+    esac; \
+  fi; \
+  skip_next=no; \
+  strip_trailopt () \
+  { \
+    flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
+  }; \
+  for flg in $$sane_makeflags; do \
+    test $$skip_next = yes && { skip_next=no; continue; }; \
+    case $$flg in \
+      *=*|--*) continue;; \
+        -*I) strip_trailopt 'I'; skip_next=yes;; \
+      -*I?*) strip_trailopt 'I';; \
+        -*O) strip_trailopt 'O'; skip_next=yes;; \
+      -*O?*) strip_trailopt 'O';; \
+        -*l) strip_trailopt 'l'; skip_next=yes;; \
+      -*l?*) strip_trailopt 'l';; \
+      -[dEDm]) skip_next=yes;; \
+      -[JT]) skip_next=yes;; \
+    esac; \
+    case $$flg in \
+      *$$target_option*) has_opt=yes; break;; \
+    esac; \
+  done; \
+  test $$has_opt = yes
+am__make_dryrun = (target_option=n; $(am__make_running_with_option))
+am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+TESTS = bliss_tests$(EXEEXT)
+check_PROGRAMS = $(am__EXEEXT_1)
+subdir = src/libstrongswan/plugins/bliss/tests
+DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
+	$(top_srcdir)/depcomp
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/m4/config/libtool.m4 \
+	$(top_srcdir)/m4/config/ltoptions.m4 \
+	$(top_srcdir)/m4/config/ltsugar.m4 \
+	$(top_srcdir)/m4/config/ltversion.m4 \
+	$(top_srcdir)/m4/config/lt~obsolete.m4 \
+	$(top_srcdir)/m4/macros/split-package-version.m4 \
+	$(top_srcdir)/m4/macros/with.m4 \
+	$(top_srcdir)/m4/macros/enable-disable.m4 \
+	$(top_srcdir)/m4/macros/add-plugin.m4 \
+	$(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+	$(ACLOCAL_M4)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+am__EXEEXT_1 = bliss_tests$(EXEEXT)
+am__dirstamp = $(am__leading_dot)dirstamp
+am_bliss_tests_OBJECTS = suites/bliss_tests-test_bliss_fft.$(OBJEXT) \
+	suites/bliss_tests-test_bliss_bitpacker.$(OBJEXT) \
+	suites/bliss_tests-test_bliss_huffman.$(OBJEXT) \
+	suites/bliss_tests-test_bliss_keys.$(OBJEXT) \
+	suites/bliss_tests-test_bliss_sampler.$(OBJEXT) \
+	suites/bliss_tests-test_bliss_signature.$(OBJEXT) \
+	suites/bliss_tests-test_bliss_sign.$(OBJEXT) \
+	bliss_tests-bliss_tests.$(OBJEXT)
+bliss_tests_OBJECTS = $(am_bliss_tests_OBJECTS)
+bliss_tests_DEPENDENCIES =  \
+	$(top_builddir)/src/libstrongswan/libstrongswan.la \
+	$(top_builddir)/src/libstrongswan/tests/libtest.la \
+	../libbliss.la
+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 = 
+bliss_tests_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+	$(LIBTOOLFLAGS) --mode=link $(CCLD) $(bliss_tests_CFLAGS) \
+	$(CFLAGS) $(bliss_tests_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
+am__v_P_1 = :
+AM_V_GEN = $(am__v_GEN_ at AM_V@)
+am__v_GEN_ = $(am__v_GEN_ at AM_DEFAULT_V@)
+am__v_GEN_0 = @echo "  GEN     " $@;
+am__v_GEN_1 = 
+AM_V_at = $(am__v_at_ at AM_V@)
+am__v_at_ = $(am__v_at_ at AM_DEFAULT_V@)
+am__v_at_0 = @
+am__v_at_1 = 
+DEFAULT_INCLUDES = -I. at am__isrc@ -I$(top_builddir)
+depcomp = $(SHELL) $(top_srcdir)/depcomp
+am__depfiles_maybe = depfiles
+am__mv = mv -f
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+	$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+	$(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \
+	$(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
+	$(AM_CFLAGS) $(CFLAGS)
+AM_V_CC = $(am__v_CC_ at AM_V@)
+am__v_CC_ = $(am__v_CC_ at AM_DEFAULT_V@)
+am__v_CC_0 = @echo "  CC      " $@;
+am__v_CC_1 = 
+CCLD = $(CC)
+LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+	$(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+	$(AM_LDFLAGS) $(LDFLAGS) -o $@
+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 = $(bliss_tests_SOURCES)
+DIST_SOURCES = $(bliss_tests_SOURCES)
+am__can_run_installinfo = \
+  case $$AM_UPDATE_INFO_DIR in \
+    n|no|NO) false;; \
+    *) (install-info --version) >/dev/null 2>&1;; \
+  esac
+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
+# *not* preserved.
+am__uniquify_input = $(AWK) '\
+  BEGIN { nonempty = 0; } \
+  { items[$$0] = 1; nonempty = 1; } \
+  END { if (nonempty) { for (i in items) print i; }; } \
+'
+# Make sure the list of sources is unique.  This is necessary because,
+# e.g., the same source file might be shared among _SOURCES variables
+# for different programs/libraries.
+am__define_uniq_tagged_files = \
+  list='$(am__tagged_files)'; \
+  unique=`for i in $$list; do \
+    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+  done | $(am__uniquify_input)`
+ETAGS = etags
+CTAGS = ctags
+am__tty_colors_dummy = \
+  mgn= red= grn= lgn= blu= brg= std=; \
+  am__color_tests=no
+am__tty_colors = { \
+  $(am__tty_colors_dummy); \
+  if test "X$(AM_COLOR_TESTS)" = Xno; then \
+    am__color_tests=no; \
+  elif test "X$(AM_COLOR_TESTS)" = Xalways; then \
+    am__color_tests=yes; \
+  elif test "X$$TERM" != Xdumb && { test -t 1; } 2>/dev/null; then \
+    am__color_tests=yes; \
+  fi; \
+  if test $$am__color_tests = yes; then \
+    red=''; \
+    grn=''; \
+    lgn=''; \
+    blu=''; \
+    mgn=''; \
+    brg=''; \
+    std=''; \
+  fi; \
+}
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+ALLOCA = @ALLOCA@
+AMTAR = @AMTAR@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+BFDLIB = @BFDLIB@
+BTLIB = @BTLIB@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+COVERAGE_CFLAGS = @COVERAGE_CFLAGS@
+COVERAGE_LDFLAGS = @COVERAGE_LDFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DLLIB = @DLLIB@
+DLLTOOL = @DLLTOOL@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+EASY_INSTALL = @EASY_INSTALL@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+FGREP = @FGREP@
+GEM = @GEM@
+GENHTML = @GENHTML@
+GPERF = @GPERF@
+GPRBUILD = @GPRBUILD@
+GREP = @GREP@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+LCOV = @LCOV@
+LD = @LD@
+LDFLAGS = @LDFLAGS@
+LEX = @LEX@
+LEXLIB = @LEXLIB@
+LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LIPO = @LIPO@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+MAKEINFO = @MAKEINFO@
+MANIFEST_TOOL = @MANIFEST_TOOL@
+MKDIR_P = @MKDIR_P@
+MYSQLCFLAG = @MYSQLCFLAG@
+MYSQLCONFIG = @MYSQLCONFIG@
+MYSQLLIB = @MYSQLLIB@
+NM = @NM@
+NMEDIT = @NMEDIT@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OPENSSL_LIB = @OPENSSL_LIB@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PACKAGE_VERSION_BUILD = @PACKAGE_VERSION_BUILD@
+PACKAGE_VERSION_MAJOR = @PACKAGE_VERSION_MAJOR@
+PACKAGE_VERSION_MINOR = @PACKAGE_VERSION_MINOR@
+PACKAGE_VERSION_REVIEW = @PACKAGE_VERSION_REVIEW@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PERL = @PERL@
+PKG_CONFIG = @PKG_CONFIG@
+PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
+PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
+PLUGIN_CFLAGS = @PLUGIN_CFLAGS@
+PTHREADLIB = @PTHREADLIB@
+PYTHON = @PYTHON@
+PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@
+PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
+PYTHON_PLATFORM = @PYTHON_PLATFORM@
+PYTHON_PREFIX = @PYTHON_PREFIX@
+PYTHON_VERSION = @PYTHON_VERSION@
+PY_TEST = @PY_TEST@
+RANLIB = @RANLIB@
+RTLIB = @RTLIB@
+RUBY = @RUBY@
+RUBYGEMDIR = @RUBYGEMDIR@
+RUBYINCLUDE = @RUBYINCLUDE@
+RUBYLIB = @RUBYLIB@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+SOCKLIB = @SOCKLIB@
+STRIP = @STRIP@
+UNWINDLIB = @UNWINDLIB@
+VERSION = @VERSION@
+YACC = @YACC@
+YFLAGS = @YFLAGS@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+aikgen_plugins = @aikgen_plugins@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+attest_plugins = @attest_plugins@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+c_plugins = @c_plugins@
+charon_natt_port = @charon_natt_port@
+charon_plugins = @charon_plugins@
+charon_udp_port = @charon_udp_port@
+clearsilver_LIBS = @clearsilver_LIBS@
+cmd_plugins = @cmd_plugins@
+datadir = @datadir@
+datarootdir = @datarootdir@
+dbusservicedir = @dbusservicedir@
+dev_headers = @dev_headers@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+fips_mode = @fips_mode@
+gtk_CFLAGS = @gtk_CFLAGS@
+gtk_LIBS = @gtk_LIBS@
+h_plugins = @h_plugins@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+imcvdir = @imcvdir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+ipsec_script = @ipsec_script@
+ipsec_script_upper = @ipsec_script_upper@
+ipsecdir = @ipsecdir@
+ipsecgroup = @ipsecgroup@
+ipseclibdir = @ipseclibdir@
+ipsecuser = @ipsecuser@
+json_CFLAGS = @json_CFLAGS@
+json_LIBS = @json_LIBS@
+libdir = @libdir@
+libexecdir = @libexecdir@
+libiptc_CFLAGS = @libiptc_CFLAGS@
+libiptc_LIBS = @libiptc_LIBS@
+linux_headers = @linux_headers@
+localedir = @localedir@
+localstatedir = @localstatedir@
+maemo_CFLAGS = @maemo_CFLAGS@
+maemo_LIBS = @maemo_LIBS@
+manager_plugins = @manager_plugins@
+mandir = @mandir@
+medsrv_plugins = @medsrv_plugins@
+mkdir_p = @mkdir_p@
+nm_CFLAGS = @nm_CFLAGS@
+nm_LIBS = @nm_LIBS@
+nm_ca_dir = @nm_ca_dir@
+nm_plugins = @nm_plugins@
+oldincludedir = @oldincludedir@
+pcsclite_CFLAGS = @pcsclite_CFLAGS@
+pcsclite_LIBS = @pcsclite_LIBS@
+pdfdir = @pdfdir@
+piddir = @piddir@
+pkgpyexecdir = @pkgpyexecdir@
+pkgpythondir = @pkgpythondir@
+pki_plugins = @pki_plugins@
+plugindir = @plugindir@
+pool_plugins = @pool_plugins@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+pyexecdir = @pyexecdir@
+pythondir = @pythondir@
+random_device = @random_device@
+resolv_conf = @resolv_conf@
+routing_table = @routing_table@
+routing_table_prio = @routing_table_prio@
+s_plugins = @s_plugins@
+sbindir = @sbindir@
+scepclient_plugins = @scepclient_plugins@
+scripts_plugins = @scripts_plugins@
+sharedstatedir = @sharedstatedir@
+soup_CFLAGS = @soup_CFLAGS@
+soup_LIBS = @soup_LIBS@
+srcdir = @srcdir@
+starter_plugins = @starter_plugins@
+strongswan_conf = @strongswan_conf@
+strongswan_options = @strongswan_options@
+swanctldir = @swanctldir@
+sysconfdir = @sysconfdir@
+systemd_daemon_CFLAGS = @systemd_daemon_CFLAGS@
+systemd_daemon_LIBS = @systemd_daemon_LIBS@
+systemd_journal_CFLAGS = @systemd_journal_CFLAGS@
+systemd_journal_LIBS = @systemd_journal_LIBS@
+systemdsystemunitdir = @systemdsystemunitdir@
+t_plugins = @t_plugins@
+target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+urandom_device = @urandom_device@
+xml_CFLAGS = @xml_CFLAGS@
+xml_LIBS = @xml_LIBS@
+bliss_tests_SOURCES = \
+	suites/test_bliss_fft.c \
+	suites/test_bliss_bitpacker.c \
+	suites/test_bliss_huffman.c \
+	suites/test_bliss_keys.c \
+	suites/test_bliss_sampler.c \
+	suites/test_bliss_signature.c \
+	suites/test_bliss_sign.c \
+	bliss_tests.h bliss_tests.c
+
+bliss_tests_CFLAGS = \
+	-I$(top_srcdir)/src/libstrongswan \
+	-I$(top_srcdir)/src/libstrongswan/tests \
+	-I$(top_srcdir)/src/libstrongswan/plugins/bliss \
+	-DPLUGINDIR=\""$(abs_top_builddir)/src/libstrongswan/plugins\"" \
+	-DPLUGINS=\""${s_plugins}\"" \
+	@COVERAGE_CFLAGS@
+
+bliss_tests_LDFLAGS = @COVERAGE_LDFLAGS@
+bliss_tests_LDADD = \
+	$(top_builddir)/src/libstrongswan/libstrongswan.la \
+	$(top_builddir)/src/libstrongswan/tests/libtest.la \
+	../libbliss.la
+
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .c .lo .o .obj
+$(srcdir)/Makefile.in:  $(srcdir)/Makefile.am  $(am__configure_deps)
+	@for dep in $?; do \
+	  case '$(am__configure_deps)' in \
+	    *$$dep*) \
+	      ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+	        && { if test -f $@; then exit 0; else break; fi; }; \
+	      exit 1;; \
+	  esac; \
+	done; \
+	echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/libstrongswan/plugins/bliss/tests/Makefile'; \
+	$(am__cd) $(top_srcdir) && \
+	  $(AUTOMAKE) --gnu src/libstrongswan/plugins/bliss/tests/Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+	@case '$?' in \
+	  *config.status*) \
+	    cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+	  *) \
+	    echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+	    cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+	esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure:  $(am__configure_deps)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4):  $(am__aclocal_m4_deps)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+
+clean-checkPROGRAMS:
+	@list='$(check_PROGRAMS)'; test -n "$$list" || exit 0; \
+	echo " rm -f" $$list; \
+	rm -f $$list || exit $$?; \
+	test -n "$(EXEEXT)" || exit 0; \
+	list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \
+	echo " rm -f" $$list; \
+	rm -f $$list
+suites/$(am__dirstamp):
+	@$(MKDIR_P) suites
+	@: > suites/$(am__dirstamp)
+suites/$(DEPDIR)/$(am__dirstamp):
+	@$(MKDIR_P) suites/$(DEPDIR)
+	@: > suites/$(DEPDIR)/$(am__dirstamp)
+suites/bliss_tests-test_bliss_fft.$(OBJEXT): suites/$(am__dirstamp) \
+	suites/$(DEPDIR)/$(am__dirstamp)
+suites/bliss_tests-test_bliss_bitpacker.$(OBJEXT):  \
+	suites/$(am__dirstamp) suites/$(DEPDIR)/$(am__dirstamp)
+suites/bliss_tests-test_bliss_huffman.$(OBJEXT):  \
+	suites/$(am__dirstamp) suites/$(DEPDIR)/$(am__dirstamp)
+suites/bliss_tests-test_bliss_keys.$(OBJEXT): suites/$(am__dirstamp) \
+	suites/$(DEPDIR)/$(am__dirstamp)
+suites/bliss_tests-test_bliss_sampler.$(OBJEXT):  \
+	suites/$(am__dirstamp) suites/$(DEPDIR)/$(am__dirstamp)
+suites/bliss_tests-test_bliss_signature.$(OBJEXT):  \
+	suites/$(am__dirstamp) suites/$(DEPDIR)/$(am__dirstamp)
+suites/bliss_tests-test_bliss_sign.$(OBJEXT): suites/$(am__dirstamp) \
+	suites/$(DEPDIR)/$(am__dirstamp)
+
+bliss_tests$(EXEEXT): $(bliss_tests_OBJECTS) $(bliss_tests_DEPENDENCIES) $(EXTRA_bliss_tests_DEPENDENCIES) 
+	@rm -f bliss_tests$(EXEEXT)
+	$(AM_V_CCLD)$(bliss_tests_LINK) $(bliss_tests_OBJECTS) $(bliss_tests_LDADD) $(LIBS)
+
+mostlyclean-compile:
+	-rm -f *.$(OBJEXT)
+	-rm -f suites/*.$(OBJEXT)
+
+distclean-compile:
+	-rm -f *.tab.c
+
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/bliss_tests-bliss_tests.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at suites/$(DEPDIR)/bliss_tests-test_bliss_bitpacker.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at suites/$(DEPDIR)/bliss_tests-test_bliss_fft.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at suites/$(DEPDIR)/bliss_tests-test_bliss_huffman.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at suites/$(DEPDIR)/bliss_tests-test_bliss_keys.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at suites/$(DEPDIR)/bliss_tests-test_bliss_sampler.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at suites/$(DEPDIR)/bliss_tests-test_bliss_sign.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at suites/$(DEPDIR)/bliss_tests-test_bliss_signature.Po at am__quote@
+
+.c.o:
+ at am__fastdepCC_TRUE@	$(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\
+ at am__fastdepCC_TRUE@	$(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\
+ at am__fastdepCC_TRUE@	$(am__mv) $$depbase.Tpo $$depbase.Po
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(COMPILE) -c -o $@ $<
+
+.c.obj:
+ at am__fastdepCC_TRUE@	$(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\
+ at am__fastdepCC_TRUE@	$(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\
+ at am__fastdepCC_TRUE@	$(am__mv) $$depbase.Tpo $$depbase.Po
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
+
+.c.lo:
+ at am__fastdepCC_TRUE@	$(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\
+ at am__fastdepCC_TRUE@	$(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\
+ at am__fastdepCC_TRUE@	$(am__mv) $$depbase.Tpo $$depbase.Plo
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(LTCOMPILE) -c -o $@ $<
+
+suites/bliss_tests-test_bliss_fft.o: suites/test_bliss_fft.c
+ at am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(bliss_tests_CFLAGS) $(CFLAGS) -MT suites/bliss_tests-test_bliss_fft.o -MD -MP -MF suites/$(DEPDIR)/bliss_tests-test_bliss_fft.Tpo -c -o suites/bliss_tests-test_bliss_fft.o `test -f 'suites/test_bliss_fft.c' || echo '$(srcdir)/'`suites/test_bliss_fft.c
+ at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) suites/$(DEPDIR)/bliss_tests-test_bliss_fft.Tpo suites/$(DEPDIR)/bliss_tests-test_bliss_fft.Po
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='suites/test_bliss_fft.c' object='suites/bliss_tests-test_bliss_fft.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) $(bliss_tests_CFLAGS) $(CFLAGS) -c -o suites/bliss_tests-test_bliss_fft.o `test -f 'suites/test_bliss_fft.c' || echo '$(srcdir)/'`suites/test_bliss_fft.c
+
+suites/bliss_tests-test_bliss_fft.obj: suites/test_bliss_fft.c
+ at am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(bliss_tests_CFLAGS) $(CFLAGS) -MT suites/bliss_tests-test_bliss_fft.obj -MD -MP -MF suites/$(DEPDIR)/bliss_tests-test_bliss_fft.Tpo -c -o suites/bliss_tests-test_bliss_fft.obj `if test -f 'suites/test_bliss_fft.c'; then $(CYGPATH_W) 'suites/test_bliss_fft.c'; else $(CYGPATH_W) '$(srcdir)/suites/test_bliss_fft.c'; fi`
+ at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) suites/$(DEPDIR)/bliss_tests-test_bliss_fft.Tpo suites/$(DEPDIR)/bliss_tests-test_bliss_fft.Po
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='suites/test_bliss_fft.c' object='suites/bliss_tests-test_bliss_fft.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) $(bliss_tests_CFLAGS) $(CFLAGS) -c -o suites/bliss_tests-test_bliss_fft.obj `if test -f 'suites/test_bliss_fft.c'; then $(CYGPATH_W) 'suites/test_bliss_fft.c'; else $(CYGPATH_W) '$(srcdir)/suites/test_bliss_fft.c'; fi`
+
+suites/bliss_tests-test_bliss_bitpacker.o: suites/test_bliss_bitpacker.c
+ at am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(bliss_tests_CFLAGS) $(CFLAGS) -MT suites/bliss_tests-test_bliss_bitpacker.o -MD -MP -MF suites/$(DEPDIR)/bliss_tests-test_bliss_bitpacker.Tpo -c -o suites/bliss_tests-test_bliss_bitpacker.o `test -f 'suites/test_bliss_bitpacker.c' || echo '$(srcdir)/'`suites/test_bliss_bitpacker.c
+ at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) suites/$(DEPDIR)/bliss_tests-test_bliss_bitpacker.Tpo suites/$(DEPDIR)/bliss_tests-test_bliss_bitpacker.Po
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='suites/test_bliss_bitpacker.c' object='suites/bliss_tests-test_bliss_bitpacker.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) $(bliss_tests_CFLAGS) $(CFLAGS) -c -o suites/bliss_tests-test_bliss_bitpacker.o `test -f 'suites/test_bliss_bitpacker.c' || echo '$(srcdir)/'`suites/test_bliss_bitpacker.c
+
+suites/bliss_tests-test_bliss_bitpacker.obj: suites/test_bliss_bitpacker.c
+ at am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(bliss_tests_CFLAGS) $(CFLAGS) -MT suites/bliss_tests-test_bliss_bitpacker.obj -MD -MP -MF suites/$(DEPDIR)/bliss_tests-test_bliss_bitpacker.Tpo -c -o suites/bliss_tests-test_bliss_bitpacker.obj `if test -f 'suites/test_bliss_bitpacker.c'; then $(CYGPATH_W) 'suites/test_bliss_bitpacker.c'; else $(CYGPATH_W) '$(srcdir)/suites/test_bliss_bitpacker.c'; fi`
+ at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) suites/$(DEPDIR)/bliss_tests-test_bliss_bitpacker.Tpo suites/$(DEPDIR)/bliss_tests-test_bliss_bitpacker.Po
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='suites/test_bliss_bitpacker.c' object='suites/bliss_tests-test_bliss_bitpacker.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) $(bliss_tests_CFLAGS) $(CFLAGS) -c -o suites/bliss_tests-test_bliss_bitpacker.obj `if test -f 'suites/test_bliss_bitpacker.c'; then $(CYGPATH_W) 'suites/test_bliss_bitpacker.c'; else $(CYGPATH_W) '$(srcdir)/suites/test_bliss_bitpacker.c'; fi`
+
+suites/bliss_tests-test_bliss_huffman.o: suites/test_bliss_huffman.c
+ at am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(bliss_tests_CFLAGS) $(CFLAGS) -MT suites/bliss_tests-test_bliss_huffman.o -MD -MP -MF suites/$(DEPDIR)/bliss_tests-test_bliss_huffman.Tpo -c -o suites/bliss_tests-test_bliss_huffman.o `test -f 'suites/test_bliss_huffman.c' || echo '$(srcdir)/'`suites/test_bliss_huffman.c
+ at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) suites/$(DEPDIR)/bliss_tests-test_bliss_huffman.Tpo suites/$(DEPDIR)/bliss_tests-test_bliss_huffman.Po
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='suites/test_bliss_huffman.c' object='suites/bliss_tests-test_bliss_huffman.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) $(bliss_tests_CFLAGS) $(CFLAGS) -c -o suites/bliss_tests-test_bliss_huffman.o `test -f 'suites/test_bliss_huffman.c' || echo '$(srcdir)/'`suites/test_bliss_huffman.c
+
+suites/bliss_tests-test_bliss_huffman.obj: suites/test_bliss_huffman.c
+ at am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(bliss_tests_CFLAGS) $(CFLAGS) -MT suites/bliss_tests-test_bliss_huffman.obj -MD -MP -MF suites/$(DEPDIR)/bliss_tests-test_bliss_huffman.Tpo -c -o suites/bliss_tests-test_bliss_huffman.obj `if test -f 'suites/test_bliss_huffman.c'; then $(CYGPATH_W) 'suites/test_bliss_huffman.c'; else $(CYGPATH_W) '$(srcdir)/suites/test_bliss_huffman.c'; fi`
+ at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) suites/$(DEPDIR)/bliss_tests-test_bliss_huffman.Tpo suites/$(DEPDIR)/bliss_tests-test_bliss_huffman.Po
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='suites/test_bliss_huffman.c' object='suites/bliss_tests-test_bliss_huffman.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) $(bliss_tests_CFLAGS) $(CFLAGS) -c -o suites/bliss_tests-test_bliss_huffman.obj `if test -f 'suites/test_bliss_huffman.c'; then $(CYGPATH_W) 'suites/test_bliss_huffman.c'; else $(CYGPATH_W) '$(srcdir)/suites/test_bliss_huffman.c'; fi`
+
+suites/bliss_tests-test_bliss_keys.o: suites/test_bliss_keys.c
+ at am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(bliss_tests_CFLAGS) $(CFLAGS) -MT suites/bliss_tests-test_bliss_keys.o -MD -MP -MF suites/$(DEPDIR)/bliss_tests-test_bliss_keys.Tpo -c -o suites/bliss_tests-test_bliss_keys.o `test -f 'suites/test_bliss_keys.c' || echo '$(srcdir)/'`suites/test_bliss_keys.c
+ at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) suites/$(DEPDIR)/bliss_tests-test_bliss_keys.Tpo suites/$(DEPDIR)/bliss_tests-test_bliss_keys.Po
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='suites/test_bliss_keys.c' object='suites/bliss_tests-test_bliss_keys.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) $(bliss_tests_CFLAGS) $(CFLAGS) -c -o suites/bliss_tests-test_bliss_keys.o `test -f 'suites/test_bliss_keys.c' || echo '$(srcdir)/'`suites/test_bliss_keys.c
+
+suites/bliss_tests-test_bliss_keys.obj: suites/test_bliss_keys.c
+ at am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(bliss_tests_CFLAGS) $(CFLAGS) -MT suites/bliss_tests-test_bliss_keys.obj -MD -MP -MF suites/$(DEPDIR)/bliss_tests-test_bliss_keys.Tpo -c -o suites/bliss_tests-test_bliss_keys.obj `if test -f 'suites/test_bliss_keys.c'; then $(CYGPATH_W) 'suites/test_bliss_keys.c'; else $(CYGPATH_W) '$(srcdir)/suites/test_bliss_keys.c'; fi`
+ at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) suites/$(DEPDIR)/bliss_tests-test_bliss_keys.Tpo suites/$(DEPDIR)/bliss_tests-test_bliss_keys.Po
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='suites/test_bliss_keys.c' object='suites/bliss_tests-test_bliss_keys.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) $(bliss_tests_CFLAGS) $(CFLAGS) -c -o suites/bliss_tests-test_bliss_keys.obj `if test -f 'suites/test_bliss_keys.c'; then $(CYGPATH_W) 'suites/test_bliss_keys.c'; else $(CYGPATH_W) '$(srcdir)/suites/test_bliss_keys.c'; fi`
+
+suites/bliss_tests-test_bliss_sampler.o: suites/test_bliss_sampler.c
+ at am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(bliss_tests_CFLAGS) $(CFLAGS) -MT suites/bliss_tests-test_bliss_sampler.o -MD -MP -MF suites/$(DEPDIR)/bliss_tests-test_bliss_sampler.Tpo -c -o suites/bliss_tests-test_bliss_sampler.o `test -f 'suites/test_bliss_sampler.c' || echo '$(srcdir)/'`suites/test_bliss_sampler.c
+ at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) suites/$(DEPDIR)/bliss_tests-test_bliss_sampler.Tpo suites/$(DEPDIR)/bliss_tests-test_bliss_sampler.Po
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='suites/test_bliss_sampler.c' object='suites/bliss_tests-test_bliss_sampler.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) $(bliss_tests_CFLAGS) $(CFLAGS) -c -o suites/bliss_tests-test_bliss_sampler.o `test -f 'suites/test_bliss_sampler.c' || echo '$(srcdir)/'`suites/test_bliss_sampler.c
+
+suites/bliss_tests-test_bliss_sampler.obj: suites/test_bliss_sampler.c
+ at am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(bliss_tests_CFLAGS) $(CFLAGS) -MT suites/bliss_tests-test_bliss_sampler.obj -MD -MP -MF suites/$(DEPDIR)/bliss_tests-test_bliss_sampler.Tpo -c -o suites/bliss_tests-test_bliss_sampler.obj `if test -f 'suites/test_bliss_sampler.c'; then $(CYGPATH_W) 'suites/test_bliss_sampler.c'; else $(CYGPATH_W) '$(srcdir)/suites/test_bliss_sampler.c'; fi`
+ at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) suites/$(DEPDIR)/bliss_tests-test_bliss_sampler.Tpo suites/$(DEPDIR)/bliss_tests-test_bliss_sampler.Po
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='suites/test_bliss_sampler.c' object='suites/bliss_tests-test_bliss_sampler.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) $(bliss_tests_CFLAGS) $(CFLAGS) -c -o suites/bliss_tests-test_bliss_sampler.obj `if test -f 'suites/test_bliss_sampler.c'; then $(CYGPATH_W) 'suites/test_bliss_sampler.c'; else $(CYGPATH_W) '$(srcdir)/suites/test_bliss_sampler.c'; fi`
+
+suites/bliss_tests-test_bliss_signature.o: suites/test_bliss_signature.c
+ at am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(bliss_tests_CFLAGS) $(CFLAGS) -MT suites/bliss_tests-test_bliss_signature.o -MD -MP -MF suites/$(DEPDIR)/bliss_tests-test_bliss_signature.Tpo -c -o suites/bliss_tests-test_bliss_signature.o `test -f 'suites/test_bliss_signature.c' || echo '$(srcdir)/'`suites/test_bliss_signature.c
+ at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) suites/$(DEPDIR)/bliss_tests-test_bliss_signature.Tpo suites/$(DEPDIR)/bliss_tests-test_bliss_signature.Po
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='suites/test_bliss_signature.c' object='suites/bliss_tests-test_bliss_signature.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) $(bliss_tests_CFLAGS) $(CFLAGS) -c -o suites/bliss_tests-test_bliss_signature.o `test -f 'suites/test_bliss_signature.c' || echo '$(srcdir)/'`suites/test_bliss_signature.c
+
+suites/bliss_tests-test_bliss_signature.obj: suites/test_bliss_signature.c
+ at am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(bliss_tests_CFLAGS) $(CFLAGS) -MT suites/bliss_tests-test_bliss_signature.obj -MD -MP -MF suites/$(DEPDIR)/bliss_tests-test_bliss_signature.Tpo -c -o suites/bliss_tests-test_bliss_signature.obj `if test -f 'suites/test_bliss_signature.c'; then $(CYGPATH_W) 'suites/test_bliss_signature.c'; else $(CYGPATH_W) '$(srcdir)/suites/test_bliss_signature.c'; fi`
+ at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) suites/$(DEPDIR)/bliss_tests-test_bliss_signature.Tpo suites/$(DEPDIR)/bliss_tests-test_bliss_signature.Po
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='suites/test_bliss_signature.c' object='suites/bliss_tests-test_bliss_signature.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) $(bliss_tests_CFLAGS) $(CFLAGS) -c -o suites/bliss_tests-test_bliss_signature.obj `if test -f 'suites/test_bliss_signature.c'; then $(CYGPATH_W) 'suites/test_bliss_signature.c'; else $(CYGPATH_W) '$(srcdir)/suites/test_bliss_signature.c'; fi`
+
+suites/bliss_tests-test_bliss_sign.o: suites/test_bliss_sign.c
+ at am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(bliss_tests_CFLAGS) $(CFLAGS) -MT suites/bliss_tests-test_bliss_sign.o -MD -MP -MF suites/$(DEPDIR)/bliss_tests-test_bliss_sign.Tpo -c -o suites/bliss_tests-test_bliss_sign.o `test -f 'suites/test_bliss_sign.c' || echo '$(srcdir)/'`suites/test_bliss_sign.c
+ at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) suites/$(DEPDIR)/bliss_tests-test_bliss_sign.Tpo suites/$(DEPDIR)/bliss_tests-test_bliss_sign.Po
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='suites/test_bliss_sign.c' object='suites/bliss_tests-test_bliss_sign.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) $(bliss_tests_CFLAGS) $(CFLAGS) -c -o suites/bliss_tests-test_bliss_sign.o `test -f 'suites/test_bliss_sign.c' || echo '$(srcdir)/'`suites/test_bliss_sign.c
+
+suites/bliss_tests-test_bliss_sign.obj: suites/test_bliss_sign.c
+ at am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(bliss_tests_CFLAGS) $(CFLAGS) -MT suites/bliss_tests-test_bliss_sign.obj -MD -MP -MF suites/$(DEPDIR)/bliss_tests-test_bliss_sign.Tpo -c -o suites/bliss_tests-test_bliss_sign.obj `if test -f 'suites/test_bliss_sign.c'; then $(CYGPATH_W) 'suites/test_bliss_sign.c'; else $(CYGPATH_W) '$(srcdir)/suites/test_bliss_sign.c'; fi`
+ at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) suites/$(DEPDIR)/bliss_tests-test_bliss_sign.Tpo suites/$(DEPDIR)/bliss_tests-test_bliss_sign.Po
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='suites/test_bliss_sign.c' object='suites/bliss_tests-test_bliss_sign.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) $(bliss_tests_CFLAGS) $(CFLAGS) -c -o suites/bliss_tests-test_bliss_sign.obj `if test -f 'suites/test_bliss_sign.c'; then $(CYGPATH_W) 'suites/test_bliss_sign.c'; else $(CYGPATH_W) '$(srcdir)/suites/test_bliss_sign.c'; fi`
+
+bliss_tests-bliss_tests.o: bliss_tests.c
+ at am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(bliss_tests_CFLAGS) $(CFLAGS) -MT bliss_tests-bliss_tests.o -MD -MP -MF $(DEPDIR)/bliss_tests-bliss_tests.Tpo -c -o bliss_tests-bliss_tests.o `test -f 'bliss_tests.c' || echo '$(srcdir)/'`bliss_tests.c
+ at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/bliss_tests-bliss_tests.Tpo $(DEPDIR)/bliss_tests-bliss_tests.Po
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='bliss_tests.c' object='bliss_tests-bliss_tests.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) $(bliss_tests_CFLAGS) $(CFLAGS) -c -o bliss_tests-bliss_tests.o `test -f 'bliss_tests.c' || echo '$(srcdir)/'`bliss_tests.c
+
+bliss_tests-bliss_tests.obj: bliss_tests.c
+ at am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(bliss_tests_CFLAGS) $(CFLAGS) -MT bliss_tests-bliss_tests.obj -MD -MP -MF $(DEPDIR)/bliss_tests-bliss_tests.Tpo -c -o bliss_tests-bliss_tests.obj `if test -f 'bliss_tests.c'; then $(CYGPATH_W) 'bliss_tests.c'; else $(CYGPATH_W) '$(srcdir)/bliss_tests.c'; fi`
+ at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/bliss_tests-bliss_tests.Tpo $(DEPDIR)/bliss_tests-bliss_tests.Po
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='bliss_tests.c' object='bliss_tests-bliss_tests.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) $(bliss_tests_CFLAGS) $(CFLAGS) -c -o bliss_tests-bliss_tests.obj `if test -f 'bliss_tests.c'; then $(CYGPATH_W) 'bliss_tests.c'; else $(CYGPATH_W) '$(srcdir)/bliss_tests.c'; fi`
+
+mostlyclean-libtool:
+	-rm -f *.lo
+
+clean-libtool:
+	-rm -rf .libs _libs
+
+ID: $(am__tagged_files)
+	$(am__define_uniq_tagged_files); mkid -fID $$unique
+tags: tags-am
+TAGS: tags
+
+tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+	set x; \
+	here=`pwd`; \
+	$(am__define_uniq_tagged_files); \
+	shift; \
+	if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
+	  test -n "$$unique" || unique=$$empty_fix; \
+	  if test $$# -gt 0; then \
+	    $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+	      "$$@" $$unique; \
+	  else \
+	    $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+	      $$unique; \
+	  fi; \
+	fi
+ctags: ctags-am
+
+CTAGS: ctags
+ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+	$(am__define_uniq_tagged_files); \
+	test -z "$(CTAGS_ARGS)$$unique" \
+	  || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+	     $$unique
+
+GTAGS:
+	here=`$(am__cd) $(top_builddir) && pwd` \
+	  && $(am__cd) $(top_srcdir) \
+	  && gtags -i $(GTAGS_ARGS) "$$here"
+cscopelist: cscopelist-am
+
+cscopelist-am: $(am__tagged_files)
+	list='$(am__tagged_files)'; \
+	case "$(srcdir)" in \
+	  [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
+	  *) sdir=$(subdir)/$(srcdir) ;; \
+	esac; \
+	for i in $$list; do \
+	  if test -f "$$i"; then \
+	    echo "$(subdir)/$$i"; \
+	  else \
+	    echo "$$sdir/$$i"; \
+	  fi; \
+	done >> $(top_builddir)/cscope.files
+
+distclean-tags:
+	-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+check-TESTS: $(TESTS)
+	@failed=0; all=0; xfail=0; xpass=0; skip=0; \
+	srcdir=$(srcdir); export srcdir; \
+	list=' $(TESTS) '; \
+	$(am__tty_colors); \
+	if test -n "$$list"; then \
+	  for tst in $$list; do \
+	    if test -f ./$$tst; then dir=./; \
+	    elif test -f $$tst; then dir=; \
+	    else dir="$(srcdir)/"; fi; \
+	    if $(TESTS_ENVIRONMENT) $${dir}$$tst $(AM_TESTS_FD_REDIRECT); then \
+	      all=`expr $$all + 1`; \
+	      case " $(XFAIL_TESTS) " in \
+	      *[\ \	]$$tst[\ \	]*) \
+		xpass=`expr $$xpass + 1`; \
+		failed=`expr $$failed + 1`; \
+		col=$$red; res=XPASS; \
+	      ;; \
+	      *) \
+		col=$$grn; res=PASS; \
+	      ;; \
+	      esac; \
+	    elif test $$? -ne 77; then \
+	      all=`expr $$all + 1`; \
+	      case " $(XFAIL_TESTS) " in \
+	      *[\ \	]$$tst[\ \	]*) \
+		xfail=`expr $$xfail + 1`; \
+		col=$$lgn; res=XFAIL; \
+	      ;; \
+	      *) \
+		failed=`expr $$failed + 1`; \
+		col=$$red; res=FAIL; \
+	      ;; \
+	      esac; \
+	    else \
+	      skip=`expr $$skip + 1`; \
+	      col=$$blu; res=SKIP; \
+	    fi; \
+	    echo "$${col}$$res$${std}: $$tst"; \
+	  done; \
+	  if test "$$all" -eq 1; then \
+	    tests="test"; \
+	    All=""; \
+	  else \
+	    tests="tests"; \
+	    All="All "; \
+	  fi; \
+	  if test "$$failed" -eq 0; then \
+	    if test "$$xfail" -eq 0; then \
+	      banner="$$All$$all $$tests passed"; \
+	    else \
+	      if test "$$xfail" -eq 1; then failures=failure; else failures=failures; fi; \
+	      banner="$$All$$all $$tests behaved as expected ($$xfail expected $$failures)"; \
+	    fi; \
+	  else \
+	    if test "$$xpass" -eq 0; then \
+	      banner="$$failed of $$all $$tests failed"; \
+	    else \
+	      if test "$$xpass" -eq 1; then passes=pass; else passes=passes; fi; \
+	      banner="$$failed of $$all $$tests did not behave as expected ($$xpass unexpected $$passes)"; \
+	    fi; \
+	  fi; \
+	  dashes="$$banner"; \
+	  skipped=""; \
+	  if test "$$skip" -ne 0; then \
+	    if test "$$skip" -eq 1; then \
+	      skipped="($$skip test was not run)"; \
+	    else \
+	      skipped="($$skip tests were not run)"; \
+	    fi; \
+	    test `echo "$$skipped" | wc -c` -le `echo "$$banner" | wc -c` || \
+	      dashes="$$skipped"; \
+	  fi; \
+	  report=""; \
+	  if test "$$failed" -ne 0 && test -n "$(PACKAGE_BUGREPORT)"; then \
+	    report="Please report to $(PACKAGE_BUGREPORT)"; \
+	    test `echo "$$report" | wc -c` -le `echo "$$banner" | wc -c` || \
+	      dashes="$$report"; \
+	  fi; \
+	  dashes=`echo "$$dashes" | sed s/./=/g`; \
+	  if test "$$failed" -eq 0; then \
+	    col="$$grn"; \
+	  else \
+	    col="$$red"; \
+	  fi; \
+	  echo "$${col}$$dashes$${std}"; \
+	  echo "$${col}$$banner$${std}"; \
+	  test -z "$$skipped" || echo "$${col}$$skipped$${std}"; \
+	  test -z "$$report" || echo "$${col}$$report$${std}"; \
+	  echo "$${col}$$dashes$${std}"; \
+	  test "$$failed" -eq 0; \
+	else :; fi
+
+distdir: $(DISTFILES)
+	@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+	topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+	list='$(DISTFILES)'; \
+	  dist_files=`for file in $$list; do echo $$file; done | \
+	  sed -e "s|^$$srcdirstrip/||;t" \
+	      -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+	case $$dist_files in \
+	  */*) $(MKDIR_P) `echo "$$dist_files" | \
+			   sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+			   sort -u` ;; \
+	esac; \
+	for file in $$dist_files; do \
+	  if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+	  if test -d $$d/$$file; then \
+	    dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+	    if test -d "$(distdir)/$$file"; then \
+	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+	    fi; \
+	    if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+	      cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+	    fi; \
+	    cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+	  else \
+	    test -f "$(distdir)/$$file" \
+	    || cp -p $$d/$$file "$(distdir)/$$file" \
+	    || exit 1; \
+	  fi; \
+	done
+check-am: all-am
+	$(MAKE) $(AM_MAKEFLAGS) $(check_PROGRAMS)
+	$(MAKE) $(AM_MAKEFLAGS) check-TESTS
+check: check-am
+all-am: Makefile
+installdirs:
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+	@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+	if test -z '$(STRIP)'; then \
+	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	      install; \
+	else \
+	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	    "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+	fi
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+	-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+	-test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+	-rm -f suites/$(DEPDIR)/$(am__dirstamp)
+	-rm -f suites/$(am__dirstamp)
+
+maintainer-clean-generic:
+	@echo "This command is intended for maintainers to use"
+	@echo "it deletes files that may require special tools to rebuild."
+clean: clean-am
+
+clean-am: clean-checkPROGRAMS clean-generic clean-libtool \
+	mostlyclean-am
+
+distclean: distclean-am
+	-rm -rf ./$(DEPDIR) suites/$(DEPDIR)
+	-rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+	distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+html-am:
+
+info: info-am
+
+info-am:
+
+install-data-am:
+
+install-dvi: install-dvi-am
+
+install-dvi-am:
+
+install-exec-am:
+
+install-html: install-html-am
+
+install-html-am:
+
+install-info: install-info-am
+
+install-info-am:
+
+install-man:
+
+install-pdf: install-pdf-am
+
+install-pdf-am:
+
+install-ps: install-ps-am
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+	-rm -rf ./$(DEPDIR) suites/$(DEPDIR)
+	-rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic \
+	mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am:
+
+.MAKE: check-am install-am install-strip
+
+.PHONY: CTAGS GTAGS TAGS all all-am check check-TESTS check-am clean \
+	clean-checkPROGRAMS 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-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
+
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/src/libstrongswan/plugins/bliss/tests/bliss_tests.c b/src/libstrongswan/plugins/bliss/tests/bliss_tests.c
new file mode 100644
index 0000000..de21e77
--- /dev/null
+++ b/src/libstrongswan/plugins/bliss/tests/bliss_tests.c
@@ -0,0 +1,60 @@
+/*
+ * 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.
+ */
+
+#include <test_runner.h>
+
+#include <library.h>
+
+/* declare test suite constructors */
+#define TEST_SUITE(x) test_suite_t* x();
+#include "bliss_tests.h"
+#undef TEST_SUITE
+
+static test_configuration_t tests[] = {
+#define TEST_SUITE(x) \
+	{ .suite = x, },
+#include "bliss_tests.h"
+	{ .suite = NULL, }
+};
+
+static bool test_runner_init(bool init)
+{
+	if (init)
+	{
+		char *plugins, *plugindir;
+
+		plugins = lib->settings->get_str(lib->settings,
+										"tests.load", PLUGINS);
+		plugindir = lib->settings->get_str(lib->settings,
+										"tests.plugindir", PLUGINDIR);
+		plugin_loader_add_plugindirs(plugindir, plugins);
+		if (!lib->plugins->load(lib->plugins, plugins))
+		{
+			return FALSE;
+		}
+	}
+	else
+	{
+		lib->processor->set_threads(lib->processor, 0);
+		lib->processor->cancel(lib->processor);
+		lib->plugins->unload(lib->plugins);
+	}
+	return TRUE;
+}
+
+int main(int argc, char *argv[])
+{
+	return test_runner_run("bliss", tests, test_runner_init);
+}
diff --git a/src/libstrongswan/plugins/bliss/tests/bliss_tests.h b/src/libstrongswan/plugins/bliss/tests/bliss_tests.h
new file mode 100644
index 0000000..f0959cc
--- /dev/null
+++ b/src/libstrongswan/plugins/bliss/tests/bliss_tests.h
@@ -0,0 +1,23 @@
+/*
+ * Copyright (C) 2014-2015 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.
+ */
+
+TEST_SUITE(bliss_fft_suite_create)
+TEST_SUITE(bliss_bitpacker_suite_create)
+TEST_SUITE(bliss_huffman_suite_create)
+TEST_SUITE(bliss_keys_suite_create)
+TEST_SUITE(bliss_sampler_suite_create)
+TEST_SUITE(bliss_signature_suite_create)
+TEST_SUITE(bliss_sign_suite_create)
+
diff --git a/src/libstrongswan/plugins/bliss/tests/suites/test_bliss_bitpacker.c b/src/libstrongswan/plugins/bliss/tests/suites/test_bliss_bitpacker.c
new file mode 100644
index 0000000..6a728e2
--- /dev/null
+++ b/src/libstrongswan/plugins/bliss/tests/suites/test_bliss_bitpacker.c
@@ -0,0 +1,112 @@
+/*
+ * 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.
+ */
+
+#include "test_suite.h"
+
+#include <bliss_bitpacker.h>
+
+static uint32_t bits[] = { 0, 1, 2, 3, 4, 7, 1, 14, 2, 29, 3, 28, 67, 0x2fe3a9c1};
+
+static chunk_t packed_bits = chunk_from_chars(0x6e, 0x71, 0xe1, 0x74,
+											  0x37, 0x21, 0x97, 0xf1,
+											  0xd4, 0xe0, 0x80);
+
+START_TEST(test_bliss_sign_bitpacker_write)
+{
+	chunk_t buf;
+	bliss_bitpacker_t *packer;
+	int i;
+
+	packer = bliss_bitpacker_create(81);
+
+	for (i = 0; i < 13; i++)
+	{
+		ck_assert(packer->write_bits(packer, bits[i], 1 + i/2));
+	}
+	ck_assert(packer->write_bits(packer, bits[13], 32));
+
+	buf = packer->extract_buf(packer);
+	ck_assert_int_eq(packer->get_bits(packer), 81);
+	ck_assert_chunk_eq(buf, packed_bits);
+
+	packer->destroy(packer);
+	free(buf.ptr);
+}
+END_TEST
+
+START_TEST(test_bliss_sign_bitpacker_read)
+{
+	uint32_t value;
+	bliss_bitpacker_t *packer;
+	int i;
+
+	packer = bliss_bitpacker_create_from_data(packed_bits);
+
+	ck_assert(!packer->read_bits(packer, &value, 33));
+
+	for (i = 0; i < 13; i++)
+	{
+		ck_assert(packer->read_bits(packer, &value, 1 + i/2));
+		ck_assert_int_eq(value, bits[i]);
+	}
+	ck_assert(packer->read_bits(packer, &value, 32));
+	ck_assert_int_eq(value, bits[13]);
+
+	packer->destroy(packer);
+}
+END_TEST
+
+START_TEST(test_bliss_sign_bitpacker_fail)
+{
+	bliss_bitpacker_t *packer;
+	uint32_t value;
+
+	packer = bliss_bitpacker_create(32);
+	ck_assert( packer->write_bits(packer, 0xff, 0));
+	ck_assert(!packer->write_bits(packer, 0, 33));
+	ck_assert( packer->write_bits(packer, 0x7f2a3b01, 31));
+	ck_assert(!packer->write_bits(packer, 3,  2));
+	packer->destroy(packer);
+
+	packer = bliss_bitpacker_create_from_data(
+							chunk_from_chars(0x7f, 0x2a, 0x3b, 0x01));
+	ck_assert(!packer->read_bits(packer, &value, 33));
+	ck_assert( packer->read_bits(packer, &value, 31));
+	ck_assert(!packer->read_bits(packer, &value,  2));
+	packer->destroy(packer);
+}
+END_TEST
+
+Suite *bliss_bitpacker_suite_create()
+{
+	Suite *s;
+	TCase *tc;
+
+	s = suite_create("bliss_bitpacker");
+
+	tc = tcase_create("bitpacker_write");
+	tcase_add_test(tc, test_bliss_sign_bitpacker_write);
+	suite_add_tcase(s, tc);
+
+	tc = tcase_create("bitpacker_read");
+	tcase_add_test(tc, test_bliss_sign_bitpacker_read);
+	suite_add_tcase(s, tc);
+
+	tc = tcase_create("bitpacker_fail");
+	tcase_add_test(tc, test_bliss_sign_bitpacker_fail);
+	suite_add_tcase(s, tc);
+
+	return s;
+}
diff --git a/src/libstrongswan/plugins/bliss/tests/suites/test_bliss_fft.c b/src/libstrongswan/plugins/bliss/tests/suites/test_bliss_fft.c
new file mode 100644
index 0000000..009aaf8
--- /dev/null
+++ b/src/libstrongswan/plugins/bliss/tests/suites/test_bliss_fft.c
@@ -0,0 +1,110 @@
+/*
+ * 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.
+ */
+
+#include "test_suite.h"
+
+#include <bliss_fft.h>
+
+static bliss_fft_params_t *fft_params[] = {
+	&bliss_fft_17_8,
+	&bliss_fft_12289_512
+};
+
+START_TEST(test_bliss_fft_impulse)
+{
+	bliss_fft_t *fft;
+	uint16_t n = fft_params[_i]->n;
+	uint32_t x[n], X[n];
+	int i;
+
+	for (i = 0; i < n; i++)
+	{
+		x[i] = 0;
+	}
+	x[0] = 1;
+ 
+	fft = bliss_fft_create(fft_params[_i]);
+	fft->transform(fft, x, X, FALSE);
+
+	for (i = 0; i < n; i++)
+	{
+		ck_assert(X[i] == 1);
+	}
+	fft->transform(fft, X, x, TRUE);
+
+	for (i = 0; i < n; i++)
+	{
+		ck_assert(x[i] == (i == 0));
+	}
+	fft->destroy(fft);
+}
+END_TEST
+
+START_TEST(test_bliss_fft_wrap)
+{
+	bliss_fft_t *fft;
+	uint16_t n = fft_params[_i]->n;
+	uint16_t q = fft_params[_i]->q;
+	uint32_t x[n],y[n], X[n], Y[n];
+	int i, j;
+
+	for (i = 0; i < n; i++)
+	{
+		x[i] = i;
+		y[i] = 0;
+	}
+	fft = bliss_fft_create(fft_params[_i]);
+	ck_assert(fft->get_size(fft) == n);
+	ck_assert(fft->get_modulus(fft) == q); 
+	fft->transform(fft, x, X, FALSE);
+
+	for (j = 0; j < n; j++)
+	{
+		y[j] = 1;
+		fft->transform(fft, y, Y, FALSE);
+
+		for (i = 0; i < n; i++)
+		{
+			Y[i] = (X[i] * Y[i]) % q;
+		}
+		fft->transform(fft, Y, Y, TRUE);
+
+		for (i = 0; i < n; i++)
+		{
+			ck_assert(Y[i] == ( i < j ? q - n - i + j : i - j));
+		}
+		y[j] = 0;
+	}
+	fft->destroy(fft);  
+}
+END_TEST
+
+Suite *bliss_fft_suite_create()
+{
+	Suite *s;
+	TCase *tc;
+
+	s = suite_create("bliss_fft");
+
+	tc = tcase_create("impulse");
+	tcase_add_loop_test(tc, test_bliss_fft_impulse, 0, countof(fft_params));
+	suite_add_tcase(s, tc);
+
+	tc = tcase_create("negative_wrap");
+	tcase_add_loop_test(tc, test_bliss_fft_wrap, 0, countof(fft_params));
+	suite_add_tcase(s, tc);
+
+	return s;
+}
diff --git a/src/libstrongswan/plugins/bliss/tests/suites/test_bliss_huffman.c b/src/libstrongswan/plugins/bliss/tests/suites/test_bliss_huffman.c
new file mode 100644
index 0000000..5447d07
--- /dev/null
+++ b/src/libstrongswan/plugins/bliss/tests/suites/test_bliss_huffman.c
@@ -0,0 +1,122 @@
+/*
+ * Copyright (C) 2015 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 <bliss_huffman_coder.h>
+
+static chunk_t data = chunk_from_chars(0x5f, 0x71, 0x9e, 0x4c);
+
+START_TEST(test_bliss_huffman_encode)
+{
+	bliss_bitpacker_t *packer;
+	bliss_huffman_code_t *code;
+	bliss_huffman_coder_t *coder;
+	chunk_t encoding;
+
+	packer = bliss_bitpacker_create(32);
+	ck_assert(packer);
+
+	code = bliss_huffman_code_get_by_id(BLISS_B_I);
+	ck_assert(code);
+
+	coder = bliss_huffman_coder_create(code, packer);
+	ck_assert(coder);
+
+	ck_assert( coder->encode(coder, 0,  0));	/* 0 */
+	ck_assert( coder->encode(coder, 1,  0));	/* 10 */
+	ck_assert( coder->encode(coder, 2,  0));	/* 111 */
+	ck_assert( coder->encode(coder, 0,  1));	/* 1101 */
+	ck_assert( coder->encode(coder, 0, -1));	/* 11000 */
+	ck_assert( coder->encode(coder, 1,  1));	/* 110011 */
+	ck_assert( coder->encode(coder, 1, -1));	/* 1100100 */
+	ck_assert(!coder->encode(coder, 3,  0));	/* 11001010 */
+	ck_assert(!coder->encode(coder, 8,  0));	/* - */
+
+	encoding = packer->extract_buf(packer);
+	ck_assert(chunk_equals(encoding, data));
+
+	chunk_free(&encoding);
+	coder->destroy(coder);
+	packer->destroy(packer);
+}
+END_TEST
+
+START_TEST(test_bliss_huffman_decode)
+{
+	bliss_bitpacker_t *packer;
+	bliss_huffman_code_t *code;
+	bliss_huffman_coder_t *coder;
+	int32_t z1;
+	int16_t z2;
+
+	packer = bliss_bitpacker_create_from_data(data);
+	ck_assert(packer);
+
+	code = bliss_huffman_code_get_by_id(BLISS_II);
+	ck_assert(!code);
+	code = bliss_huffman_code_get_by_id(BLISS_B_II);
+	ck_assert(!code);
+	code = bliss_huffman_code_get_by_id(BLISS_B_I);
+	ck_assert(code);
+
+	coder = bliss_huffman_coder_create(code, packer);
+	ck_assert(coder);
+
+	ck_assert(coder->decode(coder, &z1, &z2));	/* 0 */
+	ck_assert(z1 == 0 && z2 == 0);
+
+	ck_assert(coder->decode(coder, &z1, &z2));	/* 10 */
+	ck_assert(z1 == 1 && z2 == 0);
+
+	ck_assert(coder->decode(coder, &z1, &z2));	/* 111 */
+	ck_assert(z1 == 2 && z2 == 0);
+
+	ck_assert(coder->decode(coder, &z1, &z2));	/* 1101 */
+	ck_assert(z1 == 0 && z2 == 1);
+
+	ck_assert(coder->decode(coder, &z1, &z2));	/* 11000 */
+	ck_assert(z1 == 0 && z2 == -1);
+
+	ck_assert(coder->decode(coder, &z1, &z2));	/* 110011 */
+	ck_assert(z1 == 1 && z2 == 1);
+
+	ck_assert(coder->decode(coder, &z1, &z2));	/* 1100100 */
+	ck_assert(z1 == 1 && z2 == -1);
+
+	ck_assert(!coder->decode(coder, &z1, &z2));	/* 11001010 */
+
+	coder->destroy(coder);
+	packer->destroy(packer);
+}
+END_TEST
+
+Suite *bliss_huffman_suite_create()
+{
+	Suite *s;
+	TCase *tc;
+
+	s = suite_create("bliss_huffman");
+
+	tc = tcase_create("huffman_encode");
+	tcase_add_test(tc, test_bliss_huffman_encode);
+	suite_add_tcase(s, tc);
+
+	tc = tcase_create("huffman_decode");
+	tcase_add_test(tc, test_bliss_huffman_decode);
+	suite_add_tcase(s, tc);
+
+	return s;
+}
diff --git a/src/libstrongswan/plugins/bliss/tests/suites/test_bliss_keys.c b/src/libstrongswan/plugins/bliss/tests/suites/test_bliss_keys.c
new file mode 100644
index 0000000..f48bc1d
--- /dev/null
+++ b/src/libstrongswan/plugins/bliss/tests/suites/test_bliss_keys.c
@@ -0,0 +1,249 @@
+/*
+ * Copyright (C) 2015 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 <bliss_private_key.h>
+#include <bliss_public_key.h>
+
+static chunk_t privkey_chunk[] = {
+	{NULL, 0},
+	chunk_from_chars(0x30, 0x00),
+	chunk_from_chars(0x30, 0x01),
+	chunk_from_chars(0x30, 0x03, 0x06, 0x01, 0x01),
+	chunk_from_chars(0x30, 0x0d, 0x06, 0x0b, 0x2b, 0x06, 0x01, 0x04, 0x01, 0x82,
+					 0xa0, 0x2a, 0x05, 0x02, 0x06),
+	chunk_from_chars(0x30, 0x0f, 0x06, 0x0b, 0x2b, 0x06, 0x01, 0x04, 0x01, 0x82,
+					 0xa0, 0x2a, 0x05, 0x02, 0x05, 0x03, 0x00),
+	chunk_from_chars(0x30, 0x82, 0x04, 0x9a, 0x06, 0x0b, 0x2b, 0x06, 0x01, 0x04,
+					 0x01, 0x82, 0xa0, 0x2a, 0x05, 0x02, 0x05, 0x03, 0x82, 0x03,
+					 0x81, 0x00, 0x81, 0xe5, 0xd2, 0x71, 0xeb, 0x98, 0xe5, 0x24,
+					 0x34, 0xe4, 0x8a, 0x27, 0x23, 0x7d, 0x7d, 0x2c, 0xa3, 0xa7,
+					 0x3f, 0x87, 0xad, 0xae, 0xfa, 0xe4, 0x66, 0x1c, 0xef, 0x69,
+					 0x63, 0x5e, 0x91, 0xda, 0x41, 0x45, 0xd5, 0x8a, 0xb5, 0x26,
+					 0x33, 0x32, 0xe0, 0xa2, 0x9b, 0x52, 0x5e, 0x49, 0x5d, 0x0d,
+					 0x62, 0x72, 0x68, 0xa5, 0x94, 0x24, 0x03, 0x98, 0x48, 0x60,
+					 0x4a, 0x98, 0x97, 0x0d, 0x60, 0x7d, 0x00, 0x4f, 0xb9, 0xaf,
+					 0xcb, 0x6b, 0x41, 0x3d, 0x5b, 0xe4, 0x3e, 0x9a, 0xee, 0x06,
+		/*  100 */	 0xa1, 0xd0, 0x93, 0x53, 0x88, 0x58, 0x83, 0xb2, 0x44, 0xa1,
+					 0x16, 0x58, 0x3d, 0x32, 0xa1, 0x29, 0x85, 0x1a, 0x24, 0xc8,
+					 0xb8, 0x8c, 0x1f, 0x43, 0xbb, 0x4b, 0xdd, 0x8e, 0x72, 0xd3,
+					 0xf4, 0xfc, 0x02, 0x69, 0x47, 0xa5, 0x9d, 0xd0, 0xfc, 0xa6,
+					 0x94, 0x2e, 0x02, 0x6d, 0x85, 0x2c, 0x6d, 0xe3, 0x91, 0xd5,
+					 0xf1, 0x54, 0xbd, 0x1e, 0x63, 0x6b, 0xee, 0x28, 0xf9, 0xc6,
+					 0xec, 0x05, 0x99, 0xd5, 0xdd, 0xe5, 0x72, 0x9b, 0xbc, 0xa7,
+					 0x5a, 0x4a, 0x46, 0x3e, 0xec, 0xd7, 0x0b, 0xc5, 0x23, 0x00,
+					 0xdc, 0x08, 0x09, 0x57, 0x44, 0x2e, 0x43, 0x0f, 0xea, 0xca,
+					 0x2a, 0x31, 0xbe, 0xf3, 0x04, 0x8f, 0x8b, 0xa6, 0x3c, 0x35,
+		/*  200 */	 0x80, 0x2b, 0xe2, 0x18, 0x22, 0xfd, 0xe9, 0x39, 0x57, 0xed,
+					 0x77, 0x1d, 0x32, 0x02, 0x48, 0x2c, 0x85, 0x53, 0x9f, 0x4a,
+					 0xd8, 0x86, 0x4d, 0xd2, 0x26, 0x19, 0x12, 0x19, 0xa2, 0xb5,
+					 0xdf, 0x02, 0x50, 0xe4, 0x32, 0x9a, 0x27, 0xd0, 0x9e, 0x49,
+					 0x4a, 0x13, 0x9a, 0xfc, 0x07, 0x98, 0x60, 0x65, 0xf4, 0xc1,
+					 0x6c, 0x9a, 0x15, 0x28, 0x74, 0x5c, 0xd0, 0xa8, 0xe6, 0x2e,
+					 0x1f, 0xe9, 0xe6, 0x2b, 0xc8, 0x46, 0xe9, 0x26, 0xb0, 0xf0,
+					 0x8a, 0xe6, 0x8c, 0x9b, 0xbf, 0x64, 0xa0, 0x59, 0x33, 0x4f,
+					 0xc0, 0x0c, 0x16, 0x72, 0x89, 0x79, 0x2a, 0x3a, 0x5e, 0x3d,
+					 0x40, 0xbb, 0x73, 0xa9, 0xc0, 0x52, 0x70, 0x57, 0x06, 0xc1,
+		/*  300 */	 0xe7, 0x70, 0xb8, 0x6d, 0x1b, 0x50, 0x61, 0x85, 0xee, 0x3e,
+					 0xe5, 0x5a, 0x8a, 0x75, 0x9f, 0x1e, 0xb7, 0xea, 0x54, 0x5a,
+					 0x8f, 0x52, 0xc2, 0xae, 0x2c, 0x7a, 0x58, 0xe6, 0xcb, 0xa6,
+					 0x9b, 0x68, 0x84, 0x79, 0xf2, 0x82, 0x05, 0x57, 0xaa, 0xd5,
+					 0x51, 0x82, 0xec, 0x84, 0x63, 0xce, 0xf4, 0xa7, 0xdf, 0x4e,
+					 0xac, 0x7d, 0xdd, 0xc3, 0x02, 0x68, 0xe0, 0x35, 0xa1, 0x92,
+					 0x29, 0x02, 0x2c, 0xa0, 0xe4, 0x29, 0x66, 0xd3, 0xe8, 0xd9,
+					 0x52, 0x0f, 0x3b, 0xec, 0x53, 0x63, 0x57, 0xc3, 0xd2, 0x59,
+					 0x38, 0xe7, 0x74, 0xf4, 0x1d, 0x03, 0x88, 0x3c, 0xe9, 0x97,
+					 0x37, 0xd7, 0x12, 0x66, 0x2a, 0xb5, 0xf8, 0xcd, 0x10, 0x87,
+		/*  400 */	 0x5d, 0x6a, 0x69, 0xbb, 0x9b, 0xc5, 0x55, 0x3c, 0x09, 0x46,
+					 0x04, 0x57, 0xc0, 0x2f, 0x77, 0x89, 0xe2, 0x88, 0x15, 0x6b,
+					 0x71, 0x56, 0xe1, 0xa2, 0x30, 0x71, 0x5f, 0x1d, 0x27, 0x12,
+					 0xbf, 0xc3, 0x55, 0xde, 0xe5, 0x9c, 0x4e, 0xb8, 0xc6, 0xec,
+					 0x96, 0x3a, 0x5d, 0x6d, 0xe9, 0xd3, 0xf8, 0x28, 0xda, 0x3f,
+					 0x75, 0x24, 0xd0, 0x34, 0x50, 0xa6, 0x28, 0x65, 0x6a, 0xe9,
+					 0xa6, 0x89, 0xe5, 0x5d, 0x45, 0xaf, 0x63, 0x34, 0xaf, 0x31,
+					 0x29, 0x82, 0xe6, 0x03, 0x80, 0x5c, 0x34, 0x28, 0xd1, 0x9f,
+					 0xca, 0xd3, 0x96, 0xcb, 0x31, 0xde, 0xdb, 0xf0, 0x07, 0x2b,
+					 0xc5, 0xbc, 0x29, 0xd1, 0x11, 0xf4, 0x23, 0x3b, 0x14, 0xb5,
+		/*  500 */	 0xa6, 0xf1, 0x02, 0x9e, 0x66, 0xbe, 0xdc, 0xc4, 0xca, 0xf7,
+					 0xc0, 0x81, 0x92, 0x7c, 0xea, 0xe3, 0x42, 0x54, 0x8a, 0x6f,
+					 0x0a, 0x2a, 0xa7, 0x2a, 0x92, 0xab, 0x09, 0xb1, 0x61, 0x91,
+					 0xaa, 0x90, 0x54, 0xa3, 0x76, 0x64, 0xe2, 0xfd, 0x81, 0x9a,
+					 0x4c, 0x35, 0x11, 0x28, 0xf3, 0x14, 0x97, 0x1b, 0x61, 0xa4,
+					 0x67, 0x43, 0xae, 0x90, 0x6b, 0xe4, 0x29, 0x34, 0xec, 0x08,
+					 0xbc, 0x6a, 0x82, 0x45, 0xc7, 0x7d, 0xdc, 0xd0, 0x03, 0x98,
+					 0x29, 0x63, 0x05, 0x94, 0xb2, 0xb9, 0x04, 0xce, 0x34, 0x9a,
+					 0x64, 0xae, 0x9a, 0xa9, 0x11, 0xa5, 0x13, 0x07, 0xcc, 0x92,
+					 0xe9, 0xe5, 0x98, 0x13, 0x13, 0x8f, 0x8b, 0xb2, 0x77, 0x75,
+		/*  600 */	 0x2a, 0x6f, 0xb1, 0xa6, 0x98, 0xbf, 0x50, 0xaf, 0xa7, 0x15,
+					 0x2a, 0xe6, 0xdf, 0x41, 0xb6, 0x5e, 0x72, 0xb2, 0x74, 0xf2,
+					 0x38, 0x88, 0x41, 0x56, 0x53, 0xea, 0x83, 0x23, 0x8a, 0x6d,
+					 0x6c, 0x64, 0x6c, 0xa6, 0x04, 0x79, 0x51, 0x92, 0x89, 0xbe,
+					 0x2a, 0x54, 0xd8, 0x5a, 0x8d, 0x5b, 0x9c, 0xfc, 0x62, 0x05,
+					 0x0f, 0xbd, 0x85, 0x12, 0x57, 0x45, 0x96, 0x2e, 0x8f, 0x76,
+					 0xd4, 0x33, 0xfb, 0x4a, 0xc2, 0x9f, 0x57, 0x96, 0xb3, 0xa2,
+					 0xc6, 0xa6, 0x95, 0x3c, 0x9e, 0x7e, 0x15, 0x12, 0xd7, 0xe4,
+					 0x65, 0x05, 0x5d, 0x72, 0xc2, 0x28, 0x10, 0xa9, 0x68, 0xa9,
+					 0x01, 0xfe, 0x9e, 0x36, 0x07, 0x80, 0x41, 0xc8, 0xa3, 0x5f,
+		/*  700 */	 0x18, 0x3b, 0x38, 0x09, 0x95, 0xe2, 0x87, 0xad, 0x03, 0xfd,
+					 0xdd, 0xa6, 0xe9, 0x8e, 0xa8, 0x3a, 0xc9, 0x45, 0x7b, 0xdc,
+					 0xc2, 0x6a, 0x30, 0x78, 0xaa, 0xba, 0x32, 0xe9, 0x8a, 0x65,
+					 0x48, 0x13, 0x5b, 0x29, 0x18, 0x2e, 0x5c, 0x68, 0x8d, 0x71,
+					 0x01, 0x09, 0xab, 0x7d, 0x1a, 0xe9, 0x09, 0x74, 0x1b, 0xe1,
+					 0x90, 0x00, 0xb9, 0xda, 0xa3, 0x03, 0xb7, 0x6c, 0xdd, 0x40,
+					 0xb6, 0xe3, 0xde, 0xa6, 0x7b, 0xe9, 0x3d, 0x41, 0x4d, 0xc7,
+					 0xad, 0xa5, 0xf9, 0x8b, 0x88, 0xd4, 0x1a, 0x75, 0xb5, 0xb6,
+					 0x9f, 0x51, 0x9b, 0x8b, 0xd7, 0xa4, 0x02, 0xb0, 0x62, 0x45,
+					 0xdd, 0x6c, 0x11, 0x35, 0x03, 0x77, 0x1c, 0xdb, 0xc5, 0xac,
+		/*  800 */	 0x60, 0x37, 0x20, 0x15, 0xaf, 0xbd, 0xae, 0x76, 0x51, 0xd2,
+					 0xfb, 0x63, 0x23, 0x19, 0x81, 0xa6, 0x59, 0x7b, 0x68, 0x00,
+					 0x3d, 0x68, 0x89, 0x6b, 0x5a, 0x29, 0xbd, 0x4f, 0xc1, 0x50,
+					 0xe4, 0x98, 0x85, 0xe6, 0x1a, 0xdd, 0xc8, 0xe4, 0xa1, 0x2b,
+					 0x99, 0x42, 0x81, 0x4d, 0x07, 0xf4, 0x24, 0x93, 0x88, 0xfe,
+					 0x40, 0x90, 0x5a, 0x56, 0x0b, 0x7f, 0x8d, 0x14, 0x82, 0x6d,
+					 0xaf, 0xf6, 0x0a, 0x3d, 0xe6, 0x64, 0xb5, 0x48, 0x01, 0x37,
+					 0xfe, 0xf3, 0xba, 0x67, 0xcc, 0xd2, 0xba, 0x32, 0x76, 0xe8,
+					 0xa7, 0x41, 0x1f, 0x2a, 0xfc, 0xa9, 0x72, 0x66, 0xc7, 0xd5,
+					 0x76, 0x02, 0x6b, 0x77, 0xba, 0x6c, 0xd4, 0x84, 0x68, 0x0e,
+		/*  900 */	 0x62, 0xc8, 0x43, 0xb0, 0x81, 0xd5, 0x8f, 0xdb, 0x42, 0xc9,
+					 0xf4, 0xaf, 0x71, 0xbd, 0xb9, 0x6c, 0xd6, 0xdc, 0x03, 0x81,
+					 0x81, 0x00, 0xc5, 0x10, 0x40, 0x33, 0x0f, 0xc0, 0x14, 0x01,
+					 0x00, 0x03, 0x0c, 0x0c, 0x00, 0x00, 0x00, 0x4c, 0x0f, 0x10,
+					 0x03, 0x10, 0x00, 0x00, 0x01, 0xc0, 0x43, 0x40, 0x03, 0x5c,
+					 0x00, 0x07, 0xc0, 0x51, 0x34, 0x01, 0x30, 0x0c, 0x00, 0x00,
+					 0x04, 0xc0, 0x3d, 0x40, 0x03, 0x07, 0x40, 0xd3, 0x50, 0x0c,
+					 0x04, 0x03, 0x00, 0x11, 0x41, 0x30, 0x00, 0xc1, 0xc0, 0xc3,
+					 0x03, 0x5f, 0x04, 0x30, 0x01, 0x40, 0x40, 0x00, 0x40, 0x40,
+					 0x10, 0x40, 0x05, 0x05, 0x00, 0x53, 0x00, 0x04, 0x50, 0x00,
+		/* 1000 */	 0x00, 0x00, 0x0c, 0x00, 0x51, 0x00, 0x00, 0x00, 0x04, 0xc7,
+					 0x01, 0x50, 0xc0, 0x11, 0x00, 0x04, 0x03, 0xc0, 0x04, 0x00,
+					 0x70, 0x4c, 0x31, 0x03, 0xc0, 0x40, 0xc4, 0x40, 0x40, 0xc0,
+					 0x0c, 0x0c, 0xf1, 0x40, 0xc1, 0x31, 0x70, 0x17, 0xc0, 0x30,
+					 0xc1, 0x04, 0x0c, 0x04, 0x00, 0xc4, 0x01, 0x00, 0x34, 0x00,
+					 0x03, 0x81, 0x81, 0x00, 0xcc, 0x00, 0x50, 0x30, 0xc4, 0x13,
+					 0x0f, 0xf0, 0x43, 0x01, 0x33, 0x40, 0x30, 0x01, 0x40, 0x10,
+					 0x57, 0x04, 0x03, 0x04, 0x10, 0x00, 0xf0, 0x03, 0x04, 0x01,
+					 0x00, 0x10, 0x34, 0x03, 0xf0, 0x1c, 0x01, 0x40, 0x30, 0xf4,
+					 0x00, 0x40, 0x34, 0xc3, 0x00, 0x00, 0x01, 0x00, 0x01, 0x10,
+		/* 1100 */	 0x3f, 0x03, 0x40, 0x00, 0x10, 0x10, 0x00, 0x40, 0x03, 0x00,
+					 0x03, 0x04, 0x40, 0x03, 0x00, 0x13, 0x03, 0x00, 0xc0, 0x01,
+					 0x34, 0x01, 0x00, 0x00, 0x10, 0xf4, 0x00, 0xf0, 0x30, 0x00,
+					 0x00, 0xc3, 0x1c, 0x41, 0x00, 0x40, 0x30, 0x04, 0x10, 0xc4,
+					 0x11, 0x03, 0x00, 0x10, 0x04, 0x4f, 0x17, 0xc0, 0x00, 0x30,
+					 0xcd, 0x3c, 0x40, 0xc4, 0x00, 0xf0, 0x00, 0x00, 0x04, 0x30,
+					 0x0f, 0x31, 0x34, 0xf0, 0x00, 0x07, 0x0c, 0x34, 0x00, 0x50,
+					 0x05, 0x03, 0x10, 0x70, 0x00, 0x33, 0x0c, 0x00, 0xc4, 0x54,
+					 0x07, 0x00)
+};
+
+START_TEST(test_bliss_keys_priv)
+{
+	private_key_t *privkey;
+
+	privkey = lib->creds->create(lib->creds, CRED_PRIVATE_KEY, KEY_BLISS,
+								 BUILD_BLOB, privkey_chunk[_i], BUILD_END);
+	if (_i == countof(privkey_chunk) - 1)
+	{
+		ck_assert(privkey);
+		privkey->destroy(privkey);
+	}
+	else
+	{
+		ck_assert(!privkey);
+	}
+}
+END_TEST
+
+typedef struct privkey_mod_t privkey_mod_t;
+
+struct privkey_mod_t {
+	int offset;
+	char byte;
+};
+
+static privkey_mod_t privkey_mod[] = {
+	{   20, 0x80 },
+	{   22, 0xc1 },
+	{  920, 0x80 },
+	{  922, 0x85 },
+	{ 1052, 0x80 },
+	{ 1054, 0x8c }
+};
+
+START_TEST(test_bliss_keys_priv_mod)
+{
+	private_key_t *privkey;
+	chunk_t data;
+
+	data = chunk_clone(privkey_chunk[countof(privkey_chunk) - 1]);
+	data.ptr[privkey_mod[_i].offset] = privkey_mod[_i].byte;
+
+	privkey = lib->creds->create(lib->creds, CRED_PRIVATE_KEY, KEY_BLISS,
+								 BUILD_BLOB, data, BUILD_END);
+	ck_assert(!privkey);
+	chunk_free(&data);
+}
+END_TEST
+
+static chunk_t pubkey_chunk[] = {
+	{NULL, 0},
+	chunk_from_chars(0x30, 0x00),
+	chunk_from_chars(0x30, 0x01),
+	chunk_from_chars(0x30, 0x02, 0x30, 0x00),
+	chunk_from_chars(0x30, 0x05, 0x30, 0x03, 0x06, 0x01, 0x01),
+	chunk_from_chars(0x30, 0x11, 0x30, 0x0F, 0x06, 0x0b, 0x2b, 0x06, 0x01, 0x04,
+					 0x01, 0x82, 0xa0, 0x2a, 0x05, 0x01, 0x01, 0x04, 0x00),
+	chunk_from_chars(0x30, 0x12, 0x30, 0x10, 0x06, 0x0b, 0x2b, 0x06, 0x01, 0x04,
+					 0x01, 0x82, 0xa0, 0x2a, 0x05, 0x01, 0x01, 0x06, 0x01, 0x01),
+	chunk_from_chars(0x30, 0x1c, 0x30, 0x1a, 0x06, 0x0b, 0x2b, 0x06, 0x01, 0x04,
+					 0x01, 0x82, 0xa0, 0x2a, 0x05, 0x01, 0x01, 0x06, 0x0b, 0x2b,
+					 0x06, 0x01, 0x04, 0x01, 0x82, 0xa0, 0x2a, 0x05, 0x02, 0x06),
+	chunk_from_chars(0x30, 0x1e, 0x30, 0x1a, 0x06, 0x0b, 0x2b, 0x06, 0x01, 0x04,
+					 0x01, 0x82, 0xa0, 0x2a, 0x05, 0x01, 0x01, 0x06, 0x0b, 0x2b,
+					 0x06, 0x01, 0x04, 0x01, 0x82, 0xa0, 0x2a, 0x05, 0x02, 0x05,
+					 0x03, 0x00)
+};
+
+START_TEST(test_bliss_keys_pub)
+{
+	public_key_t *pubkey;
+
+	pubkey = lib->creds->create(lib->creds, CRED_PUBLIC_KEY, KEY_ANY,
+								 BUILD_BLOB, pubkey_chunk[_i], BUILD_END);
+	ck_assert(!pubkey);
+}
+END_TEST
+
+Suite *bliss_keys_suite_create()
+{
+	Suite *s;
+	TCase *tc;
+
+	s = suite_create("bliss_keys");
+
+	tc = tcase_create("keys_priv");
+	tcase_add_loop_test(tc, test_bliss_keys_priv, 0, countof(privkey_chunk));
+	suite_add_tcase(s, tc);
+
+	tc = tcase_create("keys_priv_mod");
+	tcase_add_loop_test(tc, test_bliss_keys_priv_mod, 0, countof(privkey_mod));
+	suite_add_tcase(s, tc);
+
+	tc = tcase_create("keys_pub");
+	tcase_add_loop_test(tc, test_bliss_keys_pub, 0, countof(pubkey_chunk));
+	suite_add_tcase(s, tc);
+
+	return s;
+}
diff --git a/src/libstrongswan/plugins/bliss/tests/suites/test_bliss_sampler.c b/src/libstrongswan/plugins/bliss/tests/suites/test_bliss_sampler.c
new file mode 100644
index 0000000..1bd1266
--- /dev/null
+++ b/src/libstrongswan/plugins/bliss/tests/suites/test_bliss_sampler.c
@@ -0,0 +1,97 @@
+/*
+ * 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.
+ */
+
+#include "test_suite.h"
+
+#include <bliss_sampler.h>
+
+static u_int key_size[] = { 1, 3, 4};
+
+START_TEST(test_bliss_sampler_gaussian)
+{
+	bliss_sampler_t *sampler;
+	bliss_param_set_t *set;
+	int i, k, count;
+	uint32_t hist[8], sign[3];
+	int32_t z;
+	hash_algorithm_t alg;
+	size_t seed_len;
+	chunk_t seed;
+
+	set = bliss_param_set_get_by_id(key_size[_i]);
+	alg = HASH_SHA256;
+	seed_len = 32;
+	count = 10000000;
+
+	seed = chunk_alloc(seed_len);
+	memset(seed.ptr, 0xcc, seed_len);
+
+	for (k = 0; k < 3; k++)
+	{
+		sign[k] = 0;
+	}
+	for (k = 0; k < 8; k++)
+	{
+		hist[k] = 0;
+	}
+
+	sampler = bliss_sampler_create(alg, seed, set);
+	for (i = 0; i < count; i++)
+	{
+		ck_assert(sampler->gaussian(sampler, &z));
+		if (z == 0)
+		{
+			sign[1]++;
+			hist[0]++;
+		}
+		else if (z > 0)
+		{
+			sign[2]++;
+			hist[z/256]++;
+		}
+		else
+		{
+			sign[0]++;
+			hist[(-z)/256]++;
+		}
+	}
+	sampler->destroy(sampler);
+	free(seed.ptr);
+
+	DBG1(DBG_LIB, "histogram");	
+	for (k = 0; k < 8; k++)
+	{
+		DBG1(DBG_LIB, "%d %7d", k, hist[k]);
+	}
+	DBG1(DBG_LIB, "- %7d", sign[0]);
+	DBG1(DBG_LIB, "0 %7d", sign[1]);
+	DBG1(DBG_LIB, "+ %7d", sign[2]);
+}
+END_TEST
+
+Suite *bliss_sampler_suite_create()
+{
+	Suite *s;
+	TCase *tc;
+
+	s = suite_create("bliss_sampler");
+
+	tc = tcase_create("sampler_gaussian");
+	tcase_set_timeout(tc, 10);
+	tcase_add_loop_test(tc, test_bliss_sampler_gaussian, 0, countof(key_size));
+	suite_add_tcase(s, tc);
+
+	return s;
+}
diff --git a/src/libstrongswan/plugins/bliss/tests/suites/test_bliss_sign.c b/src/libstrongswan/plugins/bliss/tests/suites/test_bliss_sign.c
new file mode 100644
index 0000000..8b4e9cb
--- /dev/null
+++ b/src/libstrongswan/plugins/bliss/tests/suites/test_bliss_sign.c
@@ -0,0 +1,211 @@
+/*
+ * Copyright (C) 2014-2015 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 <bliss_private_key.h>
+#include <bliss_public_key.h>
+
+static u_int key_type[] = { 1, 3, 4 };
+static u_int key_strength[] = { 128, 160, 192 };
+
+START_TEST(test_bliss_sign_all)
+{
+	signature_scheme_t signature_scheme;
+	private_key_t *privkey, *privkey1;
+	public_key_t *pubkey, *pubkey1;
+	chunk_t msg, signature, privkey_blob, pubkey_blob, pubkey_fp, privkey_fp;
+	int k;
+
+	for (k = 0; k < 4; k++)
+	{
+		int verify_count = 1000;
+
+		switch (k)
+		{
+			case 1:
+				signature_scheme = SIGN_BLISS_WITH_SHA256;
+				break;
+			case 2:
+				signature_scheme = SIGN_BLISS_WITH_SHA384;
+				break;
+			default:
+				signature_scheme = SIGN_BLISS_WITH_SHA512;
+		}
+
+		/* enforce BLISS-B key for k = 2, 3 */
+		lib->settings->set_bool(lib->settings,
+				"%s.plugins.bliss.use_bliss_b", k >= 2, lib->ns);
+
+		msg = chunk_from_str("Hello Dolly!");
+
+		/* generate private key */
+		privkey = lib->creds->create(lib->creds, CRED_PRIVATE_KEY, KEY_BLISS,
+									 BUILD_KEY_SIZE, key_type[_i], BUILD_END);
+		ck_assert(privkey);
+
+		/* generate ASN.1 DER and PEM encoding of private key */
+		ck_assert(privkey->get_encoding(privkey, (k % 2) ?
+				  PRIVKEY_ASN1_DER : PRIVKEY_PEM, &privkey_blob));
+
+		/* extract public key from private key */
+		pubkey = privkey->get_public_key(privkey);
+		ck_assert(pubkey);
+
+		/* generate ASN.1 DER and PEM encodings of public key */
+		ck_assert(pubkey->get_encoding(pubkey, (k % 2) ?
+				  PUBKEY_SPKI_ASN1_DER : PUBKEY_PEM, &pubkey_blob));
+
+		/* compare fingerprints of public and private key */
+		ck_assert(pubkey->get_fingerprint(pubkey, (k % 2) ?
+				  KEYID_PUBKEY_INFO_SHA1 : KEYID_PUBKEY_SHA1, &pubkey_fp));
+		ck_assert(privkey->get_fingerprint(privkey, (k % 2) ?
+				  KEYID_PUBKEY_INFO_SHA1 : KEYID_PUBKEY_SHA1, &privkey_fp));
+		ck_assert(chunk_equals(pubkey_fp, privkey_fp));
+
+		/* retrieve fingerprints of public and private key from cache */
+		ck_assert(pubkey->get_fingerprint(pubkey, (k % 2) ?
+				  KEYID_PUBKEY_INFO_SHA1 : KEYID_PUBKEY_SHA1, &pubkey_fp));
+		ck_assert(privkey->get_fingerprint(privkey, (k % 2) ?
+				  KEYID_PUBKEY_INFO_SHA1 : KEYID_PUBKEY_SHA1, &privkey_fp));
+
+		/* get a reference of the private key and destroy both instances */
+		privkey1 = privkey->get_ref(privkey);
+		ck_assert(privkey1);
+		ck_assert(privkey1 == privkey);
+		privkey->destroy(privkey);
+		privkey1->destroy(privkey1);
+
+		/* get a reference of the public key and destroy both instances */
+		pubkey1 = pubkey->get_ref(pubkey);
+		ck_assert(pubkey1);
+		ck_assert(pubkey1 == pubkey);
+		pubkey->destroy(pubkey);
+		pubkey1->destroy(pubkey1);
+
+		/* enforce BLISS-B key for k = 1, 3 */
+		lib->settings->set_bool(lib->settings,
+				"%s.plugins.bliss.use_bliss_b", k % 2, lib->ns);
+
+		/* load private key from ASN.1 blob */
+		privkey = lib->creds->create(lib->creds, CRED_PRIVATE_KEY, KEY_BLISS,
+									 BUILD_BLOB, privkey_blob, BUILD_END);
+		ck_assert(privkey);
+		ck_assert(privkey->get_type(privkey) == KEY_BLISS);
+		ck_assert(privkey->get_keysize(privkey) == key_strength[_i]);
+		chunk_free(&privkey_blob);
+
+		/* load public key from ASN.1 blob */
+		pubkey = lib->creds->create(lib->creds, CRED_PUBLIC_KEY, KEY_ANY,
+									BUILD_BLOB, pubkey_blob, BUILD_END);
+		ck_assert(pubkey);
+		ck_assert(pubkey->get_type(pubkey) == KEY_BLISS);
+		ck_assert(pubkey->get_keysize(pubkey) == key_strength[_i]);
+		chunk_free(&pubkey_blob);
+
+		/* generate and verify 1000 BLISS signatures */
+		while (verify_count--)
+		{
+			ck_assert(privkey->sign(privkey, signature_scheme, msg,
+									&signature));
+			ck_assert(pubkey->verify(pubkey, signature_scheme, msg,
+									 signature));
+			free(signature.ptr);
+		}
+		privkey->destroy(privkey);
+		pubkey->destroy(pubkey);
+	}
+}
+END_TEST
+
+START_TEST(test_bliss_sign_fail)
+{
+	private_key_t *privkey;
+	public_key_t *pubkey;
+	chunk_t msg, signature, encoding, fp;
+
+	/* generate non-supported BLISS-II private key */
+	privkey = lib->creds->create(lib->creds, CRED_PRIVATE_KEY, KEY_BLISS,
+								 BUILD_KEY_SIZE, BLISS_II, BUILD_END);
+	ck_assert(!privkey);
+
+	/* generate non-supported BLISS-B-II private key */
+	privkey = lib->creds->create(lib->creds, CRED_PRIVATE_KEY, KEY_BLISS,
+								 BUILD_KEY_SIZE, BLISS_B_II, BUILD_END);
+	ck_assert(!privkey);
+
+	/* generate supported BLISS-B-I private key */
+	privkey = lib->creds->create(lib->creds, CRED_PRIVATE_KEY, KEY_BLISS,
+								 BUILD_KEY_SIZE, BLISS_B_I, BUILD_END);
+	ck_assert(privkey);
+
+	/* wrong private key encoding format */
+	ck_assert(!privkey->get_encoding(privkey, PUBKEY_PEM, &encoding));
+
+	/* wrong fingerprint encoding format */
+	ck_assert(!privkey->get_fingerprint(privkey, KEYID_PGPV4, &fp));
+
+	/* extract public key */
+	pubkey = privkey->get_public_key(privkey);
+	ck_assert(pubkey);
+
+	/* wrong private key encoding format */
+	ck_assert(!pubkey->get_encoding(pubkey, PRIVKEY_PEM, &encoding));
+
+	/* wrong fingerprint encoding format */
+	ck_assert(!pubkey->get_fingerprint(pubkey, KEYID_PGPV4, &fp));
+
+	/* encryption / decryption operation is not defined for BLISS */
+	ck_assert(!pubkey->encrypt(pubkey, ENCRYPT_UNKNOWN, chunk_empty, NULL));
+	ck_assert(!privkey->decrypt(privkey, ENCRYPT_UNKNOWN, chunk_empty, NULL));
+
+	/* sign with invalid signature scheme */
+	ck_assert(!privkey->sign(privkey, SIGN_UNKNOWN, msg, &signature));
+
+	/* generate valid signature */
+	msg = chunk_from_str("Hello Dolly!");
+	ck_assert(privkey->sign(privkey, SIGN_BLISS_WITH_SHA512, msg, &signature));
+
+	/* verify with invalid signature scheme */
+	ck_assert(!pubkey->verify(pubkey, SIGN_UNKNOWN, msg, signature));
+
+	/* corrupt signature */
+	signature.ptr[signature.len - 1] ^= 0x80;
+	ck_assert(!pubkey->verify(pubkey, SIGN_BLISS_WITH_SHA512, msg, signature));
+
+	free(signature.ptr);
+	privkey->destroy(privkey);
+	pubkey->destroy(pubkey);
+}
+END_TEST
+
+Suite *bliss_sign_suite_create()
+{
+	Suite *s;
+	TCase *tc;
+
+	s = suite_create("bliss_sign");
+
+	tc = tcase_create("sign_all");
+	test_case_set_timeout(tc, 30);
+	tcase_add_loop_test(tc, test_bliss_sign_all, 0, countof(key_type));
+	suite_add_tcase(s, tc);
+
+	tc = tcase_create("sign_fail");
+	tcase_add_test(tc, test_bliss_sign_fail);
+	suite_add_tcase(s, tc);
+
+	return s;
+}
diff --git a/src/libstrongswan/plugins/bliss/tests/suites/test_bliss_signature.c b/src/libstrongswan/plugins/bliss/tests/suites/test_bliss_signature.c
new file mode 100644
index 0000000..2a2f48c
--- /dev/null
+++ b/src/libstrongswan/plugins/bliss/tests/suites/test_bliss_signature.c
@@ -0,0 +1,141 @@
+/*
+ * Copyright (C) 2015 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 <bliss_signature.h>
+
+static chunk_t data = chunk_from_chars(
+	0xC1, 0xA1, 0x96, 0x98, 0x4F, 0x60, 0xF5, 0xCA, 0x89, 0x9E,
+	0x78, 0xAF, 0x64, 0xDD, 0x01, 0x76, 0x04, 0x29, 0x11, 0xD0,
+	0x21, 0x9E, 0xE4, 0x2D, 0xC5, 0x82, 0x69, 0x19, 0x82, 0x75,
+	0x30, 0xAC, 0xB0, 0x64, 0xCB, 0x65, 0x19, 0x22, 0x4A, 0x03,
+	0x03, 0x61, 0x4A, 0x37, 0x8E, 0xA3, 0xB6, 0xB3, 0x58, 0x44,
+	0xFD, 0x68, 0x38, 0xF1, 0x4B, 0xCF, 0xE8, 0xA2, 0x05, 0x39,
+	0x87, 0xE0, 0x5E, 0x7C, 0x45, 0x33, 0x4A, 0xEB, 0x2E, 0xCF,
+	0x98, 0x01, 0x3D, 0x28, 0x60, 0xCE, 0x90, 0x45, 0xF0, 0x8E,
+	0x36, 0x25, 0x50, 0x8B, 0xA2, 0xC0, 0x6E, 0xDF, 0xC2, 0xA1,
+	0x35, 0xC1, 0x16, 0x14, 0xE8, 0x6A, 0xE3, 0x9C, 0x0B, 0x32,
+	0x53, 0x55, 0x60, 0x52, 0x43, 0x93, 0xBB, 0x9F, 0x1D, 0x17,
+	0xDC, 0x6E, 0x26, 0x99, 0x60, 0x83, 0x12, 0x53, 0xB0, 0x2B,
+	0x36, 0xE2, 0x95, 0xA7, 0xBF, 0x9B, 0xC0, 0x0A, 0x63, 0xD6,
+	0x32, 0xA9, 0xE2, 0xAD, 0x02, 0x53, 0x10, 0x81, 0x00, 0xD4,
+	0x9A, 0xC2, 0x04, 0x1B, 0x48, 0x53, 0x37, 0xF0, 0x95, 0x39,
+	0x4B, 0x2E, 0x37, 0x28, 0xE2, 0x70, 0xAD, 0xB5, 0xF1, 0x63,
+	0x48, 0x17, 0xEF, 0x45, 0xC0, 0x30, 0xA6, 0xAA, 0x37, 0x9A,
+	0x00, 0x8F, 0x8D, 0xAC, 0x66, 0x2C, 0x96, 0x8C, 0xC2, 0x74,
+	0x9D, 0x66, 0x16, 0x5D, 0x70, 0x70, 0x1D, 0x2F, 0x11, 0xBD,
+	0x11, 0x62, 0x58, 0xC6, 0xB2, 0xA6, 0xFA, 0xB7, 0x8C, 0x10,
+	0x6A, 0x13, 0x34, 0x25, 0xB8, 0xF2, 0x46, 0xE3, 0x08, 0xAD,
+	0x8D, 0x49, 0x33, 0x24, 0x37, 0xA5, 0x0A, 0xF9, 0x5E, 0x95,
+	0xF9, 0x50, 0xDA, 0x2B, 0x80, 0x4F, 0x10, 0x4F, 0xAB, 0xE4,
+	0x96, 0xB1, 0xA1, 0x28, 0xCE, 0x6D, 0xB6, 0x17, 0x33, 0x2A,
+	0xE0, 0xC3, 0x80, 0xAA, 0x3D, 0x1A, 0x5C, 0x48, 0xA0, 0x48,
+	0x60, 0xCC, 0xC7, 0x29, 0x4F, 0xB8, 0x96, 0xDF, 0xC6, 0x6A,
+	0xC2, 0x83, 0x5E, 0xFC, 0xD7, 0x4E, 0xCA, 0x14, 0xB4, 0xC6,
+	0x30, 0x29, 0xC7, 0xCE, 0x79, 0x42, 0x2D, 0x22, 0x28, 0x99,
+	0x59, 0x14, 0xFB, 0x04, 0xAD, 0x79, 0x3C, 0x74, 0x34, 0xC6,
+	0x7A, 0x1C, 0x13, 0x07, 0x17, 0xB1, 0x8A, 0x02, 0xA7, 0x70,
+	0x3C, 0x5B, 0xBA, 0x88, 0xA2, 0xE6, 0x4B, 0x2A, 0xC1, 0x1E,
+	0x42, 0xDD, 0x83, 0x2B, 0x00, 0xCC, 0xF8, 0x80, 0x03, 0x7E,
+	0x97, 0xA4, 0x04, 0xE1, 0xB2, 0x0B, 0xE2, 0xF3, 0x91, 0x91,
+	0x80, 0xA0, 0xC5, 0x44, 0x67, 0xB1, 0x56, 0xD0, 0x13, 0x58,
+	0x7B, 0x6E, 0x12, 0xE7, 0x3A, 0x90, 0xE4, 0x2C, 0x44, 0x17,
+	0xA3, 0xBD, 0x21, 0x68, 0x45, 0x61, 0x20, 0x57, 0x8D, 0x4A,
+	0xF1, 0xE6, 0xD3, 0x17, 0xC9, 0xB0, 0xF8, 0x3A, 0x87, 0x6A,
+	0x7E, 0x25, 0x45, 0xDC, 0x9A, 0x1D, 0xAC, 0x10, 0xB6, 0xF6,
+	0x07, 0x4C, 0x50, 0x92, 0xF9, 0xE1, 0x3E, 0xAD, 0x3B, 0x80,
+	0x20, 0xA8, 0x34, 0x04, 0xD6, 0x0D, 0x2D, 0x46, 0x69, 0x5E,
+	0x8C, 0x4B, 0xB0, 0x1C, 0x37, 0xD8, 0x0D, 0x72, 0x7B, 0xE6,
+	0xEE, 0x04, 0x81, 0x98, 0x78, 0x69, 0x88, 0xD8, 0xDF, 0x04,
+	0xF0, 0x80, 0xE2, 0x0A, 0xD3, 0x60, 0x94, 0xDF, 0x49, 0xF7,
+	0x52, 0x95, 0xA6, 0xAF, 0x8C, 0x13, 0x10, 0x09, 0xAA, 0x03,
+	0xAC, 0x2C, 0x89, 0x2D, 0x2C, 0x61, 0x0F, 0xBE, 0x5C, 0x29,
+	0x01, 0x7C, 0x9E, 0xD2, 0xFF, 0x34, 0xA1, 0x9E, 0xEE, 0xBF,
+	0x28, 0x18, 0x3A, 0x17, 0xA6, 0x40, 0x94, 0xD5, 0xC4, 0xEC,
+	0x27, 0x0A, 0x40, 0x1C, 0xC4, 0x16, 0x80, 0x4E, 0x6F, 0xDD,
+	0xA5, 0x6A, 0x03, 0xE8, 0xBA, 0xB2, 0xAA, 0x7A, 0x7F, 0x4B,
+	0x30, 0x11, 0x11, 0x12, 0x4A, 0xFE, 0xB2, 0x99, 0xC6, 0x12,
+	0x1A, 0x98, 0xC0, 0x15, 0x41, 0xE1, 0x55, 0x35, 0x54, 0xF2,
+	0x1C, 0xE2, 0x78, 0x85, 0x66, 0xD3, 0x9C, 0x8A, 0x88, 0x7C,
+	0x86, 0x7F, 0x48, 0xBE, 0xB7, 0x1C, 0xE4, 0xCF, 0x35, 0xEE,
+	0x24, 0xA6, 0x62, 0xD6, 0x36, 0x1F, 0x66, 0x10, 0x5D, 0xEF,
+	0x07, 0x64, 0xA8, 0xD0, 0xAD, 0x2F, 0x47, 0x02, 0xA2, 0x0F,
+	0x73, 0x96, 0x2A, 0x21, 0x20, 0x36, 0x01, 0xA3, 0x2F, 0x5E,
+	0xC8, 0x80, 0x3A, 0x54, 0xA6, 0xB5, 0xD0, 0x19, 0xBF, 0xC4,
+	0x35, 0x01, 0x0B, 0x2A, 0x8E, 0x61, 0x4A, 0xDD, 0xB2, 0x4A,
+	0xE1, 0x0C, 0x15, 0x94, 0x9C, 0xD2, 0x54, 0x93, 0x85, 0x16,
+	0x49, 0x69, 0xA0, 0x41, 0x34, 0x16, 0x69, 0x28, 0x74, 0x11,
+	0x88, 0x44, 0xC8, 0x46, 0x5E, 0x62, 0xFF, 0x6E, 0xC5, 0xA8,
+	0xE8, 0x8A, 0x8A, 0xFA, 0x2D, 0x94, 0x14, 0xD4, 0x51, 0x16,
+	0xB0, 0x40, 0xDC, 0xF3, 0xAA, 0x97, 0x39, 0x1A, 0xDA, 0x7F,
+	0x41, 0x61, 0x25, 0x1E, 0xDF, 0x46, 0x29, 0x44, 0x80, 0xEA,
+	0x10, 0xE4, 0x0F, 0x94, 0xA6, 0x52, 0x20, 0x06, 0x9C, 0x69,
+	0x48, 0x1F, 0x45, 0x30, 0x4B, 0x21, 0x02, 0xE6, 0xF3, 0x44,
+	0x35, 0xC1, 0xC8, 0xC9, 0x68, 0x6C, 0x43, 0xA4, 0x56, 0x07,
+	0x36, 0x11, 0xFB, 0x6D, 0x8E, 0xF0, 0x62, 0x5A, 0x3C, 0x8B,
+	0x23, 0xF1, 0x46, 0xE2, 0x76, 0x2A, 0x6F, 0xBB, 0x09, 0x24,
+	0x18, 0x64, 0xE6, 0x5C, 0xD0, 0x85, 0x69, 0xF0, 0x4F, 0x66,
+	0x97, 0x40, 0x01, 0x27, 0xD1, 0x41, 0xCC, 0xEB, 0x4D, 0xB7,
+	0x04, 0xC4, 0x91, 0xE0, 0x95, 0x8A, 0x43, 0x26, 0x2D, 0x1F,
+	0x88, 0xA0, 0xD8
+);
+
+START_TEST(test_bliss_signature_fail)
+{
+	bliss_param_set_t set2 = { .id = BLISS_B_II };
+	bliss_param_set_t *set;
+	bliss_signature_t *signature;
+	chunk_t encoding;
+	int k;
+
+	signature = bliss_signature_create(&set2);
+	ck_assert(signature);
+	encoding = signature->get_encoding(signature);
+	ck_assert(encoding.len == 0);
+	signature->destroy(signature);
+
+	signature  = bliss_signature_create_from_data(&set2, data);
+	ck_assert(!signature);
+
+	set = bliss_param_set_get_by_id(BLISS_B_I);
+	ck_assert(set);
+
+	for (k = 0; k < data.len - 2; k++)
+	{
+		chunk_t fragment = { data.ptr, k };
+
+		signature  = bliss_signature_create_from_data(set, fragment);
+		ck_assert(!signature);
+	}
+	signature  = bliss_signature_create_from_data(set, data);
+	ck_assert(signature);
+	signature->destroy(signature);
+}
+END_TEST
+
+Suite *bliss_signature_suite_create()
+{
+	Suite *s;
+	TCase *tc;
+
+	s = suite_create("bliss_signature");
+
+	tc = tcase_create("signature_fail");
+	tcase_add_test(tc, test_bliss_signature_fail);
+	suite_add_tcase(s, tc);
+
+	return s;
+}
diff --git a/src/libstrongswan/plugins/blowfish/Makefile.in b/src/libstrongswan/plugins/blowfish/Makefile.in
index 33e5958..f196165 100644
--- a/src/libstrongswan/plugins/blowfish/Makefile.in
+++ b/src/libstrongswan/plugins/blowfish/Makefile.in
@@ -229,6 +229,7 @@ DLLIB = @DLLIB@
 DLLTOOL = @DLLTOOL@
 DSYMUTIL = @DSYMUTIL@
 DUMPBIN = @DUMPBIN@
+EASY_INSTALL = @EASY_INSTALL@
 ECHO_C = @ECHO_C@
 ECHO_N = @ECHO_N@
 ECHO_T = @ECHO_T@
@@ -289,10 +290,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
 PLUGIN_CFLAGS = @PLUGIN_CFLAGS@
 PTHREADLIB = @PTHREADLIB@
 PYTHON = @PYTHON@
+PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@
 PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
 PYTHON_PLATFORM = @PYTHON_PLATFORM@
 PYTHON_PREFIX = @PYTHON_PREFIX@
 PYTHON_VERSION = @PYTHON_VERSION@
+PY_TEST = @PY_TEST@
 RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
@@ -366,6 +369,8 @@ json_CFLAGS = @json_CFLAGS@
 json_LIBS = @json_LIBS@
 libdir = @libdir@
 libexecdir = @libexecdir@
+libiptc_CFLAGS = @libiptc_CFLAGS@
+libiptc_LIBS = @libiptc_LIBS@
 linux_headers = @linux_headers@
 localedir = @localedir@
 localstatedir = @localstatedir@
diff --git a/src/libstrongswan/plugins/ccm/Makefile.in b/src/libstrongswan/plugins/ccm/Makefile.in
index 43bdf1f..ca7cadb 100644
--- a/src/libstrongswan/plugins/ccm/Makefile.in
+++ b/src/libstrongswan/plugins/ccm/Makefile.in
@@ -226,6 +226,7 @@ DLLIB = @DLLIB@
 DLLTOOL = @DLLTOOL@
 DSYMUTIL = @DSYMUTIL@
 DUMPBIN = @DUMPBIN@
+EASY_INSTALL = @EASY_INSTALL@
 ECHO_C = @ECHO_C@
 ECHO_N = @ECHO_N@
 ECHO_T = @ECHO_T@
@@ -286,10 +287,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
 PLUGIN_CFLAGS = @PLUGIN_CFLAGS@
 PTHREADLIB = @PTHREADLIB@
 PYTHON = @PYTHON@
+PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@
 PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
 PYTHON_PLATFORM = @PYTHON_PLATFORM@
 PYTHON_PREFIX = @PYTHON_PREFIX@
 PYTHON_VERSION = @PYTHON_VERSION@
+PY_TEST = @PY_TEST@
 RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
@@ -363,6 +366,8 @@ json_CFLAGS = @json_CFLAGS@
 json_LIBS = @json_LIBS@
 libdir = @libdir@
 libexecdir = @libexecdir@
+libiptc_CFLAGS = @libiptc_CFLAGS@
+libiptc_LIBS = @libiptc_LIBS@
 linux_headers = @linux_headers@
 localedir = @localedir@
 localstatedir = @localstatedir@
diff --git a/src/libstrongswan/plugins/cmac/Makefile.in b/src/libstrongswan/plugins/cmac/Makefile.in
index 7c56740..9e24939 100644
--- a/src/libstrongswan/plugins/cmac/Makefile.in
+++ b/src/libstrongswan/plugins/cmac/Makefile.in
@@ -226,6 +226,7 @@ DLLIB = @DLLIB@
 DLLTOOL = @DLLTOOL@
 DSYMUTIL = @DSYMUTIL@
 DUMPBIN = @DUMPBIN@
+EASY_INSTALL = @EASY_INSTALL@
 ECHO_C = @ECHO_C@
 ECHO_N = @ECHO_N@
 ECHO_T = @ECHO_T@
@@ -286,10 +287,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
 PLUGIN_CFLAGS = @PLUGIN_CFLAGS@
 PTHREADLIB = @PTHREADLIB@
 PYTHON = @PYTHON@
+PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@
 PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
 PYTHON_PLATFORM = @PYTHON_PLATFORM@
 PYTHON_PREFIX = @PYTHON_PREFIX@
 PYTHON_VERSION = @PYTHON_VERSION@
+PY_TEST = @PY_TEST@
 RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
@@ -363,6 +366,8 @@ json_CFLAGS = @json_CFLAGS@
 json_LIBS = @json_LIBS@
 libdir = @libdir@
 libexecdir = @libexecdir@
+libiptc_CFLAGS = @libiptc_CFLAGS@
+libiptc_LIBS = @libiptc_LIBS@
 linux_headers = @linux_headers@
 localedir = @localedir@
 localstatedir = @localstatedir@
diff --git a/src/libstrongswan/plugins/cmac/cmac.c b/src/libstrongswan/plugins/cmac/cmac.c
index c8cb7fb..4f222ff 100644
--- a/src/libstrongswan/plugins/cmac/cmac.c
+++ b/src/libstrongswan/plugins/cmac/cmac.c
@@ -247,6 +247,9 @@ METHOD(mac_t, set_key, bool,
 {
 	chunk_t resized, iv, l;
 
+	memset(this->t, 0, this->b);
+	this->remaining_bytes = 0;
+
 	/* we support variable keys as defined in RFC 4615 */
 	if (key.len == this->b)
 	{
diff --git a/src/libstrongswan/plugins/constraints/Makefile.in b/src/libstrongswan/plugins/constraints/Makefile.in
index 3946936..2e623ad 100644
--- a/src/libstrongswan/plugins/constraints/Makefile.in
+++ b/src/libstrongswan/plugins/constraints/Makefile.in
@@ -229,6 +229,7 @@ DLLIB = @DLLIB@
 DLLTOOL = @DLLTOOL@
 DSYMUTIL = @DSYMUTIL@
 DUMPBIN = @DUMPBIN@
+EASY_INSTALL = @EASY_INSTALL@
 ECHO_C = @ECHO_C@
 ECHO_N = @ECHO_N@
 ECHO_T = @ECHO_T@
@@ -289,10 +290,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
 PLUGIN_CFLAGS = @PLUGIN_CFLAGS@
 PTHREADLIB = @PTHREADLIB@
 PYTHON = @PYTHON@
+PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@
 PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
 PYTHON_PLATFORM = @PYTHON_PLATFORM@
 PYTHON_PREFIX = @PYTHON_PREFIX@
 PYTHON_VERSION = @PYTHON_VERSION@
+PY_TEST = @PY_TEST@
 RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
@@ -366,6 +369,8 @@ json_CFLAGS = @json_CFLAGS@
 json_LIBS = @json_LIBS@
 libdir = @libdir@
 libexecdir = @libexecdir@
+libiptc_CFLAGS = @libiptc_CFLAGS@
+libiptc_LIBS = @libiptc_LIBS@
 linux_headers = @linux_headers@
 localedir = @localedir@
 localstatedir = @localstatedir@
diff --git a/src/libstrongswan/plugins/constraints/constraints_validator.c b/src/libstrongswan/plugins/constraints/constraints_validator.c
index 62ccc71..a0f4a74 100644
--- a/src/libstrongswan/plugins/constraints/constraints_validator.c
+++ b/src/libstrongswan/plugins/constraints/constraints_validator.c
@@ -52,16 +52,67 @@ static bool check_pathlen(x509_t *issuer, int pathlen)
 }
 
 /**
- * Check if a FQDN/RFC822 constraint matches (suffix match)
+ * Check if a FQDN constraint matches
  */
-static bool suffix_matches(identification_t *constraint, identification_t *id)
+static bool fqdn_matches(identification_t *constraint, identification_t *id)
 {
-	chunk_t c, i;
+	chunk_t c, i, diff;
 
 	c = constraint->get_encoding(constraint);
 	i = id->get_encoding(id);
 
-	return i.len >= c.len && chunk_equals(c, chunk_skip(i, i.len - c.len));
+	if (!c.len || i.len < c.len)
+	{
+		return FALSE;
+	}
+	diff = chunk_create(i.ptr, i.len - c.len);
+	if (!chunk_equals(c, chunk_skip(i, diff.len)))
+	{
+		return FALSE;
+	}
+	if (!diff.len)
+	{
+		return TRUE;
+	}
+	if (c.ptr[0] == '.' || diff.ptr[diff.len - 1] == '.')
+	{
+		return TRUE;
+	}
+	return FALSE;
+}
+
+/**
+ * Check if a RFC822 constraint matches
+ */
+static bool email_matches(identification_t *constraint, identification_t *id)
+{
+	chunk_t c, i, diff;
+
+	c = constraint->get_encoding(constraint);
+	i = id->get_encoding(id);
+
+	if (!c.len || i.len < c.len)
+	{
+		return FALSE;
+	}
+	if (memchr(c.ptr, '@', c.len))
+	{	/* constraint is a full email address */
+		return chunk_equals(c, i);
+	}
+	diff = chunk_create(i.ptr, i.len - c.len);
+	if (!diff.len || !chunk_equals(c, chunk_skip(i, diff.len)))
+	{
+		return FALSE;
+	}
+	if (c.ptr[0] == '.')
+	{	/* constraint is domain, suffix match */
+		return TRUE;
+	}
+	if (diff.ptr[diff.len - 1] == '@')
+	{	/* constraint is host specific, only username can be appended */
+		return TRUE;
+	}
+	return FALSE;
 }
 
 /**
@@ -121,8 +172,10 @@ static bool name_constraint_matches(identification_t *constraint,
 			switch (type)
 			{
 				case ID_FQDN:
+					matches = fqdn_matches(constraint, id);
+					break;
 				case ID_RFC822_ADDR:
-					matches = suffix_matches(constraint, id);
+					matches = email_matches(constraint, id);
 					break;
 				case ID_DER_ASN1_DN:
 					matches = dn_matches(constraint, id);
@@ -151,7 +204,7 @@ static bool name_constraint_inherited(identification_t *constraint,
 									  x509_t *x509, bool permitted)
 {
 	enumerator_t *enumerator;
-	identification_t *id;
+	identification_t *id, *a, *b;
 	bool inherited = FALSE;
 	id_type_t type;
 
@@ -166,28 +219,26 @@ static bool name_constraint_inherited(identification_t *constraint,
 	{
 		if (id->get_type(id) == type)
 		{
+			if (permitted)
+			{	/* permitted constraint can be narrowed */
+				a = constraint;
+				b = id;
+			}
+			else
+			{	/* excluded constraint can be widened */
+				a = id;
+				b = constraint;
+			}
 			switch (type)
 			{
 				case ID_FQDN:
+					inherited = fqdn_matches(a, b);
+					break;
 				case ID_RFC822_ADDR:
-					if (permitted)
-					{	/* permitted constraint can be narrowed */
-						inherited = suffix_matches(constraint, id);
-					}
-					else
-					{	/* excluded constraint can be widened */
-						inherited = suffix_matches(id, constraint);
-					}
+					inherited = email_matches(a, b);
 					break;
 				case ID_DER_ASN1_DN:
-					if (permitted)
-					{
-						inherited = dn_matches(constraint, id);
-					}
-					else
-					{
-						inherited = dn_matches(id, constraint);
-					}
+					inherited = dn_matches(a, b);
 					break;
 				default:
 					DBG1(DBG_CFG, "%N NameConstraint matching not implemented",
@@ -298,8 +349,7 @@ static bool has_policy(x509_t *issuer, chunk_t oid)
 /**
  * Check certificatePolicies.
  */
-static bool check_policy(x509_t *subject, x509_t *issuer, bool check,
-						 auth_cfg_t *auth)
+static bool check_policy(x509_t *subject, x509_t *issuer)
 {
 	certificate_t *cert = (certificate_t*)subject;
 	x509_policy_mapping_t *mapping;
@@ -323,33 +373,85 @@ static bool check_policy(x509_t *subject, x509_t *issuer, bool check,
 	}
 	enumerator->destroy(enumerator);
 
-	if (check)
+	enumerator = subject->create_cert_policy_enumerator(subject);
+	while (enumerator->enumerate(enumerator, &policy))
+	{
+		if (!has_policy(issuer, policy->oid))
+		{
+			oid = asn1_oid_to_string(policy->oid);
+			DBG1(DBG_CFG, "policy %s missing in issuing certificate '%Y'",
+				 oid, cert->get_issuer(cert));
+			free(oid);
+			enumerator->destroy(enumerator);
+			return FALSE;
+		}
+	}
+	enumerator->destroy(enumerator);
+
+	return TRUE;
+}
+
+/**
+ * Check if a given policy is valid under a trustchain
+ */
+static bool is_policy_valid(linked_list_t *chain, chunk_t oid)
+{
+	x509_policy_mapping_t *mapping;
+	x509_cert_policy_t *policy;
+	x509_t *issuer;
+	enumerator_t *issuers, *policies, *mappings;
+	bool found = TRUE;
+
+	issuers = chain->create_enumerator(chain);
+	while (issuers->enumerate(issuers, &issuer))
 	{
-		enumerator = subject->create_cert_policy_enumerator(subject);
-		while (enumerator->enumerate(enumerator, &policy))
+		int maxmap = 8;
+
+		while (found)
 		{
-			if (!has_policy(issuer, policy->oid))
+			found = FALSE;
+
+			policies = issuer->create_cert_policy_enumerator(issuer);
+			while (policies->enumerate(policies, &policy))
 			{
-				oid = asn1_oid_to_string(policy->oid);
-				DBG1(DBG_CFG, "policy %s missing in issuing certificate '%Y'",
-					 oid, cert->get_issuer(cert));
-				free(oid);
-				enumerator->destroy(enumerator);
-				return FALSE;
+				if (chunk_equals(oid, policy->oid) ||
+					chunk_equals(any_policy, policy->oid))
+				{
+					found = TRUE;
+					break;
+				}
 			}
-			if (auth)
+			policies->destroy(policies);
+			if (found)
 			{
-				oid = asn1_oid_to_string(policy->oid);
-				if (oid)
+				break;
+			}
+			/* fall back to a mapped policy */
+			mappings = issuer->create_policy_mapping_enumerator(issuer);
+			while (mappings->enumerate(mappings, &mapping))
+			{
+				if (chunk_equals(mapping->subject, oid))
 				{
-					auth->add(auth, AUTH_RULE_CERT_POLICY, oid);
+					oid = mapping->issuer;
+					found = TRUE;
+					break;
 				}
 			}
+			mappings->destroy(mappings);
+			if (--maxmap == 0)
+			{
+				found = FALSE;
+				break;
+			}
+		}
+		if (!found)
+		{
+			break;
 		}
-		enumerator->destroy(enumerator);
 	}
+	issuers->destroy(issuers);
 
-	return TRUE;
+	return found;
 }
 
 /**
@@ -364,7 +466,7 @@ static bool has_policy_chain(linked_list_t *chain, x509_t *subject, int len)
 	enumerator = chain->create_enumerator(chain);
 	while (len-- > 0 && enumerator->enumerate(enumerator, &issuer))
 	{
-		if (!check_policy(subject, issuer, TRUE, NULL))
+		if (!check_policy(subject, issuer))
 		{
 			valid = FALSE;
 			break;
@@ -450,6 +552,7 @@ static bool check_policy_constraints(x509_t *issuer, u_int pathlen,
 	{
 		if (subject->get_type(subject) == CERT_X509)
 		{
+			x509_cert_policy_t *policy;
 			enumerator_t *enumerator;
 			linked_list_t *chain;
 			certificate_t *cert;
@@ -457,6 +560,7 @@ static bool check_policy_constraints(x509_t *issuer, u_int pathlen,
 			x509_t *x509;
 			int len = 0;
 			u_int expl, inh;
+			char *oid;
 
 			/* prepare trustchain to validate */
 			chain = linked_list_create();
@@ -517,6 +621,31 @@ static bool check_policy_constraints(x509_t *issuer, u_int pathlen,
 			}
 			enumerator->destroy(enumerator);
 
+			if (valid)
+			{
+				x509 = (x509_t*)subject;
+
+				enumerator = x509->create_cert_policy_enumerator(x509);
+				while (enumerator->enumerate(enumerator, &policy))
+				{
+					oid = asn1_oid_to_string(policy->oid);
+					if (oid)
+					{
+						if (is_policy_valid(chain, policy->oid))
+						{
+							auth->add(auth, AUTH_RULE_CERT_POLICY, oid);
+						}
+						else
+						{
+							DBG1(DBG_CFG, "certificate policy %s for '%Y' "
+								 "not allowed by trustchain, ignored",
+								 oid, subject->get_subject(subject));
+							free(oid);
+						}
+					}
+				}
+				enumerator->destroy(enumerator);
+			}
 			chain->destroy(chain);
 		}
 	}
@@ -543,12 +672,6 @@ METHOD(cert_validator_t, validate, bool,
 									subject);
 			return FALSE;
 		}
-		if (!check_policy((x509_t*)subject, (x509_t*)issuer, !pathlen, auth))
-		{
-			lib->credmgr->call_hook(lib->credmgr, CRED_HOOK_POLICY_VIOLATION,
-									subject);
-			return FALSE;
-		}
 		if (anchor)
 		{
 			if (!check_policy_constraints((x509_t*)issuer, pathlen, auth))
diff --git a/src/libstrongswan/plugins/ctr/Makefile.in b/src/libstrongswan/plugins/ctr/Makefile.in
index 4b397e8..7b7231b 100644
--- a/src/libstrongswan/plugins/ctr/Makefile.in
+++ b/src/libstrongswan/plugins/ctr/Makefile.in
@@ -226,6 +226,7 @@ DLLIB = @DLLIB@
 DLLTOOL = @DLLTOOL@
 DSYMUTIL = @DSYMUTIL@
 DUMPBIN = @DUMPBIN@
+EASY_INSTALL = @EASY_INSTALL@
 ECHO_C = @ECHO_C@
 ECHO_N = @ECHO_N@
 ECHO_T = @ECHO_T@
@@ -286,10 +287,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
 PLUGIN_CFLAGS = @PLUGIN_CFLAGS@
 PTHREADLIB = @PTHREADLIB@
 PYTHON = @PYTHON@
+PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@
 PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
 PYTHON_PLATFORM = @PYTHON_PLATFORM@
 PYTHON_PREFIX = @PYTHON_PREFIX@
 PYTHON_VERSION = @PYTHON_VERSION@
+PY_TEST = @PY_TEST@
 RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
@@ -363,6 +366,8 @@ json_CFLAGS = @json_CFLAGS@
 json_LIBS = @json_LIBS@
 libdir = @libdir@
 libexecdir = @libexecdir@
+libiptc_CFLAGS = @libiptc_CFLAGS@
+libiptc_LIBS = @libiptc_LIBS@
 linux_headers = @linux_headers@
 localedir = @localedir@
 localstatedir = @localstatedir@
diff --git a/src/libstrongswan/plugins/curl/Makefile.in b/src/libstrongswan/plugins/curl/Makefile.in
index 2e221c8..d525eac 100644
--- a/src/libstrongswan/plugins/curl/Makefile.in
+++ b/src/libstrongswan/plugins/curl/Makefile.in
@@ -226,6 +226,7 @@ DLLIB = @DLLIB@
 DLLTOOL = @DLLTOOL@
 DSYMUTIL = @DSYMUTIL@
 DUMPBIN = @DUMPBIN@
+EASY_INSTALL = @EASY_INSTALL@
 ECHO_C = @ECHO_C@
 ECHO_N = @ECHO_N@
 ECHO_T = @ECHO_T@
@@ -286,10 +287,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
 PLUGIN_CFLAGS = @PLUGIN_CFLAGS@
 PTHREADLIB = @PTHREADLIB@
 PYTHON = @PYTHON@
+PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@
 PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
 PYTHON_PLATFORM = @PYTHON_PLATFORM@
 PYTHON_PREFIX = @PYTHON_PREFIX@
 PYTHON_VERSION = @PYTHON_VERSION@
+PY_TEST = @PY_TEST@
 RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
@@ -363,6 +366,8 @@ json_CFLAGS = @json_CFLAGS@
 json_LIBS = @json_LIBS@
 libdir = @libdir@
 libexecdir = @libexecdir@
+libiptc_CFLAGS = @libiptc_CFLAGS@
+libiptc_LIBS = @libiptc_LIBS@
 linux_headers = @linux_headers@
 localedir = @localedir@
 localstatedir = @localstatedir@
diff --git a/src/libstrongswan/plugins/des/Makefile.in b/src/libstrongswan/plugins/des/Makefile.in
index 0025a2b..96b2f60 100644
--- a/src/libstrongswan/plugins/des/Makefile.in
+++ b/src/libstrongswan/plugins/des/Makefile.in
@@ -226,6 +226,7 @@ DLLIB = @DLLIB@
 DLLTOOL = @DLLTOOL@
 DSYMUTIL = @DSYMUTIL@
 DUMPBIN = @DUMPBIN@
+EASY_INSTALL = @EASY_INSTALL@
 ECHO_C = @ECHO_C@
 ECHO_N = @ECHO_N@
 ECHO_T = @ECHO_T@
@@ -286,10 +287,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
 PLUGIN_CFLAGS = @PLUGIN_CFLAGS@
 PTHREADLIB = @PTHREADLIB@
 PYTHON = @PYTHON@
+PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@
 PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
 PYTHON_PLATFORM = @PYTHON_PLATFORM@
 PYTHON_PREFIX = @PYTHON_PREFIX@
 PYTHON_VERSION = @PYTHON_VERSION@
+PY_TEST = @PY_TEST@
 RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
@@ -363,6 +366,8 @@ json_CFLAGS = @json_CFLAGS@
 json_LIBS = @json_LIBS@
 libdir = @libdir@
 libexecdir = @libexecdir@
+libiptc_CFLAGS = @libiptc_CFLAGS@
+libiptc_LIBS = @libiptc_LIBS@
 linux_headers = @linux_headers@
 localedir = @localedir@
 localstatedir = @localstatedir@
diff --git a/src/libstrongswan/plugins/dnskey/Makefile.in b/src/libstrongswan/plugins/dnskey/Makefile.in
index 0b30923..9102899 100644
--- a/src/libstrongswan/plugins/dnskey/Makefile.in
+++ b/src/libstrongswan/plugins/dnskey/Makefile.in
@@ -229,6 +229,7 @@ DLLIB = @DLLIB@
 DLLTOOL = @DLLTOOL@
 DSYMUTIL = @DSYMUTIL@
 DUMPBIN = @DUMPBIN@
+EASY_INSTALL = @EASY_INSTALL@
 ECHO_C = @ECHO_C@
 ECHO_N = @ECHO_N@
 ECHO_T = @ECHO_T@
@@ -289,10 +290,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
 PLUGIN_CFLAGS = @PLUGIN_CFLAGS@
 PTHREADLIB = @PTHREADLIB@
 PYTHON = @PYTHON@
+PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@
 PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
 PYTHON_PLATFORM = @PYTHON_PLATFORM@
 PYTHON_PREFIX = @PYTHON_PREFIX@
 PYTHON_VERSION = @PYTHON_VERSION@
+PY_TEST = @PY_TEST@
 RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
@@ -366,6 +369,8 @@ json_CFLAGS = @json_CFLAGS@
 json_LIBS = @json_LIBS@
 libdir = @libdir@
 libexecdir = @libexecdir@
+libiptc_CFLAGS = @libiptc_CFLAGS@
+libiptc_LIBS = @libiptc_LIBS@
 linux_headers = @linux_headers@
 localedir = @localedir@
 localstatedir = @localstatedir@
diff --git a/src/libstrongswan/plugins/files/Makefile.am b/src/libstrongswan/plugins/files/Makefile.am
new file mode 100644
index 0000000..6776749
--- /dev/null
+++ b/src/libstrongswan/plugins/files/Makefile.am
@@ -0,0 +1,16 @@
+AM_CPPFLAGS = \
+	-I$(top_srcdir)/src/libstrongswan
+
+AM_CFLAGS = \
+	$(PLUGIN_CFLAGS)
+
+if MONOLITHIC
+noinst_LTLIBRARIES = libstrongswan-files.la
+else
+plugin_LTLIBRARIES = libstrongswan-files.la
+endif
+
+libstrongswan_files_la_SOURCES = \
+	files_plugin.h files_plugin.c files_fetcher.c files_fetcher.h
+
+libstrongswan_files_la_LDFLAGS = -module -avoid-version
diff --git a/src/libstrongswan/plugins/files/Makefile.in b/src/libstrongswan/plugins/files/Makefile.in
new file mode 100644
index 0000000..31dc4a3
--- /dev/null
+++ b/src/libstrongswan/plugins/files/Makefile.in
@@ -0,0 +1,775 @@
+# Makefile.in generated by automake 1.14.1 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994-2013 Free Software Foundation, Inc.
+
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+ at SET_MAKE@
+
+VPATH = @srcdir@
+am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)'
+am__make_running_with_option = \
+  case $${target_option-} in \
+      ?) ;; \
+      *) echo "am__make_running_with_option: internal error: invalid" \
+              "target option '$${target_option-}' specified" >&2; \
+         exit 1;; \
+  esac; \
+  has_opt=no; \
+  sane_makeflags=$$MAKEFLAGS; \
+  if $(am__is_gnu_make); then \
+    sane_makeflags=$$MFLAGS; \
+  else \
+    case $$MAKEFLAGS in \
+      *\\[\ \	]*) \
+        bs=\\; \
+        sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
+          | sed "s/$$bs$$bs[$$bs $$bs	]*//g"`;; \
+    esac; \
+  fi; \
+  skip_next=no; \
+  strip_trailopt () \
+  { \
+    flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
+  }; \
+  for flg in $$sane_makeflags; do \
+    test $$skip_next = yes && { skip_next=no; continue; }; \
+    case $$flg in \
+      *=*|--*) continue;; \
+        -*I) strip_trailopt 'I'; skip_next=yes;; \
+      -*I?*) strip_trailopt 'I';; \
+        -*O) strip_trailopt 'O'; skip_next=yes;; \
+      -*O?*) strip_trailopt 'O';; \
+        -*l) strip_trailopt 'l'; skip_next=yes;; \
+      -*l?*) strip_trailopt 'l';; \
+      -[dEDm]) skip_next=yes;; \
+      -[JT]) skip_next=yes;; \
+    esac; \
+    case $$flg in \
+      *$$target_option*) has_opt=yes; break;; \
+    esac; \
+  done; \
+  test $$has_opt = yes
+am__make_dryrun = (target_option=n; $(am__make_running_with_option))
+am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+subdir = src/libstrongswan/plugins/files
+DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
+	$(top_srcdir)/depcomp
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/m4/config/libtool.m4 \
+	$(top_srcdir)/m4/config/ltoptions.m4 \
+	$(top_srcdir)/m4/config/ltsugar.m4 \
+	$(top_srcdir)/m4/config/ltversion.m4 \
+	$(top_srcdir)/m4/config/lt~obsolete.m4 \
+	$(top_srcdir)/m4/macros/split-package-version.m4 \
+	$(top_srcdir)/m4/macros/with.m4 \
+	$(top_srcdir)/m4/macros/enable-disable.m4 \
+	$(top_srcdir)/m4/macros/add-plugin.m4 \
+	$(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+	$(ACLOCAL_M4)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
+am__vpath_adj = case $$p in \
+    $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
+    *) f=$$p;; \
+  esac;
+am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
+am__install_max = 40
+am__nobase_strip_setup = \
+  srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
+am__nobase_strip = \
+  for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
+am__nobase_list = $(am__nobase_strip_setup); \
+  for p in $$list; do echo "$$p $$p"; done | \
+  sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
+  $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
+    if (++n[$$2] == $(am__install_max)) \
+      { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
+    END { for (dir in files) print dir, files[dir] }'
+am__base_list = \
+  sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
+  sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
+am__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; }; \
+  }
+am__installdirs = "$(DESTDIR)$(plugindir)"
+LTLIBRARIES = $(noinst_LTLIBRARIES) $(plugin_LTLIBRARIES)
+libstrongswan_files_la_LIBADD =
+am_libstrongswan_files_la_OBJECTS = files_plugin.lo files_fetcher.lo
+libstrongswan_files_la_OBJECTS = $(am_libstrongswan_files_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_files_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \
+	$(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \
+	$(AM_CFLAGS) $(CFLAGS) $(libstrongswan_files_la_LDFLAGS) \
+	$(LDFLAGS) -o $@
+ at MONOLITHIC_FALSE@am_libstrongswan_files_la_rpath = -rpath \
+ at MONOLITHIC_FALSE@	$(plugindir)
+ at MONOLITHIC_TRUE@am_libstrongswan_files_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
+am__v_P_1 = :
+AM_V_GEN = $(am__v_GEN_ at AM_V@)
+am__v_GEN_ = $(am__v_GEN_ at AM_DEFAULT_V@)
+am__v_GEN_0 = @echo "  GEN     " $@;
+am__v_GEN_1 = 
+AM_V_at = $(am__v_at_ at AM_V@)
+am__v_at_ = $(am__v_at_ at AM_DEFAULT_V@)
+am__v_at_0 = @
+am__v_at_1 = 
+DEFAULT_INCLUDES = -I. at am__isrc@ -I$(top_builddir)
+depcomp = $(SHELL) $(top_srcdir)/depcomp
+am__depfiles_maybe = depfiles
+am__mv = mv -f
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+	$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+	$(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \
+	$(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
+	$(AM_CFLAGS) $(CFLAGS)
+AM_V_CC = $(am__v_CC_ at AM_V@)
+am__v_CC_ = $(am__v_CC_ at AM_DEFAULT_V@)
+am__v_CC_0 = @echo "  CC      " $@;
+am__v_CC_1 = 
+CCLD = $(CC)
+LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+	$(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+	$(AM_LDFLAGS) $(LDFLAGS) -o $@
+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_files_la_SOURCES)
+DIST_SOURCES = $(libstrongswan_files_la_SOURCES)
+am__can_run_installinfo = \
+  case $$AM_UPDATE_INFO_DIR in \
+    n|no|NO) false;; \
+    *) (install-info --version) >/dev/null 2>&1;; \
+  esac
+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
+# *not* preserved.
+am__uniquify_input = $(AWK) '\
+  BEGIN { nonempty = 0; } \
+  { items[$$0] = 1; nonempty = 1; } \
+  END { if (nonempty) { for (i in items) print i; }; } \
+'
+# Make sure the list of sources is unique.  This is necessary because,
+# e.g., the same source file might be shared among _SOURCES variables
+# for different programs/libraries.
+am__define_uniq_tagged_files = \
+  list='$(am__tagged_files)'; \
+  unique=`for i in $$list; do \
+    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+  done | $(am__uniquify_input)`
+ETAGS = etags
+CTAGS = ctags
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+ALLOCA = @ALLOCA@
+AMTAR = @AMTAR@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+BFDLIB = @BFDLIB@
+BTLIB = @BTLIB@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+COVERAGE_CFLAGS = @COVERAGE_CFLAGS@
+COVERAGE_LDFLAGS = @COVERAGE_LDFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DLLIB = @DLLIB@
+DLLTOOL = @DLLTOOL@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+EASY_INSTALL = @EASY_INSTALL@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+FGREP = @FGREP@
+GEM = @GEM@
+GENHTML = @GENHTML@
+GPERF = @GPERF@
+GPRBUILD = @GPRBUILD@
+GREP = @GREP@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+LCOV = @LCOV@
+LD = @LD@
+LDFLAGS = @LDFLAGS@
+LEX = @LEX@
+LEXLIB = @LEXLIB@
+LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LIPO = @LIPO@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+MAKEINFO = @MAKEINFO@
+MANIFEST_TOOL = @MANIFEST_TOOL@
+MKDIR_P = @MKDIR_P@
+MYSQLCFLAG = @MYSQLCFLAG@
+MYSQLCONFIG = @MYSQLCONFIG@
+MYSQLLIB = @MYSQLLIB@
+NM = @NM@
+NMEDIT = @NMEDIT@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OPENSSL_LIB = @OPENSSL_LIB@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PACKAGE_VERSION_BUILD = @PACKAGE_VERSION_BUILD@
+PACKAGE_VERSION_MAJOR = @PACKAGE_VERSION_MAJOR@
+PACKAGE_VERSION_MINOR = @PACKAGE_VERSION_MINOR@
+PACKAGE_VERSION_REVIEW = @PACKAGE_VERSION_REVIEW@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PERL = @PERL@
+PKG_CONFIG = @PKG_CONFIG@
+PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
+PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
+PLUGIN_CFLAGS = @PLUGIN_CFLAGS@
+PTHREADLIB = @PTHREADLIB@
+PYTHON = @PYTHON@
+PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@
+PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
+PYTHON_PLATFORM = @PYTHON_PLATFORM@
+PYTHON_PREFIX = @PYTHON_PREFIX@
+PYTHON_VERSION = @PYTHON_VERSION@
+PY_TEST = @PY_TEST@
+RANLIB = @RANLIB@
+RTLIB = @RTLIB@
+RUBY = @RUBY@
+RUBYGEMDIR = @RUBYGEMDIR@
+RUBYINCLUDE = @RUBYINCLUDE@
+RUBYLIB = @RUBYLIB@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+SOCKLIB = @SOCKLIB@
+STRIP = @STRIP@
+UNWINDLIB = @UNWINDLIB@
+VERSION = @VERSION@
+YACC = @YACC@
+YFLAGS = @YFLAGS@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+aikgen_plugins = @aikgen_plugins@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+attest_plugins = @attest_plugins@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+c_plugins = @c_plugins@
+charon_natt_port = @charon_natt_port@
+charon_plugins = @charon_plugins@
+charon_udp_port = @charon_udp_port@
+clearsilver_LIBS = @clearsilver_LIBS@
+cmd_plugins = @cmd_plugins@
+datadir = @datadir@
+datarootdir = @datarootdir@
+dbusservicedir = @dbusservicedir@
+dev_headers = @dev_headers@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+fips_mode = @fips_mode@
+gtk_CFLAGS = @gtk_CFLAGS@
+gtk_LIBS = @gtk_LIBS@
+h_plugins = @h_plugins@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+imcvdir = @imcvdir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+ipsec_script = @ipsec_script@
+ipsec_script_upper = @ipsec_script_upper@
+ipsecdir = @ipsecdir@
+ipsecgroup = @ipsecgroup@
+ipseclibdir = @ipseclibdir@
+ipsecuser = @ipsecuser@
+json_CFLAGS = @json_CFLAGS@
+json_LIBS = @json_LIBS@
+libdir = @libdir@
+libexecdir = @libexecdir@
+libiptc_CFLAGS = @libiptc_CFLAGS@
+libiptc_LIBS = @libiptc_LIBS@
+linux_headers = @linux_headers@
+localedir = @localedir@
+localstatedir = @localstatedir@
+maemo_CFLAGS = @maemo_CFLAGS@
+maemo_LIBS = @maemo_LIBS@
+manager_plugins = @manager_plugins@
+mandir = @mandir@
+medsrv_plugins = @medsrv_plugins@
+mkdir_p = @mkdir_p@
+nm_CFLAGS = @nm_CFLAGS@
+nm_LIBS = @nm_LIBS@
+nm_ca_dir = @nm_ca_dir@
+nm_plugins = @nm_plugins@
+oldincludedir = @oldincludedir@
+pcsclite_CFLAGS = @pcsclite_CFLAGS@
+pcsclite_LIBS = @pcsclite_LIBS@
+pdfdir = @pdfdir@
+piddir = @piddir@
+pkgpyexecdir = @pkgpyexecdir@
+pkgpythondir = @pkgpythondir@
+pki_plugins = @pki_plugins@
+plugindir = @plugindir@
+pool_plugins = @pool_plugins@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+pyexecdir = @pyexecdir@
+pythondir = @pythondir@
+random_device = @random_device@
+resolv_conf = @resolv_conf@
+routing_table = @routing_table@
+routing_table_prio = @routing_table_prio@
+s_plugins = @s_plugins@
+sbindir = @sbindir@
+scepclient_plugins = @scepclient_plugins@
+scripts_plugins = @scripts_plugins@
+sharedstatedir = @sharedstatedir@
+soup_CFLAGS = @soup_CFLAGS@
+soup_LIBS = @soup_LIBS@
+srcdir = @srcdir@
+starter_plugins = @starter_plugins@
+strongswan_conf = @strongswan_conf@
+strongswan_options = @strongswan_options@
+swanctldir = @swanctldir@
+sysconfdir = @sysconfdir@
+systemd_daemon_CFLAGS = @systemd_daemon_CFLAGS@
+systemd_daemon_LIBS = @systemd_daemon_LIBS@
+systemd_journal_CFLAGS = @systemd_journal_CFLAGS@
+systemd_journal_LIBS = @systemd_journal_LIBS@
+systemdsystemunitdir = @systemdsystemunitdir@
+t_plugins = @t_plugins@
+target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+urandom_device = @urandom_device@
+xml_CFLAGS = @xml_CFLAGS@
+xml_LIBS = @xml_LIBS@
+AM_CPPFLAGS = \
+	-I$(top_srcdir)/src/libstrongswan
+
+AM_CFLAGS = \
+	$(PLUGIN_CFLAGS)
+
+ at MONOLITHIC_TRUE@noinst_LTLIBRARIES = libstrongswan-files.la
+ at MONOLITHIC_FALSE@plugin_LTLIBRARIES = libstrongswan-files.la
+libstrongswan_files_la_SOURCES = \
+	files_plugin.h files_plugin.c files_fetcher.c files_fetcher.h
+
+libstrongswan_files_la_LDFLAGS = -module -avoid-version
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .c .lo .o .obj
+$(srcdir)/Makefile.in:  $(srcdir)/Makefile.am  $(am__configure_deps)
+	@for dep in $?; do \
+	  case '$(am__configure_deps)' in \
+	    *$$dep*) \
+	      ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+	        && { if test -f $@; then exit 0; else break; fi; }; \
+	      exit 1;; \
+	  esac; \
+	done; \
+	echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/libstrongswan/plugins/files/Makefile'; \
+	$(am__cd) $(top_srcdir) && \
+	  $(AUTOMAKE) --gnu src/libstrongswan/plugins/files/Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+	@case '$?' in \
+	  *config.status*) \
+	    cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+	  *) \
+	    echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+	    cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+	esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure:  $(am__configure_deps)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4):  $(am__aclocal_m4_deps)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+
+clean-noinstLTLIBRARIES:
+	-test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES)
+	@list='$(noinst_LTLIBRARIES)'; \
+	locs=`for p in $$list; do echo $$p; done | \
+	      sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \
+	      sort -u`; \
+	test -z "$$locs" || { \
+	  echo rm -f $${locs}; \
+	  rm -f $${locs}; \
+	}
+
+install-pluginLTLIBRARIES: $(plugin_LTLIBRARIES)
+	@$(NORMAL_INSTALL)
+	@list='$(plugin_LTLIBRARIES)'; test -n "$(plugindir)" || list=; \
+	list2=; for p in $$list; do \
+	  if test -f $$p; then \
+	    list2="$$list2 $$p"; \
+	  else :; fi; \
+	done; \
+	test -z "$$list2" || { \
+	  echo " $(MKDIR_P) '$(DESTDIR)$(plugindir)'"; \
+	  $(MKDIR_P) "$(DESTDIR)$(plugindir)" || exit 1; \
+	  echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(plugindir)'"; \
+	  $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(plugindir)"; \
+	}
+
+uninstall-pluginLTLIBRARIES:
+	@$(NORMAL_UNINSTALL)
+	@list='$(plugin_LTLIBRARIES)'; test -n "$(plugindir)" || list=; \
+	for p in $$list; do \
+	  $(am__strip_dir) \
+	  echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(plugindir)/$$f'"; \
+	  $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(plugindir)/$$f"; \
+	done
+
+clean-pluginLTLIBRARIES:
+	-test -z "$(plugin_LTLIBRARIES)" || rm -f $(plugin_LTLIBRARIES)
+	@list='$(plugin_LTLIBRARIES)'; \
+	locs=`for p in $$list; do echo $$p; done | \
+	      sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \
+	      sort -u`; \
+	test -z "$$locs" || { \
+	  echo rm -f $${locs}; \
+	  rm -f $${locs}; \
+	}
+
+libstrongswan-files.la: $(libstrongswan_files_la_OBJECTS) $(libstrongswan_files_la_DEPENDENCIES) $(EXTRA_libstrongswan_files_la_DEPENDENCIES) 
+	$(AM_V_CCLD)$(libstrongswan_files_la_LINK) $(am_libstrongswan_files_la_rpath) $(libstrongswan_files_la_OBJECTS) $(libstrongswan_files_la_LIBADD) $(LIBS)
+
+mostlyclean-compile:
+	-rm -f *.$(OBJEXT)
+
+distclean-compile:
+	-rm -f *.tab.c
+
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/files_fetcher.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/files_plugin.Plo at am__quote@
+
+.c.o:
+ at am__fastdepCC_TRUE@	$(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\
+ at am__fastdepCC_TRUE@	$(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\
+ at am__fastdepCC_TRUE@	$(am__mv) $$depbase.Tpo $$depbase.Po
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(COMPILE) -c -o $@ $<
+
+.c.obj:
+ at am__fastdepCC_TRUE@	$(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\
+ at am__fastdepCC_TRUE@	$(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\
+ at am__fastdepCC_TRUE@	$(am__mv) $$depbase.Tpo $$depbase.Po
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
+
+.c.lo:
+ at am__fastdepCC_TRUE@	$(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\
+ at am__fastdepCC_TRUE@	$(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\
+ at am__fastdepCC_TRUE@	$(am__mv) $$depbase.Tpo $$depbase.Plo
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(LTCOMPILE) -c -o $@ $<
+
+mostlyclean-libtool:
+	-rm -f *.lo
+
+clean-libtool:
+	-rm -rf .libs _libs
+
+ID: $(am__tagged_files)
+	$(am__define_uniq_tagged_files); mkid -fID $$unique
+tags: tags-am
+TAGS: tags
+
+tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+	set x; \
+	here=`pwd`; \
+	$(am__define_uniq_tagged_files); \
+	shift; \
+	if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
+	  test -n "$$unique" || unique=$$empty_fix; \
+	  if test $$# -gt 0; then \
+	    $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+	      "$$@" $$unique; \
+	  else \
+	    $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+	      $$unique; \
+	  fi; \
+	fi
+ctags: ctags-am
+
+CTAGS: ctags
+ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+	$(am__define_uniq_tagged_files); \
+	test -z "$(CTAGS_ARGS)$$unique" \
+	  || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+	     $$unique
+
+GTAGS:
+	here=`$(am__cd) $(top_builddir) && pwd` \
+	  && $(am__cd) $(top_srcdir) \
+	  && gtags -i $(GTAGS_ARGS) "$$here"
+cscopelist: cscopelist-am
+
+cscopelist-am: $(am__tagged_files)
+	list='$(am__tagged_files)'; \
+	case "$(srcdir)" in \
+	  [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
+	  *) sdir=$(subdir)/$(srcdir) ;; \
+	esac; \
+	for i in $$list; do \
+	  if test -f "$$i"; then \
+	    echo "$(subdir)/$$i"; \
+	  else \
+	    echo "$$sdir/$$i"; \
+	  fi; \
+	done >> $(top_builddir)/cscope.files
+
+distclean-tags:
+	-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+distdir: $(DISTFILES)
+	@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+	topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+	list='$(DISTFILES)'; \
+	  dist_files=`for file in $$list; do echo $$file; done | \
+	  sed -e "s|^$$srcdirstrip/||;t" \
+	      -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+	case $$dist_files in \
+	  */*) $(MKDIR_P) `echo "$$dist_files" | \
+			   sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+			   sort -u` ;; \
+	esac; \
+	for file in $$dist_files; do \
+	  if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+	  if test -d $$d/$$file; then \
+	    dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+	    if test -d "$(distdir)/$$file"; then \
+	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+	    fi; \
+	    if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+	      cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+	    fi; \
+	    cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+	  else \
+	    test -f "$(distdir)/$$file" \
+	    || cp -p $$d/$$file "$(distdir)/$$file" \
+	    || exit 1; \
+	  fi; \
+	done
+check-am: all-am
+check: check-am
+all-am: Makefile $(LTLIBRARIES)
+installdirs:
+	for dir in "$(DESTDIR)$(plugindir)"; do \
+	  test -z "$$dir" || $(MKDIR_P) "$$dir"; \
+	done
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+	@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+	if test -z '$(STRIP)'; then \
+	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	      install; \
+	else \
+	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	    "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+	fi
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+	-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+	-test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+
+maintainer-clean-generic:
+	@echo "This command is intended for maintainers to use"
+	@echo "it deletes files that may require special tools to rebuild."
+clean: clean-am
+
+clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \
+	clean-pluginLTLIBRARIES mostlyclean-am
+
+distclean: distclean-am
+	-rm -rf ./$(DEPDIR)
+	-rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+	distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+html-am:
+
+info: info-am
+
+info-am:
+
+install-data-am: install-pluginLTLIBRARIES
+
+install-dvi: install-dvi-am
+
+install-dvi-am:
+
+install-exec-am:
+
+install-html: install-html-am
+
+install-html-am:
+
+install-info: install-info-am
+
+install-info-am:
+
+install-man:
+
+install-pdf: install-pdf-am
+
+install-pdf-am:
+
+install-ps: install-ps-am
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+	-rm -rf ./$(DEPDIR)
+	-rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic \
+	mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am: uninstall-pluginLTLIBRARIES
+
+.MAKE: install-am install-strip
+
+.PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \
+	clean-libtool clean-noinstLTLIBRARIES clean-pluginLTLIBRARIES \
+	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-man install-pdf \
+	install-pdf-am install-pluginLTLIBRARIES install-ps \
+	install-ps-am install-strip installcheck installcheck-am \
+	installdirs maintainer-clean maintainer-clean-generic \
+	mostlyclean mostlyclean-compile mostlyclean-generic \
+	mostlyclean-libtool pdf pdf-am ps ps-am tags tags-am uninstall \
+	uninstall-am uninstall-pluginLTLIBRARIES
+
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/src/libstrongswan/plugins/files/files_fetcher.c b/src/libstrongswan/plugins/files/files_fetcher.c
new file mode 100644
index 0000000..e0b7cbd
--- /dev/null
+++ b/src/libstrongswan/plugins/files/files_fetcher.c
@@ -0,0 +1,117 @@
+/*
+ * Copyright (C) 2015 Tobias Brunner
+ * Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * for more details.
+ */
+
+#include <errno.h>
+
+#include <library.h>
+#include <utils/debug.h>
+
+#include "files_fetcher.h"
+
+typedef struct private_files_fetcher_t private_files_fetcher_t;
+
+/**
+ * private data of a files_fetcher_t object.
+ */
+struct private_files_fetcher_t {
+
+	/**
+	 * Public data
+	 */
+	files_fetcher_t public;
+
+	/**
+	 * Callback function
+	 */
+	fetcher_callback_t cb;
+};
+
+METHOD(fetcher_t, fetch, status_t,
+	private_files_fetcher_t *this, char *uri, void *userdata)
+{
+	chunk_t *data;
+	status_t status = FAILED;
+
+	if (this->cb == fetcher_default_callback)
+	{
+		*(chunk_t*)userdata = chunk_empty;
+	}
+	if (!strpfx(uri, "file://"))
+	{
+		return NOT_SUPPORTED;
+	}
+	uri = uri + strlen("file://");
+	data = chunk_map(uri, FALSE);
+	if (!data)
+	{
+		DBG1(DBG_LIB, "  opening '%s' failed: %s", uri, strerror(errno));
+		return FAILED;
+	}
+	if (this->cb(userdata, *data))
+	{
+		status = SUCCESS;
+	}
+	chunk_unmap(data);
+	return status;
+}
+
+METHOD(fetcher_t, set_option, bool,
+	private_files_fetcher_t *this, fetcher_option_t option, ...)
+{
+	bool supported = TRUE;
+	va_list args;
+
+	va_start(args, option);
+	switch (option)
+	{
+		case FETCH_CALLBACK:
+		{
+			this->cb = va_arg(args, fetcher_callback_t);
+			break;
+		}
+		default:
+			supported = FALSE;
+			break;
+	}
+	va_end(args);
+	return supported;
+}
+
+METHOD(fetcher_t, destroy, void,
+	private_files_fetcher_t *this)
+{
+	free(this);
+}
+
+/*
+ * Described in header.
+ */
+files_fetcher_t *files_fetcher_create()
+{
+	private_files_fetcher_t *this;
+
+	INIT(this,
+		.public = {
+			.interface = {
+				.fetch = _fetch,
+				.set_option = _set_option,
+				.destroy = _destroy,
+			},
+		},
+		.cb = fetcher_default_callback,
+	);
+
+	return &this->public;
+}
diff --git a/src/libstrongswan/plugins/files/files_fetcher.h b/src/libstrongswan/plugins/files/files_fetcher.h
new file mode 100644
index 0000000..7fc4ec9
--- /dev/null
+++ b/src/libstrongswan/plugins/files/files_fetcher.h
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2015 Tobias Brunner
+ * Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * for more details.
+ */
+
+/**
+ * @defgroup files_fetcher files_fetcher
+ * @{ @ingroup files_p
+ */
+
+#ifndef FILES_FETCHER_H_
+#define FILES_FETCHER_H_
+
+typedef struct files_fetcher_t files_fetcher_t;
+
+/**
+ * Fetcher implementation loading local files
+ */
+struct files_fetcher_t {
+
+	/**
+	 * Implements fetcher interface
+	 */
+	fetcher_t interface;
+};
+
+/**
+ * Create a files_fetcher instance.
+ */
+files_fetcher_t *files_fetcher_create();
+
+#endif /** FILES_FETCHER_H_ @}*/
diff --git a/src/libstrongswan/plugins/files/files_plugin.c b/src/libstrongswan/plugins/files/files_plugin.c
new file mode 100644
index 0000000..6ab735d
--- /dev/null
+++ b/src/libstrongswan/plugins/files/files_plugin.c
@@ -0,0 +1,76 @@
+/*
+ * Copyright (C) 2015 Tobias Brunner
+ * Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * for more details.
+ */
+
+#include "files_plugin.h"
+#include "files_fetcher.h"
+
+#include <library.h>
+#include <utils/debug.h>
+
+typedef struct private_files_plugin_t private_files_plugin_t;
+
+/**
+ * private data of files_plugin
+ */
+struct private_files_plugin_t {
+
+	/**
+	 * public functions
+	 */
+	files_plugin_t public;
+};
+
+METHOD(plugin_t, get_name, char*,
+	private_files_plugin_t *this)
+{
+	return "files";
+}
+
+METHOD(plugin_t, get_features, int,
+	private_files_plugin_t *this, plugin_feature_t *features[])
+{
+	static plugin_feature_t f[] = {
+		PLUGIN_REGISTER(FETCHER, files_fetcher_create),
+			PLUGIN_PROVIDE(FETCHER, "file://"),
+	};
+	*features = f;
+	return countof(f);
+}
+
+METHOD(plugin_t, destroy, void,
+	private_files_plugin_t *this)
+{
+	free(this);
+}
+
+/*
+ * see header file
+ */
+plugin_t *files_plugin_create()
+{
+	private_files_plugin_t *this;
+
+	INIT(this,
+		.public = {
+			.plugin = {
+				.get_name = _get_name,
+				.get_features = _get_features,
+				.destroy = _destroy,
+			},
+		},
+	);
+
+	return &this->public.plugin;
+}
diff --git a/src/libstrongswan/plugins/files/files_plugin.h b/src/libstrongswan/plugins/files/files_plugin.h
new file mode 100644
index 0000000..c121b96
--- /dev/null
+++ b/src/libstrongswan/plugins/files/files_plugin.h
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2015 Tobias Brunner
+ * Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * for more details.
+ */
+
+/**
+ * @defgroup files_p files
+ * @ingroup plugins
+ *
+ * @defgroup files_plugin files_plugin
+ * @{ @ingroup files_p
+ */
+
+#ifndef FILES_PLUGIN_H_
+#define FILES_PLUGIN_H_
+
+#include <plugins/plugin.h>
+
+typedef struct files_plugin_t files_plugin_t;
+
+/**
+ * Plugin implementing fetcher interface loading local files directly.
+ */
+struct files_plugin_t {
+
+	/**
+	 * implements plugin interface
+	 */
+	plugin_t plugin;
+};
+
+#endif /** FILES_PLUGIN_H_ @}*/
diff --git a/src/libstrongswan/plugins/fips_prf/Makefile.in b/src/libstrongswan/plugins/fips_prf/Makefile.in
index 64ae665..b7ca1ce 100644
--- a/src/libstrongswan/plugins/fips_prf/Makefile.in
+++ b/src/libstrongswan/plugins/fips_prf/Makefile.in
@@ -228,6 +228,7 @@ DLLIB = @DLLIB@
 DLLTOOL = @DLLTOOL@
 DSYMUTIL = @DSYMUTIL@
 DUMPBIN = @DUMPBIN@
+EASY_INSTALL = @EASY_INSTALL@
 ECHO_C = @ECHO_C@
 ECHO_N = @ECHO_N@
 ECHO_T = @ECHO_T@
@@ -288,10 +289,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
 PLUGIN_CFLAGS = @PLUGIN_CFLAGS@
 PTHREADLIB = @PTHREADLIB@
 PYTHON = @PYTHON@
+PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@
 PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
 PYTHON_PLATFORM = @PYTHON_PLATFORM@
 PYTHON_PREFIX = @PYTHON_PREFIX@
 PYTHON_VERSION = @PYTHON_VERSION@
+PY_TEST = @PY_TEST@
 RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
@@ -365,6 +368,8 @@ json_CFLAGS = @json_CFLAGS@
 json_LIBS = @json_LIBS@
 libdir = @libdir@
 libexecdir = @libexecdir@
+libiptc_CFLAGS = @libiptc_CFLAGS@
+libiptc_LIBS = @libiptc_LIBS@
 linux_headers = @linux_headers@
 localedir = @localedir@
 localstatedir = @localstatedir@
diff --git a/src/libstrongswan/plugins/fips_prf/fips_prf.c b/src/libstrongswan/plugins/fips_prf/fips_prf.c
index 2382507..25accf9 100644
--- a/src/libstrongswan/plugins/fips_prf/fips_prf.c
+++ b/src/libstrongswan/plugins/fips_prf/fips_prf.c
@@ -116,6 +116,12 @@ METHOD(prf_t, get_bytes, bool,
 	u_int8_t *xkey = this->key;
 	u_int8_t one[this->b];
 
+	if (!w)
+	{
+		/* append mode is not supported */
+		return FALSE;
+	}
+
 	memset(one, 0, this->b);
 	one[this->b - 1] = 0x01;
 
@@ -250,4 +256,3 @@ fips_prf_t *fips_prf_create(pseudo_random_function_t algo)
 
 	return &this->public;
 }
-
diff --git a/src/libstrongswan/plugins/gcm/Makefile.in b/src/libstrongswan/plugins/gcm/Makefile.in
index 511bfc3..e125ab8 100644
--- a/src/libstrongswan/plugins/gcm/Makefile.in
+++ b/src/libstrongswan/plugins/gcm/Makefile.in
@@ -226,6 +226,7 @@ DLLIB = @DLLIB@
 DLLTOOL = @DLLTOOL@
 DSYMUTIL = @DSYMUTIL@
 DUMPBIN = @DUMPBIN@
+EASY_INSTALL = @EASY_INSTALL@
 ECHO_C = @ECHO_C@
 ECHO_N = @ECHO_N@
 ECHO_T = @ECHO_T@
@@ -286,10 +287,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
 PLUGIN_CFLAGS = @PLUGIN_CFLAGS@
 PTHREADLIB = @PTHREADLIB@
 PYTHON = @PYTHON@
+PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@
 PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
 PYTHON_PLATFORM = @PYTHON_PLATFORM@
 PYTHON_PREFIX = @PYTHON_PREFIX@
 PYTHON_VERSION = @PYTHON_VERSION@
+PY_TEST = @PY_TEST@
 RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
@@ -363,6 +366,8 @@ json_CFLAGS = @json_CFLAGS@
 json_LIBS = @json_LIBS@
 libdir = @libdir@
 libexecdir = @libexecdir@
+libiptc_CFLAGS = @libiptc_CFLAGS@
+libiptc_LIBS = @libiptc_LIBS@
 linux_headers = @linux_headers@
 localedir = @localedir@
 localstatedir = @localstatedir@
diff --git a/src/libstrongswan/plugins/gcrypt/Makefile.in b/src/libstrongswan/plugins/gcrypt/Makefile.in
index 0c7d22d..4ce7438 100644
--- a/src/libstrongswan/plugins/gcrypt/Makefile.in
+++ b/src/libstrongswan/plugins/gcrypt/Makefile.in
@@ -230,6 +230,7 @@ DLLIB = @DLLIB@
 DLLTOOL = @DLLTOOL@
 DSYMUTIL = @DSYMUTIL@
 DUMPBIN = @DUMPBIN@
+EASY_INSTALL = @EASY_INSTALL@
 ECHO_C = @ECHO_C@
 ECHO_N = @ECHO_N@
 ECHO_T = @ECHO_T@
@@ -290,10 +291,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
 PLUGIN_CFLAGS = @PLUGIN_CFLAGS@
 PTHREADLIB = @PTHREADLIB@
 PYTHON = @PYTHON@
+PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@
 PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
 PYTHON_PLATFORM = @PYTHON_PLATFORM@
 PYTHON_PREFIX = @PYTHON_PREFIX@
 PYTHON_VERSION = @PYTHON_VERSION@
+PY_TEST = @PY_TEST@
 RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
@@ -367,6 +370,8 @@ json_CFLAGS = @json_CFLAGS@
 json_LIBS = @json_LIBS@
 libdir = @libdir@
 libexecdir = @libexecdir@
+libiptc_CFLAGS = @libiptc_CFLAGS@
+libiptc_LIBS = @libiptc_LIBS@
 linux_headers = @linux_headers@
 localedir = @localedir@
 localstatedir = @localstatedir@
diff --git a/src/libstrongswan/plugins/gcrypt/gcrypt_dh.c b/src/libstrongswan/plugins/gcrypt/gcrypt_dh.c
index f418b94..744ec0b 100644
--- a/src/libstrongswan/plugins/gcrypt/gcrypt_dh.c
+++ b/src/libstrongswan/plugins/gcrypt/gcrypt_dh.c
@@ -35,7 +35,7 @@ struct private_gcrypt_dh_t {
 	/**
 	 * Diffie Hellman group number
 	 */
-	u_int16_t group;
+	diffie_hellman_group_t group;
 
 	/*
 	 * Generator value
@@ -73,12 +73,17 @@ struct private_gcrypt_dh_t {
 	size_t p_len;
 };
 
-METHOD(diffie_hellman_t, set_other_public_value, void,
+METHOD(diffie_hellman_t, set_other_public_value, bool,
 	private_gcrypt_dh_t *this, chunk_t value)
 {
 	gcry_mpi_t p_min_1;
 	gcry_error_t err;
 
+	if (!diffie_hellman_verify_value(this->group, value))
+	{
+		return FALSE;
+	}
+
 	if (this->yb)
 	{
 		gcry_mpi_release(this->yb);
@@ -88,7 +93,7 @@ METHOD(diffie_hellman_t, set_other_public_value, void,
 	if (err)
 	{
 		DBG1(DBG_LIB, "importing mpi yb failed: %s", gpg_strerror(err));
-		return;
+		return FALSE;
 	}
 
 	p_min_1 = gcry_mpi_new(this->p_len * 8);
@@ -112,6 +117,7 @@ METHOD(diffie_hellman_t, set_other_public_value, void,
 			 " y < 2 || y > p - 1 ");
 	}
 	gcry_mpi_release(p_min_1);
+	return this->zz != NULL;
 }
 
 /**
@@ -132,21 +138,22 @@ static chunk_t export_mpi(gcry_mpi_t value, size_t len)
 	return chunk;
 }
 
-METHOD(diffie_hellman_t, get_my_public_value, void,
+METHOD(diffie_hellman_t, get_my_public_value, bool,
 	private_gcrypt_dh_t *this, chunk_t *value)
 {
 	*value = export_mpi(this->ya, this->p_len);
+	return TRUE;
 }
 
-METHOD(diffie_hellman_t, get_shared_secret, status_t,
+METHOD(diffie_hellman_t, get_shared_secret, bool,
 	private_gcrypt_dh_t *this, chunk_t *secret)
 {
 	if (!this->zz)
 	{
-		return FAILED;
+		return FALSE;
 	}
 	*secret = export_mpi(this->zz, this->p_len);
-	return SUCCESS;
+	return TRUE;
 }
 
 METHOD(diffie_hellman_t, get_dh_group, diffie_hellman_group_t,
diff --git a/src/libstrongswan/plugins/gmp/Makefile.in b/src/libstrongswan/plugins/gmp/Makefile.in
index eab4a00..788cb93 100644
--- a/src/libstrongswan/plugins/gmp/Makefile.in
+++ b/src/libstrongswan/plugins/gmp/Makefile.in
@@ -227,6 +227,7 @@ DLLIB = @DLLIB@
 DLLTOOL = @DLLTOOL@
 DSYMUTIL = @DSYMUTIL@
 DUMPBIN = @DUMPBIN@
+EASY_INSTALL = @EASY_INSTALL@
 ECHO_C = @ECHO_C@
 ECHO_N = @ECHO_N@
 ECHO_T = @ECHO_T@
@@ -287,10 +288,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
 PLUGIN_CFLAGS = @PLUGIN_CFLAGS@
 PTHREADLIB = @PTHREADLIB@
 PYTHON = @PYTHON@
+PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@
 PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
 PYTHON_PLATFORM = @PYTHON_PLATFORM@
 PYTHON_PREFIX = @PYTHON_PREFIX@
 PYTHON_VERSION = @PYTHON_VERSION@
+PY_TEST = @PY_TEST@
 RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
@@ -364,6 +367,8 @@ json_CFLAGS = @json_CFLAGS@
 json_LIBS = @json_LIBS@
 libdir = @libdir@
 libexecdir = @libexecdir@
+libiptc_CFLAGS = @libiptc_CFLAGS@
+libiptc_LIBS = @libiptc_LIBS@
 linux_headers = @linux_headers@
 localedir = @localedir@
 localstatedir = @localstatedir@
diff --git a/src/libstrongswan/plugins/gmp/gmp_diffie_hellman.c b/src/libstrongswan/plugins/gmp/gmp_diffie_hellman.c
index b74d351..4fcb168 100644
--- a/src/libstrongswan/plugins/gmp/gmp_diffie_hellman.c
+++ b/src/libstrongswan/plugins/gmp/gmp_diffie_hellman.c
@@ -42,7 +42,7 @@ struct private_gmp_diffie_hellman_t {
 	/**
 	 * Diffie Hellman group number.
 	 */
-	u_int16_t group;
+	diffie_hellman_group_t group;
 
 	/*
 	 * Generator value.
@@ -85,11 +85,16 @@ struct private_gmp_diffie_hellman_t {
 	bool computed;
 };
 
-METHOD(diffie_hellman_t, set_other_public_value, void,
+METHOD(diffie_hellman_t, set_other_public_value, bool,
 	private_gmp_diffie_hellman_t *this, chunk_t value)
 {
 	mpz_t p_min_1;
 
+	if (!diffie_hellman_verify_value(this->group, value))
+	{
+		return FALSE;
+	}
+
 	mpz_init(p_min_1);
 	mpz_sub_ui(p_min_1, this->p, 1);
 
@@ -142,9 +147,10 @@ METHOD(diffie_hellman_t, set_other_public_value, void,
 			 " y < 2 || y > p - 1 ");
 	}
 	mpz_clear(p_min_1);
+	return this->computed;
 }
 
-METHOD(diffie_hellman_t, get_my_public_value, void,
+METHOD(diffie_hellman_t, get_my_public_value, bool,
 	private_gmp_diffie_hellman_t *this,chunk_t *value)
 {
 	value->len = this->p_len;
@@ -153,22 +159,23 @@ METHOD(diffie_hellman_t, get_my_public_value, void,
 	{
 		value->len = 0;
 	}
+	return TRUE;
 }
 
-METHOD(diffie_hellman_t, get_shared_secret, status_t,
+METHOD(diffie_hellman_t, get_shared_secret, bool,
 	private_gmp_diffie_hellman_t *this, chunk_t *secret)
 {
 	if (!this->computed)
 	{
-		return FAILED;
+		return FALSE;
 	}
 	secret->len = this->p_len;
 	secret->ptr = mpz_export(NULL, NULL, 1, secret->len, 1, 0, this->zz);
 	if (secret->ptr == NULL)
 	{
-		return FAILED;
+		return FALSE;
 	}
-	return SUCCESS;
+	return TRUE;
 }
 
 METHOD(diffie_hellman_t, get_dh_group, diffie_hellman_group_t,
@@ -245,7 +252,7 @@ static gmp_diffie_hellman_t *create_generic(diffie_hellman_group_t group,
 		*random.ptr &= 0x7F;
 	}
 	mpz_import(this->xa, random.len, 1, 1, 1, 0, random.ptr);
-	chunk_free(&random);
+	chunk_clear(&random);
 	DBG2(DBG_LIB, "size of DH secret exponent: %u bits",
 		 mpz_sizeinbase(this->xa, 2));
 
diff --git a/src/libstrongswan/plugins/hmac/Makefile.in b/src/libstrongswan/plugins/hmac/Makefile.in
index bf34e4c..a8c39cb 100644
--- a/src/libstrongswan/plugins/hmac/Makefile.in
+++ b/src/libstrongswan/plugins/hmac/Makefile.in
@@ -226,6 +226,7 @@ DLLIB = @DLLIB@
 DLLTOOL = @DLLTOOL@
 DSYMUTIL = @DSYMUTIL@
 DUMPBIN = @DUMPBIN@
+EASY_INSTALL = @EASY_INSTALL@
 ECHO_C = @ECHO_C@
 ECHO_N = @ECHO_N@
 ECHO_T = @ECHO_T@
@@ -286,10 +287,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
 PLUGIN_CFLAGS = @PLUGIN_CFLAGS@
 PTHREADLIB = @PTHREADLIB@
 PYTHON = @PYTHON@
+PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@
 PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
 PYTHON_PLATFORM = @PYTHON_PLATFORM@
 PYTHON_PREFIX = @PYTHON_PREFIX@
 PYTHON_VERSION = @PYTHON_VERSION@
+PY_TEST = @PY_TEST@
 RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
@@ -363,6 +366,8 @@ json_CFLAGS = @json_CFLAGS@
 json_LIBS = @json_LIBS@
 libdir = @libdir@
 libexecdir = @libexecdir@
+libiptc_CFLAGS = @libiptc_CFLAGS@
+libiptc_LIBS = @libiptc_LIBS@
 linux_headers = @linux_headers@
 localedir = @localedir@
 localstatedir = @localstatedir@
diff --git a/src/libstrongswan/plugins/hmac/hmac.c b/src/libstrongswan/plugins/hmac/hmac.c
index 44cb46b..96a14ae 100644
--- a/src/libstrongswan/plugins/hmac/hmac.c
+++ b/src/libstrongswan/plugins/hmac/hmac.c
@@ -103,7 +103,8 @@ METHOD(mac_t, set_key, bool,
 	if (key.len > this->b)
 	{
 		/* if key is too long, it will be hashed */
-		if (!this->h->get_hash(this->h, key, buffer))
+		if (!this->h->reset(this->h) ||
+			!this->h->get_hash(this->h, key, buffer))
 		{
 			return FALSE;
 		}
diff --git a/src/libstrongswan/plugins/keychain/Makefile.in b/src/libstrongswan/plugins/keychain/Makefile.in
index 17faa56..8f6a6f5 100644
--- a/src/libstrongswan/plugins/keychain/Makefile.in
+++ b/src/libstrongswan/plugins/keychain/Makefile.in
@@ -229,6 +229,7 @@ DLLIB = @DLLIB@
 DLLTOOL = @DLLTOOL@
 DSYMUTIL = @DSYMUTIL@
 DUMPBIN = @DUMPBIN@
+EASY_INSTALL = @EASY_INSTALL@
 ECHO_C = @ECHO_C@
 ECHO_N = @ECHO_N@
 ECHO_T = @ECHO_T@
@@ -289,10 +290,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
 PLUGIN_CFLAGS = @PLUGIN_CFLAGS@
 PTHREADLIB = @PTHREADLIB@
 PYTHON = @PYTHON@
+PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@
 PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
 PYTHON_PLATFORM = @PYTHON_PLATFORM@
 PYTHON_PREFIX = @PYTHON_PREFIX@
 PYTHON_VERSION = @PYTHON_VERSION@
+PY_TEST = @PY_TEST@
 RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
@@ -366,6 +369,8 @@ json_CFLAGS = @json_CFLAGS@
 json_LIBS = @json_LIBS@
 libdir = @libdir@
 libexecdir = @libexecdir@
+libiptc_CFLAGS = @libiptc_CFLAGS@
+libiptc_LIBS = @libiptc_LIBS@
 linux_headers = @linux_headers@
 localedir = @localedir@
 localstatedir = @localstatedir@
diff --git a/src/libstrongswan/plugins/ldap/Makefile.in b/src/libstrongswan/plugins/ldap/Makefile.in
index 332a587..5316323 100644
--- a/src/libstrongswan/plugins/ldap/Makefile.in
+++ b/src/libstrongswan/plugins/ldap/Makefile.in
@@ -226,6 +226,7 @@ DLLIB = @DLLIB@
 DLLTOOL = @DLLTOOL@
 DSYMUTIL = @DSYMUTIL@
 DUMPBIN = @DUMPBIN@
+EASY_INSTALL = @EASY_INSTALL@
 ECHO_C = @ECHO_C@
 ECHO_N = @ECHO_N@
 ECHO_T = @ECHO_T@
@@ -286,10 +287,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
 PLUGIN_CFLAGS = @PLUGIN_CFLAGS@
 PTHREADLIB = @PTHREADLIB@
 PYTHON = @PYTHON@
+PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@
 PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
 PYTHON_PLATFORM = @PYTHON_PLATFORM@
 PYTHON_PREFIX = @PYTHON_PREFIX@
 PYTHON_VERSION = @PYTHON_VERSION@
+PY_TEST = @PY_TEST@
 RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
@@ -363,6 +366,8 @@ json_CFLAGS = @json_CFLAGS@
 json_LIBS = @json_LIBS@
 libdir = @libdir@
 libexecdir = @libexecdir@
+libiptc_CFLAGS = @libiptc_CFLAGS@
+libiptc_LIBS = @libiptc_LIBS@
 linux_headers = @linux_headers@
 localedir = @localedir@
 localstatedir = @localstatedir@
diff --git a/src/libstrongswan/plugins/md4/Makefile.in b/src/libstrongswan/plugins/md4/Makefile.in
index 91fe8c4..d5f9c6c 100644
--- a/src/libstrongswan/plugins/md4/Makefile.in
+++ b/src/libstrongswan/plugins/md4/Makefile.in
@@ -226,6 +226,7 @@ DLLIB = @DLLIB@
 DLLTOOL = @DLLTOOL@
 DSYMUTIL = @DSYMUTIL@
 DUMPBIN = @DUMPBIN@
+EASY_INSTALL = @EASY_INSTALL@
 ECHO_C = @ECHO_C@
 ECHO_N = @ECHO_N@
 ECHO_T = @ECHO_T@
@@ -286,10 +287,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
 PLUGIN_CFLAGS = @PLUGIN_CFLAGS@
 PTHREADLIB = @PTHREADLIB@
 PYTHON = @PYTHON@
+PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@
 PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
 PYTHON_PLATFORM = @PYTHON_PLATFORM@
 PYTHON_PREFIX = @PYTHON_PREFIX@
 PYTHON_VERSION = @PYTHON_VERSION@
+PY_TEST = @PY_TEST@
 RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
@@ -363,6 +366,8 @@ json_CFLAGS = @json_CFLAGS@
 json_LIBS = @json_LIBS@
 libdir = @libdir@
 libexecdir = @libexecdir@
+libiptc_CFLAGS = @libiptc_CFLAGS@
+libiptc_LIBS = @libiptc_LIBS@
 linux_headers = @linux_headers@
 localedir = @localedir@
 localstatedir = @localstatedir@
diff --git a/src/libstrongswan/plugins/md5/Makefile.in b/src/libstrongswan/plugins/md5/Makefile.in
index ba6cb0c..1dd3892 100644
--- a/src/libstrongswan/plugins/md5/Makefile.in
+++ b/src/libstrongswan/plugins/md5/Makefile.in
@@ -226,6 +226,7 @@ DLLIB = @DLLIB@
 DLLTOOL = @DLLTOOL@
 DSYMUTIL = @DSYMUTIL@
 DUMPBIN = @DUMPBIN@
+EASY_INSTALL = @EASY_INSTALL@
 ECHO_C = @ECHO_C@
 ECHO_N = @ECHO_N@
 ECHO_T = @ECHO_T@
@@ -286,10 +287,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
 PLUGIN_CFLAGS = @PLUGIN_CFLAGS@
 PTHREADLIB = @PTHREADLIB@
 PYTHON = @PYTHON@
+PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@
 PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
 PYTHON_PLATFORM = @PYTHON_PLATFORM@
 PYTHON_PREFIX = @PYTHON_PREFIX@
 PYTHON_VERSION = @PYTHON_VERSION@
+PY_TEST = @PY_TEST@
 RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
@@ -363,6 +366,8 @@ json_CFLAGS = @json_CFLAGS@
 json_LIBS = @json_LIBS@
 libdir = @libdir@
 libexecdir = @libexecdir@
+libiptc_CFLAGS = @libiptc_CFLAGS@
+libiptc_LIBS = @libiptc_LIBS@
 linux_headers = @linux_headers@
 localedir = @localedir@
 localstatedir = @localstatedir@
diff --git a/src/libstrongswan/plugins/mysql/Makefile.in b/src/libstrongswan/plugins/mysql/Makefile.in
index bca4562..e2fb7e7 100644
--- a/src/libstrongswan/plugins/mysql/Makefile.in
+++ b/src/libstrongswan/plugins/mysql/Makefile.in
@@ -228,6 +228,7 @@ DLLIB = @DLLIB@
 DLLTOOL = @DLLTOOL@
 DSYMUTIL = @DSYMUTIL@
 DUMPBIN = @DUMPBIN@
+EASY_INSTALL = @EASY_INSTALL@
 ECHO_C = @ECHO_C@
 ECHO_N = @ECHO_N@
 ECHO_T = @ECHO_T@
@@ -288,10 +289,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
 PLUGIN_CFLAGS = @PLUGIN_CFLAGS@
 PTHREADLIB = @PTHREADLIB@
 PYTHON = @PYTHON@
+PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@
 PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
 PYTHON_PLATFORM = @PYTHON_PLATFORM@
 PYTHON_PREFIX = @PYTHON_PREFIX@
 PYTHON_VERSION = @PYTHON_VERSION@
+PY_TEST = @PY_TEST@
 RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
@@ -365,6 +368,8 @@ json_CFLAGS = @json_CFLAGS@
 json_LIBS = @json_LIBS@
 libdir = @libdir@
 libexecdir = @libexecdir@
+libiptc_CFLAGS = @libiptc_CFLAGS@
+libiptc_LIBS = @libiptc_LIBS@
 linux_headers = @linux_headers@
 localedir = @localedir@
 localstatedir = @localstatedir@
diff --git a/src/libstrongswan/plugins/nonce/Makefile.in b/src/libstrongswan/plugins/nonce/Makefile.in
index 0d15d7c..0b51ba5 100644
--- a/src/libstrongswan/plugins/nonce/Makefile.in
+++ b/src/libstrongswan/plugins/nonce/Makefile.in
@@ -227,6 +227,7 @@ DLLIB = @DLLIB@
 DLLTOOL = @DLLTOOL@
 DSYMUTIL = @DSYMUTIL@
 DUMPBIN = @DUMPBIN@
+EASY_INSTALL = @EASY_INSTALL@
 ECHO_C = @ECHO_C@
 ECHO_N = @ECHO_N@
 ECHO_T = @ECHO_T@
@@ -287,10 +288,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
 PLUGIN_CFLAGS = @PLUGIN_CFLAGS@
 PTHREADLIB = @PTHREADLIB@
 PYTHON = @PYTHON@
+PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@
 PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
 PYTHON_PLATFORM = @PYTHON_PLATFORM@
 PYTHON_PREFIX = @PYTHON_PREFIX@
 PYTHON_VERSION = @PYTHON_VERSION@
+PY_TEST = @PY_TEST@
 RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
@@ -364,6 +367,8 @@ json_CFLAGS = @json_CFLAGS@
 json_LIBS = @json_LIBS@
 libdir = @libdir@
 libexecdir = @libexecdir@
+libiptc_CFLAGS = @libiptc_CFLAGS@
+libiptc_LIBS = @libiptc_LIBS@
 linux_headers = @linux_headers@
 localedir = @localedir@
 localstatedir = @localstatedir@
diff --git a/src/libstrongswan/plugins/ntru/Makefile.am b/src/libstrongswan/plugins/ntru/Makefile.am
index b959afa..c9fcee9 100644
--- a/src/libstrongswan/plugins/ntru/Makefile.am
+++ b/src/libstrongswan/plugins/ntru/Makefile.am
@@ -16,7 +16,6 @@ libstrongswan_ntru_la_SOURCES = \
 	ntru_convert.h ntru_convert.c \
 	ntru_drbg.h ntru_drbg.c \
 	ntru_ke.h ntru_ke.c \
-	ntru_mgf1.h ntru_mgf1.c \
 	ntru_param_set.h ntru_param_set.c \
 	ntru_poly.h ntru_poly.c \
 	ntru_public_key.h ntru_public_key.c \
diff --git a/src/libstrongswan/plugins/ntru/Makefile.in b/src/libstrongswan/plugins/ntru/Makefile.in
index e57a367..5636692 100644
--- a/src/libstrongswan/plugins/ntru/Makefile.in
+++ b/src/libstrongswan/plugins/ntru/Makefile.in
@@ -129,9 +129,8 @@ am__installdirs = "$(DESTDIR)$(plugindir)"
 LTLIBRARIES = $(noinst_LTLIBRARIES) $(plugin_LTLIBRARIES)
 libstrongswan_ntru_la_LIBADD =
 am_libstrongswan_ntru_la_OBJECTS = ntru_plugin.lo ntru_convert.lo \
-	ntru_drbg.lo ntru_ke.lo ntru_mgf1.lo ntru_param_set.lo \
-	ntru_poly.lo ntru_public_key.lo ntru_private_key.lo \
-	ntru_trits.lo
+	ntru_drbg.lo ntru_ke.lo ntru_param_set.lo ntru_poly.lo \
+	ntru_public_key.lo ntru_private_key.lo ntru_trits.lo
 libstrongswan_ntru_la_OBJECTS = $(am_libstrongswan_ntru_la_OBJECTS)
 AM_V_lt = $(am__v_lt_ at AM_V@)
 am__v_lt_ = $(am__v_lt_ at AM_DEFAULT_V@)
@@ -229,6 +228,7 @@ DLLIB = @DLLIB@
 DLLTOOL = @DLLTOOL@
 DSYMUTIL = @DSYMUTIL@
 DUMPBIN = @DUMPBIN@
+EASY_INSTALL = @EASY_INSTALL@
 ECHO_C = @ECHO_C@
 ECHO_N = @ECHO_N@
 ECHO_T = @ECHO_T@
@@ -289,10 +289,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
 PLUGIN_CFLAGS = @PLUGIN_CFLAGS@
 PTHREADLIB = @PTHREADLIB@
 PYTHON = @PYTHON@
+PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@
 PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
 PYTHON_PLATFORM = @PYTHON_PLATFORM@
 PYTHON_PREFIX = @PYTHON_PREFIX@
 PYTHON_VERSION = @PYTHON_VERSION@
+PY_TEST = @PY_TEST@
 RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
@@ -366,6 +368,8 @@ json_CFLAGS = @json_CFLAGS@
 json_LIBS = @json_LIBS@
 libdir = @libdir@
 libexecdir = @libexecdir@
+libiptc_CFLAGS = @libiptc_CFLAGS@
+libiptc_LIBS = @libiptc_LIBS@
 linux_headers = @linux_headers@
 localedir = @localedir@
 localstatedir = @localstatedir@
@@ -438,7 +442,6 @@ libstrongswan_ntru_la_SOURCES = \
 	ntru_convert.h ntru_convert.c \
 	ntru_drbg.h ntru_drbg.c \
 	ntru_ke.h ntru_ke.c \
-	ntru_mgf1.h ntru_mgf1.c \
 	ntru_param_set.h ntru_param_set.c \
 	ntru_poly.h ntru_poly.c \
 	ntru_public_key.h ntru_public_key.c \
@@ -539,7 +542,6 @@ distclean-compile:
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/ntru_convert.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/ntru_drbg.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/ntru_ke.Plo at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/ntru_mgf1.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/ntru_param_set.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/ntru_plugin.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/ntru_poly.Plo at am__quote@
diff --git a/src/libstrongswan/plugins/ntru/ntru_ke.c b/src/libstrongswan/plugins/ntru/ntru_ke.c
index abaa223..3b5df81 100644
--- a/src/libstrongswan/plugins/ntru/ntru_ke.c
+++ b/src/libstrongswan/plugins/ntru/ntru_ke.c
@@ -56,7 +56,7 @@ struct private_ntru_ke_t {
 	/**
 	 * Diffie Hellman group number.
 	 */
-	u_int16_t group;
+	diffie_hellman_group_t group;
 
 	/**
 	 * NTRU Parameter Set
@@ -106,10 +106,10 @@ struct private_ntru_ke_t {
 	/**
 	 * Deterministic Random Bit Generator
 	 */
-    ntru_drbg_t *drbg;
+	ntru_drbg_t *drbg;
 };
 
-METHOD(diffie_hellman_t, get_my_public_value, void,
+METHOD(diffie_hellman_t, get_my_public_value, bool,
 	private_ntru_ke_t *this, chunk_t *value)
 {
 	*value = chunk_empty;
@@ -130,30 +130,30 @@ METHOD(diffie_hellman_t, get_my_public_value, void,
 			if (!this->privkey)
 			{
 				DBG1(DBG_LIB, "NTRU keypair generation failed");
-				return;
+				return FALSE;
 			}
 			this->pubkey = this->privkey->get_public_key(this->privkey);
 		}
 		*value = chunk_clone(this->pubkey->get_encoding(this->pubkey));
 		DBG3(DBG_LIB, "NTRU public key: %B", value);
 	}
+	return TRUE;
 }
 
-METHOD(diffie_hellman_t, get_shared_secret, status_t,
+METHOD(diffie_hellman_t, get_shared_secret, bool,
 	private_ntru_ke_t *this, chunk_t *secret)
 {
 	if (!this->computed || !this->shared_secret.len)
 	{
 		*secret = chunk_empty;
-		return FAILED;
+		return FALSE;
 	}
 	*secret = chunk_clone(this->shared_secret);
 
-	return SUCCESS;
+	return TRUE;
 }
 
-
-METHOD(diffie_hellman_t, set_other_public_value, void,
+METHOD(diffie_hellman_t, set_other_public_value, bool,
 	private_ntru_ke_t *this, chunk_t value)
 {
 	if (this->privkey)
@@ -162,15 +162,15 @@ METHOD(diffie_hellman_t, set_other_public_value, void,
 		if (value.len == 0)
 		{
 			DBG1(DBG_LIB, "empty NTRU ciphertext");
-			return;
+			return FALSE;
 		}
 		DBG3(DBG_LIB, "NTRU ciphertext: %B", &value);
 
 		/* decrypt the shared secret */
- 		if (!this->privkey->decrypt(this->privkey, value, &this->shared_secret))
+		if (!this->privkey->decrypt(this->privkey, value, &this->shared_secret))
 		{
 			DBG1(DBG_LIB, "NTRU decryption of shared secret failed");
-			return;
+			return FALSE;
 		}
 		this->computed = TRUE;
 	}
@@ -185,13 +185,13 @@ METHOD(diffie_hellman_t, set_other_public_value, void,
 		pubkey = ntru_public_key_create_from_data(this->drbg, value);
 		if (!pubkey)
 		{
-			return;
+			return FALSE;
 		}
 		if (pubkey->get_id(pubkey) != this->param_set->id)
 		{
 			DBG1(DBG_LIB, "received NTRU public key with wrong OUI");
 			pubkey->destroy(pubkey);
-			return;
+			return FALSE;
 		}
 		this->pubkey = pubkey;
 
@@ -204,7 +204,7 @@ METHOD(diffie_hellman_t, set_other_public_value, void,
 		{
 			DBG1(DBG_LIB, "generation of shared secret failed");
 			chunk_free(&this->shared_secret);
-			return;
+			return FALSE;
 		}
 		this->computed = TRUE;
 
@@ -212,10 +212,11 @@ METHOD(diffie_hellman_t, set_other_public_value, void,
 		if (!pubkey->encrypt(pubkey, this->shared_secret, &this->ciphertext))
 		{
 			DBG1(DBG_LIB, "NTRU encryption of shared secret failed");
-			return;
+			return FALSE;
 		}
 		DBG3(DBG_LIB, "NTRU ciphertext: %B", &this->ciphertext);
 	}
+	return this->computed;
 }
 
 METHOD(diffie_hellman_t, get_dh_group, diffie_hellman_group_t,
@@ -301,10 +302,10 @@ ntru_ke_t *ntru_ke_create(diffie_hellman_group_t group, chunk_t g, chunk_t p)
 
 	drbg = ntru_drbg_create(strength, chunk_from_str("IKE NTRU-KE"), entropy);
 	if (!drbg)
- 	{
+	{
 		DBG1(DBG_LIB, "could not instantiate DRBG at %u bit security", strength);
 		entropy->destroy(entropy);
-        return NULL;
+		return NULL;
 	}
 
 	INIT(this,
@@ -326,4 +327,3 @@ ntru_ke_t *ntru_ke_create(diffie_hellman_group_t group, chunk_t g, chunk_t p)
 
 	return &this->public;
 }
-
diff --git a/src/libstrongswan/plugins/ntru/ntru_mgf1.c b/src/libstrongswan/plugins/ntru/ntru_mgf1.c
deleted file mode 100644
index 2338db2..0000000
--- a/src/libstrongswan/plugins/ntru/ntru_mgf1.c
+++ /dev/null
@@ -1,182 +0,0 @@
-/*
- * Copyright (C) 2013 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 "ntru_mgf1.h"
-
-#include <crypto/hashers/hasher.h>
-#include <utils/debug.h>
-#include <utils/test.h>
-
-typedef struct private_ntru_mgf1_t private_ntru_mgf1_t;
-
-/**
- * Private data of an ntru_mgf1_t object.
- */
-struct private_ntru_mgf1_t {
-
-	/**
-	 * Public ntru_mgf1_t interface.
-	 */
-	ntru_mgf1_t public;
-
-	/**
-	 * Hasher the MGF1 Mask Generation Function is based on
-	 */
-	hasher_t *hasher;
-
-	/**
-	 * Counter
-	 */
-	u_int32_t counter;
-
-	/**
-	 * Set if counter has reached 2^32
-	 */
-	bool overflow;
-
-	/**
-	 * Current state to be hashed
-	 */
-	chunk_t state;
-
-	/**
-	 * Position of the 4 octet counter string
-	 */
-	u_char *ctr_str;
-
-};
-
-METHOD(ntru_mgf1_t, get_hash_size, size_t,
-	private_ntru_mgf1_t *this)
-{
-	return this->hasher->get_hash_size(this->hasher);
-}
-
-METHOD(ntru_mgf1_t, get_mask, bool,
-	private_ntru_mgf1_t *this, size_t mask_len, u_char *mask)
-{
-	u_char buf[HASH_SIZE_SHA512];
-	size_t hash_len;
-
-	hash_len = this->hasher->get_hash_size(this->hasher);
-
-	while (mask_len > 0)
-	{
-		/* detect overflow, set counter string and increment counter */
-		if (this->overflow)
-		{
-			return FALSE;
-		}
-		htoun32(this->ctr_str, this->counter++);
-		if (this->counter == 0)
-		{
-			this->overflow = TRUE;
-		}
-
-		/* get the next or final mask block from the hash function */
-		if (!this->hasher->get_hash(this->hasher, this->state,
-								   (mask_len < hash_len) ? buf : mask))
-		{
-			return FALSE;
-		}
-		if (mask_len < hash_len)
-		{
-			memcpy(mask, buf, mask_len);
-			return TRUE;
-		}
-		mask_len -= hash_len;
-		mask += hash_len;
-	}
-	return TRUE;
-}
-
-METHOD(ntru_mgf1_t, allocate_mask, bool,
-	private_ntru_mgf1_t *this, size_t mask_len, chunk_t *mask)
-{
-	if (mask_len == 0)
-	{
-		*mask = chunk_empty;
-		return TRUE;
-	}
-	*mask = chunk_alloc(mask_len);
-
-	return get_mask(this, mask_len, mask->ptr);
-}
-
-METHOD(ntru_mgf1_t, destroy, void,
-	private_ntru_mgf1_t *this)
-{
-	this->hasher->destroy(this->hasher);
-	chunk_clear(&this->state);
-	free(this);
-}
-
-/*
- * Described in header.
- */
-ntru_mgf1_t *ntru_mgf1_create(hash_algorithm_t alg, chunk_t seed,
-							  bool hash_seed)
-{
-	private_ntru_mgf1_t *this;
-	hasher_t *hasher;
-	size_t state_len;
-
-	if (seed.len == 0)
-	{
-		DBG1(DBG_LIB, "empty seed for MGF1");
-		return NULL;
-	}
-
-	hasher = lib->crypto->create_hasher(lib->crypto, alg);
-	if (!hasher)
-	{
-		DBG1(DBG_LIB, "failed to create %N hasher for MGF1",
-			 hash_algorithm_names, alg);
-		return NULL;
-	}
-	state_len = (hash_seed ? hasher->get_hash_size(hasher) : seed.len) + 4;
-	
-	INIT(this,
-		.public = {
-			.get_hash_size = _get_hash_size,
-			.allocate_mask = _allocate_mask,
-			.get_mask = _get_mask,
-			.destroy = _destroy,
-		},
-		.hasher = hasher,
-		.state = chunk_alloc(state_len),
-	);
-
-	/* determine position of the 4 octet counter string */
-	this->ctr_str = this->state.ptr + state_len - 4;
-
-	if (hash_seed)
-	{
-		if (!hasher->get_hash(hasher, seed, this->state.ptr))
-		{
-			DBG1(DBG_LIB, "failed to hash seed for MGF1");
-			destroy(this);
-			return NULL;
-		}
-	}
-	else
-	{
-		memcpy(this->state.ptr, seed.ptr, seed.len);
-	}
-
-	return &this->public;
-}
-
-EXPORT_FUNCTION_FOR_TESTS(ntru, ntru_mgf1_create);
diff --git a/src/libstrongswan/plugins/ntru/ntru_mgf1.h b/src/libstrongswan/plugins/ntru/ntru_mgf1.h
deleted file mode 100644
index 53e9041..0000000
--- a/src/libstrongswan/plugins/ntru/ntru_mgf1.h
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- * Copyright (C) 2013 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 ntru_mgf1 ntru_mgf1
- * @{ @ingroup ntru_p
- */
-
-#ifndef NTRU_MGF1_H_
-#define NTRU_MGF1_H_
-
-typedef struct ntru_mgf1_t ntru_mgf1_t;
-
-#include <library.h>
-
-/**
- * Implements the PKCS#1 MGF1 Mask Generation Function based on a hash function
- * defined in section 10.2.1 of RFC 2437 
- */
-struct ntru_mgf1_t {
-
-	/**
-	 * Get the hash size of the underlying hash function
-	 *
-	 * @return			hash size in bytes
-	 */
-	size_t (*get_hash_size)(ntru_mgf1_t *this);
-
-	/**
-	 * Generate a mask pattern and copy it to an output buffer
-	 * If the maximum number of requests has been reached, reseeding occurs
-	 *
-	 * @param mask_len	number of mask bytes to generate
-	 * @param mask		output buffer of minimum size mask_len
-	 * @return			TRUE if successful
-	 */
-	bool (*get_mask)(ntru_mgf1_t *this, size_t mask_len, u_char *mask);
-
-	/**
-	 * Generate a mask pattern and return it in an allocated chunk
-	 *
-	 * @param mask_len	number of mask bytes to generate
-	 * @param mask		chunk containing generated mask
-	 * @return			TRUE if successful
-	 */
-	bool (*allocate_mask)(ntru_mgf1_t *this, size_t mask_len, chunk_t *mask);
-
-	/**
-	 * Destroy the MGF1 object
-	 */
-	void (*destroy)(ntru_mgf1_t *this);
-};
-
-/**
- * Create an MGF1 object
- *
- * @param alg			hash algorithm to be used by MGF1
- * @param seed			seed used by MGF1 to generate mask from
- * @param hash_seed		hash seed before using it as a seed from MGF1
- */
-ntru_mgf1_t *ntru_mgf1_create(hash_algorithm_t alg, chunk_t seed,
-							  bool hash_seed);
-
-#endif /** NTRU_MGF1_H_ @}*/
-
diff --git a/src/libstrongswan/plugins/ntru/ntru_poly.c b/src/libstrongswan/plugins/ntru/ntru_poly.c
index 77ab54a..cb11601 100644
--- a/src/libstrongswan/plugins/ntru/ntru_poly.c
+++ b/src/libstrongswan/plugins/ntru/ntru_poly.c
@@ -16,8 +16,8 @@
  */
 
 #include "ntru_poly.h"
-#include "ntru_mgf1.h"
 
+#include <crypto/mgf1/mgf1_bitspender.h>
 #include <utils/debug.h>
 #include <utils/test.h>
 
@@ -297,22 +297,17 @@ ntru_poly_t *ntru_poly_create_from_seed(hash_algorithm_t alg, chunk_t seed,
 										bool is_product_form)
 {
 	private_ntru_poly_t *this;
-	size_t hash_len, octet_count = 0, i;
-	uint8_t octets[HASH_SIZE_SHA512], *used, num_left = 0, num_needed;
-	uint16_t index, limit, left = 0;
 	int n, num_indices, index_i = 0;
-	ntru_mgf1_t *mgf1;
+	uint32_t index, limit;
+	uint8_t *used;
+	mgf1_bitspender_t *bitspender;
 
-	DBG2(DBG_LIB, "MGF1 is seeded with %u bytes", seed.len);
-	mgf1 = ntru_mgf1_create(alg, seed, TRUE);
-	if (!mgf1)
+	bitspender = mgf1_bitspender_create(alg, seed, TRUE);
+	if (!bitspender)
 	{
 	    return NULL;
 	}
-	i = hash_len = mgf1->get_hash_size(mgf1);
-
 	this = ntru_poly_create(N, q, indices_len_p, indices_len_m, is_product_form);
-
 	used = malloc(N);
 	limit = N * ((1 << c_bits) / N);
 
@@ -328,43 +323,12 @@ ntru_poly_t *ntru_poly_create_from_seed(hash_algorithm_t alg, chunk_t seed,
 			/* generate a random candidate index with a size of c_bits */		
 			do
 			{
-				/* use any leftover bits first */
-				index = num_left ? left << (c_bits - num_left) : 0;
-
-				/* get the rest of the bits needed from new octets */
-				num_needed = c_bits - num_left;
-
-				while (num_needed)
+				if (!bitspender->get_bits(bitspender, c_bits, &index))
 				{
-					if (i == hash_len)
-					{
-						/* get another block from MGF1 */
-						if (!mgf1->get_mask(mgf1, hash_len, octets))
-						{
-							mgf1->destroy(mgf1);
-							destroy(this);
-							free(used);
-							return NULL;
-						}
-						octet_count += hash_len;
-						i = 0;
-					}
-					left = octets[i++];
-
-					if (num_needed <= 8)
-					{
-						/* all bits needed to fill the index are in this octet */
-						index |= left >> (8 - num_needed);
-						num_left = 8 - num_needed;
-						num_needed = 0;
-						left &= 0xff >> (8 - num_left);
-					}
-					else
-					{
-						/* more than one octet will be needed */
-						index |= left << (num_needed - 8);
-						num_needed -= 8;
-					}
+					bitspender->destroy(bitspender);
+					destroy(this);
+					free(used);
+					return NULL;
 				}
 			}
 			while (index >= limit);
@@ -380,9 +344,7 @@ ntru_poly_t *ntru_poly_create_from_seed(hash_algorithm_t alg, chunk_t seed,
 		}
 	}
 
-	DBG2(DBG_LIB, "MGF1 generates %u octets to derive %u indices",
-				   octet_count, this->num_indices);
-	mgf1->destroy(mgf1);
+	bitspender->destroy(bitspender);
 	free(used);
 
 	return &this->public;
diff --git a/src/libstrongswan/plugins/ntru/ntru_trits.c b/src/libstrongswan/plugins/ntru/ntru_trits.c
index 1abb767..57b3532 100644
--- a/src/libstrongswan/plugins/ntru/ntru_trits.c
+++ b/src/libstrongswan/plugins/ntru/ntru_trits.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2013 Andreas Steffen
+ * Copyright (C) 2013-2014 Andreas Steffen
  * HSR Hochschule fuer Technik Rapperswil
  *
  * This program is free software; you can redistribute it and/or modify it
@@ -14,9 +14,9 @@
  */
 
 #include "ntru_trits.h"
-#include "ntru_mgf1.h"
 #include "ntru_convert.h"
 
+#include <crypto/mgf1/mgf1_bitspender.h>
 #include <utils/debug.h>
 #include <utils/test.h>
 
@@ -70,17 +70,15 @@ METHOD(ntru_trits_t, destroy, void,
 ntru_trits_t *ntru_trits_create(size_t len, hash_algorithm_t alg, chunk_t seed)
 {
 	private_ntru_trits_t *this;
-	uint8_t octets[HASH_SIZE_SHA512], buf[5], *trits;
-	size_t hash_len, octet_count = 0, trits_needed, i;
-	ntru_mgf1_t *mgf1;
+	uint8_t octet, buf[5], *trits;
+	size_t trits_needed;
+	mgf1_bitspender_t *bitspender;
 
-	DBG2(DBG_LIB, "MGF1 is seeded with %u bytes", seed.len);
-	mgf1 = ntru_mgf1_create(alg, seed, TRUE);
-	if (!mgf1)
+	bitspender = mgf1_bitspender_create(alg, seed, TRUE);
+	if (!bitspender)
 	{
 	    return NULL;
 	}
-	i = hash_len = mgf1->get_hash_size(mgf1);
 
 	INIT(this,
 		.public = {
@@ -97,21 +95,15 @@ ntru_trits_t *ntru_trits_create(size_t len, hash_algorithm_t alg, chunk_t seed)
 
 	while (trits_needed > 0)
 	{
-		if (i == hash_len)
+		if (!bitspender->get_byte(bitspender, &octet))
 		{
-			/* get another block from MGF1 */
-			if (!mgf1->get_mask(mgf1, hash_len, octets))
-			{
-				mgf1->destroy(mgf1);
-				destroy(this);
-				return NULL;
-			}
-			octet_count += hash_len;
-			i = 0;
+			bitspender->destroy(bitspender);
+			destroy(this);
+			return NULL;
 		}
-		if (octets[i] < 243)  /* 243 = 3^5 */ 
+		if (octet < 243)  /* 243 = 3^5 */
 		{		
-			ntru_octet_2_trits(octets[i], (trits_needed < 5) ? buf : trits);
+			ntru_octet_2_trits(octet, (trits_needed < 5) ? buf : trits);
 			if (trits_needed < 5)
 			{
 				memcpy(trits, buf, trits_needed);
@@ -120,11 +112,8 @@ ntru_trits_t *ntru_trits_create(size_t len, hash_algorithm_t alg, chunk_t seed)
 			trits += 5;
 			trits_needed -= 5;
 		}
-		i++;
 	}
-	DBG2(DBG_LIB, "MGF1 generates %u octets to extract %u trits",
-				   octet_count, len);
-	mgf1->destroy(mgf1);
+	bitspender->destroy(bitspender);
 
 	return &this->public;
 }
diff --git a/src/libstrongswan/plugins/openssl/Makefile.in b/src/libstrongswan/plugins/openssl/Makefile.in
index ac0db01..a667ca4 100644
--- a/src/libstrongswan/plugins/openssl/Makefile.in
+++ b/src/libstrongswan/plugins/openssl/Makefile.in
@@ -236,6 +236,7 @@ DLLIB = @DLLIB@
 DLLTOOL = @DLLTOOL@
 DSYMUTIL = @DSYMUTIL@
 DUMPBIN = @DUMPBIN@
+EASY_INSTALL = @EASY_INSTALL@
 ECHO_C = @ECHO_C@
 ECHO_N = @ECHO_N@
 ECHO_T = @ECHO_T@
@@ -296,10 +297,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
 PLUGIN_CFLAGS = @PLUGIN_CFLAGS@
 PTHREADLIB = @PTHREADLIB@
 PYTHON = @PYTHON@
+PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@
 PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
 PYTHON_PLATFORM = @PYTHON_PLATFORM@
 PYTHON_PREFIX = @PYTHON_PREFIX@
 PYTHON_VERSION = @PYTHON_VERSION@
+PY_TEST = @PY_TEST@
 RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
@@ -373,6 +376,8 @@ json_CFLAGS = @json_CFLAGS@
 json_LIBS = @json_LIBS@
 libdir = @libdir@
 libexecdir = @libexecdir@
+libiptc_CFLAGS = @libiptc_CFLAGS@
+libiptc_LIBS = @libiptc_LIBS@
 linux_headers = @linux_headers@
 localedir = @localedir@
 localstatedir = @localstatedir@
diff --git a/src/libstrongswan/plugins/openssl/openssl_crypter.c b/src/libstrongswan/plugins/openssl/openssl_crypter.c
index 07b96b3..c2478a4 100644
--- a/src/libstrongswan/plugins/openssl/openssl_crypter.c
+++ b/src/libstrongswan/plugins/openssl/openssl_crypter.c
@@ -135,7 +135,7 @@ METHOD(crypter_t, get_block_size, size_t,
 METHOD(crypter_t, get_iv_size, size_t,
 	private_openssl_crypter_t *this)
 {
-	return this->cipher->block_size;
+	return this->cipher->iv_len;
 }
 
 METHOD(crypter_t, get_key_size, size_t,
diff --git a/src/libstrongswan/plugins/openssl/openssl_diffie_hellman.c b/src/libstrongswan/plugins/openssl/openssl_diffie_hellman.c
index ff33824..2615d60 100644
--- a/src/libstrongswan/plugins/openssl/openssl_diffie_hellman.c
+++ b/src/libstrongswan/plugins/openssl/openssl_diffie_hellman.c
@@ -38,7 +38,7 @@ struct private_openssl_diffie_hellman_t {
 	/**
 	 * Diffie Hellman group number.
 	 */
-	u_int16_t group;
+	diffie_hellman_group_t group;
 
 	/**
 	 * Diffie Hellman object
@@ -61,36 +61,42 @@ struct private_openssl_diffie_hellman_t {
 	bool computed;
 };
 
-METHOD(diffie_hellman_t, get_my_public_value, void,
+METHOD(diffie_hellman_t, get_my_public_value, bool,
 	private_openssl_diffie_hellman_t *this, chunk_t *value)
 {
 	*value = chunk_alloc(DH_size(this->dh));
 	memset(value->ptr, 0, value->len);
 	BN_bn2bin(this->dh->pub_key,
 			  value->ptr + value->len - BN_num_bytes(this->dh->pub_key));
+	return TRUE;
 }
 
-METHOD(diffie_hellman_t, get_shared_secret, status_t,
+METHOD(diffie_hellman_t, get_shared_secret, bool,
 	private_openssl_diffie_hellman_t *this, chunk_t *secret)
 {
 	if (!this->computed)
 	{
-		return FAILED;
+		return FALSE;
 	}
 	/* shared secret should requires a len according the DH group */
 	*secret = chunk_alloc(DH_size(this->dh));
 	memset(secret->ptr, 0, secret->len);
 	memcpy(secret->ptr + secret->len - this->shared_secret.len,
 		   this->shared_secret.ptr, this->shared_secret.len);
-	return SUCCESS;
+	return TRUE;
 }
 
 
-METHOD(diffie_hellman_t, set_other_public_value, void,
+METHOD(diffie_hellman_t, set_other_public_value, bool,
 	private_openssl_diffie_hellman_t *this, chunk_t value)
 {
 	int len;
 
+	if (!diffie_hellman_verify_value(this->group, value))
+	{
+		return FALSE;
+	}
+
 	BN_bin2bn(value.ptr, value.len, this->pub_key);
 	chunk_clear(&this->shared_secret);
 	this->shared_secret.ptr = malloc(DH_size(this->dh));
@@ -99,10 +105,11 @@ METHOD(diffie_hellman_t, set_other_public_value, void,
 	if (len < 0)
 	{
 		DBG1(DBG_LIB, "DH shared secret computation failed");
-		return;
+		return FALSE;
 	}
 	this->shared_secret.len = len;
 	this->computed = TRUE;
+	return TRUE;
 }
 
 METHOD(diffie_hellman_t, get_dh_group, diffie_hellman_group_t,
diff --git a/src/libstrongswan/plugins/openssl/openssl_ec_diffie_hellman.c b/src/libstrongswan/plugins/openssl/openssl_ec_diffie_hellman.c
index b487d59..550a543 100644
--- a/src/libstrongswan/plugins/openssl/openssl_ec_diffie_hellman.c
+++ b/src/libstrongswan/plugins/openssl/openssl_ec_diffie_hellman.c
@@ -40,7 +40,7 @@ struct private_openssl_ec_diffie_hellman_t {
 	/**
 	 * Diffie Hellman group number.
 	 */
-	u_int16_t group;
+	diffie_hellman_group_t group;
 
 	/**
 	 * EC private (public) key
@@ -216,40 +216,47 @@ error:
 	return ret;
 }
 
-METHOD(diffie_hellman_t, set_other_public_value, void,
+METHOD(diffie_hellman_t, set_other_public_value, bool,
 	private_openssl_ec_diffie_hellman_t *this, chunk_t value)
 {
+	if (!diffie_hellman_verify_value(this->group, value))
+	{
+		return FALSE;
+	}
+
 	if (!chunk2ecp(this->ec_group, value, this->pub_key))
 	{
 		DBG1(DBG_LIB, "ECDH public value is malformed");
-		return;
+		return FALSE;
 	}
 
 	chunk_clear(&this->shared_secret);
 
 	if (!compute_shared_key(this, &this->shared_secret)) {
 		DBG1(DBG_LIB, "ECDH shared secret computation failed");
-		return;
+		return FALSE;
 	}
 
 	this->computed = TRUE;
+	return TRUE;
 }
 
-METHOD(diffie_hellman_t, get_my_public_value, void,
+METHOD(diffie_hellman_t, get_my_public_value, bool,
 	private_openssl_ec_diffie_hellman_t *this,chunk_t *value)
 {
 	ecp2chunk(this->ec_group, EC_KEY_get0_public_key(this->key), value, FALSE);
+	return TRUE;
 }
 
-METHOD(diffie_hellman_t, get_shared_secret, status_t,
+METHOD(diffie_hellman_t, get_shared_secret, bool,
 	private_openssl_ec_diffie_hellman_t *this, chunk_t *secret)
 {
 	if (!this->computed)
 	{
-		return FAILED;
+		return FALSE;
 	}
 	*secret = chunk_clone(this->shared_secret);
-	return SUCCESS;
+	return TRUE;
 }
 
 METHOD(diffie_hellman_t, get_dh_group, diffie_hellman_group_t,
diff --git a/src/libstrongswan/plugins/padlock/Makefile.in b/src/libstrongswan/plugins/padlock/Makefile.in
index 4bd9587..44603af 100644
--- a/src/libstrongswan/plugins/padlock/Makefile.in
+++ b/src/libstrongswan/plugins/padlock/Makefile.in
@@ -229,6 +229,7 @@ DLLIB = @DLLIB@
 DLLTOOL = @DLLTOOL@
 DSYMUTIL = @DSYMUTIL@
 DUMPBIN = @DUMPBIN@
+EASY_INSTALL = @EASY_INSTALL@
 ECHO_C = @ECHO_C@
 ECHO_N = @ECHO_N@
 ECHO_T = @ECHO_T@
@@ -289,10 +290,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
 PLUGIN_CFLAGS = @PLUGIN_CFLAGS@
 PTHREADLIB = @PTHREADLIB@
 PYTHON = @PYTHON@
+PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@
 PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
 PYTHON_PLATFORM = @PYTHON_PLATFORM@
 PYTHON_PREFIX = @PYTHON_PREFIX@
 PYTHON_VERSION = @PYTHON_VERSION@
+PY_TEST = @PY_TEST@
 RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
@@ -366,6 +369,8 @@ json_CFLAGS = @json_CFLAGS@
 json_LIBS = @json_LIBS@
 libdir = @libdir@
 libexecdir = @libexecdir@
+libiptc_CFLAGS = @libiptc_CFLAGS@
+libiptc_LIBS = @libiptc_LIBS@
 linux_headers = @linux_headers@
 localedir = @localedir@
 localstatedir = @localstatedir@
diff --git a/src/libstrongswan/plugins/pem/Makefile.in b/src/libstrongswan/plugins/pem/Makefile.in
index f9c5b9b..4c982fd 100644
--- a/src/libstrongswan/plugins/pem/Makefile.in
+++ b/src/libstrongswan/plugins/pem/Makefile.in
@@ -227,6 +227,7 @@ DLLIB = @DLLIB@
 DLLTOOL = @DLLTOOL@
 DSYMUTIL = @DSYMUTIL@
 DUMPBIN = @DUMPBIN@
+EASY_INSTALL = @EASY_INSTALL@
 ECHO_C = @ECHO_C@
 ECHO_N = @ECHO_N@
 ECHO_T = @ECHO_T@
@@ -287,10 +288,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
 PLUGIN_CFLAGS = @PLUGIN_CFLAGS@
 PTHREADLIB = @PTHREADLIB@
 PYTHON = @PYTHON@
+PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@
 PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
 PYTHON_PLATFORM = @PYTHON_PLATFORM@
 PYTHON_PREFIX = @PYTHON_PREFIX@
 PYTHON_VERSION = @PYTHON_VERSION@
+PY_TEST = @PY_TEST@
 RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
@@ -364,6 +367,8 @@ json_CFLAGS = @json_CFLAGS@
 json_LIBS = @json_LIBS@
 libdir = @libdir@
 libexecdir = @libexecdir@
+libiptc_CFLAGS = @libiptc_CFLAGS@
+libiptc_LIBS = @libiptc_LIBS@
 linux_headers = @linux_headers@
 localedir = @localedir@
 localstatedir = @localstatedir@
diff --git a/src/libstrongswan/plugins/pem/pem_builder.c b/src/libstrongswan/plugins/pem/pem_builder.c
index 62780c3..f0e508a 100644
--- a/src/libstrongswan/plugins/pem/pem_builder.c
+++ b/src/libstrongswan/plugins/pem/pem_builder.c
@@ -365,6 +365,29 @@ static status_t pem_to_bin(chunk_t *blob, bool *pgp)
 }
 
 /**
+ * Check if a blob looks like an ASN1 SEQUENCE or SET with BER indefinite length
+ */
+static bool is_ber_indefinite_length(chunk_t blob)
+{
+	if (blob.len >= 4)
+	{
+		switch (blob.ptr[0])
+		{
+			case ASN1_SEQUENCE:
+			case ASN1_SET:
+				/* BER indefinite length uses 0x80, and is terminated with
+				 * end-of-content using 0x00,0x00 */
+				return blob.ptr[1] == 0x80 &&
+					   blob.ptr[blob.len - 2] == 0 &&
+					   blob.ptr[blob.len - 1] == 0;
+			default:
+				break;
+		}
+	}
+	return FALSE;
+}
+
+/**
  * load the credential from a blob
  */
 static void *load_from_blob(chunk_t blob, credential_type_t type, int subtype,
@@ -374,7 +397,7 @@ static void *load_from_blob(chunk_t blob, credential_type_t type, int subtype,
 	bool pgp = FALSE;
 
 	blob = chunk_clone(blob);
-	if (!is_asn1(blob))
+	if (!is_ber_indefinite_length(blob) && !is_asn1(blob))
 	{
 		if (pem_to_bin(&blob, &pgp) != SUCCESS)
 		{
diff --git a/src/libstrongswan/plugins/pem/pem_encoder.c b/src/libstrongswan/plugins/pem/pem_encoder.c
index df4b77c..35ea3e8 100644
--- a/src/libstrongswan/plugins/pem/pem_encoder.c
+++ b/src/libstrongswan/plugins/pem/pem_encoder.c
@@ -53,6 +53,11 @@ bool pem_encoder_encode(cred_encoding_type_t type, chunk_t *encoding,
 					break;
 				}
 			}
+			if (cred_encoding_args(args, CRED_PART_BLISS_PUB_ASN1_DER,
+								   &asn1, CRED_PART_END))
+			{
+				break;
+			}
 			return FALSE;
 		case PRIVKEY_PEM:
 			label ="RSA PRIVATE KEY";
@@ -86,6 +91,12 @@ bool pem_encoder_encode(cred_encoding_type_t type, chunk_t *encoding,
 				label ="EC PRIVATE KEY";
 				break;
 			}
+			if (cred_encoding_args(args, CRED_PART_BLISS_PRIV_ASN1_DER,
+								   &asn1, CRED_PART_END))
+			{
+				label ="BLISS PRIVATE KEY";
+				break;
+			}
 			return FALSE;
 		case CERT_PEM:
 			if (cred_encoding_args(args, CRED_PART_X509_ASN1_DER,
diff --git a/src/libstrongswan/plugins/pem/pem_plugin.c b/src/libstrongswan/plugins/pem/pem_plugin.c
index e7edd7b..d5bcbb6 100644
--- a/src/libstrongswan/plugins/pem/pem_plugin.c
+++ b/src/libstrongswan/plugins/pem/pem_plugin.c
@@ -60,6 +60,9 @@ METHOD(plugin_t, get_features, int,
 			PLUGIN_PROVIDE(PRIVKEY, KEY_DSA),
 				PLUGIN_DEPENDS(PRIVKEY, KEY_DSA),
 				PLUGIN_SDEPEND(HASHER, HASH_MD5),
+		PLUGIN_REGISTER(PRIVKEY, pem_private_key_load, FALSE),
+			PLUGIN_PROVIDE(PRIVKEY, KEY_BLISS),
+				PLUGIN_DEPENDS(PRIVKEY, KEY_BLISS),
 
 		/* public key PEM decoding */
 		PLUGIN_REGISTER(PUBKEY, pem_public_key_load, FALSE),
@@ -74,6 +77,8 @@ METHOD(plugin_t, get_features, int,
 		PLUGIN_REGISTER(PUBKEY, pem_public_key_load, FALSE),
 			PLUGIN_PROVIDE(PUBKEY, KEY_DSA),
 				PLUGIN_DEPENDS(PUBKEY, KEY_DSA),
+		PLUGIN_REGISTER(PUBKEY, pem_public_key_load, FALSE),
+			PLUGIN_PROVIDE(PUBKEY, KEY_BLISS),
 
 		/* certificate PEM decoding */
 		PLUGIN_REGISTER(CERT_DECODE, pem_certificate_load, FALSE),
diff --git a/src/libstrongswan/plugins/pgp/Makefile.in b/src/libstrongswan/plugins/pgp/Makefile.in
index 8e351c2..4d4215b 100644
--- a/src/libstrongswan/plugins/pgp/Makefile.in
+++ b/src/libstrongswan/plugins/pgp/Makefile.in
@@ -227,6 +227,7 @@ DLLIB = @DLLIB@
 DLLTOOL = @DLLTOOL@
 DSYMUTIL = @DSYMUTIL@
 DUMPBIN = @DUMPBIN@
+EASY_INSTALL = @EASY_INSTALL@
 ECHO_C = @ECHO_C@
 ECHO_N = @ECHO_N@
 ECHO_T = @ECHO_T@
@@ -287,10 +288,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
 PLUGIN_CFLAGS = @PLUGIN_CFLAGS@
 PTHREADLIB = @PTHREADLIB@
 PYTHON = @PYTHON@
+PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@
 PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
 PYTHON_PLATFORM = @PYTHON_PLATFORM@
 PYTHON_PREFIX = @PYTHON_PREFIX@
 PYTHON_VERSION = @PYTHON_VERSION@
+PY_TEST = @PY_TEST@
 RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
@@ -364,6 +367,8 @@ json_CFLAGS = @json_CFLAGS@
 json_LIBS = @json_LIBS@
 libdir = @libdir@
 libexecdir = @libexecdir@
+libiptc_CFLAGS = @libiptc_CFLAGS@
+libiptc_LIBS = @libiptc_LIBS@
 linux_headers = @linux_headers@
 localedir = @localedir@
 localstatedir = @localstatedir@
diff --git a/src/libstrongswan/plugins/pkcs1/Makefile.in b/src/libstrongswan/plugins/pkcs1/Makefile.in
index 445bc2d..2a70836 100644
--- a/src/libstrongswan/plugins/pkcs1/Makefile.in
+++ b/src/libstrongswan/plugins/pkcs1/Makefile.in
@@ -228,6 +228,7 @@ DLLIB = @DLLIB@
 DLLTOOL = @DLLTOOL@
 DSYMUTIL = @DSYMUTIL@
 DUMPBIN = @DUMPBIN@
+EASY_INSTALL = @EASY_INSTALL@
 ECHO_C = @ECHO_C@
 ECHO_N = @ECHO_N@
 ECHO_T = @ECHO_T@
@@ -288,10 +289,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
 PLUGIN_CFLAGS = @PLUGIN_CFLAGS@
 PTHREADLIB = @PTHREADLIB@
 PYTHON = @PYTHON@
+PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@
 PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
 PYTHON_PLATFORM = @PYTHON_PLATFORM@
 PYTHON_PREFIX = @PYTHON_PREFIX@
 PYTHON_VERSION = @PYTHON_VERSION@
+PY_TEST = @PY_TEST@
 RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
@@ -365,6 +368,8 @@ json_CFLAGS = @json_CFLAGS@
 json_LIBS = @json_LIBS@
 libdir = @libdir@
 libexecdir = @libexecdir@
+libiptc_CFLAGS = @libiptc_CFLAGS@
+libiptc_LIBS = @libiptc_LIBS@
 linux_headers = @linux_headers@
 localedir = @localedir@
 localstatedir = @localstatedir@
diff --git a/src/libstrongswan/plugins/pkcs1/pkcs1_builder.c b/src/libstrongswan/plugins/pkcs1/pkcs1_builder.c
index c6661fc..767b3ac 100644
--- a/src/libstrongswan/plugins/pkcs1/pkcs1_builder.c
+++ b/src/libstrongswan/plugins/pkcs1/pkcs1_builder.c
@@ -63,11 +63,18 @@ static public_key_t *parse_public_key(chunk_t blob)
 				}
 				else if (oid == OID_EC_PUBLICKEY)
 				{
-					/* we need the whole subjectPublicKeyInfo for EC public keys */
+					/* Need the whole subjectPublicKeyInfo for EC public keys */
 					key = lib->creds->create(lib->creds, CRED_PUBLIC_KEY,
 								KEY_ECDSA, BUILD_BLOB_ASN1_DER, blob, BUILD_END);
 					goto end;
 				}
+				else if (oid == OID_BLISS_PUBLICKEY)
+				{
+					/* Need the whole subjectPublicKeyInfo for BLISS public keys */
+					key = lib->creds->create(lib->creds, CRED_PUBLIC_KEY,
+								KEY_BLISS, BUILD_BLOB_ASN1_DER, blob, BUILD_END);
+					goto end;
+				}
 				else
 				{
 					/* key type not supported */
diff --git a/src/libstrongswan/plugins/pkcs11/Makefile.in b/src/libstrongswan/plugins/pkcs11/Makefile.in
index 34e8d0c..de033a3 100644
--- a/src/libstrongswan/plugins/pkcs11/Makefile.in
+++ b/src/libstrongswan/plugins/pkcs11/Makefile.in
@@ -231,6 +231,7 @@ DLLIB = @DLLIB@
 DLLTOOL = @DLLTOOL@
 DSYMUTIL = @DSYMUTIL@
 DUMPBIN = @DUMPBIN@
+EASY_INSTALL = @EASY_INSTALL@
 ECHO_C = @ECHO_C@
 ECHO_N = @ECHO_N@
 ECHO_T = @ECHO_T@
@@ -291,10 +292,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
 PLUGIN_CFLAGS = @PLUGIN_CFLAGS@
 PTHREADLIB = @PTHREADLIB@
 PYTHON = @PYTHON@
+PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@
 PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
 PYTHON_PLATFORM = @PYTHON_PLATFORM@
 PYTHON_PREFIX = @PYTHON_PREFIX@
 PYTHON_VERSION = @PYTHON_VERSION@
+PY_TEST = @PY_TEST@
 RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
@@ -368,6 +371,8 @@ json_CFLAGS = @json_CFLAGS@
 json_LIBS = @json_LIBS@
 libdir = @libdir@
 libexecdir = @libexecdir@
+libiptc_CFLAGS = @libiptc_CFLAGS@
+libiptc_LIBS = @libiptc_LIBS@
 linux_headers = @linux_headers@
 localedir = @localedir@
 localstatedir = @localstatedir@
diff --git a/src/libstrongswan/plugins/pkcs11/pkcs11_dh.c b/src/libstrongswan/plugins/pkcs11/pkcs11_dh.c
index 36cc284..c0033bd 100644
--- a/src/libstrongswan/plugins/pkcs11/pkcs11_dh.c
+++ b/src/libstrongswan/plugins/pkcs11/pkcs11_dh.c
@@ -47,7 +47,7 @@ struct private_pkcs11_dh_t {
 	/**
 	 * Diffie Hellman group number.
 	 */
-	u_int16_t group;
+	diffie_hellman_group_t group;
 
 	/**
 	 * Handle for own private value
@@ -81,7 +81,7 @@ struct private_pkcs11_dh_t {
  *
  * If this succeeds the shared secret is stored in this->secret.
  */
-static void derive_secret(private_pkcs11_dh_t *this, chunk_t other)
+static bool derive_secret(private_pkcs11_dh_t *this, chunk_t other)
 {
 	CK_OBJECT_CLASS klass = CKO_SECRET_KEY;
 	CK_KEY_TYPE type = CKK_GENERIC_SECRET;
@@ -102,19 +102,25 @@ static void derive_secret(private_pkcs11_dh_t *this, chunk_t other)
 	if (rv != CKR_OK)
 	{
 		DBG1(DBG_CFG, "C_DeriveKey() error: %N", ck_rv_names, rv);
-		return;
+		return FALSE;
 	}
 	if (!this->lib->get_ck_attribute(this->lib, this->session, secret,
 									 CKA_VALUE, &this->secret))
 	{
 		chunk_free(&this->secret);
-		return;
+		return FALSE;
 	}
+	return TRUE;
 }
 
-METHOD(diffie_hellman_t, set_other_public_value, void,
+METHOD(diffie_hellman_t, set_other_public_value, bool,
 	private_pkcs11_dh_t *this, chunk_t value)
 {
+	if (!diffie_hellman_verify_value(this->group, value))
+	{
+		return FALSE;
+	}
+
 	switch (this->group)
 	{
 		case ECP_192_BIT:
@@ -137,7 +143,7 @@ METHOD(diffie_hellman_t, set_other_public_value, void,
 			if (!lib->settings->get_bool(lib->settings,
 									"%s.ecp_x_coordinate_only", TRUE, lib->ns))
 			{	/* we only get the x coordinate back */
-				return;
+				return FALSE;
 			}
 			value = chunk_from_thing(params);
 			break;
@@ -145,24 +151,25 @@ METHOD(diffie_hellman_t, set_other_public_value, void,
 		default:
 			break;
 	}
-	derive_secret(this, value);
+	return derive_secret(this, value);
 }
 
-METHOD(diffie_hellman_t, get_my_public_value, void,
+METHOD(diffie_hellman_t, get_my_public_value, bool,
 	private_pkcs11_dh_t *this, chunk_t *value)
 {
 	*value = chunk_clone(this->pub_key);
+	return TRUE;
 }
 
-METHOD(diffie_hellman_t, get_shared_secret, status_t,
+METHOD(diffie_hellman_t, get_shared_secret, bool,
 	private_pkcs11_dh_t *this, chunk_t *secret)
 {
 	if (!this->secret.ptr)
 	{
-		return FAILED;
+		return FALSE;
 	}
 	*secret = chunk_clone(this->secret);
-	return SUCCESS;
+	return TRUE;
 }
 
 METHOD(diffie_hellman_t, get_dh_group, diffie_hellman_group_t,
@@ -443,4 +450,3 @@ pkcs11_dh_t *pkcs11_dh_create(diffie_hellman_group_t group,
 	}
 	return NULL;
 }
-
diff --git a/src/libstrongswan/plugins/pkcs11/pkcs11_library.c b/src/libstrongswan/plugins/pkcs11/pkcs11_library.c
index 7661473..dc8a1f1 100644
--- a/src/libstrongswan/plugins/pkcs11/pkcs11_library.c
+++ b/src/libstrongswan/plugins/pkcs11/pkcs11_library.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2011 Tobias Brunner
+ * Copyright (C) 2011-2015 Tobias Brunner
  * Hochschule fuer Technik Rapperswil
  *
  * Copyright (C) 2010 Martin Willi
@@ -21,6 +21,7 @@
 #include <dlfcn.h>
 
 #include <library.h>
+#include <asn1/asn1.h>
 #include <utils/debug.h>
 #include <threading/mutex.h>
 #include <collections/linked_list.h>
@@ -641,10 +642,37 @@ static void free_attrs(object_enumerator_t *this)
 }
 
 /**
+ * CKA_EC_POINT is encodeed as ASN.1 octet string, we can't handle that and
+ * some tokens actually return them even unwrapped.
+ *
+ * Because ASN1_OCTET_STRING is 0x04 and uncompressed EC_POINTs also begin with
+ * 0x04 (compressed ones with 0x02 or 0x03) there will be an attempt to parse
+ * unwrapped uncompressed EC_POINTs.  This will fail in most cases as the length
+ * will not be correct, however, there is a small chance that the key's first
+ * byte denotes the correct length.  Checking the first byte of the key should
+ * further reduce the risk of false positives, though.
+ *
+ * The original memory is freed if the value is unwrapped.
+ */
+static void unwrap_ec_point(chunk_t *data)
+{
+	chunk_t wrapped, unwrapped;
+
+	wrapped = unwrapped = *data;
+	if (asn1_unwrap(&unwrapped, &unwrapped) == ASN1_OCTET_STRING &&
+		unwrapped.len && unwrapped.ptr[0] >= 0x02 && unwrapped.ptr[0] <= 0x04)
+	{
+		*data = chunk_clone(unwrapped);
+		free(wrapped.ptr);
+	}
+}
+
+/**
  * Get attributes for a given object during enumeration
  */
 static bool get_attributes(object_enumerator_t *this, CK_OBJECT_HANDLE object)
 {
+	chunk_t data;
 	CK_RV rv;
 	int i;
 
@@ -677,6 +705,16 @@ static bool get_attributes(object_enumerator_t *this, CK_OBJECT_HANDLE object)
 		DBG1(DBG_CFG, "C_GetAttributeValue() error: %N", ck_rv_names, rv);
 		return FALSE;
 	}
+	for (i = 0; i < this->count; i++)
+	{
+		if (this->attr[i].type == CKA_EC_POINT)
+		{
+			data = chunk_create(this->attr[i].pValue, this->attr[i].ulValueLen);
+			unwrap_ec_point(&data);
+			this->attr[i].pValue = data.ptr;
+			this->attr[i].ulValueLen = data.len;
+		}
+	}
 	return TRUE;
 }
 
@@ -887,6 +925,10 @@ METHOD(pkcs11_library_t, get_ck_attribute, bool,
 		chunk_free(data);
 		return FALSE;
 	}
+	if (attr.type == CKA_EC_POINT)
+	{
+		unwrap_ec_point(data);
+	}
 	return TRUE;
 }
 
diff --git a/src/libstrongswan/plugins/pkcs11/pkcs11_private_key.c b/src/libstrongswan/plugins/pkcs11/pkcs11_private_key.c
index bb9cc7a..bfc5459 100644
--- a/src/libstrongswan/plugins/pkcs11/pkcs11_private_key.c
+++ b/src/libstrongswan/plugins/pkcs11/pkcs11_private_key.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2011 Tobias Brunner
+ * Copyright (C) 2011-2015 Tobias Brunner
  * Hochschule fuer Technik Rapperswil
  *
  * Copyright (C) 2010 Martin Willi
@@ -23,6 +23,7 @@
 #include "pkcs11_public_key.h"
 
 #include <utils/debug.h>
+#include <asn1/asn1.h>
 
 typedef struct private_pkcs11_private_key_t private_pkcs11_private_key_t;
 
@@ -288,7 +289,23 @@ METHOD(private_key_t, sign, bool,
 		free(buf);
 		return FALSE;
 	}
-	*signature = chunk_create(buf, len);
+	switch (scheme)
+	{
+		case SIGN_ECDSA_WITH_SHA1_DER:
+		case SIGN_ECDSA_WITH_SHA256_DER:
+		case SIGN_ECDSA_WITH_SHA384_DER:
+		case SIGN_ECDSA_WITH_SHA512_DER:
+			/* return an ASN.1 encoded sequence of integers r and s */
+			len /= 2;
+			*signature = asn1_wrap(ASN1_SEQUENCE, "mm",
+								asn1_integer("c", chunk_create(buf, len)),
+								asn1_integer("c", chunk_create(buf+len, len)));
+			free(buf);
+			break;
+		default:
+			*signature = chunk_create(buf, len);
+			break;
+	}
 	return TRUE;
 }
 
diff --git a/src/libstrongswan/plugins/pkcs11/pkcs11_public_key.c b/src/libstrongswan/plugins/pkcs11/pkcs11_public_key.c
index 0302c0e..6d52116 100644
--- a/src/libstrongswan/plugins/pkcs11/pkcs11_public_key.c
+++ b/src/libstrongswan/plugins/pkcs11/pkcs11_public_key.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2011 Tobias Brunner
+ * Copyright (C) 2011-2015 Tobias Brunner
  * Hochschule fuer Technik Rapperswil
  *
  * Copyright (C) 2010 Martin Willi
@@ -135,6 +135,7 @@ static const asn1Object_t pkinfoObjects[] = {
 /**
  * Extract the DER encoded Parameters and ECPoint from the given DER encoded
  * subjectPublicKeyInfo.
+ * Memory for ecpoint is allocated.
  */
 static bool parse_ecdsa_public_key(chunk_t blob, chunk_t *ecparams,
 								   chunk_t *ecpoint, size_t *keylen)
@@ -173,7 +174,9 @@ static bool parse_ecdsa_public_key(chunk_t blob, chunk_t *ecparams,
 				{	/* skip initial bit string octet defining 0 unused bits */
 					object = chunk_skip(object, 1);
 				}
-				*ecpoint = object;
+				/* the correct way to encode an EC_POINT in PKCS#11 is as
+				 * ASN.1 octet string */
+				*ecpoint = asn1_wrap(ASN1_OCTET_STRING, "c", object);
 				break;
 			}
 		}
@@ -205,7 +208,8 @@ METHOD(public_key_t, verify, bool,
 	CK_SESSION_HANDLE session;
 	CK_RV rv;
 	hash_algorithm_t hash_alg;
-	chunk_t hash = chunk_empty;
+	chunk_t hash = chunk_empty, parse, r, s;
+	size_t len;
 
 	mechanism = pkcs11_signature_scheme_to_mech(scheme, this->type, this->k,
 												&hash_alg);
@@ -215,9 +219,37 @@ METHOD(public_key_t, verify, bool,
 			 signature_scheme_names, scheme);
 		return FALSE;
 	}
-	if (sig.len && sig.ptr[0] == 0)
-	{	/* trim leading zero byte in sig */
-		sig = chunk_skip(sig, 1);
+	switch (scheme)
+	{
+		case SIGN_ECDSA_WITH_SHA1_DER:
+		case SIGN_ECDSA_WITH_SHA256_DER:
+		case SIGN_ECDSA_WITH_SHA384_DER:
+		case SIGN_ECDSA_WITH_SHA512_DER:
+			/* PKCS#11 expects the ECDSA signatures as simple concatenation of
+			 * r and s, so unwrap the ASN.1 encoded sequence */
+			parse = sig;
+			if (asn1_unwrap(&parse, &parse) != ASN1_SEQUENCE ||
+				asn1_unwrap(&parse, &r) != ASN1_INTEGER ||
+				asn1_unwrap(&parse, &s) != ASN1_INTEGER)
+			{
+				return FALSE;
+			}
+			r = chunk_skip_zero(r);
+			s = chunk_skip_zero(s);
+			len = (get_keysize(this) + 7) / 8;
+			if (r.len > len || s.len > len)
+			{
+				return FALSE;
+			}
+			/* concatenate r and s (forced to the defined length) */
+			sig = chunk_alloca(2*len);
+			memset(sig.ptr, 0, sig.len);
+			memcpy(sig.ptr + (len - r.len), r.ptr, r.len);
+			memcpy(sig.ptr + len + (len - s.len), s.ptr, s.len);
+			break;
+		default:
+			sig = chunk_skip_zero(sig);
+			break;
 	}
 	rv = this->lib->f->C_OpenSession(this->slot, CKF_SERIAL_SESSION, NULL, NULL,
 									 &session);
@@ -776,11 +808,11 @@ pkcs11_public_key_t *pkcs11_public_key_load(key_type_t type, va_list args)
 		if (parse_ecdsa_public_key(blob, &ecparams, &ecpoint, &keylen))
 		{
 			this = find_ecdsa_key(ecparams, ecpoint, keylen);
-			if (this)
+			if (!this)
 			{
-				return &this->public;
+				this = create_ecdsa_key(ecparams, ecpoint, keylen);
 			}
-			this = create_ecdsa_key(ecparams, ecpoint, keylen);
+			chunk_free(&ecpoint);
 			if (this)
 			{
 				return &this->public;
diff --git a/src/libstrongswan/plugins/pkcs12/Makefile.in b/src/libstrongswan/plugins/pkcs12/Makefile.in
index d90cd35..3fa0a38 100644
--- a/src/libstrongswan/plugins/pkcs12/Makefile.in
+++ b/src/libstrongswan/plugins/pkcs12/Makefile.in
@@ -228,6 +228,7 @@ DLLIB = @DLLIB@
 DLLTOOL = @DLLTOOL@
 DSYMUTIL = @DSYMUTIL@
 DUMPBIN = @DUMPBIN@
+EASY_INSTALL = @EASY_INSTALL@
 ECHO_C = @ECHO_C@
 ECHO_N = @ECHO_N@
 ECHO_T = @ECHO_T@
@@ -288,10 +289,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
 PLUGIN_CFLAGS = @PLUGIN_CFLAGS@
 PTHREADLIB = @PTHREADLIB@
 PYTHON = @PYTHON@
+PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@
 PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
 PYTHON_PLATFORM = @PYTHON_PLATFORM@
 PYTHON_PREFIX = @PYTHON_PREFIX@
 PYTHON_VERSION = @PYTHON_VERSION@
+PY_TEST = @PY_TEST@
 RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
@@ -365,6 +368,8 @@ json_CFLAGS = @json_CFLAGS@
 json_LIBS = @json_LIBS@
 libdir = @libdir@
 libexecdir = @libexecdir@
+libiptc_CFLAGS = @libiptc_CFLAGS@
+libiptc_LIBS = @libiptc_LIBS@
 linux_headers = @linux_headers@
 localedir = @localedir@
 localstatedir = @localstatedir@
diff --git a/src/libstrongswan/plugins/pkcs7/Makefile.in b/src/libstrongswan/plugins/pkcs7/Makefile.in
index f6534f0..3266e5d 100644
--- a/src/libstrongswan/plugins/pkcs7/Makefile.in
+++ b/src/libstrongswan/plugins/pkcs7/Makefile.in
@@ -230,6 +230,7 @@ DLLIB = @DLLIB@
 DLLTOOL = @DLLTOOL@
 DSYMUTIL = @DSYMUTIL@
 DUMPBIN = @DUMPBIN@
+EASY_INSTALL = @EASY_INSTALL@
 ECHO_C = @ECHO_C@
 ECHO_N = @ECHO_N@
 ECHO_T = @ECHO_T@
@@ -290,10 +291,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
 PLUGIN_CFLAGS = @PLUGIN_CFLAGS@
 PTHREADLIB = @PTHREADLIB@
 PYTHON = @PYTHON@
+PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@
 PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
 PYTHON_PLATFORM = @PYTHON_PLATFORM@
 PYTHON_PREFIX = @PYTHON_PREFIX@
 PYTHON_VERSION = @PYTHON_VERSION@
+PY_TEST = @PY_TEST@
 RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
@@ -367,6 +370,8 @@ json_CFLAGS = @json_CFLAGS@
 json_LIBS = @json_LIBS@
 libdir = @libdir@
 libexecdir = @libexecdir@
+libiptc_CFLAGS = @libiptc_CFLAGS@
+libiptc_LIBS = @libiptc_LIBS@
 linux_headers = @linux_headers@
 localedir = @localedir@
 localstatedir = @localstatedir@
diff --git a/src/libstrongswan/plugins/pkcs8/Makefile.in b/src/libstrongswan/plugins/pkcs8/Makefile.in
index 0756db8..2130c9c 100644
--- a/src/libstrongswan/plugins/pkcs8/Makefile.in
+++ b/src/libstrongswan/plugins/pkcs8/Makefile.in
@@ -227,6 +227,7 @@ DLLIB = @DLLIB@
 DLLTOOL = @DLLTOOL@
 DSYMUTIL = @DSYMUTIL@
 DUMPBIN = @DUMPBIN@
+EASY_INSTALL = @EASY_INSTALL@
 ECHO_C = @ECHO_C@
 ECHO_N = @ECHO_N@
 ECHO_T = @ECHO_T@
@@ -287,10 +288,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
 PLUGIN_CFLAGS = @PLUGIN_CFLAGS@
 PTHREADLIB = @PTHREADLIB@
 PYTHON = @PYTHON@
+PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@
 PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
 PYTHON_PLATFORM = @PYTHON_PLATFORM@
 PYTHON_PREFIX = @PYTHON_PREFIX@
 PYTHON_VERSION = @PYTHON_VERSION@
+PY_TEST = @PY_TEST@
 RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
@@ -364,6 +367,8 @@ json_CFLAGS = @json_CFLAGS@
 json_LIBS = @json_LIBS@
 libdir = @libdir@
 libexecdir = @libexecdir@
+libiptc_CFLAGS = @libiptc_CFLAGS@
+libiptc_LIBS = @libiptc_LIBS@
 linux_headers = @linux_headers@
 localedir = @localedir@
 localstatedir = @localstatedir@
diff --git a/src/libstrongswan/plugins/plugin_loader.c b/src/libstrongswan/plugins/plugin_loader.c
index 1fec1b3..f7ac347 100644
--- a/src/libstrongswan/plugins/plugin_loader.c
+++ b/src/libstrongswan/plugins/plugin_loader.c
@@ -380,7 +380,15 @@ static plugin_entry_t *load_plugin(private_plugin_loader_t *this, char *name,
 			return NULL;
 		}
 	}
-	handle = dlopen(file, RTLD_LAZY);
+	handle = dlopen(file, RTLD_LAZY
+#ifdef RTLD_NODELETE
+	/* if supported, do not unload library when unloading a plugin. It really
+	 * doesn't matter in productive systems, but causes many (dependency)
+	 * library reloads during unit tests. Some libraries can't handle that,
+	 * GnuTLS leaks file descriptors in its library load/unload functions. */
+					| RTLD_NODELETE
+#endif
+					);
 	if (handle == NULL)
 	{
 		DBG1(DBG_LIB, "plugin '%s' failed to load: %s", name, dlerror());
@@ -1283,9 +1291,9 @@ METHOD(plugin_loader_t, status, void,
 
 		if (this->stats.failed)
 		{
-			dbg(DBG_LIB, level, "unable to load %d plugin feature%s (%d due to "
-				"unmet dependencies)", this->stats.failed,
-				this->stats.failed == 1 ? "" : "s", this->stats.depends);
+			DBG2(DBG_LIB, "unable to load %d plugin feature%s (%d due to unmet "
+				 "dependencies)", this->stats.failed,
+				 this->stats.failed == 1 ? "" : "s", this->stats.depends);
 		}
 	}
 }
diff --git a/src/libstrongswan/plugins/pubkey/Makefile.in b/src/libstrongswan/plugins/pubkey/Makefile.in
index fcdbe94..a9f3dd1 100644
--- a/src/libstrongswan/plugins/pubkey/Makefile.in
+++ b/src/libstrongswan/plugins/pubkey/Makefile.in
@@ -228,6 +228,7 @@ DLLIB = @DLLIB@
 DLLTOOL = @DLLTOOL@
 DSYMUTIL = @DSYMUTIL@
 DUMPBIN = @DUMPBIN@
+EASY_INSTALL = @EASY_INSTALL@
 ECHO_C = @ECHO_C@
 ECHO_N = @ECHO_N@
 ECHO_T = @ECHO_T@
@@ -288,10 +289,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
 PLUGIN_CFLAGS = @PLUGIN_CFLAGS@
 PTHREADLIB = @PTHREADLIB@
 PYTHON = @PYTHON@
+PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@
 PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
 PYTHON_PLATFORM = @PYTHON_PLATFORM@
 PYTHON_PREFIX = @PYTHON_PREFIX@
 PYTHON_VERSION = @PYTHON_VERSION@
+PY_TEST = @PY_TEST@
 RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
@@ -365,6 +368,8 @@ json_CFLAGS = @json_CFLAGS@
 json_LIBS = @json_LIBS@
 libdir = @libdir@
 libexecdir = @libexecdir@
+libiptc_CFLAGS = @libiptc_CFLAGS@
+libiptc_LIBS = @libiptc_LIBS@
 linux_headers = @linux_headers@
 localedir = @localedir@
 localstatedir = @localstatedir@
diff --git a/src/libstrongswan/plugins/random/Makefile.in b/src/libstrongswan/plugins/random/Makefile.in
index fb6c9ae..11a1346 100644
--- a/src/libstrongswan/plugins/random/Makefile.in
+++ b/src/libstrongswan/plugins/random/Makefile.in
@@ -228,6 +228,7 @@ DLLIB = @DLLIB@
 DLLTOOL = @DLLTOOL@
 DSYMUTIL = @DSYMUTIL@
 DUMPBIN = @DUMPBIN@
+EASY_INSTALL = @EASY_INSTALL@
 ECHO_C = @ECHO_C@
 ECHO_N = @ECHO_N@
 ECHO_T = @ECHO_T@
@@ -288,10 +289,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
 PLUGIN_CFLAGS = @PLUGIN_CFLAGS@
 PTHREADLIB = @PTHREADLIB@
 PYTHON = @PYTHON@
+PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@
 PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
 PYTHON_PLATFORM = @PYTHON_PLATFORM@
 PYTHON_PREFIX = @PYTHON_PREFIX@
 PYTHON_VERSION = @PYTHON_VERSION@
+PY_TEST = @PY_TEST@
 RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
@@ -365,6 +368,8 @@ json_CFLAGS = @json_CFLAGS@
 json_LIBS = @json_LIBS@
 libdir = @libdir@
 libexecdir = @libexecdir@
+libiptc_CFLAGS = @libiptc_CFLAGS@
+libiptc_LIBS = @libiptc_LIBS@
 linux_headers = @linux_headers@
 localedir = @localedir@
 localstatedir = @localstatedir@
diff --git a/src/libstrongswan/plugins/rc2/Makefile.in b/src/libstrongswan/plugins/rc2/Makefile.in
index d84b1ba..b81acef 100644
--- a/src/libstrongswan/plugins/rc2/Makefile.in
+++ b/src/libstrongswan/plugins/rc2/Makefile.in
@@ -226,6 +226,7 @@ DLLIB = @DLLIB@
 DLLTOOL = @DLLTOOL@
 DSYMUTIL = @DSYMUTIL@
 DUMPBIN = @DUMPBIN@
+EASY_INSTALL = @EASY_INSTALL@
 ECHO_C = @ECHO_C@
 ECHO_N = @ECHO_N@
 ECHO_T = @ECHO_T@
@@ -286,10 +287,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
 PLUGIN_CFLAGS = @PLUGIN_CFLAGS@
 PTHREADLIB = @PTHREADLIB@
 PYTHON = @PYTHON@
+PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@
 PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
 PYTHON_PLATFORM = @PYTHON_PLATFORM@
 PYTHON_PREFIX = @PYTHON_PREFIX@
 PYTHON_VERSION = @PYTHON_VERSION@
+PY_TEST = @PY_TEST@
 RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
@@ -363,6 +366,8 @@ json_CFLAGS = @json_CFLAGS@
 json_LIBS = @json_LIBS@
 libdir = @libdir@
 libexecdir = @libexecdir@
+libiptc_CFLAGS = @libiptc_CFLAGS@
+libiptc_LIBS = @libiptc_LIBS@
 linux_headers = @linux_headers@
 localedir = @localedir@
 localstatedir = @localstatedir@
diff --git a/src/libstrongswan/plugins/rdrand/Makefile.in b/src/libstrongswan/plugins/rdrand/Makefile.in
index 967e862..028464b 100644
--- a/src/libstrongswan/plugins/rdrand/Makefile.in
+++ b/src/libstrongswan/plugins/rdrand/Makefile.in
@@ -228,6 +228,7 @@ DLLIB = @DLLIB@
 DLLTOOL = @DLLTOOL@
 DSYMUTIL = @DSYMUTIL@
 DUMPBIN = @DUMPBIN@
+EASY_INSTALL = @EASY_INSTALL@
 ECHO_C = @ECHO_C@
 ECHO_N = @ECHO_N@
 ECHO_T = @ECHO_T@
@@ -288,10 +289,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
 PLUGIN_CFLAGS = @PLUGIN_CFLAGS@
 PTHREADLIB = @PTHREADLIB@
 PYTHON = @PYTHON@
+PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@
 PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
 PYTHON_PLATFORM = @PYTHON_PLATFORM@
 PYTHON_PREFIX = @PYTHON_PREFIX@
 PYTHON_VERSION = @PYTHON_VERSION@
+PY_TEST = @PY_TEST@
 RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
@@ -365,6 +368,8 @@ json_CFLAGS = @json_CFLAGS@
 json_LIBS = @json_LIBS@
 libdir = @libdir@
 libexecdir = @libexecdir@
+libiptc_CFLAGS = @libiptc_CFLAGS@
+libiptc_LIBS = @libiptc_LIBS@
 linux_headers = @linux_headers@
 localedir = @localedir@
 localstatedir = @localstatedir@
diff --git a/src/libstrongswan/plugins/revocation/Makefile.in b/src/libstrongswan/plugins/revocation/Makefile.in
index 1274826..342c544 100644
--- a/src/libstrongswan/plugins/revocation/Makefile.in
+++ b/src/libstrongswan/plugins/revocation/Makefile.in
@@ -229,6 +229,7 @@ DLLIB = @DLLIB@
 DLLTOOL = @DLLTOOL@
 DSYMUTIL = @DSYMUTIL@
 DUMPBIN = @DUMPBIN@
+EASY_INSTALL = @EASY_INSTALL@
 ECHO_C = @ECHO_C@
 ECHO_N = @ECHO_N@
 ECHO_T = @ECHO_T@
@@ -289,10 +290,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
 PLUGIN_CFLAGS = @PLUGIN_CFLAGS@
 PTHREADLIB = @PTHREADLIB@
 PYTHON = @PYTHON@
+PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@
 PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
 PYTHON_PLATFORM = @PYTHON_PLATFORM@
 PYTHON_PREFIX = @PYTHON_PREFIX@
 PYTHON_VERSION = @PYTHON_VERSION@
+PY_TEST = @PY_TEST@
 RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
@@ -366,6 +369,8 @@ json_CFLAGS = @json_CFLAGS@
 json_LIBS = @json_LIBS@
 libdir = @libdir@
 libexecdir = @libexecdir@
+libiptc_CFLAGS = @libiptc_CFLAGS@
+libiptc_LIBS = @libiptc_LIBS@
 linux_headers = @linux_headers@
 localedir = @localedir@
 localstatedir = @localstatedir@
diff --git a/src/libstrongswan/plugins/sha1/Makefile.in b/src/libstrongswan/plugins/sha1/Makefile.in
index 70a98b0..18771e4 100644
--- a/src/libstrongswan/plugins/sha1/Makefile.in
+++ b/src/libstrongswan/plugins/sha1/Makefile.in
@@ -227,6 +227,7 @@ DLLIB = @DLLIB@
 DLLTOOL = @DLLTOOL@
 DSYMUTIL = @DSYMUTIL@
 DUMPBIN = @DUMPBIN@
+EASY_INSTALL = @EASY_INSTALL@
 ECHO_C = @ECHO_C@
 ECHO_N = @ECHO_N@
 ECHO_T = @ECHO_T@
@@ -287,10 +288,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
 PLUGIN_CFLAGS = @PLUGIN_CFLAGS@
 PTHREADLIB = @PTHREADLIB@
 PYTHON = @PYTHON@
+PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@
 PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
 PYTHON_PLATFORM = @PYTHON_PLATFORM@
 PYTHON_PREFIX = @PYTHON_PREFIX@
 PYTHON_VERSION = @PYTHON_VERSION@
+PY_TEST = @PY_TEST@
 RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
@@ -364,6 +367,8 @@ json_CFLAGS = @json_CFLAGS@
 json_LIBS = @json_LIBS@
 libdir = @libdir@
 libexecdir = @libexecdir@
+libiptc_CFLAGS = @libiptc_CFLAGS@
+libiptc_LIBS = @libiptc_LIBS@
 linux_headers = @linux_headers@
 localedir = @localedir@
 localstatedir = @localstatedir@
diff --git a/src/libstrongswan/plugins/sha2/Makefile.in b/src/libstrongswan/plugins/sha2/Makefile.in
index f7d11be..6aaa06b 100644
--- a/src/libstrongswan/plugins/sha2/Makefile.in
+++ b/src/libstrongswan/plugins/sha2/Makefile.in
@@ -226,6 +226,7 @@ DLLIB = @DLLIB@
 DLLTOOL = @DLLTOOL@
 DSYMUTIL = @DSYMUTIL@
 DUMPBIN = @DUMPBIN@
+EASY_INSTALL = @EASY_INSTALL@
 ECHO_C = @ECHO_C@
 ECHO_N = @ECHO_N@
 ECHO_T = @ECHO_T@
@@ -286,10 +287,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
 PLUGIN_CFLAGS = @PLUGIN_CFLAGS@
 PTHREADLIB = @PTHREADLIB@
 PYTHON = @PYTHON@
+PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@
 PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
 PYTHON_PLATFORM = @PYTHON_PLATFORM@
 PYTHON_PREFIX = @PYTHON_PREFIX@
 PYTHON_VERSION = @PYTHON_VERSION@
+PY_TEST = @PY_TEST@
 RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
@@ -363,6 +366,8 @@ json_CFLAGS = @json_CFLAGS@
 json_LIBS = @json_LIBS@
 libdir = @libdir@
 libexecdir = @libexecdir@
+libiptc_CFLAGS = @libiptc_CFLAGS@
+libiptc_LIBS = @libiptc_LIBS@
 linux_headers = @linux_headers@
 localedir = @localedir@
 localstatedir = @localstatedir@
diff --git a/src/libstrongswan/plugins/soup/Makefile.in b/src/libstrongswan/plugins/soup/Makefile.in
index ee96f08..02290b4 100644
--- a/src/libstrongswan/plugins/soup/Makefile.in
+++ b/src/libstrongswan/plugins/soup/Makefile.in
@@ -227,6 +227,7 @@ DLLIB = @DLLIB@
 DLLTOOL = @DLLTOOL@
 DSYMUTIL = @DSYMUTIL@
 DUMPBIN = @DUMPBIN@
+EASY_INSTALL = @EASY_INSTALL@
 ECHO_C = @ECHO_C@
 ECHO_N = @ECHO_N@
 ECHO_T = @ECHO_T@
@@ -287,10 +288,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
 PLUGIN_CFLAGS = @PLUGIN_CFLAGS@
 PTHREADLIB = @PTHREADLIB@
 PYTHON = @PYTHON@
+PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@
 PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
 PYTHON_PLATFORM = @PYTHON_PLATFORM@
 PYTHON_PREFIX = @PYTHON_PREFIX@
 PYTHON_VERSION = @PYTHON_VERSION@
+PY_TEST = @PY_TEST@
 RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
@@ -364,6 +367,8 @@ json_CFLAGS = @json_CFLAGS@
 json_LIBS = @json_LIBS@
 libdir = @libdir@
 libexecdir = @libexecdir@
+libiptc_CFLAGS = @libiptc_CFLAGS@
+libiptc_LIBS = @libiptc_LIBS@
 linux_headers = @linux_headers@
 localedir = @localedir@
 localstatedir = @localstatedir@
diff --git a/src/libstrongswan/plugins/sqlite/Makefile.in b/src/libstrongswan/plugins/sqlite/Makefile.in
index b9f949b..3e234f1 100644
--- a/src/libstrongswan/plugins/sqlite/Makefile.in
+++ b/src/libstrongswan/plugins/sqlite/Makefile.in
@@ -229,6 +229,7 @@ DLLIB = @DLLIB@
 DLLTOOL = @DLLTOOL@
 DSYMUTIL = @DSYMUTIL@
 DUMPBIN = @DUMPBIN@
+EASY_INSTALL = @EASY_INSTALL@
 ECHO_C = @ECHO_C@
 ECHO_N = @ECHO_N@
 ECHO_T = @ECHO_T@
@@ -289,10 +290,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
 PLUGIN_CFLAGS = @PLUGIN_CFLAGS@
 PTHREADLIB = @PTHREADLIB@
 PYTHON = @PYTHON@
+PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@
 PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
 PYTHON_PLATFORM = @PYTHON_PLATFORM@
 PYTHON_PREFIX = @PYTHON_PREFIX@
 PYTHON_VERSION = @PYTHON_VERSION@
+PY_TEST = @PY_TEST@
 RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
@@ -366,6 +369,8 @@ json_CFLAGS = @json_CFLAGS@
 json_LIBS = @json_LIBS@
 libdir = @libdir@
 libexecdir = @libexecdir@
+libiptc_CFLAGS = @libiptc_CFLAGS@
+libiptc_LIBS = @libiptc_LIBS@
 linux_headers = @linux_headers@
 localedir = @localedir@
 localstatedir = @localstatedir@
diff --git a/src/libstrongswan/plugins/sshkey/Makefile.in b/src/libstrongswan/plugins/sshkey/Makefile.in
index b66302e..a8d5a10 100644
--- a/src/libstrongswan/plugins/sshkey/Makefile.in
+++ b/src/libstrongswan/plugins/sshkey/Makefile.in
@@ -229,6 +229,7 @@ DLLIB = @DLLIB@
 DLLTOOL = @DLLTOOL@
 DSYMUTIL = @DSYMUTIL@
 DUMPBIN = @DUMPBIN@
+EASY_INSTALL = @EASY_INSTALL@
 ECHO_C = @ECHO_C@
 ECHO_N = @ECHO_N@
 ECHO_T = @ECHO_T@
@@ -289,10 +290,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
 PLUGIN_CFLAGS = @PLUGIN_CFLAGS@
 PTHREADLIB = @PTHREADLIB@
 PYTHON = @PYTHON@
+PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@
 PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
 PYTHON_PLATFORM = @PYTHON_PLATFORM@
 PYTHON_PREFIX = @PYTHON_PREFIX@
 PYTHON_VERSION = @PYTHON_VERSION@
+PY_TEST = @PY_TEST@
 RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
@@ -366,6 +369,8 @@ json_CFLAGS = @json_CFLAGS@
 json_LIBS = @json_LIBS@
 libdir = @libdir@
 libexecdir = @libexecdir@
+libiptc_CFLAGS = @libiptc_CFLAGS@
+libiptc_LIBS = @libiptc_LIBS@
 linux_headers = @linux_headers@
 localedir = @localedir@
 localstatedir = @localstatedir@
diff --git a/src/libstrongswan/plugins/test_vectors/Makefile.in b/src/libstrongswan/plugins/test_vectors/Makefile.in
index 8d7c667..8980ec4 100644
--- a/src/libstrongswan/plugins/test_vectors/Makefile.in
+++ b/src/libstrongswan/plugins/test_vectors/Makefile.in
@@ -243,6 +243,7 @@ DLLIB = @DLLIB@
 DLLTOOL = @DLLTOOL@
 DSYMUTIL = @DSYMUTIL@
 DUMPBIN = @DUMPBIN@
+EASY_INSTALL = @EASY_INSTALL@
 ECHO_C = @ECHO_C@
 ECHO_N = @ECHO_N@
 ECHO_T = @ECHO_T@
@@ -303,10 +304,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
 PLUGIN_CFLAGS = @PLUGIN_CFLAGS@
 PTHREADLIB = @PTHREADLIB@
 PYTHON = @PYTHON@
+PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@
 PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
 PYTHON_PLATFORM = @PYTHON_PLATFORM@
 PYTHON_PREFIX = @PYTHON_PREFIX@
 PYTHON_VERSION = @PYTHON_VERSION@
+PY_TEST = @PY_TEST@
 RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
@@ -380,6 +383,8 @@ json_CFLAGS = @json_CFLAGS@
 json_LIBS = @json_LIBS@
 libdir = @libdir@
 libexecdir = @libexecdir@
+libiptc_CFLAGS = @libiptc_CFLAGS@
+libiptc_LIBS = @libiptc_LIBS@
 linux_headers = @linux_headers@
 localedir = @localedir@
 localstatedir = @localstatedir@
diff --git a/src/libstrongswan/plugins/unbound/Makefile.in b/src/libstrongswan/plugins/unbound/Makefile.in
index 02f4ccd..c84717b 100644
--- a/src/libstrongswan/plugins/unbound/Makefile.in
+++ b/src/libstrongswan/plugins/unbound/Makefile.in
@@ -229,6 +229,7 @@ DLLIB = @DLLIB@
 DLLTOOL = @DLLTOOL@
 DSYMUTIL = @DSYMUTIL@
 DUMPBIN = @DUMPBIN@
+EASY_INSTALL = @EASY_INSTALL@
 ECHO_C = @ECHO_C@
 ECHO_N = @ECHO_N@
 ECHO_T = @ECHO_T@
@@ -289,10 +290,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
 PLUGIN_CFLAGS = @PLUGIN_CFLAGS@
 PTHREADLIB = @PTHREADLIB@
 PYTHON = @PYTHON@
+PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@
 PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
 PYTHON_PLATFORM = @PYTHON_PLATFORM@
 PYTHON_PREFIX = @PYTHON_PREFIX@
 PYTHON_VERSION = @PYTHON_VERSION@
+PY_TEST = @PY_TEST@
 RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
@@ -366,6 +369,8 @@ json_CFLAGS = @json_CFLAGS@
 json_LIBS = @json_LIBS@
 libdir = @libdir@
 libexecdir = @libexecdir@
+libiptc_CFLAGS = @libiptc_CFLAGS@
+libiptc_LIBS = @libiptc_LIBS@
 linux_headers = @linux_headers@
 localedir = @localedir@
 localstatedir = @localstatedir@
diff --git a/src/libstrongswan/plugins/winhttp/Makefile.in b/src/libstrongswan/plugins/winhttp/Makefile.in
index fb87917..f8db1ff 100644
--- a/src/libstrongswan/plugins/winhttp/Makefile.in
+++ b/src/libstrongswan/plugins/winhttp/Makefile.in
@@ -229,6 +229,7 @@ DLLIB = @DLLIB@
 DLLTOOL = @DLLTOOL@
 DSYMUTIL = @DSYMUTIL@
 DUMPBIN = @DUMPBIN@
+EASY_INSTALL = @EASY_INSTALL@
 ECHO_C = @ECHO_C@
 ECHO_N = @ECHO_N@
 ECHO_T = @ECHO_T@
@@ -289,10 +290,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
 PLUGIN_CFLAGS = @PLUGIN_CFLAGS@
 PTHREADLIB = @PTHREADLIB@
 PYTHON = @PYTHON@
+PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@
 PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
 PYTHON_PLATFORM = @PYTHON_PLATFORM@
 PYTHON_PREFIX = @PYTHON_PREFIX@
 PYTHON_VERSION = @PYTHON_VERSION@
+PY_TEST = @PY_TEST@
 RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
@@ -366,6 +369,8 @@ json_CFLAGS = @json_CFLAGS@
 json_LIBS = @json_LIBS@
 libdir = @libdir@
 libexecdir = @libexecdir@
+libiptc_CFLAGS = @libiptc_CFLAGS@
+libiptc_LIBS = @libiptc_LIBS@
 linux_headers = @linux_headers@
 localedir = @localedir@
 localstatedir = @localstatedir@
diff --git a/src/libstrongswan/plugins/x509/Makefile.in b/src/libstrongswan/plugins/x509/Makefile.in
index 23a6b3b..b31bfbe 100644
--- a/src/libstrongswan/plugins/x509/Makefile.in
+++ b/src/libstrongswan/plugins/x509/Makefile.in
@@ -228,6 +228,7 @@ DLLIB = @DLLIB@
 DLLTOOL = @DLLTOOL@
 DSYMUTIL = @DSYMUTIL@
 DUMPBIN = @DUMPBIN@
+EASY_INSTALL = @EASY_INSTALL@
 ECHO_C = @ECHO_C@
 ECHO_N = @ECHO_N@
 ECHO_T = @ECHO_T@
@@ -288,10 +289,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
 PLUGIN_CFLAGS = @PLUGIN_CFLAGS@
 PTHREADLIB = @PTHREADLIB@
 PYTHON = @PYTHON@
+PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@
 PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
 PYTHON_PLATFORM = @PYTHON_PLATFORM@
 PYTHON_PREFIX = @PYTHON_PREFIX@
 PYTHON_VERSION = @PYTHON_VERSION@
+PY_TEST = @PY_TEST@
 RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
@@ -365,6 +368,8 @@ json_CFLAGS = @json_CFLAGS@
 json_LIBS = @json_LIBS@
 libdir = @libdir@
 libexecdir = @libexecdir@
+libiptc_CFLAGS = @libiptc_CFLAGS@
+libiptc_LIBS = @libiptc_LIBS@
 linux_headers = @linux_headers@
 localedir = @localedir@
 localstatedir = @localstatedir@
diff --git a/src/libstrongswan/plugins/x509/x509_ac.c b/src/libstrongswan/plugins/x509/x509_ac.c
index ed58377..bfc2004 100644
--- a/src/libstrongswan/plugins/x509/x509_ac.c
+++ b/src/libstrongswan/plugins/x509/x509_ac.c
@@ -1,7 +1,7 @@
 /*
  * Copyright (C) 2002 Ueli Galizzi, Ariane Seiler
  * Copyright (C) 2003 Martin Berner, Lukas Suter
- * Copyright (C) 2002-2009 Andreas Steffen
+ * Copyright (C) 2002-2014 Andreas Steffen
  * Copyright (C) 2009 Martin Willi
  *
  * HSR Hochschule fuer Technik Rapperswil
@@ -557,7 +557,7 @@ static bool parse_certificate(private_x509_ac_t *this)
 				}
 				break;
 			case AC_OBJ_SIGNATURE:
-				this->signature = object;
+				this->signature = chunk_skip(object, 1);
 				break;
 			default:
 				break;
diff --git a/src/libstrongswan/plugins/x509/x509_cert.c b/src/libstrongswan/plugins/x509/x509_cert.c
index bdc8234..96280a0 100644
--- a/src/libstrongswan/plugins/x509/x509_cert.c
+++ b/src/libstrongswan/plugins/x509/x509_cert.c
@@ -1465,7 +1465,7 @@ static bool parse_certificate(private_x509_cert_t *this)
 				}
 				break;
 			case X509_OBJ_SIGNATURE:
-				this->signature = object;
+				this->signature = chunk_skip(object, 1);
 				break;
 			default:
 				break;
diff --git a/src/libstrongswan/plugins/x509/x509_crl.c b/src/libstrongswan/plugins/x509/x509_crl.c
index d6057c3..4d7e7bd 100644
--- a/src/libstrongswan/plugins/x509/x509_crl.c
+++ b/src/libstrongswan/plugins/x509/x509_crl.c
@@ -347,7 +347,7 @@ static bool parse(private_x509_crl_t *this)
 				break;
 			}
 			case CRL_OBJ_SIGNATURE:
-				this->signature = object;
+				this->signature = chunk_skip(object, 1);
 				break;
 			default:
 				break;
@@ -451,6 +451,7 @@ METHOD(certificate_t, issued_by, bool,
 	signature_scheme_t scheme;
 	bool valid;
 	x509_t *x509 = (x509_t*)issuer;
+	chunk_t keyid = chunk_empty;
 
 	/* check if issuer is an X.509 CA certificate */
 	if (issuer->get_type(issuer) != CERT_X509)
@@ -462,21 +463,16 @@ METHOD(certificate_t, issued_by, bool,
 		return FALSE;
 	}
 
-	/* get the public key of the issuer */
-	key = issuer->get_public_key(issuer);
-
 	/* compare keyIdentifiers if available, otherwise use DNs */
-	if (this->authKeyIdentifier.ptr && key)
+	if (this->authKeyIdentifier.ptr)
 	{
-		chunk_t fingerprint;
-
-		if (!key->get_fingerprint(key, KEYID_PUBKEY_SHA1, &fingerprint) ||
-			!chunk_equals(fingerprint, this->authKeyIdentifier))
+		keyid = x509->get_subjectKeyIdentifier(x509);
+		if (keyid.len && !chunk_equals(keyid, this->authKeyIdentifier))
 		{
 			return FALSE;
 		}
 	}
-	else
+	if (!keyid.len)
 	{
 		if (!this->issuer->equals(this->issuer, issuer->get_subject(issuer)))
 		{
@@ -484,10 +480,13 @@ METHOD(certificate_t, issued_by, bool,
 		}
 	}
 
-	/* determine signature scheme */
 	scheme = signature_scheme_from_oid(this->algorithm);
-
-	if (scheme == SIGN_UNKNOWN || key == NULL)
+	if (scheme == SIGN_UNKNOWN)
+	{
+		return FALSE;
+	}
+	key = issuer->get_public_key(issuer);
+	if (!key)
 	{
 		return FALSE;
 	}
diff --git a/src/libstrongswan/plugins/x509/x509_ocsp_request.c b/src/libstrongswan/plugins/x509/x509_ocsp_request.c
index ff0f023..eb5b019 100644
--- a/src/libstrongswan/plugins/x509/x509_ocsp_request.c
+++ b/src/libstrongswan/plugins/x509/x509_ocsp_request.c
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 2008-2009 Martin Willi
- * Copyright (C) 2007 Andreas Steffen
+ * Copyright (C) 2007-2014 Andreas Steffen
  * Hochschule fuer Technik Rapperswil
  * Copyright (C) 2003 Christoph Gysin, Simon Zwahlen
  *
@@ -265,6 +265,10 @@ static chunk_t build_optionalSignature(private_x509_ocsp_request_t *this,
 			oid = OID_ECDSA_WITH_SHA1;
 			scheme = SIGN_ECDSA_WITH_SHA1_DER;
 			break;
+		case KEY_BLISS:
+			oid = OID_BLISS_WITH_SHA512;
+			scheme = SIGN_BLISS_WITH_SHA512;
+			break;
 		default:
 			DBG1(DBG_LIB, "unable to sign OCSP request, %N signature not "
 				 "supported", key_type_names, this->key->get_type(this->key));
diff --git a/src/libstrongswan/plugins/x509/x509_ocsp_response.c b/src/libstrongswan/plugins/x509/x509_ocsp_response.c
index ad04c7d..60133fc 100644
--- a/src/libstrongswan/plugins/x509/x509_ocsp_response.c
+++ b/src/libstrongswan/plugins/x509/x509_ocsp_response.c
@@ -1,6 +1,6 @@
 /**
  * Copyright (C) 2008-2009 Martin Willi
- * Copyright (C) 2007 Andreas Steffen
+ * Copyright (C) 2007-2014 Andreas Steffen
  * Hochschule fuer Technik Rapperswil
  * Copyright (C) 2003 Christoph Gysin, Simon Zwahlen
  *
@@ -537,7 +537,7 @@ static bool parse_basicOCSPResponse(private_x509_ocsp_response_t *this,
 												parser->get_level(parser)+1, NULL);
 				break;
 			case BASIC_RESPONSE_SIGNATURE:
-				this->signature = object;
+				this->signature = chunk_skip(object, 1);
 				break;
 			case BASIC_RESPONSE_CERTIFICATE:
 			{
diff --git a/src/libstrongswan/plugins/x509/x509_pkcs10.c b/src/libstrongswan/plugins/x509/x509_pkcs10.c
index 024b4db..20561f7 100644
--- a/src/libstrongswan/plugins/x509/x509_pkcs10.c
+++ b/src/libstrongswan/plugins/x509/x509_pkcs10.c
@@ -435,7 +435,7 @@ static bool parse_certificate_request(private_x509_pkcs10_t *this)
 				this->algorithm = asn1_parse_algorithmIdentifier(object, level, NULL);
 				break;
 			case PKCS10_SIGNATURE:
-				this->signature = object;
+				this->signature = chunk_skip(object, 1);
 				break;
 			default:
 				break;
diff --git a/src/libstrongswan/plugins/xcbc/Makefile.in b/src/libstrongswan/plugins/xcbc/Makefile.in
index ffcee54..6c9901e 100644
--- a/src/libstrongswan/plugins/xcbc/Makefile.in
+++ b/src/libstrongswan/plugins/xcbc/Makefile.in
@@ -226,6 +226,7 @@ DLLIB = @DLLIB@
 DLLTOOL = @DLLTOOL@
 DSYMUTIL = @DSYMUTIL@
 DUMPBIN = @DUMPBIN@
+EASY_INSTALL = @EASY_INSTALL@
 ECHO_C = @ECHO_C@
 ECHO_N = @ECHO_N@
 ECHO_T = @ECHO_T@
@@ -286,10 +287,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
 PLUGIN_CFLAGS = @PLUGIN_CFLAGS@
 PTHREADLIB = @PTHREADLIB@
 PYTHON = @PYTHON@
+PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@
 PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
 PYTHON_PLATFORM = @PYTHON_PLATFORM@
 PYTHON_PREFIX = @PYTHON_PREFIX@
 PYTHON_VERSION = @PYTHON_VERSION@
+PY_TEST = @PY_TEST@
 RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
@@ -363,6 +366,8 @@ json_CFLAGS = @json_CFLAGS@
 json_LIBS = @json_LIBS@
 libdir = @libdir@
 libexecdir = @libexecdir@
+libiptc_CFLAGS = @libiptc_CFLAGS@
+libiptc_LIBS = @libiptc_LIBS@
 linux_headers = @linux_headers@
 localedir = @localedir@
 localstatedir = @localstatedir@
diff --git a/src/libstrongswan/plugins/xcbc/xcbc.c b/src/libstrongswan/plugins/xcbc/xcbc.c
index 802c8a3..d852a29 100644
--- a/src/libstrongswan/plugins/xcbc/xcbc.c
+++ b/src/libstrongswan/plugins/xcbc/xcbc.c
@@ -219,6 +219,10 @@ METHOD(mac_t, set_key, bool,
 {
 	chunk_t iv, k1, lengthened;
 
+	memset(this->e, 0, this->b);
+	this->remaining_bytes = 0;
+	this->zero = TRUE;
+
 	/* we support variable keys from RFC4434 */
 	if (key.len == this->b)
 	{
diff --git a/src/libstrongswan/processing/processor.h b/src/libstrongswan/processing/processor.h
index f96530e..ee08870 100644
--- a/src/libstrongswan/processing/processor.h
+++ b/src/libstrongswan/processing/processor.h
@@ -23,6 +23,8 @@
 #ifndef PROCESSOR_H_
 #define PROCESSOR_H_
 
+#include <utils/utils.h>
+
 typedef struct processor_t processor_t;
 
 #include <stdlib.h>
diff --git a/src/libstrongswan/processing/scheduler.c b/src/libstrongswan/processing/scheduler.c
index 3f1598f..d908525 100644
--- a/src/libstrongswan/processing/scheduler.c
+++ b/src/libstrongswan/processing/scheduler.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2008 Tobias Brunner
+ * Copyright (C) 2008-2015 Tobias Brunner
  * Copyright (C) 2005-2006 Martin Willi
  * Copyright (C) 2005 Jan Hutter
  * Hochschule fuer Technik Rapperswil
@@ -300,16 +300,26 @@ METHOD(scheduler_t, schedule_job_ms, void,
 	schedule_job_tv(this, job, tv);
 }
 
-METHOD(scheduler_t, destroy, void,
+METHOD(scheduler_t, flush, void,
 	private_scheduler_t *this)
 {
 	event_t *event;
-	this->condvar->destroy(this->condvar);
-	this->mutex->destroy(this->mutex);
+
+	this->mutex->lock(this->mutex);
 	while ((event = remove_event(this)) != NULL)
 	{
 		event_destroy(event);
 	}
+	this->condvar->signal(this->condvar);
+	this->mutex->unlock(this->mutex);
+}
+
+METHOD(scheduler_t, destroy, void,
+	private_scheduler_t *this)
+{
+	flush(this);
+	this->condvar->destroy(this->condvar);
+	this->mutex->destroy(this->mutex);
 	free(this->heap);
 	free(this);
 }
@@ -328,6 +338,7 @@ scheduler_t * scheduler_create()
 			.schedule_job = _schedule_job,
 			.schedule_job_ms = _schedule_job_ms,
 			.schedule_job_tv = _schedule_job_tv,
+			.flush = _flush,
 			.destroy = _destroy,
 		},
 		.heap_size = HEAP_SIZE_DEFAULT,
diff --git a/src/libstrongswan/processing/scheduler.h b/src/libstrongswan/processing/scheduler.h
index abbf74e..7f91fcc 100644
--- a/src/libstrongswan/processing/scheduler.h
+++ b/src/libstrongswan/processing/scheduler.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2009 Tobias Brunner
+ * Copyright (C) 2009-2015 Tobias Brunner
  * Copyright (C) 2005-2007 Martin Willi
  * Copyright (C) 2005 Jan Hutter
  * Hochschule fuer Technik Rapperswil
@@ -115,6 +115,11 @@ struct scheduler_t {
 	u_int (*get_job_load) (scheduler_t *this);
 
 	/**
+	 * Remove all scheduled jobs.
+	 */
+	void (*flush)(scheduler_t *this);
+
+	/**
 	 * Destroys a scheduler object.
 	 */
 	void (*destroy) (scheduler_t *this);
diff --git a/src/libstrongswan/processing/watcher.c b/src/libstrongswan/processing/watcher.c
index d4de2a9..5b94208 100644
--- a/src/libstrongswan/processing/watcher.c
+++ b/src/libstrongswan/processing/watcher.c
@@ -24,9 +24,6 @@
 
 #include <unistd.h>
 #include <errno.h>
-#ifndef WIN32
-#include <sys/select.h>
-#endif
 #include <fcntl.h>
 
 typedef struct private_watcher_t private_watcher_t;
@@ -121,11 +118,7 @@ static void update(private_watcher_t *this)
 	this->pending = TRUE;
 	if (this->notify[1] != -1)
 	{
-#ifdef WIN32
-		if (send(this->notify[1], buf, sizeof(buf), 0) == -1)
-#else
 		if (write(this->notify[1], buf, sizeof(buf)) == -1)
-#endif
 		{
 			DBG1(DBG_JOB, "notifying watcher failed: %s", strerror(errno));
 		}
@@ -245,23 +238,57 @@ static void activate_all(private_watcher_t *this)
 }
 
 /**
+ * Find flagged revents in a pollfd set by fd
+ */
+static int find_revents(struct pollfd *pfd, int count, int fd)
+{
+	int i;
+
+	for (i = 0; i < count; i++)
+	{
+		if (pfd[i].fd == fd)
+		{
+			return pfd[i].revents;
+		}
+	}
+	return 0;
+}
+
+/**
+ * Check if entry is waiting for a specific event, and if it got signaled
+ */
+static bool entry_ready(entry_t *entry, watcher_event_t event, int revents)
+{
+	if (entry->events & event)
+	{
+		switch (event)
+		{
+			case WATCHER_READ:
+				return (revents & (POLLIN | POLLHUP | POLLNVAL)) != 0;
+			case WATCHER_WRITE:
+				return (revents & (POLLOUT | POLLHUP | POLLNVAL)) != 0;
+			case WATCHER_EXCEPT:
+				return (revents & (POLLERR | POLLHUP | POLLNVAL)) != 0;
+		}
+	}
+	return FALSE;
+}
+
+/**
  * Dispatching function
  */
 static job_requeue_t watch(private_watcher_t *this)
 {
 	enumerator_t *enumerator;
 	entry_t *entry;
-	fd_set rd, wr, ex;
-	int maxfd = 0, res;
+	struct pollfd *pfd;
+	int count = 0, res;
 	bool rebuild = FALSE;
 
-	FD_ZERO(&rd);
-	FD_ZERO(&wr);
-	FD_ZERO(&ex);
-
 	this->mutex->lock(this->mutex);
 
-	if (this->fds->get_count(this->fds) == 0)
+	count = this->fds->get_count(this->fds);
+	if (count == 0)
 	{
 		this->state = WATCHER_STOPPED;
 		this->mutex->unlock(this->mutex);
@@ -272,33 +299,34 @@ static job_requeue_t watch(private_watcher_t *this)
 		this->state = WATCHER_RUNNING;
 	}
 
-	if (this->notify[0] != -1)
-	{
-		FD_SET(this->notify[0], &rd);
-		maxfd = this->notify[0];
-	}
+	pfd = alloca(sizeof(*pfd) * (count + 1));
+	pfd[0].fd = this->notify[0];
+	pfd[0].events = POLLIN;
+	count = 1;
 
 	enumerator = this->fds->create_enumerator(this->fds);
 	while (enumerator->enumerate(enumerator, &entry))
 	{
 		if (!entry->in_callback)
 		{
+			pfd[count].fd = entry->fd;
+			pfd[count].events = 0;
 			if (entry->events & WATCHER_READ)
 			{
 				DBG3(DBG_JOB, "  watching %d for reading", entry->fd);
-				FD_SET(entry->fd, &rd);
+				pfd[count].events |= POLLIN;
 			}
 			if (entry->events & WATCHER_WRITE)
 			{
 				DBG3(DBG_JOB, "  watching %d for writing", entry->fd);
-				FD_SET(entry->fd, &wr);
+				pfd[count].events |= POLLOUT;
 			}
 			if (entry->events & WATCHER_EXCEPT)
 			{
 				DBG3(DBG_JOB, "  watching %d for exceptions", entry->fd);
-				FD_SET(entry->fd, &ex);
+				pfd[count].events |= POLLERR;
 			}
-			maxfd = max(maxfd, entry->fd);
+			count++;
 		}
 	}
 	enumerator->destroy(enumerator);
@@ -306,30 +334,27 @@ static job_requeue_t watch(private_watcher_t *this)
 
 	while (!rebuild)
 	{
+		int revents;
 		char buf[1];
 		bool old;
 		ssize_t len;
 		job_t *job;
 
-		DBG2(DBG_JOB, "watcher going to select()");
+		DBG2(DBG_JOB, "watcher going to poll() %d fds", count);
 		thread_cleanup_push((void*)activate_all, this);
 		old = thread_cancelability(TRUE);
 
-		res = select(maxfd + 1, &rd, &wr, &ex, NULL);
+		res = poll(pfd, count, -1);
 		thread_cancelability(old);
 		thread_cleanup_pop(FALSE);
 
 		if (res > 0)
 		{
-			if (this->notify[0] != -1 && FD_ISSET(this->notify[0], &rd))
+			if (pfd[0].revents & POLLIN)
 			{
 				while (TRUE)
 				{
-#ifdef WIN32
-					len = recv(this->notify[0], buf, sizeof(buf), 0);
-#else
 					len = read(this->notify[0], buf, sizeof(buf));
-#endif
 					if (len == -1)
 					{
 						if (errno != EAGAIN && errno != EWOULDBLOCK)
@@ -354,21 +379,25 @@ static job_requeue_t watch(private_watcher_t *this)
 					rebuild = TRUE;
 					break;
 				}
-				if (FD_ISSET(entry->fd, &rd) && (entry->events & WATCHER_READ))
-				{
-					DBG2(DBG_JOB, "watched FD %d ready to read", entry->fd);
-					notify(this, entry, WATCHER_READ);
-				}
-				if (FD_ISSET(entry->fd, &wr) && (entry->events & WATCHER_WRITE))
-				{
-					DBG2(DBG_JOB, "watched FD %d ready to write", entry->fd);
-					notify(this, entry, WATCHER_WRITE);
-				}
-				if (FD_ISSET(entry->fd, &ex) && (entry->events & WATCHER_EXCEPT))
+				revents = find_revents(pfd, count, entry->fd);
+				if (entry_ready(entry, WATCHER_EXCEPT, revents))
 				{
 					DBG2(DBG_JOB, "watched FD %d has exception", entry->fd);
 					notify(this, entry, WATCHER_EXCEPT);
 				}
+				else
+				{
+					if (entry_ready(entry, WATCHER_READ, revents))
+					{
+						DBG2(DBG_JOB, "watched FD %d ready to read", entry->fd);
+						notify(this, entry, WATCHER_READ);
+					}
+					if (entry_ready(entry, WATCHER_WRITE, revents))
+					{
+						DBG2(DBG_JOB, "watched FD %d ready to write", entry->fd);
+						notify(this, entry, WATCHER_WRITE);
+					}
+				}
 			}
 			enumerator->destroy(enumerator);
 			this->mutex->unlock(this->mutex);
@@ -388,7 +417,7 @@ static job_requeue_t watch(private_watcher_t *this)
 		{
 			if (!this->pending && errno != EINTR)
 			{	/* complain only if no pending updates */
-				DBG1(DBG_JOB, "watcher select() error: %s", strerror(errno));
+				DBG1(DBG_JOB, "watcher poll() error: %s", strerror(errno));
 			}
 			return JOB_REQUEUE_DIRECT;
 		}
diff --git a/src/libstrongswan/selectors/traffic_selector.c b/src/libstrongswan/selectors/traffic_selector.c
index 94b7746..3b7f8c5 100644
--- a/src/libstrongswan/selectors/traffic_selector.c
+++ b/src/libstrongswan/selectors/traffic_selector.c
@@ -449,41 +449,9 @@ METHOD(traffic_selector_t, get_subset, traffic_selector_t*,
 }
 
 METHOD(traffic_selector_t, equals, bool,
-	private_traffic_selector_t *this, traffic_selector_t *other_public)
+	private_traffic_selector_t *this, traffic_selector_t *other)
 {
-	private_traffic_selector_t *other;
-
-	other = (private_traffic_selector_t*)other_public;
-	if (this->type != other->type)
-	{
-		return FALSE;
-	}
-	if (!(this->from_port == other->from_port &&
-		  this->to_port == other->to_port &&
-		  this->protocol == other->protocol))
-	{
-		return FALSE;
-	}
-	switch (this->type)
-	{
-		case TS_IPV4_ADDR_RANGE:
-			if (memeq(this->from4, other->from4, sizeof(this->from4)) &&
-				memeq(this->to4, other->to4, sizeof(this->to4)))
-			{
-				return TRUE;
-			}
-			break;
-		case TS_IPV6_ADDR_RANGE:
-			if (memeq(this->from6, other->from6, sizeof(this->from6)) &&
-				memeq(this->to6, other->to6, sizeof(this->to6)))
-			{
-				return TRUE;
-			}
-			break;
-		default:
-			break;
-	}
-	return FALSE;
+	return traffic_selector_cmp(&this->public, other, NULL) == 0;
 }
 
 METHOD(traffic_selector_t, get_from_address, chunk_t,
@@ -717,12 +685,96 @@ METHOD(traffic_selector_t, clone_, traffic_selector_t*,
 	}
 }
 
+METHOD(traffic_selector_t, hash, u_int,
+	private_traffic_selector_t *this, u_int hash)
+{
+	return chunk_hash_inc(get_from_address(this),
+			chunk_hash_inc(get_to_address(this),
+			 chunk_hash_inc(chunk_from_thing(this->from_port),
+			  chunk_hash_inc(chunk_from_thing(this->to_port),
+			   chunk_hash_inc(chunk_from_thing(this->protocol),
+				hash)))));
+}
+
 METHOD(traffic_selector_t, destroy, void,
 	private_traffic_selector_t *this)
 {
 	free(this);
 }
 
+/**
+ * Compare two integers
+ */
+static int compare_int(int a, int b)
+{
+	return a - b;
+}
+
+/*
+ * See header
+ */
+int traffic_selector_cmp(traffic_selector_t *a_pub, traffic_selector_t *b_pub,
+						 void *opts)
+{
+	private_traffic_selector_t *a, *b;
+	int res;
+
+	a = (private_traffic_selector_t*)a_pub;
+	b = (private_traffic_selector_t*)b_pub;
+
+	/* IPv4 before IPv6 */
+	res = compare_int(a->type, b->type);
+	if (res)
+	{
+		return res;
+	}
+	switch (a->type)
+	{
+		case TS_IPV4_ADDR_RANGE:
+			/* lower starting subnets first */
+			res = memcmp(a->from4, b->from4, sizeof(a->from4));
+			if (res)
+			{
+				return res;
+			}
+			/* larger subnets first */
+			res = memcmp(b->to4, a->to4, sizeof(a->to4));
+			if (res)
+			{
+				return res;
+			}
+			break;
+		case TS_IPV6_ADDR_RANGE:
+			res = memcmp(a->from6, b->from6, sizeof(a->from6));
+			if (res)
+			{
+				return res;
+			}
+			res = memcmp(b->to6, a->to6, sizeof(a->to6));
+			if (res)
+			{
+				return res;
+			}
+			break;
+		default:
+			return 1;
+	}
+	/* lower protocols first */
+	res = compare_int(a->protocol, b->protocol);
+	if (res)
+	{
+		return res;
+	}
+	/* lower starting ports first */
+	res = compare_int(a->from_port, b->from_port);
+	if (res)
+	{
+		return res;
+	}
+	/* larger port ranges first */
+	return compare_int(b->to_port, a->to_port);
+}
+
 /*
  * see header
  */
@@ -933,6 +985,7 @@ static private_traffic_selector_t *traffic_selector_create(u_int8_t protocol,
 			.set_address = _set_address,
 			.to_subnet = _to_subnet,
 			.clone = _clone_,
+			.hash = _hash,
 			.destroy = _destroy,
 		},
 		.from_port = from_port,
diff --git a/src/libstrongswan/selectors/traffic_selector.h b/src/libstrongswan/selectors/traffic_selector.h
index ab6813a..cf9a286 100644
--- a/src/libstrongswan/selectors/traffic_selector.h
+++ b/src/libstrongswan/selectors/traffic_selector.h
@@ -221,6 +221,14 @@ struct traffic_selector_t {
 	bool (*to_subnet) (traffic_selector_t *this, host_t **net, u_int8_t *mask);
 
 	/**
+	 * Create a hash value for the traffic selector.
+	 *
+	 * @param inc		optional value for incremental hashing
+	 * @return			calculated hash value for the traffic selector
+	 */
+	u_int (*hash)(traffic_selector_t *this, u_int inc);
+
+	/**
 	 * Destroys the ts object
 	 */
 	void (*destroy) (traffic_selector_t *this);
@@ -249,6 +257,17 @@ static inline u_int8_t traffic_selector_icmp_code(u_int16_t port)
 }
 
 /**
+ * Compare two traffic selectors, usable as sort function
+ *
+ * @param a				first selector to compare
+ * @param b				second selector to compare
+ * @param opts			optional sort options, currently unused
+ * @return				> 0 if a > b, 0 if a == b, < 0 if a < b
+ */
+int traffic_selector_cmp(traffic_selector_t *a, traffic_selector_t *b,
+						 void *opts);
+
+/**
  * Create a new traffic selector using human readable params.
  *
  * If protocol is ICMP or ICMPv6 the ports are interpreted as follows:  If they
diff --git a/src/libstrongswan/settings/settings_lexer.c b/src/libstrongswan/settings/settings_lexer.c
index 7643301..0d71a1d 100644
--- a/src/libstrongswan/settings/settings_lexer.c
+++ b/src/libstrongswan/settings/settings_lexer.c
@@ -456,8 +456,8 @@ static void yy_fatal_error (yyconst char msg[] ,yyscan_t yyscanner );
 	yyg->yy_c_buf_p = yy_cp;
 
 /* %% [4.0] data tables for the DFA and the user's section 1 definitions go here */
-#define YY_NUM_RULES 25
-#define YY_END_OF_BUFFER 26
+#define YY_NUM_RULES 26
+#define YY_END_OF_BUFFER 27
 /* This struct is not used in this scanner,
    but its presence is necessary. */
 struct yy_trans_info
@@ -465,31 +465,32 @@ struct yy_trans_info
 	flex_int32_t yy_verify;
 	flex_int32_t yy_nxt;
 	};
-static yyconst flex_int16_t yy_accept[50] =
+static yyconst flex_int16_t yy_accept[52] =
     {   0,
-        0,    0,    0,    0,    0,    0,   26,    9,    2,    3,
+        0,    0,    0,    0,    0,    0,   27,    9,    2,    3,
         8,    1,    6,    9,    4,    5,   14,   10,   11,   12,
-       24,   16,   15,   17,    9,    2,    1,    1,    3,    9,
-       14,   13,   24,   23,   21,   22,   18,   19,   20,    1,
-        9,    9,    9,    9,    9,    0,    7,    7,    0
+       25,   16,   15,   17,    9,    2,    1,    1,    3,    9,
+       14,   13,   25,   24,   23,   24,   21,   22,   18,   19,
+       20,    1,    9,    9,    9,    9,    9,    0,    7,    7,
+        0
     } ;
 
 static yyconst flex_int32_t yy_ec[256] =
     {   0,
         1,    1,    1,    1,    1,    1,    1,    1,    2,    3,
+        1,    1,    4,    1,    1,    1,    1,    1,    1,    1,
         1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    5,    1,    6,    7,    1,    1,    1,    1,    1,
         1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
-        1,    4,    1,    5,    6,    1,    1,    1,    1,    1,
         1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        8,    1,    1,    1,    1,    1,    1,    1,    1,    1,
         1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
-        7,    1,    1,    1,    1,    1,    1,    1,    1,    1,
         1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
-        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
-        1,    8,    1,    1,    1,    1,    1,    9,   10,   11,
+        1,    9,    1,    1,    1,    1,    1,   10,   11,   12,
 
-       12,   13,    1,    1,   14,    1,    1,   15,    1,   16,
-        1,    1,    1,   17,    1,   18,   19,    1,    1,    1,
-        1,    1,   20,    1,   21,    1,    1,    1,    1,    1,
+       13,   14,    1,    1,   15,    1,    1,   16,    1,   17,
+        1,    1,    1,   18,    1,   19,   20,    1,    1,    1,
+        1,    1,   21,    1,   22,    1,    1,    1,    1,    1,
         1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
         1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
         1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
@@ -506,88 +507,92 @@ static yyconst flex_int32_t yy_ec[256] =
         1,    1,    1,    1,    1
     } ;
 
-static yyconst flex_int32_t yy_meta[22] =
+static yyconst flex_int32_t yy_meta[23] =
     {   0,
-        1,    2,    3,    4,    5,    4,    6,    7,    1,    1,
-        1,    1,    1,    1,    1,    1,    1,    1,    1,    8,
-        4
+        1,    2,    3,    1,    4,    5,    4,    6,    7,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        8,    4
     } ;
 
-static yyconst flex_int16_t yy_base[60] =
+static yyconst flex_int16_t yy_base[62] =
     {   0,
-        0,    0,   20,   40,   24,   28,   63,    0,   33,  145,
-      145,   57,  145,   43,  145,  145,    0,  145,  145,    0,
-        0,  145,  145,   53,    0,   45,    0,   55,  145,   47,
-        0,  145,    0,  145,  145,  145,  145,  145,  145,    0,
-       41,   35,   23,   18,   36,   48,  145,   51,  145,   71,
-       79,   87,   94,  102,  107,  112,  120,  128,  136
+        0,    0,   21,   42,   26,   28,   63,    0,   31,  155,
+      155,   59,  155,   44,  155,  155,    0,  155,  155,    0,
+        0,  155,  155,   62,    0,   48,    0,   57,  155,   47,
+        0,  155,    0,  155,  155,   49,  155,  155,  155,  155,
+      155,    0,   30,   21,   28,   12,   37,   52,  155,   54,
+      155,   81,   89,   97,  104,  112,  117,  122,  130,  138,
+      146
     } ;
 
-static yyconst flex_int16_t yy_def[60] =
+static yyconst flex_int16_t yy_def[62] =
     {   0,
-       49,    1,   50,   50,   51,   51,   49,   52,   49,   49,
-       49,   53,   49,   52,   49,   49,   54,   49,   49,   55,
-       56,   49,   49,   57,   52,   49,   58,   53,   49,   52,
-       54,   49,   56,   49,   49,   49,   49,   49,   49,   58,
-       52,   52,   52,   52,   52,   59,   49,   59,    0,   49,
-       49,   49,   49,   49,   49,   49,   49,   49,   49
+       51,    1,   52,   52,   53,   53,   51,   54,   51,   51,
+       51,   55,   51,   54,   51,   51,   56,   51,   51,   57,
+       58,   51,   51,   59,   54,   51,   60,   55,   51,   54,
+       56,   51,   58,   51,   51,   51,   51,   51,   51,   51,
+       51,   60,   54,   54,   54,   54,   54,   61,   51,   61,
+        0,   51,   51,   51,   51,   51,   51,   51,   51,   51,
+       51
     } ;
 
-static yyconst flex_int16_t yy_nxt[167] =
+static yyconst flex_int16_t yy_nxt[178] =
     {   0,
-        8,    9,   10,    9,   11,   12,   13,    8,    8,    8,
-        8,    8,    8,   14,    8,    8,    8,    8,    8,   15,
-       16,   18,   18,   18,   19,   18,   22,   20,   23,   45,
-       22,   24,   23,   44,   26,   24,   26,   46,   27,   46,
-       18,   18,   18,   18,   19,   18,   26,   20,   26,   48,
-       27,   48,   48,   43,   48,   42,   41,   29,   30,   29,
-       18,   35,   49,   49,   49,   36,   49,   49,   37,   38,
-       39,   17,   17,   17,   17,   17,   17,   17,   17,   21,
-       21,   21,   21,   21,   21,   21,   21,   25,   49,   49,
-       49,   49,   49,   25,   28,   28,   28,   28,   28,   28,
-
-       28,   28,   31,   49,   49,   49,   49,   31,   49,   31,
-       32,   32,   33,   33,   49,   33,   49,   33,   49,   33,
-       34,   34,   34,   34,   34,   34,   34,   34,   40,   40,
-       49,   40,   40,   40,   40,   40,   47,   47,   47,   47,
-       47,   49,   47,   47,    7,   49,   49,   49,   49,   49,
-       49,   49,   49,   49,   49,   49,   49,   49,   49,   49,
-       49,   49,   49,   49,   49,   49
+        8,    9,   10,    8,    9,   11,   12,   13,    8,    8,
+        8,    8,    8,    8,   14,    8,    8,    8,    8,    8,
+       15,   16,   18,   18,   47,   18,   19,   18,   22,   20,
+       22,   23,   26,   23,   24,   26,   24,   27,   48,   46,
+       45,   48,   18,   18,   18,   44,   18,   19,   18,   26,
+       20,   35,   26,   50,   27,   50,   50,   43,   50,   29,
+       30,   29,   51,   18,   35,   36,   51,   51,   51,   51,
+       51,   37,   51,   51,   51,   38,   51,   51,   39,   40,
+       41,   17,   17,   17,   17,   17,   17,   17,   17,   21,
+       21,   21,   21,   21,   21,   21,   21,   25,   51,   51,
+
+       51,   51,   51,   25,   28,   28,   28,   28,   28,   28,
+       28,   28,   31,   51,   51,   51,   51,   31,   51,   31,
+       32,   32,   33,   33,   51,   33,   51,   33,   51,   33,
+       34,   34,   34,   34,   34,   34,   34,   34,   42,   42,
+       51,   42,   42,   42,   42,   42,   49,   49,   49,   49,
+       49,   51,   49,   49,    7,   51,   51,   51,   51,   51,
+       51,   51,   51,   51,   51,   51,   51,   51,   51,   51,
+       51,   51,   51,   51,   51,   51,   51
     } ;
 
-static yyconst flex_int16_t yy_chk[167] =
+static yyconst flex_int16_t yy_chk[178] =
     {   0,
         1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
         1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
-        1,    3,    3,    3,    3,    3,    5,    3,    5,   44,
-        6,    5,    6,   43,    9,    6,    9,   45,    9,   45,
-        3,    4,    4,    4,    4,    4,   26,    4,   26,   46,
-       26,   46,   48,   42,   48,   41,   30,   28,   14,   12,
-        4,   24,    7,    0,    0,   24,    0,    0,   24,   24,
-       24,   50,   50,   50,   50,   50,   50,   50,   50,   51,
-       51,   51,   51,   51,   51,   51,   51,   52,    0,    0,
-        0,    0,    0,   52,   53,   53,   53,   53,   53,   53,
-
-       53,   53,   54,    0,    0,    0,    0,   54,    0,   54,
-       55,   55,   56,   56,    0,   56,    0,   56,    0,   56,
-       57,   57,   57,   57,   57,   57,   57,   57,   58,   58,
-        0,   58,   58,   58,   58,   58,   59,   59,   59,   59,
-       59,    0,   59,   59,   49,   49,   49,   49,   49,   49,
-       49,   49,   49,   49,   49,   49,   49,   49,   49,   49,
-       49,   49,   49,   49,   49,   49
+        1,    1,    3,    3,   46,    3,    3,    3,    5,    3,
+        6,    5,    9,    6,    5,    9,    6,    9,   47,   45,
+       44,   47,    3,    4,    4,   43,    4,    4,    4,   26,
+        4,   36,   26,   48,   26,   50,   48,   30,   50,   28,
+       14,   12,    7,    4,   24,   24,    0,    0,    0,    0,
+        0,   24,    0,    0,    0,   24,    0,    0,   24,   24,
+       24,   52,   52,   52,   52,   52,   52,   52,   52,   53,
+       53,   53,   53,   53,   53,   53,   53,   54,    0,    0,
+
+        0,    0,    0,   54,   55,   55,   55,   55,   55,   55,
+       55,   55,   56,    0,    0,    0,    0,   56,    0,   56,
+       57,   57,   58,   58,    0,   58,    0,   58,    0,   58,
+       59,   59,   59,   59,   59,   59,   59,   59,   60,   60,
+        0,   60,   60,   60,   60,   60,   61,   61,   61,   61,
+       61,    0,   61,   61,   51,   51,   51,   51,   51,   51,
+       51,   51,   51,   51,   51,   51,   51,   51,   51,   51,
+       51,   51,   51,   51,   51,   51,   51
     } ;
 
 /* Table of booleans, true if rule could match eol. */
-static yyconst flex_int32_t yy_rule_can_match_eol[26] =
+static yyconst flex_int32_t yy_rule_can_match_eol[27] =
     {   0,
 0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 0, 0, 
-    0, 0, 0, 1, 0, 0,     };
+    0, 0, 0, 1, 0, 0, 0,     };
 
-static yyconst flex_int16_t yy_rule_linenum[25] =
+static yyconst flex_int16_t yy_rule_linenum[26] =
     {   0,
        59,   60,   61,   63,   64,   65,   67,   72,   77,   85,
       105,  108,  111,  114,  120,  122,  123,  146,  147,  148,
-      149,  150,  151,  154
+      149,  150,  151,  152,  153
     } ;
 
 /* The intent behind this definition is that it'll catch
@@ -635,7 +640,7 @@ static void include_files(parser_helper_t *ctx);
 
 /* state used to scan quoted strings */
 
-#line 639 "settings/settings_lexer.c"
+#line 644 "settings/settings_lexer.c"
 
 #define INITIAL 0
 #define inc 1
@@ -947,7 +952,7 @@ YY_DECL
 #line 57 "settings/settings_lexer.l"
 
 
-#line 951 "settings/settings_lexer.c"
+#line 956 "settings/settings_lexer.c"
 
     yylval = yylval_param;
 
@@ -1012,13 +1017,13 @@ yy_match:
 			while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
 				{
 				yy_current_state = (int) yy_def[yy_current_state];
-				if ( yy_current_state >= 50 )
+				if ( yy_current_state >= 52 )
 					yy_c = yy_meta[(unsigned int) yy_c];
 				}
 			yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
 			++yy_cp;
 			}
-		while ( yy_base[yy_current_state] != 145 );
+		while ( yy_base[yy_current_state] != 155 );
 
 yy_find_action:
 /* %% [10.0] code to find the action number goes here */
@@ -1053,13 +1058,13 @@ do_action:	/* This label is used only to access EOF actions. */
 			{
 			if ( yy_act == 0 )
 				fprintf( stderr, "--scanner backing up\n" );
-			else if ( yy_act < 25 )
+			else if ( yy_act < 26 )
 				fprintf( stderr, "--accepting rule at line %ld (\"%s\")\n",
 				         (long)yy_rule_linenum[yy_act], yytext );
-			else if ( yy_act == 25 )
+			else if ( yy_act == 26 )
 				fprintf( stderr, "--accepting default rule (\"%s\")\n",
 				         yytext );
-			else if ( yy_act == 26 )
+			else if ( yy_act == 27 )
 				fprintf( stderr, "--(end of buffer or a NUL)\n" );
 			else
 				fprintf( stderr, "--EOF (start condition %d)\n", YY_START );
@@ -1251,20 +1256,23 @@ case 23:
 /* rule 23 can match eol */
 YY_RULE_SETUP
 #line 151 "settings/settings_lexer.l"
-{
-		yyextra->string_add(yyextra, yytext+1);
-	}
+/* merge lines that end with EOL characters */
 	YY_BREAK
 case 24:
 YY_RULE_SETUP
-#line 154 "settings/settings_lexer.l"
+#line 152 "settings/settings_lexer.l"
+yyextra->string_add(yyextra, yytext+1);
+	YY_BREAK
+case 25:
+YY_RULE_SETUP
+#line 153 "settings/settings_lexer.l"
 {
 		yyextra->string_add(yyextra, yytext);
 	}
 	YY_BREAK
 
 case YY_STATE_EOF(INITIAL):
-#line 159 "settings/settings_lexer.l"
+#line 158 "settings/settings_lexer.l"
 {
 	settings_parser_pop_buffer_state(yyscanner);
 	if (!settings_parser_open_next_file(yyextra) && !YY_CURRENT_BUFFER)
@@ -1273,12 +1281,12 @@ case YY_STATE_EOF(INITIAL):
 	}
 }
 	YY_BREAK
-case 25:
+case 26:
 YY_RULE_SETUP
-#line 167 "settings/settings_lexer.l"
+#line 166 "settings/settings_lexer.l"
 YY_FATAL_ERROR( "flex scanner jammed" );
 	YY_BREAK
-#line 1282 "settings/settings_lexer.c"
+#line 1290 "settings/settings_lexer.c"
 
 	case YY_END_OF_BUFFER:
 		{
@@ -1591,7 +1599,7 @@ static int yy_get_next_buffer (yyscan_t yyscanner)
 		while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
 			{
 			yy_current_state = (int) yy_def[yy_current_state];
-			if ( yy_current_state >= 50 )
+			if ( yy_current_state >= 52 )
 				yy_c = yy_meta[(unsigned int) yy_c];
 			}
 		yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
@@ -1625,11 +1633,11 @@ static int yy_get_next_buffer (yyscan_t yyscanner)
 	while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
 		{
 		yy_current_state = (int) yy_def[yy_current_state];
-		if ( yy_current_state >= 50 )
+		if ( yy_current_state >= 52 )
 			yy_c = yy_meta[(unsigned int) yy_c];
 		}
 	yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
-	yy_is_jam = (yy_current_state == 49);
+	yy_is_jam = (yy_current_state == 51);
 
 	return yy_is_jam ? 0 : yy_current_state;
 }
@@ -2646,7 +2654,7 @@ void settings_parser_free (void * ptr , yyscan_t yyscanner)
 
 /* %ok-for-header */
 
-#line 167 "settings/settings_lexer.l"
+#line 166 "settings/settings_lexer.l"
 
 
 
diff --git a/src/libstrongswan/settings/settings_lexer.l b/src/libstrongswan/settings/settings_lexer.l
index c6546f4..176387f 100644
--- a/src/libstrongswan/settings/settings_lexer.l
+++ b/src/libstrongswan/settings/settings_lexer.l
@@ -148,9 +148,8 @@ static void include_files(parser_helper_t *ctx);
 	\\t     yyextra->string_add(yyextra, "\t");
 	\\b     yyextra->string_add(yyextra, "\b");
 	\\f     yyextra->string_add(yyextra, "\f");
-	\\(.|\n)			{
-		yyextra->string_add(yyextra, yytext+1);
-	}
+	\\\r?\n /* merge lines that end with EOL characters */
+	\\.     yyextra->string_add(yyextra, yytext+1);
 	[^\\\n"]+			{
 		yyextra->string_add(yyextra, yytext);
 	}
diff --git a/src/libstrongswan/tests/Makefile.am b/src/libstrongswan/tests/Makefile.am
index 7ecba19..8c081c6 100644
--- a/src/libstrongswan/tests/Makefile.am
+++ b/src/libstrongswan/tests/Makefile.am
@@ -29,6 +29,7 @@ tests_SOURCES = tests.h tests.c \
   suites/test_enum.c \
   suites/test_hashtable.c \
   suites/test_identification.c \
+  suites/test_traffic_selector.c \
   suites/test_threading.c \
   suites/test_process.c \
   suites/test_watcher.c \
@@ -40,6 +41,8 @@ tests_SOURCES = tests.h tests.c \
   suites/test_array.c \
   suites/test_ecdsa.c \
   suites/test_rsa.c \
+  suites/test_certpolicy.c \
+  suites/test_certnames.c \
   suites/test_host.c \
   suites/test_hasher.c \
   suites/test_crypter.c \
@@ -49,6 +52,7 @@ tests_SOURCES = tests.h tests.c \
   suites/test_asn1_parser.c \
   suites/test_printf.c \
   suites/test_test_rng.c \
+  suites/test_mgf1.c \
   suites/test_ntru.c
 
 tests_CFLAGS = \
diff --git a/src/libstrongswan/tests/Makefile.in b/src/libstrongswan/tests/Makefile.in
index 3268b54..97e24bd 100644
--- a/src/libstrongswan/tests/Makefile.in
+++ b/src/libstrongswan/tests/Makefile.in
@@ -125,6 +125,7 @@ am_tests_OBJECTS = tests-tests.$(OBJEXT) \
 	suites/tests-test_enum.$(OBJEXT) \
 	suites/tests-test_hashtable.$(OBJEXT) \
 	suites/tests-test_identification.$(OBJEXT) \
+	suites/tests-test_traffic_selector.$(OBJEXT) \
 	suites/tests-test_threading.$(OBJEXT) \
 	suites/tests-test_process.$(OBJEXT) \
 	suites/tests-test_watcher.$(OBJEXT) \
@@ -136,6 +137,8 @@ am_tests_OBJECTS = tests-tests.$(OBJEXT) \
 	suites/tests-test_array.$(OBJEXT) \
 	suites/tests-test_ecdsa.$(OBJEXT) \
 	suites/tests-test_rsa.$(OBJEXT) \
+	suites/tests-test_certpolicy.$(OBJEXT) \
+	suites/tests-test_certnames.$(OBJEXT) \
 	suites/tests-test_host.$(OBJEXT) \
 	suites/tests-test_hasher.$(OBJEXT) \
 	suites/tests-test_crypter.$(OBJEXT) \
@@ -145,6 +148,7 @@ am_tests_OBJECTS = tests-tests.$(OBJEXT) \
 	suites/tests-test_asn1_parser.$(OBJEXT) \
 	suites/tests-test_printf.$(OBJEXT) \
 	suites/tests-test_test_rng.$(OBJEXT) \
+	suites/tests-test_mgf1.$(OBJEXT) \
 	suites/tests-test_ntru.$(OBJEXT)
 tests_OBJECTS = $(am_tests_OBJECTS)
 tests_DEPENDENCIES =  \
@@ -260,6 +264,7 @@ DLLIB = @DLLIB@
 DLLTOOL = @DLLTOOL@
 DSYMUTIL = @DSYMUTIL@
 DUMPBIN = @DUMPBIN@
+EASY_INSTALL = @EASY_INSTALL@
 ECHO_C = @ECHO_C@
 ECHO_N = @ECHO_N@
 ECHO_T = @ECHO_T@
@@ -320,10 +325,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
 PLUGIN_CFLAGS = @PLUGIN_CFLAGS@
 PTHREADLIB = @PTHREADLIB@
 PYTHON = @PYTHON@
+PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@
 PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
 PYTHON_PLATFORM = @PYTHON_PLATFORM@
 PYTHON_PREFIX = @PYTHON_PREFIX@
 PYTHON_VERSION = @PYTHON_VERSION@
+PY_TEST = @PY_TEST@
 RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
@@ -397,6 +404,8 @@ json_CFLAGS = @json_CFLAGS@
 json_LIBS = @json_LIBS@
 libdir = @libdir@
 libexecdir = @libexecdir@
+libiptc_CFLAGS = @libiptc_CFLAGS@
+libiptc_LIBS = @libiptc_LIBS@
 linux_headers = @linux_headers@
 localedir = @localedir@
 localstatedir = @localstatedir@
@@ -480,6 +489,7 @@ tests_SOURCES = tests.h tests.c \
   suites/test_enum.c \
   suites/test_hashtable.c \
   suites/test_identification.c \
+  suites/test_traffic_selector.c \
   suites/test_threading.c \
   suites/test_process.c \
   suites/test_watcher.c \
@@ -491,6 +501,8 @@ tests_SOURCES = tests.h tests.c \
   suites/test_array.c \
   suites/test_ecdsa.c \
   suites/test_rsa.c \
+  suites/test_certpolicy.c \
+  suites/test_certnames.c \
   suites/test_host.c \
   suites/test_hasher.c \
   suites/test_crypter.c \
@@ -500,6 +512,7 @@ tests_SOURCES = tests.h tests.c \
   suites/test_asn1_parser.c \
   suites/test_printf.c \
   suites/test_test_rng.c \
+  suites/test_mgf1.c \
   suites/test_ntru.c
 
 tests_CFLAGS = \
@@ -603,6 +616,8 @@ suites/tests-test_hashtable.$(OBJEXT): suites/$(am__dirstamp) \
 	suites/$(DEPDIR)/$(am__dirstamp)
 suites/tests-test_identification.$(OBJEXT): suites/$(am__dirstamp) \
 	suites/$(DEPDIR)/$(am__dirstamp)
+suites/tests-test_traffic_selector.$(OBJEXT): suites/$(am__dirstamp) \
+	suites/$(DEPDIR)/$(am__dirstamp)
 suites/tests-test_threading.$(OBJEXT): suites/$(am__dirstamp) \
 	suites/$(DEPDIR)/$(am__dirstamp)
 suites/tests-test_process.$(OBJEXT): suites/$(am__dirstamp) \
@@ -625,6 +640,10 @@ suites/tests-test_ecdsa.$(OBJEXT): suites/$(am__dirstamp) \
 	suites/$(DEPDIR)/$(am__dirstamp)
 suites/tests-test_rsa.$(OBJEXT): suites/$(am__dirstamp) \
 	suites/$(DEPDIR)/$(am__dirstamp)
+suites/tests-test_certpolicy.$(OBJEXT): suites/$(am__dirstamp) \
+	suites/$(DEPDIR)/$(am__dirstamp)
+suites/tests-test_certnames.$(OBJEXT): suites/$(am__dirstamp) \
+	suites/$(DEPDIR)/$(am__dirstamp)
 suites/tests-test_host.$(OBJEXT): suites/$(am__dirstamp) \
 	suites/$(DEPDIR)/$(am__dirstamp)
 suites/tests-test_hasher.$(OBJEXT): suites/$(am__dirstamp) \
@@ -643,6 +662,8 @@ suites/tests-test_printf.$(OBJEXT): suites/$(am__dirstamp) \
 	suites/$(DEPDIR)/$(am__dirstamp)
 suites/tests-test_test_rng.$(OBJEXT): suites/$(am__dirstamp) \
 	suites/$(DEPDIR)/$(am__dirstamp)
+suites/tests-test_mgf1.$(OBJEXT): suites/$(am__dirstamp) \
+	suites/$(DEPDIR)/$(am__dirstamp)
 suites/tests-test_ntru.$(OBJEXT): suites/$(am__dirstamp) \
 	suites/$(DEPDIR)/$(am__dirstamp)
 
@@ -667,6 +688,8 @@ distclean-compile:
 @AMDEP_TRUE@@am__include@ @am__quote at suites/$(DEPDIR)/tests-test_asn1_parser.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at suites/$(DEPDIR)/tests-test_bio_reader.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at suites/$(DEPDIR)/tests-test_bio_writer.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at suites/$(DEPDIR)/tests-test_certnames.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at suites/$(DEPDIR)/tests-test_certpolicy.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at suites/$(DEPDIR)/tests-test_chunk.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at suites/$(DEPDIR)/tests-test_crypter.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at suites/$(DEPDIR)/tests-test_crypto_factory.Po at am__quote@
@@ -680,6 +703,7 @@ distclean-compile:
 @AMDEP_TRUE@@am__include@ @am__quote at suites/$(DEPDIR)/tests-test_identification.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at suites/$(DEPDIR)/tests-test_linked_list.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at suites/$(DEPDIR)/tests-test_linked_list_enumerator.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at suites/$(DEPDIR)/tests-test_mgf1.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at suites/$(DEPDIR)/tests-test_ntru.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at suites/$(DEPDIR)/tests-test_pen.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at suites/$(DEPDIR)/tests-test_printf.Po at am__quote@
@@ -689,6 +713,7 @@ distclean-compile:
 @AMDEP_TRUE@@am__include@ @am__quote at suites/$(DEPDIR)/tests-test_stream.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at suites/$(DEPDIR)/tests-test_test_rng.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at suites/$(DEPDIR)/tests-test_threading.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at suites/$(DEPDIR)/tests-test_traffic_selector.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at suites/$(DEPDIR)/tests-test_utils.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at suites/$(DEPDIR)/tests-test_vectors.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at suites/$(DEPDIR)/tests-test_watcher.Po at am__quote@
@@ -879,6 +904,20 @@ suites/tests-test_identification.obj: suites/test_identification.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) $(tests_CFLAGS) $(CFLAGS) -c -o suites/tests-test_identification.obj `if test -f 'suites/test_identification.c'; then $(CYGPATH_W) 'suites/test_identification.c'; else $(CYGPATH_W) '$(srcdir)/suites/test_identification.c'; fi`
 
+suites/tests-test_traffic_selector.o: suites/test_traffic_selector.c
+ at am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(tests_CFLAGS) $(CFLAGS) -MT suites/tests-test_traffic_selector.o -MD -MP -MF suites/$(DEPDIR)/tests-test_traffic_selector.Tpo -c -o suites/tests-test_traffic_selector.o `test -f 'suites/test_traffic_selector.c' || echo '$(srcdir)/'`suites/test_traffic_selector.c
+ at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) suites/$(DEPDIR)/tests-test_traffic_selector.Tpo suites/$(DEPDIR)/tests-test_traffic_selector.Po
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='suites/test_traffic_selector.c' object='suites/tests-test_traffic_selector.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) $(tests_CFLAGS) $(CFLAGS) -c -o suites/tests-test_traffic_selector.o `test -f 'suites/test_traffic_selector.c' || echo '$(srcdir)/'`suites/test_traffic_selector.c
+
+suites/tests-test_traffic_selector.obj: suites/test_traffic_selector.c
+ at am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(tests_CFLAGS) $(CFLAGS) -MT suites/tests-test_traffic_selector.obj -MD -MP -MF suites/$(DEPDIR)/tests-test_traffic_selector.Tpo -c -o suites/tests-test_traffic_selector.obj `if test -f 'suites/test_traffic_selector.c'; then $(CYGPATH_W) 'suites/test_traffic_selector.c'; else $(CYGPATH_W) '$(srcdir)/suites/test_traffic_selector.c'; fi`
+ at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) suites/$(DEPDIR)/tests-test_traffic_selector.Tpo suites/$(DEPDIR)/tests-test_traffic_selector.Po
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='suites/test_traffic_selector.c' object='suites/tests-test_traffic_selector.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) $(tests_CFLAGS) $(CFLAGS) -c -o suites/tests-test_traffic_selector.obj `if test -f 'suites/test_traffic_selector.c'; then $(CYGPATH_W) 'suites/test_traffic_selector.c'; else $(CYGPATH_W) '$(srcdir)/suites/test_traffic_selector.c'; fi`
+
 suites/tests-test_threading.o: suites/test_threading.c
 @am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(tests_CFLAGS) $(CFLAGS) -MT suites/tests-test_threading.o -MD -MP -MF suites/$(DEPDIR)/tests-test_threading.Tpo -c -o suites/tests-test_threading.o `test -f 'suites/test_threading.c' || echo '$(srcdir)/'`suites/test_threading.c
 @am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) suites/$(DEPDIR)/tests-test_threading.Tpo suites/$(DEPDIR)/tests-test_threading.Po
@@ -1033,6 +1072,34 @@ suites/tests-test_rsa.obj: suites/test_rsa.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) $(tests_CFLAGS) $(CFLAGS) -c -o suites/tests-test_rsa.obj `if test -f 'suites/test_rsa.c'; then $(CYGPATH_W) 'suites/test_rsa.c'; else $(CYGPATH_W) '$(srcdir)/suites/test_rsa.c'; fi`
 
+suites/tests-test_certpolicy.o: suites/test_certpolicy.c
+ at am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(tests_CFLAGS) $(CFLAGS) -MT suites/tests-test_certpolicy.o -MD -MP -MF suites/$(DEPDIR)/tests-test_certpolicy.Tpo -c -o suites/tests-test_certpolicy.o `test -f 'suites/test_certpolicy.c' || echo '$(srcdir)/'`suites/test_certpolicy.c
+ at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) suites/$(DEPDIR)/tests-test_certpolicy.Tpo suites/$(DEPDIR)/tests-test_certpolicy.Po
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='suites/test_certpolicy.c' object='suites/tests-test_certpolicy.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) $(tests_CFLAGS) $(CFLAGS) -c -o suites/tests-test_certpolicy.o `test -f 'suites/test_certpolicy.c' || echo '$(srcdir)/'`suites/test_certpolicy.c
+
+suites/tests-test_certpolicy.obj: suites/test_certpolicy.c
+ at am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(tests_CFLAGS) $(CFLAGS) -MT suites/tests-test_certpolicy.obj -MD -MP -MF suites/$(DEPDIR)/tests-test_certpolicy.Tpo -c -o suites/tests-test_certpolicy.obj `if test -f 'suites/test_certpolicy.c'; then $(CYGPATH_W) 'suites/test_certpolicy.c'; else $(CYGPATH_W) '$(srcdir)/suites/test_certpolicy.c'; fi`
+ at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) suites/$(DEPDIR)/tests-test_certpolicy.Tpo suites/$(DEPDIR)/tests-test_certpolicy.Po
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='suites/test_certpolicy.c' object='suites/tests-test_certpolicy.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) $(tests_CFLAGS) $(CFLAGS) -c -o suites/tests-test_certpolicy.obj `if test -f 'suites/test_certpolicy.c'; then $(CYGPATH_W) 'suites/test_certpolicy.c'; else $(CYGPATH_W) '$(srcdir)/suites/test_certpolicy.c'; fi`
+
+suites/tests-test_certnames.o: suites/test_certnames.c
+ at am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(tests_CFLAGS) $(CFLAGS) -MT suites/tests-test_certnames.o -MD -MP -MF suites/$(DEPDIR)/tests-test_certnames.Tpo -c -o suites/tests-test_certnames.o `test -f 'suites/test_certnames.c' || echo '$(srcdir)/'`suites/test_certnames.c
+ at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) suites/$(DEPDIR)/tests-test_certnames.Tpo suites/$(DEPDIR)/tests-test_certnames.Po
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='suites/test_certnames.c' object='suites/tests-test_certnames.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) $(tests_CFLAGS) $(CFLAGS) -c -o suites/tests-test_certnames.o `test -f 'suites/test_certnames.c' || echo '$(srcdir)/'`suites/test_certnames.c
+
+suites/tests-test_certnames.obj: suites/test_certnames.c
+ at am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(tests_CFLAGS) $(CFLAGS) -MT suites/tests-test_certnames.obj -MD -MP -MF suites/$(DEPDIR)/tests-test_certnames.Tpo -c -o suites/tests-test_certnames.obj `if test -f 'suites/test_certnames.c'; then $(CYGPATH_W) 'suites/test_certnames.c'; else $(CYGPATH_W) '$(srcdir)/suites/test_certnames.c'; fi`
+ at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) suites/$(DEPDIR)/tests-test_certnames.Tpo suites/$(DEPDIR)/tests-test_certnames.Po
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='suites/test_certnames.c' object='suites/tests-test_certnames.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) $(tests_CFLAGS) $(CFLAGS) -c -o suites/tests-test_certnames.obj `if test -f 'suites/test_certnames.c'; then $(CYGPATH_W) 'suites/test_certnames.c'; else $(CYGPATH_W) '$(srcdir)/suites/test_certnames.c'; fi`
+
 suites/tests-test_host.o: suites/test_host.c
 @am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(tests_CFLAGS) $(CFLAGS) -MT suites/tests-test_host.o -MD -MP -MF suites/$(DEPDIR)/tests-test_host.Tpo -c -o suites/tests-test_host.o `test -f 'suites/test_host.c' || echo '$(srcdir)/'`suites/test_host.c
 @am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) suites/$(DEPDIR)/tests-test_host.Tpo suites/$(DEPDIR)/tests-test_host.Po
@@ -1159,6 +1226,20 @@ suites/tests-test_test_rng.obj: suites/test_test_rng.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) $(tests_CFLAGS) $(CFLAGS) -c -o suites/tests-test_test_rng.obj `if test -f 'suites/test_test_rng.c'; then $(CYGPATH_W) 'suites/test_test_rng.c'; else $(CYGPATH_W) '$(srcdir)/suites/test_test_rng.c'; fi`
 
+suites/tests-test_mgf1.o: suites/test_mgf1.c
+ at am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(tests_CFLAGS) $(CFLAGS) -MT suites/tests-test_mgf1.o -MD -MP -MF suites/$(DEPDIR)/tests-test_mgf1.Tpo -c -o suites/tests-test_mgf1.o `test -f 'suites/test_mgf1.c' || echo '$(srcdir)/'`suites/test_mgf1.c
+ at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) suites/$(DEPDIR)/tests-test_mgf1.Tpo suites/$(DEPDIR)/tests-test_mgf1.Po
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='suites/test_mgf1.c' object='suites/tests-test_mgf1.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) $(tests_CFLAGS) $(CFLAGS) -c -o suites/tests-test_mgf1.o `test -f 'suites/test_mgf1.c' || echo '$(srcdir)/'`suites/test_mgf1.c
+
+suites/tests-test_mgf1.obj: suites/test_mgf1.c
+ at am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(tests_CFLAGS) $(CFLAGS) -MT suites/tests-test_mgf1.obj -MD -MP -MF suites/$(DEPDIR)/tests-test_mgf1.Tpo -c -o suites/tests-test_mgf1.obj `if test -f 'suites/test_mgf1.c'; then $(CYGPATH_W) 'suites/test_mgf1.c'; else $(CYGPATH_W) '$(srcdir)/suites/test_mgf1.c'; fi`
+ at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) suites/$(DEPDIR)/tests-test_mgf1.Tpo suites/$(DEPDIR)/tests-test_mgf1.Po
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='suites/test_mgf1.c' object='suites/tests-test_mgf1.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) $(tests_CFLAGS) $(CFLAGS) -c -o suites/tests-test_mgf1.obj `if test -f 'suites/test_mgf1.c'; then $(CYGPATH_W) 'suites/test_mgf1.c'; else $(CYGPATH_W) '$(srcdir)/suites/test_mgf1.c'; fi`
+
 suites/tests-test_ntru.o: suites/test_ntru.c
 @am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(tests_CFLAGS) $(CFLAGS) -MT suites/tests-test_ntru.o -MD -MP -MF suites/$(DEPDIR)/tests-test_ntru.Tpo -c -o suites/tests-test_ntru.o `test -f 'suites/test_ntru.c' || echo '$(srcdir)/'`suites/test_ntru.c
 @am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) suites/$(DEPDIR)/tests-test_ntru.Tpo suites/$(DEPDIR)/tests-test_ntru.Po
diff --git a/src/libstrongswan/tests/suites/test_certnames.c b/src/libstrongswan/tests/suites/test_certnames.c
new file mode 100644
index 0000000..e307028
--- /dev/null
+++ b/src/libstrongswan/tests/suites/test_certnames.c
@@ -0,0 +1,398 @@
+/*
+ * Copyright (C) 2014 Martin Willi
+ * Copyright (C) 2014 revosec AG
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * for more details.
+ */
+
+#include "test_suite.h"
+
+#include <asn1/asn1.h>
+#include <credentials/sets/mem_cred.h>
+#include <credentials/certificates/x509.h>
+
+/**
+ * RSA private key, so we don't have to generate one
+ */
+static char keydata[] = {
+  0x30,0x82,0x02,0x5e,0x02,0x01,0x00,0x02,0x81,0x81,0x00,0xb1,0x9b,0xd4,0x51,0x24,
+  0xfc,0x56,0x1d,0x3d,0xfb,0xa2,0xea,0x37,0x02,0x70,0x72,0x87,0x84,0x2f,0x3b,0x2d,
+  0x6e,0x22,0xef,0x3f,0x37,0x04,0xb2,0x6f,0xb7,0xe7,0xd8,0x58,0x05,0xde,0x34,0xbf,
+  0x99,0xe6,0x40,0x7a,0x56,0xa7,0x73,0xf5,0x98,0xcb,0xb0,0x37,0x90,0x5e,0xd1,0x3f,
+  0xf4,0x73,0x50,0x7f,0x53,0x8e,0xf1,0x04,0x25,0xb4,0x77,0x22,0x4e,0x8a,0x9d,0x27,
+  0x8f,0x6f,0xaf,0x59,0xbd,0xb0,0x0f,0xf0,0xaa,0x11,0x94,0x66,0x16,0x10,0x58,0xad,
+  0x77,0xa1,0xac,0x58,0xb4,0xd0,0x0d,0xbc,0x11,0xe0,0xc0,0xe9,0x29,0xdc,0x42,0x63,
+  0x01,0x23,0x4f,0x28,0x41,0x6d,0x34,0x9e,0x0c,0x4a,0xc8,0x62,0x83,0xb5,0x71,0x71,
+  0x0b,0x51,0xc0,0x4c,0x37,0xd4,0x68,0x19,0x52,0x9a,0x8b,0x02,0x03,0x01,0x00,0x01,
+  0x02,0x81,0x81,0x00,0x82,0xca,0x33,0x16,0xb2,0x3a,0xd4,0x1b,0x62,0x9a,0x9c,0xc5,
+  0x07,0x4f,0x57,0x89,0x2f,0x7c,0x4a,0xdf,0xb4,0x3b,0xc7,0xa4,0x11,0x14,0x2d,0xf4,
+  0x4c,0xca,0xcc,0x03,0x88,0x06,0x82,0x34,0xab,0xe7,0xe4,0x24,0x15,0x33,0x1c,0xcb,
+  0x0a,0xcf,0xc3,0x27,0x78,0x33,0x6b,0x6f,0x82,0x3e,0x3c,0x70,0xc9,0xe2,0xb9,0x7f,
+  0x88,0xc3,0x4f,0x59,0xb5,0x8e,0xa3,0x81,0xd9,0x88,0x1f,0xc0,0x38,0xbc,0xc8,0x93,
+  0x40,0x0f,0x43,0xd8,0x72,0x12,0xb4,0xcc,0x6d,0x76,0x0a,0x6f,0x01,0x05,0xa8,0x88,
+  0xf4,0x57,0x44,0xd2,0x05,0xc4,0x77,0xf5,0xfb,0x1b,0xf3,0xb2,0x0d,0x90,0xb8,0xb4,
+  0x63,0x62,0x70,0x2c,0xe4,0x28,0xd8,0x20,0x10,0x85,0x4a,0x5e,0x63,0xa9,0xb0,0xdd,
+  0xba,0xd0,0x32,0x49,0x02,0x41,0x00,0xdb,0x77,0xf1,0xdd,0x1a,0x12,0xc5,0xfb,0x2b,
+  0x5b,0xb2,0xcd,0xb6,0xd0,0x4c,0xc4,0xe5,0x93,0xd6,0xf8,0x88,0xfc,0x18,0x40,0x21,
+  0x9c,0xf7,0x2d,0x60,0x6f,0x91,0xf5,0x73,0x3c,0xf7,0x7f,0x67,0x1d,0x5b,0xb5,0xee,
+  0x29,0xc1,0xd4,0xc6,0xdb,0x44,0x4c,0x40,0x05,0x63,0xaa,0x71,0x95,0x18,0x14,0xa7,
+  0x23,0x9f,0x7a,0xee,0x7f,0xb5,0xc7,0x02,0x41,0x00,0xcf,0x2c,0x24,0x50,0x65,0xf4,
+  0x94,0x7b,0xe9,0xf3,0x13,0x77,0xea,0x27,0x3c,0x6f,0x03,0x84,0xa7,0x7d,0xa2,0x54,
+  0x40,0x97,0x82,0x0e,0xd9,0x09,0x9f,0x4a,0xa6,0x75,0xe5,0x66,0xe4,0x9c,0x59,0xd9,
+  0x3a,0xe6,0xf7,0xd8,0x8b,0x68,0xb0,0x21,0x52,0x31,0xb3,0x4a,0xa0,0x2c,0x41,0xd7,
+  0x1f,0x7b,0xe2,0x0f,0x15,0xc9,0x6e,0xc0,0xe5,0x1d,0x02,0x41,0x00,0x9c,0x1a,0x61,
+  0x9f,0x89,0xc7,0x26,0xa9,0x33,0xba,0xe2,0xa0,0x6d,0xd3,0x15,0x77,0xcb,0x6f,0xef,
+  0xad,0x12,0x0a,0x75,0xd9,0x4f,0xcf,0x4d,0x05,0x2a,0x9d,0xd1,0x2c,0xcb,0xcd,0xe6,
+  0xa0,0xe9,0x20,0x39,0xb6,0x5a,0xf3,0xba,0x99,0xf4,0xe3,0xcb,0x5d,0x8d,0x00,0x08,
+  0x57,0x18,0xb9,0x1a,0xca,0xbd,0xe3,0x99,0xb1,0x1f,0xe9,0x18,0xcb,0x02,0x40,0x65,
+  0x35,0x1b,0x48,0x6b,0x86,0x60,0x43,0x68,0xb6,0xe6,0xfb,0xdd,0xd7,0xed,0x1e,0x0e,
+  0x89,0xef,0x88,0xe0,0x94,0x68,0x39,0x9b,0xbf,0xc5,0x27,0x7e,0x39,0xe9,0xb8,0x0e,
+  0xa9,0x85,0x65,0x1c,0x3f,0x93,0x16,0xe2,0x5d,0x57,0x3d,0x7d,0x4d,0xc9,0xe9,0x9d,
+  0xbd,0x07,0x22,0x97,0xc7,0x90,0x09,0xe5,0x15,0x99,0x7f,0x1e,0x2b,0xfd,0xc1,0x02,
+  0x41,0x00,0x92,0x78,0xfe,0x04,0xa0,0x53,0xed,0x36,0x97,0xbd,0x16,0xce,0x91,0x9b,
+  0xbe,0x1f,0x8e,0x40,0x00,0x99,0x0c,0x49,0x15,0xca,0x59,0xd3,0xe3,0xd4,0xeb,0x71,
+  0xcf,0xda,0xd7,0xc8,0x99,0x74,0xfc,0x6b,0xe8,0xfd,0xe5,0xe0,0x49,0x61,0xcb,0xda,
+  0xe3,0xe7,0x8b,0x72,0xb5,0x69,0x73,0x2b,0x8b,0x54,0xcb,0xd9,0x48,0x6d,0x61,0x02,
+  0x49,0xe8,
+};
+
+/**
+ * Issue a certificate with permitted/excluded name constraints
+ */
+static certificate_t* create_cert(certificate_t *ca, char *subject, char *san,
+								x509_flag_t flags, identification_t *permitted,
+								identification_t *excluded)
+{
+	private_key_t *privkey;
+	public_key_t *pubkey;
+	certificate_t *cert;
+	identification_t *id;
+	linked_list_t *plist, *elist, *sans;
+
+	privkey = lib->creds->create(lib->creds, CRED_PRIVATE_KEY, KEY_RSA,
+								 BUILD_BLOB_ASN1_DER, chunk_from_thing(keydata),
+								 BUILD_END);
+	ck_assert(privkey);
+	pubkey = privkey->get_public_key(privkey);
+	ck_assert(pubkey);
+	plist = linked_list_create();
+	if (permitted)
+	{
+		plist->insert_last(plist, permitted);
+	}
+	elist = linked_list_create();
+	if (excluded)
+	{
+		elist->insert_last(elist, excluded);
+	}
+	sans = linked_list_create();
+	if (san)
+	{
+		id = identification_create_from_string(san);
+		sans->insert_last(sans, id);
+	}
+	id = identification_create_from_string(subject);
+	cert = lib->creds->create(lib->creds, CRED_CERTIFICATE, CERT_X509,
+						BUILD_SIGNING_KEY, privkey,
+						BUILD_PUBLIC_KEY, pubkey,
+						BUILD_SUBJECT, id,
+						BUILD_X509_FLAG, flags,
+						BUILD_SIGNING_CERT, ca,
+						BUILD_SUBJECT_ALTNAMES, sans,
+						BUILD_PERMITTED_NAME_CONSTRAINTS, plist,
+						BUILD_EXCLUDED_NAME_CONSTRAINTS, elist,
+						BUILD_END);
+	ck_assert(cert);
+	id->destroy(id);
+	sans->destroy_offset(sans, offsetof(identification_t, destroy));
+	plist->destroy_offset(plist, offsetof(identification_t, destroy));
+	elist->destroy_offset(elist, offsetof(identification_t, destroy));
+	privkey->destroy(privkey);
+	pubkey->destroy(pubkey);
+
+	return cert;
+}
+
+/**
+ * Check if a certificate with given subject has a valid trustchain
+ */
+static bool check_trust(identification_t *subject)
+{
+	enumerator_t *certs;
+	certificate_t *cert;
+	bool trusted;
+
+	certs = lib->credmgr->create_trusted_enumerator(lib->credmgr, KEY_ANY,
+													subject, FALSE);
+	trusted = certs->enumerate(certs, &cert, NULL);
+	certs->destroy(certs);
+
+	return trusted;
+}
+
+static mem_cred_t *creds;
+
+START_SETUP(setup)
+{
+	creds = mem_cred_create();
+	lib->credmgr->add_set(lib->credmgr, &creds->set);
+}
+END_SETUP
+
+START_TEARDOWN(teardown)
+{
+	lib->credmgr->remove_set(lib->credmgr, &creds->set);
+	creds->destroy(creds);
+	lib->credmgr->flush_cache(lib->credmgr, CERT_ANY);
+}
+END_TEARDOWN
+
+static struct {
+	char *constraint;
+	char *subject;
+	bool good;
+} permitted_dn[] = {
+	{ "C=CH, O=strongSwan", "C=CH, O=strongSwan, CN=tester", TRUE },
+	{ "C=CH, O=strongSwan", "C=CH, O=strong", FALSE },
+	{ "C=CH, O=strongSwan", "C=CH, O=strong, CN=tester", FALSE },
+	{ "C=CH, O=strongSwan", "C=CH, O=another, CN=tester", FALSE },
+	{ "C=CH, O=strongSwan", "C=CH, CN=tester, O=strongSwan", FALSE },
+};
+
+START_TEST(test_permitted_dn)
+{
+	certificate_t *ca, *im, *sj;
+	identification_t *id;
+
+	id = identification_create_from_string(permitted_dn[_i].constraint);
+	ca = create_cert(NULL, "C=CH, O=strongSwan, CN=CA", NULL, X509_CA, id, NULL);
+	id = identification_create_from_string(permitted_dn[_i].constraint);
+	im = create_cert(ca, "C=CH, O=strongSwan, CN=IM", NULL, X509_CA, id, NULL);
+	sj = create_cert(im, permitted_dn[_i].subject, NULL, 0, NULL, NULL);
+
+	creds->add_cert(creds, TRUE, ca);
+	creds->add_cert(creds, FALSE, im);
+	creds->add_cert(creds, FALSE, sj);
+
+	ck_assert(check_trust(sj->get_subject(sj)) == permitted_dn[_i].good);
+}
+END_TEST
+
+static struct {
+	id_type_t ctype;
+	char *cdata;
+	char *subject;
+	bool good;
+} permitted_san[] = {
+	{ ID_FQDN, ".strongswan.org", "test.strongswan.org", TRUE },
+	{ ID_FQDN, "strongswan.org", "test.strongswan.org", TRUE },
+	{ ID_FQDN, "a.b.c.strongswan.org", "d.a.b.c.strongswan.org", TRUE },
+	{ ID_FQDN, "a.b.c.strongswan.org", "a.b.c.d.strongswan.org", FALSE },
+	{ ID_FQDN, "strongswan.org", "strongswan.org.com", FALSE },
+	{ ID_FQDN, ".strongswan.org", "strongswan.org", FALSE },
+	{ ID_FQDN, "strongswan.org", "nostrongswan.org", FALSE },
+	{ ID_FQDN, "strongswan.org", "swan.org", FALSE },
+	{ ID_FQDN, "strongswan.org", "swan.org", FALSE },
+	{ ID_RFC822_ADDR, "tester at strongswan.org", "tester at strongswan.org", TRUE },
+	{ ID_RFC822_ADDR, "tester at strongswan.org", "atester at strongswan.org", FALSE },
+	{ ID_RFC822_ADDR, "strongswan.org", "tester at strongswan.org", TRUE },
+	{ ID_RFC822_ADDR, "strongswan.org", "tester at test.strongswan.org", FALSE },
+	{ ID_RFC822_ADDR, ".strongswan.org", "tester at test.strongswan.org", TRUE },
+	{ ID_RFC822_ADDR, ".strongswan.org", "tester at strongswan.org", FALSE },
+};
+
+START_TEST(test_permitted_san)
+{
+	certificate_t *ca, *sj;
+	identification_t *id;
+
+	id = identification_create_from_encoding(permitted_san[_i].ctype,
+									chunk_from_str(permitted_san[_i].cdata));
+	ca = create_cert(NULL, "CN=CA", NULL, X509_CA, id, NULL);
+	sj = create_cert(ca, "CN=SJ", permitted_san[_i].subject, 0, NULL, NULL);
+
+	creds->add_cert(creds, TRUE, ca);
+	creds->add_cert(creds, FALSE, sj);
+
+	ck_assert(check_trust(sj->get_subject(sj)) == permitted_san[_i].good);
+}
+END_TEST
+
+static struct {
+	char *constraint;
+	char *subject;
+	bool good;
+} excluded_dn[] = {
+	{ "C=CH, O=another", "C=CH, O=strongSwan, CN=tester", TRUE },
+	{ "C=CH, O=another", "C=CH, O=anot", TRUE },
+	{ "C=CH, O=another", "C=CH, O=anot, CN=tester", TRUE },
+	{ "C=CH, O=another", "C=CH, O=another, CN=tester", FALSE },
+	{ "C=CH, O=another", "C=CH, CN=tester, O=another", TRUE },
+};
+
+START_TEST(test_excluded_dn)
+{
+	certificate_t *ca, *im, *sj;
+	identification_t *id;
+
+	id = identification_create_from_string(excluded_dn[_i].constraint);
+	ca = create_cert(NULL, "C=CH, O=strongSwan, CN=CA", NULL, X509_CA, NULL, id);
+	id = identification_create_from_string(excluded_dn[_i].constraint);
+	im = create_cert(ca, "C=CH, O=strongSwan, CN=IM", NULL, X509_CA, NULL, id);
+	sj = create_cert(im, excluded_dn[_i].subject, NULL, 0, NULL, NULL);
+
+	creds->add_cert(creds, TRUE, ca);
+	creds->add_cert(creds, FALSE, im);
+	creds->add_cert(creds, FALSE, sj);
+
+	ck_assert(check_trust(sj->get_subject(sj)) == excluded_dn[_i].good);
+}
+END_TEST
+
+static struct {
+	id_type_t ctype;
+	char *cdata;
+	char *subject;
+	bool good;
+} excluded_san[] = {
+	{ ID_FQDN, ".strongswan.org", "test.strongswan.org", FALSE },
+	{ ID_FQDN, "strongswan.org", "test.strongswan.org", FALSE },
+	{ ID_FQDN, "a.b.c.strongswan.org", "d.a.b.c.strongswan.org", FALSE },
+	{ ID_FQDN, "a.b.c.strongswan.org", "a.b.c.d.strongswan.org", TRUE },
+	{ ID_FQDN, "strongswan.org", "strongswan.org.com", TRUE },
+	{ ID_FQDN, ".strongswan.org", "strongswan.org", TRUE },
+	{ ID_FQDN, "strongswan.org", "nostrongswan.org", TRUE },
+	{ ID_FQDN, "strongswan.org", "swan.org", TRUE },
+	{ ID_FQDN, "strongswan.org", "swan.org", TRUE },
+	{ ID_RFC822_ADDR, "tester at strongswan.org", "tester at strongswan.org", FALSE },
+	{ ID_RFC822_ADDR, "tester at strongswan.org", "atester at strongswan.org", TRUE },
+	{ ID_RFC822_ADDR, "strongswan.org", "tester at strongswan.org", FALSE },
+	{ ID_RFC822_ADDR, "strongswan.org", "tester at test.strongswan.org", TRUE },
+	{ ID_RFC822_ADDR, ".strongswan.org", "tester at test.strongswan.org", FALSE },
+	{ ID_RFC822_ADDR, ".strongswan.org", "tester at strongswan.org", TRUE },
+};
+
+START_TEST(test_excluded_san)
+{
+	certificate_t *ca, *sj;
+	identification_t *id;
+
+	id = identification_create_from_encoding(excluded_san[_i].ctype,
+									chunk_from_str(excluded_san[_i].cdata));
+	ca = create_cert(NULL, "CN=CA", NULL, X509_CA, NULL, id);
+	sj = create_cert(ca, "CN=SJ", excluded_san[_i].subject, 0, NULL, NULL);
+
+	creds->add_cert(creds, TRUE, ca);
+	creds->add_cert(creds, FALSE, sj);
+
+	ck_assert(check_trust(sj->get_subject(sj)) == excluded_san[_i].good);
+}
+END_TEST
+
+static struct {
+	char *caconst;
+	char *imconst;
+	char *subject;
+	bool good;
+} permitted_dninh[] = {
+	{ "C=CH", "C=CH, O=strongSwan", "C=CH, O=strongSwan, CN=tester", TRUE },
+	{ "C=CH", "C=DE, O=strongSwan", "C=CH, O=strongSwan, CN=tester", FALSE },
+	{ "C=CH, O=strongSwan", "C=CH", "C=CH", FALSE },
+};
+
+START_TEST(test_permitted_dninh)
+{
+	certificate_t *ca, *im, *sj;
+	identification_t *id;
+
+	id = identification_create_from_string(permitted_dninh[_i].caconst);
+	ca = create_cert(NULL, "C=CH, O=strongSwan, CN=CA", NULL, X509_CA, id, NULL);
+	id = identification_create_from_string(permitted_dninh[_i].imconst);
+	im = create_cert(ca, "C=CH, O=strongSwan, CN=IM", NULL, X509_CA, id, NULL);
+	sj = create_cert(im, permitted_dninh[_i].subject, NULL, 0, NULL, NULL);
+
+	creds->add_cert(creds, TRUE, ca);
+	creds->add_cert(creds, FALSE, im);
+	creds->add_cert(creds, FALSE, sj);
+
+	ck_assert(check_trust(sj->get_subject(sj)) == permitted_dninh[_i].good);
+}
+END_TEST
+
+static struct {
+	char *caconst;
+	char *imconst;
+	char *subject;
+	bool good;
+} excluded_dninh[] = {
+	{ "C=CH, O=strongSwan", "C=CH", "C=DE", TRUE },
+	{ "C=CH, O=strongSwan", "C=DE", "C=CH", FALSE },
+	{ "C=CH", "C=CH, O=strongSwan", "C=CH, O=strongSwan, CN=tester", FALSE },
+};
+
+START_TEST(test_excluded_dninh)
+{
+	certificate_t *ca, *im, *sj;
+	identification_t *id;
+
+	id = identification_create_from_string(excluded_dninh[_i].caconst);
+	ca = create_cert(NULL, "C=CH, O=strongSwan, CN=CA", NULL, X509_CA, NULL, id);
+	id = identification_create_from_string(excluded_dninh[_i].imconst);
+	im = create_cert(ca, "C=DE, CN=IM", NULL, X509_CA, NULL, id);
+	sj = create_cert(im, excluded_dninh[_i].subject, NULL, 0, NULL, NULL);
+
+	creds->add_cert(creds, TRUE, ca);
+	creds->add_cert(creds, FALSE, im);
+	creds->add_cert(creds, FALSE, sj);
+
+	ck_assert(check_trust(sj->get_subject(sj)) == excluded_dninh[_i].good);
+}
+END_TEST
+
+Suite *certnames_suite_create()
+{
+	Suite *s;
+	TCase *tc;
+
+	s = suite_create("certnames");
+
+	tc = tcase_create("permitted DN name constraints");
+	tcase_add_checked_fixture(tc, setup, teardown);
+	tcase_add_loop_test(tc, test_permitted_dn, 0, countof(permitted_dn));
+	suite_add_tcase(s, tc);
+
+	tc = tcase_create("permitted subjectAltName constraints");
+	tcase_add_checked_fixture(tc, setup, teardown);
+	tcase_add_loop_test(tc, test_permitted_san, 0, countof(permitted_san));
+	suite_add_tcase(s, tc);
+
+	tc = tcase_create("excluded DN constraints");
+	tcase_add_checked_fixture(tc, setup, teardown);
+	tcase_add_loop_test(tc, test_excluded_dn, 0, countof(excluded_dn));
+	suite_add_tcase(s, tc);
+
+	tc = tcase_create("excluded subjectAltName constraints");
+	tcase_add_checked_fixture(tc, setup, teardown);
+	tcase_add_loop_test(tc, test_excluded_san, 0, countof(excluded_san));
+	suite_add_tcase(s, tc);
+
+	tc = tcase_create("permitted DN name constraint inherit");
+	tcase_add_checked_fixture(tc, setup, teardown);
+	tcase_add_loop_test(tc, test_permitted_dninh, 0, countof(permitted_dninh));
+	suite_add_tcase(s, tc);
+
+	tc = tcase_create("excluded DN name constraint inherit");
+	tcase_add_checked_fixture(tc, setup, teardown);
+	tcase_add_loop_test(tc, test_excluded_dninh, 0, countof(excluded_dninh));
+	suite_add_tcase(s, tc);
+
+	return s;
+}
diff --git a/src/libstrongswan/tests/suites/test_certpolicy.c b/src/libstrongswan/tests/suites/test_certpolicy.c
new file mode 100644
index 0000000..7501e1a
--- /dev/null
+++ b/src/libstrongswan/tests/suites/test_certpolicy.c
@@ -0,0 +1,637 @@
+/*
+ * Copyright (C) 2014 Martin Willi
+ * Copyright (C) 2014 revosec AG
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * for more details.
+ */
+
+#include "test_suite.h"
+
+#include <asn1/asn1.h>
+#include <credentials/sets/mem_cred.h>
+#include <credentials/certificates/x509.h>
+
+/**
+ * RSA private key, so we don't have to generate one
+ */
+static char keydata[] = {
+  0x30,0x82,0x02,0x5e,0x02,0x01,0x00,0x02,0x81,0x81,0x00,0xb1,0x9b,0xd4,0x51,0x24,
+  0xfc,0x56,0x1d,0x3d,0xfb,0xa2,0xea,0x37,0x02,0x70,0x72,0x87,0x84,0x2f,0x3b,0x2d,
+  0x6e,0x22,0xef,0x3f,0x37,0x04,0xb2,0x6f,0xb7,0xe7,0xd8,0x58,0x05,0xde,0x34,0xbf,
+  0x99,0xe6,0x40,0x7a,0x56,0xa7,0x73,0xf5,0x98,0xcb,0xb0,0x37,0x90,0x5e,0xd1,0x3f,
+  0xf4,0x73,0x50,0x7f,0x53,0x8e,0xf1,0x04,0x25,0xb4,0x77,0x22,0x4e,0x8a,0x9d,0x27,
+  0x8f,0x6f,0xaf,0x59,0xbd,0xb0,0x0f,0xf0,0xaa,0x11,0x94,0x66,0x16,0x10,0x58,0xad,
+  0x77,0xa1,0xac,0x58,0xb4,0xd0,0x0d,0xbc,0x11,0xe0,0xc0,0xe9,0x29,0xdc,0x42,0x63,
+  0x01,0x23,0x4f,0x28,0x41,0x6d,0x34,0x9e,0x0c,0x4a,0xc8,0x62,0x83,0xb5,0x71,0x71,
+  0x0b,0x51,0xc0,0x4c,0x37,0xd4,0x68,0x19,0x52,0x9a,0x8b,0x02,0x03,0x01,0x00,0x01,
+  0x02,0x81,0x81,0x00,0x82,0xca,0x33,0x16,0xb2,0x3a,0xd4,0x1b,0x62,0x9a,0x9c,0xc5,
+  0x07,0x4f,0x57,0x89,0x2f,0x7c,0x4a,0xdf,0xb4,0x3b,0xc7,0xa4,0x11,0x14,0x2d,0xf4,
+  0x4c,0xca,0xcc,0x03,0x88,0x06,0x82,0x34,0xab,0xe7,0xe4,0x24,0x15,0x33,0x1c,0xcb,
+  0x0a,0xcf,0xc3,0x27,0x78,0x33,0x6b,0x6f,0x82,0x3e,0x3c,0x70,0xc9,0xe2,0xb9,0x7f,
+  0x88,0xc3,0x4f,0x59,0xb5,0x8e,0xa3,0x81,0xd9,0x88,0x1f,0xc0,0x38,0xbc,0xc8,0x93,
+  0x40,0x0f,0x43,0xd8,0x72,0x12,0xb4,0xcc,0x6d,0x76,0x0a,0x6f,0x01,0x05,0xa8,0x88,
+  0xf4,0x57,0x44,0xd2,0x05,0xc4,0x77,0xf5,0xfb,0x1b,0xf3,0xb2,0x0d,0x90,0xb8,0xb4,
+  0x63,0x62,0x70,0x2c,0xe4,0x28,0xd8,0x20,0x10,0x85,0x4a,0x5e,0x63,0xa9,0xb0,0xdd,
+  0xba,0xd0,0x32,0x49,0x02,0x41,0x00,0xdb,0x77,0xf1,0xdd,0x1a,0x12,0xc5,0xfb,0x2b,
+  0x5b,0xb2,0xcd,0xb6,0xd0,0x4c,0xc4,0xe5,0x93,0xd6,0xf8,0x88,0xfc,0x18,0x40,0x21,
+  0x9c,0xf7,0x2d,0x60,0x6f,0x91,0xf5,0x73,0x3c,0xf7,0x7f,0x67,0x1d,0x5b,0xb5,0xee,
+  0x29,0xc1,0xd4,0xc6,0xdb,0x44,0x4c,0x40,0x05,0x63,0xaa,0x71,0x95,0x18,0x14,0xa7,
+  0x23,0x9f,0x7a,0xee,0x7f,0xb5,0xc7,0x02,0x41,0x00,0xcf,0x2c,0x24,0x50,0x65,0xf4,
+  0x94,0x7b,0xe9,0xf3,0x13,0x77,0xea,0x27,0x3c,0x6f,0x03,0x84,0xa7,0x7d,0xa2,0x54,
+  0x40,0x97,0x82,0x0e,0xd9,0x09,0x9f,0x4a,0xa6,0x75,0xe5,0x66,0xe4,0x9c,0x59,0xd9,
+  0x3a,0xe6,0xf7,0xd8,0x8b,0x68,0xb0,0x21,0x52,0x31,0xb3,0x4a,0xa0,0x2c,0x41,0xd7,
+  0x1f,0x7b,0xe2,0x0f,0x15,0xc9,0x6e,0xc0,0xe5,0x1d,0x02,0x41,0x00,0x9c,0x1a,0x61,
+  0x9f,0x89,0xc7,0x26,0xa9,0x33,0xba,0xe2,0xa0,0x6d,0xd3,0x15,0x77,0xcb,0x6f,0xef,
+  0xad,0x12,0x0a,0x75,0xd9,0x4f,0xcf,0x4d,0x05,0x2a,0x9d,0xd1,0x2c,0xcb,0xcd,0xe6,
+  0xa0,0xe9,0x20,0x39,0xb6,0x5a,0xf3,0xba,0x99,0xf4,0xe3,0xcb,0x5d,0x8d,0x00,0x08,
+  0x57,0x18,0xb9,0x1a,0xca,0xbd,0xe3,0x99,0xb1,0x1f,0xe9,0x18,0xcb,0x02,0x40,0x65,
+  0x35,0x1b,0x48,0x6b,0x86,0x60,0x43,0x68,0xb6,0xe6,0xfb,0xdd,0xd7,0xed,0x1e,0x0e,
+  0x89,0xef,0x88,0xe0,0x94,0x68,0x39,0x9b,0xbf,0xc5,0x27,0x7e,0x39,0xe9,0xb8,0x0e,
+  0xa9,0x85,0x65,0x1c,0x3f,0x93,0x16,0xe2,0x5d,0x57,0x3d,0x7d,0x4d,0xc9,0xe9,0x9d,
+  0xbd,0x07,0x22,0x97,0xc7,0x90,0x09,0xe5,0x15,0x99,0x7f,0x1e,0x2b,0xfd,0xc1,0x02,
+  0x41,0x00,0x92,0x78,0xfe,0x04,0xa0,0x53,0xed,0x36,0x97,0xbd,0x16,0xce,0x91,0x9b,
+  0xbe,0x1f,0x8e,0x40,0x00,0x99,0x0c,0x49,0x15,0xca,0x59,0xd3,0xe3,0xd4,0xeb,0x71,
+  0xcf,0xda,0xd7,0xc8,0x99,0x74,0xfc,0x6b,0xe8,0xfd,0xe5,0xe0,0x49,0x61,0xcb,0xda,
+  0xe3,0xe7,0x8b,0x72,0xb5,0x69,0x73,0x2b,0x8b,0x54,0xcb,0xd9,0x48,0x6d,0x61,0x02,
+  0x49,0xe8,
+};
+
+/**
+ * Issue a certificate fr given policy, including extended flags
+ */
+static certificate_t* create_cert_ext(certificate_t *ca, char *subject,
+									  char *oid, x509_flag_t flags,
+									  char *map_s, char *map_i,
+									  u_int require_explicit,
+									  u_int inhibit_mapping,
+									  u_int inhibit_any)
+{
+	private_key_t *privkey;
+	public_key_t *pubkey;
+	certificate_t *cert;
+	identification_t *id;
+	linked_list_t *policies, *maps;
+	x509_cert_policy_t policy = {};
+	x509_policy_mapping_t map = {};
+
+	privkey = lib->creds->create(lib->creds, CRED_PRIVATE_KEY, KEY_RSA,
+								 BUILD_BLOB_ASN1_DER, chunk_from_thing(keydata),
+								 BUILD_END);
+	ck_assert(privkey);
+	pubkey = privkey->get_public_key(privkey);
+	ck_assert(pubkey);
+	policies = linked_list_create();
+	if (oid)
+	{
+		policy.oid = asn1_oid_from_string(oid);
+		ck_assert(policy.oid.ptr);
+		policies->insert_last(policies, &policy);
+	}
+	maps = linked_list_create();
+	if (map_s && map_i)
+	{
+		map.subject = asn1_oid_from_string(map_s);
+		ck_assert(map.subject.ptr);
+		map.issuer = asn1_oid_from_string(map_i);
+		ck_assert(map.issuer.ptr);
+		maps->insert_last(maps, &map);
+	}
+	id = identification_create_from_string(subject);
+	cert = lib->creds->create(lib->creds, CRED_CERTIFICATE, CERT_X509,
+						BUILD_SIGNING_KEY, privkey,
+						BUILD_PUBLIC_KEY, pubkey,
+						BUILD_SUBJECT, id,
+						BUILD_X509_FLAG, flags,
+						BUILD_CERTIFICATE_POLICIES, policies,
+						BUILD_POLICY_MAPPINGS, maps,
+						BUILD_SIGNING_CERT, ca,
+						BUILD_POLICY_REQUIRE_EXPLICIT, require_explicit,
+						BUILD_POLICY_INHIBIT_MAPPING, inhibit_mapping,
+						BUILD_POLICY_INHIBIT_ANY, inhibit_any,
+						BUILD_END);
+	ck_assert(cert);
+	id->destroy(id);
+	policies->destroy(policies);
+	maps->destroy(maps);
+	privkey->destroy(privkey);
+	pubkey->destroy(pubkey);
+	free(policy.oid.ptr);
+	free(map.subject.ptr);
+	free(map.issuer.ptr);
+
+	return cert;
+}
+
+/**
+ * Issue a certificate with given certificate policy and flags
+ */
+static certificate_t* create_cert(certificate_t *ca, char *subject,
+								  char *oid, x509_flag_t flags,
+								  char *map_s, char *map_i)
+{
+	return create_cert_ext(ca, subject, oid, flags, map_s, map_i,
+						   X509_NO_CONSTRAINT, X509_NO_CONSTRAINT,
+						   X509_NO_CONSTRAINT);
+}
+
+/**
+ * Check if a certificate with given subject has an oid
+ */
+static bool check_oid(identification_t *subject, char *oid)
+{
+	enumerator_t *certs, *auths;
+	certificate_t *cert;
+	auth_cfg_t *auth;
+	bool found = FALSE;
+	auth_rule_t type;
+	char *current;
+
+	certs = lib->credmgr->create_trusted_enumerator(lib->credmgr, KEY_ANY,
+													subject, FALSE);
+	if (!certs->enumerate(certs, &cert, &auth))
+	{
+		certs->destroy(certs);
+		ck_assert_msg(FALSE, "no trusted certificate found for %Y", subject);
+	}
+	auths = auth->create_enumerator(auth);
+	while (auths->enumerate(auths, &type, &current))
+	{
+		if (type == AUTH_RULE_CERT_POLICY)
+		{
+			if (streq(current, oid))
+			{
+				found = TRUE;
+				break;
+			}
+		}
+	}
+	auths->destroy(auths);
+	certs->destroy(certs);
+
+	return found;
+}
+
+/**
+ * Check if a certificate with given subject has a valid trustchain
+ */
+static bool check_trust(identification_t *subject)
+{
+	enumerator_t *certs;
+	certificate_t *cert;
+	bool trusted;
+
+	certs = lib->credmgr->create_trusted_enumerator(lib->credmgr, KEY_ANY,
+													subject, FALSE);
+	trusted = certs->enumerate(certs, &cert, NULL);
+	certs->destroy(certs);
+
+	return trusted;
+}
+
+static mem_cred_t *creds;
+
+static char *anyPolicy = "2.5.29.32.0";
+static char *extended = "2.23.140.1.1";
+static char *baseline = "2.23.140.1.2";
+
+START_SETUP(setup)
+{
+	creds = mem_cred_create();
+	lib->credmgr->add_set(lib->credmgr, &creds->set);
+}
+END_SETUP
+
+START_TEARDOWN(teardown)
+{
+	lib->credmgr->remove_set(lib->credmgr, &creds->set);
+	creds->destroy(creds);
+	lib->credmgr->flush_cache(lib->credmgr, CERT_ANY);
+}
+END_TEARDOWN
+
+START_TEST(test_valid_fixed)
+{
+	certificate_t *ca, *im, *sj;
+
+	ca = create_cert(NULL, "CN=CA", baseline, X509_CA, NULL, NULL);
+	im = create_cert(ca, "CN=IM", baseline, X509_CA, NULL, NULL);
+	sj = create_cert(im, "CN=SJ", baseline, 0, NULL, NULL);
+
+	creds->add_cert(creds, TRUE, ca);
+	creds->add_cert(creds, FALSE, im);
+	creds->add_cert(creds, FALSE, sj);
+
+	ck_assert(check_oid(sj->get_subject(sj), baseline));
+}
+END_TEST
+
+START_TEST(test_valid_any1)
+{
+	certificate_t *ca, *im, *sj;
+
+	ca = create_cert(NULL, "CN=CA", anyPolicy, X509_CA, NULL, NULL);
+	im = create_cert(ca, "CN=IM", baseline, X509_CA, NULL, NULL);
+	sj = create_cert(im, "CN=SJ", baseline, 0, NULL, NULL);
+
+	creds->add_cert(creds, TRUE, ca);
+	creds->add_cert(creds, FALSE, im);
+	creds->add_cert(creds, FALSE, sj);
+
+	ck_assert(check_oid(sj->get_subject(sj), baseline));
+}
+END_TEST
+
+START_TEST(test_valid_any2)
+{
+	certificate_t *ca, *im, *sj;
+
+	ca = create_cert(NULL, "CN=CA", anyPolicy, X509_CA, NULL, NULL);
+	im = create_cert(ca, "CN=IM", anyPolicy, X509_CA, NULL, NULL);
+	sj = create_cert(im, "CN=SJ", baseline, 0, NULL, NULL);
+
+	creds->add_cert(creds, TRUE, ca);
+	creds->add_cert(creds, FALSE, im);
+	creds->add_cert(creds, FALSE, sj);
+
+	ck_assert(check_oid(sj->get_subject(sj), baseline));
+}
+END_TEST
+
+START_TEST(test_invalid_missing)
+{
+	certificate_t *ca, *im, *sj;
+
+	ca = create_cert(NULL, "CN=CA", baseline, X509_CA, NULL, NULL);
+	im = create_cert(ca, "CN=IM", baseline, X509_CA, NULL, NULL);
+	sj = create_cert(im, "CN=SJ", NULL, 0, NULL, NULL);
+
+	creds->add_cert(creds, TRUE, ca);
+	creds->add_cert(creds, FALSE, im);
+	creds->add_cert(creds, FALSE, sj);
+
+	ck_assert(!check_oid(sj->get_subject(sj), baseline));
+}
+END_TEST
+
+START_TEST(test_invalid_wrong)
+{
+	certificate_t *ca, *im, *sj;
+
+	ca = create_cert(NULL, "CN=CA", baseline, X509_CA, NULL, NULL);
+	im = create_cert(ca, "CN=IM", baseline, X509_CA, NULL, NULL);
+	sj = create_cert(im, "CN=SJ", baseline, 0, NULL, NULL);
+
+	creds->add_cert(creds, TRUE, ca);
+	creds->add_cert(creds, FALSE, im);
+	creds->add_cert(creds, FALSE, sj);
+
+	ck_assert(!check_oid(sj->get_subject(sj), extended));
+}
+END_TEST
+
+START_TEST(test_invalid_any1)
+{
+	certificate_t *ca, *im, *sj;
+
+	ca = create_cert(NULL, "CN=CA", anyPolicy, X509_CA, NULL, NULL);
+	im = create_cert(ca, "CN=IM", anyPolicy, X509_CA, NULL, NULL);
+	sj = create_cert(im, "CN=SJ", NULL, 0, NULL, NULL);
+
+	creds->add_cert(creds, TRUE, ca);
+	creds->add_cert(creds, FALSE, im);
+	creds->add_cert(creds, FALSE, sj);
+
+	ck_assert(!check_oid(sj->get_subject(sj), baseline));
+}
+END_TEST
+
+START_TEST(test_invalid_any2)
+{
+	certificate_t *ca, *im, *sj;
+
+	ca = create_cert(NULL, "CN=CA", anyPolicy, X509_CA, NULL, NULL);
+	im = create_cert(ca, "CN=IM", anyPolicy, X509_CA, NULL, NULL);
+	sj = create_cert(im, "CN=SJ", anyPolicy, 0, NULL, NULL);
+
+	creds->add_cert(creds, TRUE, ca);
+	creds->add_cert(creds, FALSE, im);
+	creds->add_cert(creds, FALSE, sj);
+
+	ck_assert(!check_oid(sj->get_subject(sj), baseline));
+}
+END_TEST
+
+START_TEST(test_badchain_wrong)
+{
+	certificate_t *ca, *im, *sj;
+
+	ca = create_cert(NULL, "CN=CA", baseline, X509_CA, NULL, NULL);
+	im = create_cert(ca, "CN=IM", extended, X509_CA, NULL, NULL);
+	sj = create_cert(im, "CN=SJ", extended, 0, NULL, NULL);
+
+	creds->add_cert(creds, TRUE, ca);
+	creds->add_cert(creds, FALSE, im);
+	creds->add_cert(creds, FALSE, sj);
+
+	ck_assert(!check_oid(sj->get_subject(sj), baseline));
+	ck_assert(!check_oid(sj->get_subject(sj), extended));
+}
+END_TEST
+
+START_TEST(test_badchain_gap)
+{
+	certificate_t *ca, *im, *sj;
+
+	ca = create_cert(NULL, "CN=CA", baseline, X509_CA, NULL, NULL);
+	im = create_cert(ca, "CN=IM", NULL, X509_CA, NULL, NULL);
+	sj = create_cert(im, "CN=SJ", baseline, 0, NULL, NULL);
+
+	creds->add_cert(creds, TRUE, ca);
+	creds->add_cert(creds, FALSE, im);
+	creds->add_cert(creds, FALSE, sj);
+
+	ck_assert(!check_oid(sj->get_subject(sj), baseline));
+}
+END_TEST
+
+START_TEST(test_badchain_any)
+{
+	certificate_t *ca, *im, *sj;
+
+	ca = create_cert(NULL, "CN=CA", baseline, X509_CA, NULL, NULL);
+	im = create_cert(ca, "CN=IM", anyPolicy, X509_CA, NULL, NULL);
+	sj = create_cert(im, "CN=SJ", extended, 0, NULL, NULL);
+
+	creds->add_cert(creds, TRUE, ca);
+	creds->add_cert(creds, FALSE, im);
+	creds->add_cert(creds, FALSE, sj);
+
+	ck_assert(!check_oid(sj->get_subject(sj), extended));
+}
+END_TEST
+
+START_TEST(test_valid_mapping)
+{
+	certificate_t *ca, *im, *sj;
+
+	ca = create_cert(NULL, "CN=CA", anyPolicy, X509_CA, NULL, NULL);
+	im = create_cert(ca, "CN=IM", extended, X509_CA, baseline, extended);
+	sj = create_cert(im, "CN=SJ", baseline, 0, NULL, NULL);
+
+	creds->add_cert(creds, TRUE, ca);
+	creds->add_cert(creds, FALSE, im);
+	creds->add_cert(creds, FALSE, sj);
+
+	ck_assert(check_oid(sj->get_subject(sj), baseline));
+}
+END_TEST
+
+START_TEST(test_valid_mapping_twice)
+{
+	certificate_t *ca, *im, *sj;
+
+	ca = create_cert(NULL, "CN=CA", "2.23.140.1.3", X509_CA,
+					 extended, "2.23.140.1.3");
+	im = create_cert(ca, "CN=IM", extended, X509_CA, baseline, extended);
+	sj = create_cert(im, "CN=SJ", baseline, 0, NULL, NULL);
+
+	creds->add_cert(creds, TRUE, ca);
+	creds->add_cert(creds, FALSE, im);
+	creds->add_cert(creds, FALSE, sj);
+
+	ck_assert(check_oid(sj->get_subject(sj), baseline));
+}
+END_TEST
+
+START_TEST(test_invalid_mapping_loop)
+{
+	certificate_t *ca, *im, *sj;
+
+	ca = create_cert(NULL, "CN=CA", anyPolicy, X509_CA, NULL, NULL);
+	im = create_cert(ca, "CN=IM", extended, X509_CA, baseline, baseline);
+	sj = create_cert(im, "CN=SJ", baseline, 0, NULL, NULL);
+
+	creds->add_cert(creds, TRUE, ca);
+	creds->add_cert(creds, FALSE, im);
+	creds->add_cert(creds, FALSE, sj);
+
+	ck_assert(!check_oid(sj->get_subject(sj), baseline));
+}
+END_TEST
+
+START_TEST(test_invalid_mapping_notallowed)
+{
+	certificate_t *ca, *im, *sj;
+
+	ca = create_cert(NULL, "CN=CA", baseline, X509_CA, NULL, NULL);
+	im = create_cert(ca, "CN=IM", extended, X509_CA, baseline, extended);
+	sj = create_cert(im, "CN=SJ", baseline, 0, NULL, NULL);
+
+	creds->add_cert(creds, TRUE, ca);
+	creds->add_cert(creds, FALSE, im);
+	creds->add_cert(creds, FALSE, sj);
+
+	ck_assert(!check_oid(sj->get_subject(sj), baseline));
+}
+END_TEST
+
+START_TEST(test_invalid_mapping_nopolicy)
+{
+	certificate_t *ca, *im, *sj;
+
+	ca = create_cert(NULL, "CN=CA", baseline, X509_CA, NULL, NULL);
+	im = create_cert(ca, "CN=IM", "2.23.140.1.3", X509_CA, baseline, extended);
+	sj = create_cert(im, "CN=SJ", baseline, 0, NULL, NULL);
+
+	creds->add_cert(creds, TRUE, ca);
+	creds->add_cert(creds, FALSE, im);
+	creds->add_cert(creds, FALSE, sj);
+
+	ck_assert(!check_oid(sj->get_subject(sj), baseline));
+}
+END_TEST
+
+START_TEST(test_inhibit_mapping_good)
+{
+	certificate_t *ca, *im, *sj;
+
+	ca = create_cert_ext(NULL, "CN=CA", extended, X509_CA, NULL, NULL,
+						 X509_NO_CONSTRAINT, 1, X509_NO_CONSTRAINT);
+	im = create_cert(ca, "CN=IM", extended, X509_CA, baseline, extended);
+	sj = create_cert(im, "CN=SJ", baseline, 0, NULL, NULL);
+
+	creds->add_cert(creds, TRUE, ca);
+	creds->add_cert(creds, FALSE, im);
+	creds->add_cert(creds, FALSE, sj);
+
+	ck_assert(check_oid(sj->get_subject(sj), baseline));
+}
+END_TEST
+
+START_TEST(test_inhibit_mapping_bad)
+{
+	certificate_t *ca, *i1, *i2, *sj;
+
+	ca = create_cert_ext(NULL, "CN=CA", extended, X509_CA, NULL, NULL,
+						 X509_NO_CONSTRAINT, 1, X509_NO_CONSTRAINT);
+	i1 = create_cert(ca, "CN=IM1", extended, X509_CA, NULL, NULL);
+	i2 = create_cert(i1, "CN=IM2", extended, X509_CA, baseline, extended);
+	sj = create_cert(i2, "CN=SJ", baseline, 0, NULL, NULL);
+
+	creds->add_cert(creds, TRUE, ca);
+	creds->add_cert(creds, FALSE, i1);
+	creds->add_cert(creds, FALSE, i2);
+	creds->add_cert(creds, FALSE, sj);
+
+	/* TODO: we currently reject the certificate completely, but should
+	 * actually just invalidate the policy not mapped properly */
+	ck_assert(!check_trust(sj->get_subject(sj)));
+}
+END_TEST
+
+START_TEST(test_inhibit_any_good)
+{
+	certificate_t *ca, *im, *sj;
+
+	ca = create_cert_ext(NULL, "CN=CA", anyPolicy, X509_CA, NULL, NULL,
+						 X509_NO_CONSTRAINT, X509_NO_CONSTRAINT, 1);
+	im = create_cert(ca, "CN=IM", anyPolicy, X509_CA, NULL, NULL);
+	sj = create_cert(im, "CN=SJ", baseline, 0, NULL, NULL);
+
+	creds->add_cert(creds, TRUE, ca);
+	creds->add_cert(creds, FALSE, im);
+	creds->add_cert(creds, FALSE, sj);
+
+	ck_assert(check_oid(sj->get_subject(sj), baseline));
+}
+END_TEST
+
+START_TEST(test_inhibit_any_bad)
+{
+	certificate_t *ca, *i1, *i2, *sj;
+
+	ca = create_cert_ext(NULL, "CN=CA", anyPolicy, X509_CA, NULL, NULL,
+						 X509_NO_CONSTRAINT, X509_NO_CONSTRAINT, 1);
+	i1 = create_cert(ca, "CN=IM1", anyPolicy, X509_CA, NULL, NULL);
+	i2 = create_cert(i1, "CN=IM2", anyPolicy, X509_CA, NULL, NULL);
+	sj = create_cert(i2, "CN=SJ", baseline, 0, NULL, NULL);
+
+	creds->add_cert(creds, TRUE, ca);
+	creds->add_cert(creds, FALSE, i1);
+	creds->add_cert(creds, FALSE, i2);
+	creds->add_cert(creds, FALSE, sj);
+
+	/* TODO: we currently reject the certificate completely, but should
+	 * actually just invalidate the policy relying on inhibited anyPolicy */
+	ck_assert(!check_trust(sj->get_subject(sj)));
+}
+END_TEST
+
+START_TEST(test_require_explicit_good)
+{
+	certificate_t *ca, *im, *sj;
+
+	ca = create_cert_ext(NULL, "CN=CA", anyPolicy, X509_CA, NULL, NULL,
+						 1, X509_NO_CONSTRAINT, X509_NO_CONSTRAINT);
+	im = create_cert(ca, "CN=IM", baseline, X509_CA, NULL, NULL);
+	sj = create_cert(im, "CN=SJ", baseline, 0, NULL, NULL);
+
+	creds->add_cert(creds, TRUE, ca);
+	creds->add_cert(creds, FALSE, im);
+	creds->add_cert(creds, FALSE, sj);
+
+	ck_assert(check_oid(sj->get_subject(sj), baseline));
+}
+END_TEST
+
+START_TEST(test_require_explicit_bad)
+{
+	certificate_t *ca, *i1, *i2, *sj;
+
+	ca = create_cert_ext(NULL, "CN=CA", anyPolicy, X509_CA, NULL, NULL,
+						 1, X509_NO_CONSTRAINT, X509_NO_CONSTRAINT);
+	i1 = create_cert(ca, "CN=IM1", extended, X509_CA, NULL, NULL);
+	i2 = create_cert(i1, "CN=IM2", extended, X509_CA, NULL, NULL);
+	sj = create_cert(i2, "CN=SJ", baseline, 0, NULL, NULL);
+
+	creds->add_cert(creds, TRUE, ca);
+	creds->add_cert(creds, FALSE, i1);
+	creds->add_cert(creds, FALSE, i2);
+	creds->add_cert(creds, FALSE, sj);
+
+	/* TODO: we currently reject the certificate completely, but should
+	 * actually just invalidate the policy violating requireExplicit */
+	ck_assert(!check_trust(sj->get_subject(sj)));
+}
+END_TEST
+
+Suite *certpolicy_suite_create()
+{
+	Suite *s;
+	TCase *tc;
+
+	s = suite_create("certpolicy");
+
+	tc = tcase_create("policy valid");
+	tcase_add_checked_fixture(tc, setup, teardown);
+	tcase_add_test(tc, test_valid_fixed);
+	tcase_add_test(tc, test_valid_any1);
+	tcase_add_test(tc, test_valid_any2);
+	suite_add_tcase(s, tc);
+
+	tc = tcase_create("policy invalid");
+	tcase_add_checked_fixture(tc, setup, teardown);
+	tcase_add_test(tc, test_invalid_missing);
+	tcase_add_test(tc, test_invalid_wrong);
+	tcase_add_test(tc, test_invalid_any1);
+	tcase_add_test(tc, test_invalid_any2);
+	suite_add_tcase(s, tc);
+
+	tc = tcase_create("policy badchain");
+	tcase_add_checked_fixture(tc, setup, teardown);
+	tcase_add_test(tc, test_badchain_wrong);
+	tcase_add_test(tc, test_badchain_gap);
+	tcase_add_test(tc, test_badchain_any);
+	suite_add_tcase(s, tc);
+
+	tc = tcase_create("policy valid mapping");
+	tcase_add_checked_fixture(tc, setup, teardown);
+	tcase_add_test(tc, test_valid_mapping);
+	tcase_add_test(tc, test_valid_mapping_twice);
+	suite_add_tcase(s, tc);
+
+	tc = tcase_create("policy invalid mapping");
+	tcase_add_checked_fixture(tc, setup, teardown);
+	tcase_add_test(tc, test_invalid_mapping_loop);
+	tcase_add_test(tc, test_invalid_mapping_notallowed);
+	tcase_add_test(tc, test_invalid_mapping_nopolicy);
+	suite_add_tcase(s, tc);
+
+	tc = tcase_create("inhibit policy mapping");
+	tcase_add_checked_fixture(tc, setup, teardown);
+	tcase_add_test(tc, test_inhibit_mapping_good);
+	tcase_add_test(tc, test_inhibit_mapping_bad);
+	suite_add_tcase(s, tc);
+
+	tc = tcase_create("inhibit any policy");
+	tcase_add_checked_fixture(tc, setup, teardown);
+	tcase_add_test(tc, test_inhibit_any_good);
+	tcase_add_test(tc, test_inhibit_any_bad);
+	suite_add_tcase(s, tc);
+
+	tc = tcase_create("require explicit policy");
+	tcase_add_checked_fixture(tc, setup, teardown);
+	tcase_add_test(tc, test_require_explicit_good);
+	tcase_add_test(tc, test_require_explicit_bad);
+	suite_add_tcase(s, tc);
+
+	return s;
+}
diff --git a/src/libstrongswan/tests/suites/test_chunk.c b/src/libstrongswan/tests/suites/test_chunk.c
index d71e010..b5d2365 100644
--- a/src/libstrongswan/tests/suites/test_chunk.c
+++ b/src/libstrongswan/tests/suites/test_chunk.c
@@ -787,6 +787,11 @@ END_TEST
  * test for chunk_internet_checksum[_inc]()
  */
 
+static inline u_int16_t compensate_alignment(u_int16_t val)
+{
+	return ((val & 0xff) << 8) | (val >> 8);
+}
+
 START_TEST(test_chunk_internet_checksum)
 {
 	chunk_t chunk;
@@ -804,9 +809,9 @@ START_TEST(test_chunk_internet_checksum)
 
 	/* need to compensate for even/odd alignment */
 	sum = chunk_internet_checksum(chunk_create(chunk.ptr, 9));
-	sum = ntohs(sum);
+	sum = compensate_alignment(sum);
 	sum = chunk_internet_checksum_inc(chunk_create(chunk.ptr+9, 11), sum);
-	sum = ntohs(sum);
+	sum = compensate_alignment(sum);
 	ck_assert_int_eq(0x442e, ntohs(sum));
 
 	chunk = chunk_from_chars(0x45,0x00,0x00,0x30,0x44,0x22,0x40,0x00,0x80,0x06,
@@ -821,9 +826,9 @@ START_TEST(test_chunk_internet_checksum)
 
 	/* need to compensate for even/odd alignment */
 	sum = chunk_internet_checksum(chunk_create(chunk.ptr, 9));
-	sum = ntohs(sum);
+	sum = compensate_alignment(sum);
 	sum = chunk_internet_checksum_inc(chunk_create(chunk.ptr+9, 10), sum);
-	sum = ntohs(sum);
+	sum = compensate_alignment(sum);
 	ck_assert_int_eq(0x4459, ntohs(sum));
 }
 END_TEST
diff --git a/src/libstrongswan/tests/suites/test_enum.c b/src/libstrongswan/tests/suites/test_enum.c
index b48b51c..53ebd29 100644
--- a/src/libstrongswan/tests/suites/test_enum.c
+++ b/src/libstrongswan/tests/suites/test_enum.c
@@ -58,6 +58,39 @@ ENUM_NEXT(test_enum_split_names, SPLIT5, SPLIT5, SPLIT4,
 ENUM_END(test_enum_split_names, SPLIT5);
 
 /*******************************************************************************
+ * enum flags
+ */
+enum {
+	FLAG1 = (1 << 0),
+	FLAG2 = (1 << 1),
+	FLAG3 = (1 << 2),
+	FLAG4 = (1 << 3),
+	FLAG5 = (1 << 4),
+	FLAG6 = (1 << 5),
+	FLAG7 = (1 << 6),
+	FLAG8 = (1 << 7),
+	FLAG9 = (1 << 8),
+	FLAG10 = (1 << 9),
+	FLAG11 = (1 << 10),
+	FLAG12 = (1 << 11),
+} test_enum_flags;
+
+ENUM_FLAGS(test_enum_flags_names, FLAG1, FLAG5,
+	"FLAG1", "FLAG2", "FLAG3", "FLAG4", "FLAG5");
+
+ENUM_FLAGS(test_enum_flags_incomplete_names, FLAG3, FLAG4,
+	"FLAG3", "FLAG4");
+
+ENUM_FLAGS(test_enum_flags_null_names, FLAG1, FLAG4,
+	"FLAG1", NULL, "FLAG3", NULL);
+
+ENUM_FLAGS(test_enum_flags_overflow_names, FLAG1, FLAG12,
+	"OVERFLOWFLAGLONGNAME1",  "OVERFLOWFLAGLONGNAME2",  "OVERFLOWFLAGLONGNAME3",
+	"OVERFLOWFLAGLONGNAME4",  "OVERFLOWFLAGLONGNAME5",  "OVERFLOWFLAGLONGNAME6",
+	"OVERFLOWFLAGLONGNAME7",  "OVERFLOWFLAGLONGNAME8",  "OVERFLOWFLAGLONGNAME9",
+	"OVERFLOWFLAGLONGNAME10", "OVERFLOWFLAGLONGNAME11", "OVERFLOWFLAGLONGNAME12");
+
+/*******************************************************************************
  * enum_to_name
  */
 
@@ -198,11 +231,52 @@ static struct {
 	{256, "(256)"},
 };
 
+/*******************************************************************************
+ * flag_to_name
+ */
+
+static struct {
+	int val;
+	char *str;
+} printf_tests_flags[] = {
+	{0, "(unset)"},
+	{FLAG1, "FLAG1"},
+	{FLAG2, "FLAG2"},
+	{FLAG3, "FLAG3"},
+	{FLAG4, "FLAG4"},
+	{FLAG5, "FLAG5"},
+	{FLAG1 | FLAG3, "FLAG1 | FLAG3"},
+	{FLAG1 | FLAG3 | 32, "FLAG1 | FLAG3 | (0x20)"},
+	{FLAG1 | FLAG3 | 32 | 64, "FLAG1 | FLAG3 | (0x20) | (0x40)"},
+	{0x20, "(0x20)"},
+	{0x80000000, "(0x80000000)"},
+	{0xFFFFF, "FLAG1 | FLAG2 | FLAG3 | FLAG4 | "
+			  "FLAG5 | (0x20) | (0x40) | (0x80) | "
+			 "(0x100) | (0x200) | (0x400) | (0x800) | "
+			 "(0x1000) | (0x2000) | (0x4000) | (0x8000) | "
+			 "(0x10000) | (0x20000) | (0x40000) | (0x80000)"},
+}, printf_tests_flags_incomplete[] = {
+	{FLAG1, "(0x1)"},
+	{FLAG1 | FLAG2 | FLAG3, "(0x1) | (0x2) | FLAG3"},
+	{FLAG3 | FLAG4 | FLAG5, "FLAG3 | FLAG4 | (0x10)"},
+}, printf_tests_flags_null[] = {
+	{FLAG1 | FLAG2 | FLAG3 | FLAG4, "FLAG1 | FLAG3"},
+}, printf_tests_flags_overflow[] = {
+	{0xFFFFFFFF, "(0xFFFFFFFF)"},
+}, printf_tests_flags_noflagenum[] = {
+	{-1, "(-1)"},
+	{6435, "(6435)"},
+}, enum_flags_to_string_tests[] = {
+	{-1, NULL},
+	{6435, NULL},
+};
+
 START_TEST(test_enum_printf_hook_cont)
 {
 	char buf[128];
 
-	snprintf(buf, sizeof(buf), "%N", test_enum_cont_names, printf_tests_cont[_i].val);
+	snprintf(buf, sizeof(buf), "%N",
+			 test_enum_cont_names, printf_tests_cont[_i].val);
 	ck_assert_str_eq(printf_tests_cont[_i].str, buf);
 }
 END_TEST
@@ -211,11 +285,89 @@ START_TEST(test_enum_printf_hook_split)
 {
 	char buf[128];
 
-	snprintf(buf, sizeof(buf), "%N", test_enum_split_names, printf_tests_split[_i].val);
+	snprintf(buf, sizeof(buf), "%N",
+			 test_enum_split_names, printf_tests_split[_i].val);
 	ck_assert_str_eq(printf_tests_split[_i].str, buf);
 }
 END_TEST
 
+START_TEST(test_enum_printf_hook_flags)
+{
+	char buf[1024];
+
+	snprintf(buf, sizeof(buf), "%N", test_enum_flags_names,
+			 printf_tests_flags[_i].val);
+	ck_assert_str_eq(printf_tests_flags[_i].str, buf);
+}
+END_TEST
+
+START_TEST(test_enum_printf_hook_flags_incomplete)
+{
+	char buf[1024];
+
+	snprintf(buf, sizeof(buf), "%N", test_enum_flags_incomplete_names,
+			 printf_tests_flags_incomplete[_i].val);
+	ck_assert_str_eq(printf_tests_flags_incomplete[_i].str, buf);
+}
+END_TEST
+
+START_TEST(test_enum_printf_hook_flags_null)
+{
+	char buf[1024];
+
+	snprintf(buf, sizeof(buf), "%N", test_enum_flags_null_names,
+			 printf_tests_flags_null[_i].val);
+	ck_assert_str_eq(printf_tests_flags_null[_i].str, buf);
+}
+END_TEST
+
+START_TEST(test_enum_printf_hook_flags_overflow)
+{
+	char buf[1024];
+
+	snprintf(buf, sizeof(buf), "%N", test_enum_flags_overflow_names,
+			 printf_tests_flags_overflow[_i].val);
+	ck_assert_str_eq(printf_tests_flags_overflow[_i].str, buf);
+}
+END_TEST
+
+START_TEST(test_enum_printf_hook_flags_noflagenum)
+{
+	char buf[1024];
+
+	snprintf(buf, sizeof(buf), "%N", test_enum_cont_names,
+			 printf_tests_flags_noflagenum[_i].val);
+	ck_assert_str_eq(printf_tests_flags_noflagenum[_i].str, buf);
+}
+END_TEST
+
+START_TEST(test_enum_flags_to_string)
+{
+	char buf[1], *str;
+
+	str = enum_flags_to_string(test_enum_flags_names,
+			enum_flags_to_string_tests[_i].val, buf, sizeof(buf));
+	if (str)
+	{
+		ck_assert_str_eq(enum_flags_to_string_tests[_i].str, str);
+	}
+	else
+	{
+		ck_assert(str == enum_flags_to_string_tests[_i].str);
+	}
+}
+END_TEST
+
+START_TEST(test_enum_flags_to_string_noflagenum)
+{
+	char buf[1024];
+
+	enum_flags_to_string(test_enum_cont_names,
+			printf_tests_flags_noflagenum[_i].val, buf, sizeof(buf));
+	ck_assert_str_eq(printf_tests_flags_noflagenum[_i].str, buf);
+}
+END_TEST
+
 START_TEST(test_enum_printf_hook_width)
 {
 	char buf[128];
@@ -246,9 +398,19 @@ Suite *enum_suite_create()
 	tcase_add_loop_test(tc, test_enum_from_name_split, 0, countof(enum_tests_split));
 	suite_add_tcase(s, tc);
 
+	tc = tcase_create("enum_flags_to_string");
+	tcase_add_loop_test(tc, test_enum_flags_to_string, 0, countof(enum_flags_to_string_tests));
+	tcase_add_loop_test(tc, test_enum_flags_to_string_noflagenum, 0, countof(printf_tests_flags_noflagenum));
+	suite_add_tcase(s, tc);
+
 	tc = tcase_create("enum_printf_hook");
 	tcase_add_loop_test(tc, test_enum_printf_hook_cont, 0, countof(printf_tests_cont));
 	tcase_add_loop_test(tc, test_enum_printf_hook_split, 0, countof(printf_tests_split));
+	tcase_add_loop_test(tc, test_enum_printf_hook_flags, 0, countof(printf_tests_flags));
+	tcase_add_loop_test(tc, test_enum_printf_hook_flags_incomplete, 0, countof(printf_tests_flags_incomplete));
+	tcase_add_loop_test(tc, test_enum_printf_hook_flags_null, 0, countof(printf_tests_flags_null));
+	tcase_add_loop_test(tc, test_enum_printf_hook_flags_overflow, 0, countof(printf_tests_flags_overflow));
+	tcase_add_loop_test(tc, test_enum_printf_hook_flags_noflagenum, 0, countof(printf_tests_flags_noflagenum));
 	tcase_add_test(tc, test_enum_printf_hook_width);
 	suite_add_tcase(s, tc);
 
diff --git a/src/libstrongswan/tests/suites/test_hasher.c b/src/libstrongswan/tests/suites/test_hasher.c
index 41a9d64..14cc321 100644
--- a/src/libstrongswan/tests/suites/test_hasher.c
+++ b/src/libstrongswan/tests/suites/test_hasher.c
@@ -48,6 +48,9 @@ static hasher_oid_t oids[] = {
 	{ OID_ECDSA_WITH_SHA256, HASH_SHA256, KEY_ECDSA },
 	{ OID_ECDSA_WITH_SHA384, HASH_SHA384, KEY_ECDSA },
 	{ OID_ECDSA_WITH_SHA512, HASH_SHA512, KEY_ECDSA },
+	{ OID_BLISS_WITH_SHA256, HASH_SHA256, KEY_BLISS },
+	{ OID_BLISS_WITH_SHA384, HASH_SHA384, KEY_BLISS },
+	{ OID_BLISS_WITH_SHA512, HASH_SHA512, KEY_BLISS },
 	{ OID_UNKNOWN, HASH_UNKNOWN, KEY_ECDSA }
 };
 
diff --git a/src/libstrongswan/tests/suites/test_host.c b/src/libstrongswan/tests/suites/test_host.c
index 6344208..7161b2c 100644
--- a/src/libstrongswan/tests/suites/test_host.c
+++ b/src/libstrongswan/tests/suites/test_host.c
@@ -237,6 +237,48 @@ START_TEST(test_create_from_string_and_family_other)
 END_TEST
 
 /*******************************************************************************
+ * host_create_from_dns
+ */
+
+static void test_create_from_dns(int family, chunk_t addr)
+{
+	host_t *host;
+
+	host = host_create_from_dns("localhost", family, 500);
+	if (family != AF_INET6)
+	{
+		ck_assert(host != NULL);
+	}
+	if (host)
+	{
+		if (family != AF_UNSPEC)
+		{
+			verify_address(host, addr, family, 500);
+		}
+		host->destroy(host);
+	}
+}
+
+START_TEST(test_create_from_dns_any)
+{
+	test_create_from_dns(AF_UNSPEC, chunk_empty);
+}
+END_TEST
+
+START_TEST(test_create_from_dns_v4)
+{
+	test_create_from_dns(AF_INET, chunk_from_chars(127,0,0,1));
+}
+END_TEST
+
+START_TEST(test_create_from_dns_v6)
+{
+	test_create_from_dns(AF_INET6,
+						 chunk_from_chars(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1));
+}
+END_TEST
+
+/*******************************************************************************
  * host_create_from_sockaddr
  */
 
@@ -400,6 +442,90 @@ START_TEST(test_create_from_subnet_v6)
 END_TEST
 
 /*******************************************************************************
+ * host_create_from_range
+ */
+
+static const chunk_t addr_v4_to = chunk_from_chars(0xc0, 0xa8, 0x00, 0x05);
+static const chunk_t addr_v6_to = chunk_from_chars(0xfe, 0xc1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+												   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05);
+
+static void verify_range(char *str, int family, chunk_t from_addr,
+						 chunk_t to_addr)
+{
+	host_t *from, *to;
+
+	if (!family)
+	{
+		ck_assert(!host_create_from_range(str, &from, &to));
+	}
+	else
+	{
+		ck_assert(host_create_from_range(str, &from, &to));
+		verify_address(from, from_addr, family, 0);
+		verify_address(to, to_addr, family, 0);
+		from->destroy(from);
+		to->destroy(to);
+	}
+}
+
+START_TEST(test_create_from_range_v4)
+{
+	host_t *from, *to;
+
+	ck_assert(host_create_from_range("0.0.0.0-0.0.0.0", &from, &to));
+	verify_any(from, AF_INET, 0);
+	verify_any(to, AF_INET, 0);
+	from->destroy(from);
+	to->destroy(to);
+
+	verify_range("192.168.0.1-192.168.0.1", AF_INET, addr_v4, addr_v4);
+	verify_range("192.168.0.1-192.168.0.5", AF_INET, addr_v4, addr_v4_to);
+	verify_range("192.168.0.1- 192.168.0.5", AF_INET, addr_v4, addr_v4_to);
+	verify_range("192.168.0.1 -192.168.0.5", AF_INET, addr_v4, addr_v4_to);
+	verify_range("192.168.0.1 - 192.168.0.5", AF_INET, addr_v4, addr_v4_to);
+	verify_range("192.168.0.5-192.168.0.1", AF_INET, addr_v4_to, addr_v4);
+
+	verify_range("192.168.0.1", 0, chunk_empty, chunk_empty);
+	verify_range("192.168.0.1-", 0, chunk_empty, chunk_empty);
+	verify_range("-192.168.0.1", 0, chunk_empty, chunk_empty);
+	verify_range("192.168.0.1-192", 0, chunk_empty, chunk_empty);
+	verify_range("192.168.0.1-192.168", 0, chunk_empty, chunk_empty);
+	verify_range("192.168.0.1-192.168.0", 0, chunk_empty, chunk_empty);
+	verify_range("foo.b.a.r", 0, chunk_empty, chunk_empty);
+	verify_range("foo.b.a.r-b.a.r.f", 0, chunk_empty, chunk_empty);
+}
+END_TEST
+
+START_TEST(test_create_from_range_v6)
+{
+	host_t *from, *to;
+
+	ck_assert(host_create_from_range("::-::", &from, &to));
+	verify_any(from, AF_INET6, 0);
+	verify_any(to, AF_INET6, 0);
+	from->destroy(from);
+	to->destroy(to);
+
+	verify_range("fec1::1-fec1::1", AF_INET6, addr_v6, addr_v6);
+	verify_range("fec1::1-fec1::5", AF_INET6, addr_v6, addr_v6_to);
+	verify_range("fec1::1- fec1::5", AF_INET6, addr_v6, addr_v6_to);
+	verify_range("fec1::1 -fec1::5", AF_INET6, addr_v6, addr_v6_to);
+	verify_range("fec1::1 - fec1::5", AF_INET6, addr_v6, addr_v6_to);
+	verify_range("fec1::5-fec1::1", AF_INET6, addr_v6_to, addr_v6);
+
+	verify_range("fec1::1", 0, chunk_empty, chunk_empty);
+	verify_range("fec1::1-", 0, chunk_empty, chunk_empty);
+	verify_range("-fec1::1", 0, chunk_empty, chunk_empty);
+	verify_range("fec1::1-fec1", 0, chunk_empty, chunk_empty);
+	verify_range("foo::bar", 0, chunk_empty, chunk_empty);
+	verify_range("foo::bar-bar::foo", 0, chunk_empty, chunk_empty);
+
+	verify_range("fec1::1-192.168.0.1", 0, chunk_empty, chunk_empty);
+	verify_range("192.168.0.1-fec1::1", 0, chunk_empty, chunk_empty);
+}
+END_TEST
+
+/*******************************************************************************
  * host_create_netmask
  */
 
@@ -610,6 +736,12 @@ Suite *host_suite_create()
 	tcase_add_test(tc, test_create_from_string_and_family_other);
 	suite_add_tcase(s, tc);
 
+	tc = tcase_create("host_create_from_dns");
+	tcase_add_test(tc, test_create_from_dns_any);
+	tcase_add_test(tc, test_create_from_dns_v4);
+	tcase_add_test(tc, test_create_from_dns_v6);
+	suite_add_tcase(s, tc);
+
 	tc = tcase_create("host_create_from_sockaddr");
 	tcase_add_test(tc, test_create_from_sockaddr_v4);
 	tcase_add_test(tc, test_create_from_sockaddr_v6);
@@ -627,6 +759,11 @@ Suite *host_suite_create()
 	tcase_add_test(tc, test_create_from_subnet_v6);
 	suite_add_tcase(s, tc);
 
+	tc = tcase_create("host_create_from_range");
+	tcase_add_test(tc, test_create_from_range_v4);
+	tcase_add_test(tc, test_create_from_range_v6);
+	suite_add_tcase(s, tc);
+
 	tc = tcase_create("host_create_netmask");
 	tcase_add_test(tc, test_create_netmask_v4);
 	tcase_add_test(tc, test_create_netmask_v6);
diff --git a/src/libstrongswan/tests/suites/test_identification.c b/src/libstrongswan/tests/suites/test_identification.c
index 5de7857..de00e4a 100644
--- a/src/libstrongswan/tests/suites/test_identification.c
+++ b/src/libstrongswan/tests/suites/test_identification.c
@@ -122,58 +122,68 @@ static struct {
 		} data;
 	} result;
 } string_data[] = {
-	{NULL,      ID_ANY,  { .type = ENC_CHUNK }},
-	{"",        ID_ANY,  { .type = ENC_CHUNK }},
-	{"%any",    ID_ANY,  { .type = ENC_CHUNK }},
-	{"%any6",   ID_ANY,  { .type = ENC_CHUNK }},
-	{"0.0.0.0", ID_ANY,  { .type = ENC_CHUNK }},
-	{"0::0",    ID_ANY,  { .type = ENC_CHUNK }},
-	{"::",      ID_ANY,  { .type = ENC_CHUNK }},
-	{"*",       ID_ANY,  { .type = ENC_CHUNK }},
-	{"any",     ID_FQDN, { .type = ENC_SIMPLE }},
-	{"any6",    ID_FQDN, { .type = ENC_SIMPLE }},
-	{"0",       ID_FQDN, { .type = ENC_SIMPLE }},
-	{"**",      ID_FQDN, { .type = ENC_SIMPLE }},
-	{"192.168.1.1", ID_IPV4_ADDR, { .type = ENC_CHUNK,
-									.data.c = chunk_from_chars(0xc0, 0xa8, 0x01, 0x01) }},
-	{"192.168.",ID_FQDN, { .type = ENC_SIMPLE }},
-	{".",       ID_FQDN, { .type = ENC_SIMPLE }},
-	{"fec0::1", ID_IPV6_ADDR, { .type = ENC_CHUNK,
-								.data.c = chunk_from_chars(0xfe, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-														   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01) }},
-	{"fec0::",  ID_IPV6_ADDR, { .type = ENC_CHUNK,
-								.data.c = chunk_from_chars(0xfe, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-														   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00) }},
-	{"fec0:",   ID_KEY_ID,    { .type = ENC_SIMPLE }},
-	{":",       ID_KEY_ID,    { .type = ENC_SIMPLE }},
-	{"alice at strongswan.org", ID_RFC822_ADDR, { .type = ENC_SIMPLE }},
-	{"alice at strongswan", ID_RFC822_ADDR, { .type = ENC_SIMPLE }},
-	{"alice@",  ID_RFC822_ADDR, { .type = ENC_SIMPLE }},
-	{"alice",   ID_FQDN, { .type = ENC_SIMPLE }},
-	{"@",       ID_FQDN, { .type = ENC_CHUNK }},
-	{" @",      ID_RFC822_ADDR, { .type = ENC_SIMPLE }},
-	{"@strongswan.org",  ID_FQDN, { .type = ENC_STRING,
-									.data.s = "strongswan.org" }},
-	{"@#deadbeef", ID_KEY_ID, { .type = ENC_CHUNK,
-								.data.c = chunk_from_chars(0xde, 0xad, 0xbe, 0xef) }},
-	{"@#deadbee",  ID_KEY_ID, { .type = ENC_CHUNK,
-								.data.c = chunk_from_chars(0x0d, 0xea, 0xdb, 0xee) }},
-	{"foo=bar",    ID_KEY_ID, { .type = ENC_SIMPLE }},
-	{"foo=",	   ID_KEY_ID, { .type = ENC_SIMPLE }},
-	{"=bar",	   ID_KEY_ID, { .type = ENC_SIMPLE }},
-	{"C=",		   ID_DER_ASN1_DN, { .type = ENC_CHUNK,
-									 .data.c = chunk_from_chars(0x30, 0x0b, 0x31, 0x09, 0x30, 0x07, 0x06,
-																0x03, 0x55, 0x04, 0x06, 0x13, 0x00)}},
-	{"C=CH",	   ID_DER_ASN1_DN, { .type = ENC_CHUNK,
-									 .data.c = chunk_from_chars(0x30, 0x0d, 0x31, 0x0b, 0x30, 0x09, 0x06,
-																0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x43, 0x48)}},
-	{"C=CH,",	   ID_DER_ASN1_DN, { .type = ENC_CHUNK,
-									 .data.c = chunk_from_chars(0x30, 0x0d, 0x31, 0x0b, 0x30, 0x09, 0x06,
-																0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x43, 0x48)}},
-	{"C=CH, ",	   ID_DER_ASN1_DN, { .type = ENC_CHUNK,
-									 .data.c = chunk_from_chars(0x30, 0x0d, 0x31, 0x0b, 0x30, 0x09, 0x06,
-																0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x43, 0x48)}},
-	{"C=CH, O",	   ID_KEY_ID, { .type = ENC_SIMPLE }},
+	{NULL,						ID_ANY,			{ .type = ENC_CHUNK }},
+	{"",						ID_ANY,			{ .type = ENC_CHUNK }},
+	{"%any",					ID_ANY,			{ .type = ENC_CHUNK }},
+	{"%any6",					ID_ANY,			{ .type = ENC_CHUNK }},
+	{"0.0.0.0",					ID_ANY,			{ .type = ENC_CHUNK }},
+	{"0::0",					ID_ANY,			{ .type = ENC_CHUNK }},
+	{"::",						ID_ANY,			{ .type = ENC_CHUNK }},
+	{"*",						ID_ANY,			{ .type = ENC_CHUNK }},
+	{"any",						ID_FQDN,		{ .type = ENC_SIMPLE }},
+	{"any6",					ID_FQDN,		{ .type = ENC_SIMPLE }},
+	{"0",						ID_FQDN,		{ .type = ENC_SIMPLE }},
+	{"**",						ID_FQDN,		{ .type = ENC_SIMPLE }},
+	{"192.168.1.1",				ID_IPV4_ADDR,	{ .type = ENC_CHUNK,
+		.data.c = chunk_from_chars(0xc0,0xa8,0x01,0x01) }},
+	{"192.168.",				ID_FQDN,		{ .type = ENC_SIMPLE }},
+	{".",						ID_FQDN,		{ .type = ENC_SIMPLE }},
+	{"fec0::1",					ID_IPV6_ADDR,	{ .type = ENC_CHUNK,
+		.data.c = chunk_from_chars(0xfe,0xc0,0x00,0x00,0x00,0x00,0x00,0x00,
+								   0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01) }},
+	{"fec0::",					ID_IPV6_ADDR,	{ .type = ENC_CHUNK,
+		.data.c = chunk_from_chars(0xfe,0xc0,0x00,0x00,0x00,0x00,0x00,0x00,
+								   0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00) }},
+	{"fec0:",					ID_KEY_ID,		{ .type = ENC_SIMPLE }},
+	{":",						ID_KEY_ID,		{ .type = ENC_SIMPLE }},
+	{"alice at strongswan.org",	ID_RFC822_ADDR,	{ .type = ENC_SIMPLE }},
+	{"alice at strongswan",		ID_RFC822_ADDR,	{ .type = ENC_SIMPLE }},
+	{"alice@",					ID_RFC822_ADDR,	{ .type = ENC_SIMPLE }},
+	{"alice",					ID_FQDN,		{ .type = ENC_SIMPLE }},
+	{"@",						ID_FQDN,		{ .type = ENC_CHUNK }},
+	{" @",						ID_RFC822_ADDR,	{ .type = ENC_SIMPLE }},
+	{"@strongswan.org",			ID_FQDN,		{ .type = ENC_STRING,
+		.data.s = "strongswan.org" }},
+	{"@#deadbeef",				ID_KEY_ID,		{ .type = ENC_CHUNK,
+		.data.c = chunk_from_chars(0xde,0xad,0xbe,0xef) }},
+	{"@#deadbee",				ID_KEY_ID,		{ .type = ENC_CHUNK,
+		.data.c = chunk_from_chars(0x0d,0xea,0xdb,0xee) }},
+	{"foo=bar",					ID_KEY_ID,		{ .type = ENC_SIMPLE }},
+	{"foo=",					ID_KEY_ID,		{ .type = ENC_SIMPLE }},
+	{"=bar",					ID_KEY_ID,		{ .type = ENC_SIMPLE }},
+	{"C=",						ID_DER_ASN1_DN,	{ .type = ENC_CHUNK,
+		.data.c = chunk_from_chars(0x30,0x0b,0x31,0x09,0x30,0x07,0x06,
+								   0x03,0x55,0x04,0x06,0x13,0x00) }},
+	{"C=CH",					ID_DER_ASN1_DN,	{ .type = ENC_CHUNK,
+		.data.c = chunk_from_chars(0x30,0x0d,0x31,0x0b,0x30,0x09,0x06,
+								   0x03,0x55,0x04,0x06,0x13,0x02,0x43,0x48) }},
+	{"C=CH,",					ID_DER_ASN1_DN,	{ .type = ENC_CHUNK,
+		.data.c = chunk_from_chars(0x30,0x0d,0x31,0x0b,0x30,0x09,0x06,
+								   0x03,0x55,0x04,0x06,0x13,0x02,0x43,0x48) }},
+	{"C=CH, ",					ID_DER_ASN1_DN,	{ .type = ENC_CHUNK,
+		.data.c = chunk_from_chars(0x30,0x0d,0x31,0x0b,0x30,0x09,0x06,
+								   0x03,0x55,0x04,0x06,0x13,0x02,0x43,0x48) }},
+	{"C=CH, O",					ID_KEY_ID,		{ .type = ENC_SIMPLE }},
+	{"IPv4:#c0a80101",			ID_IPV4_ADDR,	{ .type = ENC_CHUNK,
+		.data.c = chunk_from_chars(0xc0,0xa8,0x01,0x01) }},
+	{ "email:tester",			ID_RFC822_ADDR,	{ .type = ENC_STRING,
+		.data.s = "tester" }},
+	{ "{1}:#c0a80101",			ID_IPV4_ADDR,	{ .type = ENC_CHUNK,
+		.data.c = chunk_from_chars(0xc0,0xa8,0x01,0x01) }},
+	{ "{0x02}:tester",			ID_FQDN,		{ .type = ENC_STRING,
+		.data.s = "tester" }},
+	{ "{99}:somedata",			99,				{ .type = ENC_STRING,
+		.data.s = "somedata" }},
 };
 
 START_TEST(test_from_string)
diff --git a/src/libstrongswan/tests/suites/test_mgf1.c b/src/libstrongswan/tests/suites/test_mgf1.c
new file mode 100644
index 0000000..9388b95
--- /dev/null
+++ b/src/libstrongswan/tests/suites/test_mgf1.c
@@ -0,0 +1,268 @@
+/*
+ * 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.
+ */
+
+#include "test_suite.h"
+
+#include <tests/utils/test_rng.h>
+#include <utils/test.h>
+#include <crypto/mgf1/mgf1.h>
+#include <crypto/mgf1/mgf1_bitspender.h>
+
+typedef struct {
+	hash_algorithm_t alg;
+	size_t hash_size;
+	size_t ml1, ml2, ml3, seed_len;
+	chunk_t seed;
+	chunk_t hashed_seed;
+	chunk_t mask;
+	uint32_t bits[22];
+} mgf1_test_t;
+
+/**
+ * MGF1 Mask Generation Function Test Vectors
+ */
+mgf1_test_t mgf1_tests[] = {
+	{	HASH_SHA1, 20, 60, 20, 15, 24,
+		chunk_from_chars(
+						0xED, 0xA5, 0xC3, 0xBC, 0xAF, 0xB3, 0x20, 0x7D,
+						0x14, 0xA1, 0x54, 0xF7, 0x8B, 0x37, 0xF2, 0x8D,
+						0x8C, 0x9B, 0xD5, 0x63, 0x57, 0x38, 0x11, 0xC2,
+						0xB5, 0xCA, 0xBF, 0x06, 0x43, 0x45, 0x19, 0xD5,
+						0xE7, 0x36, 0xD0, 0x29, 0x21, 0xDA, 0x02, 0x20,
+						0x45, 0xF6, 0x5F, 0x0F, 0x10, 0x04, 0x2A, 0xE3,
+						0x6A, 0x1D, 0xD5, 0x9F, 0x1D, 0x66, 0x44, 0x8F,
+						0xFA, 0xC6, 0xCA, 0xA4, 0x6E, 0x3B, 0x00, 0x66,
+						0xA6, 0xC9, 0x80, 0x5C, 0xF5, 0x2D, 0xD7, 0x72,
+						0xC6, 0xD4, 0x4F, 0x30, 0x72, 0xA2, 0xAD, 0xE0,
+						0x33, 0xE8, 0x55, 0xD5, 0xE6, 0xD6, 0x00, 0x1D,
+						0xA8, 0x68, 0xFF, 0x97, 0x36, 0x8A, 0xF4, 0xD6,
+						0xF1, 0xB6, 0x7E, 0x1F, 0x06, 0xCB, 0x57, 0xCB,
+						0x35, 0x38, 0xF2, 0x2D, 0xF6, 0x20),
+		chunk_from_chars(
+						0xF3, 0x9B, 0x0B, 0xB4, 0x97, 0x50, 0xB5, 0xA7,
+						0xE6, 0xBD, 0xDA, 0xD0, 0x9A, 0x52, 0xBE, 0xA0,
+						0x21, 0xC4, 0x90, 0xB6),
+		chunk_from_chars(
+						0x10, 0x43, 0x76, 0x72, 0x6C, 0xDE, 0xA0, 0x0E,
+						0x77, 0x51, 0xFB, 0x58, 0x39, 0x8A, 0x36, 0xE1,
+						0x63, 0x2B, 0xC9, 0x17, 0x56, 0x0C, 0x4B, 0x46,
+						0xA4, 0x07, 0xA4, 0x3B, 0x8E, 0x33, 0x4D, 0xD1,
+						0x65, 0xF1, 0xAC, 0xC8, 0x59, 0x21, 0x32, 0x16,
+						0x44, 0x2B, 0x7F, 0xB2, 0xA8, 0xA7, 0x26, 0x5D,
+						0xE8, 0x02, 0xBE, 0x8E, 0xDC, 0x34, 0xEB, 0x10,
+						0x76, 0x16, 0x8C, 0xDD, 0x90, 0x92, 0x3D, 0x29,
+						0x90, 0x98, 0x46, 0x11, 0x73, 0x53, 0x47, 0xB1,
+						0x2C, 0xD4, 0x83, 0x78, 0x9B, 0x93, 0x2F, 0x5B,
+						0xFC, 0x26, 0xFF, 0x42, 0x08, 0x1F, 0x70, 0x66,
+						0x40, 0x4B, 0xE7, 0x22, 0x3A, 0x56, 0x10, 0x6D,
+						0x4D, 0x29, 0x0B, 0xCE, 0xA6, 0x21, 0xB5, 0x5C,
+						0x71, 0x66, 0x2F, 0x70, 0x35, 0xD8, 0x8A, 0x92,
+						0x33, 0xF0, 0x16, 0xD4, 0x0E, 0x43, 0x8A, 0x14),
+		{ 0, 0, 0, 4, 1, 1, 46, 103, 38, 411, 848, 57, 3540, 4058, 12403,
+		  0x63, 0x2B, 0xC9, 0x17, 0x56, 669409, 0xA407A43B },
+	},
+	{	HASH_SHA256, 32, 64, 32, 33, 40,
+		chunk_from_chars(
+						0x52, 0xC5, 0xDD, 0x1E, 0xEF, 0x76, 0x1B, 0x53,
+						0x08, 0xE4, 0x86, 0x3F, 0x91, 0x12, 0x98, 0x69,
+						0xC5, 0x9D, 0xDE, 0xF6, 0xFC, 0xFA, 0x93, 0xCE,
+						0x32, 0x52, 0x66, 0xF9, 0xC9, 0x97, 0xF6, 0x42,
+						0x00, 0x2C, 0x64, 0xED, 0x1A, 0x6B, 0x14, 0x0A,
+						0x4B, 0x04, 0xCF, 0x6D, 0x2D, 0x82, 0x0A, 0x07,
+						0xA2, 0x3B, 0xDE, 0xCE, 0x19, 0x8A, 0x39, 0x43,
+						0x16, 0x61, 0x29, 0x98, 0x68, 0xEA, 0xE5, 0xCC,
+						0x0A, 0xF8, 0xE9, 0x71, 0x26, 0xF1, 0x07, 0x36,
+						0x2C, 0x07, 0x1E, 0xEB, 0xE4, 0x28, 0xA2, 0xF4,
+						0xA8, 0x12, 0xC0, 0xC8, 0x20, 0x37, 0xF8, 0xF2,
+						0x6C, 0xAF, 0xDC, 0x6F, 0x2E, 0xD0, 0x62, 0x58,
+						0xD2, 0x37, 0x03, 0x6D, 0xFA, 0x6E, 0x1A, 0xAC,
+						0x9F, 0xCA, 0x56, 0xC6, 0xA4, 0x52, 0x41, 0xE8,
+						0x0F, 0x1B, 0x0C, 0xB9, 0xE6, 0xBA, 0xDE, 0xE1,
+						0x03, 0x5E, 0xC2, 0xE5, 0xF8, 0xF4, 0xF3, 0x46,
+						0x3A, 0x12, 0xC0, 0x1F, 0x3A, 0x00, 0xD0, 0x91,
+						0x18, 0xDD, 0x53, 0xE4, 0x22, 0xF5, 0x26, 0xA4,
+						0x54, 0xEE, 0x20, 0xF0, 0x80),
+		chunk_from_chars(
+						0x76, 0x89, 0x8B, 0x1B, 0x60, 0xEC, 0x10, 0x9D,
+						0x8F, 0x13, 0xF2, 0xFE, 0xD9, 0x85, 0xC1, 0xAB,
+						0x7E, 0xEE, 0xB1, 0x31, 0xDD, 0xF7, 0x7F, 0x0C,
+						0x7D, 0xF9, 0x6B, 0x7B, 0x19, 0x80, 0xBD, 0x28),
+		chunk_from_chars(
+						0xF1, 0x19, 0x02, 0x4F, 0xDA, 0x58, 0x05, 0x9A,
+						0x07, 0xDF, 0x61, 0x81, 0x22, 0x0E, 0x15, 0x46,
+						0xCB, 0x35, 0x3C, 0xDC, 0xAD, 0x20, 0xD9, 0x3F,
+						0x0D, 0xD1, 0xAA, 0x64, 0x66, 0x5C, 0xFA, 0x4A,
+						0xFE, 0xD6, 0x8F, 0x55, 0x57, 0x15, 0xB2, 0xA6,
+						0xA0, 0xE6, 0xA8, 0xC6, 0xBD, 0x28, 0xB4, 0xD5,
+						0x6E, 0x5B, 0x4B, 0xB0, 0x97, 0x09, 0xF5, 0xAC,
+						0x57, 0x65, 0x13, 0x97, 0x71, 0x2C, 0x45, 0x13,
+						0x3D, 0xEE, 0xFB, 0xBF, 0xFE, 0xAF, 0xBB, 0x4B,
+						0x0D, 0x5C, 0x45, 0xD4, 0x2F, 0x17, 0x92, 0x07,
+						0x66, 0x11, 0xF5, 0x46, 0xF8, 0x0C, 0x03, 0x92,
+						0xF5, 0xF5, 0xFF, 0xA4, 0xF3, 0x52, 0xF4, 0x08,
+						0x2C, 0x49, 0x32, 0x1A, 0x93, 0x51, 0x98, 0xB6,
+						0x94, 0x83, 0x39, 0xCF, 0x6B, 0x1F, 0x2F, 0xFC,
+						0x2B, 0xFF, 0x10, 0x71, 0x7D, 0x35, 0x6C, 0xEA,
+						0xC5, 0x66, 0xC7, 0x26, 0x7D, 0x9E, 0xAC, 0xDD,
+						0x35, 0xD7, 0x06, 0x3F, 0x40, 0x82, 0xDA, 0xC3,
+						0x2B, 0x3C, 0x91, 0x3A, 0x32, 0xF8, 0xB2, 0xC6,
+						0x44, 0x4D, 0xCD, 0xB6, 0x54, 0x5F, 0x81, 0x95,
+						0x59, 0xA1, 0xE5, 0x4E, 0xA5, 0x0A, 0x4A, 0x42),
+		 { 0, 1, 3, 4, 4, 12, 32, 36, 253, 331, 2, 1640, 503, 6924, 580,
+		   0xCB, 0x35, 0x3C, 0xDC, 0xAD, 922950, 0x0DD1AA64 }
+	}
+};
+
+START_TEST(mgf1_test_mgf1)
+{
+	mgf1_t *mgf1;
+	chunk_t mask, mask1, mask2, mask3;
+
+	mask1 = mgf1_tests[_i].mask;
+	mask2 = chunk_skip(mask1, mgf1_tests[_i].ml1);
+	mask3 = chunk_skip(mask2, mgf1_tests[_i].ml2);
+	mask1.len = mgf1_tests[_i].ml1;
+	mask2.len = mgf1_tests[_i].ml2;
+	mask3.len = mgf1_tests[_i].ml3;
+
+	mgf1 = mgf1_create(HASH_UNKNOWN, mgf1_tests[_i].seed, TRUE);
+	ck_assert(mgf1 == NULL);
+
+	mgf1 = mgf1_create(mgf1_tests[_i].alg, chunk_empty, TRUE);
+	ck_assert(mgf1 == NULL);
+
+	/* return mask in allocated chunk */
+	mgf1 = mgf1_create(mgf1_tests[_i].alg, mgf1_tests[_i].seed, TRUE);
+	ck_assert(mgf1);
+
+	/* check hash size */
+	ck_assert(mgf1->get_hash_size(mgf1) == mgf1_tests[_i].hash_size);
+
+	/* get zero number of octets */
+	ck_assert(mgf1->allocate_mask(mgf1, 0, &mask));
+	ck_assert(mask.len == 0 && mask.ptr == NULL);
+
+	/* get non-zero number of octets */
+	ck_assert(mgf1->allocate_mask(mgf1, mgf1_tests[_i].mask.len, &mask));
+	ck_assert(chunk_equals(mask, mgf1_tests[_i].mask));
+	mgf1->destroy(mgf1);
+
+	/* copy mask to pre-allocated buffer */
+	mgf1 = mgf1_create(mgf1_tests[_i].alg, mgf1_tests[_i].seed, TRUE);
+	ck_assert(mgf1);
+	ck_assert(mgf1->get_mask(mgf1, mgf1_tests[_i].mask.len, mask.ptr));
+	ck_assert(chunk_equals(mask, mgf1_tests[_i].mask));
+	mgf1->destroy(mgf1);
+
+	/* get mask in batches without hashing the seed */
+	mgf1 = mgf1_create(mgf1_tests[_i].alg, mgf1_tests[_i].hashed_seed, FALSE);
+	ck_assert(mgf1);
+
+	/* first batch */
+	ck_assert(mgf1->get_mask(mgf1, mask1.len, mask.ptr));
+	mask.len = mask1.len;
+	ck_assert(chunk_equals(mask, mask1));
+
+	/* second batch */
+	ck_assert(mgf1->get_mask(mgf1, mask2.len, mask.ptr));
+	mask.len = mask2.len;
+	ck_assert(chunk_equals(mask, mask2));
+
+	/* third batch */
+	ck_assert(mgf1->get_mask(mgf1, mask3.len, mask.ptr));
+	mask.len = mask3.len;
+	ck_assert(chunk_equals(mask, mask3));
+
+	mgf1->destroy(mgf1);
+	chunk_free(&mask);
+}
+END_TEST
+
+START_TEST(mgf1_test_bitspender)
+{
+	mgf1_bitspender_t *bitspender;
+	uint32_t bits;
+	uint8_t byte;
+	int j;
+
+	bitspender = mgf1_bitspender_create(HASH_UNKNOWN,
+										mgf1_tests[_i].hashed_seed, FALSE);
+	ck_assert(bitspender == NULL);
+
+	bitspender = mgf1_bitspender_create(mgf1_tests[_i].alg,
+										mgf1_tests[_i].hashed_seed, FALSE);
+	ck_assert(bitspender);
+
+	for (j = 0; j < 15; j++)
+	{
+		ck_assert(bitspender->get_bits(bitspender, j, &bits));
+		DBG1(DBG_LIB, "bits[%d] = %u, bits = %u", j, mgf1_tests[_i].bits[j],
+					   bits);
+		ck_assert(bits == mgf1_tests[_i].bits[j]);
+	}
+	ck_assert(!bitspender->get_bits(bitspender, 33, &bits));
+
+	for (j = 15; j < 20; j++)
+	{
+		ck_assert(bitspender->get_byte(bitspender, &byte));
+		DBG1(DBG_LIB, "bits[%d] = 0x%02x, byte = 0x%02x", j,
+				   mgf1_tests[_i].bits[j], byte);
+		ck_assert(byte == mgf1_tests[_i].bits[j]);
+	}
+
+	j = 20; /* 23 remaining bits */
+	ck_assert(bitspender->get_bits(bitspender, 23, &bits));
+	DBG1(DBG_LIB, "bits[%d] = %u, bits = %u", j,
+				   mgf1_tests[_i].bits[j], bits);
+	ck_assert(bits == mgf1_tests[_i].bits[j]);
+
+	j = 21; /* 32 aligned bits */
+	ck_assert(bitspender->get_bits(bitspender, 32, &bits));
+	DBG1(DBG_LIB, "bits[%d] = 0x%08x, bits = 0x%08x", j,
+				   mgf1_tests[_i].bits[j], bits);
+	ck_assert(bits == mgf1_tests[_i].bits[j]);
+
+	bitspender->destroy(bitspender);
+}
+END_TEST
+
+
+Suite *mgf1_suite_create(char *name, int n)
+{
+	Suite *s;
+	TCase *tc;
+
+	s = suite_create(name);
+
+	tc = tcase_create("mgf1");
+	tcase_add_loop_test(tc, mgf1_test_mgf1, n, n + 1);
+	suite_add_tcase(s, tc);
+
+	tc = tcase_create("bitspender");
+	tcase_add_loop_test(tc, mgf1_test_bitspender, n, n + 1);
+	suite_add_tcase(s, tc);
+
+	return s;
+}
+
+Suite *mgf1_sha1_suite_create()
+{
+	return mgf1_suite_create("mgf1-sha1", 0);
+}
+
+Suite *mgf1_sha256_suite_create()
+{
+	return mgf1_suite_create("mgf1-sha256", 1);
+}
diff --git a/src/libstrongswan/tests/suites/test_ntru.c b/src/libstrongswan/tests/suites/test_ntru.c
index 7c0cb81..d209fa2 100644
--- a/src/libstrongswan/tests/suites/test_ntru.c
+++ b/src/libstrongswan/tests/suites/test_ntru.c
@@ -16,20 +16,17 @@
 #include "test_suite.h"
 
 #include <tests/utils/test_rng.h>
+#include <utils/test.h>
+#include <crypto/mgf1/mgf1.h>
 #include <plugins/ntru/ntru_drbg.h>
-#include <plugins/ntru/ntru_mgf1.h>
 #include <plugins/ntru/ntru_trits.h>
 #include <plugins/ntru/ntru_poly.h>
 #include <plugins/ntru/ntru_param_set.h>
 #include <plugins/ntru/ntru_private_key.h>
-#include <utils/test.h>
 
 IMPORT_FUNCTION_FOR_TESTS(ntru, ntru_drbg_create, ntru_drbg_t*,
 						  u_int32_t strength, chunk_t pers_str, rng_t *entropy)
 
-IMPORT_FUNCTION_FOR_TESTS(ntru, ntru_mgf1_create, ntru_mgf1_t*,
-						  hash_algorithm_t alg, chunk_t seed, bool hash_seed)
-
 IMPORT_FUNCTION_FOR_TESTS(ntru, ntru_trits_create, ntru_trits_t*,
 						  size_t len, hash_algorithm_t alg, chunk_t seed)
 
@@ -334,13 +331,11 @@ typedef struct {
 typedef struct {
 	hash_algorithm_t alg;
 	size_t hash_size;
-	size_t ml1, ml2, ml3, seed_len;
+	size_t seed_len;
 	chunk_t seed;
-	chunk_t hashed_seed;
-	chunk_t mask;
 	chunk_t trits;
 	poly_test_t poly_test[2];
-} mgf1_test_t;
+} trits_test_t;
 
 uint16_t indices_ees439ep1[] = {
 	367, 413,  16, 214, 114, 128,  42, 268, 346, 329, 119, 303, 208, 287, 150,
@@ -386,10 +381,10 @@ uint16_t indices_ees1171ep1[] = {
 };
 
 /**
- * MGF1 Mask Generation Function Test Vectors
+ * Trits and Polynomial Test Vectors
  */
-mgf1_test_t mgf1_tests[] = {
-	{	HASH_SHA1, 20, 60, 20, 15, 24,
+static trits_test_t trits_tests[] = {
+	{	HASH_SHA1, 20, 24,
 		chunk_from_chars(
 						0xED, 0xA5, 0xC3, 0xBC, 0xAF, 0xB3, 0x20, 0x7D,
 						0x14, 0xA1, 0x54, 0xF7, 0x8B, 0x37, 0xF2, 0x8D,
@@ -406,26 +401,6 @@ mgf1_test_t mgf1_tests[] = {
 						0xF1, 0xB6, 0x7E, 0x1F, 0x06, 0xCB, 0x57, 0xCB,
 						0x35, 0x38, 0xF2, 0x2D, 0xF6, 0x20),
 		chunk_from_chars(
-						0xF3, 0x9B, 0x0B, 0xB4, 0x97, 0x50, 0xB5, 0xA7,
-						0xE6, 0xBD, 0xDA, 0xD0, 0x9A, 0x52, 0xBE, 0xA0,
-						0x21, 0xC4, 0x90, 0xB6),
-		chunk_from_chars(
-						0x10, 0x43, 0x76, 0x72, 0x6C, 0xDE, 0xA0, 0x0E,
-						0x77, 0x51, 0xFB, 0x58, 0x39, 0x8A, 0x36, 0xE1,
-						0x63, 0x2B, 0xC9, 0x17, 0x56, 0x0C, 0x4B, 0x46,
-						0xA4, 0x07, 0xA4, 0x3B, 0x8E, 0x33, 0x4D, 0xD1,
-						0x65, 0xF1, 0xAC, 0xC8, 0x59, 0x21, 0x32, 0x16,
-						0x44, 0x2B, 0x7F, 0xB2, 0xA8, 0xA7, 0x26, 0x5D,
-						0xE8, 0x02, 0xBE, 0x8E, 0xDC, 0x34, 0xEB, 0x10,
-						0x76, 0x16, 0x8C, 0xDD, 0x90, 0x92, 0x3D, 0x29,
-						0x90, 0x98, 0x46, 0x11, 0x73, 0x53, 0x47, 0xB1,
-						0x2C, 0xD4, 0x83, 0x78, 0x9B, 0x93, 0x2F, 0x5B,
-						0xFC, 0x26, 0xFF, 0x42, 0x08, 0x1F, 0x70, 0x66,
-						0x40, 0x4B, 0xE7, 0x22, 0x3A, 0x56, 0x10, 0x6D,
-						0x4D, 0x29, 0x0B, 0xCE, 0xA6, 0x21, 0xB5, 0x5C,
-						0x71, 0x66, 0x2F, 0x70, 0x35, 0xD8, 0x8A, 0x92,
-						0x33, 0xF0, 0x16, 0xD4, 0x0E, 0x43, 0x8A, 0x14),
-		chunk_from_chars(
 				1, 2, 1, 0, 0,  1, 1, 1, 2, 0,  1, 0, 1, 1, 1,  0, 2, 0, 1, 1,
 				0, 0, 0, 1, 1,  0, 2, 0, 2, 2,	1, 2, 2, 2, 1,  2, 1, 1, 0, 0,
 				2, 0, 1, 1, 1,	0, 0, 0, 0, 1,  1, 2, 0, 0, 1,  0, 1, 0, 2, 0,
@@ -457,7 +432,7 @@ mgf1_test_t mgf1_tests[] = {
 			}
 		}
 	},
-	{	HASH_SHA256, 32, 64, 32, 33, 40,
+	{	HASH_SHA256, 32, 40,
 		chunk_from_chars(
 						0x52, 0xC5, 0xDD, 0x1E, 0xEF, 0x76, 0x1B, 0x53,
 						0x08, 0xE4, 0x86, 0x3F, 0x91, 0x12, 0x98, 0x69,
@@ -479,32 +454,6 @@ mgf1_test_t mgf1_tests[] = {
 						0x18, 0xDD, 0x53, 0xE4, 0x22, 0xF5, 0x26, 0xA4,
 						0x54, 0xEE, 0x20, 0xF0, 0x80),
 		chunk_from_chars(
-						0x76, 0x89, 0x8B, 0x1B, 0x60, 0xEC, 0x10, 0x9D,
-						0x8F, 0x13, 0xF2, 0xFE, 0xD9, 0x85, 0xC1, 0xAB,
-						0x7E, 0xEE, 0xB1, 0x31, 0xDD, 0xF7, 0x7F, 0x0C,
-						0x7D, 0xF9, 0x6B, 0x7B, 0x19, 0x80, 0xBD, 0x28),
-		chunk_from_chars(
-						0xF1, 0x19, 0x02, 0x4F, 0xDA, 0x58, 0x05, 0x9A,
-						0x07, 0xDF, 0x61, 0x81, 0x22, 0x0E, 0x15, 0x46,
-						0xCB, 0x35, 0x3C, 0xDC, 0xAD, 0x20, 0xD9, 0x3F,
-						0x0D, 0xD1, 0xAA, 0x64, 0x66, 0x5C, 0xFA, 0x4A,
-						0xFE, 0xD6, 0x8F, 0x55, 0x57, 0x15, 0xB2, 0xA6,
-						0xA0, 0xE6, 0xA8, 0xC6, 0xBD, 0x28, 0xB4, 0xD5,
-						0x6E, 0x5B, 0x4B, 0xB0, 0x97, 0x09, 0xF5, 0xAC,
-						0x57, 0x65, 0x13, 0x97, 0x71, 0x2C, 0x45, 0x13,
-						0x3D, 0xEE, 0xFB, 0xBF, 0xFE, 0xAF, 0xBB, 0x4B,
-						0x0D, 0x5C, 0x45, 0xD4, 0x2F, 0x17, 0x92, 0x07,
-						0x66, 0x11, 0xF5, 0x46, 0xF8, 0x0C, 0x03, 0x92,
-						0xF5, 0xF5, 0xFF, 0xA4, 0xF3, 0x52, 0xF4, 0x08,
-						0x2C, 0x49, 0x32, 0x1A, 0x93, 0x51, 0x98, 0xB6,
-						0x94, 0x83, 0x39, 0xCF, 0x6B, 0x1F, 0x2F, 0xFC,
-						0x2B, 0xFF, 0x10, 0x71, 0x7D, 0x35, 0x6C, 0xEA,
-						0xC5, 0x66, 0xC7, 0x26, 0x7D, 0x9E, 0xAC, 0xDD,
-						0x35, 0xD7, 0x06, 0x3F, 0x40, 0x82, 0xDA, 0xC3,
-						0x2B, 0x3C, 0x91, 0x3A, 0x32, 0xF8, 0xB2, 0xC6,
-						0x44, 0x4D, 0xCD, 0xB6, 0x54, 0x5F, 0x81, 0x95,
-						0x59, 0xA1, 0xE5, 0x4E, 0xA5, 0x0A, 0x4A, 0x42),
-		chunk_from_chars(
 				1, 2, 2, 2, 2,  1, 2, 2, 0, 0,  2, 0, 0, 0, 0,  1, 2, 2, 2, 0,
 				2, 0, 0, 2, 2,  1, 2, 0, 0, 1,  2, 1, 0, 0, 0,  1, 0, 2, 2, 1,
 				1, 2, 0, 0, 0,  1, 2, 0, 2, 2,  1, 2, 1, 0, 1,  0, 1, 2, 1, 1,
@@ -546,104 +495,34 @@ mgf1_test_t mgf1_tests[] = {
 	}
 };
 
-START_TEST(test_ntru_mgf1)
-{
-	ntru_mgf1_t *mgf1;
-	chunk_t mask, mask1, mask2, mask3;
-
-	mask1 = mgf1_tests[_i].mask;
-	mask2 = chunk_skip(mask1, mgf1_tests[_i].ml1);
-	mask3 = chunk_skip(mask2, mgf1_tests[_i].ml2);
-	mask1.len = mgf1_tests[_i].ml1;
-	mask2.len = mgf1_tests[_i].ml2;
-	mask3.len = mgf1_tests[_i].ml3;
-
-	mgf1 = TEST_FUNCTION(ntru, ntru_mgf1_create, HASH_UNKNOWN,
-						 mgf1_tests[_i].seed, TRUE);
-	ck_assert(mgf1 == NULL);
-
-	mgf1 = TEST_FUNCTION(ntru, ntru_mgf1_create, mgf1_tests[_i].alg,
-						 chunk_empty, TRUE);
-	ck_assert(mgf1 == NULL);
-
-	/* return mask in allocated chunk */
-	mgf1 = TEST_FUNCTION(ntru, ntru_mgf1_create, mgf1_tests[_i].alg,
-						 mgf1_tests[_i].seed, TRUE);
-	ck_assert(mgf1);
-
-	/* check hash size */
-	ck_assert(mgf1->get_hash_size(mgf1) == mgf1_tests[_i].hash_size);
-
-	/* get zero number of octets */
-	ck_assert(mgf1->allocate_mask(mgf1, 0, &mask));
-	ck_assert(mask.len == 0 && mask.ptr == NULL);
-
-	/* get non-zero number of octets */
-	ck_assert(mgf1->allocate_mask(mgf1, mgf1_tests[_i].mask.len, &mask));
-	ck_assert(chunk_equals(mask, mgf1_tests[_i].mask));
-	mgf1->destroy(mgf1);
-
-	/* copy mask to pre-allocated buffer */
-	mgf1 = TEST_FUNCTION(ntru, ntru_mgf1_create, mgf1_tests[_i].alg,
-						 mgf1_tests[_i].seed, TRUE);
-	ck_assert(mgf1);
-	ck_assert(mgf1->get_mask(mgf1, mgf1_tests[_i].mask.len, mask.ptr));
-	ck_assert(chunk_equals(mask, mgf1_tests[_i].mask));
-	mgf1->destroy(mgf1);
-
-	/* get mask in batches without hashing the seed */
-	mgf1 = TEST_FUNCTION(ntru, ntru_mgf1_create, mgf1_tests[_i].alg,
-						 mgf1_tests[_i].hashed_seed, FALSE);
-	ck_assert(mgf1);
-
-	/* first batch */
-	ck_assert(mgf1->get_mask(mgf1, mask1.len, mask.ptr));
-	mask.len = mask1.len;
-	ck_assert(chunk_equals(mask, mask1));
-
-	/* second batch */
-	ck_assert(mgf1->get_mask(mgf1, mask2.len, mask.ptr));
-	mask.len = mask2.len;
-	ck_assert(chunk_equals(mask, mask2));
-
-	/* third batch */
-	ck_assert(mgf1->get_mask(mgf1, mask3.len, mask.ptr));
-	mask.len = mask3.len;
-	ck_assert(chunk_equals(mask, mask3));
-
-	mgf1->destroy(mgf1);
-	chunk_free(&mask);
-}
-END_TEST
-
 START_TEST(test_ntru_trits)
 {
 	ntru_trits_t *mask;
 	chunk_t trits;
 
-	mask = TEST_FUNCTION(ntru, ntru_trits_create, mgf1_tests[_i].trits.len,
-						 HASH_UNKNOWN, mgf1_tests[_i].seed);
+	mask = TEST_FUNCTION(ntru, ntru_trits_create, trits_tests[_i].trits.len,
+						 HASH_UNKNOWN, trits_tests[_i].seed);
 	ck_assert(mask == NULL);
 
-	mask = TEST_FUNCTION(ntru, ntru_trits_create, mgf1_tests[_i].trits.len,
-						 mgf1_tests[_i].alg, chunk_empty);
+	mask = TEST_FUNCTION(ntru, ntru_trits_create, trits_tests[_i].trits.len,
+						 trits_tests[_i].alg, chunk_empty);
 	ck_assert(mask == NULL);
 
-	mask = TEST_FUNCTION(ntru, ntru_trits_create, mgf1_tests[_i].trits.len,
-						 mgf1_tests[_i].alg, mgf1_tests[_i].seed);
+	mask = TEST_FUNCTION(ntru, ntru_trits_create, trits_tests[_i].trits.len,
+						 trits_tests[_i].alg, trits_tests[_i].seed);
 	ck_assert(mask);
 
 	trits = chunk_create(mask->get_trits(mask), mask->get_size(mask));
-	ck_assert(chunk_equals(trits, mgf1_tests[_i].trits));
+	ck_assert(chunk_equals(trits, trits_tests[_i].trits));
 	mask->destroy(mask);
 
 	/* generate a multiple of 5 trits */
-	mask = TEST_FUNCTION(ntru, ntru_trits_create, 10, mgf1_tests[_i].alg,
-						 mgf1_tests[_i].seed);
+	mask = TEST_FUNCTION(ntru, ntru_trits_create, 10, trits_tests[_i].alg,
+						 trits_tests[_i].seed);
 	ck_assert(mask);
 
 	trits = chunk_create(mask->get_trits(mask), mask->get_size(mask));
-	ck_assert(chunk_equals(trits, chunk_create(mgf1_tests[_i].trits.ptr, 10)));
+	ck_assert(chunk_equals(trits, chunk_create(trits_tests[_i].trits.ptr, 10)));
 	mask->destroy(mask);
 }
 END_TEST
@@ -656,10 +535,10 @@ START_TEST(test_ntru_poly)
 	poly_test_t *p;
 	int j, n;
 
-	seed = mgf1_tests[_i].seed;
-	seed.len = mgf1_tests[_i].seed_len;
+	seed = trits_tests[_i].seed;
+	seed.len = trits_tests[_i].seed_len;
 
-	p = &mgf1_tests[_i].poly_test[0];
+	p = &trits_tests[_i].poly_test[0];
 	poly = TEST_FUNCTION(ntru, ntru_poly_create_from_seed, HASH_UNKNOWN, seed,
 						 p->c_bits, p->N, p->q, p->indices_len, p->indices_len,
 						 p->is_product_form);
@@ -667,9 +546,9 @@ START_TEST(test_ntru_poly)
 
 	for (n = 0; n < 2; n++)
 	{
-		p = &mgf1_tests[_i].poly_test[n];
+		p = &trits_tests[_i].poly_test[n];
 		poly = TEST_FUNCTION(ntru, ntru_poly_create_from_seed,
-							mgf1_tests[_i].alg, seed, p->c_bits, p->N, p->q,
+							trits_tests[_i].alg, seed, p->c_bits, p->N, p->q,
 							p->indices_len, p->indices_len, p->is_product_form);
 		ck_assert(poly != NULL && poly->get_size(poly) == p->indices_size);
 
@@ -1182,7 +1061,6 @@ START_TEST(test_ntru_ke)
 	diffie_hellman_t *i_ntru, *r_ntru;
 	char buf[10];
 	int k, n, len;
-	status_t status;
 
 	k = (_i) / countof(parameter_sets);
 	n = (_i) % countof(parameter_sets);
@@ -1199,23 +1077,21 @@ START_TEST(test_ntru_ke)
 	ck_assert(i_ntru != NULL);
 	ck_assert(i_ntru->get_dh_group(i_ntru) == params[k].group);
 
-	i_ntru->get_my_public_value(i_ntru, &pub_key);
+	ck_assert(i_ntru->get_my_public_value(i_ntru, &pub_key));
 	ck_assert(pub_key.len > 0);
 
 	r_ntru = lib->crypto->create_dh(lib->crypto, params[k].group);
 	ck_assert(r_ntru != NULL);
 
-	r_ntru->set_other_public_value(r_ntru, pub_key);
-	r_ntru->get_my_public_value(r_ntru, &cipher_text);
+	ck_assert(r_ntru->set_other_public_value(r_ntru, pub_key));
+	ck_assert(r_ntru->get_my_public_value(r_ntru, &cipher_text));
 	ck_assert(cipher_text.len > 0);
 
-	status = r_ntru->get_shared_secret(r_ntru, &r_shared_secret);
-	ck_assert(status == SUCCESS);
+	ck_assert(r_ntru->get_shared_secret(r_ntru, &r_shared_secret));
 	ck_assert(r_shared_secret.len > 0);
 
-	i_ntru->set_other_public_value(i_ntru, cipher_text);
-	status = i_ntru->get_shared_secret(i_ntru, &i_shared_secret);
-	ck_assert(status == SUCCESS);
+	ck_assert(i_ntru->set_other_public_value(i_ntru, cipher_text));
+	ck_assert(i_ntru->get_shared_secret(i_ntru, &i_shared_secret));
 	ck_assert(chunk_equals(i_shared_secret, r_shared_secret));
 
 	chunk_clear(&i_shared_secret);
@@ -1233,8 +1109,8 @@ START_TEST(test_ntru_retransmission)
 	chunk_t pub_key1, pub_key2;
 
 	i_ntru = lib->crypto->create_dh(lib->crypto, NTRU_256_BIT);
-	i_ntru->get_my_public_value(i_ntru, &pub_key1);
-	i_ntru->get_my_public_value(i_ntru, &pub_key2);
+	ck_assert(i_ntru->get_my_public_value(i_ntru, &pub_key1));
+	ck_assert(i_ntru->get_my_public_value(i_ntru, &pub_key2));
 	ck_assert(chunk_equals(pub_key1, pub_key2));
 
 	chunk_free(&pub_key1);
@@ -1260,8 +1136,8 @@ START_TEST(test_ntru_pubkey_oid)
 	chunk_t cipher_text;
 
 	r_ntru = lib->crypto->create_dh(lib->crypto, NTRU_128_BIT);
-	r_ntru->set_other_public_value(r_ntru, oid_tests[_i]);
-	r_ntru->get_my_public_value(r_ntru, &cipher_text);
+	ck_assert(!r_ntru->set_other_public_value(r_ntru, oid_tests[_i]));
+	ck_assert(r_ntru->get_my_public_value(r_ntru, &cipher_text));
 	ck_assert(cipher_text.len == 0);
 	r_ntru->destroy(r_ntru);
 }
@@ -1276,14 +1152,14 @@ START_TEST(test_ntru_wrong_set)
 						  "libstrongswan.plugins.ntru.parameter_set",
 			 			  "x9_98_bandwidth");
 	i_ntru = lib->crypto->create_dh(lib->crypto, NTRU_112_BIT);
-	i_ntru->get_my_public_value(i_ntru, &pub_key);
+	ck_assert(i_ntru->get_my_public_value(i_ntru, &pub_key));
 
 	lib->settings->set_str(lib->settings,
 						  "libstrongswan.plugins.ntru.parameter_set",
 						  "optimum");
 	r_ntru = lib->crypto->create_dh(lib->crypto, NTRU_112_BIT);
-	r_ntru->set_other_public_value(r_ntru, pub_key);
-	r_ntru->get_my_public_value(r_ntru, &cipher_text);
+	ck_assert(!r_ntru->set_other_public_value(r_ntru, pub_key));
+	ck_assert(r_ntru->get_my_public_value(r_ntru, &cipher_text));
 	ck_assert(cipher_text.len == 0);
 
 	chunk_free(&pub_key);
@@ -1314,9 +1190,9 @@ START_TEST(test_ntru_ciphertext)
 	for (i = 0; i < countof(test); i++)
 	{
 		i_ntru = lib->crypto->create_dh(lib->crypto, NTRU_128_BIT);
-		i_ntru->get_my_public_value(i_ntru, &pub_key);
-		i_ntru->set_other_public_value(i_ntru, test[i]);
-		ck_assert(i_ntru->get_shared_secret(i_ntru, &shared_secret) != SUCCESS);
+		ck_assert(i_ntru->get_my_public_value(i_ntru, &pub_key));
+		ck_assert(!i_ntru->set_other_public_value(i_ntru, test[i]));
+		ck_assert(!i_ntru->get_shared_secret(i_ntru, &shared_secret));
 		ck_assert(shared_secret.len == 0);
 
 		chunk_free(&pub_key);
@@ -1334,12 +1210,12 @@ START_TEST(test_ntru_wrong_ciphertext)
 	r_ntru = lib->crypto->create_dh(lib->crypto, NTRU_128_BIT);
 	m_ntru = lib->crypto->create_dh(lib->crypto, NTRU_128_BIT);
 
-	i_ntru->get_my_public_value(i_ntru, &pub_key_i);
-	m_ntru->get_my_public_value(m_ntru, &pub_key_m);
-	r_ntru->set_other_public_value(r_ntru, pub_key_m);
-	r_ntru->get_my_public_value(r_ntru, &cipher_text);
-	i_ntru->set_other_public_value(i_ntru, cipher_text);
-	ck_assert(i_ntru->get_shared_secret(i_ntru, &shared_secret) != SUCCESS);
+	ck_assert(i_ntru->get_my_public_value(i_ntru, &pub_key_i));
+	ck_assert(m_ntru->get_my_public_value(m_ntru, &pub_key_m));
+	ck_assert(r_ntru->set_other_public_value(r_ntru, pub_key_m));
+	ck_assert(r_ntru->get_my_public_value(r_ntru, &cipher_text));
+	ck_assert(!i_ntru->set_other_public_value(i_ntru, cipher_text));
+	ck_assert(!i_ntru->get_shared_secret(i_ntru, &shared_secret));
 	ck_assert(shared_secret.len == 0);
 
 	chunk_free(&pub_key_i);
@@ -1370,16 +1246,12 @@ Suite *ntru_suite_create()
 	tcase_add_test(tc, test_ntru_drbg_reseed);
 	suite_add_tcase(s, tc);
 
-	tc = tcase_create("mgf1");
-	tcase_add_loop_test(tc, test_ntru_mgf1, 0, countof(mgf1_tests));
-	suite_add_tcase(s, tc);
-
 	tc = tcase_create("trits");
-	tcase_add_loop_test(tc, test_ntru_trits, 0, countof(mgf1_tests));
+	tcase_add_loop_test(tc, test_ntru_trits, 0, countof(trits_tests));
 	suite_add_tcase(s, tc);
 
 	tc = tcase_create("poly");
-	tcase_add_loop_test(tc, test_ntru_poly, 0, countof(mgf1_tests));
+	tcase_add_loop_test(tc, test_ntru_poly, 0, countof(trits_tests));
 	suite_add_tcase(s, tc);
 
 	tc = tcase_create("ring_mult");
diff --git a/src/libstrongswan/tests/suites/test_settings.c b/src/libstrongswan/tests/suites/test_settings.c
index b9d429a..9601a34 100644
--- a/src/libstrongswan/tests/suites/test_settings.c
+++ b/src/libstrongswan/tests/suites/test_settings.c
@@ -908,7 +908,7 @@ START_SETUP(setup_string_config)
 		"special = \"all { special } characters # can be used.\"\n"
 		"unterminated = \"is fine\n"
 		"but = produces a warning\n"
-		"newlines = \"can either be encoded\\nor\\\n"
+		"newlines = \"can either be encoded\\nor \\\n"
 		"escaped\"\n"
 		"quotes = \"\\\"and\\\" slashes \\\\ can \\\\ be\" # escaped too\n"
 		"multiple = \"strings\" are \"combined\"\n"
@@ -922,7 +922,7 @@ START_TEST(test_strings)
 	verify_string("all { special } characters # can be used.", "special");
 	verify_string("is fine", "unterminated");
 	verify_string("produces a warning", "but");
-	verify_string("can either be encoded\nor\nescaped", "newlines");
+	verify_string("can either be encoded\nor escaped", "newlines");
 	verify_string("\"and\" slashes \\ can \\ be", "quotes");
 	verify_string("strings are combined", "multiple");
 }
diff --git a/src/libstrongswan/tests/suites/test_threading.c b/src/libstrongswan/tests/suites/test_threading.c
index 47e4484..55a4cd7 100644
--- a/src/libstrongswan/tests/suites/test_threading.c
+++ b/src/libstrongswan/tests/suites/test_threading.c
@@ -553,6 +553,49 @@ START_TEST(test_rwlock)
 }
 END_TEST
 
+static void *rwlock_try_run(void *param)
+{
+	if (rwlock->try_write_lock(rwlock))
+	{
+		rwlock->unlock(rwlock);
+		return param;
+	}
+	return NULL;
+}
+
+START_TEST(test_rwlock_try)
+{
+	uintptr_t magic = 0xcafebabe;
+	thread_t *thread;
+
+	rwlock = rwlock_create(RWLOCK_TYPE_DEFAULT);
+
+	thread = thread_create(rwlock_try_run, (void*)magic);
+	ck_assert_int_eq((uintptr_t)thread->join(thread), magic);
+
+	rwlock->read_lock(rwlock);
+	thread = thread_create(rwlock_try_run, (void*)magic);
+	ck_assert(thread->join(thread) == NULL);
+	rwlock->unlock(rwlock);
+
+	rwlock->read_lock(rwlock);
+	rwlock->read_lock(rwlock);
+	rwlock->read_lock(rwlock);
+	thread = thread_create(rwlock_try_run, (void*)magic);
+	ck_assert(thread->join(thread) == NULL);
+	rwlock->unlock(rwlock);
+	rwlock->unlock(rwlock);
+	rwlock->unlock(rwlock);
+
+	rwlock->write_lock(rwlock);
+	thread = thread_create(rwlock_try_run, (void*)magic);
+	ck_assert(thread->join(thread) == NULL);
+	rwlock->unlock(rwlock);
+
+	rwlock->destroy(rwlock);
+}
+END_TEST
+
 /**
  * Rwlock condvar
  */
@@ -1132,6 +1175,191 @@ START_TEST(test_cancel_point)
 }
 END_TEST
 
+static void close_fd_ptr(void *fd)
+{
+	close(*(int*)fd);
+}
+
+static void cancellation_recv()
+{
+	int sv[2];
+	char buf[1];
+
+	ck_assert(socketpair(AF_UNIX, SOCK_STREAM, 0, sv) == 0);
+
+	thread_cleanup_push(close_fd_ptr, &sv[0]);
+	thread_cleanup_push(close_fd_ptr, &sv[1]);
+
+	thread_cancelability(TRUE);
+	while (TRUE)
+	{
+		ck_assert(recv(sv[0], buf, sizeof(buf), 0) == 1);
+	}
+}
+
+static void cancellation_read()
+{
+	int sv[2];
+	char buf[1];
+
+	ck_assert(socketpair(AF_UNIX, SOCK_STREAM, 0, sv) == 0);
+
+	thread_cleanup_push(close_fd_ptr, &sv[0]);
+	thread_cleanup_push(close_fd_ptr, &sv[1]);
+
+	thread_cancelability(TRUE);
+	while (TRUE)
+	{
+		ck_assert(read(sv[0], buf, sizeof(buf)) == 1);
+	}
+}
+
+static void cancellation_select()
+{
+	int sv[2];
+	fd_set set;
+
+	ck_assert(socketpair(AF_UNIX, SOCK_STREAM, 0, sv) == 0);
+
+	thread_cleanup_push(close_fd_ptr, &sv[0]);
+	thread_cleanup_push(close_fd_ptr, &sv[1]);
+
+	FD_ZERO(&set);
+	FD_SET(sv[0], &set);
+	thread_cancelability(TRUE);
+	while (TRUE)
+	{
+		ck_assert(select(sv[0] + 1, &set, NULL, NULL, NULL) == 1);
+	}
+}
+
+static void cancellation_poll()
+{
+	int sv[2];
+	struct pollfd pfd;
+
+	ck_assert(socketpair(AF_UNIX, SOCK_STREAM, 0, sv) == 0);
+
+	thread_cleanup_push(close_fd_ptr, &sv[0]);
+	thread_cleanup_push(close_fd_ptr, &sv[1]);
+
+	pfd.fd = sv[0];
+	pfd.events = POLLIN;
+	thread_cancelability(TRUE);
+	while (TRUE)
+	{
+		ck_assert(poll(&pfd, 1, -1) == 1);
+	}
+}
+
+static void cancellation_accept()
+{
+	host_t *host;
+	int fd, c;
+
+	fd = socket(AF_INET, SOCK_STREAM, 0);
+	ck_assert(fd >= 0);
+	host = host_create_from_string("127.0.0.1", 0);
+	ck_assert_msg(bind(fd, host->get_sockaddr(host),
+					   *host->get_sockaddr_len(host)) == 0, "%m");
+	host->destroy(host);
+	ck_assert(listen(fd, 5) == 0);
+
+	thread_cleanup_push(close_fd_ptr, &fd);
+
+	thread_cancelability(TRUE);
+	while (TRUE)
+	{
+		c = accept(fd, NULL, NULL);
+		ck_assert(c >= 0);
+		close(c);
+	}
+}
+
+static void cancellation_cond()
+{
+	mutex_t *mutex;
+	condvar_t *cond;
+
+	mutex = mutex_create(MUTEX_TYPE_DEFAULT);
+	cond = condvar_create(CONDVAR_TYPE_DEFAULT);
+	mutex->lock(mutex);
+
+	thread_cleanup_push((void*)mutex->destroy, mutex);
+	thread_cleanup_push((void*)cond->destroy, cond);
+
+	thread_cancelability(TRUE);
+	while (TRUE)
+	{
+		cond->wait(cond, mutex);
+	}
+}
+
+static void cancellation_rwcond()
+{
+	rwlock_t *lock;
+	rwlock_condvar_t *cond;
+
+	lock = rwlock_create(RWLOCK_TYPE_DEFAULT);
+	cond = rwlock_condvar_create();
+	lock->write_lock(lock);
+
+	thread_cleanup_push((void*)lock->destroy, lock);
+	thread_cleanup_push((void*)cond->destroy, cond);
+
+	thread_cancelability(TRUE);
+	while (TRUE)
+	{
+		cond->wait(cond, lock);
+	}
+}
+
+static void (*cancellation_points[])() = {
+	cancellation_read,
+	cancellation_recv,
+	cancellation_select,
+	cancellation_poll,
+	cancellation_accept,
+	cancellation_cond,
+	cancellation_rwcond,
+};
+
+static void* run_cancellation_point(void (*fn)())
+{
+	fn();
+	return NULL;
+}
+
+static void* run_cancellation_point_pre(void (*fn)())
+{
+	usleep(5000);
+	fn();
+	return NULL;
+}
+
+START_TEST(test_cancellation_point)
+{
+	thread_t *thread;
+
+	thread = thread_create((void*)run_cancellation_point,
+						   cancellation_points[_i]);
+	usleep(5000);
+	thread->cancel(thread);
+	thread->join(thread);
+}
+END_TEST
+
+START_TEST(test_cancellation_point_pre)
+{
+	thread_t *thread;
+
+	thread = thread_create((void*)run_cancellation_point_pre,
+						   cancellation_points[_i]);
+	thread->cancel(thread);
+	thread->join(thread);
+}
+END_TEST
+
 static void cleanup1(void *data)
 {
 	uintptr_t *value = (uintptr_t*)data;
@@ -1423,6 +1651,7 @@ Suite *threading_suite_create()
 
 	tc = tcase_create("rwlock");
 	tcase_add_test(tc, test_rwlock);
+	tcase_add_test(tc, test_rwlock_try);
 	suite_add_tcase(s, tc);
 
 	tc = tcase_create("rwlock condvar");
@@ -1456,6 +1685,13 @@ Suite *threading_suite_create()
 	tcase_add_test(tc, test_cancel_point);
 	suite_add_tcase(s, tc);
 
+	tc = tcase_create("thread cancellation point");
+	tcase_add_loop_test(tc, test_cancellation_point,
+						0, countof(cancellation_points));
+	tcase_add_loop_test(tc, test_cancellation_point_pre,
+						0, countof(cancellation_points));
+	suite_add_tcase(s, tc);
+
 	tc = tcase_create("thread cleanup");
 	tcase_add_test(tc, test_cleanup);
 	tcase_add_test(tc, test_cleanup_exit);
diff --git a/src/libstrongswan/tests/suites/test_traffic_selector.c b/src/libstrongswan/tests/suites/test_traffic_selector.c
new file mode 100644
index 0000000..4312c6c
--- /dev/null
+++ b/src/libstrongswan/tests/suites/test_traffic_selector.c
@@ -0,0 +1,284 @@
+/*
+ * Copyright (C) 2015 Martin Willi
+ * Copyright (C) 2015 revosec AG
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * for more details.
+ */
+
+#include "test_suite.h"
+
+#include <selectors/traffic_selector.h>
+
+
+static void verify(const char *str, const char *alt, traffic_selector_t *ts)
+{
+	char buf[512];
+
+	ck_assert(ts != NULL);
+	snprintf(buf, sizeof(buf), "%R", ts);
+	ts->destroy(ts);
+	if (!streq(buf, str) && !streq(buf, alt))
+	{
+		fail("%s != %s or %s", buf, str, alt);
+	}
+}
+
+START_TEST(test_create_from_string)
+{
+	verify("10.1.0.0/16[tcp/http]", "10.1.0.0/16[6/80]",
+		traffic_selector_create_from_string(IPPROTO_TCP, TS_IPV4_ADDR_RANGE,
+							"10.1.0.0", 80, "10.1.255.255", 80));
+	verify("10.1.0.1..10.1.0.99[udp/1234-1235]",
+		   "10.1.0.1..10.1.0.99[17/1234-1235]",
+		traffic_selector_create_from_string(IPPROTO_UDP, TS_IPV4_ADDR_RANGE,
+							"10.1.0.1", 1234, "10.1.0.99", 1235));
+	verify("fec1::/64", NULL,
+		traffic_selector_create_from_string(0, TS_IPV6_ADDR_RANGE,
+							"fec1::", 0, "fec1::ffff:ffff:ffff:ffff", 65535));
+}
+END_TEST
+
+START_TEST(test_create_from_cidr)
+{
+	verify("10.1.0.0/16", NULL,
+		traffic_selector_create_from_cidr("10.1.0.0/16", 0, 0, 65535));
+	verify("10.1.0.1/32[udp/1234-1235]", "10.1.0.1/32[17/1234-1235]",
+		traffic_selector_create_from_cidr("10.1.0.1/32", IPPROTO_UDP,
+										  1234, 1235));
+}
+END_TEST
+
+START_TEST(test_create_from_bytes)
+{
+	verify("10.1.0.0/16", NULL,
+		traffic_selector_create_from_bytes(0, TS_IPV4_ADDR_RANGE,
+			chunk_from_chars(0x0a,0x01,0x00,0x00), 0,
+			chunk_from_chars(0x0a,0x01,0xff,0xff), 65535));
+}
+END_TEST
+
+START_TEST(test_create_from_subnet)
+{
+	verify("10.1.0.0/16", NULL,
+		traffic_selector_create_from_subnet(
+					host_create_from_string("10.1.0.0", 0), 16, 0, 0, 65535));
+}
+END_TEST
+
+
+START_TEST(test_subset)
+{
+	traffic_selector_t *a, *b;
+
+	a = traffic_selector_create_from_cidr("10.1.0.0/16", 0, 0, 65535);
+	b = traffic_selector_create_from_cidr("10.1.5.0/24", 0, 0, 65535);
+	verify("10.1.5.0/24", NULL, a->get_subset(a, b));
+	a->destroy(a);
+	b->destroy(b);
+}
+END_TEST
+
+START_TEST(test_subset_port)
+{
+	traffic_selector_t *a, *b;
+
+	a = traffic_selector_create_from_cidr("10.0.0.0/8", IPPROTO_TCP, 55, 60);
+	b = traffic_selector_create_from_cidr("10.2.7.16/30", 0, 0, 65535);
+	verify("10.2.7.16/30[tcp/55-60]", "10.2.7.16/30[6/55-60]",
+		a->get_subset(a, b));
+	a->destroy(a);
+	b->destroy(b);
+}
+END_TEST
+
+START_TEST(test_subset_equal)
+{
+	traffic_selector_t *a, *b;
+
+	a = traffic_selector_create_from_cidr("10.1.0.0/16", IPPROTO_TCP, 80, 80);
+	b = traffic_selector_create_from_cidr("10.1.0.0/16", IPPROTO_TCP, 80, 80);
+	verify("10.1.0.0/16[tcp/http]", "10.1.0.0/16[6/80]", a->get_subset(a, b));
+	a->destroy(a);
+	b->destroy(b);
+}
+END_TEST
+
+START_TEST(test_subset_nonet)
+{
+	traffic_selector_t *a, *b;
+
+	a = traffic_selector_create_from_cidr("10.1.0.0/16", 0, 0, 65535);
+	b = traffic_selector_create_from_cidr("10.2.0.0/16", 0, 0, 65535);
+	ck_assert(a->get_subset(a, b) == NULL);
+	a->destroy(a);
+	b->destroy(b);
+}
+END_TEST
+
+START_TEST(test_subset_noport)
+{
+	traffic_selector_t *a, *b;
+
+	a = traffic_selector_create_from_cidr("10.1.0.0/16", 0, 0, 9999);
+	b = traffic_selector_create_from_cidr("10.1.0.0/16", 0, 10000, 65535);
+	ck_assert(a->get_subset(a, b) == NULL);
+	a->destroy(a);
+	b->destroy(b);
+}
+END_TEST
+
+START_TEST(test_subset_noproto)
+{
+	traffic_selector_t *a, *b;
+
+	a = traffic_selector_create_from_cidr("10.1.0.0/16", IPPROTO_TCP, 0, 65535);
+	b = traffic_selector_create_from_cidr("10.1.0.0/16", IPPROTO_UDP, 0, 65535);
+	ck_assert(a->get_subset(a, b) == NULL);
+	a->destroy(a);
+	b->destroy(b);
+}
+END_TEST
+
+START_TEST(test_subset_nofamily)
+{
+	traffic_selector_t *a, *b;
+
+	a = traffic_selector_create_from_cidr("0.0.0.0/0", 0, 0, 65535);
+	b = traffic_selector_create_from_cidr("::/0", 0, 0, 65535);
+	ck_assert(a->get_subset(a, b) == NULL);
+	a->destroy(a);
+	b->destroy(b);
+}
+END_TEST
+
+struct {
+	char *net;
+	char *host;
+	bool inc;
+} include_tests[] = {
+	{ "0.0.0.0/0",		"192.168.1.2",			TRUE },
+	{ "::/0",			"fec2::1",				TRUE },
+	{ "fec2::/64",		"fec2::afaf",			TRUE },
+	{ "10.1.0.0/16",	"10.1.0.1",				TRUE },
+	{ "10.5.6.7/32",	"10.5.6.7",				TRUE },
+	{ "0.0.0.0/0",		"fec2::1",				FALSE },
+	{ "::/0",			"1.2.3.4",				FALSE },
+	{ "10.0.0.0/16",	"10.1.0.0",				FALSE },
+	{ "fec2::/64",		"fec2:0:0:1::afaf",		FALSE },
+};
+
+START_TEST(test_includes)
+{
+	traffic_selector_t *ts;
+	host_t *h;
+
+	ts = traffic_selector_create_from_cidr(include_tests[_i].net, 0, 0, 65535);
+	h = host_create_from_string(include_tests[_i].host, 0);
+	ck_assert(ts->includes(ts, h) == include_tests[_i].inc);
+	ts->destroy(ts);
+	h->destroy(h);
+}
+END_TEST
+
+struct {
+	int res;
+	struct {
+		char *net;
+		u_int8_t proto;
+		u_int16_t from_port;
+		u_int16_t to_port;
+	} a, b;
+} cmp_tests[] = {
+	{  0, { "10.0.0.0/8", 0, 0, 65535 },	{ "10.0.0.0/8", 0, 0, 65535 },	},
+	{  0, { "10.0.0.0/8", 17, 123, 456 },	{ "10.0.0.0/8", 17, 123, 456 },	},
+	{  0, { "fec2::/64", 0, 0, 65535 },		{ "fec2::/64", 0, 0, 65535 },	},
+	{  0, { "fec2::/64", 4, 0, 65535 },		{ "fec2::/64", 4, 0, 65535 },	},
+
+	{ -1, { "1.0.0.0/8", 0, 0, 65535 },		{ "2.0.0.0/8", 0, 0, 65535 },	},
+	{  1, { "2.0.0.0/8", 0, 0, 65535 },		{ "1.0.0.0/8", 0, 0, 65535 },	},
+	{ -1, { "1.0.0.0/8", 0, 0, 65535 },		{ "1.0.0.0/16", 0, 0, 65535 },	},
+	{  1, { "1.0.0.0/16", 0, 0, 65535 },	{ "1.0.0.0/8", 0, 0, 65535 },	},
+
+	{ -1, { "10.0.0.0/8", 0, 0, 65535 },	{ "fec2::/64", 0, 0, 65535 },	},
+	{  1, { "fec2::/64", 0, 0, 65535 },		{ "10.0.0.0/8", 0, 0, 65535 },	},
+
+	{ -1, { "10.0.0.0/8", 16, 123, 456 },	{ "10.0.0.0/8", 17, 123, 456 },	},
+	{  1, { "fec2::/64", 5, 0, 65535 },		{ "fec2::/64", 4, 0, 65535 },	},
+
+	{ -1, { "10.0.0.0/8", 17, 111, 456 },	{ "10.0.0.0/8", 17, 222, 456 },	},
+	{  1, { "fec2::/64", 17, 555, 65535 },	{ "fec2::/64", 17, 444, 65535 },},
+
+	{ -1, { "10.0.0.0/8", 17, 55, 65535 },	{ "10.0.0.0/8", 17, 55, 666 },	},
+	{  1, { "fec2::/64", 17, 55, 111 },		{ "fec2::/64", 17, 55, 4567 },	},
+
+};
+
+START_TEST(test_cmp)
+{
+	traffic_selector_t *a, *b;
+
+	a = traffic_selector_create_from_cidr(
+						cmp_tests[_i].a.net, cmp_tests[_i].a.proto,
+						cmp_tests[_i].a.from_port, cmp_tests[_i].a.to_port);
+	b = traffic_selector_create_from_cidr(
+						cmp_tests[_i].b.net, cmp_tests[_i].b.proto,
+						cmp_tests[_i].b.from_port, cmp_tests[_i].b.to_port);
+	switch (cmp_tests[_i].res)
+	{
+		case 0:
+			ck_assert(traffic_selector_cmp(a, b, NULL) == 0);
+			break;
+		case 1:
+			ck_assert(traffic_selector_cmp(a, b, NULL) > 0);
+			break;
+		case -1:
+			ck_assert(traffic_selector_cmp(a, b, NULL) < 0);
+			break;
+	}
+	a->destroy(a);
+	b->destroy(b);
+}
+END_TEST
+
+Suite *traffic_selector_suite_create()
+{
+	Suite *s;
+	TCase *tc;
+
+	s = suite_create("traffic selector");
+
+	tc = tcase_create("create");
+	tcase_add_test(tc, test_create_from_string);
+	tcase_add_test(tc, test_create_from_cidr);
+	tcase_add_test(tc, test_create_from_bytes);
+	tcase_add_test(tc, test_create_from_subnet);
+	suite_add_tcase(s, tc);
+
+	tc = tcase_create("subset");
+	tcase_add_test(tc, test_subset);
+	tcase_add_test(tc, test_subset_port);
+	tcase_add_test(tc, test_subset_equal);
+	tcase_add_test(tc, test_subset_nonet);
+	tcase_add_test(tc, test_subset_noport);
+	tcase_add_test(tc, test_subset_noproto);
+	tcase_add_test(tc, test_subset_nofamily);
+	suite_add_tcase(s, tc);
+
+	tc = tcase_create("includes");
+	tcase_add_loop_test(tc, test_includes, 0, countof(include_tests));
+	suite_add_tcase(s, tc);
+
+	tc = tcase_create("cmp");
+	tcase_add_loop_test(tc, test_cmp, 0, countof(cmp_tests));
+	suite_add_tcase(s, tc);
+
+	return s;
+}
diff --git a/src/libstrongswan/tests/suites/test_utils.c b/src/libstrongswan/tests/suites/test_utils.c
index abca462..85a8544 100644
--- a/src/libstrongswan/tests/suites/test_utils.c
+++ b/src/libstrongswan/tests/suites/test_utils.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2013 Tobias Brunner
+ * Copyright (C) 2013-2015 Tobias Brunner
  * Hochschule fuer Technik Rapperswil
  *
  * This program is free software; you can redistribute it and/or modify it
@@ -18,6 +18,7 @@
 #include <library.h>
 #include <utils/utils.h>
 #include <ipsec/ipsec_types.h>
+#include <credentials/keys/public_key.h>
 
 #include <time.h>
 
@@ -695,6 +696,44 @@ START_TEST(test_mark_from_string)
 }
 END_TEST
 
+/*******************************************************************************
+ * signature_schemes_for_key
+ */
+
+static struct {
+	key_type_t type;
+	int size;
+	signature_scheme_t expected[4];
+} scheme_data[] = {
+	{KEY_RSA,   1024, { SIGN_RSA_EMSA_PKCS1_SHA256, SIGN_RSA_EMSA_PKCS1_SHA384, SIGN_RSA_EMSA_PKCS1_SHA512, SIGN_UNKNOWN }},
+	{KEY_RSA,   2048, { SIGN_RSA_EMSA_PKCS1_SHA256, SIGN_RSA_EMSA_PKCS1_SHA384, SIGN_RSA_EMSA_PKCS1_SHA512, SIGN_UNKNOWN }},
+	{KEY_RSA,   4096, { SIGN_RSA_EMSA_PKCS1_SHA384, SIGN_RSA_EMSA_PKCS1_SHA512, SIGN_UNKNOWN }},
+	{KEY_RSA,   8192, { SIGN_RSA_EMSA_PKCS1_SHA512, SIGN_UNKNOWN }},
+	{KEY_ECDSA,  256, { SIGN_ECDSA_WITH_SHA256_DER, SIGN_ECDSA_WITH_SHA384_DER, SIGN_ECDSA_WITH_SHA512_DER, SIGN_UNKNOWN }},
+	{KEY_ECDSA,  384, { SIGN_ECDSA_WITH_SHA384_DER, SIGN_ECDSA_WITH_SHA512_DER, SIGN_UNKNOWN }},
+	{KEY_ECDSA,  512, { SIGN_ECDSA_WITH_SHA512_DER, SIGN_UNKNOWN }},
+	{KEY_BLISS,  128, { SIGN_BLISS_WITH_SHA256, SIGN_BLISS_WITH_SHA384, SIGN_BLISS_WITH_SHA512, SIGN_UNKNOWN }},
+	{KEY_BLISS,  192, { SIGN_BLISS_WITH_SHA384, SIGN_BLISS_WITH_SHA512, SIGN_UNKNOWN }},
+	{KEY_BLISS,  256, { SIGN_BLISS_WITH_SHA512, SIGN_UNKNOWN }},
+};
+
+START_TEST(test_signature_schemes_for_key)
+{
+	enumerator_t  *enumerator;
+	signature_scheme_t scheme;
+	int i;
+
+	enumerator = signature_schemes_for_key(scheme_data[_i].type, scheme_data[_i].size);
+	for (i = 0; scheme_data[_i].expected[i] != SIGN_UNKNOWN; i++)
+	{
+		ck_assert(enumerator->enumerate(enumerator, &scheme));
+		ck_assert_int_eq(scheme_data[_i].expected[i], scheme);
+	}
+	ck_assert(!enumerator->enumerate(enumerator, &scheme));
+	enumerator->destroy(enumerator);
+}
+END_TEST
+
 Suite *utils_suite_create()
 {
 	Suite *s;
@@ -777,5 +816,9 @@ Suite *utils_suite_create()
 	tcase_add_loop_test(tc, test_mark_from_string, 0, countof(mark_data));
 	suite_add_tcase(s, tc);
 
+	tc = tcase_create("signature_schemes_for_key");
+	tcase_add_loop_test(tc, test_signature_schemes_for_key, 0, countof(scheme_data));
+	suite_add_tcase(s, tc);
+
 	return s;
 }
diff --git a/src/libstrongswan/tests/tests.h b/src/libstrongswan/tests/tests.h
index 5862278..e1d8ca4 100644
--- a/src/libstrongswan/tests/tests.h
+++ b/src/libstrongswan/tests/tests.h
@@ -23,6 +23,7 @@ TEST_SUITE(linked_list_enumerator_suite_create)
 TEST_SUITE(hashtable_suite_create)
 TEST_SUITE(array_suite_create)
 TEST_SUITE(identification_suite_create)
+TEST_SUITE(traffic_selector_suite_create)
 TEST_SUITE(threading_suite_create)
 TEST_SUITE(process_suite_create)
 TEST_SUITE(watcher_suite_create)
@@ -32,6 +33,8 @@ TEST_SUITE(settings_suite_create)
 TEST_SUITE(vectors_suite_create)
 TEST_SUITE_DEPEND(ecdsa_suite_create, PRIVKEY_GEN, KEY_ECDSA)
 TEST_SUITE_DEPEND(rsa_suite_create, PRIVKEY_GEN, KEY_RSA)
+TEST_SUITE_DEPEND(certpolicy_suite_create, CERT_ENCODE, CERT_X509)
+TEST_SUITE_DEPEND(certnames_suite_create, CERT_ENCODE, CERT_X509)
 TEST_SUITE(host_suite_create)
 TEST_SUITE(printf_suite_create)
 TEST_SUITE(hasher_suite_create)
@@ -41,5 +44,7 @@ TEST_SUITE(pen_suite_create)
 TEST_SUITE(asn1_suite_create)
 TEST_SUITE(asn1_parser_suite_create)
 TEST_SUITE(test_rng_suite_create)
+TEST_SUITE_DEPEND(mgf1_sha1_suite_create, HASHER, HASH_SHA1)
+TEST_SUITE_DEPEND(mgf1_sha256_suite_create, HASHER, HASH_SHA256)
 TEST_SUITE_DEPEND(ntru_suite_create, DH, NTRU_112_BIT)
 TEST_SUITE_DEPEND(fetch_http_suite_create, FETCHER, "http://")
diff --git a/src/libstrongswan/threading/semaphore.h b/src/libstrongswan/threading/semaphore.h
index 34d8149..d3ab0f3 100644
--- a/src/libstrongswan/threading/semaphore.h
+++ b/src/libstrongswan/threading/semaphore.h
@@ -21,10 +21,7 @@
 #ifndef THREADING_SEMAPHORE_H_
 #define THREADING_SEMAPHORE_H_
 
-#ifdef __APPLE__
-/* Mach uses a semaphore_create() call, use a different name for ours */
-#define semaphore_create(x) strongswan_semaphore_create(x)
-#endif /* __APPLE__ */
+#include <utils/utils.h>
 
 typedef struct semaphore_t semaphore_t;
 
@@ -87,4 +84,3 @@ struct semaphore_t {
 semaphore_t *semaphore_create(u_int value);
 
 #endif /** THREADING_SEMAPHORE_H_ @} */
-
diff --git a/src/libstrongswan/threading/thread.h b/src/libstrongswan/threading/thread.h
index 6abb834..3827554 100644
--- a/src/libstrongswan/threading/thread.h
+++ b/src/libstrongswan/threading/thread.h
@@ -21,40 +21,9 @@
 #ifndef THREADING_THREAD_H_
 #define THREADING_THREAD_H_
 
-typedef struct thread_t thread_t;
-
-#ifdef __APPLE__
-/* thread_create is a syscall used to create Mach kernel threads and although
- * there are no errors or warnings during compilation or linkage the dynamic
- * linker does not use our implementation, therefore we rename it here
- */
-#define thread_create(main, arg) strongswan_thread_create(main, arg)
+#include <utils/utils.h>
 
-/* on Mac OS X 10.5 several system calls we use are no cancellation points.
- * fortunately, select isn't one of them, so we wrap some of the others with
- * calls to select(2).
- */
-#include <sys/socket.h>
-#include <sys/select.h>
-
-#define WRAP_WITH_SELECT(func, socket, ...)\
-	fd_set rfds; FD_ZERO(&rfds); FD_SET(socket, &rfds);\
-	if (select(socket + 1, &rfds, NULL, NULL, NULL) <= 0) { return -1; }\
-	return func(socket, __VA_ARGS__)
-
-static inline int cancellable_accept(int socket, struct sockaddr *address,
-									 socklen_t *address_len)
-{
-	WRAP_WITH_SELECT(accept, socket, address, address_len);
-}
-#define accept cancellable_accept
-static inline int cancellable_recvfrom(int socket, void *buffer, size_t length,
-				int flags, struct sockaddr *address, socklen_t *address_len)
-{
-	WRAP_WITH_SELECT(recvfrom, socket, buffer, length, flags, address, address_len);
-}
-#define recvfrom cancellable_recvfrom
-#endif /* __APPLE__ */
+typedef struct thread_t thread_t;
 
 /**
  * Main function of a thread.
@@ -189,32 +158,4 @@ void threads_init();
  */
 void threads_deinit();
 
-
-#ifdef __APPLE__
-
-/*
- * While select() is a cancellation point, it seems that OS X does not honor
- * pending cancellation points when entering the function. We manually test for
- * and honor pending cancellation requests, but this obviously can't prevent
- * some race conditions where the the cancellation happens after the check,
- * but before the select.
- */
-static inline int precancellable_select(int nfds, fd_set *restrict readfds,
-						fd_set *restrict writefds, fd_set *restrict errorfds,
-						struct timeval *restrict timeout)
-{
-	if (thread_cancelability(TRUE))
-	{
-		thread_cancellation_point();
-	}
-	else
-	{
-		thread_cancelability(FALSE);
-	}
-	return select(nfds, readfds, writefds, errorfds, timeout);
-}
-#define select precancellable_select
-
-#endif /* __APPLE__ */
-
 #endif /** THREADING_THREAD_H_ @} */
diff --git a/src/libstrongswan/threading/windows/rwlock.c b/src/libstrongswan/threading/windows/rwlock.c
index 0de57f7..fc0d6d8 100644
--- a/src/libstrongswan/threading/windows/rwlock.c
+++ b/src/libstrongswan/threading/windows/rwlock.c
@@ -85,8 +85,6 @@ METHOD(rwlock_t, write_lock, void,
 METHOD(rwlock_t, try_write_lock, bool,
 	private_rwlock_t *this)
 {
-	/* TODO: causes random failures and segfaults. Bug? */
-	return FALSE;
 	return TryAcquireSRWLockExclusive(&this->srw);
 }
 
diff --git a/src/libstrongswan/utils/chunk.c b/src/libstrongswan/utils/chunk.c
index 4b24b37..c4471be 100644
--- a/src/libstrongswan/utils/chunk.c
+++ b/src/libstrongswan/utils/chunk.c
@@ -992,7 +992,7 @@ u_int32_t chunk_hash_static(chunk_t chunk)
  */
 u_int16_t chunk_internet_checksum_inc(chunk_t data, u_int16_t checksum)
 {
-	u_int32_t sum = ntohs(~checksum);
+	u_int32_t sum = ntohs((u_int16_t)~checksum);
 
 	while (data.len > 1)
 	{
diff --git a/src/libstrongswan/utils/compat/apple.h b/src/libstrongswan/utils/compat/apple.h
new file mode 100644
index 0000000..61afb9d
--- /dev/null
+++ b/src/libstrongswan/utils/compat/apple.h
@@ -0,0 +1,119 @@
+/*
+ * Copyright (C) 2014 Martin Willi
+ * Copyright (C) 2014 revosec AG
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * for more details.
+ */
+
+/**
+ * @defgroup apple apple
+ * @{ @ingroup compat
+ */
+
+#ifndef APPLE_H_
+#define APPLE_H_
+
+#include <poll.h>
+#include <sys/socket.h>
+#include <sys/select.h>
+
+/* thread_create is a syscall used to create Mach kernel threads and although
+ * there are no errors or warnings during compilation or linkage the dynamic
+ * linker does not use our implementation, therefore we rename it here
+ */
+#define thread_create(main, arg) strongswan_thread_create(main, arg)
+
+/* Mach uses a semaphore_create() call, use a different name for ours */
+#define semaphore_create(x) strongswan_semaphore_create(x)
+
+/* Since OS X 10.10 XPC includes some additional conflicting Mach types */
+#define host_t strongswan_host_t
+#define processor_t strongswan_processor_t
+#define task_t strongswan_task_t
+#define thread_t strongswan_thread_t
+
+/* forward declaration, see below */
+static inline int precancellable_poll(struct pollfd fds[], nfds_t nfds,
+									  int timeout);
+
+/* on Mac OS X 10.5 several system calls we use are no cancellation points.
+ * fortunately, select isn't one of them, so we wrap some of the others with
+ * calls to select(2).
+ */
+
+#define WRAP_WITH_POLL(func, socket, ...) \
+	struct pollfd pfd = { \
+		.fd = socket, \
+		.events = POLLIN, \
+	}; \
+	if (precancellable_poll(&pfd, 1, -1) <= 0) \
+	{\
+		return -1; \
+	}\
+	return func(socket, __VA_ARGS__)
+
+static inline int cancellable_accept(int socket, struct sockaddr *address,
+									 socklen_t *address_len)
+{
+	WRAP_WITH_POLL(accept, socket, address, address_len);
+}
+#define accept cancellable_accept
+static inline int cancellable_recvfrom(int socket, void *buffer, size_t length,
+				int flags, struct sockaddr *address, socklen_t *address_len)
+{
+	WRAP_WITH_POLL(recvfrom, socket, buffer, length, flags, address, address_len);
+}
+#define recvfrom cancellable_recvfrom
+
+#include <threading/thread.h>
+
+/*
+ * While select() is a cancellation point, it seems that OS X does not honor
+ * pending cancellation points when entering the function. We manually test for
+ * and honor pending cancellation requests, but this obviously can't prevent
+ * some race conditions where the the cancellation happens after the check,
+ * but before the select.
+ */
+static inline int precancellable_select(int nfds, fd_set *restrict readfds,
+						fd_set *restrict writefds, fd_set *restrict errorfds,
+						struct timeval *restrict timeout)
+{
+	if (thread_cancelability(TRUE))
+	{
+		thread_cancellation_point();
+	}
+	else
+	{
+		thread_cancelability(FALSE);
+	}
+	return select(nfds, readfds, writefds, errorfds, timeout);
+}
+#define select precancellable_select
+
+/*
+ * The same as to select(2) applies to poll(2)
+ */
+static inline int precancellable_poll(struct pollfd fds[], nfds_t nfds,
+									  int timeout)
+{
+	if (thread_cancelability(TRUE))
+	{
+		thread_cancellation_point();
+	}
+	else
+	{
+		thread_cancelability(FALSE);
+	}
+	return poll(fds, nfds, timeout);
+}
+#define poll precancellable_poll
+
+#endif /** APPLE_H_ @}*/
diff --git a/src/libstrongswan/utils/compat/windows.c b/src/libstrongswan/utils/compat/windows.c
new file mode 100644
index 0000000..1f22ffa
--- /dev/null
+++ b/src/libstrongswan/utils/compat/windows.c
@@ -0,0 +1,684 @@
+/*
+ * Copyright (C) 2013 Martin Willi
+ * Copyright (C) 2013 revosec AG
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * for more details.
+ */
+
+/* WSAPoll() */
+#define _WIN32_WINNT 0x0600
+
+#include <utils/utils.h>
+
+#include <errno.h>
+
+/**
+ * See header
+ */
+void windows_init()
+{
+	WSADATA wsad;
+
+	/* initialize winsock2 */
+	WSAStartup(MAKEWORD(2, 2), &wsad);
+}
+
+/**
+ * See header
+ */
+void windows_deinit()
+{
+	WSACleanup();
+}
+
+/**
+ * See header
+ */
+int usleep(useconds_t usec)
+{
+	if (usec > 0 && usec < 1000)
+	{	/* do not Sleep(0) for small values */
+		usec = 1000;
+	}
+	SleepEx(usec / 1000, TRUE);
+	return 0;
+}
+
+/**
+ * See header.
+ */
+char* strndup(const char *s, size_t n)
+{
+	char *dst;
+
+	n = min(strnlen(s, n), n);
+	dst = malloc(n + 1);
+	memcpy(dst, s, n);
+	dst[n] = '\0';
+
+	return dst;
+}
+
+/*
+ * See header.
+ */
+void *dlopen(const char *filename, int flag)
+{
+	return LoadLibrary(filename);
+}
+
+/**
+ * Load a symbol from known default libs (monolithic build)
+ */
+static void* dlsym_default(const char *name)
+{
+	const char *dlls[] = {
+		"libstrongswan-0.dll",
+		"libhydra-0.dll",
+		"libcharon-0.dll",
+		"libtnccs-0.dll",
+		NULL /* .exe */
+	};
+	HANDLE handle;
+	void *sym = NULL;
+	int i;
+
+	for (i = 0; i < countof(dlls); i++)
+	{
+		handle = GetModuleHandle(dlls[i]);
+		if (handle)
+		{
+			sym = GetProcAddress(handle, name);
+			if (sym)
+			{
+				break;
+			}
+		}
+	}
+	return sym;
+}
+
+/**
+ * Emulate RTLD_NEXT for some known symbols
+ */
+static void* dlsym_next(const char *name)
+{
+	struct {
+		const char *dll;
+		const char *syms[4];
+	} dlls[] = {
+		/* for leak detective */
+		{ "msvcrt",
+			{ "malloc", "calloc", "realloc", "free" }
+		},
+	};
+	HANDLE handle = NULL;
+	int i, j;
+
+	for (i = 0; i < countof(dlls); i++)
+	{
+		for (j = 0; j < countof(dlls[0].syms); j++)
+		{
+			if (dlls[i].syms[j] && streq(dlls[i].syms[j], name))
+			{
+				handle = GetModuleHandle(dlls[i].dll);
+				break;
+			}
+		}
+	}
+	if (handle)
+	{
+		return GetProcAddress(handle, name);
+	}
+	return handle;
+}
+
+/**
+ * See header.
+ */
+void* dlsym(void *handle, const char *symbol)
+{
+	if (handle == RTLD_DEFAULT)
+	{
+		return dlsym_default(symbol);
+	}
+	if (handle == RTLD_NEXT)
+	{
+		return dlsym_next(symbol);
+	}
+	return GetProcAddress((HMODULE)handle, symbol);
+}
+
+/**
+ * See header.
+ */
+char* dlerror(void)
+{
+	static char buf[128];
+	char *pos;
+	DWORD err;
+
+	err = GetLastError();
+	if (FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
+					  NULL, err, 0, buf, sizeof(buf), NULL) > 0)
+	{
+		pos = strchr(buf, '\n');
+		if (pos)
+		{
+			*pos = '\0';
+		}
+	}
+	else
+	{
+		snprintf(buf, sizeof(buf), "(%u)", err);
+	}
+	return buf;
+}
+
+/**
+ * See header.
+ */
+int dlclose(void *handle)
+{
+	return FreeLibrary((HMODULE)handle);
+}
+
+/**
+ * See header
+ */
+int socketpair(int domain, int type, int protocol, int sv[2])
+{
+	struct sockaddr_in addr = {
+		.sin_family = AF_INET,
+		.sin_addr.s_addr = htonl(INADDR_LOOPBACK),
+	};
+	socklen_t len = sizeof(addr);
+	int s, c, sc;
+	BOOL on;
+
+	/* We don't check domain for AF_INET, as we use it as replacement for
+	 * AF_UNIX. */
+	if (type != SOCK_STREAM)
+	{
+		errno = EINVAL;
+		return -1;
+	}
+	if (protocol != 0 && protocol != IPPROTO_TCP)
+	{
+		errno = EINVAL;
+		return -1;
+	}
+	s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
+	if (s == -1)
+	{
+		return -1;
+	}
+	c = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
+	if (c == -1)
+	{
+		closesocket(s);
+		return -1;
+	}
+	if (bind(s, (struct sockaddr*)&addr, sizeof(addr)) == 0 &&
+		getsockname(s,(struct sockaddr*)&addr, &len) == 0 &&
+		listen(s, 0) == 0 &&
+		connect(c, (struct sockaddr*)&addr, sizeof(addr)) == 0)
+	{
+		sc = accept(s, NULL, NULL);
+		if (sc >= 0)
+		{
+			closesocket(s);
+			s = sc;
+			if (setsockopt(s, IPPROTO_TCP, TCP_NODELAY,
+						   (void*)&on, sizeof(on)) == 0 &&
+				setsockopt(c, IPPROTO_TCP, TCP_NODELAY,
+						   (void*)&on, sizeof(on)) == 0)
+			{
+				sv[0] = s;
+				sv[1] = c;
+				return 0;
+			}
+		}
+	}
+	closesocket(s);
+	closesocket(c);
+	return -1;
+}
+
+/**
+ * See header
+ */
+char* getpass(const char *prompt)
+{
+	static char buf[64] = "";
+	char *pos;
+	HANDLE in, out;
+	DWORD mode, written = 0, total, done;
+
+	out = GetStdHandle(STD_OUTPUT_HANDLE);
+	in = GetStdHandle(STD_INPUT_HANDLE);
+
+	if (out == INVALID_HANDLE_VALUE || in == INVALID_HANDLE_VALUE ||
+		!GetConsoleMode(out, &mode) || !GetConsoleMode(in, &mode))
+	{
+		return NULL;
+	}
+
+	total = strlen(prompt);
+	while (written < total)
+	{
+		if (!WriteConsole(out, prompt + written, total - written, &done, NULL))
+		{
+			return NULL;
+		}
+		written += done;
+	}
+
+	if (!SetConsoleMode(in, mode & ~ENABLE_ECHO_INPUT))
+	{
+		return NULL;
+	}
+
+	while (TRUE)
+	{
+		if (!ReadConsole(in, buf, sizeof(buf), &done, NULL))
+		{
+			SetConsoleMode(in, mode);
+			return NULL;
+		}
+		buf[sizeof(buf)-1] = '\0';
+
+		if (done)
+		{
+			pos = strchr(buf, '\r');
+			if (pos)
+			{
+				*pos = '\0';
+			}
+			break;
+		}
+	}
+	SetConsoleMode(in, mode);
+
+	/* append a newline, as we have no echo during input */
+	WriteConsole(out, "\r\n", 2, &done, NULL);
+
+	return buf;
+}
+
+/**
+ * See header.
+ */
+#undef strerror_s
+int strerror_s_extended(char *buf, size_t buflen, int errnum)
+{
+	const char *errstr [] = {
+		/* EADDRINUSE */		"Address in use",
+		/* EADDRNOTAVAIL */		"Address not available",
+		/* EAFNOSUPPORT */		"Address family not supported",
+		/* EALREADY */			"Connection already in progress",
+		/* EBADMSG */			"Bad message",
+		/* ECANCELED */			"Operation canceled",
+		/* ECONNABORTED */		"Connection aborted",
+		/* ECONNREFUSED */		"Connection refused",
+		/* ECONNRESET */		"Connection reset",
+		/* EDESTADDRREQ */		"Destination address required",
+		/* EHOSTUNREACH */		"Host is unreachable",
+		/* EIDRM */				"Identifier removed",
+		/* EINPROGRESS */		"Operation in progress",
+		/* EISCONN */			"Socket is connected",
+		/* ELOOP */				"Too many levels of symbolic links",
+		/* EMSGSIZE */			"Message too large",
+		/* ENETDOWN */			"Network is down",
+		/* ENETRESET */			"Connection aborted by network",
+		/* ENETUNREACH */		"Network unreachable",
+		/* ENOBUFS */			"No buffer space available",
+		/* ENODATA */			"No message is available",
+		/* ENOLINK */			"No link",
+		/* ENOMSG */			"No message of the desired type",
+		/* ENOPROTOOPT */		"Protocol not available",
+		/* ENOSR */				"No stream resources",
+		/* ENOSTR */			"Not a stream",
+		/* ENOTCONN */			"The socket is not connected",
+		/* ENOTRECOVERABLE */	"State not recoverable",
+		/* ENOTSOCK */			"Not a socket",
+		/* ENOTSUP */			"Not supported",
+		/* EOPNOTSUPP */		"Operation not supported on socket",
+		/* EOTHER */			"Other error",
+		/* EOVERFLOW */			"Value too large to be stored in data type",
+		/* EOWNERDEAD */		"Previous owner died",
+		/* EPROTO */			"Protocol error",
+		/* EPROTONOSUPPORT */	"Protocol not supported",
+		/* EPROTOTYPE */		"Protocol wrong type for socket",
+		/* ETIME */				"Timeout",
+		/* ETIMEDOUT */			"Connection timed out",
+		/* ETXTBSY */			"Text file busy",
+		/* EWOULDBLOCK */		"Operation would block",
+	};
+	int offset = EADDRINUSE;
+
+	if (errnum < offset || errnum >= offset + countof(errstr))
+	{
+		return strerror_s(buf, buflen, errnum);
+	}
+	strncpy(buf, errstr[errnum - offset], buflen);
+	buf[buflen - 1] = '\0';
+	return 0;
+}
+
+/**
+ * Set errno for a function setting WSA error on failure
+ */
+static int wserr(int retval)
+{
+	if (retval < 0)
+	{
+		static const struct {
+			DWORD wsa;
+			int err;
+		} map[] = {
+			{ WSANOTINITIALISED,			EBADF						},
+			{ WSAENETDOWN,					ENETDOWN					},
+			{ WSAENETRESET,					ENETRESET					},
+			{ WSAECONNABORTED,				ECONNABORTED				},
+			{ WSAESHUTDOWN,					ECONNABORTED				},
+			{ WSAEACCES,					EACCES						},
+			{ WSAEINTR,						EINTR						},
+			{ WSAEINPROGRESS,				EINPROGRESS					},
+			{ WSAEFAULT,					EFAULT						},
+			{ WSAENOBUFS,					ENOBUFS						},
+			{ WSAENOTSOCK,					ENOTSOCK					},
+			{ WSAEOPNOTSUPP,				EOPNOTSUPP					},
+			{ WSAEWOULDBLOCK,				EWOULDBLOCK					},
+			{ WSAEMSGSIZE,					EMSGSIZE					},
+			{ WSAEINVAL,					EINVAL						},
+			{ WSAENOTCONN,					ENOTCONN					},
+			{ WSAEHOSTUNREACH,				EHOSTUNREACH				},
+			{ WSAENETUNREACH,				ENETUNREACH					},
+			{ WSAECONNABORTED,				ECONNABORTED				},
+			{ WSAECONNRESET,				ECONNRESET					},
+			{ WSAETIMEDOUT,					ETIMEDOUT					},
+			{ WSAEMFILE,					EMFILE						},
+			{ WSAEALREADY,					EALREADY					},
+			{ WSAEDESTADDRREQ,				EDESTADDRREQ				},
+			{ WSAEISCONN,					EISCONN						},
+			{ WSAEOPNOTSUPP,				EOPNOTSUPP					},
+			{ WSAEPROTOTYPE,				EPROTOTYPE					},
+			{ WSAENOPROTOOPT,				ENOPROTOOPT					},
+			{ WSAEPROTONOSUPPORT,			EPROTONOSUPPORT				},
+			{ WSAEPFNOSUPPORT,				EPROTONOSUPPORT				},
+			{ WSAEAFNOSUPPORT,				EAFNOSUPPORT				},
+			{ WSAEADDRNOTAVAIL,				EADDRNOTAVAIL				},
+			{ WSAEADDRINUSE,				EADDRINUSE					},
+			{ WSAETIMEDOUT,					ETIMEDOUT					},
+			{ WSAECONNREFUSED,				ECONNREFUSED				},
+			{ WSAELOOP,						ELOOP						},
+			{ WSAENAMETOOLONG,				ENAMETOOLONG				},
+			{ WSAENOTEMPTY,					ENOTEMPTY					},
+			{ WSAEPROTOTYPE,				EPROTOTYPE					},
+			{ WSAVERNOTSUPPORTED,			ENOTSUP						},
+		};
+		DWORD wsa, i;
+
+		wsa = WSAGetLastError();
+		for (i = 0; i < countof(map); i++)
+		{
+			if (map[i].wsa == wsa)
+			{
+				errno = map[i].err;
+				return retval;
+			}
+		}
+		errno = ENOENT;
+		return retval;
+	}
+	errno = 0;
+	return retval;
+}
+
+/**
+ * Check and clear the dontwait flag
+ */
+static bool check_dontwait(int *flags)
+{
+	if (*flags & MSG_DONTWAIT)
+	{
+		*flags &= ~MSG_DONTWAIT;
+		return TRUE;
+	}
+	return FALSE;
+}
+
+/**
+ * See header
+ */
+#undef shutdown
+int windows_shutdown(int sockfd, int how)
+{
+	return wserr(shutdown(sockfd, how));
+}
+
+/**
+ * See header
+ */
+#undef accept
+int windows_accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen)
+{
+	return wserr(accept(sockfd, addr, addrlen));
+}
+
+/**
+ * See header
+ */
+#undef bind
+int windows_bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen)
+{
+	return wserr(bind(sockfd, addr, addrlen));
+}
+
+/**
+ * See header
+ */
+#undef connect
+int windows_connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen)
+{
+	return wserr(connect(sockfd, addr, addrlen));
+}
+
+/**
+ * See header
+ */
+#undef getsockname
+int windows_getsockname(int sockfd, struct sockaddr *addr, socklen_t *addrlen)
+{
+	return wserr(getsockname(sockfd, addr, addrlen));
+}
+
+/**
+ * See header
+ */
+#undef getsockopt
+int windows_getsockopt(int sockfd, int level, int optname,
+					   void *optval, socklen_t *optlen)
+{
+	return wserr(getsockopt(sockfd, level, optname, optval, optlen));
+}
+
+/**
+ * See header
+ */
+#undef setsockopt
+int windows_setsockopt(int sockfd, int level, int optname,
+					   const void *optval, socklen_t optlen)
+{
+	return wserr(setsockopt(sockfd, level, optname, optval, optlen));
+}
+
+/**
+ * See header
+ */
+#undef socket
+int windows_socket(int domain, int type, int protocol)
+{
+	return wserr(socket(domain, type, protocol));
+}
+
+/**
+ * See header
+ */
+#undef select
+int windows_select(int nfds, fd_set *readfds, fd_set *writefds,
+				   fd_set *exceptfds, struct timeval *timeout)
+{
+	return wserr(select(nfds, readfds, writefds, exceptfds, timeout));
+}
+
+/**
+ * See header
+ */
+#undef close
+int windows_close(int fd)
+{
+	int ret;
+
+	ret = close(fd);
+	if (ret == -1 && errno == EBADF)
+	{	/* Winsock socket? */
+		ret = wserr(closesocket(fd));
+	}
+	return ret;
+}
+
+/**
+ * See header
+ */
+#undef recv
+ssize_t windows_recv(int sockfd, void *buf, size_t len, int flags)
+{
+	u_long on = 1, off = 0;
+	ssize_t outlen = -1;
+
+	if (!check_dontwait(&flags))
+	{
+		return wserr(recv(sockfd, buf, len, flags));
+	}
+	if (wserr(ioctlsocket(sockfd, FIONBIO, &on) == 0))
+	{
+		outlen = wserr(recv(sockfd, buf, len, flags));
+		ioctlsocket(sockfd, FIONBIO, &off);
+	}
+	return outlen;
+}
+
+/**
+ * See header
+ */
+#undef recvfrom
+ssize_t windows_recvfrom(int sockfd, void *buf, size_t len, int flags,
+						 struct sockaddr *src_addr, socklen_t *addrlen)
+{
+	u_long on = 1, off = 0;
+	ssize_t outlen = -1;
+
+	if (!check_dontwait(&flags))
+	{
+		return wserr(recvfrom(sockfd, buf, len, flags, src_addr, addrlen));
+	}
+	if (wserr(ioctlsocket(sockfd, FIONBIO, &on)) == 0)
+	{
+		outlen = wserr(recvfrom(sockfd, buf, len, flags, src_addr, addrlen));
+		ioctlsocket(sockfd, FIONBIO, &off);
+	}
+	return outlen;
+}
+
+/**
+ * See header
+ */
+#undef send
+ssize_t windows_send(int sockfd, const void *buf, size_t len, int flags)
+{
+	u_long on = 1, off = 0;
+	ssize_t outlen = -1;
+
+	if (!check_dontwait(&flags))
+	{
+		return wserr(send(sockfd, buf, len, flags));
+	}
+	if (wserr(ioctlsocket(sockfd, FIONBIO, &on)) == 0)
+	{
+		outlen = wserr(send(sockfd, buf, len, flags));
+		ioctlsocket(sockfd, FIONBIO, &off);
+	}
+	return outlen;
+}
+
+/**
+ * See header
+ */
+#undef sendto
+ssize_t windows_sendto(int sockfd, const void *buf, size_t len, int flags,
+					   const struct sockaddr *dest_addr, socklen_t addrlen)
+{
+	u_long on = 1, off = 0;
+	ssize_t outlen = -1;
+
+	if (!check_dontwait(&flags))
+	{
+		return wserr(sendto(sockfd, buf, len, flags, dest_addr, addrlen));
+	}
+	if (wserr(ioctlsocket(sockfd, FIONBIO, &on)) == 0)
+	{
+		outlen = wserr(sendto(sockfd, buf, len, flags, dest_addr, addrlen));
+		ioctlsocket(sockfd, FIONBIO, &off);
+	}
+	return outlen;
+}
+
+/**
+ * See header
+ */
+#undef read
+ssize_t windows_read(int fd, void *buf, size_t count)
+{
+	ssize_t ret;
+
+	ret = wserr(recv(fd, buf, count, 0));
+	if (ret == -1 && errno == ENOTSOCK)
+	{
+		ret = read(fd, buf, count);
+	}
+	return ret;
+}
+
+/**
+ * See header
+ */
+#undef write
+ssize_t windows_write(int fd, void *buf, size_t count)
+{
+	ssize_t ret;
+
+	ret = wserr(send(fd, buf, count, 0));
+	if (ret == -1 && errno == ENOTSOCK)
+	{
+		ret = write(fd, buf, count);
+	}
+	return ret;
+}
+
+/**
+ * See header
+ */
+int poll(struct pollfd *fds, int nfds, int timeout)
+{
+	return wserr(WSAPoll(fds, nfds, timeout));
+}
diff --git a/src/libstrongswan/utils/compat/windows.h b/src/libstrongswan/utils/compat/windows.h
new file mode 100644
index 0000000..fd4f1f1
--- /dev/null
+++ b/src/libstrongswan/utils/compat/windows.h
@@ -0,0 +1,627 @@
+/*
+ * Copyright (C) 2013 Martin Willi
+ * Copyright (C) 2013 revosec AG
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * for more details.
+ */
+
+/**
+ * @defgroup windows windows
+ * @{ @ingroup compat
+ */
+
+#ifndef WINDOWS_H_
+#define WINDOWS_H_
+
+#include <winsock2.h>
+#include <ws2tcpip.h>
+#include <direct.h>
+#include <inttypes.h>
+#include <unistd.h>
+#include <sys/stat.h>
+
+/* undef Windows variants evaluating values more than once */
+#undef min
+#undef max
+
+/* interface is defined as an alias to "struct" in basetypes.h, but
+ * we use it here and there as ordinary identifier. */
+#undef interface
+
+/* used by Windows API, but we have our own */
+#undef CALLBACK
+
+/* UID/GID types for capabilities, even if not supported */
+typedef u_int uid_t;
+typedef u_int gid_t;
+
+/**
+ * Initialize Windows libraries
+ */
+void windows_init();
+
+/**
+ * Deinitialize windows libraries
+ */
+void windows_deinit();
+
+/**
+ * Replacement for random(3)
+ */
+static inline long random(void)
+{
+	return rand();
+}
+
+/**
+ * Replacement for srandom(3)
+ */
+static inline void srandom(unsigned int seed)
+{
+	srand(seed);
+}
+
+/**
+ * Replacement of sched_yield(2) from <sched.h>
+ */
+static inline int sched_yield(void)
+{
+	Sleep(0);
+	return 0;
+}
+
+/**
+ * Replacement of sleep(3), cancellable by thread_cancel()
+ */
+#define sleep sleep_cancellable
+static inline int sleep_cancellable(unsigned int seconds)
+{
+	SleepEx(seconds * 1000, TRUE);
+	return 0;
+}
+
+/**
+ * Replacement of usleep(3), cancellable, ms resolution only
+ */
+int usleep(useconds_t usec);
+
+/**
+ * strdup(3), the Windows variant can't free(strdup("")) and others
+ */
+#define strdup strdup_windows
+static inline char* strdup_windows(const char *src)
+{
+	size_t len;
+	char *dst;
+
+	len = strlen(src) + 1;
+	dst = malloc(len);
+	memcpy(dst, src, len);
+	return dst;
+}
+
+/**
+ * strndup(3)
+ */
+char* strndup(const char *s, size_t n);
+
+/**
+ * Provided via ws2_32
+ */
+#ifndef InetNtop
+const char WINAPI *inet_ntop(int af, const void *src, char *dst, socklen_t size);
+#endif
+
+/**
+ * Provided via ws2_32
+ */
+#ifndef InetPton
+int WINAPI inet_pton(int af, const char *src, void *dst);
+#endif
+
+/**
+ * Provided by printf hook backend
+ */
+int asprintf(char **strp, const char *fmt, ...);
+
+/**
+ * Provided by printf hook backend
+ */
+int vasprintf(char **strp, const char *fmt, va_list ap);
+
+/**
+ * timeradd(3) from <sys/time.h>
+ */
+static inline void timeradd(struct timeval *a, struct timeval *b,
+							struct timeval *res)
+{
+	res->tv_sec = a->tv_sec + b->tv_sec;
+	res->tv_usec = a->tv_usec + b->tv_usec;
+	if (res->tv_usec >= 1000000)
+	{
+		res->tv_usec -= 1000000;
+		res->tv_sec++;
+	}
+}
+
+/**
+ * timersub(3) from <sys/time.h>
+ */
+static inline void timersub(struct timeval *a, struct timeval *b,
+							struct timeval *res)
+{
+	res->tv_sec = a->tv_sec - b->tv_sec;
+	res->tv_usec = a->tv_usec - b->tv_usec;
+	if (res->tv_usec < 0)
+	{
+		res->tv_usec += 1000000;
+		res->tv_sec--;
+	}
+}
+
+/**
+ * gmtime_r(3) from <time.h>
+ */
+static inline struct tm *gmtime_r(const time_t *timep, struct tm *result)
+{
+	struct tm *ret;
+
+	/* gmtime_s() and friends seem not to be implemented/functioning.
+	 * Relying on gmtime() on Windows works as well, as it uses thread
+	 * specific buffers. */
+	ret = gmtime(timep);
+	if (ret)
+	{
+		memcpy(result, ret, sizeof(*result));
+	}
+	return ret;
+}
+
+/**
+ * localtime_r(3) from <time.h>
+ */
+static inline struct tm *localtime_r(const time_t *timep, struct tm *result)
+{
+	struct tm *ret;
+
+	/* localtime_s() and friends seem not to be implemented/functioning.
+	 * Relying on localtime() on Windows works as well, as it uses thread
+	 * specific buffers. */
+	ret = localtime(timep);
+	if (ret)
+	{
+		memcpy(result, ret, sizeof(*result));
+	}
+	return ret;
+}
+
+/**
+ * setenv(3) from <stdlib.h>, overwrite flag is ignored
+ */
+static inline int setenv(const char *name, const char *value, int overwrite)
+{
+	if (SetEnvironmentVariableA(name, value) == 0)
+	{	/* failed */
+		return -1;
+	}
+	return 0;
+}
+
+/**
+ * Lazy binding, ignored on Windows
+ */
+#define RTLD_LAZY 1
+
+/**
+ * Default handle targeting .exe
+ */
+#define RTLD_DEFAULT (NULL)
+
+/**
+ * Find symbol in next library
+ */
+#define RTLD_NEXT ((void*)~(uintptr_t)0)
+
+/**
+ * dlopen(3) from <dlfcn.h>
+ */
+void* dlopen(const char *filename, int flag);
+
+/**
+ * dlsym() from <dlfcn.h>
+ */
+void* dlsym(void *handle, const char *symbol);
+
+/**
+ * dlerror(3) from <dlfcn.h>, currently not thread save
+ */
+char* dlerror(void);
+
+/**
+ * dlclose() from <dlfcn.h>
+ */
+int dlclose(void *handle);
+
+/**
+ * socketpair(2) for SOCK_STREAM, uses TCP on loopback
+ */
+int socketpair(int domain, int type, int protocol, int sv[2]);
+
+/**
+ * getpass(3) on Windows consoles
+ */
+char* getpass(const char *prompt);
+#define HAVE_GETPASS
+
+/**
+ * Map MSG_DONTWAIT to the reserved, but deprecated MSG_INTERRUPT
+ */
+#define MSG_DONTWAIT MSG_INTERRUPT
+
+/**
+ * shutdown(2) "how"-aliases, to use Unix variant on Windows
+ */
+#define SHUT_RD SD_RECEIVE
+#define SHUT_WR SD_SEND
+#define SHUT_RDWR SD_BOTH
+
+/**
+ * shutdown(2) setting errno
+ */
+#define shutdown windows_shutdown
+int windows_shutdown(int sockfd, int how);
+
+/**
+ * accept(2) setting errno
+ */
+#define accept windows_accept
+int windows_accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
+
+/**
+ * bind(2) setting errno
+ */
+#define bind windows_bind
+int windows_bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
+
+/**
+ * connect(2) setting errno
+ */
+#define connect windows_connect
+int windows_connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
+
+/**
+ * getsockname(2) setting errno
+ */
+#define getsockname windows_getsockname
+int windows_getsockname(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
+
+/**
+ * getsockopt(2) setting errno
+ */
+#define getsockopt windows_getsockopt
+int windows_getsockopt(int sockfd, int level, int optname,
+					   void *optval, socklen_t *optlen);
+
+/**
+ * setsockopt(2) setting errno
+ */
+#define setsockopt windows_setsockopt
+int windows_setsockopt(int sockfd, int level, int optname,
+					   const void *optval, socklen_t optlen);
+
+/**
+ * socket(2) setting errno
+ */
+#define socket windows_socket
+int windows_socket(int domain, int type, int protocol);
+
+/**
+ * select(2) setting errno
+ */
+#define select windows_select
+int windows_select(int nfds, fd_set *readfds, fd_set *writefds,
+				   fd_set *exceptfds, struct timeval *timeout);
+
+/**
+ * close(2) working for file handles and Winsock sockets
+ */
+#define close windows_close
+int windows_close(int fd);
+
+/**
+ * recv(2) with support for MSG_DONTWAIT
+ */
+#define recv windows_recv
+ssize_t windows_recv(int sockfd, void *buf, size_t len, int flags);
+
+/**
+ * recvfrom(2) with support for MSG_DONTWAIT
+ */
+#define recvfrom windows_recvfrom
+ssize_t windows_recvfrom(int sockfd, void *buf, size_t len, int flags,
+						 struct sockaddr *src_addr, socklen_t *addrlen);
+
+/**
+ * recvfrom(2) with support for MSG_DONTWAIT
+ */
+#define send windows_send
+ssize_t windows_send(int sockfd, const void *buf, size_t len, int flags);
+
+/**
+ * recvfrom(2) with support for MSG_DONTWAIT
+ */
+#define sendto windows_send
+ssize_t windows_sendto(int sockfd, const void *buf, size_t len, int flags,
+					   const struct sockaddr *dest_addr, socklen_t addrlen);
+
+/**
+ * read(2) working on files and sockets, cancellable on sockets only
+ *
+ * On Windows, there does not seem to be a way how a cancellable read can
+ * be implemented on Low level I/O functions for files, _pipe()s or stdio.
+ */
+#define read windows_read
+ssize_t windows_read(int fd, void *buf, size_t count);
+
+/**
+ * write(2) working on files and sockets
+ */
+#define write windows_write
+ssize_t windows_write(int fd, void *buf, size_t count);
+
+#if _WIN32_WINNT < 0x0600
+/**
+ * Define pollfd and flags on our own if not specified
+ */
+struct pollfd {
+	SOCKET fd;
+	short events;
+	short revents;
+};
+enum {
+	POLLERR =		0x0001,
+	POLLHUP =		0x0002,
+	POLLNVAL =		0x0004,
+	POLLWRNORM =	0x0010,
+	POLLWRBAND =	0x0020,
+	POLLPRI =		0x0400,
+	POLLRDNORM =	0x0100,
+	POLLRDBAND =	0x0200,
+	POLLIN =		POLLRDNORM | POLLRDBAND,
+	POLLOUT =		POLLWRNORM,
+};
+#endif /* _WIN32_WINNT < 0x0600 */
+
+/**
+ * poll(2), implemented using Winsock2 WSAPoll()
+ */
+int poll(struct pollfd *fds, int nfds, int timeout);
+
+/**
+ * Declaration missing on older WinGW
+ */
+_CRTIMP errno_t strerror_s(char *buf, size_t size, int errnum);
+
+/**
+ * strerror_s, but supporting POSIX compatibility errno >= 100
+ */
+#define strerror_s strerror_s_extended
+int strerror_s_extended(char *buf, size_t buflen, int errnum);
+
+/**
+ * strerror_r(2) replacement, XSI variant
+ */
+static inline int strerror_r(int errnum, char *buf, size_t buflen)
+{
+	return strerror_s(buf, buflen, errnum);
+}
+#define HAVE_STRERROR_R /* but not STRERROR_R_CHAR_P */
+
+/**
+ * MinGW does provide extended errno values. Windows itself knowns them
+ * for POSIX compatibility; we define them as well.
+ */
+#ifndef EADDRINUSE
+#define EADDRINUSE			100
+#endif
+#ifndef EADDRNOTAVAIL
+#define EADDRNOTAVAIL		101
+#endif
+#ifndef EAFNOSUPPORT
+#define EAFNOSUPPORT		102
+#endif
+#ifndef EALREADY
+#define EALREADY			103
+#endif
+#ifndef EBADMSG
+#define EBADMSG				104
+#endif
+#ifndef ECANCELED
+#define ECANCELED			105
+#endif
+#ifndef ECONNABORTED
+#define ECONNABORTED		106
+#endif
+#ifndef ECONNREFUSED
+#define ECONNREFUSED		107
+#endif
+#ifndef ECONNRESET
+#define ECONNRESET			108
+#endif
+#ifndef EDESTADDRREQ
+#define EDESTADDRREQ		109
+#endif
+#ifndef EHOSTUNREACH
+#define EHOSTUNREACH		110
+#endif
+#ifndef EIDRM
+#define EIDRM				111
+#endif
+#ifndef EINPROGRESS
+#define EINPROGRESS			112
+#endif
+#ifndef EISCONN
+#define EISCONN				113
+#endif
+#ifndef ELOOP
+#define ELOOP				114
+#endif
+#ifndef EMSGSIZE
+#define EMSGSIZE			115
+#endif
+#ifndef ENETDOWN
+#define ENETDOWN			116
+#endif
+#ifndef ENETRESET
+#define ENETRESET			117
+#endif
+#ifndef ENETUNREACH
+#define ENETUNREACH			118
+#endif
+#ifndef ENOBUFS
+#define ENOBUFS				119
+#endif
+#ifndef ENODATA
+#define ENODATA				120
+#endif
+#ifndef ENOLINK
+#define ENOLINK				121
+#endif
+#ifndef ENOMSG
+#define ENOMSG				122
+#endif
+#ifndef ENOPROTOOPT
+#define ENOPROTOOPT			123
+#endif
+#ifndef ENOSR
+#define ENOSR				124
+#endif
+#ifndef ENOSTR
+#define ENOSTR				125
+#endif
+#ifndef ENOTCONN
+#define ENOTCONN			126
+#endif
+#ifndef ENOTRECOVERABLE
+#define ENOTRECOVERABLE		127
+#endif
+#ifndef ENOTSOCK
+#define ENOTSOCK			128
+#endif
+#ifndef ENOTSUP
+#define ENOTSUP				129
+#endif
+#ifndef EOPNOTSUPP
+#define EOPNOTSUPP			130
+#endif
+#ifndef EOTHER
+#define EOTHER				131
+#endif
+#ifndef EOVERFLOW
+#define EOVERFLOW			132
+#endif
+#ifndef EOWNERDEAD
+#define EOWNERDEAD			133
+#endif
+#ifndef EPROTO
+#define EPROTO				134
+#endif
+#ifndef EPROTONOSUPPORT
+#define EPROTONOSUPPORT		135
+#endif
+#ifndef EPROTOTYPE
+#define EPROTOTYPE			136
+#endif
+#ifndef ETIME
+#define ETIME				137
+#endif
+#ifndef ETIMEDOUT
+#define ETIMEDOUT			138
+#endif
+#ifndef ETXTBSY
+#define ETXTBSY				139
+#endif
+#ifndef EWOULDBLOCK
+#define EWOULDBLOCK			140
+#endif
+
+
+/* Windows does not support "ll" format printf length modifiers. Mingw
+ * therefore maps these to the Windows specific I64 length modifier. That
+ * won't work for us, as we use our own printf backend on Windows, which works
+ * just fine with "ll". */
+#undef PRId64
+#define PRId64 "lld"
+#undef PRId64
+#define PRId64 "lld"
+#undef PRIdLEAST64
+#define PRIdLEAST64 "lld"
+#undef PRIdFAST64
+#define PRIdFAST64 "lld"
+#undef PRIdMAX
+#define PRIdMAX "lld"
+#undef PRIi64
+#define PRIi64 "lli"
+#undef PRIiLEAST64
+#define PRIiLEAST64 "lli"
+#undef PRIiFAST64
+#define PRIiFAST64 "lli"
+#undef PRIiMAX
+#define PRIiMAX "lli"
+#undef PRIo64
+#define PRIo64 "llo"
+#undef PRIoLEAST64
+#define PRIoLEAST64 "llo"
+#undef PRIoFAST64
+#define PRIoFAST64 "llo"
+#undef PRIoMAX
+#define PRIoMAX "llo"
+#undef PRIu64
+#define PRIu64 "llu"
+#undef PRIuLEAST64
+#define PRIuLEAST64 "llu"
+#undef PRIuFAST64
+#define PRIuFAST64 "llu"
+#undef PRIuMAX
+#define PRIuMAX "llu"
+#undef PRIx64
+#define PRIx64 "llx"
+#undef PRIxLEAST64
+#define PRIxLEAST64 "llx"
+#undef PRIxFAST64
+#define PRIxFAST64 "llx"
+#undef PRIxMAX
+#define PRIxMAX "llx"
+#undef PRIX64
+#define PRIX64 "llX"
+#undef PRIXLEAST64
+#define PRIXLEAST64 "llX"
+#undef PRIXFAST64
+#define PRIXFAST64 "llX"
+#undef PRIXMAX
+#define PRIXMAX "llX"
+
+#ifdef _WIN64
+# undef PRIdPTR
+# define PRIdPTR "lld"
+# undef PRIiPTR
+# define PRIiPTR "lli"
+# undef PRIoPTR
+# define PRIoPTR "llo"
+# undef PRIuPTR
+# define PRIuPTR "llu"
+# undef PRIxPTR
+# define PRIxPTR "llx"
+# undef PRIXPTR
+# define PRIXPTR "llX"
+#endif /* _WIN64 */
+
+#endif /** WINDOWS_H_ @}*/
diff --git a/src/libstrongswan/utils/enum.c b/src/libstrongswan/utils/enum.c
index f96fe29..089bebb 100644
--- a/src/libstrongswan/utils/enum.c
+++ b/src/libstrongswan/utils/enum.c
@@ -60,20 +60,103 @@ bool enum_from_name_as_int(enum_name_t *e, const char *name, int *val)
 }
 
 /**
+ * Get the position of a flag name using offset calculation
+ */
+static int find_flag_pos(u_int val, u_int first)
+{
+	int offset = 0;
+
+	while (val != 0x01)
+	{
+		val = val >> 1;
+		offset++;
+	}
+	return first - offset;
+}
+
+/**
  * Described in header.
  */
+char *enum_flags_to_string(enum_name_t *e, u_int val, char *buf, size_t len)
+{
+	char *pos = buf, *delim = "";
+	int i, wr;
+
+	if (e->next != ENUM_FLAG_MAGIC)
+	{
+		if (snprintf(buf, len, "(%d)", (int)val) >= len)
+		{
+			return NULL;
+		}
+		return buf;
+	}
+
+	if (snprintf(buf, len, "(unset)") >= len)
+	{
+		return NULL;
+	}
+
+	for (i = 0; val; i++)
+	{
+		u_int flag = 1 << i;
+
+		if (val & flag)
+		{
+			char *name = NULL, hex[32];
+
+			if (flag >= (u_int)e->first && flag <= (u_int)e->last)
+			{
+				name = e->names[find_flag_pos(e->first, i)];
+			}
+			else
+			{
+				snprintf(hex, sizeof(hex), "(0x%X)", flag);
+				name = hex;
+			}
+			if (name)
+			{
+				wr = snprintf(pos, len, "%s%s", delim, name);
+				if (wr >= len)
+				{
+					return NULL;
+				}
+				len -= wr;
+				pos += wr;
+				delim = " | ";
+			}
+			val &= ~flag;
+		}
+	}
+	return buf;
+}
+
+/**
+ * See header.
+ */
 int enum_printf_hook(printf_hook_data_t *data, printf_hook_spec_t *spec,
 					 const void *const *args)
 {
 	enum_name_t *ed = *((enum_name_t**)(args[0]));
 	int val = *((int*)(args[1]));
-	char *name, buf[32];
+	char *name, buf[512];
 
-	name = enum_to_name(ed, val);
-	if (name == NULL)
+	if (ed->next == ENUM_FLAG_MAGIC)
+	{
+		name = enum_flags_to_string(ed, val, buf, sizeof(buf));
+		if (name == NULL)
+		{
+			snprintf(buf, sizeof(buf), "(0x%X)", val);
+			name = buf;
+		}
+	}
+	else
 	{
-		snprintf(buf, sizeof(buf), "(%d)", val);
-		name = buf;
+		name = enum_to_name(ed, val);
+		if (name == NULL)
+		{
+			snprintf(buf, sizeof(buf), "(%d)", val);
+			name = buf;
+		}
 	}
 	if (spec->minus)
 	{
diff --git a/src/libstrongswan/utils/enum.h b/src/libstrongswan/utils/enum.h
index 3c03c2a..928f407 100644
--- a/src/libstrongswan/utils/enum.h
+++ b/src/libstrongswan/utils/enum.h
@@ -27,6 +27,11 @@
 typedef struct enum_name_t enum_name_t;
 
 /**
+ * Magic enum_name_t pointer indicating this is an enum name for flags
+ */
+#define ENUM_FLAG_MAGIC ((enum_name_t*)~(uintptr_t)0)
+
+/**
  * Struct to store names for enums.
  *
  * To print the string representation of enumeration values, the strings
@@ -58,7 +63,7 @@ struct enum_name_t {
 	int first;
 	/** value of the last enum string */
 	int last;
-	/** next enum_name_t in list */
+	/** next enum_name_t in list, or ENUM_FLAG_MAGIC */
 	enum_name_t *next;
 	/** array of strings containing names from first to last */
 	char *names[];
@@ -107,6 +112,23 @@ struct enum_name_t {
 #define ENUM(name, first, last, ...) ENUM_BEGIN(name, first, last, __VA_ARGS__); ENUM_END(name, last)
 
 /**
+ * Define a enum name with only one range for flags.
+ *
+ * Using an enum list for flags would be overkill. Hence we use a single
+ * range with all values in range. The next pointer is abused to mark
+ * that the enum name is for flags only. Use NULL if a particular flag
+ * is not meant to be printed.
+ *
+ * @param name	name of the enum_name list
+ * @param first	enum value of the first enum string
+ * @param last	enum value of the last enum string
+ * @param ...	a list of strings
+ */
+#define ENUM_FLAGS(name, first, last, ...) \
+	static enum_name_t name##last = {first, last, ENUM_FLAG_MAGIC, { __VA_ARGS__ }}; \
+	ENUM_END(name, last)
+
+/**
  * Convert a enum value to its string representation.
  *
  * @param e		enum names for this enum value
@@ -146,6 +168,17 @@ char *enum_to_name(enum_name_t *e, int val);
 bool enum_from_name_as_int(enum_name_t *e, const char *name, int *val);
 
 /**
+ * Convert a enum value containing flags to its string representation.
+ *
+ * @param e		enum names for this enum value suitable for flags
+ * @param val	enum value to get string for
+ * @param buf	buffer to write flag string to
+ * @param len	buffer size
+ * @return		buf, NULL if buffer too small
+ */
+char *enum_flags_to_string(enum_name_t *e, u_int val, char *buf, size_t len);
+
+/**
  * printf hook function for enum_names_t.
  *
  * Arguments are:
diff --git a/src/libstrongswan/utils/identification.c b/src/libstrongswan/utils/identification.c
index 46ac7e8..b69adf3 100644
--- a/src/libstrongswan/utils/identification.c
+++ b/src/libstrongswan/utils/identification.c
@@ -17,6 +17,7 @@
 
 #include <string.h>
 #include <stdio.h>
+#include <errno.h>
 
 #include "identification.h"
 
@@ -927,6 +928,82 @@ static private_identification_t *identification_create(id_type_t type)
 	return this;
 }
 
+/**
+ * Create an identity for a specific type, determined by prefix
+ */
+static private_identification_t* create_from_string_with_prefix_type(char *str)
+{
+	struct {
+		const char *str;
+		id_type_t type;
+	} prefixes[] = {
+		{ "ipv4:",			ID_IPV4_ADDR			},
+		{ "ipv6:",			ID_IPV6_ADDR			},
+		{ "rfc822:",		ID_RFC822_ADDR			},
+		{ "email:",			ID_RFC822_ADDR			},
+		{ "userfqdn:",		ID_USER_FQDN			},
+		{ "fqdn:",			ID_FQDN					},
+		{ "dns:",			ID_FQDN					},
+		{ "asn1dn:",		ID_DER_ASN1_DN			},
+		{ "asn1gn:",		ID_DER_ASN1_GN			},
+		{ "keyid:",			ID_KEY_ID				},
+	};
+	private_identification_t *this;
+	int i;
+
+	for (i = 0; i < countof(prefixes); i++)
+	{
+		if (strcasepfx(str, prefixes[i].str))
+		{
+			this = identification_create(prefixes[i].type);
+			str += strlen(prefixes[i].str);
+			if (*str == '#')
+			{
+				this->encoded = chunk_from_hex(chunk_from_str(str + 1), NULL);
+			}
+			else
+			{
+				this->encoded = chunk_clone(chunk_from_str(str));
+			}
+			return this;
+		}
+	}
+	return NULL;
+}
+
+/**
+ * Create an identity for a specific type, determined by a numerical prefix
+ *
+ * The prefix is of the form "{x}:", where x denotes the numerical identity
+ * type.
+ */
+static private_identification_t* create_from_string_with_num_type(char *str)
+{
+	private_identification_t *this;
+	u_long type;
+
+	if (*str++ != '{')
+	{
+		return NULL;
+	}
+	errno = 0;
+	type = strtoul(str, &str, 0);
+	if (errno || *str++ != '}' || *str++ != ':')
+	{
+		return NULL;
+	}
+	this = identification_create(type);
+	if (*str == '#')
+	{
+		this->encoded = chunk_from_hex(chunk_from_str(str + 1), NULL);
+	}
+	else
+	{
+		this->encoded = chunk_clone(chunk_from_str(str));
+	}
+	return this;
+}
+
 /*
  * Described in header.
  */
@@ -939,6 +1016,16 @@ identification_t *identification_create_from_string(char *string)
 	{
 		string = "%any";
 	}
+	this = create_from_string_with_prefix_type(string);
+	if (this)
+	{
+		return &this->public;
+	}
+	this = create_from_string_with_num_type(string);
+	if (this)
+	{
+		return &this->public;
+	}
 	if (strchr(string, '=') != NULL)
 	{
 		/* we interpret this as an ASCII X.501 ID_DER_ASN1_DN.
diff --git a/src/libstrongswan/utils/identification.h b/src/libstrongswan/utils/identification.h
index e624468..e6a9fe1 100644
--- a/src/libstrongswan/utils/identification.h
+++ b/src/libstrongswan/utils/identification.h
@@ -302,6 +302,15 @@ struct identification_t {
  * N, G, I, dnQualifier, ID, EN, EmployeeNumber, E, Email, emailAddress, UN,
  * unstructuredName, TCGID.
  *
+ * To skip automatic type detection the following prefixes may be used to
+ * enforce a specific type: ipv4:, ipv6:, rfc822:, email:, userfqdn:, fqdn:,
+ * dns:, asn1dn:, asn1gn: and keyid:. If a # follows the :, the remaining data
+ * is interpreted as hex encoded binary data for that ID, otherwise the raw
+ * string following the prefix is used as identity data, without conversion.
+ * To specify a non-standard ID type, the numerical type may be prefixed
+ * between curly backets, building a prefix. For instance the "{1}:" prefix
+ * defines an ID_IPV4_ADDR type.
+ *
  * This constructor never returns NULL. If it does not find a suitable
  * conversion function, it will copy the string to an ID_KEY_ID.
  *
diff --git a/src/libstrongswan/utils/utils.h b/src/libstrongswan/utils/utils.h
index da253cc..7c48d94 100644
--- a/src/libstrongswan/utils/utils.h
+++ b/src/libstrongswan/utils/utils.h
@@ -29,7 +29,7 @@
 #include <string.h>
 
 #ifdef WIN32
-# include "windows.h"
+# include "compat/windows.h"
 #else
 # define _GNU_SOURCE
 # include <arpa/inet.h>
@@ -37,6 +37,7 @@
 # include <netdb.h>
 # include <netinet/in.h>
 # include <sched.h>
+# include <poll.h>
 #endif
 
 /**
@@ -96,6 +97,9 @@
 
 #include "enum.h"
 #include "utils/strerror.h"
+#ifdef __APPLE__
+# include "compat/apple.h"
+#endif
 
 /**
  * Directory separator character in paths on this platform
diff --git a/src/libstrongswan/utils/windows.c b/src/libstrongswan/utils/windows.c
deleted file mode 100644
index 8820287..0000000
--- a/src/libstrongswan/utils/windows.c
+++ /dev/null
@@ -1,641 +0,0 @@
-/*
- * Copyright (C) 2013 Martin Willi
- * Copyright (C) 2013 revosec AG
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * for more details.
- */
-
-#include "utils.h"
-
-#include <errno.h>
-
-/**
- * See header
- */
-void windows_init()
-{
-	WSADATA wsad;
-
-	/* initialize winsock2 */
-	WSAStartup(MAKEWORD(2, 2), &wsad);
-}
-
-/**
- * See header
- */
-void windows_deinit()
-{
-	WSACleanup();
-}
-
-/**
- * See header
- */
-int usleep(useconds_t usec)
-{
-	if (usec > 0 && usec < 1000)
-	{	/* do not Sleep(0) for small values */
-		usec = 1000;
-	}
-	SleepEx(usec / 1000, TRUE);
-	return 0;
-}
-
-/**
- * See header.
- */
-char* strndup(const char *s, size_t n)
-{
-	char *dst;
-
-	n = min(strnlen(s, n), n);
-	dst = malloc(n + 1);
-	memcpy(dst, s, n);
-	dst[n] = '\0';
-
-	return dst;
-}
-
-/*
- * See header.
- */
-void *dlopen(const char *filename, int flag)
-{
-	return LoadLibrary(filename);
-}
-
-/**
- * Load a symbol from known default libs (monolithic build)
- */
-static void* dlsym_default(const char *name)
-{
-	const char *dlls[] = {
-		"libstrongswan-0.dll",
-		"libhydra-0.dll",
-		"libcharon-0.dll",
-		"libtnccs-0.dll",
-		NULL /* .exe */
-	};
-	HANDLE handle;
-	void *sym = NULL;
-	int i;
-
-	for (i = 0; i < countof(dlls); i++)
-	{
-		handle = GetModuleHandle(dlls[i]);
-		if (handle)
-		{
-			sym = GetProcAddress(handle, name);
-			if (sym)
-			{
-				break;
-			}
-		}
-	}
-	return sym;
-}
-
-/**
- * Emulate RTLD_NEXT for some known symbols
- */
-static void* dlsym_next(const char *name)
-{
-	struct {
-		const char *dll;
-		const char *syms[4];
-	} dlls[] = {
-		/* for leak detective */
-		{ "msvcrt",
-			{ "malloc", "calloc", "realloc", "free" }
-		},
-	};
-	HANDLE handle = NULL;
-	int i, j;
-
-	for (i = 0; i < countof(dlls); i++)
-	{
-		for (j = 0; j < countof(dlls[0].syms); j++)
-		{
-			if (dlls[i].syms[j] && streq(dlls[i].syms[j], name))
-			{
-				handle = GetModuleHandle(dlls[i].dll);
-				break;
-			}
-		}
-	}
-	if (handle)
-	{
-		return GetProcAddress(handle, name);
-	}
-	return handle;
-}
-
-/**
- * See header.
- */
-void* dlsym(void *handle, const char *symbol)
-{
-	if (handle == RTLD_DEFAULT)
-	{
-		return dlsym_default(symbol);
-	}
-	if (handle == RTLD_NEXT)
-	{
-		return dlsym_next(symbol);
-	}
-	return GetProcAddress((HMODULE)handle, symbol);
-}
-
-/**
- * See header.
- */
-char* dlerror(void)
-{
-	static char buf[128];
-	char *pos;
-	DWORD err;
-
-	err = GetLastError();
-	if (FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
-					  NULL, err, 0, buf, sizeof(buf), NULL) > 0)
-	{
-		pos = strchr(buf, '\n');
-		if (pos)
-		{
-			*pos = '\0';
-		}
-	}
-	else
-	{
-		snprintf(buf, sizeof(buf), "(%u)", err);
-	}
-	return buf;
-}
-
-/**
- * See header.
- */
-int dlclose(void *handle)
-{
-	return FreeLibrary((HMODULE)handle);
-}
-
-/**
- * See header
- */
-int socketpair(int domain, int type, int protocol, int sv[2])
-{
-	struct sockaddr_in addr = {
-		.sin_family = AF_INET,
-		.sin_addr.s_addr = htonl(INADDR_LOOPBACK),
-	};
-	socklen_t len = sizeof(addr);
-	int s, c, sc;
-	BOOL on;
-
-	/* We don't check domain for AF_INET, as we use it as replacement for
-	 * AF_UNIX. */
-	if (type != SOCK_STREAM)
-	{
-		errno = EINVAL;
-		return -1;
-	}
-	if (protocol != 0 && protocol != IPPROTO_TCP)
-	{
-		errno = EINVAL;
-		return -1;
-	}
-	s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
-	if (s == -1)
-	{
-		return -1;
-	}
-	c = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
-	if (c == -1)
-	{
-		closesocket(s);
-		return -1;
-	}
-	if (bind(s, (struct sockaddr*)&addr, sizeof(addr)) == 0 &&
-		getsockname(s,(struct sockaddr*)&addr, &len) == 0 &&
-		listen(s, 0) == 0 &&
-		connect(c, (struct sockaddr*)&addr, sizeof(addr)) == 0)
-	{
-		sc = accept(s, NULL, NULL);
-		if (sc >= 0)
-		{
-			closesocket(s);
-			s = sc;
-			if (setsockopt(s, IPPROTO_TCP, TCP_NODELAY,
-						   (void*)&on, sizeof(on)) == 0 &&
-				setsockopt(c, IPPROTO_TCP, TCP_NODELAY,
-						   (void*)&on, sizeof(on)) == 0)
-			{
-				sv[0] = s;
-				sv[1] = c;
-				return 0;
-			}
-		}
-	}
-	closesocket(s);
-	closesocket(c);
-	return -1;
-}
-
-/**
- * See header
- */
-char* getpass(const char *prompt)
-{
-	static char buf[64] = "";
-	char *pos;
-	HANDLE in, out;
-	DWORD mode, written = 0, total, done;
-
-	out = GetStdHandle(STD_OUTPUT_HANDLE);
-	in = GetStdHandle(STD_INPUT_HANDLE);
-
-	if (out == INVALID_HANDLE_VALUE || in == INVALID_HANDLE_VALUE ||
-		!GetConsoleMode(out, &mode) || !GetConsoleMode(in, &mode))
-	{
-		return NULL;
-	}
-
-	total = strlen(prompt);
-	while (written < total)
-	{
-		if (!WriteConsole(out, prompt + written, total - written, &done, NULL))
-		{
-			return NULL;
-		}
-		written += done;
-	}
-
-	if (!SetConsoleMode(in, mode & ~ENABLE_ECHO_INPUT))
-	{
-		return NULL;
-	}
-
-	while (TRUE)
-	{
-		if (!ReadConsole(in, buf, sizeof(buf), &done, NULL))
-		{
-			SetConsoleMode(in, mode);
-			return NULL;
-		}
-		buf[sizeof(buf)-1] = '\0';
-
-		if (done)
-		{
-			pos = strchr(buf, '\r');
-			if (pos)
-			{
-				*pos = '\0';
-			}
-			break;
-		}
-	}
-	SetConsoleMode(in, mode);
-
-	/* append a newline, as we have no echo during input */
-	WriteConsole(out, "\r\n", 2, &done, NULL);
-
-	return buf;
-}
-
-/**
- * See header.
- */
-#undef strerror_s
-int strerror_s_extended(char *buf, size_t buflen, int errnum)
-{
-	const char *errstr [] = {
-		/* EADDRINUSE */		"Address in use",
-		/* EADDRNOTAVAIL */		"Address not available",
-		/* EAFNOSUPPORT */		"Address family not supported",
-		/* EALREADY */			"Connection already in progress",
-		/* EBADMSG */			"Bad message",
-		/* ECANCELED */			"Operation canceled",
-		/* ECONNABORTED */		"Connection aborted",
-		/* ECONNREFUSED */		"Connection refused",
-		/* ECONNRESET */		"Connection reset",
-		/* EDESTADDRREQ */		"Destination address required",
-		/* EHOSTUNREACH */		"Host is unreachable",
-		/* EIDRM */				"Identifier removed",
-		/* EINPROGRESS */		"Operation in progress",
-		/* EISCONN */			"Socket is connected",
-		/* ELOOP */				"Too many levels of symbolic links",
-		/* EMSGSIZE */			"Message too large",
-		/* ENETDOWN */			"Network is down",
-		/* ENETRESET */			"Connection aborted by network",
-		/* ENETUNREACH */		"Network unreachable",
-		/* ENOBUFS */			"No buffer space available",
-		/* ENODATA */			"No message is available",
-		/* ENOLINK */			"No link",
-		/* ENOMSG */			"No message of the desired type",
-		/* ENOPROTOOPT */		"Protocol not available",
-		/* ENOSR */				"No stream resources",
-		/* ENOSTR */			"Not a stream",
-		/* ENOTCONN */			"The socket is not connected",
-		/* ENOTRECOVERABLE */	"State not recoverable",
-		/* ENOTSOCK */			"Not a socket",
-		/* ENOTSUP */			"Not supported",
-		/* EOPNOTSUPP */		"Operation not supported on socket",
-		/* EOTHER */			"Other error",
-		/* EOVERFLOW */			"Value too large to be stored in data type",
-		/* EOWNERDEAD */		"Previous owner died",
-		/* EPROTO */			"Protocol error",
-		/* EPROTONOSUPPORT */	"Protocol not supported",
-		/* EPROTOTYPE */		"Protocol wrong type for socket",
-		/* ETIME */				"Timeout",
-		/* ETIMEDOUT */			"Connection timed out",
-		/* ETXTBSY */			"Text file busy",
-		/* EWOULDBLOCK */		"Operation would block",
-	};
-	int offset = EADDRINUSE;
-
-	if (errnum < offset || errnum >= offset + countof(errstr))
-	{
-		return strerror_s(buf, buflen, errnum);
-	}
-	strncpy(buf, errstr[errnum - offset], buflen);
-	buf[buflen - 1] = '\0';
-	return 0;
-}
-
-/**
- * Set errno for a function setting WSA error on failure
- */
-static int wserr(int retval)
-{
-	if (retval < 0)
-	{
-		static const struct {
-			DWORD wsa;
-			int err;
-		} map[] = {
-			{ WSANOTINITIALISED,			EBADF						},
-			{ WSAENETDOWN,					ENETDOWN					},
-			{ WSAENETRESET,					ENETRESET					},
-			{ WSAECONNABORTED,				ECONNABORTED				},
-			{ WSAESHUTDOWN,					ECONNABORTED				},
-			{ WSAEACCES,					EACCES						},
-			{ WSAEINTR,						EINTR						},
-			{ WSAEINPROGRESS,				EINPROGRESS					},
-			{ WSAEFAULT,					EFAULT						},
-			{ WSAENOBUFS,					ENOBUFS						},
-			{ WSAENOTSOCK,					ENOTSOCK					},
-			{ WSAEOPNOTSUPP,				EOPNOTSUPP					},
-			{ WSAEWOULDBLOCK,				EWOULDBLOCK					},
-			{ WSAEMSGSIZE,					EMSGSIZE					},
-			{ WSAEINVAL,					EINVAL						},
-			{ WSAENOTCONN,					ENOTCONN					},
-			{ WSAEHOSTUNREACH,				EHOSTUNREACH				},
-			{ WSAENETUNREACH,				ENETUNREACH					},
-			{ WSAECONNABORTED,				ECONNABORTED				},
-			{ WSAECONNRESET,				ECONNRESET					},
-			{ WSAETIMEDOUT,					ETIMEDOUT					},
-			{ WSAEMFILE,					EMFILE						},
-			{ WSAEALREADY,					EALREADY					},
-			{ WSAEDESTADDRREQ,				EDESTADDRREQ				},
-			{ WSAEISCONN,					EISCONN						},
-			{ WSAEOPNOTSUPP,				EOPNOTSUPP					},
-			{ WSAEPROTOTYPE,				EPROTOTYPE					},
-			{ WSAENOPROTOOPT,				ENOPROTOOPT					},
-			{ WSAEPROTONOSUPPORT,			EPROTONOSUPPORT				},
-			{ WSAEPFNOSUPPORT,				EPROTONOSUPPORT				},
-			{ WSAEAFNOSUPPORT,				EAFNOSUPPORT				},
-			{ WSAEADDRNOTAVAIL,				EADDRNOTAVAIL				},
-			{ WSAEADDRINUSE,				EADDRINUSE					},
-			{ WSAETIMEDOUT,					ETIMEDOUT					},
-			{ WSAECONNREFUSED,				ECONNREFUSED				},
-			{ WSAELOOP,						ELOOP						},
-			{ WSAENAMETOOLONG,				ENAMETOOLONG				},
-			{ WSAENOTEMPTY,					ENOTEMPTY					},
-			{ WSAEPROTOTYPE,				EPROTOTYPE					},
-			{ WSAVERNOTSUPPORTED,			ENOTSUP						},
-		};
-		DWORD wsa, i;
-
-		wsa = WSAGetLastError();
-		for (i = 0; i < countof(map); i++)
-		{
-			if (map[i].wsa == wsa)
-			{
-				errno = map[i].err;
-				return retval;
-			}
-		}
-		errno = ENOENT;
-		return retval;
-	}
-	errno = 0;
-	return retval;
-}
-
-/**
- * Check and clear the dontwait flag
- */
-static bool check_dontwait(int *flags)
-{
-	if (*flags & MSG_DONTWAIT)
-	{
-		*flags &= ~MSG_DONTWAIT;
-		return TRUE;
-	}
-	return FALSE;
-}
-
-/**
- * See header
- */
-#undef shutdown
-int windows_shutdown(int sockfd, int how)
-{
-	return wserr(shutdown(sockfd, how));
-}
-
-/**
- * See header
- */
-#undef accept
-int windows_accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen)
-{
-	return wserr(accept(sockfd, addr, addrlen));
-}
-
-/**
- * See header
- */
-#undef bind
-int windows_bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen)
-{
-	return wserr(bind(sockfd, addr, addrlen));
-}
-
-/**
- * See header
- */
-#undef connect
-int windows_connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen)
-{
-	return wserr(connect(sockfd, addr, addrlen));
-}
-
-/**
- * See header
- */
-#undef getsockname
-int windows_getsockname(int sockfd, struct sockaddr *addr, socklen_t *addrlen)
-{
-	return wserr(getsockname(sockfd, addr, addrlen));
-}
-
-/**
- * See header
- */
-#undef getsockopt
-int windows_getsockopt(int sockfd, int level, int optname,
-					   void *optval, socklen_t *optlen)
-{
-	return wserr(getsockopt(sockfd, level, optname, optval, optlen));
-}
-
-/**
- * See header
- */
-#undef setsockopt
-int windows_setsockopt(int sockfd, int level, int optname,
-					   const void *optval, socklen_t optlen)
-{
-	return wserr(setsockopt(sockfd, level, optname, optval, optlen));
-}
-
-/**
- * See header
- */
-#undef socket
-int windows_socket(int domain, int type, int protocol)
-{
-	return wserr(socket(domain, type, protocol));
-}
-
-/**
- * See header
- */
-#undef select
-int windows_select(int nfds, fd_set *readfds, fd_set *writefds,
-				   fd_set *exceptfds, struct timeval *timeout)
-{
-	return wserr(select(nfds, readfds, writefds, exceptfds, timeout));
-}
-
-/**
- * See header
- */
-#undef close
-int windows_close(int fd)
-{
-	int ret;
-
-	ret = close(fd);
-	if (ret == -1 && errno == EBADF)
-	{	/* Winsock socket? */
-		ret = wserr(closesocket(fd));
-	}
-	return ret;
-}
-
-/**
- * See header
- */
-#undef recv
-ssize_t windows_recv(int sockfd, void *buf, size_t len, int flags)
-{
-	u_long on = 1, off = 0;
-	ssize_t outlen = -1;
-
-	if (!check_dontwait(&flags))
-	{
-		return wserr(recv(sockfd, buf, len, flags));
-	}
-	if (wserr(ioctlsocket(sockfd, FIONBIO, &on) == 0))
-	{
-		outlen = wserr(recv(sockfd, buf, len, flags));
-		ioctlsocket(sockfd, FIONBIO, &off);
-	}
-	return outlen;
-}
-
-/**
- * See header
- */
-#undef recvfrom
-ssize_t windows_recvfrom(int sockfd, void *buf, size_t len, int flags,
-						 struct sockaddr *src_addr, socklen_t *addrlen)
-{
-	u_long on = 1, off = 0;
-	ssize_t outlen = -1;
-
-	if (!check_dontwait(&flags))
-	{
-		return wserr(recvfrom(sockfd, buf, len, flags, src_addr, addrlen));
-	}
-	if (wserr(ioctlsocket(sockfd, FIONBIO, &on)) == 0)
-	{
-		outlen = wserr(recvfrom(sockfd, buf, len, flags, src_addr, addrlen));
-		ioctlsocket(sockfd, FIONBIO, &off);
-	}
-	return outlen;
-}
-
-/**
- * See header
- */
-#undef send
-ssize_t windows_send(int sockfd, const void *buf, size_t len, int flags)
-{
-	u_long on = 1, off = 0;
-	ssize_t outlen = -1;
-
-	if (!check_dontwait(&flags))
-	{
-		return wserr(send(sockfd, buf, len, flags));
-	}
-	if (wserr(ioctlsocket(sockfd, FIONBIO, &on)) == 0)
-	{
-		outlen = wserr(send(sockfd, buf, len, flags));
-		ioctlsocket(sockfd, FIONBIO, &off);
-	}
-	return outlen;
-}
-
-/**
- * See header
- */
-#undef sendto
-ssize_t windows_sendto(int sockfd, const void *buf, size_t len, int flags,
-					   const struct sockaddr *dest_addr, socklen_t addrlen)
-{
-	u_long on = 1, off = 0;
-	ssize_t outlen = -1;
-
-	if (!check_dontwait(&flags))
-	{
-		return wserr(sendto(sockfd, buf, len, flags, dest_addr, addrlen));
-	}
-	if (wserr(ioctlsocket(sockfd, FIONBIO, &on)) == 0)
-	{
-		outlen = wserr(sendto(sockfd, buf, len, flags, dest_addr, addrlen));
-		ioctlsocket(sockfd, FIONBIO, &off);
-	}
-	return outlen;
-}
diff --git a/src/libstrongswan/utils/windows.h b/src/libstrongswan/utils/windows.h
deleted file mode 100644
index 3761e10..0000000
--- a/src/libstrongswan/utils/windows.h
+++ /dev/null
@@ -1,584 +0,0 @@
-/*
- * Copyright (C) 2013 Martin Willi
- * Copyright (C) 2013 revosec AG
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * for more details.
- */
-
-/**
- * @defgroup windows windows
- * @{ @ingroup utils
- */
-
-#ifndef WINDOWS_H_
-#define WINDOWS_H_
-
-#include <winsock2.h>
-#include <ws2tcpip.h>
-#include <direct.h>
-#include <inttypes.h>
-#include <unistd.h>
-#include <sys/stat.h>
-
-/* undef Windows variants evaluating values more than once */
-#undef min
-#undef max
-
-/* interface is defined as an alias to "struct" in basetypes.h, but
- * we use it here and there as ordinary identifier. */
-#undef interface
-
-/* used by Windows API, but we have our own */
-#undef CALLBACK
-
-/* UID/GID types for capabilities, even if not supported */
-typedef u_int uid_t;
-typedef u_int gid_t;
-
-/**
- * Initialize Windows libraries
- */
-void windows_init();
-
-/**
- * Deinitialize windows libraries
- */
-void windows_deinit();
-
-/**
- * Replacement for random(3)
- */
-static inline long random(void)
-{
-	return rand();
-}
-
-/**
- * Replacement for srandom(3)
- */
-static inline void srandom(unsigned int seed)
-{
-	srand(seed);
-}
-
-/**
- * Replacement of sched_yield(2) from <sched.h>
- */
-static inline int sched_yield(void)
-{
-	Sleep(0);
-	return 0;
-}
-
-/**
- * Replacement of sleep(3), cancellable by thread_cancel()
- */
-#define sleep sleep_cancellable
-static inline int sleep_cancellable(unsigned int seconds)
-{
-	SleepEx(seconds * 1000, TRUE);
-	return 0;
-}
-
-/**
- * Replacement of usleep(3), cancellable, ms resolution only
- */
-int usleep(useconds_t usec);
-
-/**
- * strdup(3), the Windows variant can't free(strdup("")) and others
- */
-#define strdup strdup_windows
-static inline char* strdup_windows(const char *src)
-{
-	size_t len;
-	char *dst;
-
-	len = strlen(src) + 1;
-	dst = malloc(len);
-	memcpy(dst, src, len);
-	return dst;
-}
-
-/**
- * strndup(3)
- */
-char* strndup(const char *s, size_t n);
-
-/**
- * Provided via ws2_32
- */
-#ifndef InetNtop
-const char WINAPI *inet_ntop(int af, const void *src, char *dst, socklen_t size);
-#endif
-
-/**
- * Provided via ws2_32
- */
-#ifndef InetPton
-int WINAPI inet_pton(int af, const char *src, void *dst);
-#endif
-
-/**
- * Provided by printf hook backend
- */
-int asprintf(char **strp, const char *fmt, ...);
-
-/**
- * Provided by printf hook backend
- */
-int vasprintf(char **strp, const char *fmt, va_list ap);
-
-/**
- * timeradd(3) from <sys/time.h>
- */
-static inline void timeradd(struct timeval *a, struct timeval *b,
-							struct timeval *res)
-{
-	res->tv_sec = a->tv_sec + b->tv_sec;
-	res->tv_usec = a->tv_usec + b->tv_usec;
-	if (res->tv_usec >= 1000000)
-	{
-		res->tv_usec -= 1000000;
-		res->tv_sec++;
-	}
-}
-
-/**
- * timersub(3) from <sys/time.h>
- */
-static inline void timersub(struct timeval *a, struct timeval *b,
-							struct timeval *res)
-{
-	res->tv_sec = a->tv_sec - b->tv_sec;
-	res->tv_usec = a->tv_usec - b->tv_usec;
-	if (res->tv_usec < 0)
-	{
-		res->tv_usec += 1000000;
-		res->tv_sec--;
-	}
-}
-
-/**
- * gmtime_r(3) from <time.h>
- */
-static inline struct tm *gmtime_r(const time_t *timep, struct tm *result)
-{
-	struct tm *ret;
-
-	/* gmtime_s() and friends seem not to be implemented/functioning.
-	 * Relying on gmtime() on Windows works as well, as it uses thread
-	 * specific buffers. */
-	ret = gmtime(timep);
-	if (ret)
-	{
-		memcpy(result, ret, sizeof(*result));
-	}
-	return ret;
-}
-
-/**
- * localtime_r(3) from <time.h>
- */
-static inline struct tm *localtime_r(const time_t *timep, struct tm *result)
-{
-	struct tm *ret;
-
-	/* localtime_s() and friends seem not to be implemented/functioning.
-	 * Relying on localtime() on Windows works as well, as it uses thread
-	 * specific buffers. */
-	ret = localtime(timep);
-	if (ret)
-	{
-		memcpy(result, ret, sizeof(*result));
-	}
-	return ret;
-}
-
-/**
- * setenv(3) from <stdlib.h>, overwrite flag is ignored
- */
-static inline int setenv(const char *name, const char *value, int overwrite)
-{
-	if (SetEnvironmentVariableA(name, value) == 0)
-	{	/* failed */
-		return -1;
-	}
-	return 0;
-}
-
-/**
- * Lazy binding, ignored on Windows
- */
-#define RTLD_LAZY 1
-
-/**
- * Default handle targeting .exe
- */
-#define RTLD_DEFAULT (NULL)
-
-/**
- * Find symbol in next library
- */
-#define RTLD_NEXT ((void*)~(uintptr_t)0)
-
-/**
- * dlopen(3) from <dlfcn.h>
- */
-void* dlopen(const char *filename, int flag);
-
-/**
- * dlsym() from <dlfcn.h>
- */
-void* dlsym(void *handle, const char *symbol);
-
-/**
- * dlerror(3) from <dlfcn.h>, currently not thread save
- */
-char* dlerror(void);
-
-/**
- * dlclose() from <dlfcn.h>
- */
-int dlclose(void *handle);
-
-/**
- * socketpair(2) for SOCK_STREAM, uses TCP on loopback
- */
-int socketpair(int domain, int type, int protocol, int sv[2]);
-
-/**
- * getpass(3) on Windows consoles
- */
-char* getpass(const char *prompt);
-#define HAVE_GETPASS
-
-/**
- * Map MSG_DONTWAIT to the reserved, but deprecated MSG_INTERRUPT
- */
-#define MSG_DONTWAIT MSG_INTERRUPT
-
-/**
- * shutdown(2) "how"-aliases, to use Unix variant on Windows
- */
-#define SHUT_RD SD_RECEIVE
-#define SHUT_WR SD_SEND
-#define SHUT_RDWR SD_BOTH
-
-/**
- * shutdown(2) setting errno
- */
-#define shutdown windows_shutdown
-int windows_shutdown(int sockfd, int how);
-
-/**
- * accept(2) setting errno
- */
-#define accept windows_accept
-int windows_accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
-
-/**
- * bind(2) setting errno
- */
-#define bind windows_bind
-int windows_bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
-
-/**
- * connect(2) setting errno
- */
-#define connect windows_connect
-int windows_connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
-
-/**
- * getsockname(2) setting errno
- */
-#define getsockname windows_getsockname
-int windows_getsockname(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
-
-/**
- * getsockopt(2) setting errno
- */
-#define getsockopt windows_getsockopt
-int windows_getsockopt(int sockfd, int level, int optname,
-					   void *optval, socklen_t *optlen);
-
-/**
- * setsockopt(2) setting errno
- */
-#define setsockopt windows_setsockopt
-int windows_setsockopt(int sockfd, int level, int optname,
-					   const void *optval, socklen_t optlen);
-
-/**
- * socket(2) setting errno
- */
-#define socket windows_socket
-int windows_socket(int domain, int type, int protocol);
-
-/**
- * select(2) setting errno
- */
-#define select windows_select
-int windows_select(int nfds, fd_set *readfds, fd_set *writefds,
-				   fd_set *exceptfds, struct timeval *timeout);
-
-/**
- * close(2) working for file handles and Winsock sockets
- */
-#define close windows_close
-int windows_close(int fd);
-
-/**
- * recv(2) with support for MSG_DONTWAIT
- */
-#define recv windows_recv
-ssize_t windows_recv(int sockfd, void *buf, size_t len, int flags);
-
-/**
- * recvfrom(2) with support for MSG_DONTWAIT
- */
-#define recvfrom windows_recvfrom
-ssize_t windows_recvfrom(int sockfd, void *buf, size_t len, int flags,
-						 struct sockaddr *src_addr, socklen_t *addrlen);
-
-/**
- * recvfrom(2) with support for MSG_DONTWAIT
- */
-#define send windows_send
-ssize_t windows_send(int sockfd, const void *buf, size_t len, int flags);
-
-/**
- * recvfrom(2) with support for MSG_DONTWAIT
- */
-#define sendto windows_send
-ssize_t windows_sendto(int sockfd, const void *buf, size_t len, int flags,
-					   const struct sockaddr *dest_addr, socklen_t addrlen);
-
-/**
- * Declaration missing on older WinGW
- */
-_CRTIMP errno_t strerror_s(char *buf, size_t size, int errnum);
-
-/**
- * strerror_s, but supporting POSIX compatibility errno >= 100
- */
-#define strerror_s strerror_s_extended
-int strerror_s_extended(char *buf, size_t buflen, int errnum);
-
-/**
- * strerror_r(2) replacement, XSI variant
- */
-static inline int strerror_r(int errnum, char *buf, size_t buflen)
-{
-	return strerror_s(buf, buflen, errnum);
-}
-#define HAVE_STRERROR_R /* but not STRERROR_R_CHAR_P */
-
-/**
- * MinGW does provide extended errno values. Windows itself knowns them
- * for POSIX compatibility; we define them as well.
- */
-#ifndef EADDRINUSE
-#define EADDRINUSE			100
-#endif
-#ifndef EADDRNOTAVAIL
-#define EADDRNOTAVAIL		101
-#endif
-#ifndef EAFNOSUPPORT
-#define EAFNOSUPPORT		102
-#endif
-#ifndef EALREADY
-#define EALREADY			103
-#endif
-#ifndef EBADMSG
-#define EBADMSG				104
-#endif
-#ifndef ECANCELED
-#define ECANCELED			105
-#endif
-#ifndef ECONNABORTED
-#define ECONNABORTED		106
-#endif
-#ifndef ECONNREFUSED
-#define ECONNREFUSED		107
-#endif
-#ifndef ECONNRESET
-#define ECONNRESET			108
-#endif
-#ifndef EDESTADDRREQ
-#define EDESTADDRREQ		109
-#endif
-#ifndef EHOSTUNREACH
-#define EHOSTUNREACH		110
-#endif
-#ifndef EIDRM
-#define EIDRM				111
-#endif
-#ifndef EINPROGRESS
-#define EINPROGRESS			112
-#endif
-#ifndef EISCONN
-#define EISCONN				113
-#endif
-#ifndef ELOOP
-#define ELOOP				114
-#endif
-#ifndef EMSGSIZE
-#define EMSGSIZE			115
-#endif
-#ifndef ENETDOWN
-#define ENETDOWN			116
-#endif
-#ifndef ENETRESET
-#define ENETRESET			117
-#endif
-#ifndef ENETUNREACH
-#define ENETUNREACH			118
-#endif
-#ifndef ENOBUFS
-#define ENOBUFS				119
-#endif
-#ifndef ENODATA
-#define ENODATA				120
-#endif
-#ifndef ENOLINK
-#define ENOLINK				121
-#endif
-#ifndef ENOMSG
-#define ENOMSG				122
-#endif
-#ifndef ENOPROTOOPT
-#define ENOPROTOOPT			123
-#endif
-#ifndef ENOSR
-#define ENOSR				124
-#endif
-#ifndef ENOSTR
-#define ENOSTR				125
-#endif
-#ifndef ENOTCONN
-#define ENOTCONN			126
-#endif
-#ifndef ENOTRECOVERABLE
-#define ENOTRECOVERABLE		127
-#endif
-#ifndef ENOTSOCK
-#define ENOTSOCK			128
-#endif
-#ifndef ENOTSUP
-#define ENOTSUP				129
-#endif
-#ifndef EOPNOTSUPP
-#define EOPNOTSUPP			130
-#endif
-#ifndef EOTHER
-#define EOTHER				131
-#endif
-#ifndef EOVERFLOW
-#define EOVERFLOW			132
-#endif
-#ifndef EOWNERDEAD
-#define EOWNERDEAD			133
-#endif
-#ifndef EPROTO
-#define EPROTO				134
-#endif
-#ifndef EPROTONOSUPPORT
-#define EPROTONOSUPPORT		135
-#endif
-#ifndef EPROTOTYPE
-#define EPROTOTYPE			136
-#endif
-#ifndef ETIME
-#define ETIME				137
-#endif
-#ifndef ETIMEDOUT
-#define ETIMEDOUT			138
-#endif
-#ifndef ETXTBSY
-#define ETXTBSY				139
-#endif
-#ifndef EWOULDBLOCK
-#define EWOULDBLOCK			140
-#endif
-
-
-/* Windows does not support "ll" format printf length modifiers. Mingw
- * therefore maps these to the Windows specific I64 length modifier. That
- * won't work for us, as we use our own printf backend on Windows, which works
- * just fine with "ll". */
-#undef PRId64
-#define PRId64 "lld"
-#undef PRId64
-#define PRId64 "lld"
-#undef PRIdLEAST64
-#define PRIdLEAST64 "lld"
-#undef PRIdFAST64
-#define PRIdFAST64 "lld"
-#undef PRIdMAX
-#define PRIdMAX "lld"
-#undef PRIi64
-#define PRIi64 "lli"
-#undef PRIiLEAST64
-#define PRIiLEAST64 "lli"
-#undef PRIiFAST64
-#define PRIiFAST64 "lli"
-#undef PRIiMAX
-#define PRIiMAX "lli"
-#undef PRIo64
-#define PRIo64 "llo"
-#undef PRIoLEAST64
-#define PRIoLEAST64 "llo"
-#undef PRIoFAST64
-#define PRIoFAST64 "llo"
-#undef PRIoMAX
-#define PRIoMAX "llo"
-#undef PRIu64
-#define PRIu64 "llu"
-#undef PRIuLEAST64
-#define PRIuLEAST64 "llu"
-#undef PRIuFAST64
-#define PRIuFAST64 "llu"
-#undef PRIuMAX
-#define PRIuMAX "llu"
-#undef PRIx64
-#define PRIx64 "llx"
-#undef PRIxLEAST64
-#define PRIxLEAST64 "llx"
-#undef PRIxFAST64
-#define PRIxFAST64 "llx"
-#undef PRIxMAX
-#define PRIxMAX "llx"
-#undef PRIX64
-#define PRIX64 "llX"
-#undef PRIXLEAST64
-#define PRIXLEAST64 "llX"
-#undef PRIXFAST64
-#define PRIXFAST64 "llX"
-#undef PRIXMAX
-#define PRIXMAX "llX"
-
-#ifdef _WIN64
-# undef PRIdPTR
-# define PRIdPTR "lld"
-# undef PRIiPTR
-# define PRIiPTR "lli"
-# undef PRIoPTR
-# define PRIoPTR "llo"
-# undef PRIuPTR
-# define PRIuPTR "llu"
-# undef PRIxPTR
-# define PRIxPTR "llx"
-# undef PRIXPTR
-# define PRIXPTR "llX"
-#endif /* _WIN64 */
-
-#endif /** WINDOWS_H_ @}*/
diff --git a/src/libtls/Makefile.in b/src/libtls/Makefile.in
index 426d8bc..e6c23d9 100644
--- a/src/libtls/Makefile.in
+++ b/src/libtls/Makefile.in
@@ -278,6 +278,7 @@ DLLIB = @DLLIB@
 DLLTOOL = @DLLTOOL@
 DSYMUTIL = @DSYMUTIL@
 DUMPBIN = @DUMPBIN@
+EASY_INSTALL = @EASY_INSTALL@
 ECHO_C = @ECHO_C@
 ECHO_N = @ECHO_N@
 ECHO_T = @ECHO_T@
@@ -338,10 +339,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
 PLUGIN_CFLAGS = @PLUGIN_CFLAGS@
 PTHREADLIB = @PTHREADLIB@
 PYTHON = @PYTHON@
+PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@
 PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
 PYTHON_PLATFORM = @PYTHON_PLATFORM@
 PYTHON_PREFIX = @PYTHON_PREFIX@
 PYTHON_VERSION = @PYTHON_VERSION@
+PY_TEST = @PY_TEST@
 RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
@@ -415,6 +418,8 @@ json_CFLAGS = @json_CFLAGS@
 json_LIBS = @json_LIBS@
 libdir = @libdir@
 libexecdir = @libexecdir@
+libiptc_CFLAGS = @libiptc_CFLAGS@
+libiptc_LIBS = @libiptc_LIBS@
 linux_headers = @linux_headers@
 localedir = @localedir@
 localstatedir = @localstatedir@
diff --git a/src/libtls/tests/Makefile.in b/src/libtls/tests/Makefile.in
index 2e44fb4..7d5b377 100644
--- a/src/libtls/tests/Makefile.in
+++ b/src/libtls/tests/Makefile.in
@@ -223,6 +223,7 @@ DLLIB = @DLLIB@
 DLLTOOL = @DLLTOOL@
 DSYMUTIL = @DSYMUTIL@
 DUMPBIN = @DUMPBIN@
+EASY_INSTALL = @EASY_INSTALL@
 ECHO_C = @ECHO_C@
 ECHO_N = @ECHO_N@
 ECHO_T = @ECHO_T@
@@ -283,10 +284,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
 PLUGIN_CFLAGS = @PLUGIN_CFLAGS@
 PTHREADLIB = @PTHREADLIB@
 PYTHON = @PYTHON@
+PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@
 PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
 PYTHON_PLATFORM = @PYTHON_PLATFORM@
 PYTHON_PREFIX = @PYTHON_PREFIX@
 PYTHON_VERSION = @PYTHON_VERSION@
+PY_TEST = @PY_TEST@
 RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
@@ -360,6 +363,8 @@ json_CFLAGS = @json_CFLAGS@
 json_LIBS = @json_LIBS@
 libdir = @libdir@
 libexecdir = @libexecdir@
+libiptc_CFLAGS = @libiptc_CFLAGS@
+libiptc_LIBS = @libiptc_LIBS@
 linux_headers = @linux_headers@
 localedir = @localedir@
 localstatedir = @localstatedir@
diff --git a/src/libtls/tls.c b/src/libtls/tls.c
index 6a8d503..08a06f5 100644
--- a/src/libtls/tls.c
+++ b/src/libtls/tls.c
@@ -415,6 +415,12 @@ METHOD(tls_t, get_eap_msk, chunk_t,
 	return this->crypto->get_eap_msk(this->crypto);
 }
 
+METHOD(tls_t, get_auth, auth_cfg_t*,
+	private_tls_t *this)
+{
+	return this->handshake->get_auth(this->handshake);
+}
+
 METHOD(tls_t, destroy, void,
 	private_tls_t *this)
 {
@@ -465,6 +471,7 @@ tls_t *tls_create(bool is_server, identification_t *server,
 			.get_purpose = _get_purpose,
 			.is_complete = _is_complete,
 			.get_eap_msk = _get_eap_msk,
+			.get_auth = _get_auth,
 			.destroy = _destroy,
 		},
 		.is_server = is_server,
@@ -487,7 +494,7 @@ tls_t *tls_create(bool is_server, identification_t *server,
 										this->alert, peer, server)->handshake;
 	}
 	this->fragmentation = tls_fragmentation_create(this->handshake, this->alert,
-												   this->application);
+												   this->application, purpose);
 	this->compression = tls_compression_create(this->fragmentation, this->alert);
 	this->protection = tls_protection_create(this->compression, this->alert);
 	this->crypto->set_protection(this->crypto, this->protection);
diff --git a/src/libtls/tls.h b/src/libtls/tls.h
index fc1d9b9..f3dc198 100644
--- a/src/libtls/tls.h
+++ b/src/libtls/tls.h
@@ -252,6 +252,13 @@ struct tls_t {
 	chunk_t (*get_eap_msk)(tls_t *this);
 
 	/**
+	 * Get the authentication details after completing the handshake.
+	 *
+	 * @return			authentication details, internal data
+	 */
+	auth_cfg_t* (*get_auth)(tls_t *this);
+
+	/**
 	 * Destroy a tls_t.
 	 */
 	void (*destroy)(tls_t *this);
diff --git a/src/libtls/tls_eap.c b/src/libtls/tls_eap.c
index ebe5bc3..12d5aed 100644
--- a/src/libtls/tls_eap.c
+++ b/src/libtls/tls_eap.c
@@ -426,6 +426,12 @@ METHOD(tls_eap_t, set_identifier, void,
 	this->identifier = identifier;
 }
 
+METHOD(tls_eap_t, get_auth, auth_cfg_t*,
+	private_tls_eap_t *this)
+{
+	return this->tls->get_auth(this->tls);
+}
+
 METHOD(tls_eap_t, destroy, void,
 	private_tls_eap_t *this)
 {
@@ -453,6 +459,7 @@ tls_eap_t *tls_eap_create(eap_type_t type, tls_t *tls, size_t frag_size,
 			.get_msk = _get_msk,
 			.get_identifier = _get_identifier,
 			.set_identifier = _set_identifier,
+			.get_auth = _get_auth,
 			.destroy = _destroy,
 		},
 		.type = type,
diff --git a/src/libtls/tls_eap.h b/src/libtls/tls_eap.h
index f3fbba0..df41fc4 100644
--- a/src/libtls/tls_eap.h
+++ b/src/libtls/tls_eap.h
@@ -77,6 +77,13 @@ struct tls_eap_t {
 	void (*set_identifier) (tls_eap_t *this, uint8_t identifier);
 
 	/**
+	 * Get the authentication details after completing the handshake.
+	 *
+	 * @return				authentication details, internal data
+	 */
+	auth_cfg_t* (*get_auth)(tls_eap_t *this);
+
+	/**
 	 * Destroy a tls_eap_t.
 	 */
 	void (*destroy)(tls_eap_t *this);
diff --git a/src/libtls/tls_fragmentation.c b/src/libtls/tls_fragmentation.c
index 6e4347e..a97ca1e 100644
--- a/src/libtls/tls_fragmentation.c
+++ b/src/libtls/tls_fragmentation.c
@@ -96,9 +96,32 @@ struct private_tls_fragmentation_t {
 	 * Upper layer application data protocol
 	 */
 	tls_application_t *application;
+
+	/**
+	 * Type of context this TLS instance runs in
+	 */
+	tls_purpose_t purpose;
 };
 
 /**
+ * Check if we should send a close notify once the application finishes
+ */
+static bool send_close_notify(private_tls_fragmentation_t *this)
+{
+	switch (this->purpose)
+	{
+		case TLS_PURPOSE_EAP_TLS:
+		case TLS_PURPOSE_EAP_TTLS:
+		case TLS_PURPOSE_EAP_PEAP:
+			/* not for TLS-in-EAP, as we indicate completion with EAP-SUCCCESS.
+			 * Windows does not like close notifies, and hangs/disconnects. */
+			return FALSE;
+		default:
+			return TRUE;
+	}
+}
+
+/**
  * Process a TLS alert
  */
 static status_t process_alert(private_tls_fragmentation_t *this,
@@ -223,6 +246,10 @@ static status_t process_application(private_tls_fragmentation_t *this,
 				continue;
 			case SUCCESS:
 				this->application_finished = TRUE;
+				if (!send_close_notify(this))
+				{
+					return SUCCESS;
+				}
 				/* FALL */
 			case FAILED:
 			default:
@@ -368,6 +395,10 @@ static status_t build_application(private_tls_fragmentation_t *this)
 				break;
 			case SUCCESS:
 				this->application_finished = TRUE;
+				if (!send_close_notify(this))
+				{
+					break;
+				}
 				/* FALL */
 			case FAILED:
 			default:
@@ -463,7 +494,8 @@ METHOD(tls_fragmentation_t, destroy, void,
  * See header
  */
 tls_fragmentation_t *tls_fragmentation_create(tls_handshake_t *handshake,
-							tls_alert_t *alert, tls_application_t *application)
+							tls_alert_t *alert, tls_application_t *application,
+							tls_purpose_t purpose)
 {
 	private_tls_fragmentation_t *this;
 
@@ -478,6 +510,7 @@ tls_fragmentation_t *tls_fragmentation_create(tls_handshake_t *handshake,
 		.alert = alert,
 		.state = ALERT_NONE,
 		.application = application,
+		.purpose = purpose,
 	);
 
 	return &this->public;
diff --git a/src/libtls/tls_fragmentation.h b/src/libtls/tls_fragmentation.h
index f650e7b..a49f27b 100644
--- a/src/libtls/tls_fragmentation.h
+++ b/src/libtls/tls_fragmentation.h
@@ -80,9 +80,11 @@ struct tls_fragmentation_t {
  * @param handshake			upper layer handshake protocol
  * @param alert				TLS alert handler
  * @param application		upper layer application data or NULL
+ * @param purpose			type of context this TLS stack is running in
  * @return					TLS fragmentation layer
  */
 tls_fragmentation_t *tls_fragmentation_create(tls_handshake_t *handshake,
-							tls_alert_t *alert, tls_application_t *application);
+							tls_alert_t *alert, tls_application_t *application,
+							tls_purpose_t purpose);
 
 #endif /** TLS_FRAGMENTATION_H_ @}*/
diff --git a/src/libtls/tls_handshake.h b/src/libtls/tls_handshake.h
index 7fa660c..7edb49b 100644
--- a/src/libtls/tls_handshake.h
+++ b/src/libtls/tls_handshake.h
@@ -98,6 +98,13 @@ struct tls_handshake_t {
 	identification_t* (*get_server_id)(tls_handshake_t *this);
 
 	/**
+	 * Get the peers authentication information after completing the handshake.
+	 *
+	 * @return			authentication data, internal data
+	 */
+	auth_cfg_t* (*get_auth)(tls_handshake_t *this);
+
+	/**
 	 * Destroy a tls_handshake_t.
 	 */
 	void (*destroy)(tls_handshake_t *this);
diff --git a/src/libtls/tls_peer.c b/src/libtls/tls_peer.c
index a95b40f..e6be36b 100644
--- a/src/libtls/tls_peer.c
+++ b/src/libtls/tls_peer.c
@@ -312,7 +312,7 @@ static status_t process_certificate(private_tls_peer_t *this,
 static public_key_t *find_public_key(private_tls_peer_t *this)
 {
 	public_key_t *public = NULL, *current;
-	certificate_t *cert;
+	certificate_t *cert, *found;
 	enumerator_t *enumerator;
 	auth_cfg_t *auth;
 
@@ -323,8 +323,13 @@ static public_key_t *find_public_key(private_tls_peer_t *this)
 						KEY_ANY, cert->get_subject(cert), this->server_auth);
 		while (enumerator->enumerate(enumerator, &current, &auth))
 		{
-			public = current->get_ref(current);
-			break;
+			found = auth->get(auth, AUTH_RULE_SUBJECT_CERT);
+			if (found && cert->equals(cert, found))
+			{
+				public = current->get_ref(current);
+				this->server_auth->merge(this->server_auth, auth, FALSE);
+				break;
+			}
 		}
 		enumerator->destroy(enumerator);
 	}
@@ -379,7 +384,12 @@ static status_t process_modp_key_exchange(private_tls_peer_t *this,
 		this->alert->add(this->alert, TLS_FATAL, TLS_INTERNAL_ERROR);
 		return NEED_MORE;
 	}
-	this->dh->set_other_public_value(this->dh, pub);
+	if (!this->dh->set_other_public_value(this->dh, pub))
+	{
+		DBG1(DBG_TLS, "applying DH public value failed");
+		this->alert->add(this->alert, TLS_FATAL, TLS_INTERNAL_ERROR);
+		return NEED_MORE;
+	}
 
 	this->state = STATE_KEY_EXCHANGE_RECEIVED;
 	return NEED_MORE;
@@ -489,7 +499,12 @@ static status_t process_ec_key_exchange(private_tls_peer_t *this,
 		this->alert->add(this->alert, TLS_FATAL, TLS_INTERNAL_ERROR);
 		return NEED_MORE;
 	}
-	this->dh->set_other_public_value(this->dh, chunk_skip(pub, 1));
+	if (!this->dh->set_other_public_value(this->dh, chunk_skip(pub, 1)))
+	{
+		DBG1(DBG_TLS, "applying DH public value failed");
+		this->alert->add(this->alert, TLS_FATAL, TLS_INTERNAL_ERROR);
+		return NEED_MORE;
+	}
 
 	this->state = STATE_KEY_EXCHANGE_RECEIVED;
 	return NEED_MORE;
@@ -968,7 +983,7 @@ static status_t send_key_exchange_dhe(private_tls_peer_t *this,
 {
 	chunk_t premaster, pub;
 
-	if (this->dh->get_shared_secret(this->dh, &premaster) != SUCCESS)
+	if (!this->dh->get_shared_secret(this->dh, &premaster))
 	{
 		DBG1(DBG_TLS, "calculating premaster from DH failed");
 		this->alert->add(this->alert, TLS_FATAL, TLS_INTERNAL_ERROR);
@@ -985,7 +1000,11 @@ static status_t send_key_exchange_dhe(private_tls_peer_t *this,
 	}
 	chunk_clear(&premaster);
 
-	this->dh->get_my_public_value(this->dh, &pub);
+	if (!this->dh->get_my_public_value(this->dh, &pub))
+	{
+		this->alert->add(this->alert, TLS_FATAL, TLS_INTERNAL_ERROR);
+		return NEED_MORE;
+	}
 	if (this->dh->get_dh_group(this->dh) == MODP_CUSTOM)
 	{
 		writer->write_data16(writer, pub);
@@ -1153,6 +1172,12 @@ METHOD(tls_handshake_t, get_server_id, identification_t*,
 	return this->server;
 }
 
+METHOD(tls_handshake_t, get_auth, auth_cfg_t*,
+	private_tls_peer_t *this)
+{
+	return this->server_auth;
+}
+
 METHOD(tls_handshake_t, destroy, void,
 	private_tls_peer_t *this)
 {
@@ -1186,6 +1211,7 @@ tls_peer_t *tls_peer_create(tls_t *tls, tls_crypto_t *crypto, tls_alert_t *alert
 				.finished = _finished,
 				.get_peer_id = _get_peer_id,
 				.get_server_id = _get_server_id,
+				.get_auth = _get_auth,
 				.destroy = _destroy,
 			},
 		},
diff --git a/src/libtls/tls_protection.c b/src/libtls/tls_protection.c
index b016db2..e73fedc 100644
--- a/src/libtls/tls_protection.c
+++ b/src/libtls/tls_protection.c
@@ -101,14 +101,13 @@ METHOD(tls_protection_t, build, status_t,
 	status_t status;
 
 	status = this->compression->build(this->compression, type, data);
-	if (*type == TLS_CHANGE_CIPHER_SPEC)
-	{
-		this->seq_out = 0;
-		return status;
-	}
-
 	if (status == NEED_MORE)
 	{
+		if (*type == TLS_CHANGE_CIPHER_SPEC)
+		{
+			this->seq_out = 0;
+			return status;
+		}
 		if (this->aead_out)
 		{
 			if (!this->aead_out->encrypt(this->aead_out, this->version,
diff --git a/src/libtls/tls_server.c b/src/libtls/tls_server.c
index aeb5a71..b1a214f 100644
--- a/src/libtls/tls_server.c
+++ b/src/libtls/tls_server.c
@@ -494,8 +494,13 @@ static status_t process_key_exchange_dhe(private_tls_server_t *this,
 		}
 		pub = chunk_skip(pub, 1);
 	}
-	this->dh->set_other_public_value(this->dh, pub);
-	if (this->dh->get_shared_secret(this->dh, &premaster) != SUCCESS)
+	if (!this->dh->set_other_public_value(this->dh, pub))
+	{
+		DBG1(DBG_TLS, "applying DH public value failed");
+		this->alert->add(this->alert, TLS_FATAL, TLS_INTERNAL_ERROR);
+		return NEED_MORE;
+	}
+	if (!this->dh->get_shared_secret(this->dh, &premaster))
 	{
 		DBG1(DBG_TLS, "calculating premaster from DH failed");
 		this->alert->add(this->alert, TLS_FATAL, TLS_INTERNAL_ERROR);
@@ -551,6 +556,7 @@ static status_t process_cert_verify(private_tls_server_t *this,
 		sig->destroy(sig);
 		if (verified)
 		{
+			this->peer_auth->merge(this->peer_auth, auth, FALSE);
 			break;
 		}
 		DBG1(DBG_TLS, "signature verification failed, trying another key");
@@ -914,7 +920,11 @@ static status_t send_server_key_exchange(private_tls_server_t *this,
 		this->alert->add(this->alert, TLS_FATAL, TLS_INTERNAL_ERROR);
 		return NEED_MORE;
 	}
-	this->dh->get_my_public_value(this->dh, &chunk);
+	if (!this->dh->get_my_public_value(this->dh, &chunk))
+	{
+		this->alert->add(this->alert, TLS_FATAL, TLS_INTERNAL_ERROR);
+		return NEED_MORE;
+	}
 	if (params)
 	{
 		writer->write_data16(writer, chunk);
@@ -1073,6 +1083,12 @@ METHOD(tls_handshake_t, get_server_id, identification_t*,
 	return this->server;
 }
 
+METHOD(tls_handshake_t, get_auth, auth_cfg_t*,
+	private_tls_server_t *this)
+{
+	return this->peer_auth;
+}
+
 METHOD(tls_handshake_t, destroy, void,
 	private_tls_server_t *this)
 {
@@ -1107,6 +1123,7 @@ tls_server_t *tls_server_create(tls_t *tls,
 				.finished = _finished,
 				.get_peer_id = _get_peer_id,
 				.get_server_id = _get_server_id,
+				.get_auth = _get_auth,
 				.destroy = _destroy,
 			},
 		},
diff --git a/src/libtls/tls_socket.c b/src/libtls/tls_socket.c
index 648771e..2ccd975 100644
--- a/src/libtls/tls_socket.c
+++ b/src/libtls/tls_socket.c
@@ -291,25 +291,24 @@ METHOD(tls_socket_t, splice, bool,
 	private_tls_socket_t *this, int rfd, int wfd)
 {
 	char buf[PLAIN_BUF_SIZE], *pos;
-	fd_set set;
 	ssize_t in, out;
 	bool old, plain_eof = FALSE, crypto_eof = FALSE;
+	struct pollfd pfd[] = {
+		{ .fd = this->fd,	.events = POLLIN, },
+		{ .fd = rfd,		.events = POLLIN, },
+	};
 
 	while (!plain_eof && !crypto_eof)
 	{
-		FD_ZERO(&set);
-		FD_SET(rfd, &set);
-		FD_SET(this->fd, &set);
-
 		old = thread_cancelability(TRUE);
-		in = select(max(rfd, this->fd) + 1, &set, NULL, NULL, NULL);
+		in = poll(pfd, countof(pfd), -1);
 		thread_cancelability(old);
 		if (in == -1)
 		{
 			DBG1(DBG_TLS, "TLS select error: %s", strerror(errno));
 			return FALSE;
 		}
-		while (!plain_eof && FD_ISSET(this->fd, &set))
+		while (!plain_eof && pfd[0].revents & (POLLIN | POLLHUP | POLLNVAL))
 		{
 			in = read_(this, buf, sizeof(buf), FALSE);
 			switch (in)
@@ -342,7 +341,7 @@ METHOD(tls_socket_t, splice, bool,
 			}
 			break;
 		}
-		if (!crypto_eof && FD_ISSET(rfd, &set))
+		if (!crypto_eof && pfd[1].revents & (POLLIN | POLLHUP | POLLNVAL))
 		{
 			in = read(rfd, buf, sizeof(buf));
 			switch (in)
diff --git a/src/libtnccs/Android.mk b/src/libtnccs/Android.mk
index 68f85c2..e379732 100644
--- a/src/libtnccs/Android.mk
+++ b/src/libtnccs/Android.mk
@@ -22,7 +22,7 @@ endif
 LOCAL_SRC_FILES += $(call add_plugin, tnc-tnccs)
 
 LOCAL_SRC_FILES += $(call add_plugin, tnccs-20)
-LOCAL_SRC_FILES += $(call add_plugin_subdirs, tnccs-20, batch messages messages/ietf messages/tcg state_machine)
+LOCAL_SRC_FILES += $(call add_plugin_subdirs, tnccs-20, batch messages messages/ietf messages/ita messages/tcg state_machine)
 ifneq ($(call plugin_enabled, tnccs-20),)
 LOCAL_C_INCLUDES += $(LOCAL_PATH)/plugins/tnccs_20/
 endif
diff --git a/src/libtnccs/Makefile.in b/src/libtnccs/Makefile.in
index b0bfdf2..dc8c1b8 100644
--- a/src/libtnccs/Makefile.in
+++ b/src/libtnccs/Makefile.in
@@ -283,6 +283,7 @@ DLLIB = @DLLIB@
 DLLTOOL = @DLLTOOL@
 DSYMUTIL = @DSYMUTIL@
 DUMPBIN = @DUMPBIN@
+EASY_INSTALL = @EASY_INSTALL@
 ECHO_C = @ECHO_C@
 ECHO_N = @ECHO_N@
 ECHO_T = @ECHO_T@
@@ -343,10 +344,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
 PLUGIN_CFLAGS = @PLUGIN_CFLAGS@
 PTHREADLIB = @PTHREADLIB@
 PYTHON = @PYTHON@
+PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@
 PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
 PYTHON_PLATFORM = @PYTHON_PLATFORM@
 PYTHON_PREFIX = @PYTHON_PREFIX@
 PYTHON_VERSION = @PYTHON_VERSION@
+PY_TEST = @PY_TEST@
 RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
@@ -420,6 +423,8 @@ json_CFLAGS = @json_CFLAGS@
 json_LIBS = @json_LIBS@
 libdir = @libdir@
 libexecdir = @libexecdir@
+libiptc_CFLAGS = @libiptc_CFLAGS@
+libiptc_LIBS = @libiptc_LIBS@
 linux_headers = @linux_headers@
 localedir = @localedir@
 localstatedir = @localstatedir@
diff --git a/src/libtnccs/plugins/tnc_imc/Makefile.in b/src/libtnccs/plugins/tnc_imc/Makefile.in
index 2b76aab..3641bdf 100644
--- a/src/libtnccs/plugins/tnc_imc/Makefile.in
+++ b/src/libtnccs/plugins/tnc_imc/Makefile.in
@@ -231,6 +231,7 @@ DLLIB = @DLLIB@
 DLLTOOL = @DLLTOOL@
 DSYMUTIL = @DSYMUTIL@
 DUMPBIN = @DUMPBIN@
+EASY_INSTALL = @EASY_INSTALL@
 ECHO_C = @ECHO_C@
 ECHO_N = @ECHO_N@
 ECHO_T = @ECHO_T@
@@ -291,10 +292,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
 PLUGIN_CFLAGS = @PLUGIN_CFLAGS@
 PTHREADLIB = @PTHREADLIB@
 PYTHON = @PYTHON@
+PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@
 PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
 PYTHON_PLATFORM = @PYTHON_PLATFORM@
 PYTHON_PREFIX = @PYTHON_PREFIX@
 PYTHON_VERSION = @PYTHON_VERSION@
+PY_TEST = @PY_TEST@
 RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
@@ -368,6 +371,8 @@ json_CFLAGS = @json_CFLAGS@
 json_LIBS = @json_LIBS@
 libdir = @libdir@
 libexecdir = @libexecdir@
+libiptc_CFLAGS = @libiptc_CFLAGS@
+libiptc_LIBS = @libiptc_LIBS@
 linux_headers = @linux_headers@
 localedir = @localedir@
 localstatedir = @localstatedir@
diff --git a/src/libtnccs/plugins/tnc_imc/tnc_imc_plugin.c b/src/libtnccs/plugins/tnc_imc/tnc_imc_plugin.c
index 859dded..ce5b481 100644
--- a/src/libtnccs/plugins/tnc_imc/tnc_imc_plugin.c
+++ b/src/libtnccs/plugins/tnc_imc/tnc_imc_plugin.c
@@ -44,6 +44,7 @@ METHOD(plugin_t, get_features, int,
 		PLUGIN_CALLBACK(tnc_manager_register, tnc_imc_manager_create),
 			PLUGIN_PROVIDE(CUSTOM, "imc-manager"),
 				PLUGIN_DEPENDS(CUSTOM, "tnccs-manager"),
+				PLUGIN_SDEPEND(CUSTOM, "imv-manager"),
 				PLUGIN_SDEPEND(CERT_DECODE, CERT_X509),
 				PLUGIN_SDEPEND(CERT_DECODE, CERT_TRUSTED_PUBKEY),
 	};
diff --git a/src/libtnccs/plugins/tnc_imc/tnc_imc_plugin.h b/src/libtnccs/plugins/tnc_imc/tnc_imc_plugin.h
index 8c5521c..8cbc703 100644
--- a/src/libtnccs/plugins/tnc_imc/tnc_imc_plugin.h
+++ b/src/libtnccs/plugins/tnc_imc/tnc_imc_plugin.h
@@ -15,7 +15,7 @@
 
 /**
  * @defgroup tnc_imc tnc_imc
- * @ingroup cplugins
+ * @ingroup tplugins
  *
  * @defgroup tnc_imc_plugin tnc_imc_plugin
  * @{ @ingroup tnc_imc
diff --git a/src/libtnccs/plugins/tnc_imv/Makefile.in b/src/libtnccs/plugins/tnc_imv/Makefile.in
index 06e7b04..c4b1bee 100644
--- a/src/libtnccs/plugins/tnc_imv/Makefile.in
+++ b/src/libtnccs/plugins/tnc_imv/Makefile.in
@@ -232,6 +232,7 @@ DLLIB = @DLLIB@
 DLLTOOL = @DLLTOOL@
 DSYMUTIL = @DSYMUTIL@
 DUMPBIN = @DUMPBIN@
+EASY_INSTALL = @EASY_INSTALL@
 ECHO_C = @ECHO_C@
 ECHO_N = @ECHO_N@
 ECHO_T = @ECHO_T@
@@ -292,10 +293,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
 PLUGIN_CFLAGS = @PLUGIN_CFLAGS@
 PTHREADLIB = @PTHREADLIB@
 PYTHON = @PYTHON@
+PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@
 PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
 PYTHON_PLATFORM = @PYTHON_PLATFORM@
 PYTHON_PREFIX = @PYTHON_PREFIX@
 PYTHON_VERSION = @PYTHON_VERSION@
+PY_TEST = @PY_TEST@
 RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
@@ -369,6 +372,8 @@ json_CFLAGS = @json_CFLAGS@
 json_LIBS = @json_LIBS@
 libdir = @libdir@
 libexecdir = @libexecdir@
+libiptc_CFLAGS = @libiptc_CFLAGS@
+libiptc_LIBS = @libiptc_LIBS@
 linux_headers = @linux_headers@
 localedir = @localedir@
 localstatedir = @localstatedir@
diff --git a/src/libtnccs/plugins/tnc_imv/tnc_imv_plugin.h b/src/libtnccs/plugins/tnc_imv/tnc_imv_plugin.h
index afeee2e..5786bba 100644
--- a/src/libtnccs/plugins/tnc_imv/tnc_imv_plugin.h
+++ b/src/libtnccs/plugins/tnc_imv/tnc_imv_plugin.h
@@ -15,7 +15,7 @@
 
 /**
  * @defgroup tnc_imv tnc_imv
- * @ingroup cplugins
+ * @ingroup tplugins
  *
  * @defgroup tnc_imv_plugin tnc_imv_plugin
  * @{ @ingroup tnc_imv
diff --git a/src/libtnccs/plugins/tnc_tnccs/Makefile.in b/src/libtnccs/plugins/tnc_tnccs/Makefile.in
index 8910fe7..5b01e31 100644
--- a/src/libtnccs/plugins/tnc_tnccs/Makefile.in
+++ b/src/libtnccs/plugins/tnc_tnccs/Makefile.in
@@ -231,6 +231,7 @@ DLLIB = @DLLIB@
 DLLTOOL = @DLLTOOL@
 DSYMUTIL = @DSYMUTIL@
 DUMPBIN = @DUMPBIN@
+EASY_INSTALL = @EASY_INSTALL@
 ECHO_C = @ECHO_C@
 ECHO_N = @ECHO_N@
 ECHO_T = @ECHO_T@
@@ -291,10 +292,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
 PLUGIN_CFLAGS = @PLUGIN_CFLAGS@
 PTHREADLIB = @PTHREADLIB@
 PYTHON = @PYTHON@
+PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@
 PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
 PYTHON_PLATFORM = @PYTHON_PLATFORM@
 PYTHON_PREFIX = @PYTHON_PREFIX@
 PYTHON_VERSION = @PYTHON_VERSION@
+PY_TEST = @PY_TEST@
 RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
@@ -368,6 +371,8 @@ json_CFLAGS = @json_CFLAGS@
 json_LIBS = @json_LIBS@
 libdir = @libdir@
 libexecdir = @libexecdir@
+libiptc_CFLAGS = @libiptc_CFLAGS@
+libiptc_LIBS = @libiptc_LIBS@
 linux_headers = @linux_headers@
 localedir = @localedir@
 localstatedir = @localstatedir@
diff --git a/src/libtnccs/plugins/tnc_tnccs/tnc_tnccs_manager.c b/src/libtnccs/plugins/tnc_tnccs/tnc_tnccs_manager.c
index b8683f7..30e5052 100644
--- a/src/libtnccs/plugins/tnc_tnccs/tnc_tnccs_manager.c
+++ b/src/libtnccs/plugins/tnc_tnccs/tnc_tnccs_manager.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2010-2013 Andreas Steffen
+ * Copyright (C) 2010-2015 Andreas Steffen
  * HSR Hochschule fuer Technik Rapperswil
  *
  * This program is free software; you can redistribute it and/or modify it
@@ -169,8 +169,8 @@ METHOD(tnccs_manager_t, remove_method, void,
 
 METHOD(tnccs_manager_t, create_instance, tnccs_t*,
 	private_tnc_tnccs_manager_t *this, tnccs_type_t type, bool is_server,
-	identification_t *server, identification_t *peer, tnc_ift_type_t transport,
-	tnccs_cb_t cb)
+	identification_t *server_id, identification_t *peer_id, host_t *server_ip,
+	host_t *peer_ip, tnc_ift_type_t transport, tnccs_cb_t cb)
 {
 	enumerator_t *enumerator;
 	tnccs_entry_t *entry;
@@ -182,7 +182,8 @@ METHOD(tnccs_manager_t, create_instance, tnccs_t*,
 	{
 		if (type == entry->type)
 		{
-			protocol = entry->constructor(is_server, server, peer, transport, cb);
+			protocol = entry->constructor(is_server, server_id, peer_id,
+										  server_ip, peer_ip, transport, cb);
 			if (protocol)
 			{
 				break;
@@ -716,7 +717,8 @@ METHOD(tnccs_manager_t, get_attribute, TNC_Result,
 		case TNC_ATTRIBUTEID_AR_IDENTITIES:
 		{
 			linked_list_t *list;
-			identification_t *peer;
+			identification_t *peer_id;
+			host_t *peer_ip;
 			tnccs_t *tnccs;
 			tncif_identity_t *tnc_id;
 			u_int32_t id_type, subject_type;
@@ -726,10 +728,11 @@ METHOD(tnccs_manager_t, get_attribute, TNC_Result,
 
 			list = linked_list_create();
 			tnccs = entry->tnccs;
-			peer = tnccs->tls.get_peer_id(&tnccs->tls);
-			if (peer)
+
+			peer_id = tnccs->tls.get_peer_id(&tnccs->tls);
+			if (peer_id)
 			{
-				switch (peer->get_type(peer))
+				switch (peer_id->get_type(peer_id))
 				{
 					case ID_IPV4_ADDR:
 						id_type = TNC_ID_IPV4_ADDR;
@@ -756,7 +759,7 @@ METHOD(tnccs_manager_t, get_attribute, TNC_Result,
 						subject_type = TNC_SUBJECT_UNKNOWN;
 				}
 				if (id_type != TNC_ID_UNKNOWN &&
-					asprintf(&id_str, "%Y", peer) >= 0)
+					asprintf(&id_str, "%Y", peer_id) >= 0)
 				{
 					id_value = chunk_from_str(id_str);
 					tnc_id = tncif_identity_create(
@@ -767,6 +770,33 @@ METHOD(tnccs_manager_t, get_attribute, TNC_Result,
 					list->insert_last(list, tnc_id);
 				}
 			}
+
+			peer_ip = tnccs->get_peer_ip(tnccs);
+			if (peer_ip)
+			{
+				switch (peer_ip->get_family(peer_ip))
+				{
+					case AF_INET:
+						id_type = TNC_ID_IPV4_ADDR;
+						break;
+					case AF_INET6:
+						id_type = TNC_ID_IPV6_ADDR;
+						break;
+					default:
+						id_type = TNC_ID_UNKNOWN;
+				}
+
+				if (id_type != TNC_ID_UNKNOWN &&
+					asprintf(&id_str, "%H", peer_ip) >= 0)
+				{
+					id_value = chunk_from_str(id_str);
+					tnc_id = tncif_identity_create(
+								pen_type_create(PEN_TCG, id_type), id_value,
+								pen_type_create(PEN_TCG, TNC_SUBJECT_MACHINE),
+								pen_type_create(PEN_TCG, TNC_AUTH_UNKNOWN));
+					list->insert_last(list, tnc_id);
+				}
+			}
 			result = identity_attribute(buffer_len, buffer, value_len, list);
 			list->destroy_offset(list, offsetof(tncif_identity_t, destroy));
 			return result;
diff --git a/src/libtnccs/plugins/tnc_tnccs/tnc_tnccs_plugin.h b/src/libtnccs/plugins/tnc_tnccs/tnc_tnccs_plugin.h
index f935fa4..c99d5e7 100644
--- a/src/libtnccs/plugins/tnc_tnccs/tnc_tnccs_plugin.h
+++ b/src/libtnccs/plugins/tnc_tnccs/tnc_tnccs_plugin.h
@@ -15,7 +15,7 @@
 
 /**
  * @defgroup tnc_tnccs tnc_tnccs
- * @ingroup cplugins
+ * @ingroup tplugins
  *
  * @defgroup tnc_tnccs_plugin tnc_tnccs_plugin
  * @{ @ingroup tnc_tnccs
diff --git a/src/libtnccs/plugins/tnccs_11/Makefile.in b/src/libtnccs/plugins/tnccs_11/Makefile.in
index ea6ac55..e0c039a 100644
--- a/src/libtnccs/plugins/tnccs_11/Makefile.in
+++ b/src/libtnccs/plugins/tnccs_11/Makefile.in
@@ -241,6 +241,7 @@ DLLIB = @DLLIB@
 DLLTOOL = @DLLTOOL@
 DSYMUTIL = @DSYMUTIL@
 DUMPBIN = @DUMPBIN@
+EASY_INSTALL = @EASY_INSTALL@
 ECHO_C = @ECHO_C@
 ECHO_N = @ECHO_N@
 ECHO_T = @ECHO_T@
@@ -301,10 +302,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
 PLUGIN_CFLAGS = @PLUGIN_CFLAGS@
 PTHREADLIB = @PTHREADLIB@
 PYTHON = @PYTHON@
+PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@
 PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
 PYTHON_PLATFORM = @PYTHON_PLATFORM@
 PYTHON_PREFIX = @PYTHON_PREFIX@
 PYTHON_VERSION = @PYTHON_VERSION@
+PY_TEST = @PY_TEST@
 RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
@@ -378,6 +381,8 @@ json_CFLAGS = @json_CFLAGS@
 json_LIBS = @json_LIBS@
 libdir = @libdir@
 libexecdir = @libexecdir@
+libiptc_CFLAGS = @libiptc_CFLAGS@
+libiptc_LIBS = @libiptc_LIBS@
 linux_headers = @linux_headers@
 localedir = @localedir@
 localstatedir = @localstatedir@
diff --git a/src/libtnccs/plugins/tnccs_11/tnccs_11.c b/src/libtnccs/plugins/tnccs_11/tnccs_11.c
index 28c5e52..0918a2b 100644
--- a/src/libtnccs/plugins/tnccs_11/tnccs_11.c
+++ b/src/libtnccs/plugins/tnccs_11/tnccs_11.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2010-2013 Andreas Steffen
+ * Copyright (C) 2010-2015 Andreas Steffen
  * HSR Hochschule fuer Technik Rapperswil
  *
  * This program is free software; you can redistribute it and/or modify it
@@ -54,12 +54,22 @@ struct private_tnccs_11_t {
 	/**
 	 * Server identity
 	 */
-	identification_t *server;
+	identification_t *server_id;
 
 	/**
 	 * Client identity
 	 */
-	identification_t *peer;
+	identification_t *peer_id;
+
+	/**
+	 * Server IP address
+	 */
+	host_t *server_ip;
+
+	/**
+	 * Client IP address
+	 */
+	host_t *peer_ip;
 
 	/**
 	 * Underlying TNC IF-T transport protocol
@@ -527,20 +537,20 @@ METHOD(tls_t, is_server, bool,
 METHOD(tls_t, get_server_id, identification_t*,
 	private_tnccs_11_t *this)
 {
-	return this->server;
+	return this->server_id;
 }
 
 METHOD(tls_t, set_peer_id, void,
 	private_tnccs_11_t *this, identification_t *id)
 {
-	DESTROY_IF(this->peer);
-	this->peer = id->clone(id);
+	DESTROY_IF(this->peer_id);
+	this->peer_id = id->clone(id);
 }
 
 METHOD(tls_t, get_peer_id, identification_t*,
 	private_tnccs_11_t *this)
 {
-	return this->peer;
+	return this->peer_id;
 }
 
 METHOD(tls_t, get_purpose, tls_purpose_t,
@@ -578,14 +588,28 @@ METHOD(tls_t, destroy, void,
 	{
 		tnc->tnccs->remove_connection(tnc->tnccs, this->connection_id,
 												  this->is_server);
-		this->server->destroy(this->server);
-		this->peer->destroy(this->peer);
+		this->server_id->destroy(this->server_id);
+		this->peer_id->destroy(this->peer_id);
+		this->server_ip->destroy(this->server_ip);
+		this->peer_ip->destroy(this->peer_ip);
 		this->mutex->destroy(this->mutex);
 		DESTROY_IF(this->batch);
 		free(this);
 	}
 }
 
+METHOD(tnccs_t, get_server_ip, host_t*,
+	private_tnccs_11_t *this)
+{
+	return this->server_ip;
+}
+
+METHOD(tnccs_t, get_peer_ip, host_t*,
+	private_tnccs_11_t *this)
+{
+	return this->peer_ip;
+}
+
 METHOD(tnccs_t, get_transport, tnc_ift_type_t,
 	private_tnccs_11_t *this)
 {
@@ -628,9 +652,10 @@ METHOD(tnccs_t, get_ref, tnccs_t*,
 /**
  * See header
  */
-tnccs_t* tnccs_11_create(bool is_server,
-						 identification_t *server, identification_t *peer,
-						 tnc_ift_type_t transport, tnccs_cb_t cb)
+tnccs_t* tnccs_11_create(bool is_server, identification_t *server_id,
+						 identification_t *peer_id, host_t *server_ip,
+						 host_t *peer_ip, tnc_ift_type_t transport,
+						 tnccs_cb_t cb)
 {
 	private_tnccs_11_t *this;
 
@@ -648,6 +673,8 @@ tnccs_t* tnccs_11_create(bool is_server,
 				.get_eap_msk = _get_eap_msk,
 				.destroy = _destroy,
 			},
+			.get_server_ip = _get_server_ip,
+			.get_peer_ip = _get_peer_ip,
 			.get_transport = _get_transport,
 			.set_transport = _set_transport,
 			.get_auth_type = _get_auth_type,
@@ -656,8 +683,10 @@ tnccs_t* tnccs_11_create(bool is_server,
 			.get_ref = _get_ref,
 		},
 		.is_server = is_server,
-		.server = server->clone(server),
-		.peer = peer->clone(peer),
+		.server_id = server_id->clone(server_id),
+		.peer_id = peer_id->clone(peer_id),
+		.server_ip = server_ip->clone(server_ip),
+		.peer_ip = peer_ip->clone(peer_ip),
 		.transport = transport,
 		.callback = cb,
 		.mutex = mutex_create(MUTEX_TYPE_DEFAULT),
diff --git a/src/libtnccs/plugins/tnccs_11/tnccs_11.h b/src/libtnccs/plugins/tnccs_11/tnccs_11.h
index e805df8..60d5518 100644
--- a/src/libtnccs/plugins/tnccs_11/tnccs_11.h
+++ b/src/libtnccs/plugins/tnccs_11/tnccs_11.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2010-2013 Andreas Steffen
+ * Copyright (C) 2010-2015 Andreas Steffen
  * HSR Hochschule fuer Technik Rapperswil
  *
  * This program is free software; you can redistribute it and/or modify it
@@ -29,14 +29,17 @@
  * Create an instance of the TNC IF-TNCCS 1.1 protocol handler.
  *
  * @param is_server		TRUE to act as TNC Server, FALSE for TNC Client
- * @param server		Server identity
- * @param peer			Client identity
+ * @param server_id		Server identity
+ * @param peer_id		Client identity
+ * @param server_ip		Server IP address
+ * @param peer_ip		Client IP address
  * @param transport		Underlying IF-T transport protocol
  * @param cb			Callback function if TNC Server, NULL if TNC Client
  * @return				TNC_IF_TNCCS 1.1 protocol stack
  */
-tnccs_t* tnccs_11_create(bool is_server,
-						 identification_t *server, identification_t *peer,
-						 tnc_ift_type_t transport, tnccs_cb_t cb);
+tnccs_t* tnccs_11_create(bool is_server, identification_t *server_id,
+						 identification_t *peer_id, host_t *server_ip,
+						 host_t *peer_ip, tnc_ift_type_t transport,
+						 tnccs_cb_t cb);
 
 #endif /** TNCCS_11_H_ @}*/
diff --git a/src/libtnccs/plugins/tnccs_11/tnccs_11_plugin.h b/src/libtnccs/plugins/tnccs_11/tnccs_11_plugin.h
index 619a073..73ea575 100644
--- a/src/libtnccs/plugins/tnccs_11/tnccs_11_plugin.h
+++ b/src/libtnccs/plugins/tnccs_11/tnccs_11_plugin.h
@@ -15,7 +15,7 @@
 
 /**
  * @defgroup tnccs_11 tnccs_11
- * @ingroup cplugins
+ * @ingroup tplugins
  *
  * @defgroup tnccs_11_plugin tnccs_11_plugin
  * @{ @ingroup tnccs_11
diff --git a/src/libtnccs/plugins/tnccs_20/Makefile.am b/src/libtnccs/plugins/tnccs_20/Makefile.am
index 2aefecd..7d1cdde 100644
--- a/src/libtnccs/plugins/tnccs_20/Makefile.am
+++ b/src/libtnccs/plugins/tnccs_20/Makefile.am
@@ -18,6 +18,8 @@ endif
 
 libstrongswan_tnccs_20_la_SOURCES = \
 	tnccs_20_plugin.h tnccs_20_plugin.c tnccs_20.h tnccs_20.c \
+	tnccs_20_handler.h \
+	tnccs_20_server.h tnccs_20_server.c tnccs_20_client.h tnccs_20_client.c \
 	batch/pb_tnc_batch.h batch/pb_tnc_batch.c \
 	messages/pb_tnc_msg.h messages/pb_tnc_msg.c \
 	messages/ietf/pb_experimental_msg.h messages/ietf/pb_experimental_msg.c \
@@ -28,6 +30,8 @@ libstrongswan_tnccs_20_la_SOURCES = \
 	messages/ietf/pb_language_preference_msg.h messages/ietf/pb_language_preference_msg.c \
 	messages/ietf/pb_reason_string_msg.h messages/ietf/pb_reason_string_msg.c \
 	messages/ietf/pb_remediation_parameters_msg.h messages/ietf/pb_remediation_parameters_msg.c \
+	messages/ita/pb_mutual_capability_msg.h messages/ita/pb_mutual_capability_msg.c \
+	messages/ita/pb_noskip_test_msg.h messages/ita/pb_noskip_test_msg.c \
 	messages/tcg/pb_pdp_referral_msg.h messages/tcg/pb_pdp_referral_msg.c \
 	state_machine/pb_tnc_state_machine.h state_machine/pb_tnc_state_machine.c
 
diff --git a/src/libtnccs/plugins/tnccs_20/Makefile.in b/src/libtnccs/plugins/tnccs_20/Makefile.in
index 90c8047..17d997f 100644
--- a/src/libtnccs/plugins/tnccs_20/Makefile.in
+++ b/src/libtnccs/plugins/tnccs_20/Makefile.in
@@ -132,8 +132,8 @@ LTLIBRARIES = $(noinst_LTLIBRARIES) $(plugin_LTLIBRARIES)
 @MONOLITHIC_FALSE@	$(top_builddir)/src/libtnccs/libtnccs.la
 am__dirstamp = $(am__leading_dot)dirstamp
 am_libstrongswan_tnccs_20_la_OBJECTS = tnccs_20_plugin.lo tnccs_20.lo \
-	batch/pb_tnc_batch.lo messages/pb_tnc_msg.lo \
-	messages/ietf/pb_experimental_msg.lo \
+	tnccs_20_server.lo tnccs_20_client.lo batch/pb_tnc_batch.lo \
+	messages/pb_tnc_msg.lo messages/ietf/pb_experimental_msg.lo \
 	messages/ietf/pb_pa_msg.lo \
 	messages/ietf/pb_assessment_result_msg.lo \
 	messages/ietf/pb_access_recommendation_msg.lo \
@@ -141,6 +141,8 @@ am_libstrongswan_tnccs_20_la_OBJECTS = tnccs_20_plugin.lo tnccs_20.lo \
 	messages/ietf/pb_language_preference_msg.lo \
 	messages/ietf/pb_reason_string_msg.lo \
 	messages/ietf/pb_remediation_parameters_msg.lo \
+	messages/ita/pb_mutual_capability_msg.lo \
+	messages/ita/pb_noskip_test_msg.lo \
 	messages/tcg/pb_pdp_referral_msg.lo \
 	state_machine/pb_tnc_state_machine.lo
 libstrongswan_tnccs_20_la_OBJECTS =  \
@@ -242,6 +244,7 @@ DLLIB = @DLLIB@
 DLLTOOL = @DLLTOOL@
 DSYMUTIL = @DSYMUTIL@
 DUMPBIN = @DUMPBIN@
+EASY_INSTALL = @EASY_INSTALL@
 ECHO_C = @ECHO_C@
 ECHO_N = @ECHO_N@
 ECHO_T = @ECHO_T@
@@ -302,10 +305,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
 PLUGIN_CFLAGS = @PLUGIN_CFLAGS@
 PTHREADLIB = @PTHREADLIB@
 PYTHON = @PYTHON@
+PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@
 PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
 PYTHON_PLATFORM = @PYTHON_PLATFORM@
 PYTHON_PREFIX = @PYTHON_PREFIX@
 PYTHON_VERSION = @PYTHON_VERSION@
+PY_TEST = @PY_TEST@
 RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
@@ -379,6 +384,8 @@ json_CFLAGS = @json_CFLAGS@
 json_LIBS = @json_LIBS@
 libdir = @libdir@
 libexecdir = @libexecdir@
+libiptc_CFLAGS = @libiptc_CFLAGS@
+libiptc_LIBS = @libiptc_LIBS@
 linux_headers = @linux_headers@
 localedir = @localedir@
 localstatedir = @localstatedir@
@@ -454,6 +461,8 @@ AM_CFLAGS = \
 
 libstrongswan_tnccs_20_la_SOURCES = \
 	tnccs_20_plugin.h tnccs_20_plugin.c tnccs_20.h tnccs_20.c \
+	tnccs_20_handler.h \
+	tnccs_20_server.h tnccs_20_server.c tnccs_20_client.h tnccs_20_client.c \
 	batch/pb_tnc_batch.h batch/pb_tnc_batch.c \
 	messages/pb_tnc_msg.h messages/pb_tnc_msg.c \
 	messages/ietf/pb_experimental_msg.h messages/ietf/pb_experimental_msg.c \
@@ -464,6 +473,8 @@ libstrongswan_tnccs_20_la_SOURCES = \
 	messages/ietf/pb_language_preference_msg.h messages/ietf/pb_language_preference_msg.c \
 	messages/ietf/pb_reason_string_msg.h messages/ietf/pb_reason_string_msg.c \
 	messages/ietf/pb_remediation_parameters_msg.h messages/ietf/pb_remediation_parameters_msg.c \
+	messages/ita/pb_mutual_capability_msg.h messages/ita/pb_mutual_capability_msg.c \
+	messages/ita/pb_noskip_test_msg.h messages/ita/pb_noskip_test_msg.c \
 	messages/tcg/pb_pdp_referral_msg.h messages/tcg/pb_pdp_referral_msg.c \
 	state_machine/pb_tnc_state_machine.h state_machine/pb_tnc_state_machine.c
 
@@ -590,6 +601,17 @@ messages/ietf/pb_reason_string_msg.lo: messages/ietf/$(am__dirstamp) \
 messages/ietf/pb_remediation_parameters_msg.lo:  \
 	messages/ietf/$(am__dirstamp) \
 	messages/ietf/$(DEPDIR)/$(am__dirstamp)
+messages/ita/$(am__dirstamp):
+	@$(MKDIR_P) messages/ita
+	@: > messages/ita/$(am__dirstamp)
+messages/ita/$(DEPDIR)/$(am__dirstamp):
+	@$(MKDIR_P) messages/ita/$(DEPDIR)
+	@: > messages/ita/$(DEPDIR)/$(am__dirstamp)
+messages/ita/pb_mutual_capability_msg.lo:  \
+	messages/ita/$(am__dirstamp) \
+	messages/ita/$(DEPDIR)/$(am__dirstamp)
+messages/ita/pb_noskip_test_msg.lo: messages/ita/$(am__dirstamp) \
+	messages/ita/$(DEPDIR)/$(am__dirstamp)
 messages/tcg/$(am__dirstamp):
 	@$(MKDIR_P) messages/tcg
 	@: > messages/tcg/$(am__dirstamp)
@@ -618,6 +640,8 @@ mostlyclean-compile:
 	-rm -f messages/*.lo
 	-rm -f messages/ietf/*.$(OBJEXT)
 	-rm -f messages/ietf/*.lo
+	-rm -f messages/ita/*.$(OBJEXT)
+	-rm -f messages/ita/*.lo
 	-rm -f messages/tcg/*.$(OBJEXT)
 	-rm -f messages/tcg/*.lo
 	-rm -f state_machine/*.$(OBJEXT)
@@ -627,7 +651,9 @@ distclean-compile:
 	-rm -f *.tab.c
 
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/tnccs_20.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/tnccs_20_client.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/tnccs_20_plugin.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/tnccs_20_server.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at batch/$(DEPDIR)/pb_tnc_batch.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at messages/$(DEPDIR)/pb_tnc_msg.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at messages/ietf/$(DEPDIR)/pb_access_recommendation_msg.Plo at am__quote@
@@ -638,6 +664,8 @@ distclean-compile:
 @AMDEP_TRUE@@am__include@ @am__quote at messages/ietf/$(DEPDIR)/pb_pa_msg.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at messages/ietf/$(DEPDIR)/pb_reason_string_msg.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at messages/ietf/$(DEPDIR)/pb_remediation_parameters_msg.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at messages/ita/$(DEPDIR)/pb_mutual_capability_msg.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at messages/ita/$(DEPDIR)/pb_noskip_test_msg.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at messages/tcg/$(DEPDIR)/pb_pdp_referral_msg.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at state_machine/$(DEPDIR)/pb_tnc_state_machine.Plo at am__quote@
 
@@ -673,6 +701,7 @@ clean-libtool:
 	-rm -rf batch/.libs batch/_libs
 	-rm -rf messages/.libs messages/_libs
 	-rm -rf messages/ietf/.libs messages/ietf/_libs
+	-rm -rf messages/ita/.libs messages/ita/_libs
 	-rm -rf messages/tcg/.libs messages/tcg/_libs
 	-rm -rf state_machine/.libs state_machine/_libs
 
@@ -797,6 +826,8 @@ distclean-generic:
 	-rm -f messages/$(am__dirstamp)
 	-rm -f messages/ietf/$(DEPDIR)/$(am__dirstamp)
 	-rm -f messages/ietf/$(am__dirstamp)
+	-rm -f messages/ita/$(DEPDIR)/$(am__dirstamp)
+	-rm -f messages/ita/$(am__dirstamp)
 	-rm -f messages/tcg/$(DEPDIR)/$(am__dirstamp)
 	-rm -f messages/tcg/$(am__dirstamp)
 	-rm -f state_machine/$(DEPDIR)/$(am__dirstamp)
@@ -811,7 +842,7 @@ clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \
 	clean-pluginLTLIBRARIES mostlyclean-am
 
 distclean: distclean-am
-	-rm -rf ./$(DEPDIR) batch/$(DEPDIR) messages/$(DEPDIR) messages/ietf/$(DEPDIR) messages/tcg/$(DEPDIR) state_machine/$(DEPDIR)
+	-rm -rf ./$(DEPDIR) batch/$(DEPDIR) messages/$(DEPDIR) messages/ietf/$(DEPDIR) messages/ita/$(DEPDIR) messages/tcg/$(DEPDIR) state_machine/$(DEPDIR)
 	-rm -f Makefile
 distclean-am: clean-am distclean-compile distclean-generic \
 	distclean-tags
@@ -857,7 +888,7 @@ install-ps-am:
 installcheck-am:
 
 maintainer-clean: maintainer-clean-am
-	-rm -rf ./$(DEPDIR) batch/$(DEPDIR) messages/$(DEPDIR) messages/ietf/$(DEPDIR) messages/tcg/$(DEPDIR) state_machine/$(DEPDIR)
+	-rm -rf ./$(DEPDIR) batch/$(DEPDIR) messages/$(DEPDIR) messages/ietf/$(DEPDIR) messages/ita/$(DEPDIR) messages/tcg/$(DEPDIR) state_machine/$(DEPDIR)
 	-rm -f Makefile
 maintainer-clean-am: distclean-am maintainer-clean-generic
 
diff --git a/src/libtnccs/plugins/tnccs_20/batch/pb_tnc_batch.c b/src/libtnccs/plugins/tnccs_20/batch/pb_tnc_batch.c
index 228c082..faad02b 100644
--- a/src/libtnccs/plugins/tnccs_20/batch/pb_tnc_batch.c
+++ b/src/libtnccs/plugins/tnccs_20/batch/pb_tnc_batch.c
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 2010 Sansar Choinyanbuu
- * Copyright (C) 2010-2012 Andreas Steffen
+ * Copyright (C) 2010-2015 Andreas Steffen
  * HSR Hochschule fuer Technik Rapperswil
  *
  * This program is free software; you can redistribute it and/or modify it
@@ -85,7 +85,7 @@ struct private_pb_tnc_batch_t {
 	pb_tnc_batch_t public;
 
 	/**
-	 * TNCC if TRUE, TNCS if FALSE
+	 * from TNC server if TRUE, from TNC client if FALSE
 	 */
 	bool is_server;
 
@@ -166,6 +166,9 @@ METHOD(pb_tnc_batch_t, add_msg, bool,
 		case PEN_TCG:
 			msg_type_names = pb_tnc_tcg_msg_type_names;
 			break;
+		case PEN_ITA:
+			msg_type_names = pb_tnc_ita_msg_type_names;
+			break;
 	}
 	DBG2(DBG_TNC, "adding %N/%N message", pen_names, msg_type.vendor_id,
 										  msg_type_names, msg_type.type);
@@ -176,6 +179,7 @@ METHOD(pb_tnc_batch_t, add_msg, bool,
 METHOD(pb_tnc_batch_t, build, void,
 	private_pb_tnc_batch_t *this)
 {
+	u_int8_t version;
 	u_int32_t msg_len;
 	chunk_t msg_value;
 	enumerator_t *enumerator;
@@ -184,9 +188,14 @@ METHOD(pb_tnc_batch_t, build, void,
 	pb_tnc_msg_info_t *msg_infos;
 	bio_writer_t *writer;
 
+	/* Set wrong PB-TNC version for testing purposes to force a PB-TNC error */
+	version = lib->settings->get_int(lib->settings,
+						"%s.plugins.tnccs-20.tests.pb_tnc_version",
+						 PB_TNC_VERSION, lib->ns);
+
 	/* build PB-TNC batch header */
 	writer = bio_writer_create(this->batch_len);
-	writer->write_uint8 (writer, PB_TNC_VERSION);
+	writer->write_uint8 (writer, version);
 	writer->write_uint8 (writer, this->is_server ?
 								 PB_TNC_BATCH_FLAG_D : PB_TNC_BATCH_FLAG_NONE);
 	writer->write_uint16(writer, this->type);
@@ -211,6 +220,9 @@ METHOD(pb_tnc_batch_t, build, void,
 			case PEN_TCG:
 				msg_infos = pb_tnc_tcg_msg_infos;
 				break;
+			case PEN_ITA:
+				msg_infos = pb_tnc_ita_msg_infos;
+				break;
 		}
 		if (msg_infos[msg_type.type].has_noskip_flag)
 		{
@@ -228,15 +240,15 @@ METHOD(pb_tnc_batch_t, build, void,
 	writer->destroy(writer);
 }
 
-static status_t process_batch_header(private_pb_tnc_batch_t *this,
-									 pb_tnc_state_machine_t *state_machine)
+METHOD(pb_tnc_batch_t, process_header, status_t,
+	private_pb_tnc_batch_t *this, bool directionality, bool is_server,
+	bool *from_server)
 {
 	bio_reader_t *reader;
 	pb_tnc_msg_t *msg;
 	pb_error_msg_t *err_msg;
 	u_int8_t version, flags, reserved, type;
 	u_int32_t batch_len;
-	bool directionality;
 
 	if (this->encoding.len < PB_TNC_BATCH_HEADER_SIZE)
 	{
@@ -267,13 +279,14 @@ static status_t process_batch_header(private_pb_tnc_batch_t *this,
 	}
 
 	/* Directionality */
-	directionality = (flags & PB_TNC_BATCH_FLAG_D) != PB_TNC_BATCH_FLAG_NONE;
-	if (directionality == this->is_server)
+	*from_server = (flags & PB_TNC_BATCH_FLAG_D) != PB_TNC_BATCH_FLAG_NONE;
+
+	if (directionality & (*from_server == is_server))
 	{
 		DBG1(DBG_TNC, "wrong Directionality: batch is from a PB %s",
-			 directionality ? "server" : "client");
+					   is_server ? "server" : "client");
 		msg = pb_error_msg_create_with_offset(TRUE, PEN_IETF,
-							PB_ERROR_INVALID_PARAMETER, 1);
+					   PB_ERROR_INVALID_PARAMETER, 1);
 		goto fatal;
 	}
 
@@ -287,17 +300,6 @@ static status_t process_batch_header(private_pb_tnc_batch_t *this,
 		goto fatal;
 	}
 
-	if (!state_machine->receive_batch(state_machine, this->type))
-	{
-		DBG1(DBG_TNC, "unexpected PB-TNC batch type: %N",
-					   pb_tnc_batch_type_names, this->type);
-		msg = pb_error_msg_create(TRUE, PEN_IETF,
-								  PB_ERROR_UNEXPECTED_BATCH_TYPE);
-		goto fatal;
-	}
-	DBG1(DBG_TNC, "processing PB-TNC %N batch", pb_tnc_batch_type_names,
-												this->type);
-
 	/* Batch Length */
 	if (this->encoding.len != batch_len)
 	{
@@ -310,12 +312,6 @@ static status_t process_batch_header(private_pb_tnc_batch_t *this,
 
 	this->offset = PB_TNC_BATCH_HEADER_SIZE;
 
-	/* Register an empty CDATA batch with the state machine */
-	if (this->type == PB_BATCH_CDATA)
-	{
-		state_machine->set_empty_cdata(state_machine,
-									   this->offset == this->encoding.len);
-	}
 	return SUCCESS;
 
 fatal:
@@ -395,11 +391,18 @@ static status_t process_tnc_msg(private_pb_tnc_batch_t *this)
 		msg_type_names = pb_tnc_msg_type_names;
 		msg_infos = pb_tnc_msg_infos;
 	}
-	else if (vendor_id == PEN_TCG && msg_type <= PB_TCG_MSG_ROOF)
+	else if (vendor_id == PEN_TCG && msg_type <= PB_TCG_MSG_ROOF &&
+									 msg_type >  PB_TCG_MSG_RESERVED)
 	{
 		msg_type_names = pb_tnc_tcg_msg_type_names;
 		msg_infos = pb_tnc_tcg_msg_infos;
 	}
+	else if (vendor_id == PEN_ITA && msg_type <= PB_ITA_MSG_ROOF &&
+									 msg_type >  PB_ITA_MSG_NOSKIP_TEST)
+	{
+		msg_type_names = pb_tnc_ita_msg_type_names;
+		msg_infos = pb_tnc_ita_msg_infos;
+	}
 	else
 	{
 		if (msg_len < PB_TNC_MSG_HEADER_SIZE)
@@ -413,7 +416,7 @@ static status_t process_tnc_msg(private_pb_tnc_batch_t *this)
 
 		if (noskip_flag)
 		{
-			DBG1(DBG_TNC, "reject PB-TNC message 0x%06x/0x%08x)",
+			DBG1(DBG_TNC, "reject PB-TNC message (0x%06x/0x%08x)",
 						   vendor_id, msg_type);
 			msg = pb_error_msg_create_with_offset(TRUE, PEN_IETF,
 							PB_ERROR_UNSUPPORTED_MANDATORY_MSG, this->offset);
@@ -421,7 +424,7 @@ static status_t process_tnc_msg(private_pb_tnc_batch_t *this)
 		}
 		else
 		{
-			DBG1(DBG_TNC, "ignore PB-TNC message 0x%06x/0x%08x)",
+			DBG1(DBG_TNC, "ignore PB-TNC message (0x%06x/0x%08x)",
 						   vendor_id, msg_type);
 			this->offset += msg_len;
 			return SUCCESS;
@@ -502,14 +505,26 @@ fatal:
 METHOD(pb_tnc_batch_t, process, status_t,
 	private_pb_tnc_batch_t *this, pb_tnc_state_machine_t *state_machine)
 {
-	status_t status;
+	pb_tnc_msg_t *msg;
+	status_t status = SUCCESS;
 
-	status = process_batch_header(this, state_machine);
-	if (status != SUCCESS)
+	if (!state_machine->receive_batch(state_machine, this->type))
 	{
+		DBG1(DBG_TNC, "unexpected PB-TNC batch type: %N",
+					   pb_tnc_batch_type_names, this->type);
+		msg = pb_error_msg_create(TRUE, PEN_IETF,
+								  PB_ERROR_UNEXPECTED_BATCH_TYPE);
+		this->errors->insert_last(this->errors, msg);
 		return FAILED;
 	}
 
+	/* Register an empty CDATA batch with the state machine */
+	if (this->type == PB_BATCH_CDATA)
+	{
+		state_machine->set_empty_cdata(state_machine,
+									   this->offset == this->encoding.len);
+	}
+
 	while (this->offset < this->encoding.len)
 	{
 		switch (process_tnc_msg(this))
@@ -585,7 +600,7 @@ pb_tnc_batch_t* pb_tnc_batch_create(bool is_server, pb_tnc_batch_type_t type,
 /**
  * See header
  */
-pb_tnc_batch_t* pb_tnc_batch_create_from_data(bool is_server, chunk_t data)
+pb_tnc_batch_t* pb_tnc_batch_create_from_data(chunk_t data)
 {
 	private_pb_tnc_batch_t *this;
 
@@ -595,12 +610,12 @@ pb_tnc_batch_t* pb_tnc_batch_create_from_data(bool is_server, chunk_t data)
 			.get_encoding = _get_encoding,
 			.add_msg = _add_msg,
 			.build = _build,
+			.process_header = _process_header,
 			.process = _process,
 			.create_msg_enumerator = _create_msg_enumerator,
 			.create_error_enumerator = _create_error_enumerator,
 			.destroy = _destroy,
 		},
-		.is_server = is_server,
 		.messages = linked_list_create(),
 		.errors = linked_list_create(),
 		.encoding = chunk_clone(data),
diff --git a/src/libtnccs/plugins/tnccs_20/batch/pb_tnc_batch.h b/src/libtnccs/plugins/tnccs_20/batch/pb_tnc_batch.h
index 106c557..6089c7d 100644
--- a/src/libtnccs/plugins/tnccs_20/batch/pb_tnc_batch.h
+++ b/src/libtnccs/plugins/tnccs_20/batch/pb_tnc_batch.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2010-2012 Andreas Steffen
+ * Copyright (C) 2010-2015 Andreas Steffen
  * HSR Hochschule fuer Technik Rapperswil
  *
  * This program is free software; you can redistribute it and/or modify it
@@ -84,10 +84,21 @@ struct pb_tnc_batch_t {
 	void (*build)(pb_tnc_batch_t *this);
 
 	/**
+	 * Process the PB-TNC Batch header
+	 *
+	 * @param directionality	TRUE if no mutual TNC measurements
+	 * @param is_server			TRUE if called by TNC server
+	 * @param from_server		TRUE if sent by TNC server
+	 * @return					return processing status
+	 */
+	status_t (*process_header)(pb_tnc_batch_t *this, bool directionality,
+							   bool is_server, bool *from_server);
+
+	/**
 	 * Process the PB-TNC Batch
 	 *
-	 * @param				PB-TNC state machine
-	 * @return				return processing status
+	 * @param state_machine		PB-TNC state machine
+	 * @return					return processing status
 	 */
 	status_t (*process)(pb_tnc_batch_t *this,
 						pb_tnc_state_machine_t *state_machine);
@@ -95,14 +106,14 @@ struct pb_tnc_batch_t {
 	/**
 	 * Enumerates over all PB-TNC Messages
 	 *
-	 * @return				return message enumerator
+	 * @return					return message enumerator
 	 */
 	enumerator_t* (*create_msg_enumerator)(pb_tnc_batch_t *this);
 
 	/**
 	 * Enumerates over all parsing errors
 	 *
-	 * @return				return error enumerator
+	 * @return					return error enumerator
 	 */
 	enumerator_t* (*create_error_enumerator)(pb_tnc_batch_t *this);
 
@@ -115,9 +126,9 @@ struct pb_tnc_batch_t {
 /**
  * Create an empty PB-TNC Batch of a given type
  *
- * @param is_server			TRUE if server, FALSE if client
- * @param type				PB-TNC batch type
- * @param max_batch_len		maximum size the PB-TNC batch
+ * @param is_server				TRUE if server, FALSE if client
+ * @param type					PB-TNC batch type
+ * @param max_batch_len			maximum size the PB-TNC batch
  */
 pb_tnc_batch_t* pb_tnc_batch_create(bool is_server, pb_tnc_batch_type_t type,
 									size_t max_batch_len);
@@ -125,9 +136,8 @@ pb_tnc_batch_t* pb_tnc_batch_create(bool is_server, pb_tnc_batch_type_t type,
 /**
  * Create an unprocessed PB-TNC Batch from data
  *
- * @param is_server			TRUE if server, FALSE if client
  * @param  data				encoded PB-TNC batch
  */
-pb_tnc_batch_t* pb_tnc_batch_create_from_data(bool is_server, chunk_t data);
+pb_tnc_batch_t* pb_tnc_batch_create_from_data(chunk_t data);
 
 #endif /** PB_TNC_BATCH_H_ @}*/
diff --git a/src/libtnccs/plugins/tnccs_20/messages/ita/pb_mutual_capability_msg.c b/src/libtnccs/plugins/tnccs_20/messages/ita/pb_mutual_capability_msg.c
new file mode 100644
index 0000000..1f35cae
--- /dev/null
+++ b/src/libtnccs/plugins/tnccs_20/messages/ita/pb_mutual_capability_msg.c
@@ -0,0 +1,174 @@
+/*
+ * Copyright (C) 2015 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 "pb_mutual_capability_msg.h"
+
+#include <bio/bio_writer.h>
+#include <bio/bio_reader.h>
+#include <utils/debug.h>
+
+ENUM(pb_tnc_mutual_protocol_type_names, PB_MUTUAL_HALF_DUPLEX,
+										PB_MUTUAL_FULL_DUPLEX,
+	"half duplex",
+	"full duplex"
+);
+
+typedef struct private_pb_mutual_capability_msg_t private_pb_mutual_capability_msg_t;
+
+/**
+ *   PB-Mutual-Capability message
+ *
+ *    0                   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
+ *   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ *   |H|F|                      Reserved                             |
+ *   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ */
+
+# define MUTUAL_CAPABILITY_HEADER_SIZE		4
+
+/**
+ * Private data of a pb_mutual_capability_msg_t object.
+ *
+ */
+struct private_pb_mutual_capability_msg_t {
+	/**
+	 * Public pb_mutual_capability_msg_t interface.
+	 */
+	pb_mutual_capability_msg_t public;
+
+	/**
+	 * PB-TNC message type
+	 */
+	pen_type_t type;
+
+	/**
+	 * PB-TNC mutual protocols
+	 */
+	uint32_t protocols;
+
+	/**
+	 * Encoded message
+	 */
+	chunk_t encoding;
+};
+
+METHOD(pb_tnc_msg_t, get_type, pen_type_t,
+	private_pb_mutual_capability_msg_t *this)
+{
+	return this->type;
+}
+
+METHOD(pb_tnc_msg_t, get_encoding, chunk_t,
+	private_pb_mutual_capability_msg_t *this)
+{
+	return this->encoding;
+}
+
+METHOD(pb_tnc_msg_t, build, void,
+	private_pb_mutual_capability_msg_t *this)
+{
+	bio_writer_t *writer;
+
+	if (this->encoding.ptr)
+	{
+		return;
+	}
+	writer = bio_writer_create(MUTUAL_CAPABILITY_HEADER_SIZE);
+	writer->write_uint32(writer, this->protocols);
+
+	this->encoding = writer->get_buf(writer);
+	this->encoding = chunk_clone(this->encoding);
+	writer->destroy(writer);
+}
+
+METHOD(pb_tnc_msg_t, process, status_t,
+	private_pb_mutual_capability_msg_t *this, u_int32_t *offset)
+{
+	bio_reader_t *reader;
+
+	*offset = 0;
+
+	/* process message */
+	reader = bio_reader_create(this->encoding);
+	reader->read_uint32(reader, &this->protocols);
+	reader->destroy(reader);
+
+	return SUCCESS;
+}
+
+METHOD(pb_tnc_msg_t, destroy, void,
+	private_pb_mutual_capability_msg_t *this)
+{
+	free(this->encoding.ptr);
+	free(this);
+}
+
+METHOD(pb_mutual_capability_msg_t, get_protocols, uint32_t,
+	private_pb_mutual_capability_msg_t *this)
+{
+	return this->protocols;
+}
+
+/**
+ * See header
+ */
+pb_tnc_msg_t* pb_mutual_capability_msg_create(uint32_t protocols)
+{
+	private_pb_mutual_capability_msg_t *this;
+
+	INIT(this,
+		.public = {
+			.pb_interface = {
+				.get_type = _get_type,
+				.get_encoding = _get_encoding,
+				.build = _build,
+				.process = _process,
+				.destroy = _destroy,
+			},
+			.get_protocols = _get_protocols,
+		},
+		.type = { PEN_ITA, PB_ITA_MSG_MUTUAL_CAPABILITY },
+		.protocols = protocols,
+	);
+
+	return &this->public.pb_interface;
+}
+
+/**
+ * See header
+ */
+pb_tnc_msg_t *pb_mutual_capability_msg_create_from_data(chunk_t data)
+{
+	private_pb_mutual_capability_msg_t *this;
+
+	INIT(this,
+		.public = {
+			.pb_interface = {
+				.get_type = _get_type,
+				.get_encoding = _get_encoding,
+				.build = _build,
+				.process = _process,
+				.destroy = _destroy,
+			},
+			.get_protocols = _get_protocols,
+		},
+		.type = { PEN_ITA, PB_ITA_MSG_MUTUAL_CAPABILITY },
+		.encoding = chunk_clone(data),
+	);
+
+	return &this->public.pb_interface;
+}
+
diff --git a/src/libtnccs/plugins/tnccs_20/messages/ita/pb_mutual_capability_msg.h b/src/libtnccs/plugins/tnccs_20/messages/ita/pb_mutual_capability_msg.h
new file mode 100644
index 0000000..db810a0
--- /dev/null
+++ b/src/libtnccs/plugins/tnccs_20/messages/ita/pb_mutual_capability_msg.h
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 2015 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 pb_mutual_capability_msg pb_mutual_capability_msg
+ * @{ @ingroup tnccs_20
+ */
+
+#ifndef PB_MUTUAL_CAPABILITY_MSG_H_
+#define PB_MUTUAL_CAPABILITY_MSG_H_
+
+typedef enum pb_tnc_mutual_protocol_type_t pb_tnc_mutual_protocol_type_t;
+typedef struct pb_mutual_capability_msg_t pb_mutual_capability_msg_t;
+
+#include "messages/pb_tnc_msg.h"
+
+/**
+ * PB-TNC mutual protocol types
+ */
+enum pb_tnc_mutual_protocol_type_t {
+	PB_MUTUAL_HALF_DUPLEX =	(1 << 31),
+	PB_MUTUAL_FULL_DUPLEX =	(1 << 30)
+};
+
+/**
+ * enum name for pb_mutual_protocol_type_t.
+ */
+extern enum_name_t *pb_tnc_mutual_protocol_type_names;
+
+/**
+ * Class representing the PB-Mutual-Capabilities message type.
+ */
+struct pb_mutual_capability_msg_t {
+
+	/**
+	 * PB-TNC Message interface
+	 */
+	pb_tnc_msg_t pb_interface;
+
+	/**
+	 * Get the PB-TNC mutual protocol types
+	 *
+	 * @return				PB-TNC mutual protocol types
+	 */
+	uint32_t(*get_protocols)(pb_mutual_capability_msg_t *this);
+
+};
+
+/**
+ * Create a PB-Mutual-Capability message
+ *
+ * @param protocols			Supported PB-TNC mutual protocols
+ */
+pb_tnc_msg_t* pb_mutual_capability_msg_create(uint32_t protocols);
+
+/**
+ * Create an unprocessed PB-Mutual-Capability message from raw data
+ *
+  * @param data		PB-Mutual-Capability message data
+ */
+pb_tnc_msg_t* pb_mutual_capability_msg_create_from_data(chunk_t data);
+
+#endif /** PB_MUTUAL_CAPABILITY_MSG_ @}*/
diff --git a/src/libtnccs/plugins/tnccs_20/messages/ita/pb_noskip_test_msg.c b/src/libtnccs/plugins/tnccs_20/messages/ita/pb_noskip_test_msg.c
new file mode 100644
index 0000000..c95222e
--- /dev/null
+++ b/src/libtnccs/plugins/tnccs_20/messages/ita/pb_noskip_test_msg.c
@@ -0,0 +1,92 @@
+/*
+ * Copyright (C) 2015 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 "pb_noskip_test_msg.h"
+
+typedef struct private_pb_noskip_test_msg_t private_pb_noskip_test_msg_t;
+
+/**
+ * Private data of a pb_noskip_test_msg_t object.
+ *
+ */
+struct private_pb_noskip_test_msg_t {
+	/**
+	 * Public pb_noskip_test_msg_t interface.
+	 */
+	pb_noskip_test_msg_t public;
+
+	/**
+	 * PB-TNC message type
+	 */
+	pen_type_t type;
+
+	/**
+	 * Encoded message
+	 */
+	chunk_t encoding;
+};
+
+METHOD(pb_tnc_msg_t, get_type, pen_type_t,
+	private_pb_noskip_test_msg_t *this)
+{
+	return this->type;
+}
+
+METHOD(pb_tnc_msg_t, get_encoding, chunk_t,
+	private_pb_noskip_test_msg_t *this)
+{
+	return this->encoding;
+}
+
+METHOD(pb_tnc_msg_t, build, void,
+	private_pb_noskip_test_msg_t *this)
+{
+	/* nothing to do since the message is empty */
+}
+
+METHOD(pb_tnc_msg_t, process, status_t,
+	private_pb_noskip_test_msg_t *this, u_int32_t *offset)
+{
+	return SUCCESS;
+}
+
+METHOD(pb_tnc_msg_t, destroy, void,
+	private_pb_noskip_test_msg_t *this)
+{
+	free(this);
+}
+
+/**
+ * See header
+ */
+pb_tnc_msg_t *pb_noskip_test_msg_create(void)
+{
+	private_pb_noskip_test_msg_t *this;
+
+	INIT(this,
+		.public = {
+			.pb_interface = {
+				.get_type = _get_type,
+				.get_encoding = _get_encoding,
+				.build = _build,
+				.process = _process,
+				.destroy = _destroy,
+			},
+		},
+		.type = { PEN_ITA, PB_ITA_MSG_NOSKIP_TEST },
+	);
+
+	return &this->public.pb_interface;
+}
diff --git a/src/libtnccs/plugins/tnccs_20/messages/ita/pb_noskip_test_msg.h b/src/libtnccs/plugins/tnccs_20/messages/ita/pb_noskip_test_msg.h
new file mode 100644
index 0000000..6325582
--- /dev/null
+++ b/src/libtnccs/plugins/tnccs_20/messages/ita/pb_noskip_test_msg.h
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2015 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 pb_noskip_test_msg pb_noskip_test_msg
+ * @{ @ingroup tnccs_20
+ */
+
+#ifndef PB_NOSKIP_TEST_MSG_H_
+#define PB_NOSKIP_TEST_MSG_H_
+
+typedef struct pb_noskip_test_msg_t pb_noskip_test_msg_t;
+
+#include "messages/pb_tnc_msg.h"
+
+/**
+ * Class representing the PB-Noskip-Test message type.
+ */
+struct pb_noskip_test_msg_t {
+
+	/**
+	 * PB-TNC Message interface
+	 */
+	pb_tnc_msg_t pb_interface;
+};
+
+/**
+ * Create a PB-Noskip-Test message from parameters
+ */
+pb_tnc_msg_t* pb_noskip_test_msg_create(void);
+
+#endif /** PB_NOSKIP_TEST_MSG_H_ @}*/
diff --git a/src/libtnccs/plugins/tnccs_20/messages/pb_tnc_msg.c b/src/libtnccs/plugins/tnccs_20/messages/pb_tnc_msg.c
index ec43490..b46c776 100644
--- a/src/libtnccs/plugins/tnccs_20/messages/pb_tnc_msg.c
+++ b/src/libtnccs/plugins/tnccs_20/messages/pb_tnc_msg.c
@@ -22,6 +22,7 @@
 #include "ietf/pb_access_recommendation_msg.h"
 #include "ietf/pb_remediation_parameters_msg.h"
 #include "ietf/pb_reason_string_msg.h"
+#include "ita/pb_mutual_capability_msg.h"
 #include "tcg/pb_pdp_referral_msg.h"
 
 #include <library.h>
@@ -37,10 +38,17 @@ ENUM(pb_tnc_msg_type_names, PB_MSG_EXPERIMENTAL, PB_MSG_REASON_STRING,
 	"PB-Reason-String"
 );
 
-ENUM(pb_tnc_tcg_msg_type_names, PB_TCG_MSG_PDP_REFERRAL, PB_TCG_MSG_PDP_REFERRAL,
+ENUM(pb_tnc_tcg_msg_type_names, PB_TCG_MSG_PDP_REFERRAL,
+								PB_TCG_MSG_PDP_REFERRAL,
 	"PB-PDP-Referral"
 );
 
+ENUM(pb_tnc_ita_msg_type_names, PB_ITA_MSG_NOSKIP_TEST,
+								PB_ITA_MSG_MUTUAL_CAPABILITY,
+	"PB-Noskip-Test",
+	"PB-Mutual-Capability"
+);
+
 pb_tnc_msg_info_t pb_tnc_msg_infos[] = {
 	{ 12, FALSE, FALSE, TRUE_OR_FALSE },
 	{ 24, FALSE, FALSE, TRUE  },
@@ -57,6 +65,11 @@ pb_tnc_msg_info_t pb_tnc_tcg_msg_infos[] = {
 	{ 20, FALSE, FALSE,  FALSE },
 };
 
+pb_tnc_msg_info_t pb_tnc_ita_msg_infos[] = {
+	{ 12, TRUE,  FALSE,  TRUE  },
+	{ 16, FALSE, FALSE,  FALSE },
+};
+
 /**
  * See header
  */
@@ -91,5 +104,12 @@ pb_tnc_msg_t* pb_tnc_msg_create_from_data(pen_type_t msg_type, chunk_t value)
 			return pb_pdp_referral_msg_create_from_data(value);
 		}
 	}
+	else if (msg_type.vendor_id == PEN_ITA)
+	{
+		if (msg_type.type == PB_ITA_MSG_MUTUAL_CAPABILITY)
+		{
+			return pb_mutual_capability_msg_create_from_data(value);
+		}
+	}
 	return NULL;
 }
diff --git a/src/libtnccs/plugins/tnccs_20/messages/pb_tnc_msg.h b/src/libtnccs/plugins/tnccs_20/messages/pb_tnc_msg.h
index 6eeed51..35b0b7c 100644
--- a/src/libtnccs/plugins/tnccs_20/messages/pb_tnc_msg.h
+++ b/src/libtnccs/plugins/tnccs_20/messages/pb_tnc_msg.h
@@ -54,6 +54,7 @@ extern enum_name_t *pb_tnc_msg_type_names;
  * PB-TNC Message Type defined in the TCG namespace
  */
 enum pb_tnc_tcg_msg_type_t {
+	PB_TCG_MSG_RESERVED =				0,
 	PB_TCG_MSG_PDP_REFERRAL =			1,
 	PB_TCG_MSG_ROOF =					1
 };
@@ -64,6 +65,20 @@ enum pb_tnc_tcg_msg_type_t {
 extern enum_name_t *pb_tnc_tcg_msg_type_names;
 
 /**
+ * PB-TNC Message Type defined in the ITA namespace
+ */
+enum pb_tnc_ita_msg_type_t {
+	PB_ITA_MSG_NOSKIP_TEST =			0,
+	PB_ITA_MSG_MUTUAL_CAPABILITY =		1,
+	PB_ITA_MSG_ROOF =					1
+};
+
+/**
+ * enum name for pb_tnc_tcg_msg_type_t.
+ */
+extern enum_name_t *pb_tnc_ita_msg_type_names;
+
+/**
  * Information entry describing a PB-TNC Message Type
  */
 struct pb_tnc_msg_info_t {
@@ -86,6 +101,11 @@ extern pb_tnc_msg_info_t pb_tnc_msg_infos[];
 extern pb_tnc_msg_info_t pb_tnc_tcg_msg_infos[];
 
 /**
+ * Information on PB-TNC ITA Message Types
+ */
+extern pb_tnc_msg_info_t pb_tnc_ita_msg_infos[];
+
+/**
  * Generic interface for all PB-TNC message types.
  *
  * To handle all messages in a generic way, this interface
diff --git a/src/libtnccs/plugins/tnccs_20/tnccs_20.c b/src/libtnccs/plugins/tnccs_20/tnccs_20.c
index dc4da51..a1a9573 100644
--- a/src/libtnccs/plugins/tnccs_20/tnccs_20.c
+++ b/src/libtnccs/plugins/tnccs_20/tnccs_20.c
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 2010 Sansar Choinyanbuu
- * Copyright (C) 2010-2013 Andreas Steffen
+ * Copyright (C) 2010-2015 Andreas Steffen
  * HSR Hochschule fuer Technik Rapperswil
  *
  * This program is free software; you can redistribute it and/or modify it
@@ -15,30 +15,17 @@
  */
 
 #include "tnccs_20.h"
+#include "tnccs_20_handler.h"
+#include "tnccs_20_server.h"
+#include "tnccs_20_client.h"
 #include "batch/pb_tnc_batch.h"
 #include "messages/pb_tnc_msg.h"
 #include "messages/ietf/pb_pa_msg.h"
-#include "messages/ietf/pb_error_msg.h"
-#include "messages/ietf/pb_assessment_result_msg.h"
-#include "messages/ietf/pb_access_recommendation_msg.h"
-#include "messages/ietf/pb_remediation_parameters_msg.h"
-#include "messages/ietf/pb_reason_string_msg.h"
-#include "messages/ietf/pb_language_preference_msg.h"
-#include "messages/tcg/pb_pdp_referral_msg.h"
-#include "state_machine/pb_tnc_state_machine.h"
 
 #include <tncif_names.h>
 #include <tncif_pa_subtypes.h>
 
-#include <tnc/tnc.h>
-#include <tnc/tnccs/tnccs_manager.h>
-#include <tnc/imc/imc_manager.h>
-#include <tnc/imv/imv_manager.h>
-
-#include <threading/mutex.h>
 #include <utils/debug.h>
-#include <collections/linked_list.h>
-#include <pen/pen.h>
 
 typedef struct private_tnccs_20_t private_tnccs_20_t;
 
@@ -60,77 +47,72 @@ struct private_tnccs_20_t {
 	/**
 	 * Server identity
 	 */
-	identification_t *server;
+	identification_t *server_id;
 
 	/**
 	 * Client identity
 	 */
-	identification_t *peer;
+	identification_t *peer_id;
 
 	/**
-	 * Underlying TNC IF-T transport protocol
+	 * Server IP address
 	 */
-	tnc_ift_type_t transport;
+	host_t *server_ip;
 
 	/**
-	 * Type of TNC client authentication
+	 * Client IP address
 	 */
-	u_int32_t auth_type;
+	host_t *peer_ip;
 
 	/**
-	 * PB-TNC State Machine
+	 * Underlying TNC IF-T transport protocol
 	 */
-	pb_tnc_state_machine_t *state_machine;
+	tnc_ift_type_t transport;
 
 	/**
-	 * Connection ID assigned to this TNCCS connection
+	 *  TNC IF-T transport protocol for EAP methods
 	 */
-	TNC_ConnectionID connection_id;
+	bool eap_transport;
 
 	/**
-	 * PB-TNC messages to be sent
+	 * Type of TNC client authentication
 	 */
-	linked_list_t *messages;
+	u_int32_t auth_type;
 
 	/**
-	 * Type of PB-TNC batch being constructed
+	 * Mutual PB-TNC protocol enabled
 	 */
-	pb_tnc_batch_type_t batch_type;
+	bool mutual;
 
 	/**
-	 * Maximum PB-TNC batch size
+	 * Direction the next batch will go to
 	 */
-	size_t max_batch_len;
+	bool to_server;
 
 	/**
-	 * Maximum PA-TNC message size
+	 * TNC Server
 	 */
-	size_t max_msg_len;
+	tnccs_20_handler_t *tnc_server;
 
 	/**
-	 * Mutex locking the batch in construction
+	 * TNC Client
 	 */
-	mutex_t *mutex;
+	tnccs_20_handler_t *tnc_client;
 
 	/**
-	 * Flag set while processing
+	 * Active TNCSS handler
 	 */
-	bool fatal_error;
+	tnccs_20_handler_t *tnccs_handler;
 
 	/**
-	 * Flag set by IMC/IMV RequestHandshakeRetry() function
+	 * Maximum PB-TNC batch size
 	 */
-	bool request_handshake_retry;
-
-	/**
-	  * SendMessage() by IMC/IMV only allowed if flag is set
-	  */
-	bool send_msg;
+	size_t max_batch_len;
 
 	/**
-	 * Set of IMV recommendations  (TNC Server only)
+	 * Maximum PA-TNC message size
 	 */
-	recommendations_t *recs;
+	size_t max_msg_len;
 
 	/**
 	 * Callback function to communicate recommendation (TNC Server only)
@@ -138,69 +120,30 @@ struct private_tnccs_20_t {
 	tnccs_cb_t callback;
 
 	/**
-	 * Data to pass to callback function (TNC Server only)
-	 */
-	void *cb_data;
-
-	/**
-	 * PDP server FQDN
-	 */
-	chunk_t pdp_server;
-
-	/**
-	 * PDP server port
-	 */
-	u_int16_t pdp_port;
-
-	/**
 	 * reference count
 	 */
 	refcount_t ref;
 
 };
 
-/**
- * If the batch type changes then delete all accumulated PB-TNC messages
- */
-void change_batch_type(private_tnccs_20_t *this, pb_tnc_batch_type_t batch_type)
-{
-	pb_tnc_msg_t *msg;
-
-	if (batch_type != this->batch_type)
-	{
-		if (this->batch_type != PB_BATCH_NONE)
-		{
-			DBG1(DBG_TNC, "cancelling PB-TNC %N batch",
-				 pb_tnc_batch_type_names, this->batch_type);
-
-			while (this->messages->remove_last(this->messages,
-											  (void**)&msg) == SUCCESS)
-			{
-				msg->destroy(msg);
-			}
-		}
-		this->batch_type = batch_type;
-	}
-}
-
 METHOD(tnccs_t, send_msg, TNC_Result,
 	private_tnccs_20_t* this, TNC_IMCID imc_id, TNC_IMVID imv_id,
-						      TNC_UInt32 msg_flags,
+							  TNC_UInt32 msg_flags,
 							  TNC_BufferReference msg,
 							  TNC_UInt32 msg_len,
-						      TNC_VendorID msg_vid,
-						      TNC_MessageSubtype msg_subtype)
+							  TNC_VendorID msg_vid,
+							  TNC_MessageSubtype msg_subtype)
 {
 	pb_tnc_msg_t *pb_tnc_msg;
-	pb_tnc_batch_type_t batch_type;
 	enum_name_t *pa_subtype_names;
 	bool excl;
 
-	if (!this->send_msg)
+	if (!this->tnccs_handler->get_send_flag(this->tnccs_handler))
 	{
 		DBG1(DBG_TNC, "%s %u not allowed to call SendMessage()",
-			this->is_server ? "IMV" : "IMC",
-			this->is_server ? imv_id : imc_id);
+					   this->to_server ? "IMC" : "IMV",
+					   this->to_server ? imc_id : imv_id);
+
 		return TNC_RESULT_ILLEGAL_OPERATION;
 	}
 	excl = (msg_flags & TNC_MESSAGE_FLAGS_EXCLUSIVE) != 0;
@@ -220,698 +163,169 @@ METHOD(tnccs_t, send_msg, TNC_Result,
 		DBG2(DBG_TNC, "creating PB-PA message type '%N' 0x%06x/0x%08x",
 					   pen_names, msg_vid, msg_vid, msg_subtype);
 	}
+	this->tnccs_handler->add_msg(this->tnccs_handler, pb_tnc_msg);
 
-	/* adding PA message to SDATA or CDATA batch only */
-	batch_type = this->is_server ? PB_BATCH_SDATA : PB_BATCH_CDATA;
-	this->mutex->lock(this->mutex);
-	if (this->batch_type == PB_BATCH_NONE)
-	{
-		this->batch_type = batch_type;
-	}
-	if (this->batch_type == batch_type)
-	{
-		this->messages->insert_last(this->messages, pb_tnc_msg);
-	}
-	else
-	{
-		pb_tnc_msg->destroy(pb_tnc_msg);
-	}
-	this->mutex->unlock(this->mutex);
 	return TNC_RESULT_SUCCESS;
 }
 
-/**
- * Handle a single PB-TNC IETF standard message according to its type
- */
-static void handle_ietf_message(private_tnccs_20_t *this, pb_tnc_msg_t *msg)
-{
-	pen_type_t msg_type = msg->get_type(msg);
-
-	switch (msg_type.type)
-	{
-		case PB_MSG_EXPERIMENTAL:
-			/* nothing to do */
-			break;
-		case PB_MSG_PA:
-		{
-			pb_pa_msg_t *pa_msg;
-			pen_type_t msg_subtype;
-			u_int16_t imc_id, imv_id;
-			chunk_t msg_body;
-			bool excl;
-			enum_name_t *pa_subtype_names;
-
-			pa_msg = (pb_pa_msg_t*)msg;
-			msg_subtype = pa_msg->get_subtype(pa_msg);
-			msg_body = pa_msg->get_body(pa_msg);
-			imc_id = pa_msg->get_collector_id(pa_msg);
-			imv_id = pa_msg->get_validator_id(pa_msg);
-			excl = pa_msg->get_exclusive_flag(pa_msg);
-
-			pa_subtype_names = get_pa_subtype_names(msg_subtype.vendor_id);
-			if (pa_subtype_names)
-			{
-				DBG2(DBG_TNC, "handling PB-PA message type '%N/%N' 0x%06x/0x%08x",
-					 pen_names, msg_subtype.vendor_id, pa_subtype_names,
-					 msg_subtype.type, msg_subtype.vendor_id, msg_subtype.type);
-			}
-			else
-			{
-				DBG2(DBG_TNC, "handling PB-PA message type '%N' 0x%06x/0x%08x",
-					 pen_names, msg_subtype.vendor_id, msg_subtype.vendor_id,
-					 msg_subtype.type);
-			}
-
-			this->send_msg = TRUE;
-			if (this->is_server)
-			{
-				tnc->imvs->receive_message(tnc->imvs, this->connection_id,
-										   excl, msg_body.ptr, msg_body.len,
-										   msg_subtype.vendor_id,
-										   msg_subtype.type, imc_id, imv_id);
-			}
-			else
-			{
-				tnc->imcs->receive_message(tnc->imcs, this->connection_id,
-										   excl, msg_body.ptr, msg_body.len,
-										   msg_subtype.vendor_id,
-										   msg_subtype.type, imv_id, imc_id);
-			}
-			this->send_msg = FALSE;
-			break;
-		}
-		case PB_MSG_ASSESSMENT_RESULT:
-		{
-			pb_assessment_result_msg_t *assess_msg;
-			u_int32_t result;
-
-			assess_msg = (pb_assessment_result_msg_t*)msg;
-			result = assess_msg->get_assessment_result(assess_msg);
-			DBG1(DBG_TNC, "PB-TNC assessment result is '%N'",
-				 TNC_IMV_Evaluation_Result_names, result);
-			break;
-		}
-		case PB_MSG_ACCESS_RECOMMENDATION:
-		{
-			pb_access_recommendation_msg_t *rec_msg;
-			pb_access_recommendation_code_t rec;
-			TNC_ConnectionState state = TNC_CONNECTION_STATE_ACCESS_NONE;
-
-			rec_msg = (pb_access_recommendation_msg_t*)msg;
-			rec = rec_msg->get_access_recommendation(rec_msg);
-			DBG1(DBG_TNC, "PB-TNC access recommendation is '%N'",
-						   pb_access_recommendation_code_names, rec);
-			switch (rec)
-			{
-				case PB_REC_ACCESS_ALLOWED:
-					state = TNC_CONNECTION_STATE_ACCESS_ALLOWED;
-					break;
-				case PB_REC_ACCESS_DENIED:
-					state = TNC_CONNECTION_STATE_ACCESS_NONE;
-					break;
-				case PB_REC_QUARANTINED:
-					state = TNC_CONNECTION_STATE_ACCESS_ISOLATED;
-			}
-			tnc->imcs->notify_connection_change(tnc->imcs, this->connection_id,
-												state);
-			break;
-		}
-		case PB_MSG_REMEDIATION_PARAMETERS:
-		{
-			pb_remediation_parameters_msg_t *rem_msg;
-			pen_type_t parameters_type;
-			chunk_t parameters, string, lang_code;
-
-			rem_msg = (pb_remediation_parameters_msg_t*)msg;
-			parameters_type = rem_msg->get_parameters_type(rem_msg);
-			parameters = rem_msg->get_parameters(rem_msg);
-
-			if (parameters_type.vendor_id == PEN_IETF)
-			{
-				switch (parameters_type.type)
-				{
-					case PB_REMEDIATION_URI:
-						DBG1(DBG_TNC, "remediation uri: %.*s",
-									   parameters.len, parameters.ptr);
-						break;
-					case PB_REMEDIATION_STRING:
-						string = rem_msg->get_string(rem_msg, &lang_code);
-						DBG1(DBG_TNC, "remediation string: [%.*s]\n%.*s",
-									   lang_code.len, lang_code.ptr,
-									   string.len, string.ptr);
-						break;
-					default:
-						DBG1(DBG_TNC, "remediation parameters: %B", &parameters);
-				}
-			}
-			else
-			{
-				DBG1(DBG_TNC, "remediation parameters: %B", &parameters);
-			}
-			break;
-		}
-		case PB_MSG_ERROR:
-		{
-			pb_error_msg_t *err_msg;
-			bool fatal;
-			u_int32_t vendor_id;
-			u_int16_t error_code;
-
-			err_msg = (pb_error_msg_t*)msg;
-			fatal = err_msg->get_fatal_flag(err_msg);
-			vendor_id = err_msg->get_vendor_id(err_msg);
-			error_code = err_msg->get_error_code(err_msg);
-
-			if (fatal)
-			{
-				this->fatal_error = TRUE;
-			}
-
-			if (vendor_id == PEN_IETF)
-			{
-				switch (error_code)
-				{
-					case PB_ERROR_INVALID_PARAMETER:
-					case PB_ERROR_UNSUPPORTED_MANDATORY_MSG:
-						DBG1(DBG_TNC, "received %s PB-TNC error '%N' "
-									  "(offset %u bytes)",
-									  fatal ? "fatal" : "non-fatal",
-									  pb_tnc_error_code_names, error_code,
-									  err_msg->get_offset(err_msg));
-						break;
-					case PB_ERROR_VERSION_NOT_SUPPORTED:
-						DBG1(DBG_TNC, "received %s PB-TNC error '%N' "
-									  "caused by bad version 0x%02x",
-									  fatal ? "fatal" : "non-fatal",
-									  pb_tnc_error_code_names, error_code,
-									  err_msg->get_bad_version(err_msg));
-						break;
-					case PB_ERROR_UNEXPECTED_BATCH_TYPE:
-					case PB_ERROR_LOCAL_ERROR:
-					default:
-						DBG1(DBG_TNC, "received %s PB-TNC error '%N'",
-									  fatal ? "fatal" : "non-fatal",
-									  pb_tnc_error_code_names, error_code);
-						break;
-				}
-			}
-			else
-			{
-				DBG1(DBG_TNC, "received %s PB-TNC error (%u) "
-							  "with Vendor ID 0x%06x",
-							  fatal ? "fatal" : "non-fatal",
-							  error_code, vendor_id);
-			}
-			break;
-		}
-		case PB_MSG_LANGUAGE_PREFERENCE:
-		{
-			pb_language_preference_msg_t *lang_msg;
-			chunk_t lang;
-
-			lang_msg = (pb_language_preference_msg_t*)msg;
-			lang = lang_msg->get_language_preference(lang_msg);
-
-			if (this->recs)
-			{
-				DBG2(DBG_TNC, "setting language preference to '%.*s'",
-					 (int)lang.len, lang.ptr);
-				this->recs->set_preferred_language(this->recs, lang);
-			}
-			break;
-		}
-		case PB_MSG_REASON_STRING:
-		{
-			pb_reason_string_msg_t *reason_msg;
-			chunk_t reason_string, language_code;
-
-			reason_msg = (pb_reason_string_msg_t*)msg;
-			reason_string = reason_msg->get_reason_string(reason_msg);
-			language_code = reason_msg->get_language_code(reason_msg);
-			DBG1(DBG_TNC, "reason string is '%.*s' [%.*s]",
-				 (int)reason_string.len, reason_string.ptr,
-				 (int)language_code.len, language_code.ptr);
-			break;
-		}
-		default:
-			break;
-	}
-}
-
-/**
- * Handle a single PB-TNC TCG standard message according to its type
- */
-static void handle_tcg_message(private_tnccs_20_t *this, pb_tnc_msg_t *msg)
-{
-	pen_type_t msg_type = msg->get_type(msg);
-
-	switch (msg_type.type)
-	{
-		case PB_TCG_MSG_PDP_REFERRAL:
-		{
-			pb_pdp_referral_msg_t *pdp_msg;
-			pen_type_t pdp_id_type;
-			u_int8_t pdp_protocol;
-
-			pdp_msg = (pb_pdp_referral_msg_t*)msg;
-			pdp_id_type = pdp_msg->get_identifier_type(pdp_msg);
-
-			if (pdp_id_type.vendor_id == PEN_TCG &&
-				pdp_id_type.type == PB_PDP_ID_FQDN)
-			{
-				this->pdp_server = chunk_clone(pdp_msg->get_fqdn(pdp_msg,
-										 &pdp_protocol, &this->pdp_port));
-				if (pdp_protocol != 0)
-				{
-					DBG1(DBG_TNC, "unsupported PDP transport protocol");
-					break;
-				}
-				DBG1(DBG_TNC, "PDP server '%.*s' is listening on port %u",
-							   this->pdp_server.len, this->pdp_server.ptr,
-							   this->pdp_port);
-			}
-			break;
-		}
-		default:
-			break;
-	}
-}
-
-/**
- * Handle a single PB-TNC message according to its type
- */
-static void handle_message(private_tnccs_20_t *this, pb_tnc_msg_t *msg)
-{
-	pen_type_t msg_type = msg->get_type(msg);
-
-	switch (msg_type.vendor_id)
-	{
-		case PEN_IETF:
-			handle_ietf_message(this, msg);
-			break;
-		case PEN_TCG:
-			handle_tcg_message(this, msg);
-			break;
-		default:
-			break;
-	}
-}
-
-/**
- *  Build a CRETRY or SRETRY batch
- */
-static void build_retry_batch(private_tnccs_20_t *this)
-{
-	pb_tnc_batch_type_t batch_retry_type;
-
-	batch_retry_type = this->is_server ? PB_BATCH_SRETRY : PB_BATCH_CRETRY;
-	if (this->batch_type == batch_retry_type)
-	{
-		/* retry batch has already been selected */
-		return;
-	}
-
-	change_batch_type(this, batch_retry_type);
-
-	if (this->is_server)
-	{
-		this->recs->clear_recommendation(this->recs);
-		tnc->imvs->notify_connection_change(tnc->imvs, this->connection_id,
-											TNC_CONNECTION_STATE_HANDSHAKE);
-	}
-}
-
 METHOD(tls_t, process, status_t,
 	private_tnccs_20_t *this, void *buf, size_t buflen)
 {
-	chunk_t data;
 	pb_tnc_batch_t *batch;
-	pb_tnc_msg_t *msg;
-	enumerator_t *enumerator;
-	identification_t *pdp_server;
-	u_int16_t *pdp_port;
+	bool from_server, fatal_header_error = FALSE;
 	status_t status;
+	chunk_t data;
 
-	if (this->is_server && !this->connection_id)
+	/* On arrival of first batch from TNC client create TNC server */
+	if (this->is_server && !this->tnc_server)
 	{
-		this->connection_id = tnc->tnccs->create_connection(tnc->tnccs,
-									TNCCS_2_0, (tnccs_t*)this, _send_msg,
-									&this->request_handshake_retry,
-									this->max_msg_len, &this->recs);
-		if (!this->connection_id)
+		this->tnc_server = tnccs_20_server_create(&this->public, _send_msg,
+									this->max_batch_len, this->max_msg_len,
+									this->eap_transport);
+		if (!this->tnc_server)
 		{
 			return FAILED;
 		}
-		tnc->imvs->notify_connection_change(tnc->imvs, this->connection_id,
-											TNC_CONNECTION_STATE_CREATE);
-		tnc->imvs->notify_connection_change(tnc->imvs, this->connection_id,
-											TNC_CONNECTION_STATE_HANDSHAKE);
-
-		/* Send a PB-TNC TCG PDP Referral message if PDP is known */
-		pdp_server = (identification_t*)lib->get(lib, "pt-tls-server");
-		pdp_port = (u_int16_t*)lib->get(lib, "pt-tls-port");
-
-		if ((this->transport ==	TNC_IFT_EAP_1_1 ||
-			 this->transport == TNC_IFT_EAP_2_0) &&	pdp_server && pdp_port)
-		{
-			msg = pb_pdp_referral_msg_create_from_fqdn(
-						pdp_server->get_encoding(pdp_server), *pdp_port);
-			this->messages->insert_last(this->messages, msg);
-		}
-
+		this->tnccs_handler = this->tnc_server;
+		this->tnccs_handler->begin_handshake(this->tnccs_handler, FALSE);
 	}
 
 	data = chunk_create(buf, buflen);
-	DBG1(DBG_TNC, "received TNCCS batch (%u bytes) for Connection ID %u",
-				   data.len, this->connection_id);
+	DBG1(DBG_TNC, "received TNCCS batch (%u bytes)", data.len);
 	DBG3(DBG_TNC, "%B", &data);
-	batch = pb_tnc_batch_create_from_data(this->is_server, data);
-	status = batch->process(batch, this->state_machine);
 
-	if (status != FAILED)
+	/* Parse the header of the received PB-TNC batch */
+	batch = pb_tnc_batch_create_from_data(data);
+	status = batch->process_header(batch, !this->mutual, this->is_server,
+								   &from_server);
+	if (status == FAILED)
 	{
-		enumerator_t *enumerator;
-		pb_tnc_msg_t *msg;
-		pb_tnc_batch_type_t batch_type;
-		bool empty = TRUE;
-
-		batch_type = batch->get_type(batch);
-
-		if (batch_type == PB_BATCH_CRETRY)
-		{
-			/* Send an SRETRY batch in response */
-			this->mutex->lock(this->mutex);
-			build_retry_batch(this);
-			this->mutex->unlock(this->mutex);
-		}
-		else if (batch_type == PB_BATCH_SRETRY)
-		{
-			/* Restart the measurements */
-			tnc->imcs->notify_connection_change(tnc->imcs,
-			this->connection_id, TNC_CONNECTION_STATE_HANDSHAKE);
-			this->send_msg = TRUE;
-			tnc->imcs->begin_handshake(tnc->imcs, this->connection_id);
-			this->send_msg = FALSE;
-		}
-
-		enumerator = batch->create_msg_enumerator(batch);
-		while (enumerator->enumerate(enumerator, &msg))
-		{
-			handle_message(this, msg);
-			empty = FALSE;
-		}
-		enumerator->destroy(enumerator);
+		fatal_header_error = TRUE;
+		status = VERIFY_ERROR;
+	}
+	this->to_server = this->mutual ? from_server : !this->is_server;
 
-		/* received an empty CLOSE batch from PB-TNC client */
-		if (this->is_server && batch_type == PB_BATCH_CLOSE && empty)
+	/* In the mutual case, first batch from TNC server requires a TNC client */
+	if (this->to_server && !this->tnc_client)
+	{
+		this->tnc_client = tnccs_20_client_create(&this->public, _send_msg,
+									this->max_batch_len, this->max_msg_len);
+		if (!this->tnc_client)
 		{
 			batch->destroy(batch);
-			if (this->fatal_error)
-			{
-				DBG1(DBG_TNC, "a fatal PB-TNC error occurred, "
-							  "terminating connection");
-				return FAILED;
-			}
-			else
-			{
-				return SUCCESS;
-			}
-		}
-
-		this->send_msg = TRUE;
-		if (this->is_server)
-		{
-			tnc->imvs->batch_ending(tnc->imvs, this->connection_id);
-		}
-		else
-		{
-			tnc->imcs->batch_ending(tnc->imcs, this->connection_id);
+			return FAILED;
 		}
-		this->send_msg = FALSE;
+		this->tnccs_handler = this->tnc_client;
+		this->tnccs_handler->begin_handshake(this->tnccs_handler, this->mutual);
 	}
+	else
+	{
+		/* Set active TNCCS handler for processing */
+		this->tnccs_handler = this->to_server ? this->tnc_client :
+												this->tnc_server;
+	}
+	DBG2(DBG_TNC, "TNC %s is handling inbound connection",
+				   this->to_server ? "client" : "server");
 
-	switch (status)
+	if (status == SUCCESS)
 	{
-		case FAILED:
-			this->fatal_error = TRUE;
-			this->mutex->lock(this->mutex);
-			change_batch_type(this, PB_BATCH_CLOSE);
-			this->mutex->unlock(this->mutex);
-			/* fall through to add error messages to outbound batch */
-		case VERIFY_ERROR:
-			enumerator = batch->create_error_enumerator(batch);
-			while (enumerator->enumerate(enumerator, &msg))
-			{
-				this->mutex->lock(this->mutex);
-				this->messages->insert_last(this->messages, msg->get_ref(msg));
-				this->mutex->unlock(this->mutex);
-			}
-			enumerator->destroy(enumerator);
-			break;
-		case SUCCESS:
-		default:
-			break;
+		status = this->tnccs_handler->process(this->tnccs_handler, batch);
+	}
+	if (status == VERIFY_ERROR)
+	{
+		this->tnccs_handler->handle_errors(this->tnccs_handler, batch,
+										   fatal_header_error);
+		status = NEED_MORE;
 	}
 	batch->destroy(batch);
 
-	return NEED_MORE;
-}
+	/* Has a mutual connection been established? */
+	this->mutual = this->is_server ?
+				   this->tnc_server->get_mutual(this->tnc_server) :
+				   this->tnc_client->get_mutual(this->tnc_client);
 
-/**
- *  Build a RESULT batch if a final recommendation is available
- */
-static void check_and_build_recommendation(private_tnccs_20_t *this)
-{
-	TNC_IMV_Action_Recommendation rec;
-	TNC_IMV_Evaluation_Result eval;
-	TNC_ConnectionState state;
-	TNC_IMVID id;
-	chunk_t reason, language;
-	enumerator_t *enumerator;
-	pb_tnc_msg_t *msg;
-	pb_access_recommendation_code_t pb_rec;
-
-	if (!this->recs->have_recommendation(this->recs, &rec, &eval))
-	{
-		tnc->imvs->solicit_recommendation(tnc->imvs, this->connection_id);
-	}
-	if (this->recs->have_recommendation(this->recs, &rec, &eval))
+	if (this->mutual && !this->is_server)
 	{
-		this->batch_type = PB_BATCH_RESULT;
+		pb_tnc_state_t client_state, server_state;
 
-		msg = pb_assessment_result_msg_create(eval);
-		this->messages->insert_last(this->messages, msg);
+		client_state = !this->tnc_client ? PB_STATE_INIT :
+						this->tnc_client->get_state(this->tnc_client);
+		server_state = !this->tnc_server ? PB_STATE_INIT :
+						this->tnc_server->get_state(this->tnc_server);
 
-		/**
-		 * Map IMV Action Recommendation codes to PB Access Recommendation codes
-		 * and communicate Access Recommendation to IMVs
-		 */
-		switch (rec)
+		/* In half-duplex mutual mode toggle the direction on the client side */
+		if ((!this->to_server && client_state != PB_STATE_DECIDED) ||
+			( this->to_server && server_state != PB_STATE_END))
 		{
-			case TNC_IMV_ACTION_RECOMMENDATION_ALLOW:
-				state = TNC_CONNECTION_STATE_ACCESS_ALLOWED;
-				pb_rec = PB_REC_ACCESS_ALLOWED;
-				break;
-			case TNC_IMV_ACTION_RECOMMENDATION_ISOLATE:
-				state = TNC_CONNECTION_STATE_ACCESS_ISOLATED;
-				pb_rec = PB_REC_QUARANTINED;
-				break;
-			case TNC_IMV_ACTION_RECOMMENDATION_NO_ACCESS:
-			case TNC_IMV_ACTION_RECOMMENDATION_NO_RECOMMENDATION:
-			default:
-				state = TNC_CONNECTION_STATE_ACCESS_NONE;
-				pb_rec = PB_REC_ACCESS_DENIED;
+			this->to_server = !this->to_server;
+		}
+		else if (client_state == PB_STATE_DECIDED &&
+				 server_state == PB_STATE_END)
+		{
+			/* Cause the final CLOSE batch to be sent to the TNC server */
+			this->to_server = TRUE;
 		}
-		tnc->imvs->notify_connection_change(tnc->imvs, this->connection_id,
-											state);
-
-		msg = pb_access_recommendation_msg_create(pb_rec);
-		this->messages->insert_last(this->messages, msg);
 
-		enumerator = this->recs->create_reason_enumerator(this->recs);
-		while (enumerator->enumerate(enumerator, &id, &reason, &language))
+		/* Suppress a successful CLOSE batch coming from the TNC server */
+		if (status == SUCCESS)
 		{
-			msg = pb_reason_string_msg_create(reason, language);
-			this->messages->insert_last(this->messages, msg);
+			status = NEED_MORE;
 		}
-		enumerator->destroy(enumerator);
 	}
+
+	return status;
 }
 
 METHOD(tls_t, build, status_t,
 	private_tnccs_20_t *this, void *buf, size_t *buflen, size_t *msglen)
 {
-	status_t status;
-	pb_tnc_state_t state;
-
-	/* Initialize the connection */
-	if (!this->is_server && !this->connection_id)
-	{
-		pb_tnc_msg_t *msg;
-		char *pref_lang;
-
-		this->connection_id = tnc->tnccs->create_connection(tnc->tnccs,
-										TNCCS_2_0, (tnccs_t*)this, _send_msg,
-										&this->request_handshake_retry,
-										this->max_msg_len, NULL);
-		if (!this->connection_id)
-		{
-			return FAILED;
-		}
-
-		/* Create PB-TNC Language Preference message */
-		pref_lang = tnc->imcs->get_preferred_language(tnc->imcs);
-		msg = pb_language_preference_msg_create(chunk_create(pref_lang,
-													strlen(pref_lang)));
-		this->mutex->lock(this->mutex);
-		this->batch_type = PB_BATCH_CDATA;
-		this->messages->insert_last(this->messages, msg);
-		this->mutex->unlock(this->mutex);
-
-		tnc->imcs->notify_connection_change(tnc->imcs, this->connection_id,
-											TNC_CONNECTION_STATE_CREATE);
-		tnc->imcs->notify_connection_change(tnc->imcs, this->connection_id,
-											TNC_CONNECTION_STATE_HANDSHAKE);
-		this->send_msg = TRUE;
-		tnc->imcs->begin_handshake(tnc->imcs, this->connection_id);
-		this->send_msg = FALSE;
-	}
-
-	state = this->state_machine->get_state(this->state_machine);
-
-	if (this->fatal_error && state == PB_STATE_END)
-	{
-		DBG1(DBG_TNC, "a fatal PB-TNC error occurred, terminating connection");
-		return FAILED;
-	}
-
-	/* Do not allow any asynchronous IMCs or IMVs to add additional messages */
-	this->mutex->lock(this->mutex);
-
-	if (this->request_handshake_retry)
-	{
-		if (state != PB_STATE_INIT)
-		{
-			build_retry_batch(this);
-		}
-
-		/* Reset the flag for the next handshake retry request */
-		this->request_handshake_retry = FALSE;
-	}
-
-	if (this->is_server &&  state == PB_STATE_SERVER_WORKING &&
-		this->recs->have_recommendation(this->recs, NULL, NULL))
+	if (this->to_server)
 	{
-		check_and_build_recommendation(this);
-	}
+		DBG2(DBG_TNC, "TNC client is handling outbound connection");
 
-	if (this->batch_type == PB_BATCH_NONE)
-	{
-		if (this->is_server)
+		/* Before sending the first PB-TNC batch create TNC client */
+		if (this->tnc_client)
 		{
-			if (state == PB_STATE_SERVER_WORKING)
-			{
-				if (this->state_machine->get_empty_cdata(this->state_machine))
-				{
-					check_and_build_recommendation(this);
-				}
-				else
-				{
-					DBG2(DBG_TNC, "no recommendation available yet, "
-								  "sending empty PB-TNC SDATA batch");
-					this->batch_type = PB_BATCH_SDATA;
-				}
-			}
+			this->tnccs_handler = this->tnc_client;
 		}
 		else
 		{
-			switch (state)
+			this->tnc_client = tnccs_20_client_create(&this->public, _send_msg,
+													  this->max_batch_len,
+													  this->max_msg_len);
+			if (!this->tnc_client)
 			{
-				case PB_STATE_CLIENT_WORKING:
-					DBG2(DBG_TNC, "no client data to send, "
-								  "sending empty PB-TNC CDATA batch");
-					this->batch_type = PB_BATCH_CDATA;
-					break;
-				case PB_STATE_DECIDED:
-					/**
-					 * In the DECIDED state and if no CRETRY is under way,
-					 * a PB-TNC client replies with an empty CLOSE batch.
-					 */
-					this->batch_type = PB_BATCH_CLOSE;
-					break;
-				default:
-					break;
+				return FAILED;
 			}
+			this->tnccs_handler = this->tnc_client;
+			this->tnccs_handler->begin_handshake(this->tnccs_handler,
+												 this->mutual);
 		}
 	}
-
-	if (this->batch_type != PB_BATCH_NONE)
+	else
 	{
-		pb_tnc_batch_t *batch;
-		pb_tnc_msg_t *msg;
-		chunk_t data;
-		int msg_count;
-		enumerator_t *enumerator;
+		DBG2(DBG_TNC, "TNC server is handling outbound connection");
 
-		if (this->state_machine->send_batch(this->state_machine, this->batch_type))
+		/* Before sending the first PB-TNC batch create TNC server */
+		if (this->tnc_server)
 		{
-			batch = pb_tnc_batch_create(this->is_server, this->batch_type,
-										min(this->max_batch_len, *buflen));
-
-			enumerator = this->messages->create_enumerator(this->messages);
-			while (enumerator->enumerate(enumerator, &msg))
-			{
-				if (batch->add_msg(batch, msg))
-				{
-					this->messages->remove_at(this->messages, enumerator);
-				}
-				else
-				{
-					break;
-				}
-			}
-			enumerator->destroy(enumerator);
-
-			batch->build(batch);
-			data = batch->get_encoding(batch);
-			DBG1(DBG_TNC, "sending PB-TNC %N batch (%d bytes) for Connection ID %u",
-						   pb_tnc_batch_type_names, this->batch_type, data.len,
-						   this->connection_id);
-			DBG3(DBG_TNC, "%B", &data);
-
-			*buflen = data.len;
-			*msglen = 0;
-			memcpy(buf, data.ptr, *buflen);
-			batch->destroy(batch);
-
-			msg_count = this->messages->get_count(this->messages);
-			if (msg_count)
-			{
-				DBG2(DBG_TNC, "queued %d PB-TNC message%s for next %N batch",
-					 msg_count, (msg_count == 1) ? "" : "s",
-					 pb_tnc_batch_type_names, this->batch_type);
-			}
-			else
-			{
-				this->batch_type = PB_BATCH_NONE;
-			}
-
-			status = ALREADY_DONE;
+			this->tnccs_handler = this->tnc_server;
 		}
 		else
 		{
-			change_batch_type(this, PB_BATCH_NONE);
-			status = INVALID_STATE;
+			this->tnc_server = tnccs_20_server_create(&this->public, _send_msg,
+										this->max_batch_len, this->max_msg_len,
+										this->eap_transport);
+			if (!this->tnc_server)
+			{
+				return FAILED;
+			}
+			this->tnccs_handler = this->tnc_server;
+			this->tnccs_handler->begin_handshake(this->tnccs_handler,
+												 this->mutual);
 		}
 	}
-	else
-	{
-		DBG1(DBG_TNC, "no PB-TNC batch to send");
-		status = INVALID_STATE;
-	}
-	this->mutex->unlock(this->mutex);
-
-	return status;
+	return this->tnccs_handler->build(this->tnccs_handler, buf, buflen, msglen);
 }
 
 METHOD(tls_t, is_server, bool,
@@ -923,20 +337,20 @@ METHOD(tls_t, is_server, bool,
 METHOD(tls_t, get_server_id, identification_t*,
 	private_tnccs_20_t *this)
 {
-	return this->server;
+	return this->server_id;
 }
 
 METHOD(tls_t, set_peer_id, void,
 	private_tnccs_20_t *this, identification_t *id)
 {
-	DESTROY_IF(this->peer);
-	this->peer = id->clone(id);
+	DESTROY_IF(this->peer_id);
+	this->peer_id = id->clone(id);
 }
 
 METHOD(tls_t, get_peer_id, identification_t*,
 	private_tnccs_20_t *this)
 {
-	return this->peer;
+	return this->peer_id;
 }
 
 METHOD(tls_t, get_purpose, tls_purpose_t,
@@ -951,14 +365,17 @@ METHOD(tls_t, is_complete, bool,
 	TNC_IMV_Action_Recommendation rec;
 	TNC_IMV_Evaluation_Result eval;
 
-	if (this->recs && this->recs->have_recommendation(this->recs, &rec, &eval))
+	if (this->tnc_server)
 	{
-		return this->callback ? this->callback(rec, eval) : TRUE;
-	}
-	else
-	{
-		return FALSE;
+		tnccs_20_server_t *tnc_server;
+
+		tnc_server = (tnccs_20_server_t*)this->tnc_server;
+		if (tnc_server->have_recommendation(tnc_server, &rec, &eval))
+		{
+			return this->callback ? this->callback(rec, eval) : TRUE;
+		}
 	}
+	return FALSE;
 }
 
 METHOD(tls_t, get_eap_msk, chunk_t,
@@ -972,19 +389,28 @@ METHOD(tls_t, destroy, void,
 {
 	if (ref_put(&this->ref))
 	{
-		tnc->tnccs->remove_connection(tnc->tnccs, this->connection_id,
-												  this->is_server);
-		this->server->destroy(this->server);
-		this->peer->destroy(this->peer);
-		this->state_machine->destroy(this->state_machine);
-		this->mutex->destroy(this->mutex);
-		this->messages->destroy_offset(this->messages,
-									   offsetof(pb_tnc_msg_t, destroy));
-		free(this->pdp_server.ptr);
+		DESTROY_IF(this->tnc_server);
+		DESTROY_IF(this->tnc_client);
+		this->server_id->destroy(this->server_id);
+		this->peer_id->destroy(this->peer_id);
+		this->server_ip->destroy(this->server_ip);
+		this->peer_ip->destroy(this->peer_ip);
 		free(this);
 	}
 }
 
+METHOD(tnccs_t, get_server_ip, host_t*,
+	private_tnccs_20_t *this)
+{
+	return this->server_ip;
+}
+
+METHOD(tnccs_t, get_peer_ip, host_t*,
+	private_tnccs_20_t *this)
+{
+	return this->peer_ip;
+}
+
 METHOD(tnccs_t, get_transport, tnc_ift_type_t,
 	private_tnccs_20_t *this)
 {
@@ -1012,9 +438,19 @@ METHOD(tnccs_t, set_auth_type, void,
 METHOD(tnccs_t, get_pdp_server, chunk_t,
 	private_tnccs_20_t *this, u_int16_t *port)
 {
-	*port = this->pdp_port;
+	if (this->tnc_client)
+	{
+		tnccs_20_client_t *tnc_client;
+
+		tnc_client = (tnccs_20_client_t*)this->tnc_client;
 
-	return this->pdp_server;
+		return tnc_client->get_pdp_server(tnc_client, port);
+	}
+	else
+	{
+		*port = 0;
+		return chunk_empty;
+	}
 }
 
 METHOD(tnccs_t, get_ref, tnccs_t*,
@@ -1027,9 +463,10 @@ METHOD(tnccs_t, get_ref, tnccs_t*,
 /**
  * See header
  */
-tnccs_t* tnccs_20_create(bool is_server,
-						 identification_t *server, identification_t *peer,
-						 tnc_ift_type_t transport, tnccs_cb_t cb)
+tnccs_t* tnccs_20_create(bool is_server, identification_t *server_id,
+						 identification_t *peer_id, host_t *server_ip,
+						 host_t *peer_ip, tnc_ift_type_t transport,
+						 tnccs_cb_t cb)
 {
 	private_tnccs_20_t *this;
 	size_t max_batch_size, default_max_batch_size;
@@ -1079,6 +516,8 @@ tnccs_t* tnccs_20_create(bool is_server,
 				.get_eap_msk = _get_eap_msk,
 				.destroy = _destroy,
 			},
+			.get_server_ip = _get_server_ip,
+			.get_peer_ip = _get_peer_ip,
 			.get_transport = _get_transport,
 			.set_transport = _set_transport,
 			.get_auth_type = _get_auth_type,
@@ -1087,13 +526,15 @@ tnccs_t* tnccs_20_create(bool is_server,
 			.get_ref = _get_ref,
 		},
 		.is_server = is_server,
-		.server = server->clone(server),
-		.peer = peer->clone(peer),
+		.to_server = !is_server,
+		.server_id = server_id->clone(server_id),
+		.peer_id = peer_id->clone(peer_id),
+		.server_ip = server_ip->clone(server_ip),
+		.peer_ip = peer_ip->clone(peer_ip),
 		.transport = transport,
+		.eap_transport = transport == TNC_IFT_EAP_1_1 ||
+						 transport == TNC_IFT_EAP_2_0,
 		.callback = cb,
-		.state_machine = pb_tnc_state_machine_create(is_server),
-		.mutex = mutex_create(MUTEX_TYPE_DEFAULT),
-		.messages = linked_list_create(),
 		.max_batch_len = max_batch_size,
 		.max_msg_len = max_message_size,
 		.ref = 1,
diff --git a/src/libtnccs/plugins/tnccs_20/tnccs_20.h b/src/libtnccs/plugins/tnccs_20/tnccs_20.h
index 2857b14..010cbec 100644
--- a/src/libtnccs/plugins/tnccs_20/tnccs_20.h
+++ b/src/libtnccs/plugins/tnccs_20/tnccs_20.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2010-2013 Andreas Steffen
+ * Copyright (C) 2010-2015 Andreas Steffen
  * HSR Hochschule fuer Technik Rapperswil
  *
  * This program is free software; you can redistribute it and/or modify it
@@ -29,14 +29,17 @@
  * Create an instance of the TNC IF-TNCCS 2.0 protocol handler.
  *
  * @param is_server		TRUE to act as TNC Server, FALSE for TNC Client
- * @param server		Server identity
- * @param peer			Client identity
+ * @param server_id		Server identity
+ * @param peer_id		Client identity
+ * @param server_ip		Server IP address
+ * @param peer_ip		Client IP address
  * @param transport		Underlying IF-T transport protocol
  * @param cb			Callback function if TNC Server, NULL if TNC Client
  * @return				TNC_IF_TNCCS 2.0 protocol stack
  */
-tnccs_t* tnccs_20_create(bool is_server,
-						 identification_t *server, identification_t *peer,
-						 tnc_ift_type_t transport, tnccs_cb_t cb);
+tnccs_t* tnccs_20_create(bool is_server, identification_t *server_id,
+						 identification_t *peer_id, host_t *server_ip,
+						 host_t *peer_ip, tnc_ift_type_t transport,
+						 tnccs_cb_t cb);
 
 #endif /** TNCCS_20_H_ @}*/
diff --git a/src/libtnccs/plugins/tnccs_20/tnccs_20_client.c b/src/libtnccs/plugins/tnccs_20/tnccs_20_client.c
new file mode 100644
index 0000000..4ba8221
--- /dev/null
+++ b/src/libtnccs/plugins/tnccs_20/tnccs_20_client.c
@@ -0,0 +1,820 @@
+/*
+ * Copyright (C) 2015 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 "tnccs_20_client.h"
+#include "messages/pb_tnc_msg.h"
+#include "messages/ietf/pb_pa_msg.h"
+#include "messages/ietf/pb_error_msg.h"
+#include "messages/ietf/pb_assessment_result_msg.h"
+#include "messages/ietf/pb_access_recommendation_msg.h"
+#include "messages/ietf/pb_remediation_parameters_msg.h"
+#include "messages/ietf/pb_reason_string_msg.h"
+#include "messages/ietf/pb_language_preference_msg.h"
+#include "messages/ita/pb_mutual_capability_msg.h"
+#include "messages/ita/pb_noskip_test_msg.h"
+#include "messages/tcg/pb_pdp_referral_msg.h"
+#include "state_machine/pb_tnc_state_machine.h"
+
+#include <tncif_names.h>
+#include <tncif_pa_subtypes.h>
+
+#include <tnc/tnc.h>
+#include <tnc/tnccs/tnccs_manager.h>
+#include <tnc/imc/imc_manager.h>
+
+#include <threading/mutex.h>
+#include <utils/debug.h>
+#include <collections/linked_list.h>
+#include <pen/pen.h>
+
+typedef struct private_tnccs_20_client_t private_tnccs_20_client_t;
+
+/**
+ * Private data of a tnccs_20_client_t object.
+ */
+struct private_tnccs_20_client_t {
+
+	/**
+	 * Public tnccs_20_client_t interface.
+	 */
+	tnccs_20_client_t public;
+
+	/**
+	 * PB-TNC State Machine
+	 */
+	pb_tnc_state_machine_t *state_machine;
+
+	/**
+	 * Connection ID assigned to this TNCCS connection
+	 */
+	TNC_ConnectionID connection_id;
+
+	/**
+	 * PB-TNC messages to be sent
+	 */
+	linked_list_t *messages;
+
+	/**
+	 * Type of PB-TNC batch being constructed
+	 */
+	pb_tnc_batch_type_t batch_type;
+
+	/**
+	 * Maximum PB-TNC batch size
+	 */
+	size_t max_batch_len;
+
+	/**
+	 * Mutex locking the batch in construction
+	 */
+	mutex_t *mutex;
+
+	/**
+	 * Flag set while processing
+	 */
+	bool fatal_error;
+
+	/**
+	 * Flag set by IMC RequestHandshakeRetry() function
+	 */
+	bool request_handshake_retry;
+
+	/**
+	  * SendMessage() by IMC only allowed if flag is set
+	  */
+	bool send_msg;
+
+	/**
+	 * PDP server FQDN
+	 */
+	chunk_t pdp_server;
+
+	/**
+	 * PDP server port
+	 */
+	u_int16_t pdp_port;
+
+	/**
+	 * Mutual PB-TNC protocol enabled
+	 */
+	bool mutual;
+
+	/**
+	 * Mutual Capability message sent
+	 */
+	bool sent_mutual_capability;
+
+};
+
+/**
+ * The following two functions are shared with the tnccs_20_server class
+ */
+void tnccs_20_handle_ietf_error_msg(pb_tnc_msg_t *msg, bool *fatal_error)
+{
+	pb_error_msg_t *err_msg;
+	u_int32_t vendor_id;
+	u_int16_t error_code;
+	bool fatal;
+
+	err_msg = (pb_error_msg_t*)msg;
+	fatal = err_msg->get_fatal_flag(err_msg);
+	vendor_id = err_msg->get_vendor_id(err_msg);
+	error_code = err_msg->get_error_code(err_msg);
+
+	if (fatal)
+	{
+		*fatal_error = TRUE;
+	}
+
+	if (vendor_id == PEN_IETF)
+	{
+		switch (error_code)
+		{
+			case PB_ERROR_INVALID_PARAMETER:
+			case PB_ERROR_UNSUPPORTED_MANDATORY_MSG:
+				DBG1(DBG_TNC, "received %s PB-TNC error '%N' (offset %u bytes)",
+							  fatal ? "fatal" : "non-fatal",
+							  pb_tnc_error_code_names, error_code,
+							  err_msg->get_offset(err_msg));
+				break;
+			case PB_ERROR_VERSION_NOT_SUPPORTED:
+				DBG1(DBG_TNC, "received %s PB-TNC error '%N' "
+							  "caused by bad version 0x%02x",
+							  fatal ? "fatal" : "non-fatal",
+							  pb_tnc_error_code_names, error_code,
+							  err_msg->get_bad_version(err_msg));
+				break;
+			case PB_ERROR_UNEXPECTED_BATCH_TYPE:
+			case PB_ERROR_LOCAL_ERROR:
+			default:
+				DBG1(DBG_TNC, "received %s PB-TNC error '%N'",
+							  fatal ? "fatal" : "non-fatal",
+							  pb_tnc_error_code_names, error_code);
+				break;
+		}
+	}
+	else
+	{
+		DBG1(DBG_TNC, "received %s PB-TNC error (%u) with Vendor ID 0x%06x",
+					  fatal ? "fatal" : "non-fatal", error_code, vendor_id);
+	}
+}
+
+bool tnccs_20_handle_ita_mutual_capability_msg(pb_tnc_msg_t *msg)
+{
+	pb_mutual_capability_msg_t *mutual_msg;
+	uint32_t protocols;
+
+	if (!lib->settings->get_bool(lib->settings,
+				"%s.plugins.tnccs-20.mutual", FALSE, lib->ns))
+	{
+		/* PB-TNC mutual capability disabled, ignore message */
+		return FALSE;
+	}
+
+	mutual_msg = (pb_mutual_capability_msg_t*)msg;
+	protocols = mutual_msg->get_protocols(mutual_msg);
+
+	if (protocols & PB_MUTUAL_HALF_DUPLEX)
+	{
+		DBG1(DBG_TNC, "activating mutual PB-TNC %N protocol",
+			 pb_tnc_mutual_protocol_type_names, PB_MUTUAL_HALF_DUPLEX);
+		return TRUE;
+	}
+
+	return FALSE;
+}
+
+/**
+ * If the batch type changes then delete all accumulated PB-TNC messages
+ */
+static void change_batch_type(private_tnccs_20_client_t *this,
+							  pb_tnc_batch_type_t batch_type)
+{
+	pb_tnc_msg_t *msg;
+
+	if (batch_type != this->batch_type)
+	{
+		if (this->batch_type != PB_BATCH_NONE)
+		{
+			DBG1(DBG_TNC, "cancelling PB-TNC %N batch",
+				 pb_tnc_batch_type_names, this->batch_type);
+
+			while (this->messages->remove_last(this->messages,
+											  (void**)&msg) == SUCCESS)
+			{
+				msg->destroy(msg);
+			}
+		}
+		this->batch_type = batch_type;
+	}
+}
+
+/**
+ * Handle a single PB-TNC IETF standard message according to its type
+ */
+static void handle_ietf_message(private_tnccs_20_client_t *this, pb_tnc_msg_t *msg)
+{
+	pen_type_t msg_type = msg->get_type(msg);
+
+	switch (msg_type.type)
+	{
+		case PB_MSG_EXPERIMENTAL:
+			/* nothing to do */
+			break;
+		case PB_MSG_PA:
+		{
+			pb_pa_msg_t *pa_msg;
+			pen_type_t msg_subtype;
+			u_int16_t imc_id, imv_id;
+			chunk_t msg_body;
+			bool excl;
+			enum_name_t *pa_subtype_names;
+
+			pa_msg = (pb_pa_msg_t*)msg;
+			msg_subtype = pa_msg->get_subtype(pa_msg);
+			msg_body = pa_msg->get_body(pa_msg);
+			imc_id = pa_msg->get_collector_id(pa_msg);
+			imv_id = pa_msg->get_validator_id(pa_msg);
+			excl = pa_msg->get_exclusive_flag(pa_msg);
+
+			pa_subtype_names = get_pa_subtype_names(msg_subtype.vendor_id);
+			if (pa_subtype_names)
+			{
+				DBG2(DBG_TNC, "handling PB-PA message type '%N/%N' 0x%06x/0x%08x",
+					 pen_names, msg_subtype.vendor_id, pa_subtype_names,
+					 msg_subtype.type, msg_subtype.vendor_id, msg_subtype.type);
+			}
+			else
+			{
+				DBG2(DBG_TNC, "handling PB-PA message type '%N' 0x%06x/0x%08x",
+					 pen_names, msg_subtype.vendor_id, msg_subtype.vendor_id,
+					 msg_subtype.type);
+			}
+			this->send_msg = TRUE;
+			tnc->imcs->receive_message(tnc->imcs, this->connection_id,
+									   excl, msg_body.ptr, msg_body.len,
+									   msg_subtype.vendor_id,
+									   msg_subtype.type, imv_id, imc_id);
+			this->send_msg = FALSE;
+			break;
+		}
+		case PB_MSG_ASSESSMENT_RESULT:
+		{
+			pb_assessment_result_msg_t *assess_msg;
+			u_int32_t result;
+
+			assess_msg = (pb_assessment_result_msg_t*)msg;
+			result = assess_msg->get_assessment_result(assess_msg);
+			DBG1(DBG_TNC, "PB-TNC assessment result is '%N'",
+				 TNC_IMV_Evaluation_Result_names, result);
+			break;
+		}
+		case PB_MSG_ACCESS_RECOMMENDATION:
+		{
+			pb_access_recommendation_msg_t *rec_msg;
+			pb_access_recommendation_code_t rec;
+			TNC_ConnectionState state = TNC_CONNECTION_STATE_ACCESS_NONE;
+
+			rec_msg = (pb_access_recommendation_msg_t*)msg;
+			rec = rec_msg->get_access_recommendation(rec_msg);
+			DBG1(DBG_TNC, "PB-TNC access recommendation is '%N'",
+						   pb_access_recommendation_code_names, rec);
+			switch (rec)
+			{
+				case PB_REC_ACCESS_ALLOWED:
+					state = TNC_CONNECTION_STATE_ACCESS_ALLOWED;
+					break;
+				case PB_REC_ACCESS_DENIED:
+					state = TNC_CONNECTION_STATE_ACCESS_NONE;
+					break;
+				case PB_REC_QUARANTINED:
+					state = TNC_CONNECTION_STATE_ACCESS_ISOLATED;
+			}
+			tnc->imcs->notify_connection_change(tnc->imcs, this->connection_id,
+												state);
+			break;
+		}
+		case PB_MSG_REMEDIATION_PARAMETERS:
+		{
+			pb_remediation_parameters_msg_t *rem_msg;
+			pen_type_t parameters_type;
+			chunk_t parameters, string, lang_code;
+
+			rem_msg = (pb_remediation_parameters_msg_t*)msg;
+			parameters_type = rem_msg->get_parameters_type(rem_msg);
+			parameters = rem_msg->get_parameters(rem_msg);
+
+			if (parameters_type.vendor_id == PEN_IETF)
+			{
+				switch (parameters_type.type)
+				{
+					case PB_REMEDIATION_URI:
+						DBG1(DBG_TNC, "remediation uri: %.*s",
+									   parameters.len, parameters.ptr);
+						break;
+					case PB_REMEDIATION_STRING:
+						string = rem_msg->get_string(rem_msg, &lang_code);
+						DBG1(DBG_TNC, "remediation string: [%.*s]\n%.*s",
+									   lang_code.len, lang_code.ptr,
+									   string.len, string.ptr);
+						break;
+					default:
+						DBG1(DBG_TNC, "remediation parameters: %B", &parameters);
+				}
+			}
+			else
+			{
+				DBG1(DBG_TNC, "remediation parameters: %B", &parameters);
+			}
+			break;
+		}
+		case PB_MSG_ERROR:
+			tnccs_20_handle_ietf_error_msg(msg, &this->fatal_error);
+			break;
+		case PB_MSG_REASON_STRING:
+		{
+			pb_reason_string_msg_t *reason_msg;
+			chunk_t reason_string, language_code;
+
+			reason_msg = (pb_reason_string_msg_t*)msg;
+			reason_string = reason_msg->get_reason_string(reason_msg);
+			language_code = reason_msg->get_language_code(reason_msg);
+			DBG1(DBG_TNC, "reason string is '%.*s' [%.*s]",
+				 (int)reason_string.len, reason_string.ptr,
+				 (int)language_code.len, language_code.ptr);
+			break;
+		}
+		default:
+			break;
+	}
+}
+
+/**
+ * Handle a single PB-TNC TCG standard message according to its type
+ */
+static void handle_tcg_message(private_tnccs_20_client_t *this, pb_tnc_msg_t *msg)
+{
+	pen_type_t msg_type = msg->get_type(msg);
+
+	switch (msg_type.type)
+	{
+		case PB_TCG_MSG_PDP_REFERRAL:
+		{
+			pb_pdp_referral_msg_t *pdp_msg;
+			pen_type_t pdp_id_type;
+			u_int8_t pdp_protocol;
+
+			pdp_msg = (pb_pdp_referral_msg_t*)msg;
+			pdp_id_type = pdp_msg->get_identifier_type(pdp_msg);
+
+			if (pdp_id_type.vendor_id == PEN_TCG &&
+				pdp_id_type.type == PB_PDP_ID_FQDN)
+			{
+				this->pdp_server = chunk_clone(pdp_msg->get_fqdn(pdp_msg,
+										 &pdp_protocol, &this->pdp_port));
+				if (pdp_protocol != 0)
+				{
+					DBG1(DBG_TNC, "unsupported PDP transport protocol");
+					break;
+				}
+				DBG1(DBG_TNC, "PDP server '%.*s' is listening on port %u",
+							   this->pdp_server.len, this->pdp_server.ptr,
+							   this->pdp_port);
+			}
+			break;
+		}
+		default:
+			break;
+	}
+}
+
+/**
+ * Handle a single PB-TNC ITA standard message according to its type
+ */
+static void handle_ita_message(private_tnccs_20_client_t *this, pb_tnc_msg_t *msg)
+{
+	pen_type_t msg_type = msg->get_type(msg);
+
+	switch (msg_type.type)
+	{
+		case PB_ITA_MSG_MUTUAL_CAPABILITY:
+			this->mutual = tnccs_20_handle_ita_mutual_capability_msg(msg);
+			break;
+		default:
+			break;
+	}
+}
+
+/**
+ * Handle a single PB-TNC message according to its type
+ */
+static void handle_message(private_tnccs_20_client_t *this, pb_tnc_msg_t *msg)
+{
+	pen_type_t msg_type = msg->get_type(msg);
+
+	switch (msg_type.vendor_id)
+	{
+		case PEN_IETF:
+			handle_ietf_message(this, msg);
+			break;
+		case PEN_TCG:
+			handle_tcg_message(this, msg);
+			break;
+		case PEN_ITA:
+			handle_ita_message(this, msg);
+			break;
+		default:
+			break;
+	}
+}
+
+/**
+ *  Build a CRETRY batch
+ */
+static void build_retry_batch(private_tnccs_20_client_t *this)
+{
+	if (this->batch_type == PB_BATCH_CRETRY)
+	{
+		/* retry batch has already been selected */
+		return;
+	}
+	change_batch_type(this, PB_BATCH_CRETRY);
+}
+
+METHOD(tnccs_20_handler_t, process, status_t,
+	private_tnccs_20_client_t *this, pb_tnc_batch_t *batch)
+{
+	pb_tnc_batch_type_t batch_type;
+	status_t status;
+
+	batch_type = batch->get_type(batch);
+
+	DBG1(DBG_TNC, "processing PB-TNC %N batch for Connection ID %d",
+		 pb_tnc_batch_type_names, batch_type, this->connection_id);
+
+	status = batch->process(batch, this->state_machine);
+
+	if (status != FAILED)
+	{
+		enumerator_t *enumerator;
+		pb_tnc_msg_t *msg;
+		bool empty = TRUE;
+
+		if (batch_type == PB_BATCH_SRETRY)
+		{
+			/* Restart the measurements */
+			tnc->imcs->notify_connection_change(tnc->imcs,
+						this->connection_id, TNC_CONNECTION_STATE_HANDSHAKE);
+			this->send_msg = TRUE;
+			tnc->imcs->begin_handshake(tnc->imcs, this->connection_id);
+			this->send_msg = FALSE;
+		}
+
+		enumerator = batch->create_msg_enumerator(batch);
+		while (enumerator->enumerate(enumerator, &msg))
+		{
+			handle_message(this, msg);
+			empty = FALSE;
+		}
+		enumerator->destroy(enumerator);
+
+		/* received a CLOSE batch from PB-TNC server */
+		if (batch_type == PB_BATCH_CLOSE)
+		{
+			return empty ? SUCCESS : FAILED;
+		}
+
+ 		this->send_msg = TRUE;
+		tnc->imcs->batch_ending(tnc->imcs, this->connection_id);
+		this->send_msg = FALSE;
+	}
+
+	switch (status)
+	{
+		case FAILED:
+			this->fatal_error = TRUE;
+			status = VERIFY_ERROR;
+			break;
+		case VERIFY_ERROR:
+			break;
+		case SUCCESS:
+		default:
+			status = NEED_MORE;
+			break;
+	}
+
+	return status;
+}
+
+METHOD(tnccs_20_handler_t, build, status_t,
+	private_tnccs_20_client_t *this, void *buf, size_t *buflen, size_t *msglen)
+{
+	status_t status;
+	pb_tnc_state_t state;
+
+	state = this->state_machine->get_state(this->state_machine);
+
+	if (this->fatal_error && state == PB_STATE_END)
+	{
+		DBG1(DBG_TNC, "a fatal PB-TNC error occurred, terminating connection");
+		return FAILED;
+	}
+
+	/* Do not allow any asynchronous IMCs to add additional messages */
+	this->mutex->lock(this->mutex);
+
+	if (this->request_handshake_retry)
+	{
+		if (state != PB_STATE_INIT)
+		{
+			build_retry_batch(this);
+		}
+
+		/* Reset the flag for the next handshake retry request */
+		this->request_handshake_retry = FALSE;
+	}
+
+	if (this->batch_type == PB_BATCH_NONE)
+	{
+		switch (state)
+		{
+			case PB_STATE_CLIENT_WORKING:
+				DBG2(DBG_TNC, "no client data to send, "
+							  "sending empty PB-TNC CDATA batch");
+				this->batch_type = PB_BATCH_CDATA;
+				break;
+			case PB_STATE_DECIDED:
+				/**
+				 * In the DECIDED state and if no CRETRY is under way,
+				 * a PB-TNC client replies with an empty CLOSE batch.
+				 */
+				this->batch_type = PB_BATCH_CLOSE;
+				break;
+			default:
+				break;
+		}
+	}
+
+	if (this->batch_type != PB_BATCH_NONE)
+	{
+		pb_tnc_batch_t *batch;
+		pb_tnc_msg_t *msg;
+		chunk_t data;
+		int msg_count;
+		enumerator_t *enumerator;
+
+		if (this->state_machine->send_batch(this->state_machine, this->batch_type))
+		{
+			batch = pb_tnc_batch_create(FALSE, this->batch_type,
+										min(this->max_batch_len, *buflen));
+
+			enumerator = this->messages->create_enumerator(this->messages);
+			while (enumerator->enumerate(enumerator, &msg))
+			{
+				if (batch->add_msg(batch, msg))
+				{
+					this->messages->remove_at(this->messages, enumerator);
+				}
+				else
+				{
+					break;
+				}
+			}
+			enumerator->destroy(enumerator);
+
+			batch->build(batch);
+			data = batch->get_encoding(batch);
+			DBG1(DBG_TNC, "sending PB-TNC %N batch (%d bytes) for Connection ID %u",
+						   pb_tnc_batch_type_names, this->batch_type, data.len,
+						   this->connection_id);
+			DBG3(DBG_TNC, "%B", &data);
+
+			*buflen = data.len;
+			*msglen = 0;
+			memcpy(buf, data.ptr, *buflen);
+			batch->destroy(batch);
+
+			msg_count = this->messages->get_count(this->messages);
+			if (msg_count)
+			{
+				DBG2(DBG_TNC, "queued %d PB-TNC message%s for next %N batch",
+					 msg_count, (msg_count == 1) ? "" : "s",
+					 pb_tnc_batch_type_names, this->batch_type);
+			}
+			else
+			{
+				this->batch_type = PB_BATCH_NONE;
+			}
+
+			status = ALREADY_DONE;
+		}
+		else
+		{
+			change_batch_type(this, PB_BATCH_NONE);
+			status = INVALID_STATE;
+		}
+	}
+	else
+	{
+		DBG1(DBG_TNC, "no PB-TNC batch to send");
+		status = INVALID_STATE;
+	}
+	this->mutex->unlock(this->mutex);
+
+	return status;
+}
+
+METHOD(tnccs_20_handler_t, begin_handshake, void,
+	private_tnccs_20_client_t *this, bool mutual)
+{
+	pb_tnc_msg_t *msg;
+	char *pref_lang;
+
+	tnc->imcs->notify_connection_change(tnc->imcs, this->connection_id,
+										TNC_CONNECTION_STATE_HANDSHAKE);
+
+	/* Announce PB-TNC Mutual Capability if activated */
+	this->sent_mutual_capability = mutual;
+
+	if (!mutual && lib->settings->get_bool(lib->settings,
+				"%s.plugins.tnccs-20.mutual", FALSE, lib->ns))
+	{
+		pb_tnc_mutual_protocol_type_t protocols;
+
+		protocols = PB_MUTUAL_HALF_DUPLEX;
+		DBG2(DBG_TNC, "proposing PB-TNC mutual %N protocol",
+			 pb_tnc_mutual_protocol_type_names, PB_MUTUAL_HALF_DUPLEX);
+		msg = pb_mutual_capability_msg_create(protocols);
+		this->mutex->lock(this->mutex);
+		this->messages->insert_last(this->messages, msg);
+		this->mutex->unlock(this->mutex);
+		this->sent_mutual_capability = TRUE;
+	}
+
+	/* Create PB-TNC Language Preference message */
+	pref_lang = tnc->imcs->get_preferred_language(tnc->imcs);
+	msg = pb_language_preference_msg_create(chunk_create(pref_lang,
+												strlen(pref_lang)));
+	this->mutex->lock(this->mutex);
+	this->messages->insert_last(this->messages, msg);
+	this->mutex->unlock(this->mutex);
+
+	this->send_msg = TRUE;
+	tnc->imcs->begin_handshake(tnc->imcs, this->connection_id);
+	this->send_msg = FALSE;
+
+	/* Send a PB-Noskip-Test message for testing purposes */
+	if (lib->settings->get_bool(lib->settings,
+				"%s.plugins.tnccs-20.tests.pb_tnc_noskip", FALSE, lib->ns))
+	{
+		msg = pb_noskip_test_msg_create();
+		this->mutex->lock(this->mutex);
+		this->messages->insert_last(this->messages, msg);
+		this->mutex->unlock(this->mutex);
+	}
+}
+
+METHOD(tnccs_20_handler_t, get_send_flag, bool,
+	private_tnccs_20_client_t *this)
+{
+	return this->send_msg;
+}
+
+METHOD(tnccs_20_handler_t, get_mutual, bool,
+	private_tnccs_20_client_t *this)
+{
+	return this->mutual;
+}
+
+METHOD(tnccs_20_handler_t, get_state, pb_tnc_state_t,
+	private_tnccs_20_client_t *this)
+{
+	return this->state_machine->get_state(this->state_machine);
+}
+
+METHOD(tnccs_20_handler_t, add_msg, void,
+	private_tnccs_20_client_t *this, pb_tnc_msg_t *msg)
+{
+	/* adding PA message to CDATA batch only */
+	this->mutex->lock(this->mutex);
+	if (this->batch_type == PB_BATCH_NONE)
+	{
+		this->batch_type = PB_BATCH_CDATA;
+	}
+	if (this->batch_type == PB_BATCH_CDATA)
+	{
+		this->messages->insert_last(this->messages, msg);
+	}
+	else
+	{
+		msg->destroy(msg);
+	}
+	this->mutex->unlock(this->mutex);
+}
+
+METHOD(tnccs_20_handler_t, handle_errors, void,
+	private_tnccs_20_client_t *this, pb_tnc_batch_t *batch,
+	bool fatal_header_error)
+{
+	pb_tnc_msg_t *msg;
+	enumerator_t *enumerator;
+
+	if (fatal_header_error || this->fatal_error)
+	{
+		this->mutex->lock(this->mutex);
+		change_batch_type(this, PB_BATCH_CLOSE);
+		this->mutex->unlock(this->mutex);
+	}
+
+	enumerator = batch->create_error_enumerator(batch);
+	while (enumerator->enumerate(enumerator, &msg))
+	{
+		this->mutex->lock(this->mutex);
+		this->messages->insert_last(this->messages, msg->get_ref(msg));
+		this->mutex->unlock(this->mutex);
+	}
+	enumerator->destroy(enumerator);
+}
+
+METHOD(tnccs_20_handler_t, destroy, void,
+	private_tnccs_20_client_t *this)
+{
+	if (this->connection_id)
+	{
+		tnc->tnccs->remove_connection(tnc->tnccs, this->connection_id, FALSE);
+	}
+	this->state_machine->destroy(this->state_machine);
+	this->mutex->destroy(this->mutex);
+	this->messages->destroy_offset(this->messages,
+								   offsetof(pb_tnc_msg_t, destroy));
+	free(this->pdp_server.ptr);
+	free(this);
+}
+
+METHOD(tnccs_20_client_t, get_pdp_server, chunk_t,
+	private_tnccs_20_client_t *this, u_int16_t *port)
+{
+	*port = this->pdp_port;
+
+	return this->pdp_server;
+}
+
+/**
+ * See header
+ */
+tnccs_20_handler_t* tnccs_20_client_create(tnccs_t *tnccs,
+										   tnccs_send_message_t send_msg,
+										   size_t max_batch_len,
+										   size_t max_msg_len)
+{
+	private_tnccs_20_client_t *this;
+
+	INIT(this,
+		.public = {
+			.handler = {
+				.process = _process,
+				.build = _build,
+				.begin_handshake = _begin_handshake,
+				.get_send_flag = _get_send_flag,
+				.get_mutual = _get_mutual,
+				.get_state = _get_state,
+				.add_msg = _add_msg,
+				.handle_errors = _handle_errors,
+				.destroy = _destroy,
+			},
+			.get_pdp_server = _get_pdp_server,
+		},
+		.state_machine = pb_tnc_state_machine_create(FALSE),
+		.mutex = mutex_create(MUTEX_TYPE_DEFAULT),
+		.messages = linked_list_create(),
+		.batch_type = PB_BATCH_CDATA,
+		.max_batch_len = max_batch_len,
+	);
+
+	this->connection_id = tnc->tnccs->create_connection(tnc->tnccs,
+											TNCCS_2_0, tnccs, send_msg,
+											&this->request_handshake_retry,
+											max_msg_len, NULL);
+	if (!this->connection_id)
+	{
+		destroy(this);
+		return NULL;
+	}
+	tnc->imcs->notify_connection_change(tnc->imcs, this->connection_id,
+										TNC_CONNECTION_STATE_CREATE);
+
+	return &this->public.handler;
+}
diff --git a/src/libtnccs/plugins/tnccs_20/tnccs_20_client.h b/src/libtnccs/plugins/tnccs_20/tnccs_20_client.h
new file mode 100644
index 0000000..7a5f33e
--- /dev/null
+++ b/src/libtnccs/plugins/tnccs_20/tnccs_20_client.h
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2015 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 tnccs_20_client_h tnccs_20_client
+ * @{ @ingroup tnccs_20
+ */
+
+#ifndef TNCCS_20_CLIENT_H_
+#define TNCCS_20_CLIENT_H_
+
+#include <library.h>
+
+#include <tnc/tnccs/tnccs.h>
+
+#include "tnccs_20_handler.h"
+
+typedef struct tnccs_20_client_t tnccs_20_client_t;
+
+/**
+ * Interface for a TNC client
+ */
+struct tnccs_20_client_t {
+
+	/**
+	 * IF-TNCCS 2.0 protocol handler interface
+	 */
+	tnccs_20_handler_t handler;
+
+	/**
+	 * Get PDP server information if available
+	 *
+	 * @param port			PT-TLS port of the PDP server
+	 * @return				FQDN of PDP server
+	 */
+	chunk_t (*get_pdp_server)(tnccs_20_client_t *this, u_int16_t *port);
+
+};
+
+/**
+ * Create an instance of the TNC IF-TNCCS 2.0 client-side protocol handler.
+ *
+ * @param tnccs				TNC IF-TNCCS 2.0 stack
+ * @param send_msg			TNF IF-TNCCS 2.0 send message callback function
+ * @param max_batch_len		Maximum PB-TNC batch size
+ * @param max_msg_len		Maximum PA-TNC message size
+ */
+tnccs_20_handler_t* tnccs_20_client_create(tnccs_t *tnccs,
+										   tnccs_send_message_t send_msg,
+										   size_t max_batch_len,
+										   size_t max_msg_len);
+
+#endif /** TNCCS_20_CLIENT_H_ @}*/
diff --git a/src/libtnccs/plugins/tnccs_20/tnccs_20_handler.h b/src/libtnccs/plugins/tnccs_20/tnccs_20_handler.h
new file mode 100644
index 0000000..5c4d7a7
--- /dev/null
+++ b/src/libtnccs/plugins/tnccs_20/tnccs_20_handler.h
@@ -0,0 +1,105 @@
+/*
+ * Copyright (C) 2015 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 tnccs_20_handler_h tnccs_20_handler
+ * @{ @ingroup tnccs_20
+ */
+
+#ifndef TNCCS_20_HANDLER_H_
+#define TNCCS_20_HANDLER_H_
+
+#include <library.h>
+
+#include "batch/pb_tnc_batch.h"
+#include "messages/pb_tnc_msg.h"
+
+typedef struct tnccs_20_handler_t tnccs_20_handler_t;
+
+/**
+ * Interface for an IF-TNCCS 2.0 protocol handler
+ */
+struct tnccs_20_handler_t {
+
+	/**
+	 * Process content of received PB-TNC batch
+	 *
+	 * @param batch			PB-TNC batch to be processed
+	 * @return				status
+	 */
+	status_t (*process)(tnccs_20_handler_t *this, pb_tnc_batch_t *batch);
+
+	/**
+	 * Build PB-TNC batch to be sent
+	 *
+	 * @param buf			buffer to write PB-TNC batch to
+	 * @param buflen		size of buffer, receives bytes written
+	 * @param msglen		receives size of all PB-TNCH batch
+	 * @return				status
+	 */
+	status_t (*build)(tnccs_20_handler_t *this, void *buf, size_t *buflen,
+														  size_t *msglen);
+
+	/**
+	 * Put the IMCs or IMVs into the handshake state
+	 *
+	 * @param mutual		TRUE if PB-TNC mutual mode is already established
+	 */
+	void (*begin_handshake)(tnccs_20_handler_t *this, bool mutual);
+
+	/**
+	 * Indicates if IMCs or IMVs are allowed to send PA-TNC messages
+	 *
+	 * @return				TRUE if allowed to send
+	 */
+	bool (*get_send_flag)(tnccs_20_handler_t *this);
+
+	/**
+	 * Indicates if the PB-TNC mutual protocol has been enabled
+	 *
+	 * @return				TRUE if enabled
+	 */
+	bool (*get_mutual)(tnccs_20_handler_t *this);
+
+	/**
+	 * Get state of the PB-TNC protocol
+	 *
+	 * @return				PB-TNC state
+	 */
+	pb_tnc_state_t (*get_state)(tnccs_20_handler_t *this);
+
+	/**
+	 * Add a PB-PA message to the handler's message queue
+	 *
+	 * @param msg			PB-PA message to be added
+	 */
+	void (*add_msg)(tnccs_20_handler_t *this, pb_tnc_msg_t *msg);
+
+	/**
+	 * Handle errors that occurred during PB-TNC batch header processing
+	 *
+	 * @param batch					batch where a fatal error occurred
+	 * @param fatal_header_error	TRUE if fatal error in batch header
+	 */
+	void (*handle_errors)(tnccs_20_handler_t *this, pb_tnc_batch_t *batch,
+						  bool fatal_header_error);
+
+	/**
+	 * Destroys a tnccs_20_handler_t object.
+	 */
+	void (*destroy)(tnccs_20_handler_t *this);
+};
+
+#endif /** TNCCS_20_HANDLER_H_ @}*/
diff --git a/src/libtnccs/plugins/tnccs_20/tnccs_20_plugin.h b/src/libtnccs/plugins/tnccs_20/tnccs_20_plugin.h
index 1c4ecf4..5073fbe 100644
--- a/src/libtnccs/plugins/tnccs_20/tnccs_20_plugin.h
+++ b/src/libtnccs/plugins/tnccs_20/tnccs_20_plugin.h
@@ -15,7 +15,7 @@
 
 /**
  * @defgroup tnccs_20 tnccs_20
- * @ingroup cplugins
+ * @ingroup tplugins
  *
  * @defgroup tnccs_20_plugin tnccs_20_plugin
  * @{ @ingroup tnccs_20
diff --git a/src/libtnccs/plugins/tnccs_20/tnccs_20_server.c b/src/libtnccs/plugins/tnccs_20/tnccs_20_server.c
new file mode 100644
index 0000000..038fc17
--- /dev/null
+++ b/src/libtnccs/plugins/tnccs_20/tnccs_20_server.c
@@ -0,0 +1,693 @@
+/*
+ * Copyright (C) 2015 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 "tnccs_20_server.h"
+#include "messages/pb_tnc_msg.h"
+#include "messages/ietf/pb_pa_msg.h"
+#include "messages/ietf/pb_error_msg.h"
+#include "messages/ietf/pb_assessment_result_msg.h"
+#include "messages/ietf/pb_access_recommendation_msg.h"
+#include "messages/ietf/pb_remediation_parameters_msg.h"
+#include "messages/ietf/pb_reason_string_msg.h"
+#include "messages/ietf/pb_language_preference_msg.h"
+#include "messages/ita/pb_mutual_capability_msg.h"
+#include "messages/ita/pb_noskip_test_msg.h"
+#include "messages/tcg/pb_pdp_referral_msg.h"
+#include "state_machine/pb_tnc_state_machine.h"
+
+#include <tncif_names.h>
+#include <tncif_pa_subtypes.h>
+
+#include <tnc/tnc.h>
+#include <tnc/tnccs/tnccs_manager.h>
+#include <tnc/imv/imv_manager.h>
+
+#include <threading/mutex.h>
+#include <utils/debug.h>
+#include <collections/linked_list.h>
+#include <pen/pen.h>
+
+typedef struct private_tnccs_20_server_t private_tnccs_20_server_t;
+
+/**
+ * Private data of a tnccs_20_server_t object.
+ */
+struct private_tnccs_20_server_t {
+
+	/**
+	 * Public tnccs_20_server_t interface.
+	 */
+	tnccs_20_server_t public;
+
+	/**
+	 * PB-TNC State Machine
+	 */
+	pb_tnc_state_machine_t *state_machine;
+
+	/**
+	 * Connection ID assigned to this TNCCS connection
+	 */
+	TNC_ConnectionID connection_id;
+
+	/**
+	 * PB-TNC messages to be sent
+	 */
+	linked_list_t *messages;
+
+	/**
+	 * Type of PB-TNC batch being constructed
+	 */
+	pb_tnc_batch_type_t batch_type;
+
+	/**
+	 * Maximum PB-TNC batch size
+	 */
+	size_t max_batch_len;
+
+	/**
+	 * Mutex locking the batch in construction
+	 */
+	mutex_t *mutex;
+
+	/**
+	 * Flag set while processing
+	 */
+	bool fatal_error;
+
+	/**
+	 * Flag set by IMC/IMV RequestHandshakeRetry() function
+	 */
+	bool request_handshake_retry;
+
+	/**
+	  * SendMessage() by IMV only allowed if flag is set
+	  */
+	bool send_msg;
+
+	/**
+	 * Set of IMV recommendations
+	 */
+	recommendations_t *recs;
+
+	/**
+	 *  TNC IF-T transport protocol for EAP methods
+	 */
+	bool eap_transport;
+
+	/**
+	 * Mutual PB-TNC protocol enabled
+	 */
+	bool mutual;
+
+	/**
+	 * Mutual Capability message sent
+	 */
+	bool sent_mutual_capability;
+
+};
+
+/**
+ * The following two functions are shared with the tnccs_20_server class
+ */
+extern void tnccs_20_handle_ietf_error_msg(pb_tnc_msg_t *msg,
+										   bool *fatal_error);
+extern bool tnccs_20_handle_ita_mutual_capability_msg(pb_tnc_msg_t *msg);
+
+/**
+ * If the batch type changes then delete all accumulated PB-TNC messages
+ */
+static void change_batch_type(private_tnccs_20_server_t *this,
+							  pb_tnc_batch_type_t batch_type)
+{
+	pb_tnc_msg_t *msg;
+
+	if (batch_type != this->batch_type)
+	{
+		if (this->batch_type != PB_BATCH_NONE)
+		{
+			DBG1(DBG_TNC, "cancelling PB-TNC %N batch",
+				 pb_tnc_batch_type_names, this->batch_type);
+
+			while (this->messages->remove_last(this->messages,
+											  (void**)&msg) == SUCCESS)
+			{
+				msg->destroy(msg);
+			}
+		}
+		this->batch_type = batch_type;
+	}
+}
+
+/**
+ * Handle a single PB-TNC IETF standard message according to its type
+ */
+static void handle_ietf_message(private_tnccs_20_server_t *this, pb_tnc_msg_t *msg)
+{
+	pen_type_t msg_type = msg->get_type(msg);
+
+	switch (msg_type.type)
+	{
+		case PB_MSG_EXPERIMENTAL:
+			/* nothing to do */
+			break;
+		case PB_MSG_PA:
+		{
+			pb_pa_msg_t *pa_msg;
+			pen_type_t msg_subtype;
+			u_int16_t imc_id, imv_id;
+			chunk_t msg_body;
+			bool excl;
+			enum_name_t *pa_subtype_names;
+
+			pa_msg = (pb_pa_msg_t*)msg;
+			msg_subtype = pa_msg->get_subtype(pa_msg);
+			msg_body = pa_msg->get_body(pa_msg);
+			imc_id = pa_msg->get_collector_id(pa_msg);
+			imv_id = pa_msg->get_validator_id(pa_msg);
+			excl = pa_msg->get_exclusive_flag(pa_msg);
+
+			pa_subtype_names = get_pa_subtype_names(msg_subtype.vendor_id);
+			if (pa_subtype_names)
+			{
+				DBG2(DBG_TNC, "handling PB-PA message type '%N/%N' 0x%06x/0x%08x",
+					 pen_names, msg_subtype.vendor_id, pa_subtype_names,
+					 msg_subtype.type, msg_subtype.vendor_id, msg_subtype.type);
+			}
+			else
+			{
+				DBG2(DBG_TNC, "handling PB-PA message type '%N' 0x%06x/0x%08x",
+					 pen_names, msg_subtype.vendor_id, msg_subtype.vendor_id,
+					 msg_subtype.type);
+			}
+			this->send_msg = TRUE;
+			tnc->imvs->receive_message(tnc->imvs, this->connection_id,
+									   excl, msg_body.ptr, msg_body.len,
+									   msg_subtype.vendor_id,
+									   msg_subtype.type, imc_id, imv_id);
+			this->send_msg = FALSE;
+			break;
+		}
+		case PB_MSG_ERROR:
+			tnccs_20_handle_ietf_error_msg(msg, &this->fatal_error);
+			break;
+		case PB_MSG_LANGUAGE_PREFERENCE:
+		{
+			pb_language_preference_msg_t *lang_msg;
+			chunk_t lang;
+
+			lang_msg = (pb_language_preference_msg_t*)msg;
+			lang = lang_msg->get_language_preference(lang_msg);
+			DBG2(DBG_TNC, "setting language preference to '%.*s'",
+				 (int)lang.len, lang.ptr);
+			this->recs->set_preferred_language(this->recs, lang);
+			break;
+		}
+		default:
+			break;
+	}
+}
+
+/**
+ * Handle a single PB-TNC ITA standard message according to its type
+ */
+static void handle_ita_message(private_tnccs_20_server_t *this, pb_tnc_msg_t *msg)
+{
+	pen_type_t msg_type = msg->get_type(msg);
+
+	switch (msg_type.type)
+	{
+		case PB_ITA_MSG_MUTUAL_CAPABILITY:
+			this->mutual = tnccs_20_handle_ita_mutual_capability_msg(msg);
+
+			/* Respond with PB-TNC Mutual Capability message if necessary */
+			if (this->mutual && !this->sent_mutual_capability)
+			{
+				msg = pb_mutual_capability_msg_create(PB_MUTUAL_HALF_DUPLEX);
+				this->mutex->lock(this->mutex);
+				this->messages->insert_last(this->messages, msg);
+				this->mutex->unlock(this->mutex);
+				this->sent_mutual_capability = TRUE;
+			}
+			break;
+		default:
+			break;
+	}
+}
+
+/**
+ * Handle a single PB-TNC message according to its type
+ */
+static void handle_message(private_tnccs_20_server_t *this, pb_tnc_msg_t *msg)
+{
+	pen_type_t msg_type = msg->get_type(msg);
+
+	switch (msg_type.vendor_id)
+	{
+		case PEN_IETF:
+			handle_ietf_message(this, msg);
+			break;
+		case PEN_ITA:
+			handle_ita_message(this, msg);
+			break;
+		default:
+			break;
+	}
+}
+
+/**
+ *  Build an SRETRY batch
+ */
+static void build_retry_batch(private_tnccs_20_server_t *this)
+{
+	if (this->batch_type == PB_BATCH_SRETRY)
+	{
+		/* retry batch has already been selected */
+		return;
+	}
+	change_batch_type(this, PB_BATCH_SRETRY);
+
+	this->recs->clear_recommendation(this->recs);
+	tnc->imvs->notify_connection_change(tnc->imvs, this->connection_id,
+										TNC_CONNECTION_STATE_HANDSHAKE);
+}
+
+METHOD(tnccs_20_handler_t, process, status_t,
+	private_tnccs_20_server_t *this, pb_tnc_batch_t *batch)
+{
+	pb_tnc_batch_type_t batch_type;
+	status_t status;
+
+	batch_type = batch->get_type(batch);
+
+	DBG1(DBG_TNC, "processing PB-TNC %N batch for Connection ID %d",
+		 pb_tnc_batch_type_names, batch_type, this->connection_id);
+	status = batch->process(batch, this->state_machine);
+
+	if (status != FAILED)
+	{
+		enumerator_t *enumerator;
+		pb_tnc_msg_t *msg;
+		bool empty = TRUE;
+
+		if (batch_type == PB_BATCH_CRETRY)
+		{
+			/* Send an SRETRY batch in response */
+			this->mutex->lock(this->mutex);
+			build_retry_batch(this);
+			this->mutex->unlock(this->mutex);
+		}
+
+		enumerator = batch->create_msg_enumerator(batch);
+		while (enumerator->enumerate(enumerator, &msg))
+		{
+			handle_message(this, msg);
+			empty = FALSE;
+		}
+		enumerator->destroy(enumerator);
+
+		/* received a CLOSE batch from PB-TNC client */
+		if (batch_type == PB_BATCH_CLOSE)
+		{
+			return empty ? SUCCESS : FAILED;
+		}
+
+		this->send_msg = TRUE;
+		tnc->imvs->batch_ending(tnc->imvs, this->connection_id);
+		this->send_msg = FALSE;
+	}
+
+	switch (status)
+	{
+		case FAILED:
+			this->fatal_error = TRUE;
+			status = VERIFY_ERROR;
+			break;
+		case VERIFY_ERROR:
+			break;
+		case SUCCESS:
+		default:
+			status = NEED_MORE;
+			break;
+	}
+
+	return status;
+}
+
+/**
+ *  Build a RESULT batch if a final recommendation is available
+ */
+static void check_and_build_recommendation(private_tnccs_20_server_t *this)
+{
+	TNC_IMV_Action_Recommendation rec;
+	TNC_IMV_Evaluation_Result eval;
+	TNC_ConnectionState state;
+	TNC_IMVID id;
+	chunk_t reason, language;
+	enumerator_t *enumerator;
+	pb_tnc_msg_t *msg;
+	pb_access_recommendation_code_t pb_rec;
+
+	if (!this->recs->have_recommendation(this->recs, &rec, &eval))
+	{
+		tnc->imvs->solicit_recommendation(tnc->imvs, this->connection_id);
+	}
+	if (this->recs->have_recommendation(this->recs, &rec, &eval))
+	{
+		this->batch_type = PB_BATCH_RESULT;
+
+		msg = pb_assessment_result_msg_create(eval);
+		this->messages->insert_last(this->messages, msg);
+
+		/**
+		 * Map IMV Action Recommendation codes to PB Access Recommendation codes
+		 * and communicate Access Recommendation to IMVs
+		 */
+		switch (rec)
+		{
+			case TNC_IMV_ACTION_RECOMMENDATION_ALLOW:
+				state = TNC_CONNECTION_STATE_ACCESS_ALLOWED;
+				pb_rec = PB_REC_ACCESS_ALLOWED;
+				break;
+			case TNC_IMV_ACTION_RECOMMENDATION_ISOLATE:
+				state = TNC_CONNECTION_STATE_ACCESS_ISOLATED;
+				pb_rec = PB_REC_QUARANTINED;
+				break;
+			case TNC_IMV_ACTION_RECOMMENDATION_NO_ACCESS:
+			case TNC_IMV_ACTION_RECOMMENDATION_NO_RECOMMENDATION:
+			default:
+				state = TNC_CONNECTION_STATE_ACCESS_NONE;
+				pb_rec = PB_REC_ACCESS_DENIED;
+		}
+		tnc->imvs->notify_connection_change(tnc->imvs, this->connection_id,
+											state);
+
+		msg = pb_access_recommendation_msg_create(pb_rec);
+		this->messages->insert_last(this->messages, msg);
+
+		enumerator = this->recs->create_reason_enumerator(this->recs);
+		while (enumerator->enumerate(enumerator, &id, &reason, &language))
+		{
+			msg = pb_reason_string_msg_create(reason, language);
+			this->messages->insert_last(this->messages, msg);
+		}
+		enumerator->destroy(enumerator);
+	}
+}
+
+METHOD(tnccs_20_handler_t, build, status_t,
+	private_tnccs_20_server_t *this, void *buf, size_t *buflen, size_t *msglen)
+{
+	status_t status;
+	pb_tnc_state_t state;
+
+	state = this->state_machine->get_state(this->state_machine);
+
+	if (this->fatal_error && state == PB_STATE_END)
+	{
+		DBG1(DBG_TNC, "a fatal PB-TNC error occurred, terminating connection");
+		return FAILED;
+	}
+
+	/* Do not allow any asynchronous IMVs to add additional messages */
+	this->mutex->lock(this->mutex);
+
+	if (this->request_handshake_retry)
+	{
+		if (state != PB_STATE_INIT)
+		{
+			build_retry_batch(this);
+		}
+
+		/* Reset the flag for the next handshake retry request */
+		this->request_handshake_retry = FALSE;
+	}
+
+	if (state == PB_STATE_SERVER_WORKING &&
+		this->recs->have_recommendation(this->recs, NULL, NULL))
+	{
+		check_and_build_recommendation(this);
+	}
+
+	if (this->batch_type == PB_BATCH_NONE)
+	{
+		if (state == PB_STATE_SERVER_WORKING)
+		{
+			if (this->state_machine->get_empty_cdata(this->state_machine))
+			{
+				check_and_build_recommendation(this);
+			}
+			else
+			{
+				DBG2(DBG_TNC, "no recommendation available yet, "
+							  "sending empty PB-TNC SDATA batch");
+				this->batch_type = PB_BATCH_SDATA;
+			}
+		}
+	}
+
+	if (this->batch_type != PB_BATCH_NONE)
+	{
+		pb_tnc_batch_t *batch;
+		pb_tnc_msg_t *msg;
+		chunk_t data;
+		int msg_count;
+		enumerator_t *enumerator;
+
+		if (this->state_machine->send_batch(this->state_machine, this->batch_type))
+		{
+			batch = pb_tnc_batch_create(TRUE, this->batch_type,
+										min(this->max_batch_len, *buflen));
+
+			enumerator = this->messages->create_enumerator(this->messages);
+			while (enumerator->enumerate(enumerator, &msg))
+			{
+				if (batch->add_msg(batch, msg))
+				{
+					this->messages->remove_at(this->messages, enumerator);
+				}
+				else
+				{
+					break;
+				}
+			}
+			enumerator->destroy(enumerator);
+
+			batch->build(batch);
+			data = batch->get_encoding(batch);
+			DBG1(DBG_TNC, "sending PB-TNC %N batch (%d bytes) for Connection ID %u",
+						   pb_tnc_batch_type_names, this->batch_type, data.len,
+						   this->connection_id);
+			DBG3(DBG_TNC, "%B", &data);
+
+			*buflen = data.len;
+			*msglen = 0;
+			memcpy(buf, data.ptr, *buflen);
+			batch->destroy(batch);
+
+			msg_count = this->messages->get_count(this->messages);
+			if (msg_count)
+			{
+				DBG2(DBG_TNC, "queued %d PB-TNC message%s for next %N batch",
+					 msg_count, (msg_count == 1) ? "" : "s",
+					 pb_tnc_batch_type_names, this->batch_type);
+			}
+			else
+			{
+				this->batch_type = PB_BATCH_NONE;
+			}
+
+			status = ALREADY_DONE;
+		}
+		else
+		{
+			change_batch_type(this, PB_BATCH_NONE);
+			status = INVALID_STATE;
+		}
+	}
+	else
+	{
+		DBG1(DBG_TNC, "no PB-TNC batch to send");
+		status = INVALID_STATE;
+	}
+	this->mutex->unlock(this->mutex);
+
+	return status;
+}
+
+METHOD(tnccs_20_handler_t, begin_handshake, void,
+	private_tnccs_20_server_t *this, bool mutual)
+{
+	pb_tnc_msg_t *msg;
+	identification_t *pdp_server;
+	u_int16_t *pdp_port;
+
+	tnc->imvs->notify_connection_change(tnc->imvs, this->connection_id,
+										TNC_CONNECTION_STATE_HANDSHAKE);
+
+	/* Send a PB-TNC TCG PDP Referral message if PDP is known */
+	pdp_server = (identification_t*)lib->get(lib, "pt-tls-server");
+	pdp_port = (u_int16_t*)lib->get(lib, "pt-tls-port");
+
+	if (this->eap_transport && pdp_server && pdp_port)
+	{
+		msg = pb_pdp_referral_msg_create_from_fqdn(
+						pdp_server->get_encoding(pdp_server), *pdp_port);
+		this->mutex->lock(this->mutex);
+		this->messages->insert_last(this->messages, msg);
+		this->mutex->unlock(this->mutex);
+	}
+
+	/* Send a PB-Noskip-Test message for testing purposes */
+	if (lib->settings->get_bool(lib->settings,
+				"%s.plugins.tnccs-20.tests.pb_tnc_noskip", FALSE, lib->ns))
+	{
+		msg = pb_noskip_test_msg_create();
+		this->mutex->lock(this->mutex);
+		this->messages->insert_last(this->messages, msg);
+		this->mutex->unlock(this->mutex);
+	}
+}
+
+METHOD(tnccs_20_handler_t, get_send_flag, bool,
+	private_tnccs_20_server_t *this)
+{
+	return this->send_msg;
+}
+
+METHOD(tnccs_20_handler_t, get_mutual, bool,
+	private_tnccs_20_server_t *this)
+{
+	return this->mutual;
+}
+
+METHOD(tnccs_20_handler_t, get_state, pb_tnc_state_t,
+	private_tnccs_20_server_t *this)
+{
+	return this->state_machine->get_state(this->state_machine);
+}
+
+METHOD(tnccs_20_handler_t, add_msg, void,
+	private_tnccs_20_server_t *this, pb_tnc_msg_t *msg)
+{
+	/* adding PA message to SDATA batch only */
+	this->mutex->lock(this->mutex);
+	if (this->batch_type == PB_BATCH_NONE)
+	{
+		this->batch_type = PB_BATCH_SDATA;
+	}
+	if (this->batch_type == PB_BATCH_SDATA)
+	{
+		this->messages->insert_last(this->messages, msg);
+	}
+	else
+	{
+		msg->destroy(msg);
+	}
+	this->mutex->unlock(this->mutex);
+}
+
+METHOD(tnccs_20_handler_t, handle_errors, void,
+	private_tnccs_20_server_t *this,  pb_tnc_batch_t *batch,
+	bool fatal_header_error)
+{
+	pb_tnc_msg_t *msg;
+	enumerator_t *enumerator;
+
+	if (fatal_header_error || this->fatal_error)
+	{
+		this->mutex->lock(this->mutex);
+		change_batch_type(this, PB_BATCH_CLOSE);
+		this->mutex->unlock(this->mutex);
+	}
+
+	enumerator = batch->create_error_enumerator(batch);
+	while (enumerator->enumerate(enumerator, &msg))
+	{
+		this->mutex->lock(this->mutex);
+		this->messages->insert_last(this->messages, msg->get_ref(msg));
+		this->mutex->unlock(this->mutex);
+	}
+	enumerator->destroy(enumerator);
+}
+
+METHOD(tnccs_20_handler_t, destroy, void,
+	private_tnccs_20_server_t *this)
+{
+	if (this->connection_id)
+	{
+		tnc->tnccs->remove_connection(tnc->tnccs, this->connection_id, TRUE);
+	}
+	this->state_machine->destroy(this->state_machine);
+	this->mutex->destroy(this->mutex);
+	this->messages->destroy_offset(this->messages,
+								   offsetof(pb_tnc_msg_t, destroy));
+	free(this);
+}
+
+METHOD(tnccs_20_server_t, have_recommendation, bool,
+	private_tnccs_20_server_t *this, TNC_IMV_Action_Recommendation *rec,
+	TNC_IMV_Evaluation_Result *eval)
+{
+	return this->recs->have_recommendation(this->recs, rec, eval);
+}
+
+/**
+ * See header
+ */
+tnccs_20_handler_t* tnccs_20_server_create(tnccs_t *tnccs,
+										   tnccs_send_message_t send_msg,
+										   size_t max_batch_len,
+										   size_t max_msg_len,
+										   bool eap_transport)
+{
+	private_tnccs_20_server_t *this;
+
+	INIT(this,
+		.public = {
+			.handler = {
+				.process = _process,
+				.build = _build,
+				.begin_handshake = _begin_handshake,
+				.get_send_flag = _get_send_flag,
+				.get_mutual = _get_mutual,
+				.get_state = _get_state,
+				.add_msg = _add_msg,
+				.handle_errors = _handle_errors,
+				.destroy = _destroy,
+			},
+			.have_recommendation = _have_recommendation,
+		},
+		.state_machine = pb_tnc_state_machine_create(TRUE),
+		.mutex = mutex_create(MUTEX_TYPE_DEFAULT),
+		.messages = linked_list_create(),
+		.batch_type = PB_BATCH_SDATA,
+		.max_batch_len = max_batch_len,
+		.eap_transport = eap_transport,
+	);
+
+	this->connection_id = tnc->tnccs->create_connection(tnc->tnccs,
+											TNCCS_2_0, tnccs, send_msg,
+											&this->request_handshake_retry,
+											max_msg_len, &this->recs);
+	if (!this->connection_id)
+	{
+		destroy(this);
+		return NULL;
+	}
+	tnc->imvs->notify_connection_change(tnc->imvs, this->connection_id,
+										TNC_CONNECTION_STATE_CREATE);
+
+	return &this->public.handler;
+}
diff --git a/src/libtnccs/plugins/tnccs_20/tnccs_20_server.h b/src/libtnccs/plugins/tnccs_20/tnccs_20_server.h
new file mode 100644
index 0000000..5833d11
--- /dev/null
+++ b/src/libtnccs/plugins/tnccs_20/tnccs_20_server.h
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 2015 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 tnccs_20_server_h tnccs_20_server
+ * @{ @ingroup tnccs_20
+ */
+
+#ifndef TNCCS_20_SERVER_H_
+#define TNCCS_20_SERVER_H_
+
+#include <library.h>
+
+#include <tnc/tnccs/tnccs.h>
+
+#include "tnccs_20_handler.h"
+
+typedef struct tnccs_20_server_t tnccs_20_server_t;
+
+/**
+ * Interface for a TNC server
+ */
+struct tnccs_20_server_t {
+
+	/**
+	 * IF-TNCCS 2.0 protocol handler interface
+	 */
+	tnccs_20_handler_t handler;
+
+	/**
+	 * Check if an Action Recommendation is already available
+	 *
+	 * @param rec			TNC Action Recommendation
+	 * @param eval			TNC Evaluation Result
+	 * @return				TRUE if Action Recommendation is
+	 */
+	bool (*have_recommendation)(tnccs_20_server_t *this,
+								TNC_IMV_Action_Recommendation *rec,
+								TNC_IMV_Evaluation_Result *eval);
+
+};
+
+/**
+ * Create an instance of the TNC IF-TNCCS 2.0 server-side protocol handler.
+ *
+ * @param tnccs				TNC IF-TNCCS 2.0 stack
+ * @param send_msg			TNF IF-TNCCS 2.0 send message callback function
+ * @param max_batch_len		Maximum PB-TNC batch size
+ * @param max_msg_len		Maximum PA-TNC message size
+ * @param eap_transport		TRUE if IF-T for EAP methods
+ */
+tnccs_20_handler_t* tnccs_20_server_create(tnccs_t *tnccs,
+										   tnccs_send_message_t send_msg,
+										   size_t max_batch_len,
+										   size_t max_msg_len,
+										   bool eap_transport);
+
+
+#endif /** TNCCS_20_SERVER_H_ @}*/
diff --git a/src/libtnccs/plugins/tnccs_dynamic/Makefile.in b/src/libtnccs/plugins/tnccs_dynamic/Makefile.in
index 6a03df9..3f21a22 100644
--- a/src/libtnccs/plugins/tnccs_dynamic/Makefile.in
+++ b/src/libtnccs/plugins/tnccs_dynamic/Makefile.in
@@ -231,6 +231,7 @@ DLLIB = @DLLIB@
 DLLTOOL = @DLLTOOL@
 DSYMUTIL = @DSYMUTIL@
 DUMPBIN = @DUMPBIN@
+EASY_INSTALL = @EASY_INSTALL@
 ECHO_C = @ECHO_C@
 ECHO_N = @ECHO_N@
 ECHO_T = @ECHO_T@
@@ -291,10 +292,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
 PLUGIN_CFLAGS = @PLUGIN_CFLAGS@
 PTHREADLIB = @PTHREADLIB@
 PYTHON = @PYTHON@
+PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@
 PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
 PYTHON_PLATFORM = @PYTHON_PLATFORM@
 PYTHON_PREFIX = @PYTHON_PREFIX@
 PYTHON_VERSION = @PYTHON_VERSION@
+PY_TEST = @PY_TEST@
 RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
@@ -368,6 +371,8 @@ json_CFLAGS = @json_CFLAGS@
 json_LIBS = @json_LIBS@
 libdir = @libdir@
 libexecdir = @libexecdir@
+libiptc_CFLAGS = @libiptc_CFLAGS@
+libiptc_LIBS = @libiptc_LIBS@
 linux_headers = @linux_headers@
 localedir = @localedir@
 localstatedir = @localstatedir@
diff --git a/src/libtnccs/plugins/tnccs_dynamic/tnccs_dynamic.c b/src/libtnccs/plugins/tnccs_dynamic/tnccs_dynamic.c
index e08236e..44b804f 100644
--- a/src/libtnccs/plugins/tnccs_dynamic/tnccs_dynamic.c
+++ b/src/libtnccs/plugins/tnccs_dynamic/tnccs_dynamic.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2011-2013 Andreas Steffen
+ * Copyright (C) 2011-2015 Andreas Steffen
  * HSR Hochschule fuer Technik Rapperswil
  *
  * This program is free software; you can redistribute it and/or modify it
@@ -34,12 +34,22 @@ struct private_tnccs_dynamic_t {
 	/**
 	 * Server identity
 	 */
-	identification_t *server;
+	identification_t *server_id;
 
 	/**
 	 * Client identity
 	 */
-	identification_t *peer;
+	identification_t *peer_id;
+
+	/**
+	 * Server IP address
+	 */
+	host_t *server_ip;
+
+	/**
+	 * Client IP address
+	 */
+	host_t *peer_ip;
 
 	/**
 	 * Detected TNC IF-TNCCS stack
@@ -109,8 +119,8 @@ METHOD(tls_t, process, status_t,
 		DBG1(DBG_TNC, "%N protocol detected dynamically",
 					   tnccs_type_names, type);
 		tnccs = tnc->tnccs->create_instance(tnc->tnccs, type, TRUE,
-							this->server, this->peer, this->transport,
-							this->callback);
+							this->server_id, this->peer_id, this->server_ip,
+							this->peer_ip, this->transport,	this->callback);
 		if (!tnccs)
 		{
 			DBG1(DBG_TNC, "N% protocol not supported", tnccs_type_names, type);
@@ -137,14 +147,14 @@ METHOD(tls_t, is_server, bool,
 METHOD(tls_t, get_server_id, identification_t*,
 	private_tnccs_dynamic_t *this)
 {
-	return this->server;
+	return this->server_id;
 }
 
 METHOD(tls_t, set_peer_id, void,
 	private_tnccs_dynamic_t *this, identification_t *id)
 {
-	DESTROY_IF(this->peer);
-	this->peer = id->clone(id);
+	DESTROY_IF(this->peer_id);
+	this->peer_id = id->clone(id);
 	if (this->tls)
 	{
 		this->tls->set_peer_id(this->tls, id);
@@ -154,7 +164,7 @@ METHOD(tls_t, set_peer_id, void,
 METHOD(tls_t, get_peer_id, identification_t*,
 	private_tnccs_dynamic_t *this)
 {
-	return this->peer;
+	return this->peer_id;
 }
 
 METHOD(tls_t, get_purpose, tls_purpose_t,
@@ -181,12 +191,26 @@ METHOD(tls_t, destroy, void,
 	if (ref_put(&this->ref))
 	{
 		DESTROY_IF(this->tls);
-		this->server->destroy(this->server);
-		this->peer->destroy(this->peer);
+		this->server_id->destroy(this->server_id);
+		this->peer_id->destroy(this->peer_id);
+		this->server_ip->destroy(this->server_ip);
+		this->peer_ip->destroy(this->peer_ip);
 		free(this);
 	}
 }
 
+METHOD(tnccs_t, get_server_ip, host_t*,
+	private_tnccs_dynamic_t *this)
+{
+	return this->server_ip;
+}
+
+METHOD(tnccs_t, get_peer_ip, host_t*,
+	private_tnccs_dynamic_t *this)
+{
+	return this->peer_ip;
+}
+
 METHOD(tnccs_t, get_transport, tnc_ift_type_t,
 	private_tnccs_dynamic_t *this)
 {
@@ -229,9 +253,10 @@ METHOD(tnccs_t, get_ref, tnccs_t*,
 /**
  * See header
  */
-tnccs_t* tnccs_dynamic_create(bool is_server,
-							  identification_t *server, identification_t *peer,
-							  tnc_ift_type_t transport, tnccs_cb_t cb)
+tnccs_t* tnccs_dynamic_create(bool is_server, identification_t *server_id,
+							  identification_t *peer_id, host_t *server_ip,
+							  host_t *peer_ip, tnc_ift_type_t transport,
+							  tnccs_cb_t cb)
 {
 	private_tnccs_dynamic_t *this;
 
@@ -249,6 +274,8 @@ tnccs_t* tnccs_dynamic_create(bool is_server,
 				.get_eap_msk = _get_eap_msk,
 				.destroy = _destroy,
 			},
+			.get_server_ip = _get_server_ip,
+			.get_peer_ip = _get_peer_ip,
 			.get_transport = _get_transport,
 			.set_transport = _set_transport,
 			.get_auth_type = _get_auth_type,
@@ -256,8 +283,10 @@ tnccs_t* tnccs_dynamic_create(bool is_server,
 			.get_pdp_server = _get_pdp_server,
 			.get_ref = _get_ref,
 		},
-		.server = server->clone(server),
-		.peer = peer->clone(peer),
+		.server_id = server_id->clone(server_id),
+		.peer_id = peer_id->clone(peer_id),
+		.server_ip = server_ip->clone(server_ip),
+		.peer_ip = peer_ip->clone(peer_ip),
 		.transport = transport,
 		.callback = cb,
 		.ref = 1,
diff --git a/src/libtnccs/plugins/tnccs_dynamic/tnccs_dynamic.h b/src/libtnccs/plugins/tnccs_dynamic/tnccs_dynamic.h
index cbdc80b..2e11417 100644
--- a/src/libtnccs/plugins/tnccs_dynamic/tnccs_dynamic.h
+++ b/src/libtnccs/plugins/tnccs_dynamic/tnccs_dynamic.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2011-2013 Andreas Steffen
+ * Copyright (C) 2011-2015 Andreas Steffen
  * HSR Hochschule fuer Technik Rapperswil
  *
  * This program is free software; you can redistribute it and/or modify it
@@ -29,14 +29,17 @@
  * Create an instance of a dynamic TNC IF-TNCCS protocol handler.
  *
  * @param is_server		TRUE to act as TNC Server, FALSE for TNC Client
- * @param server		Server identity
- * @param peer			Client identity
+ * @param server_id		Server identity
+ * @param peer_id		Client identity
+ * @param server_ip		Server IP address
+ * @param peer_ip		Client IP address
  * @param transport		Underlying IF-T transport protocol
  * @param cb			Callback function if TNC Server, NULL if TNC Client
  * @return				dynamic TNC IF-TNCCS protocol stack
  */
-tnccs_t* tnccs_dynamic_create(bool is_server,
-							  identification_t *server, identification_t *peer,
-							  tnc_ift_type_t transport, tnccs_cb_t cb);
+tnccs_t* tnccs_dynamic_create(bool is_server, identification_t *server_id,
+							  identification_t *peer_id, host_t *server_ip,
+							  host_t *peer_ip, tnc_ift_type_t transport,
+							  tnccs_cb_t cb);
 
 #endif /** TNCCS_DYNAMIC_H_ @}*/
diff --git a/src/libtnccs/plugins/tnccs_dynamic/tnccs_dynamic_plugin.h b/src/libtnccs/plugins/tnccs_dynamic/tnccs_dynamic_plugin.h
index b518e12..97dd0df 100644
--- a/src/libtnccs/plugins/tnccs_dynamic/tnccs_dynamic_plugin.h
+++ b/src/libtnccs/plugins/tnccs_dynamic/tnccs_dynamic_plugin.h
@@ -15,7 +15,7 @@
 
 /**
  * @defgroup tnccs_dynamic tnccs_dynamic
- * @ingroup cplugins
+ * @ingroup tplugins
  *
  * @defgroup tnccs_dynamic_plugin tnccs_dynamic_plugin
  * @{ @ingroup tnccs_dynamic
diff --git a/src/libtnccs/tnc/imc/imc.h b/src/libtnccs/tnc/imc/imc.h
index 3ff7d51..6d13f6b 100644
--- a/src/libtnccs/tnc/imc/imc.h
+++ b/src/libtnccs/tnc/imc/imc.h
@@ -15,7 +15,7 @@
 
 /**
  * @defgroup imc imc
- * @ingroup tnc
+ * @ingroup libtnccs
  *
  * @defgroup imct imc
  * @{ @ingroup imc
diff --git a/src/libtnccs/tnc/imv/imv.h b/src/libtnccs/tnc/imv/imv.h
index 3716532..fbc26a1 100644
--- a/src/libtnccs/tnc/imv/imv.h
+++ b/src/libtnccs/tnc/imv/imv.h
@@ -15,7 +15,7 @@
 
 /**
  * @defgroup imv imv
- * @ingroup tnc
+ * @ingroup libtnccs
  *
  * @defgroup imvt imv
  * @{ @ingroup imv
diff --git a/src/libtnccs/tnc/tnc.h b/src/libtnccs/tnc/tnc.h
index e5a4a29..7bf8c84 100644
--- a/src/libtnccs/tnc/tnc.h
+++ b/src/libtnccs/tnc/tnc.h
@@ -14,9 +14,12 @@
  */
 
 /**
- * @defgroup tnc tnc
+ * @defgroup libtnccs libtnccs
  *
- * @addtogroup tnc
+ * @defgroup tplugins plugins
+ * @ingroup libtnccs
+ *
+ * @addtogroup libtnccs
  * @{
  */
 
diff --git a/src/libtnccs/tnc/tnccs/tnccs.h b/src/libtnccs/tnc/tnccs/tnccs.h
index eefd556..8ff295b 100644
--- a/src/libtnccs/tnc/tnccs/tnccs.h
+++ b/src/libtnccs/tnc/tnccs/tnccs.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2010-2013 Andreas Steffen
+ * Copyright (C) 2010-2015 Andreas Steffen
  * HSR Hochschule fuer Technik Rapperswil
  *
  * This program is free software; you can redistribute it and/or modify it
@@ -15,7 +15,7 @@
 
 /**
  * @defgroup tnccs tnccs
- * @ingroup tnc
+ * @ingroup libtnccs
  *
  * @defgroup tnccst tnccs
  * @{ @ingroup tnccs
@@ -87,6 +87,20 @@ struct tnccs_t {
 	tls_t tls;
 
 	/**
+	 * Get server IP address
+	 *
+	 * @return				Server IP address
+	 */
+	host_t* (*get_server_ip)(tnccs_t *this);
+
+	/**
+	 * Get peer IP address
+	 *
+	 * @return				Peer IP address
+	 */
+	host_t* (*get_peer_ip)(tnccs_t *this);
+
+	/**
 	 * Get underlying TNC IF-T transport protocol
 	 *
 	 * @return				TNC IF-T transport protocol
@@ -135,15 +149,19 @@ struct tnccs_t {
  * Constructor definition for a pluggable TNCCS protocol implementation.
  *
  * @param is_server		TRUE if TNC Server, FALSE if TNC Client
- * @param server		Server identity
- * @param peer			Client identity
+ * @param server_id		Server identity
+ * @param peer_id		Client identity
+ * @param server_ip		Server IP address
+ * @param peer_ip		Client IP address
  * @param transport		Underlying TNC IF-T transport protocol used
  * @param cb			Callback function if TNC Server, NULL if TNC Client
  * @return				implementation of the tnccs_t interface
  */
 typedef tnccs_t *(*tnccs_constructor_t)(bool is_server,
-										identification_t *server,
-										identification_t *peer,
+										identification_t *server_id,
+										identification_t *peer_id,
+										host_t *server_ip,
+										host_t *peer_ip,
 										tnc_ift_type_t transport,
 										tnccs_cb_t cb);
 
diff --git a/src/libtnccs/tnc/tnccs/tnccs_manager.h b/src/libtnccs/tnc/tnccs/tnccs_manager.h
index 791336e..b5c85f3 100644
--- a/src/libtnccs/tnc/tnccs/tnccs_manager.h
+++ b/src/libtnccs/tnc/tnccs/tnccs_manager.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2010-2013 Andreas Steffen
+ * Copyright (C) 2010-2015 Andreas Steffen
  * HSR Hochschule fuer Technik Rapperswil
  *
  * This program is free software; you can redistribute it and/or modify it
@@ -56,16 +56,19 @@ struct tnccs_manager_t {
 	 *
 	 * @param type		  type of the TNCCS protocol
 	 * @param is_server	  TRUE if TNC Server, FALSE if TNC Client
-	 * @param server	  Server identity
-	 * @param peer		  Client identity
+	 * @param server_id	  Server identity
+	 * @param peer_id	  Client identity
+	 * @param server_ip	  Server IP address
+	 * @param peer_ip	  Client IP address
 	 * @param transport	  Underlying TNC IF-T transport protocol used
 	 * @param cb		  Callback function if TNC Server, NULL if TNC Client
 	 * @return			  TNCCS protocol instance, NULL if no constructor found
 	 */
 	tnccs_t* (*create_instance)(tnccs_manager_t *this, tnccs_type_t type,
-								bool is_server, identification_t *server,
-								identification_t *peer,
-								tnc_ift_type_t transport, tnccs_cb_t cb);
+								bool is_server, identification_t *server_id,
+								identification_t *peer_id, host_t *server_ip,
+								host_t *peer_ip, tnc_ift_type_t transport,
+								tnccs_cb_t cb);
 
 	/**
 	 * Create a TNCCS connection and assign a unique connection ID as well a
diff --git a/src/libtncif/Makefile.in b/src/libtncif/Makefile.in
index efa06b9..010fadc 100644
--- a/src/libtncif/Makefile.in
+++ b/src/libtncif/Makefile.in
@@ -193,6 +193,7 @@ DLLIB = @DLLIB@
 DLLTOOL = @DLLTOOL@
 DSYMUTIL = @DSYMUTIL@
 DUMPBIN = @DUMPBIN@
+EASY_INSTALL = @EASY_INSTALL@
 ECHO_C = @ECHO_C@
 ECHO_N = @ECHO_N@
 ECHO_T = @ECHO_T@
@@ -253,10 +254,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
 PLUGIN_CFLAGS = @PLUGIN_CFLAGS@
 PTHREADLIB = @PTHREADLIB@
 PYTHON = @PYTHON@
+PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@
 PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
 PYTHON_PLATFORM = @PYTHON_PLATFORM@
 PYTHON_PREFIX = @PYTHON_PREFIX@
 PYTHON_VERSION = @PYTHON_VERSION@
+PY_TEST = @PY_TEST@
 RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
@@ -330,6 +333,8 @@ json_CFLAGS = @json_CFLAGS@
 json_LIBS = @json_LIBS@
 libdir = @libdir@
 libexecdir = @libexecdir@
+libiptc_CFLAGS = @libiptc_CFLAGS@
+libiptc_LIBS = @libiptc_LIBS@
 linux_headers = @linux_headers@
 localedir = @localedir@
 localstatedir = @localstatedir@
diff --git a/src/libtncif/tncif_names.c b/src/libtncif/tncif_names.c
index ac948c8..b348c54 100644
--- a/src/libtncif/tncif_names.c
+++ b/src/libtncif/tncif_names.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2010 Andreas Steffen
+ * Copyright (C) 2010-2015 Andreas Steffen
  * HSR Hochschule fuer Technik Rapperswil
  *
  * This program is free software; you can redistribute it and/or modify it
@@ -46,6 +46,18 @@ ENUM(TNC_IMV_Evaluation_Result_names,
 	"don't know"
 );
 
+ENUM(TNC_Identity_names,
+	TNC_ID_UNKNOWN,
+	TNC_ID_X500_DN,
+	"unknown",
+	"IPv4 address",
+	"IPv6 address",
+	"FQDN",
+	"email address",
+	"username",
+	"X.500 DN"
+);
+
 ENUM(TNC_Subject_names,
 	TNC_SUBJECT_UNKNOWN,
 	TNC_SUBJECT_USER,
diff --git a/src/libtncif/tncif_names.h b/src/libtncif/tncif_names.h
index 75458f9..64dd14f 100644
--- a/src/libtncif/tncif_names.h
+++ b/src/libtncif/tncif_names.h
@@ -1,5 +1,6 @@
 /*
- * Copyright (C) 2011 Andreas Steffen, HSR Hochschule fuer Technik Rapperswil
+ * Copyright (C) 2011-2015 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
@@ -30,6 +31,7 @@
 extern enum_name_t *TNC_Connection_State_names;
 extern enum_name_t *TNC_IMV_Action_Recommendation_names;
 extern enum_name_t *TNC_IMV_Evaluation_Result_names;
+extern enum_name_t *TNC_Identity_names;
 extern enum_name_t *TNC_Subject_names;
 extern enum_name_t *TNC_Authentication_names;
 
diff --git a/src/manager/Makefile.in b/src/manager/Makefile.in
index 79ee9c7..500220a 100644
--- a/src/manager/Makefile.in
+++ b/src/manager/Makefile.in
@@ -245,6 +245,7 @@ DLLIB = @DLLIB@
 DLLTOOL = @DLLTOOL@
 DSYMUTIL = @DSYMUTIL@
 DUMPBIN = @DUMPBIN@
+EASY_INSTALL = @EASY_INSTALL@
 ECHO_C = @ECHO_C@
 ECHO_N = @ECHO_N@
 ECHO_T = @ECHO_T@
@@ -305,10 +306,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
 PLUGIN_CFLAGS = @PLUGIN_CFLAGS@
 PTHREADLIB = @PTHREADLIB@
 PYTHON = @PYTHON@
+PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@
 PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
 PYTHON_PLATFORM = @PYTHON_PLATFORM@
 PYTHON_PREFIX = @PYTHON_PREFIX@
 PYTHON_VERSION = @PYTHON_VERSION@
+PY_TEST = @PY_TEST@
 RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
@@ -382,6 +385,8 @@ json_CFLAGS = @json_CFLAGS@
 json_LIBS = @json_LIBS@
 libdir = @libdir@
 libexecdir = @libexecdir@
+libiptc_CFLAGS = @libiptc_CFLAGS@
+libiptc_LIBS = @libiptc_LIBS@
 linux_headers = @linux_headers@
 localedir = @localedir@
 localstatedir = @localstatedir@
diff --git a/src/medsrv/Makefile.in b/src/medsrv/Makefile.in
index 3de9153..7265457 100644
--- a/src/medsrv/Makefile.in
+++ b/src/medsrv/Makefile.in
@@ -234,6 +234,7 @@ DLLIB = @DLLIB@
 DLLTOOL = @DLLTOOL@
 DSYMUTIL = @DSYMUTIL@
 DUMPBIN = @DUMPBIN@
+EASY_INSTALL = @EASY_INSTALL@
 ECHO_C = @ECHO_C@
 ECHO_N = @ECHO_N@
 ECHO_T = @ECHO_T@
@@ -294,10 +295,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
 PLUGIN_CFLAGS = @PLUGIN_CFLAGS@
 PTHREADLIB = @PTHREADLIB@
 PYTHON = @PYTHON@
+PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@
 PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
 PYTHON_PLATFORM = @PYTHON_PLATFORM@
 PYTHON_PREFIX = @PYTHON_PREFIX@
 PYTHON_VERSION = @PYTHON_VERSION@
+PY_TEST = @PY_TEST@
 RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
@@ -371,6 +374,8 @@ json_CFLAGS = @json_CFLAGS@
 json_LIBS = @json_LIBS@
 libdir = @libdir@
 libexecdir = @libexecdir@
+libiptc_CFLAGS = @libiptc_CFLAGS@
+libiptc_LIBS = @libiptc_LIBS@
 linux_headers = @linux_headers@
 localedir = @localedir@
 localstatedir = @localstatedir@
diff --git a/src/pki/Makefile.am b/src/pki/Makefile.am
index 266802c..ab407e0 100644
--- a/src/pki/Makefile.am
+++ b/src/pki/Makefile.am
@@ -13,6 +13,7 @@ pki_SOURCES = pki.c pki.h command.c command.h \
 	commands/signcrl.c \
 	commands/acert.c \
 	commands/pkcs7.c \
+	commands/pkcs12.c \
 	commands/verify.c
 
 pki_LDADD = $(top_builddir)/src/libstrongswan/libstrongswan.la
diff --git a/src/pki/Makefile.in b/src/pki/Makefile.in
index 5f7a1bc..4205469 100644
--- a/src/pki/Makefile.in
+++ b/src/pki/Makefile.in
@@ -108,7 +108,7 @@ am_pki_OBJECTS = pki.$(OBJEXT) command.$(OBJEXT) \
 	commands/req.$(OBJEXT) commands/self.$(OBJEXT) \
 	commands/print.$(OBJEXT) commands/signcrl.$(OBJEXT) \
 	commands/acert.$(OBJEXT) commands/pkcs7.$(OBJEXT) \
-	commands/verify.$(OBJEXT)
+	commands/pkcs12.$(OBJEXT) commands/verify.$(OBJEXT)
 pki_OBJECTS = $(am_pki_OBJECTS)
 pki_DEPENDENCIES = $(top_builddir)/src/libstrongswan/libstrongswan.la
 AM_V_lt = $(am__v_lt_ at AM_V@)
@@ -243,6 +243,7 @@ DLLIB = @DLLIB@
 DLLTOOL = @DLLTOOL@
 DSYMUTIL = @DSYMUTIL@
 DUMPBIN = @DUMPBIN@
+EASY_INSTALL = @EASY_INSTALL@
 ECHO_C = @ECHO_C@
 ECHO_N = @ECHO_N@
 ECHO_T = @ECHO_T@
@@ -303,10 +304,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
 PLUGIN_CFLAGS = @PLUGIN_CFLAGS@
 PTHREADLIB = @PTHREADLIB@
 PYTHON = @PYTHON@
+PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@
 PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
 PYTHON_PLATFORM = @PYTHON_PLATFORM@
 PYTHON_PREFIX = @PYTHON_PREFIX@
 PYTHON_VERSION = @PYTHON_VERSION@
+PY_TEST = @PY_TEST@
 RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
@@ -380,6 +383,8 @@ json_CFLAGS = @json_CFLAGS@
 json_LIBS = @json_LIBS@
 libdir = @libdir@
 libexecdir = @libexecdir@
+libiptc_CFLAGS = @libiptc_CFLAGS@
+libiptc_LIBS = @libiptc_LIBS@
 linux_headers = @linux_headers@
 localedir = @localedir@
 localstatedir = @localstatedir@
@@ -450,6 +455,7 @@ pki_SOURCES = pki.c pki.h command.c command.h \
 	commands/signcrl.c \
 	commands/acert.c \
 	commands/pkcs7.c \
+	commands/pkcs12.c \
 	commands/verify.c
 
 pki_LDADD = $(top_builddir)/src/libstrongswan/libstrongswan.la
@@ -566,6 +572,8 @@ commands/acert.$(OBJEXT): commands/$(am__dirstamp) \
 	commands/$(DEPDIR)/$(am__dirstamp)
 commands/pkcs7.$(OBJEXT): commands/$(am__dirstamp) \
 	commands/$(DEPDIR)/$(am__dirstamp)
+commands/pkcs12.$(OBJEXT): commands/$(am__dirstamp) \
+	commands/$(DEPDIR)/$(am__dirstamp)
 commands/verify.$(OBJEXT): commands/$(am__dirstamp) \
 	commands/$(DEPDIR)/$(am__dirstamp)
 
@@ -586,6 +594,7 @@ distclean-compile:
 @AMDEP_TRUE@@am__include@ @am__quote at commands/$(DEPDIR)/gen.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at commands/$(DEPDIR)/issue.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at commands/$(DEPDIR)/keyid.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at commands/$(DEPDIR)/pkcs12.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at commands/$(DEPDIR)/pkcs7.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at commands/$(DEPDIR)/print.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at commands/$(DEPDIR)/pub.Po at am__quote@
diff --git a/src/pki/command.h b/src/pki/command.h
index 9cf036b..d49adda 100644
--- a/src/pki/command.h
+++ b/src/pki/command.h
@@ -24,7 +24,7 @@
 /**
  * Maximum number of commands (+1).
  */
-#define MAX_COMMANDS 12
+#define MAX_COMMANDS 13
 
 /**
  * Maximum number of options in a command (+3)
diff --git a/src/pki/commands/acert.c b/src/pki/commands/acert.c
index 185aa40..7099977 100644
--- a/src/pki/commands/acert.c
+++ b/src/pki/commands/acert.c
@@ -1,6 +1,7 @@
 /*
  * Copyright (C) 2009 Martin Willi
- * Hochschule fuer Technik Rapperswil
+ * Copyright (C) 2015 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
@@ -31,7 +32,7 @@
 static int acert()
 {
 	cred_encoding_type_t form = CERT_ASN1_DER;
-	hash_algorithm_t digest = HASH_SHA1;
+	hash_algorithm_t digest = HASH_UNKNOWN;
 	certificate_t *ac = NULL, *cert = NULL, *issuer =NULL;
 	private_key_t *private = NULL;
 	public_key_t *public = NULL;
@@ -161,6 +162,10 @@ static int acert()
 		error = "loading issuer private key failed";
 		goto end;
 	}
+	if (digest == HASH_UNKNOWN)
+	{
+		digest = get_default_digest(private);
+	}
 	if (!private->belongs_to(private, public))
 	{
 		error = "issuer private key does not match issuer certificate";
@@ -286,7 +291,7 @@ static void __attribute__ ((constructor))reg()
 			{"not-before",		'F', 1, "date/time the validity of the AC starts"},
 			{"not-after",		'T', 1, "date/time the validity of the AC ends"},
 			{"dateform",		'D', 1, "strptime(3) input format, default: %d.%m.%y %T"},
-			{"digest",			'g', 1, "digest for signature creation, default: sha1"},
+			{"digest",			'g', 1, "digest for signature creation, default: key-specific"},
 			{"outform",			'f', 1, "encoding of generated cert, default: der"},
 		}
 	});
diff --git a/src/pki/commands/gen.c b/src/pki/commands/gen.c
index ce28a09..8b11854 100644
--- a/src/pki/commands/gen.c
+++ b/src/pki/commands/gen.c
@@ -1,6 +1,7 @@
 /*
  * Copyright (C) 2009 Martin Willi
- * Hochschule fuer Technik Rapperswil
+ * Copyright (C) 2014-2015 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
@@ -43,6 +44,10 @@ static int gen()
 				{
 					type = KEY_ECDSA;
 				}
+				else if (streq(arg, "bliss"))
+				{
+					type = KEY_BLISS;
+				}
 				else
 				{
 					return command_usage("invalid key type");
@@ -96,6 +101,9 @@ static int gen()
 			case KEY_ECDSA:
 				size = 384;
 				break;
+			case KEY_BLISS:
+				size = 1;
+				break;
 			default:
 				break;
 		}
@@ -151,12 +159,12 @@ static void __attribute__ ((constructor))reg()
 {
 	command_register((command_t) {
 		gen, 'g', "gen", "generate a new private key",
-		{"  [--type rsa|ecdsa] [--size bits] [--safe-primes]",
+		{"  [--type rsa|ecdsa|bliss] [--size bits] [--safe-primes]",
 		 "[--shares n] [--threshold l] [--outform der|pem]"},
 		{
 			{"help",		'h', 0, "show usage information"},
 			{"type",		't', 1, "type of key, default: rsa"},
-			{"size",		's', 1, "keylength in bits, default: rsa 2048, ecdsa 384"},
+			{"size",		's', 1, "keylength in bits, default: rsa 2048, ecdsa 384, bliss 1"},
 			{"safe-primes", 'p', 0, "generate rsa safe primes"},
 			{"shares",		'n', 1, "number of private rsa key shares"},
 			{"threshold",	'l', 1, "minimum number of participating rsa key shares"},
diff --git a/src/pki/commands/issue.c b/src/pki/commands/issue.c
index aaa2c2f..6a2d09d 100644
--- a/src/pki/commands/issue.c
+++ b/src/pki/commands/issue.c
@@ -1,6 +1,7 @@
 /*
  * Copyright (C) 2009 Martin Willi
- * Hochschule fuer Technik Rapperswil
+ * Copyright (C) 2015 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
@@ -59,7 +60,7 @@ static void destroy_cdp(x509_cdp_t *this)
 static int issue()
 {
 	cred_encoding_type_t form = CERT_ASN1_DER;
-	hash_algorithm_t digest = HASH_SHA1;
+	hash_algorithm_t digest = HASH_UNKNOWN;
 	certificate_t *cert_req = NULL, *cert = NULL, *ca =NULL;
 	private_key_t *private = NULL;
 	public_key_t *public = NULL;
@@ -287,6 +288,7 @@ static int issue()
 		}
 		break;
 	}
+
 	if (!cacert)
 	{
 		error = "--cacert is required";
@@ -355,6 +357,10 @@ static int issue()
 		error = "loading CA private key failed";
 		goto end;
 	}
+	if (digest == HASH_UNKNOWN)
+	{
+		digest = get_default_digest(private);
+	}
 	if (!private->belongs_to(private, public))
 	{
 		error = "CA private key does not match CA certificate";
@@ -589,7 +595,7 @@ static void __attribute__ ((constructor))reg()
 			{"crl",				'u', 1, "CRL distribution point URI to include"},
 			{"crlissuer",		'I', 1, "CRL Issuer for CRL at distribution point"},
 			{"ocsp",			'o', 1, "OCSP AuthorityInfoAccess URI to include"},
-			{"digest",			'g', 1, "digest for signature creation, default: sha1"},
+			{"digest",			'g', 1, "digest for signature creation, default: key-specific"},
 			{"outform",			'f', 1, "encoding of generated cert, default: der"},
 		}
 	});
diff --git a/src/pki/commands/keyid.c b/src/pki/commands/keyid.c
index c3ac0c2..3bc62e7 100644
--- a/src/pki/commands/keyid.c
+++ b/src/pki/commands/keyid.c
@@ -52,6 +52,11 @@ static int keyid()
 					type = CRED_PRIVATE_KEY;
 					subtype = KEY_ECDSA;
 				}
+				else if (streq(arg, "bliss-priv"))
+				{
+					type = CRED_PRIVATE_KEY;
+					subtype = KEY_BLISS;
+				}
 				else if (streq(arg, "pub"))
 				{
 					type = CRED_PUBLIC_KEY;
@@ -164,7 +169,7 @@ static void __attribute__ ((constructor))reg()
 	command_register((command_t)
 		{ keyid, 'k', "keyid",
 		"calculate key identifiers of a key/certificate",
-		{"[--in file] [--type rsa-priv|ecdsa-priv|pub|pkcs10|x509]"},
+		{"[--in file] [--type rsa-priv|ecdsa-priv|bliss-priv|pub|pkcs10|x509]"},
 		{
 			{"help",	'h', 0, "show usage information"},
 			{"in",		'i', 1, "input file, default: stdin"},
diff --git a/src/pki/commands/pkcs12.c b/src/pki/commands/pkcs12.c
new file mode 100644
index 0000000..dcd1496
--- /dev/null
+++ b/src/pki/commands/pkcs12.c
@@ -0,0 +1,247 @@
+/*
+ * Copyright (C) 2014 Tobias Brunner
+ * Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * for more details.
+ */
+
+#include <errno.h>
+
+#include "pki.h"
+
+#include <credentials/certificates/x509.h>
+#include <credentials/containers/pkcs12.h>
+
+/**
+ * Show info about PKCS#12 container
+ */
+static int show(pkcs12_t *pkcs12)
+{
+	enumerator_t *enumerator;
+	certificate_t *cert;
+	private_key_t *key;
+	int index = 1;
+
+	printf("Certificates:\n");
+	enumerator = pkcs12->create_cert_enumerator(pkcs12);
+	while (enumerator->enumerate(enumerator, &cert))
+	{
+		x509_t *x509 = (x509_t*)cert;
+
+		if (x509->get_flags(x509) & X509_CA)
+		{
+			printf("[%2d] \"%Y\" (CA)\n", index++, cert->get_subject(cert));
+		}
+		else
+		{
+			printf("[%2d] \"%Y\"\n", index++, cert->get_subject(cert));
+		}
+	}
+	enumerator->destroy(enumerator);
+
+	printf("Private keys:\n");
+	enumerator = pkcs12->create_key_enumerator(pkcs12);
+	while (enumerator->enumerate(enumerator, &key))
+	{
+		printf("[%2d] %N %d bits\n", index++, key_type_names,
+			   key->get_type(key), key->get_keysize(key));
+	}
+	enumerator->destroy(enumerator);
+	return 0;
+}
+
+static int export(pkcs12_t *pkcs12, int index, char *outform)
+{
+	cred_encoding_type_t form;
+	enumerator_t *enumerator;
+	certificate_t *cert;
+	private_key_t *key;
+	chunk_t encoding;
+	int i = 1;
+
+	enumerator = pkcs12->create_cert_enumerator(pkcs12);
+	while (enumerator->enumerate(enumerator, &cert))
+	{
+		if (i++ == index)
+		{
+			form = CERT_ASN1_DER;
+			if (outform && !get_form(outform, &form, CRED_CERTIFICATE))
+			{
+				enumerator->destroy(enumerator);
+				return command_usage("invalid output format");
+			}
+			if (cert->get_encoding(cert, form, &encoding))
+			{
+				set_file_mode(stdout, form);
+				if (fwrite(encoding.ptr, encoding.len, 1, stdout) == 1)
+				{
+					free(encoding.ptr);
+					enumerator->destroy(enumerator);
+					return 0;
+				}
+				free(encoding.ptr);
+			}
+			fprintf(stderr, "certificate export failed\n");
+			enumerator->destroy(enumerator);
+			return 1;
+		}
+	}
+	enumerator->destroy(enumerator);
+
+	enumerator = pkcs12->create_key_enumerator(pkcs12);
+	while (enumerator->enumerate(enumerator, &key))
+	{
+		if (i++ == index)
+		{
+			form = PRIVKEY_ASN1_DER;
+			if (outform && !get_form(outform, &form, CRED_PRIVATE_KEY))
+			{
+				enumerator->destroy(enumerator);
+				return command_usage("invalid output format");
+			}
+			if (key->get_encoding(key, form, &encoding))
+			{
+				set_file_mode(stdout, form);
+				if (fwrite(encoding.ptr, encoding.len, 1, stdout) == 1)
+				{
+					free(encoding.ptr);
+					enumerator->destroy(enumerator);
+					return 0;
+				}
+				free(encoding.ptr);
+			}
+			fprintf(stderr, "private key export failed\n");
+			enumerator->destroy(enumerator);
+			return 0;
+		}
+	}
+	enumerator->destroy(enumerator);
+
+	fprintf(stderr, "invalid index %d\n", index);
+	return 1;
+}
+
+
+/**
+ * Handle PKCs#12 containers
+ */
+static int pkcs12()
+{
+	char *arg, *file = NULL, *outform = NULL;
+	pkcs12_t *p12 = NULL;
+	int res = 1, index = 0;
+	enum {
+		OP_NONE,
+		OP_LIST,
+		OP_EXPORT,
+	} op = OP_NONE;
+
+	while (TRUE)
+	{
+		switch (command_getopt(&arg))
+		{
+			case 'h':
+				return command_usage(NULL);
+			case 'i':
+				file = arg;
+				continue;
+			case 'l':
+				if (op != OP_NONE)
+				{
+					goto invalid;
+				}
+				op = OP_LIST;
+				continue;
+			case 'e':
+				if (op != OP_NONE)
+				{
+					goto invalid;
+				}
+				op = OP_EXPORT;
+				index = atoi(arg);
+				continue;
+			case 'f':
+				outform = arg;
+				continue;
+			case EOF:
+				break;
+			default:
+			invalid:
+				return command_usage("invalid --pkcs12 option");
+		}
+		break;
+	}
+
+	if (file)
+	{
+		p12 = lib->creds->create(lib->creds, CRED_CONTAINER, CONTAINER_PKCS12,
+								  BUILD_FROM_FILE, file, BUILD_END);
+	}
+	else
+	{
+		chunk_t chunk;
+
+		set_file_mode(stdin, CERT_ASN1_DER);
+		if (!chunk_from_fd(0, &chunk))
+		{
+			fprintf(stderr, "reading input failed: %s\n", strerror(errno));
+			return 1;
+		}
+		p12 = lib->creds->create(lib->creds, CRED_CONTAINER, CONTAINER_PKCS12,
+								  BUILD_BLOB, chunk, BUILD_END);
+		free(chunk.ptr);
+	}
+
+	if (!p12)
+	{
+		fprintf(stderr, "reading input failed!\n");
+		goto end;
+	}
+
+	switch (op)
+	{
+		case OP_LIST:
+			res = show(p12);
+			break;
+		case OP_EXPORT:
+			res = export(p12, index, outform);
+			break;
+		default:
+			p12->container.destroy(&p12->container);
+			return command_usage(NULL);
+	}
+
+end:
+	if (p12)
+	{
+		p12->container.destroy(&p12->container);
+	}
+	return res;
+}
+
+/**
+ * Register the command.
+ */
+static void __attribute__ ((constructor))reg()
+{
+	command_register((command_t) {
+		pkcs12, 'u', "pkcs12", "PKCS#12 functions",
+		{"--export index|--list [--in file]",
+		 "[--outform der|pem]"},
+		{
+			{"help",	'h', 0, "show usage information"},
+			{"in",		'i', 1, "input file, default: stdin"},
+			{"list",	'l', 0, "list certificates and keys"},
+			{"export",	'e', 1, "export the credential with the given index"},
+			{"outform",	'f', 1, "encoding of exported credentials, default: der"},
+		}
+	});
+}
diff --git a/src/pki/commands/print.c b/src/pki/commands/print.c
index fb07169..fa69de1 100644
--- a/src/pki/commands/print.c
+++ b/src/pki/commands/print.c
@@ -32,9 +32,12 @@
 static void print_pubkey(public_key_t *key)
 {
 	chunk_t chunk;
+	key_type_t type;
+
+	type = key->get_type(key);
+	printf("pubkey:    %N %d bits%s\n", key_type_names, type,
+			key->get_keysize(key), (type == KEY_BLISS) ? " strength" : "");
 
-	printf("pubkey:    %N %d bits\n", key_type_names, key->get_type(key),
-		   key->get_keysize(key));
 	if (key->get_fingerprint(key, KEYID_PUBKEY_INFO_SHA1, &chunk))
 	{
 		printf("keyid:     %#B\n", &chunk);
@@ -66,6 +69,22 @@ static void print_key(private_key_t *key)
 }
 
 /**
+ * Get a prefix for a named constraint identity type
+ */
+static char* get_type_pfx(identification_t *id)
+{
+	switch (id->get_type(id))
+	{
+		case ID_RFC822_ADDR:
+			return "email:";
+		case ID_FQDN:
+			return "dns:";
+		default:
+			return "";
+	}
+}
+
+/**
  * Print X509 specific certificate information
  */
 static void print_x509(x509_t *x509)
@@ -202,7 +221,7 @@ static void print_x509(x509_t *x509)
 			printf("Permitted NameConstraints:\n");
 			first = FALSE;
 		}
-		printf("           %Y\n", id);
+		printf("           %s%Y\n", get_type_pfx(id), id);
 	}
 	enumerator->destroy(enumerator);
 	first = TRUE;
@@ -214,7 +233,7 @@ static void print_x509(x509_t *x509)
 			printf("Excluded NameConstraints:\n");
 			first = FALSE;
 		}
-		printf("           %Y\n", id);
+		printf("           %s%Y\n", get_type_pfx(id), id);
 	}
 	enumerator->destroy(enumerator);
 
@@ -580,6 +599,11 @@ static int print()
 					type = CRED_PRIVATE_KEY;
 					subtype = KEY_ECDSA;
 				}
+				else if (streq(arg, "bliss-priv"))
+				{
+					type = CRED_PRIVATE_KEY;
+					subtype = KEY_BLISS;
+				}
 				else
 				{
 					return command_usage( "invalid input type");
@@ -652,7 +676,7 @@ static void __attribute__ ((constructor))reg()
 	command_register((command_t)
 		{ print, 'a', "print",
 		"print a credential in a human readable form",
-		{"[--in file] [--type rsa-priv|ecdsa-priv|pub|x509|crl|ac]"},
+		{"[--in file] [--type rsa-priv|ecdsa-priv|bliss-priv|pub|x509|crl|ac]"},
 		{
 			{"help",	'h', 0, "show usage information"},
 			{"in",		'i', 1, "input file, default: stdin"},
diff --git a/src/pki/commands/pub.c b/src/pki/commands/pub.c
index b8d2f70..ccc3c42 100644
--- a/src/pki/commands/pub.c
+++ b/src/pki/commands/pub.c
@@ -1,6 +1,7 @@
 /*
  * Copyright (C) 2009 Martin Willi
- * Hochschule fuer Technik Rapperswil
+ * Copyright (C) 2015 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
@@ -53,6 +54,11 @@ static int pub()
 					type = CRED_PRIVATE_KEY;
 					subtype = KEY_ECDSA;
 				}
+				else if (streq(arg, "bliss"))
+				{
+					type = CRED_PRIVATE_KEY;
+					subtype = KEY_BLISS;
+				}
 				else if (streq(arg, "pub"))
 				{
 					type = CRED_PUBLIC_KEY;
@@ -183,7 +189,7 @@ static void __attribute__ ((constructor))reg()
 	command_register((command_t) {
 		pub, 'p', "pub",
 		"extract the public key from a private key/certificate",
-		{"[--in file|--keyid hex] [--type rsa|ecdsa|pub|pkcs10|x509]",
+		{"[--in file|--keyid hex] [--type rsa|ecdsa|bliss|pub|pkcs10|x509]",
 		 "[--outform der|pem|dnskey|sshkey]"},
 		{
 			{"help",	'h', 0, "show usage information"},
diff --git a/src/pki/commands/req.c b/src/pki/commands/req.c
index 0236835..da991b5 100644
--- a/src/pki/commands/req.c
+++ b/src/pki/commands/req.c
@@ -1,6 +1,7 @@
 /*
  * Copyright (C) 2009 Martin Willi
- * Copyright (C) 2009 Andreas Steffen
+ * Copyright (C) 2009-2015 Andreas Steffen
+ * HSR Hochschule fuer Technik Rapperswil
  *
  * HSR Hochschule fuer Technik Rapperswil
  *
@@ -30,7 +31,7 @@ static int req()
 {
 	cred_encoding_type_t form = CERT_ASN1_DER;
 	key_type_t type = KEY_RSA;
-	hash_algorithm_t digest = HASH_SHA1;
+	hash_algorithm_t digest = HASH_UNKNOWN;
 	certificate_t *cert = NULL;
 	private_key_t *private = NULL;
 	char *file = NULL, *dn = NULL, *error = NULL;
@@ -57,6 +58,10 @@ static int req()
 				{
 					type = KEY_ECDSA;
 				}
+				else if (streq(arg, "bliss"))
+				{
+					type = KEY_BLISS;
+				}
 				else
 				{
 					error = "invalid input type";
@@ -134,6 +139,10 @@ static int req()
 		error = "parsing private key failed";
 		goto end;
 	}
+	if (digest == HASH_UNKNOWN)
+	{
+		digest = get_default_digest(private);
+	}
 	cert = lib->creds->create(lib->creds, CRED_CERTIFICATE, CERT_PKCS10_REQUEST,
 							  BUILD_SIGNING_KEY, private,
 							  BUILD_SUBJECT, id,
@@ -185,7 +194,7 @@ static void __attribute__ ((constructor))reg()
 	command_register((command_t) {
 		req, 'r', "req",
 		"create a PKCS#10 certificate request",
-		{"  [--in file] [--type rsa|ecdsa] --dn distinguished-name",
+		{"  [--in file] [--type rsa|ecdsa|bliss] --dn distinguished-name",
 		 "[--san subjectAltName]+ [--password challengePassword]",
 		 "[--digest md5|sha1|sha224|sha256|sha384|sha512] [--outform der|pem]"},
 		{
@@ -195,7 +204,7 @@ static void __attribute__ ((constructor))reg()
 			{"dn",		'd', 1, "subject distinguished name"},
 			{"san",		'a', 1, "subjectAltName to include in cert request"},
 			{"password",'p', 1, "challengePassword to include in cert request"},
-			{"digest",	'g', 1, "digest for signature creation, default: sha1"},
+			{"digest",	'g', 1, "digest for signature creation, default: key-specific"},
 			{"outform",	'f', 1, "encoding of generated request, default: der"},
 		}
 	});
diff --git a/src/pki/commands/self.c b/src/pki/commands/self.c
index daefcdc..a785c2a 100644
--- a/src/pki/commands/self.c
+++ b/src/pki/commands/self.c
@@ -1,6 +1,7 @@
 /*
  * Copyright (C) 2009 Martin Willi
- * Hochschule fuer Technik Rapperswil
+ * Copyright (C) 2015 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
@@ -49,7 +50,7 @@ static int self()
 {
 	cred_encoding_type_t form = CERT_ASN1_DER;
 	key_type_t type = KEY_RSA;
-	hash_algorithm_t digest = HASH_SHA1;
+	hash_algorithm_t digest = HASH_UNKNOWN;
 	certificate_t *cert = NULL;
 	private_key_t *private = NULL;
 	public_key_t *public = NULL;
@@ -57,7 +58,8 @@ static int self()
 	identification_t *id = NULL;
 	linked_list_t *san, *ocsp, *permitted, *excluded, *policies, *mappings;
 	int pathlen = X509_NO_CONSTRAINT, inhibit_any = X509_NO_CONSTRAINT;
-	int inhibit_mapping = X509_NO_CONSTRAINT, require_explicit = X509_NO_CONSTRAINT;
+	int inhibit_mapping = X509_NO_CONSTRAINT;
+	int require_explicit = X509_NO_CONSTRAINT;
 	chunk_t serial = chunk_empty;
 	chunk_t encoding = chunk_empty;
 	time_t not_before, not_after, lifetime = 1095 * 24 * 60 * 60;
@@ -88,6 +90,10 @@ static int self()
 				{
 					type = KEY_ECDSA;
 				}
+				else if (streq(arg, "bliss"))
+				{
+					type = KEY_BLISS;
+				}
 				else
 				{
 					error = "invalid input type";
@@ -308,6 +314,10 @@ static int self()
 		error = "loading private key failed";
 		goto end;
 	}
+	if (digest == HASH_UNKNOWN)
+	{
+		digest = get_default_digest(private);
+	}
 	public = private->get_public_key(private);
 	if (!public)
 	{
@@ -407,7 +417,7 @@ static void __attribute__ ((constructor))reg()
 	command_register((command_t) {
 		self, 's', "self",
 		"create a self signed certificate",
-		{" [--in file|--keyid hex] [--type rsa|ecdsa]",
+		{" [--in file|--keyid hex] [--type rsa|ecdsa|bliss]",
 		 " --dn distinguished-name [--san subjectAltName]+",
 		 "[--lifetime days] [--serial hex] [--ca] [--ocsp uri]+",
 		 "[--flag serverAuth|clientAuth|crlSign|ocspSigning|msSmartcardLogon]+",
@@ -441,7 +451,7 @@ static void __attribute__ ((constructor))reg()
 			{"policy-any",		'A', 1, "inhibitAnyPolicy constraint"},
 			{"flag",			'e', 1, "include extendedKeyUsage flag"},
 			{"ocsp",			'o', 1, "OCSP AuthorityInfoAccess URI to include"},
-			{"digest",			'g', 1, "digest for signature creation, default: sha1"},
+			{"digest",			'g', 1, "digest for signature creation, default: key-specific"},
 			{"outform",			'f', 1, "encoding of generated cert, default: der"},
 		}
 	});
diff --git a/src/pki/commands/signcrl.c b/src/pki/commands/signcrl.c
index e5f49ef..720dfd8 100644
--- a/src/pki/commands/signcrl.c
+++ b/src/pki/commands/signcrl.c
@@ -117,7 +117,7 @@ static int sign_crl()
 	certificate_t *ca = NULL, *crl = NULL;
 	crl_t *lastcrl = NULL;
 	x509_t *x509;
-	hash_algorithm_t digest = HASH_SHA1;
+	hash_algorithm_t digest = HASH_UNKNOWN;
 	char *arg, *cacert = NULL, *cakey = NULL, *lastupdate = NULL, *error = NULL;
 	char *basecrl = NULL;
 	char serial[512], *keyid = NULL;
@@ -330,6 +330,10 @@ static int sign_crl()
 		error = "loading CA private key failed";
 		goto error;
 	}
+	if (digest == HASH_UNKNOWN)
+	{
+		digest = get_default_digest(private);
+	}
 	if (!private->belongs_to(private, public))
 	{
 		error = "CA private key does not match CA certificate";
@@ -465,7 +469,7 @@ static void __attribute__ ((constructor))reg()
 			{"serial",		's', 1, "hex encoded certificate serial number to revoke"},
 			{"reason",		'r', 1, "reason for certificate revocation"},
 			{"date",		'd', 1, "revocation date as unix timestamp, default: now"},
-			{"digest",		'g', 1, "digest for signature creation, default: sha1"},
+			{"digest",		'g', 1, "digest for signature creation, default: key-specific"},
 			{"outform",		'f', 1, "encoding of generated crl, default: der"},
 		}
 	});
diff --git a/src/pki/man/Makefile.in b/src/pki/man/Makefile.in
index c288015..45355ba 100644
--- a/src/pki/man/Makefile.in
+++ b/src/pki/man/Makefile.in
@@ -81,10 +81,11 @@ subdir = src/pki/man
 DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
 	$(srcdir)/pki.1.in $(srcdir)/pki---gen.1.in \
 	$(srcdir)/pki---issue.1.in $(srcdir)/pki---keyid.1.in \
-	$(srcdir)/pki---pkcs7.1.in $(srcdir)/pki---print.1.in \
-	$(srcdir)/pki---pub.1.in $(srcdir)/pki---req.1.in \
-	$(srcdir)/pki---self.1.in $(srcdir)/pki---signcrl.1.in \
-	$(srcdir)/pki---acert.1.in $(srcdir)/pki---verify.1.in
+	$(srcdir)/pki---pkcs7.1.in $(srcdir)/pki---pkcs12.1.in \
+	$(srcdir)/pki---print.1.in $(srcdir)/pki---pub.1.in \
+	$(srcdir)/pki---req.1.in $(srcdir)/pki---self.1.in \
+	$(srcdir)/pki---signcrl.1.in $(srcdir)/pki---acert.1.in \
+	$(srcdir)/pki---verify.1.in
 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
 am__aclocal_m4_deps = $(top_srcdir)/m4/config/libtool.m4 \
 	$(top_srcdir)/m4/config/ltoptions.m4 \
@@ -101,8 +102,9 @@ am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
 mkinstalldirs = $(install_sh) -d
 CONFIG_HEADER = $(top_builddir)/config.h
 CONFIG_CLEAN_FILES = pki.1 pki---gen.1 pki---issue.1 pki---keyid.1 \
-	pki---pkcs7.1 pki---print.1 pki---pub.1 pki---req.1 \
-	pki---self.1 pki---signcrl.1 pki---acert.1 pki---verify.1
+	pki---pkcs7.1 pki---pkcs12.1 pki---print.1 pki---pub.1 \
+	pki---req.1 pki---self.1 pki---signcrl.1 pki---acert.1 \
+	pki---verify.1
 CONFIG_CLEAN_VPATH_FILES =
 AM_V_P = $(am__v_P_ at AM_V@)
 am__v_P_ = $(am__v_P_ at AM_DEFAULT_V@)
@@ -181,6 +183,7 @@ DLLIB = @DLLIB@
 DLLTOOL = @DLLTOOL@
 DSYMUTIL = @DSYMUTIL@
 DUMPBIN = @DUMPBIN@
+EASY_INSTALL = @EASY_INSTALL@
 ECHO_C = @ECHO_C@
 ECHO_N = @ECHO_N@
 ECHO_T = @ECHO_T@
@@ -241,10 +244,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
 PLUGIN_CFLAGS = @PLUGIN_CFLAGS@
 PTHREADLIB = @PTHREADLIB@
 PYTHON = @PYTHON@
+PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@
 PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
 PYTHON_PLATFORM = @PYTHON_PLATFORM@
 PYTHON_PREFIX = @PYTHON_PREFIX@
 PYTHON_VERSION = @PYTHON_VERSION@
+PY_TEST = @PY_TEST@
 RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
@@ -318,6 +323,8 @@ json_CFLAGS = @json_CFLAGS@
 json_LIBS = @json_LIBS@
 libdir = @libdir@
 libexecdir = @libexecdir@
+libiptc_CFLAGS = @libiptc_CFLAGS@
+libiptc_LIBS = @libiptc_LIBS@
 linux_headers = @linux_headers@
 localedir = @localedir@
 localstatedir = @localstatedir@
@@ -434,6 +441,8 @@ pki---keyid.1: $(top_builddir)/config.status $(srcdir)/pki---keyid.1.in
 	cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@
 pki---pkcs7.1: $(top_builddir)/config.status $(srcdir)/pki---pkcs7.1.in
 	cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@
+pki---pkcs12.1: $(top_builddir)/config.status $(srcdir)/pki---pkcs12.1.in
+	cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@
 pki---print.1: $(top_builddir)/config.status $(srcdir)/pki---print.1.in
 	cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@
 pki---pub.1: $(top_builddir)/config.status $(srcdir)/pki---pub.1.in
diff --git a/src/pki/man/pki---acert.1.in b/src/pki/man/pki---acert.1.in
index ec1d8be..d7460fd 100644
--- a/src/pki/man/pki---acert.1.in
+++ b/src/pki/man/pki---acert.1.in
@@ -99,8 +99,8 @@ Serial number in hex. It is randomly allocated by default.
 .TP
 .BI "\-g, \-\-digest " digest
 Digest to use for signature creation. One of \fImd5\fR, \fIsha1\fR,
-\fIsha224\fR, \fIsha256\fR, \fIsha384\fR, or \fIsha512\fR. Defaults to
-\fIsha1\fR.
+\fIsha224\fR, \fIsha256\fR, \fIsha384\fR, or \fIsha512\fR. The default is
+determined based on the type and size of the signature key.
 .TP
 .BI "\-f, \-\-outform " encoding
 Encoding of the created certificate file. Either \fIder\fR (ASN.1 DER) or
diff --git a/src/pki/man/pki---issue.1.in b/src/pki/man/pki---issue.1.in
index 375cb2f..3a89059 100644
--- a/src/pki/man/pki---issue.1.in
+++ b/src/pki/man/pki---issue.1.in
@@ -122,8 +122,8 @@ Add extendedKeyUsage flag. One of \fIserverAuth\fR, \fIclientAuth\fR,
 .TP
 .BI "\-g, \-\-digest " digest
 Digest to use for signature creation. One of \fImd5\fR, \fIsha1\fR,
-\fIsha224\fR, \fIsha256\fR, \fIsha384\fR, or \fIsha512\fR. Defaults to
-\fIsha1\fR.
+\fIsha224\fR, \fIsha256\fR, \fIsha384\fR, or \fIsha512\fR.  The default is
+determined based on the type and size of the signature key.
 .TP
 .BI "\-f, \-\-outform " encoding
 Encoding of the created certificate file. Either \fIder\fR (ASN.1 DER) or
@@ -147,10 +147,22 @@ times.
 Set path length constraint.
 .TP
 .BI "\-n, \-\-nc-permitted " name
-Add permitted NameConstraint extension to certificate.
+Add permitted NameConstraint extension to certificate. For DNS or email
+constraints, the identity type is not always detectable by the given name. Use
+the
+.B dns:
+or
+.B email:
+prefix to force a constraint type.
 .TP
 .BI "\-N, \-\-nc-excluded " name
-Add excluded NameConstraint extension to certificate.
+Add excluded NameConstraint extension to certificate. For DNS or email
+constraints, the identity type is not always detectable by the given name. Use
+the
+.B dns:
+or
+.B email:
+prefix to force a constraint type.
 .TP
 .BI "\-M, \-\-policy-mapping " issuer-oid:subject-oid
 Add policyMapping from issuer to subject OID.
diff --git a/src/pki/man/pki---pkcs12.1.in b/src/pki/man/pki---pkcs12.1.in
new file mode 100644
index 0000000..470a663
--- /dev/null
+++ b/src/pki/man/pki---pkcs12.1.in
@@ -0,0 +1,62 @@
+.TH "PKI \-\-PKCS12" 1 "2014-10-17" "@PACKAGE_VERSION@" "strongSwan"
+.
+.SH "NAME"
+.
+pki \-\-pkcs12 \- Provides PKCS#12 functions
+.
+.SH "SYNOPSIS"
+.
+.SY pki\ \-\-pkcs12
+.BR \-\-list
+.OP \-\-in file
+.OP \-\-debug level
+.YS
+.
+.SY pki\ \-\-pkcs12
+.BI \-\-export\~ index
+.OP \-\-in file
+.OP \-\-outform encoding
+.OP \-\-debug level
+.YS
+.
+.SY pki\ \-\-pkcs12
+.BI \-\-options\~ file
+.YS
+.
+.SY "pki \-\-pkcs12"
+.B \-h
+|
+.B \-\-help
+.YS
+.
+.SH "DESCRIPTION"
+.
+This sub-command of
+.BR pki (1)
+provides functions to work with PKCS#12 containers.
+.
+.SH "OPTIONS"
+.
+.TP
+.B "\-h, \-\-help"
+Print usage information with a summary of the available options.
+.TP
+.BI "\-v, \-\-debug " level
+Set debug level, default: 1.
+.TP
+.BI "\-+, \-\-options " file
+Read command line options from \fIfile\fR.
+.TP
+.BI "\-l, \-\-list"
+List certificates and keys contained in a PKCS#12 container.
+.TP
+.BI "\-e, \-\-export " index
+Export the credential with the given \fIindex\fR.  Use \fI\-\-list\fR to
+determine the index of certificates and keys.
+.TP
+.BI "\-i, \-\-in " file
+PKCS#12 input file. If not given the input is read from \fISTDIN\fR.
+.
+.SH "SEE ALSO"
+.
+.BR pki (1)
\ No newline at end of file
diff --git a/src/pki/man/pki---req.1.in b/src/pki/man/pki---req.1.in
index ab144ce..a6f6a48 100644
--- a/src/pki/man/pki---req.1.in
+++ b/src/pki/man/pki---req.1.in
@@ -62,8 +62,8 @@ The challengePassword to include in the certificate request.
 .TP
 .BI "\-g, \-\-digest " digest
 Digest to use for signature creation. One of \fImd5\fR, \fIsha1\fR,
-\fIsha224\fR, \fIsha256\fR, \fIsha384\fR, or \fIsha512\fR. Defaults to
-\fIsha1\fR.
+\fIsha224\fR, \fIsha256\fR, \fIsha384\fR, or \fIsha512\fR.  The default is
+determined based on the type and size of the signature key.
 .TP
 .BI "\-f, \-\-outform " encoding
 Encoding of the created certificate file. Either \fIder\fR (ASN.1 DER) or
diff --git a/src/pki/man/pki---self.1.in b/src/pki/man/pki---self.1.in
index 5e6e78b..53f53f8 100644
--- a/src/pki/man/pki---self.1.in
+++ b/src/pki/man/pki---self.1.in
@@ -109,8 +109,8 @@ Add extendedKeyUsage flag. One of \fIserverAuth\fR, \fIclientAuth\fR,
 .TP
 .BI "\-g, \-\-digest " digest
 Digest to use for signature creation. One of \fImd5\fR, \fIsha1\fR,
-\fIsha224\fR, \fIsha256\fR, \fIsha384\fR, or \fIsha512\fR. Defaults to
-\fIsha1\fR.
+\fIsha224\fR, \fIsha256\fR, \fIsha384\fR, or \fIsha512\fR.  The default is
+determined based on the type and size of the signature key.
 .TP
 .BI "\-f, \-\-outform " encoding
 Encoding of the created certificate file. Either \fIder\fR (ASN.1 DER) or
@@ -127,10 +127,22 @@ times.
 Set path length constraint.
 .TP
 .BI "\-n, \-\-nc-permitted " name
-Add permitted NameConstraint extension to certificate.
+Add permitted NameConstraint extension to certificate. For DNS or email
+constraints, the identity type is not always detectable by the given name. Use
+the
+.B dns:
+or
+.B email:
+prefix to force a constraint type.
 .TP
 .BI "\-N, \-\-nc-excluded " name
-Add excluded NameConstraint extension to certificate.
+Add excluded NameConstraint extension to certificate. For DNS or email
+constraints, the identity type is not always detectable by the given name. Use
+the
+.B dns:
+or
+.B email:
+prefix to force a constraint type.
 .TP
 .BI "\-M, \-\-policy-mapping " issuer-oid:subject-oid
 Add policyMapping from issuer to subject OID.
diff --git a/src/pki/man/pki---signcrl.1.in b/src/pki/man/pki---signcrl.1.in
index bd6cba5..b930bfa 100644
--- a/src/pki/man/pki---signcrl.1.in
+++ b/src/pki/man/pki---signcrl.1.in
@@ -98,8 +98,8 @@ Freshest delta CRL URI to include in CRL. Can be used multiple times.
 .TP
 .BI "\-g, \-\-digest " digest
 Digest to use for signature creation. One of \fImd5\fR, \fIsha1\fR,
-\fIsha224\fR, \fIsha256\fR, \fIsha384\fR, or \fIsha512\fR. Defaults to
-\fIsha1\fR.
+\fIsha224\fR, \fIsha256\fR, \fIsha384\fR, or \fIsha512\fR.  The default is
+determined based on the type and size of the signature key.
 .TP
 .BI "\-f, \-\-outform " encoding
 Encoding of the created certificate file. Either \fIder\fR (ASN.1 DER) or
diff --git a/src/pki/pki.c b/src/pki/pki.c
index 434287d..4727049 100644
--- a/src/pki/pki.c
+++ b/src/pki/pki.c
@@ -1,4 +1,5 @@
 /*
+ * Copyright (C) 2012-2014 Tobias Brunner
  * Copyright (C) 2009 Martin Willi
  * Hochschule fuer Technik Rapperswil
  *
@@ -22,6 +23,7 @@
 #include <fcntl.h>
 
 #include <utils/debug.h>
+#include <credentials/sets/mem_cred.h>
 #include <credentials/sets/callback_cred.h>
 
 /**
@@ -235,12 +237,40 @@ void set_file_mode(FILE *stream, cred_encoding_type_t enc)
 #endif
 }
 
+/*
+ * Described in header
+ */
+hash_algorithm_t get_default_digest(private_key_t *private)
+{
+	enumerator_t *enumerator;
+	signature_scheme_t scheme;
+	hash_algorithm_t alg = HASH_UNKNOWN;
+
+	enumerator = signature_schemes_for_key(private->get_type(private),
+										   private->get_keysize(private));
+	if (enumerator->enumerate(enumerator, &scheme))
+	{
+		alg = hasher_from_signature_scheme(scheme);
+	}
+	enumerator->destroy(enumerator);
+
+	/* default to SHA-256 */
+	return alg == HASH_UNKNOWN ? HASH_SHA256 : alg;
+}
+
 /**
  * Callback credential set pki uses
  */
 static callback_cred_t *cb_set;
 
 /**
+ * Credential set to cache entered secrets
+ */
+static mem_cred_t *cb_creds;
+
+static shared_key_type_t prompted;
+
+/**
  * Callback function to receive credentials
  */
 static shared_key_t* cb(void *data, shared_key_type_t type,
@@ -248,7 +278,12 @@ static shared_key_t* cb(void *data, shared_key_type_t type,
 						id_match_t *match_me, id_match_t *match_other)
 {
 	char buf[64], *label, *secret = NULL;
+	shared_key_t *shared;
 
+	if (prompted == type)
+	{
+		return NULL;
+	}
 	switch (type)
 	{
 		case SHARED_PIN:
@@ -266,6 +301,7 @@ static shared_key_t* cb(void *data, shared_key_type_t type,
 #endif
 	if (secret && strlen(secret))
 	{
+		prompted = type;
 		if (match_me)
 		{
 			*match_me = ID_MATCH_PERFECT;
@@ -274,8 +310,10 @@ static shared_key_t* cb(void *data, shared_key_type_t type,
 		{
 			*match_other = ID_MATCH_NONE;
 		}
-		return shared_key_create(type,
-							chunk_clone(chunk_create(secret, strlen(secret))));
+		shared = shared_key_create(type, chunk_clone(chunk_from_str(secret)));
+		/* cache password in case it is required more than once */
+		cb_creds->add_shared(cb_creds, shared, NULL);
+		return shared->get_ref(shared);
 	}
 	return NULL;
 }
@@ -287,6 +325,8 @@ static void add_callback()
 {
 	cb_set = callback_cred_create_shared(cb, NULL);
 	lib->credmgr->add_set(lib->credmgr, &cb_set->set);
+	cb_creds = mem_cred_create();
+	lib->credmgr->add_set(lib->credmgr, &cb_creds->set);
 }
 
 /**
@@ -294,6 +334,8 @@ static void add_callback()
  */
 static void remove_callback()
 {
+	lib->credmgr->remove_set(lib->credmgr, &cb_creds->set);
+	cb_creds->destroy(cb_creds);
 	lib->credmgr->remove_set(lib->credmgr, &cb_set->set);
 	cb_set->destroy(cb_set);
 }
diff --git a/src/pki/pki.h b/src/pki/pki.h
index 1f08277..017e61d 100644
--- a/src/pki/pki.h
+++ b/src/pki/pki.h
@@ -55,4 +55,12 @@ bool calculate_lifetime(char *format, char *nbstr, char *nastr, time_t span,
  */
 void set_file_mode(FILE *stream, cred_encoding_type_t enc);
 
+/**
+ * Select default digest for signatures with the given key
+ *
+ * @param private	private key
+ * @return			hash algorithm
+ */
+hash_algorithm_t get_default_digest(private_key_t *private);
+
 #endif /** PKI_H_ @}*/
diff --git a/src/pool/Makefile.am b/src/pool/Makefile.am
index b8d662e..5ae624b 100644
--- a/src/pool/Makefile.am
+++ b/src/pool/Makefile.am
@@ -11,11 +11,13 @@ pool.o :	$(top_builddir)/config.status
 AM_CPPFLAGS = \
 	-I$(top_srcdir)/src/libstrongswan \
 	-I$(top_srcdir)/src/libhydra \
+	-I$(top_srcdir)/src/libcharon \
 	-DPLUGINS=\""${pool_plugins}\""
 
 pool_LDADD = \
 	$(top_builddir)/src/libstrongswan/libstrongswan.la \
-	$(top_builddir)/src/libhydra/libhydra.la
+	$(top_builddir)/src/libhydra/libhydra.la \
+	$(top_builddir)/src/libcharon/libcharon.la
 
 endif USE_ATTR_SQL
 
diff --git a/src/pool/Makefile.in b/src/pool/Makefile.in
index 4f753a0..b955754 100644
--- a/src/pool/Makefile.in
+++ b/src/pool/Makefile.in
@@ -109,7 +109,8 @@ am__pool_SOURCES_DIST = pool.c pool_attributes.c pool_attributes.h \
 @USE_ATTR_SQL_TRUE@	pool_usage.$(OBJEXT)
 pool_OBJECTS = $(am_pool_OBJECTS)
 @USE_ATTR_SQL_TRUE at pool_DEPENDENCIES = $(top_builddir)/src/libstrongswan/libstrongswan.la \
- at USE_ATTR_SQL_TRUE@	$(top_builddir)/src/libhydra/libhydra.la
+ at USE_ATTR_SQL_TRUE@	$(top_builddir)/src/libhydra/libhydra.la \
+ at USE_ATTR_SQL_TRUE@	$(top_builddir)/src/libcharon/libcharon.la
 AM_V_lt = $(am__v_lt_ at AM_V@)
 am__v_lt_ = $(am__v_lt_ at AM_DEFAULT_V@)
 am__v_lt_0 = --silent
@@ -228,6 +229,7 @@ DLLIB = @DLLIB@
 DLLTOOL = @DLLTOOL@
 DSYMUTIL = @DSYMUTIL@
 DUMPBIN = @DUMPBIN@
+EASY_INSTALL = @EASY_INSTALL@
 ECHO_C = @ECHO_C@
 ECHO_N = @ECHO_N@
 ECHO_T = @ECHO_T@
@@ -288,10 +290,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
 PLUGIN_CFLAGS = @PLUGIN_CFLAGS@
 PTHREADLIB = @PTHREADLIB@
 PYTHON = @PYTHON@
+PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@
 PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
 PYTHON_PLATFORM = @PYTHON_PLATFORM@
 PYTHON_PREFIX = @PYTHON_PREFIX@
 PYTHON_VERSION = @PYTHON_VERSION@
+PY_TEST = @PY_TEST@
 RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
@@ -365,6 +369,8 @@ json_CFLAGS = @json_CFLAGS@
 json_LIBS = @json_LIBS@
 libdir = @libdir@
 libexecdir = @libexecdir@
+libiptc_CFLAGS = @libiptc_CFLAGS@
+libiptc_LIBS = @libiptc_LIBS@
 linux_headers = @linux_headers@
 localedir = @localedir@
 localstatedir = @localstatedir@
@@ -430,11 +436,13 @@ xml_LIBS = @xml_LIBS@
 @USE_ATTR_SQL_TRUE at AM_CPPFLAGS = \
 @USE_ATTR_SQL_TRUE@	-I$(top_srcdir)/src/libstrongswan \
 @USE_ATTR_SQL_TRUE@	-I$(top_srcdir)/src/libhydra \
+ at USE_ATTR_SQL_TRUE@	-I$(top_srcdir)/src/libcharon \
 @USE_ATTR_SQL_TRUE@	-DPLUGINS=\""${pool_plugins}\""
 
 @USE_ATTR_SQL_TRUE at pool_LDADD = \
 @USE_ATTR_SQL_TRUE@	$(top_builddir)/src/libstrongswan/libstrongswan.la \
- at USE_ATTR_SQL_TRUE@	$(top_builddir)/src/libhydra/libhydra.la
+ at USE_ATTR_SQL_TRUE@	$(top_builddir)/src/libhydra/libhydra.la \
+ at USE_ATTR_SQL_TRUE@	$(top_builddir)/src/libcharon/libcharon.la
 
 templatesdir = $(pkgdatadir)/templates/database/sql
 dist_templates_DATA = mysql.sql sqlite.sql
diff --git a/src/pt-tls-client/Makefile.in b/src/pt-tls-client/Makefile.in
index 7ee25c0..a02db98 100644
--- a/src/pt-tls-client/Makefile.in
+++ b/src/pt-tls-client/Makefile.in
@@ -198,6 +198,7 @@ DLLIB = @DLLIB@
 DLLTOOL = @DLLTOOL@
 DSYMUTIL = @DSYMUTIL@
 DUMPBIN = @DUMPBIN@
+EASY_INSTALL = @EASY_INSTALL@
 ECHO_C = @ECHO_C@
 ECHO_N = @ECHO_N@
 ECHO_T = @ECHO_T@
@@ -258,10 +259,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
 PLUGIN_CFLAGS = @PLUGIN_CFLAGS@
 PTHREADLIB = @PTHREADLIB@
 PYTHON = @PYTHON@
+PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@
 PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
 PYTHON_PLATFORM = @PYTHON_PLATFORM@
 PYTHON_PREFIX = @PYTHON_PREFIX@
 PYTHON_VERSION = @PYTHON_VERSION@
+PY_TEST = @PY_TEST@
 RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
@@ -335,6 +338,8 @@ json_CFLAGS = @json_CFLAGS@
 json_LIBS = @json_LIBS@
 libdir = @libdir@
 libexecdir = @libexecdir@
+libiptc_CFLAGS = @libiptc_CFLAGS@
+libiptc_LIBS = @libiptc_LIBS@
 linux_headers = @linux_headers@
 localedir = @localedir@
 localstatedir = @localstatedir@
diff --git a/src/pt-tls-client/pt-tls-client.c b/src/pt-tls-client/pt-tls-client.c
index a8d45b5..3a179af 100644
--- a/src/pt-tls-client/pt-tls-client.c
+++ b/src/pt-tls-client/pt-tls-client.c
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 2010-2013 Martin Willi, revosec AG
- * Copyright (C) 2013-2014 Andreas Steffen
+ * Copyright (C) 2013-2015 Andreas Steffen
  * HSR Hochschule für Technik Rapperswil
  *
  * This program is free software; you can redistribute it and/or modify it
@@ -54,32 +54,44 @@ static int client(char *address, u_int16_t port, char *identity)
 {
 	pt_tls_client_t *assessment;
 	tls_t *tnccs;
-	identification_t *server, *client;
-	host_t *host;
+	identification_t *server_id, *client_id;
+	host_t *server_ip, *client_ip;
 	status_t status;
 
-	host = host_create_from_dns(address, AF_UNSPEC, port);
-	if (!host)
+	server_ip = host_create_from_dns(address, AF_UNSPEC, port);
+	if (!server_ip)
 	{
 		return 1;
 	}
-	server = identification_create_from_string(address);
-	client = identification_create_from_string(identity);
+
+	client_ip = host_create_any(server_ip->get_family(server_ip));
+	if (!client_ip)
+	{
+		server_ip->destroy(server_ip);
+		return 1;
+	}
+	server_id = identification_create_from_string(address);
+	client_id = identification_create_from_string(identity);
+
 	tnccs = (tls_t*)tnc->tnccs->create_instance(tnc->tnccs, TNCCS_2_0, FALSE,
-								server, client, TNC_IFT_TLS_2_0, NULL);
+								server_id, client_id, server_ip, client_ip,
+								TNC_IFT_TLS_2_0, NULL);
+	client_ip->destroy(client_ip);
+
 	if (!tnccs)
 	{
 		fprintf(stderr, "loading TNCCS failed: %s\n", PLUGINS);
-		host->destroy(host);
-		server->destroy(server);
-		client->destroy(client);
+		server_ip->destroy(server_ip);
+		server_id->destroy(server_id);
+		client_id->destroy(client_id);
 		return 1;
 	}
-	assessment = pt_tls_client_create(host, server, client);
+	assessment = pt_tls_client_create(server_ip, server_id, client_id);
 	status = assessment->run_assessment(assessment, (tnccs_t*)tnccs);
 	assessment->destroy(assessment);
 	tnccs->destroy(tnccs);
-	return status;
+
+	return (status != SUCCESS);
 }
 
 
@@ -258,6 +270,7 @@ int main(int argc, char *argv[])
 			{"port",		required_argument,		NULL,		'p' },
 			{"cert",		required_argument,		NULL,		'x' },
 			{"key",			required_argument,		NULL,		'k' },
+			{"mutual",		no_argument,			NULL,		'm' },
 			{"quiet",		no_argument,			NULL,		'q' },
 			{"debug",		required_argument,		NULL,		'd' },
 			{"optionsfrom",	required_argument,		NULL,		'+' },
@@ -299,6 +312,10 @@ int main(int argc, char *argv[])
 			case 'p':			/* --port <port> */
 				port = atoi(optarg);
 				continue;
+			case 'm':			/* --mutual */
+				lib->settings->set_bool(lib->settings,
+								"%s.plugins.tnccs-20.mutual", TRUE, lib->ns);
+				continue;
 			case 'q':       	/* --quiet */
 				log_to_stderr = FALSE;
 				continue;
diff --git a/src/scepclient/Makefile.in b/src/scepclient/Makefile.in
index 6a947ef..bcc70cb 100644
--- a/src/scepclient/Makefile.in
+++ b/src/scepclient/Makefile.in
@@ -225,6 +225,7 @@ DLLIB = @DLLIB@
 DLLTOOL = @DLLTOOL@
 DSYMUTIL = @DSYMUTIL@
 DUMPBIN = @DUMPBIN@
+EASY_INSTALL = @EASY_INSTALL@
 ECHO_C = @ECHO_C@
 ECHO_N = @ECHO_N@
 ECHO_T = @ECHO_T@
@@ -285,10 +286,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
 PLUGIN_CFLAGS = @PLUGIN_CFLAGS@
 PTHREADLIB = @PTHREADLIB@
 PYTHON = @PYTHON@
+PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@
 PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
 PYTHON_PLATFORM = @PYTHON_PLATFORM@
 PYTHON_PREFIX = @PYTHON_PREFIX@
 PYTHON_VERSION = @PYTHON_VERSION@
+PY_TEST = @PY_TEST@
 RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
@@ -362,6 +365,8 @@ json_CFLAGS = @json_CFLAGS@
 json_LIBS = @json_LIBS@
 libdir = @libdir@
 libexecdir = @libexecdir@
+libiptc_CFLAGS = @libiptc_CFLAGS@
+libiptc_LIBS = @libiptc_LIBS@
 linux_headers = @linux_headers@
 localedir = @localedir@
 localstatedir = @localstatedir@
diff --git a/src/starter/Makefile.in b/src/starter/Makefile.in
index 88d362f..ee68adc 100644
--- a/src/starter/Makefile.in
+++ b/src/starter/Makefile.in
@@ -271,6 +271,7 @@ DLLIB = @DLLIB@
 DLLTOOL = @DLLTOOL@
 DSYMUTIL = @DSYMUTIL@
 DUMPBIN = @DUMPBIN@
+EASY_INSTALL = @EASY_INSTALL@
 ECHO_C = @ECHO_C@
 ECHO_N = @ECHO_N@
 ECHO_T = @ECHO_T@
@@ -331,10 +332,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
 PLUGIN_CFLAGS = @PLUGIN_CFLAGS@
 PTHREADLIB = @PTHREADLIB@
 PYTHON = @PYTHON@
+PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@
 PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
 PYTHON_PLATFORM = @PYTHON_PLATFORM@
 PYTHON_PREFIX = @PYTHON_PREFIX@
 PYTHON_VERSION = @PYTHON_VERSION@
+PY_TEST = @PY_TEST@
 RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
@@ -408,6 +411,8 @@ json_CFLAGS = @json_CFLAGS@
 json_LIBS = @json_LIBS@
 libdir = @libdir@
 libexecdir = @libexecdir@
+libiptc_CFLAGS = @libiptc_CFLAGS@
+libiptc_LIBS = @libiptc_LIBS@
 linux_headers = @linux_headers@
 localedir = @localedir@
 localstatedir = @localstatedir@
diff --git a/src/starter/cmp.c b/src/starter/cmp.c
index cea864a..aee55d9 100644
--- a/src/starter/cmp.c
+++ b/src/starter/cmp.c
@@ -45,7 +45,7 @@ bool starter_cmp_conn(starter_conn_t *c1, starter_conn_t *c2)
 	VARCMP(mark_in.value);
 	VARCMP(mark_in.mask);
 	VARCMP(mark_out.value);
-	VARCMP(mark_in.mask);
+	VARCMP(mark_out.mask);
 	VARCMP(tfc);
 	VARCMP(sa_keying_tries);
 
diff --git a/src/starter/parser/lexer.c b/src/starter/parser/lexer.c
index 157b89c..cebf5a0 100644
--- a/src/starter/parser/lexer.c
+++ b/src/starter/parser/lexer.c
@@ -456,8 +456,8 @@ static void yy_fatal_error (yyconst char msg[] ,yyscan_t yyscanner );
 	yyg->yy_c_buf_p = yy_cp;
 
 /* %% [4.0] data tables for the DFA and the user's section 1 definitions go here */
-#define YY_NUM_RULES 28
-#define YY_END_OF_BUFFER 29
+#define YY_NUM_RULES 29
+#define YY_END_OF_BUFFER 30
 /* This struct is not used in this scanner,
    but its presence is necessary. */
 struct yy_trans_info
@@ -465,34 +465,35 @@ struct yy_trans_info
 	flex_int32_t yy_verify;
 	flex_int32_t yy_nxt;
 	};
-static yyconst flex_int16_t yy_accept[81] =
+static yyconst flex_int16_t yy_accept[83] =
     {   0,
-        0,    0,    0,    0,    0,    0,   29,   12,    3,    5,
+        0,    0,    0,    0,    0,    0,   30,   12,    3,    5,
        11,    4,    6,   12,   12,    2,   12,   12,   17,   13,
-       14,   15,   27,   19,   18,   20,   12,    3,    4,    4,
-        0,   12,    2,    0,    9,   12,   12,   17,   16,   27,
-       26,   24,   25,   21,   22,   23,   12,    0,   12,   12,
-       12,    0,   12,    8,   12,   12,    0,   12,   12,   12,
-        0,   12,   12,   12,    0,    0,   12,    0,    0,    0,
-       12,    0,    1,   10,   10,    0,    0,    0,    7,    0
+       14,   15,   28,   19,   18,   20,   12,    3,    4,    4,
+        0,   12,    2,    0,    9,   12,   12,   17,   16,   28,
+       27,   26,   27,   24,   25,   21,   22,   23,   12,    0,
+       12,   12,   12,    0,   12,    8,   12,   12,    0,   12,
+       12,   12,    0,   12,   12,   12,    0,    0,   12,    0,
+        0,    0,   12,    0,    1,   10,   10,    0,    0,    0,
+        7,    0
     } ;
 
 static yyconst flex_int32_t yy_ec[256] =
     {   0,
         1,    1,    1,    1,    1,    1,    1,    1,    2,    3,
+        1,    1,    4,    1,    1,    1,    1,    1,    1,    1,
         1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    5,    1,    6,    7,    1,    1,    1,    1,    1,
         1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
-        1,    4,    1,    5,    6,    1,    1,    1,    1,    1,
         1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        8,    1,    1,    9,    1,    1,    1,    1,    1,    1,
         1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
-        7,    1,    1,    8,    1,    1,    1,    1,    1,    1,
         1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
-        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
-        1,    9,    1,    1,    1,    1,   10,   11,   12,   13,
+        1,   10,    1,    1,    1,    1,   11,   12,   13,   14,
 
-       14,   15,   16,    1,   17,    1,    1,   18,    1,   19,
-       20,   21,    1,   22,   23,   24,   25,   26,    1,    1,
-        1,    1,    1,    1,   27,    1,    1,    1,    1,    1,
+       15,   16,   17,    1,   18,    1,    1,   19,    1,   20,
+       21,   22,    1,   23,   24,   25,   26,   27,    1,    1,
+        1,    1,    1,    1,   28,    1,    1,    1,    1,    1,
         1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
         1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
         1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
@@ -509,106 +510,110 @@ static yyconst flex_int32_t yy_ec[256] =
         1,    1,    1,    1,    1
     } ;
 
-static yyconst flex_int32_t yy_meta[28] =
+static yyconst flex_int32_t yy_meta[29] =
     {   0,
-        1,    2,    3,    2,    4,    2,    5,    1,    6,    1,
+        1,    2,    3,    1,    2,    4,    2,    5,    1,    6,
         1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
-        1,    1,    1,    1,    1,    1,    1
+        1,    1,    1,    1,    1,    1,    1,    1
     } ;
 
-static yyconst flex_int16_t yy_base[92] =
+static yyconst flex_int16_t yy_base[94] =
     {   0,
-        0,   16,   41,   49,    6,    7,  141,    0,   23,  172,
-      172,    0,  172,  134,  120,   30,   20,  120,    0,  172,
-      172,   33,    0,  172,  172,   50,    0,   60,    0,    0,
-        0,  118,   69,  115,    0,  109,  105,    0,  172,    0,
-      172,  172,  172,  172,  172,  172,   76,   71,   16,   69,
-       66,   67,   72,    0,   71,   74,   69,   69,   64,   69,
-       62,   77,   61,   55,   60,   54,   94,   66,   64,   49,
-      100,   46,  172,  172,   74,   24,   16,    5,  172,  172,
-      107,  113,  119,  125,  131,  137,  142,  147,  153,  159,
-      165
+        0,   17,   43,   52,    7,   26,  102,    0,    9,  189,
+      189,    0,  189,   93,   79,   36,   10,   83,    0,  189,
+      189,   59,    0,  189,  189,   85,    0,   32,    0,    0,
+        0,   83,   65,   80,    0,   74,   70,    0,  189,    0,
+      189,  189,   88,  189,  189,  189,  189,  189,   71,   63,
+       31,   61,   58,   59,   64,    0,   63,   66,   61,   61,
+       56,   60,   53,   64,   41,   10,   40,   32,  109,   66,
+       49,   27,  116,   37,  189,  189,   71,    8,    2,    5,
+      189,  189,  124,  130,  136,  142,  148,  154,  159,  164,
+      170,  176,  182
 
     } ;
 
-static yyconst flex_int16_t yy_def[92] =
+static yyconst flex_int16_t yy_def[94] =
     {   0,
-       81,   81,   82,   82,   83,   83,   80,   84,   80,   80,
-       80,   85,   80,   84,   84,   80,   84,   84,   86,   80,
-       80,   80,   87,   80,   80,   88,   84,   80,   85,   85,
-       84,   84,   80,   80,   84,   84,   84,   86,   80,   87,
-       80,   80,   80,   80,   80,   80,   84,   80,   84,   84,
-       84,   80,   84,   84,   84,   84,   80,   84,   84,   84,
-       80,   84,   84,   84,   80,   80,   89,   90,   91,   80,
-       89,   91,   80,   80,   90,   80,   80,   80,   80,    0,
-       80,   80,   80,   80,   80,   80,   80,   80,   80,   80,
-       80
+       83,   83,   84,   84,   85,   85,   82,   86,   82,   82,
+       82,   87,   82,   86,   86,   82,   86,   86,   88,   82,
+       82,   82,   89,   82,   82,   90,   86,   82,   87,   87,
+       86,   86,   82,   82,   86,   86,   86,   88,   82,   89,
+       82,   82,   82,   82,   82,   82,   82,   82,   86,   82,
+       86,   86,   86,   82,   86,   86,   86,   86,   82,   86,
+       86,   86,   82,   86,   86,   86,   82,   82,   91,   92,
+       93,   82,   91,   93,   82,   82,   92,   82,   82,   82,
+       82,    0,   82,   82,   82,   82,   82,   82,   82,   82,
+       82,   82,   82
 
     } ;
 
-static yyconst flex_int16_t yy_nxt[200] =
+static yyconst flex_int16_t yy_nxt[218] =
     {   0,
-       80,    9,   10,    9,   11,   12,   13,   14,   24,   24,
-       25,   25,   80,   80,   26,   26,   15,   16,   10,   16,
-       11,   12,   13,   14,   28,   79,   28,   17,   29,   35,
-       53,   33,   15,   33,   54,   29,   39,   39,   39,   36,
-       78,   18,   20,   20,   20,   21,   20,   77,   73,   22,
-       20,   20,   20,   21,   20,   34,   68,   22,   68,   39,
-       42,   28,   76,   28,   43,   29,   73,   75,   44,   75,
-       33,   45,   33,   46,   29,   75,   70,   75,   69,   67,
-       66,   65,   64,   63,   62,   61,   60,   59,   58,   57,
-       56,   55,   52,   51,   34,   72,   73,   72,   72,   72,
-
-       72,   72,   73,   72,   72,   72,   72,    8,    8,    8,
-        8,    8,    8,   19,   19,   19,   19,   19,   19,   23,
-       23,   23,   23,   23,   23,   27,   50,   49,   48,   47,
-       27,   30,   30,   37,   30,   30,   30,   38,   32,   31,
-       80,   38,   40,   40,   80,   80,   40,   41,   41,   41,
-       41,   41,   41,   71,   71,   71,   71,   71,   71,   74,
-       74,   74,   74,   80,   74,   72,   72,   72,   72,   72,
-       72,    7,   80,   80,   80,   80,   80,   80,   80,   80,
-       80,   80,   80,   80,   80,   80,   80,   80,   80,   80,
-       80,   80,   80,   80,   80,   80,   80,   80,   80
-
+       82,    9,   10,   82,    9,   11,   12,   13,   14,   24,
+       28,   70,   25,   28,   70,   29,   26,   15,   16,   10,
+       35,   16,   11,   12,   13,   14,   81,   80,   24,   17,
+       36,   25,   79,   28,   15,   26,   28,   33,   29,   75,
+       33,   78,   29,   18,   20,   20,   55,   20,   21,   20,
+       56,   75,   22,   20,   20,   72,   20,   21,   20,   71,
+       69,   22,   34,   39,   39,   39,   33,   77,   68,   33,
+       77,   29,   77,   67,   66,   77,   65,   64,   63,   62,
+       61,   60,   59,   58,   57,   54,   39,   42,   43,   53,
+       42,   34,   52,   51,   50,   49,   44,   37,   32,   31,
+
+       45,   82,   82,   82,   46,   82,   82,   47,   82,   48,
+       74,   75,   82,   74,   74,   74,   74,   74,   75,   82,
+       74,   74,   74,   74,    8,    8,    8,    8,    8,    8,
+       19,   19,   19,   19,   19,   19,   23,   23,   23,   23,
+       23,   23,   27,   82,   82,   82,   82,   27,   30,   30,
+       82,   30,   30,   30,   38,   82,   82,   82,   38,   40,
+       40,   82,   82,   40,   41,   41,   41,   41,   41,   41,
+       73,   73,   73,   73,   73,   73,   76,   76,   76,   76,
+       82,   76,   74,   74,   74,   74,   74,   74,    7,   82,
+       82,   82,   82,   82,   82,   82,   82,   82,   82,   82,
+
+       82,   82,   82,   82,   82,   82,   82,   82,   82,   82,
+       82,   82,   82,   82,   82,   82,   82
     } ;
 
-static yyconst flex_int16_t yy_chk[200] =
+static yyconst flex_int16_t yy_chk[218] =
     {   0,
-        0,    1,    1,    1,    1,    1,    1,    1,    5,    6,
-        5,    6,    0,    0,    5,    6,    1,    2,    2,    2,
-        2,    2,    2,    2,    9,   78,    9,    2,    9,   17,
-       49,   16,    2,   16,   49,   16,   22,   22,   22,   17,
-       77,    2,    3,    3,    3,    3,    3,   76,   72,    3,
-        4,    4,    4,    4,    4,   16,   64,    4,   64,   22,
-       26,   28,   70,   28,   26,   28,   69,   68,   26,   68,
-       33,   26,   33,   26,   33,   75,   66,   75,   65,   63,
-       62,   61,   60,   59,   58,   57,   56,   55,   53,   52,
-       51,   50,   48,   47,   33,   67,   67,   67,   67,   67,
-
-       67,   71,   71,   71,   71,   71,   71,   81,   81,   81,
-       81,   81,   81,   82,   82,   82,   82,   82,   82,   83,
-       83,   83,   83,   83,   83,   84,   37,   36,   34,   32,
-       84,   85,   85,   18,   85,   85,   85,   86,   15,   14,
-        7,   86,   87,   87,    0,    0,   87,   88,   88,   88,
-       88,   88,   88,   89,   89,   89,   89,   89,   89,   90,
-       90,   90,   90,    0,   90,   91,   91,   91,   91,   91,
-       91,   80,   80,   80,   80,   80,   80,   80,   80,   80,
-       80,   80,   80,   80,   80,   80,   80,   80,   80,   80,
-       80,   80,   80,   80,   80,   80,   80,   80,   80
-
+        0,    1,    1,    0,    1,    1,    1,    1,    1,    5,
+        9,   66,    5,    9,   66,    9,    5,    1,    2,    2,
+       17,    2,    2,    2,    2,    2,   80,   79,    6,    2,
+       17,    6,   78,   28,    2,    6,   28,   16,   28,   74,
+       16,   72,   16,    2,    3,    3,   51,    3,    3,    3,
+       51,   71,    3,    4,    4,   68,    4,    4,    4,   67,
+       65,    4,   16,   22,   22,   22,   33,   70,   64,   33,
+       70,   33,   77,   63,   62,   77,   61,   60,   59,   58,
+       57,   55,   54,   53,   52,   50,   22,   26,   26,   49,
+       43,   33,   37,   36,   34,   32,   26,   18,   15,   14,
+
+       26,    7,    0,    0,   26,    0,    0,   26,    0,   26,
+       69,   69,    0,   69,   69,   69,   69,   73,   73,    0,
+       73,   73,   73,   73,   83,   83,   83,   83,   83,   83,
+       84,   84,   84,   84,   84,   84,   85,   85,   85,   85,
+       85,   85,   86,    0,    0,    0,    0,   86,   87,   87,
+        0,   87,   87,   87,   88,    0,    0,    0,   88,   89,
+       89,    0,    0,   89,   90,   90,   90,   90,   90,   90,
+       91,   91,   91,   91,   91,   91,   92,   92,   92,   92,
+        0,   92,   93,   93,   93,   93,   93,   93,   82,   82,
+       82,   82,   82,   82,   82,   82,   82,   82,   82,   82,
+
+       82,   82,   82,   82,   82,   82,   82,   82,   82,   82,
+       82,   82,   82,   82,   82,   82,   82
     } ;
 
 /* Table of booleans, true if rule could match eol. */
-static yyconst flex_int32_t yy_rule_can_match_eol[29] =
+static yyconst flex_int32_t yy_rule_can_match_eol[30] =
     {   0,
 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 
-    1, 0, 0, 0, 0, 0, 1, 0, 0,     };
+    1, 0, 0, 0, 0, 0, 1, 0, 0, 0,     };
 
-static yyconst flex_int16_t yy_rule_linenum[28] =
+static yyconst flex_int16_t yy_rule_linenum[29] =
     {   0,
        60,   61,   62,   63,   65,   67,   68,   69,   70,   72,
        77,   82,   90,  109,  112,  115,  118,  124,  126,  127,
-      150,  151,  152,  153,  154,  155,  158
+      150,  151,  152,  153,  154,  155,  156,  157
     } ;
 
 /* The intent behind this definition is that it'll catch
@@ -657,7 +662,7 @@ static void include_files(parser_helper_t *ctx);
 
 /* state used to scan quoted strings */
 
-#line 661 "parser/lexer.c"
+#line 666 "parser/lexer.c"
 
 #define INITIAL 0
 #define inc 1
@@ -972,7 +977,7 @@ YY_DECL
 #line 58 "parser/lexer.l"
 
 
-#line 976 "parser/lexer.c"
+#line 981 "parser/lexer.c"
 
     yylval = yylval_param;
 
@@ -1038,13 +1043,13 @@ yy_match:
 			while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
 				{
 				yy_current_state = (int) yy_def[yy_current_state];
-				if ( yy_current_state >= 81 )
+				if ( yy_current_state >= 83 )
 					yy_c = yy_meta[(unsigned int) yy_c];
 				}
 			yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
 			++yy_cp;
 			}
-		while ( yy_base[yy_current_state] != 172 );
+		while ( yy_base[yy_current_state] != 189 );
 
 yy_find_action:
 /* %% [10.0] code to find the action number goes here */
@@ -1079,13 +1084,13 @@ do_action:	/* This label is used only to access EOF actions. */
 			{
 			if ( yy_act == 0 )
 				fprintf( stderr, "--scanner backing up\n" );
-			else if ( yy_act < 28 )
+			else if ( yy_act < 29 )
 				fprintf( stderr, "--accepting rule at line %ld (\"%s\")\n",
 				         (long)yy_rule_linenum[yy_act], yytext );
-			else if ( yy_act == 28 )
+			else if ( yy_act == 29 )
 				fprintf( stderr, "--accepting default rule (\"%s\")\n",
 				         yytext );
-			else if ( yy_act == 29 )
+			else if ( yy_act == 30 )
 				fprintf( stderr, "--(end of buffer or a NUL)\n" );
 			else
 				fprintf( stderr, "--EOF (start condition %d)\n", YY_START );
@@ -1300,20 +1305,23 @@ case 26:
 /* rule 26 can match eol */
 YY_RULE_SETUP
 #line 155 "parser/lexer.l"
-{
-		yyextra->string_add(yyextra, yytext+1);
-	}
+/* merge lines that end with EOL characters */
 	YY_BREAK
 case 27:
 YY_RULE_SETUP
-#line 158 "parser/lexer.l"
+#line 156 "parser/lexer.l"
+yyextra->string_add(yyextra, yytext+1);
+	YY_BREAK
+case 28:
+YY_RULE_SETUP
+#line 157 "parser/lexer.l"
 {
 		yyextra->string_add(yyextra, yytext);
 	}
 	YY_BREAK
 
 case YY_STATE_EOF(INITIAL):
-#line 163 "parser/lexer.l"
+#line 162 "parser/lexer.l"
 {
 	conf_parser_pop_buffer_state(yyscanner);
 	if (!conf_parser_open_next_file(yyextra) && !YY_CURRENT_BUFFER)
@@ -1322,12 +1330,12 @@ case YY_STATE_EOF(INITIAL):
 	}
 }
 	YY_BREAK
-case 28:
+case 29:
 YY_RULE_SETUP
-#line 171 "parser/lexer.l"
+#line 170 "parser/lexer.l"
 YY_FATAL_ERROR( "flex scanner jammed" );
 	YY_BREAK
-#line 1331 "parser/lexer.c"
+#line 1339 "parser/lexer.c"
 
 	case YY_END_OF_BUFFER:
 		{
@@ -1641,7 +1649,7 @@ static int yy_get_next_buffer (yyscan_t yyscanner)
 		while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
 			{
 			yy_current_state = (int) yy_def[yy_current_state];
-			if ( yy_current_state >= 81 )
+			if ( yy_current_state >= 83 )
 				yy_c = yy_meta[(unsigned int) yy_c];
 			}
 		yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
@@ -1675,11 +1683,11 @@ static int yy_get_next_buffer (yyscan_t yyscanner)
 	while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
 		{
 		yy_current_state = (int) yy_def[yy_current_state];
-		if ( yy_current_state >= 81 )
+		if ( yy_current_state >= 83 )
 			yy_c = yy_meta[(unsigned int) yy_c];
 		}
 	yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
-	yy_is_jam = (yy_current_state == 80);
+	yy_is_jam = (yy_current_state == 82);
 
 	return yy_is_jam ? 0 : yy_current_state;
 }
@@ -2697,7 +2705,7 @@ void conf_parser_free (void * ptr , yyscan_t yyscanner)
 
 /* %ok-for-header */
 
-#line 171 "parser/lexer.l"
+#line 170 "parser/lexer.l"
 
 
 
diff --git a/src/starter/parser/lexer.l b/src/starter/parser/lexer.l
index a88cbe8..d967e74 100644
--- a/src/starter/parser/lexer.l
+++ b/src/starter/parser/lexer.l
@@ -152,9 +152,8 @@ static void include_files(parser_helper_t *ctx);
 	\\t     yyextra->string_add(yyextra, "\t");
 	\\b     yyextra->string_add(yyextra, "\b");
 	\\f     yyextra->string_add(yyextra, "\f");
-	\\(.|\n)			{
-		yyextra->string_add(yyextra, yytext+1);
-	}
+	\\\r?\n /* merge lines that end with EOL characters */
+	\\.     yyextra->string_add(yyextra, yytext+1);
 	[^\\\n"]+			{
 		yyextra->string_add(yyextra, yytext);
 	}
diff --git a/src/starter/starterstroke.c b/src/starter/starterstroke.c
index 1e305db..6e1f160 100644
--- a/src/starter/starterstroke.c
+++ b/src/starter/starterstroke.c
@@ -35,10 +35,16 @@ static char* push_string(stroke_msg_t *msg, char *string)
 {
 	unsigned long string_start = msg->length;
 
-	if (string == NULL || msg->length + strlen(string) >= sizeof(stroke_msg_t))
+	if (string == NULL)
 	{
 		return NULL;
 	}
+	else if ((size_t)msg->length + strlen(string) >= sizeof(stroke_msg_t))
+	{
+		/* set invalid length to fail during message send */
+		msg->length = ~0;
+		return NULL;
+	}
 	else
 	{
 		msg->length += strlen(string) + 1;
@@ -53,6 +59,12 @@ static int send_stroke_msg (stroke_msg_t *msg)
 	char *uri, buffer[64];
 	int count;
 
+	if (msg->length > sizeof(stroke_msg_t))
+	{
+		DBG1(DBG_APP, "stroke message exceeds buffer size");
+		return -1;
+	}
+
 	/* starter is not called from commandline, and therefore absolutely silent */
 	msg->output_verbosity = -1;
 
diff --git a/src/starter/tests/Makefile.in b/src/starter/tests/Makefile.in
index d42a0d2..b261255 100644
--- a/src/starter/tests/Makefile.in
+++ b/src/starter/tests/Makefile.in
@@ -223,6 +223,7 @@ DLLIB = @DLLIB@
 DLLTOOL = @DLLTOOL@
 DSYMUTIL = @DSYMUTIL@
 DUMPBIN = @DUMPBIN@
+EASY_INSTALL = @EASY_INSTALL@
 ECHO_C = @ECHO_C@
 ECHO_N = @ECHO_N@
 ECHO_T = @ECHO_T@
@@ -283,10 +284,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
 PLUGIN_CFLAGS = @PLUGIN_CFLAGS@
 PTHREADLIB = @PTHREADLIB@
 PYTHON = @PYTHON@
+PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@
 PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
 PYTHON_PLATFORM = @PYTHON_PLATFORM@
 PYTHON_PREFIX = @PYTHON_PREFIX@
 PYTHON_VERSION = @PYTHON_VERSION@
+PY_TEST = @PY_TEST@
 RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
@@ -360,6 +363,8 @@ json_CFLAGS = @json_CFLAGS@
 json_LIBS = @json_LIBS@
 libdir = @libdir@
 libexecdir = @libexecdir@
+libiptc_CFLAGS = @libiptc_CFLAGS@
+libiptc_LIBS = @libiptc_LIBS@
 linux_headers = @linux_headers@
 localedir = @localedir@
 localstatedir = @localstatedir@
diff --git a/src/stroke/Makefile.in b/src/stroke/Makefile.in
index 9c041df..c32ebf9 100644
--- a/src/stroke/Makefile.in
+++ b/src/stroke/Makefile.in
@@ -197,6 +197,7 @@ DLLIB = @DLLIB@
 DLLTOOL = @DLLTOOL@
 DSYMUTIL = @DSYMUTIL@
 DUMPBIN = @DUMPBIN@
+EASY_INSTALL = @EASY_INSTALL@
 ECHO_C = @ECHO_C@
 ECHO_N = @ECHO_N@
 ECHO_T = @ECHO_T@
@@ -257,10 +258,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
 PLUGIN_CFLAGS = @PLUGIN_CFLAGS@
 PTHREADLIB = @PTHREADLIB@
 PYTHON = @PYTHON@
+PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@
 PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
 PYTHON_PLATFORM = @PYTHON_PLATFORM@
 PYTHON_PREFIX = @PYTHON_PREFIX@
 PYTHON_VERSION = @PYTHON_VERSION@
+PY_TEST = @PY_TEST@
 RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
@@ -334,6 +337,8 @@ json_CFLAGS = @json_CFLAGS@
 json_LIBS = @json_LIBS@
 libdir = @libdir@
 libexecdir = @libexecdir@
+libiptc_CFLAGS = @libiptc_CFLAGS@
+libiptc_LIBS = @libiptc_LIBS@
 linux_headers = @linux_headers@
 localedir = @localedir@
 localstatedir = @localstatedir@
diff --git a/src/stroke/stroke_msg.h b/src/stroke/stroke_msg.h
index 60886cf..c2b923f 100644
--- a/src/stroke/stroke_msg.h
+++ b/src/stroke/stroke_msg.h
@@ -32,7 +32,7 @@
  */
 #define STROKE_SOCKET IPSEC_PIDDIR "/charon.ctl"
 
-#define STROKE_BUF_LEN		2048
+#define STROKE_BUF_LEN		4096
 
 typedef enum list_flag_t list_flag_t;
 
diff --git a/src/swanctl/Makefile.am b/src/swanctl/Makefile.am
index b84d705..f4f9fdf 100644
--- a/src/swanctl/Makefile.am
+++ b/src/swanctl/Makefile.am
@@ -65,4 +65,5 @@ install-data-local: swanctl.conf
 	test -e "$(DESTDIR)$(swanctldir)/rsa" || $(INSTALL) -d -m 750 "$(DESTDIR)$(swanctldir)/rsa" || true
 	test -e "$(DESTDIR)$(swanctldir)/ecdsa" || $(INSTALL) -d -m 750 "$(DESTDIR)$(swanctldir)/ecdsa" || true
 	test -e "$(DESTDIR)$(swanctldir)/pkcs8" || $(INSTALL) -d -m 750 "$(DESTDIR)$(swanctldir)/pkcs8" || true
+	test -e "$(DESTDIR)$(swanctldir)/pkcs12" || $(INSTALL) -d -m 750 "$(DESTDIR)$(swanctldir)/pkcs12" || true
 	test -e "$(DESTDIR)$(swanctldir)/swanctl.conf" || $(INSTALL) -m 640 $(srcdir)/swanctl.conf $(DESTDIR)$(swanctldir)/swanctl.conf || true
diff --git a/src/swanctl/Makefile.in b/src/swanctl/Makefile.in
index 649e6d8..f981bb1 100644
--- a/src/swanctl/Makefile.in
+++ b/src/swanctl/Makefile.in
@@ -238,6 +238,7 @@ DLLIB = @DLLIB@
 DLLTOOL = @DLLTOOL@
 DSYMUTIL = @DSYMUTIL@
 DUMPBIN = @DUMPBIN@
+EASY_INSTALL = @EASY_INSTALL@
 ECHO_C = @ECHO_C@
 ECHO_N = @ECHO_N@
 ECHO_T = @ECHO_T@
@@ -298,10 +299,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
 PLUGIN_CFLAGS = @PLUGIN_CFLAGS@
 PTHREADLIB = @PTHREADLIB@
 PYTHON = @PYTHON@
+PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@
 PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
 PYTHON_PLATFORM = @PYTHON_PLATFORM@
 PYTHON_PREFIX = @PYTHON_PREFIX@
 PYTHON_VERSION = @PYTHON_VERSION@
+PY_TEST = @PY_TEST@
 RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
@@ -375,6 +378,8 @@ json_CFLAGS = @json_CFLAGS@
 json_LIBS = @json_LIBS@
 libdir = @libdir@
 libexecdir = @libexecdir@
+libiptc_CFLAGS = @libiptc_CFLAGS@
+libiptc_LIBS = @libiptc_LIBS@
 linux_headers = @linux_headers@
 localedir = @localedir@
 localstatedir = @localstatedir@
@@ -991,6 +996,7 @@ install-data-local: swanctl.conf
 	test -e "$(DESTDIR)$(swanctldir)/rsa" || $(INSTALL) -d -m 750 "$(DESTDIR)$(swanctldir)/rsa" || true
 	test -e "$(DESTDIR)$(swanctldir)/ecdsa" || $(INSTALL) -d -m 750 "$(DESTDIR)$(swanctldir)/ecdsa" || true
 	test -e "$(DESTDIR)$(swanctldir)/pkcs8" || $(INSTALL) -d -m 750 "$(DESTDIR)$(swanctldir)/pkcs8" || true
+	test -e "$(DESTDIR)$(swanctldir)/pkcs12" || $(INSTALL) -d -m 750 "$(DESTDIR)$(swanctldir)/pkcs12" || true
 	test -e "$(DESTDIR)$(swanctldir)/swanctl.conf" || $(INSTALL) -m 640 $(srcdir)/swanctl.conf $(DESTDIR)$(swanctldir)/swanctl.conf || true
 
 # Tell versions [3.59,3.63) of GNU make to not export all variables.
diff --git a/src/swanctl/commands/list_conns.c b/src/swanctl/commands/list_conns.c
index 31ab9c4..019c888 100644
--- a/src/swanctl/commands/list_conns.c
+++ b/src/swanctl/commands/list_conns.c
@@ -103,7 +103,7 @@ CALLBACK(conn_sn, int,
 	{
 		return vici_parse_cb(res, children_sn, NULL, NULL, NULL);
 	}
-	if (streq(name, "local") || streq(name, "remote"))
+	if (strpfx(name, "local") || strpfx(name, "remote"))
 	{
 		hashtable_t *auth;
 
@@ -112,7 +112,8 @@ CALLBACK(conn_sn, int,
 		if (ret == 0)
 		{
 			printf("  %s %s authentication:\n",
-				name, auth->get(auth, "class") ?: "unspecified");
+				strpfx(name, "local") ? "local" : "remote",
+				auth->get(auth, "class") ?: "unspecified");
 			if (auth->get(auth, "id"))
 			{
 				printf("    id: %s\n", auth->get(auth, "id"));
diff --git a/src/swanctl/commands/list_sas.c b/src/swanctl/commands/list_sas.c
index 35e7469..81e1b7c 100644
--- a/src/swanctl/commands/list_sas.c
+++ b/src/swanctl/commands/list_sas.c
@@ -86,8 +86,8 @@ CALLBACK(child_sas, int,
 	ret = vici_parse_cb(res, NULL, sa_values, sa_list, child);
 	if (ret == 0)
 	{
-		printf("  %s: #%s, %s, %s%s, %s:",
-			name, child->get(child, "reqid"),
+		printf("  %s: #%s, reqid %s, %s, %s%s, %s:",
+			name, child->get(child, "uniqueid"), child->get(child, "reqid"),
 			child->get(child, "state"), child->get(child, "mode"),
 			child->get(child, "encap") ? "-in-UDP" : "",
 			child->get(child, "protocol"));
@@ -122,7 +122,7 @@ CALLBACK(child_sas, int,
 		}
 		if (child->get(child, "esn"))
 		{
-			printf("/%s", child->get(child, "esn"));
+			printf("/ESN");
 		}
 		printf("\n");
 
diff --git a/src/swanctl/commands/load_conns.c b/src/swanctl/commands/load_conns.c
index de30d8e..6ee8b87 100644
--- a/src/swanctl/commands/load_conns.c
+++ b/src/swanctl/commands/load_conns.c
@@ -93,11 +93,12 @@ static void add_list_key(vici_req_t *req, char *key, char *value)
 /**
  * Add a vici list of blobs from a comma separated file list
  */
-static void add_file_list_key(vici_req_t *req, char *key, char *value)
+static bool add_file_list_key(vici_req_t *req, char *key, char *value)
 {
 	enumerator_t *enumerator;
 	chunk_t *map;
 	char *token, buf[PATH_MAX];
+	bool ret = TRUE;
 
 	vici_begin_list(req, key);
 	enumerator = enumerator_create_token(value, ",", " ");
@@ -127,21 +128,26 @@ static void add_file_list_key(vici_req_t *req, char *key, char *value)
 		}
 		else
 		{
-			fprintf(stderr, "loading certificate '%s' failed: %s\n",
-					token, strerror(errno));
+			fprintf(stderr, "loading %s certificate '%s' failed: %s\n",
+					key, token, strerror(errno));
+			ret = FALSE;
+			break;
 		}
 	}
 	enumerator->destroy(enumerator);
 	vici_end_list(req);
+
+	return ret;
 }
 
 /**
  * Translate setting key/values from a section into vici key-values/lists
  */
-static void add_key_values(vici_req_t *req, settings_t *cfg, char *section)
+static bool add_key_values(vici_req_t *req, settings_t *cfg, char *section)
 {
 	enumerator_t *enumerator;
 	char *key, *value;
+	bool ret = TRUE;
 
 	enumerator = cfg->create_key_value_enumerator(cfg, section);
 	while (enumerator->enumerate(enumerator, &key, &value))
@@ -152,34 +158,51 @@ static void add_key_values(vici_req_t *req, settings_t *cfg, char *section)
 		}
 		else if (is_file_list_key(key))
 		{
-			add_file_list_key(req, key, value);
+			ret = add_file_list_key(req, key, value);
 		}
 		else
 		{
 			vici_add_key_valuef(req, key, "%s", value);
 		}
+		if (!ret)
+		{
+			break;
+		}
 	}
 	enumerator->destroy(enumerator);
+
+	return ret;
 }
 
 /**
  * Translate a settings section to a vici section
  */
-static void add_sections(vici_req_t *req, settings_t *cfg, char *section)
+static bool add_sections(vici_req_t *req, settings_t *cfg, char *section)
 {
 	enumerator_t *enumerator;
 	char *name, buf[256];
+	bool ret = TRUE;
 
 	enumerator = cfg->create_section_enumerator(cfg, section);
 	while (enumerator->enumerate(enumerator, &name))
 	{
 		vici_begin_section(req, name);
 		snprintf(buf, sizeof(buf), "%s.%s", section, name);
-		add_key_values(req, cfg, buf);
-		add_sections(req, cfg, buf);
+		ret = add_key_values(req, cfg, buf);
+		if (!ret)
+		{
+			break;
+		}
+		ret = add_sections(req, cfg, buf);
+		if (!ret)
+		{
+			break;
+		}
 		vici_end_section(req);
 	}
 	enumerator->destroy(enumerator);
+
+	return ret;
 }
 
 /**
@@ -198,8 +221,12 @@ static bool load_conn(vici_conn_t *conn, settings_t *cfg,
 	req = vici_begin("load-conn");
 
 	vici_begin_section(req, section);
-	add_key_values(req, cfg, buf);
-	add_sections(req, cfg, buf);
+	if (!add_key_values(req, cfg, buf) ||
+		!add_sections(req, cfg, buf))
+	{
+		vici_free_req(req);
+		return FALSE;
+	}
 	vici_end_section(req);
 
 	res = vici_submit(req, conn);
diff --git a/src/swanctl/commands/load_creds.c b/src/swanctl/commands/load_creds.c
index 86ee3c1..d2ebc22 100644
--- a/src/swanctl/commands/load_creds.c
+++ b/src/swanctl/commands/load_creds.c
@@ -25,6 +25,7 @@
 
 #include <credentials/sets/mem_cred.h>
 #include <credentials/sets/callback_cred.h>
+#include <credentials/containers/pkcs12.h>
 
 /**
  * Load a single certificate over vici
@@ -60,7 +61,7 @@ static bool load_cert(vici_conn_t *conn, command_format_options_t format,
 	}
 	else
 	{
-		printf("loaded %s certificate '%s'\n", type, dir);
+		printf("loaded %s certificate from '%s'\n", type, dir);
 	}
 	vici_free_res(res);
 	return ret;
@@ -113,7 +114,14 @@ static bool load_key(vici_conn_t *conn, command_format_options_t format,
 
 	req = vici_begin("load-key");
 
-	vici_add_key_valuef(req, "type", "%s", type);
+	if (streq(type, "pkcs8"))
+	{	/* as used by vici */
+		vici_add_key_valuef(req, "type", "any");
+	}
+	else
+	{
+		vici_add_key_valuef(req, "type", "%s", type);
+	}
 	vici_add_key_value(req, "data", data.ptr, data.len);
 
 	res = vici_submit(req, conn);
@@ -135,20 +143,59 @@ static bool load_key(vici_conn_t *conn, command_format_options_t format,
 	}
 	else
 	{
-		printf("loaded %s key '%s'\n", type, dir);
+		printf("loaded %s key from '%s'\n", type, dir);
 	}
 	vici_free_res(res);
 	return ret;
 }
 
 /**
+ * Load a private key of any type to vici
+ */
+static bool load_key_anytype(vici_conn_t *conn, command_format_options_t format,
+							 char *path, private_key_t *private)
+{
+	bool loaded = FALSE;
+	chunk_t encoding;
+
+	if (!private->get_encoding(private, PRIVKEY_ASN1_DER, &encoding))
+	{
+		fprintf(stderr, "encoding private key from '%s' failed\n", path);
+		return FALSE;
+	}
+	switch (private->get_type(private))
+	{
+		case KEY_RSA:
+			loaded = load_key(conn, format, path, "rsa", encoding);
+			break;
+		case KEY_ECDSA:
+			loaded = load_key(conn, format, path, "ecdsa", encoding);
+			break;
+		default:
+			fprintf(stderr, "unsupported key type in '%s'\n", path);
+			break;
+	}
+	chunk_clear(&encoding);
+	return loaded;
+}
+
+/**
+ * Data passed to password callback
+ */
+typedef struct {
+	char prompt[128];
+	mem_cred_t *cache;
+} cb_data_t;
+
+/**
  * Callback function to prompt for private key passwords
  */
 CALLBACK(password_cb, shared_key_t*,
-	char *prompt, shared_key_type_t type,
+	cb_data_t *data, shared_key_type_t type,
 	identification_t *me, identification_t *other,
 	id_match_t *match_me, id_match_t *match_other)
 {
+	shared_key_t *shared;
 	char *pwd = NULL;
 
 	if (type != SHARED_PRIVATE_KEY_PASS)
@@ -156,7 +203,7 @@ CALLBACK(password_cb, shared_key_t*,
 		return NULL;
 	}
 #ifdef HAVE_GETPASS
-	pwd = getpass(prompt);
+	pwd = getpass(data->prompt);
 #endif
 	if (!pwd || strlen(pwd) == 0)
 	{
@@ -170,65 +217,94 @@ CALLBACK(password_cb, shared_key_t*,
 	{
 		*match_other = ID_MATCH_PERFECT;
 	}
-	return shared_key_create(type, chunk_clone(chunk_from_str(pwd)));
+	shared = shared_key_create(type, chunk_clone(chunk_from_str(pwd)));
+	/* cache secret if it is required more than once (PKCS#12) */
+	data->cache->add_shared(data->cache, shared, NULL);
+	return shared->get_ref(shared);
 }
 
 /**
- * Try to parse a potentially encrypted private key using password prompt
+ * Determine credential type and subtype from a type string
  */
-static private_key_t* decrypt_key(char *name, char *type, chunk_t encoding)
+static bool determine_credtype(char *type, credential_type_t *credtype,
+							   int *subtype)
 {
-	key_type_t kt = KEY_ANY;
-	private_key_t *private;
-	callback_cred_t *cb;
-	char buf[128];
+	struct {
+		char *type;
+		credential_type_t credtype;
+		int subtype;
+	} map[] = {
+		{ "pkcs8",			CRED_PRIVATE_KEY,		KEY_ANY,			},
+		{ "rsa",			CRED_PRIVATE_KEY,		KEY_RSA,			},
+		{ "ecdsa",			CRED_PRIVATE_KEY,		KEY_ECDSA,			},
+		{ "pkcs12",			CRED_CONTAINER,			CONTAINER_PKCS12,	},
+	};
+	int i;
 
-	if (streq(type, "rsa"))
+	for (i = 0; i < countof(map); i++)
 	{
-		kt = KEY_RSA;
+		if (streq(map[i].type, type))
+		{
+			*credtype = map[i].credtype;
+			*subtype = map[i].subtype;
+			return TRUE;
+		}
 	}
-	else if (streq(type, "ecdsa"))
+	return FALSE;
+}
+
+/**
+ * Try to parse a potentially encrypted credential using password prompt
+ */
+static void* decrypt(char *name, char *type, chunk_t encoding)
+{
+	credential_type_t credtype;
+	int subtype;
+	void *cred;
+	callback_cred_t *cb;
+	cb_data_t data;
+
+	if (!determine_credtype(type, &credtype, &subtype))
 	{
-		kt = KEY_ECDSA;
+		return NULL;
 	}
 
-	snprintf(buf, sizeof(buf), "Password for '%s': ", name);
+	snprintf(data.prompt, sizeof(data.prompt), "Password for %s file '%s': ",
+			 type, name);
 
-	cb = callback_cred_create_shared(password_cb, buf);
+	data.cache = mem_cred_create();
+	lib->credmgr->add_set(lib->credmgr, &data.cache->set);
+	cb = callback_cred_create_shared(password_cb, &data);
 	lib->credmgr->add_set(lib->credmgr, &cb->set);
 
-	private = lib->creds->create(lib->creds, CRED_PRIVATE_KEY, kt,
-								 BUILD_BLOB_PEM, encoding, BUILD_END);
+	cred = lib->creds->create(lib->creds, credtype, subtype,
+							  BUILD_BLOB_PEM, encoding, BUILD_END);
 
+	lib->credmgr->remove_set(lib->credmgr, &data.cache->set);
+	data.cache->destroy(data.cache);
 	lib->credmgr->remove_set(lib->credmgr, &cb->set);
 	cb->destroy(cb);
 
-	return private;
+	return cred;
 }
 
 /**
- * Try to parse a potentially encrypted private key using configured secret
+ * Try to parse a potentially encrypted credential using configured secret
  */
-static private_key_t* decrypt_key_with_config(settings_t *cfg, char *name,
-											  char *type, chunk_t encoding)
-{	key_type_t kt = KEY_ANY;
+static void* decrypt_with_config(settings_t *cfg, char *name, char *type,
+								 chunk_t encoding)
+{
+	credential_type_t credtype;
+	int subtype;
 	enumerator_t *enumerator, *secrets;
 	char *section, *key, *value, *file, buf[128];
 	shared_key_t *shared;
-	private_key_t *private = NULL;
+	void *cred = NULL;
 	mem_cred_t *mem = NULL;
 
-	if (streq(type, "rsa"))
-	{
-		kt = KEY_RSA;
-	}
-	else if (streq(type, "ecdsa"))
-	{
-		kt = KEY_ECDSA;
-	}
-	else
+	if (!determine_credtype(type, &credtype, &subtype))
 	{
-		type = "pkcs8";
+		return NULL;
 	}
 
 	/* load all secrets for this key type */
@@ -265,12 +341,12 @@ static private_key_t* decrypt_key_with_config(settings_t *cfg, char *name,
 	{
 		lib->credmgr->add_local_set(lib->credmgr, &mem->set, FALSE);
 
-		private = lib->creds->create(lib->creds, CRED_PRIVATE_KEY, kt,
-									 BUILD_BLOB_PEM, encoding, BUILD_END);
+		cred = lib->creds->create(lib->creds, credtype, subtype,
+								  BUILD_BLOB_PEM, encoding, BUILD_END);
 
 		lib->credmgr->remove_local_set(lib->credmgr, &mem->set);
 
-		if (!private)
+		if (!cred)
 		{
 			fprintf(stderr, "configured decryption secret for '%s' invalid\n",
 					name);
@@ -279,7 +355,7 @@ static private_key_t* decrypt_key_with_config(settings_t *cfg, char *name,
 		mem->destroy(mem);
 	}
 
-	return private;
+	return cred;
 }
 
 /**
@@ -292,30 +368,15 @@ static bool load_encrypted_key(vici_conn_t *conn,
 {
 	private_key_t *private;
 	bool loaded = FALSE;
-	chunk_t encoding;
 
-	private = decrypt_key_with_config(cfg, rel, type, data);
+	private = decrypt_with_config(cfg, rel, type, data);
 	if (!private && !noprompt)
 	{
-		private = decrypt_key(rel, type, data);
+		private = decrypt(rel, type, data);
 	}
 	if (private)
 	{
-		if (private->get_encoding(private, PRIVKEY_ASN1_DER, &encoding))
-		{
-			switch (private->get_type(private))
-			{
-				case KEY_RSA:
-					loaded = load_key(conn, format, path, "rsa", encoding);
-					break;
-				case KEY_ECDSA:
-					loaded = load_key(conn, format, path, "ecdsa", encoding);
-					break;
-				default:
-					break;
-			}
-			chunk_clear(&encoding);
-		}
+		loaded = load_key_anytype(conn, format, path, private);
 		private->destroy(private);
 	}
 	return loaded;
@@ -361,6 +422,114 @@ static void load_keys(vici_conn_t *conn, command_format_options_t format,
 }
 
 /**
+ * Load credentials from a PKCS#12 container over vici
+ */
+static bool load_pkcs12(vici_conn_t *conn, command_format_options_t format,
+						char *path, pkcs12_t *p12)
+{
+	enumerator_t *enumerator;
+	certificate_t *cert;
+	private_key_t *private;
+	chunk_t encoding;
+	bool loaded = TRUE;
+
+	enumerator = p12->create_cert_enumerator(p12);
+	while (loaded && enumerator->enumerate(enumerator, &cert))
+	{
+		loaded = FALSE;
+		if (cert->get_encoding(cert, CERT_ASN1_DER, &encoding))
+		{
+			loaded = load_cert(conn, format, path, "x509", encoding);
+			if (loaded)
+			{
+				fprintf(stderr, "  %Y\n", cert->get_subject(cert));
+			}
+			free(encoding.ptr);
+		}
+		else
+		{
+			fprintf(stderr, "encoding certificate from '%s' failed\n", path);
+		}
+	}
+	enumerator->destroy(enumerator);
+
+	enumerator = p12->create_key_enumerator(p12);
+	while (loaded && enumerator->enumerate(enumerator, &private))
+	{
+		loaded = load_key_anytype(conn, format, path, private);
+	}
+	enumerator->destroy(enumerator);
+
+	return loaded;
+}
+
+/**
+ * Try to decrypt and load credentials from a container
+ */
+static bool load_encrypted_container(vici_conn_t *conn,
+					command_format_options_t format, settings_t *cfg, char *rel,
+					char *path, char *type, bool noprompt, chunk_t data)
+{
+	container_t *container;
+	bool loaded = FALSE;
+
+	container = decrypt_with_config(cfg, rel, type, data);
+	if (!container && !noprompt)
+	{
+		container = decrypt(rel, type, data);
+	}
+	if (container)
+	{
+		switch (container->get_type(container))
+		{
+			case CONTAINER_PKCS12:
+				loaded = load_pkcs12(conn, format, path, (pkcs12_t*)container);
+				break;
+			default:
+				break;
+		}
+		container->destroy(container);
+	}
+	return loaded;
+}
+
+/**
+ * Load credential containers from a directory
+ */
+static void load_containers(vici_conn_t *conn, command_format_options_t format,
+						bool noprompt, settings_t *cfg, char *type, char *dir)
+{
+	enumerator_t *enumerator;
+	struct stat st;
+	chunk_t *map;
+	char *path, *rel;
+
+	enumerator = enumerator_create_directory(dir);
+	if (enumerator)
+	{
+		while (enumerator->enumerate(enumerator, &rel, &path, &st))
+		{
+			if (S_ISREG(st.st_mode))
+			{
+				map = chunk_map(path, FALSE);
+				if (map)
+				{
+					load_encrypted_container(conn, format, cfg, rel, path,
+											 type, noprompt, *map);
+					chunk_unmap(map);
+				}
+				else
+				{
+					fprintf(stderr, "mapping '%s' failed: %s, skipped\n",
+							path, strerror(errno));
+				}
+			}
+		}
+		enumerator->destroy(enumerator);
+	}
+}
+
+/**
  * Load a single secret over VICI
  */
 static bool load_secret(vici_conn_t *conn, settings_t *cfg,
@@ -380,6 +549,7 @@ static bool load_secret(vici_conn_t *conn, settings_t *cfg,
 		"rsa",
 		"ecdsa",
 		"pkcs8",
+		"pkcs12",
 	};
 
 	for (i = 0; i < countof(types); i++)
@@ -510,7 +680,9 @@ int load_creds_cfg(vici_conn_t *conn, command_format_options_t format,
 
 	load_keys(conn, format, noprompt, cfg, "rsa", SWANCTL_RSADIR);
 	load_keys(conn, format, noprompt, cfg, "ecdsa", SWANCTL_ECDSADIR);
-	load_keys(conn, format, noprompt, cfg, "any", SWANCTL_PKCS8DIR);
+	load_keys(conn, format, noprompt, cfg, "pkcs8", SWANCTL_PKCS8DIR);
+
+	load_containers(conn, format, noprompt, cfg, "pkcs12", SWANCTL_PKCS12DIR);
 
 	enumerator = cfg->create_section_enumerator(cfg, "secrets");
 	while (enumerator->enumerate(enumerator, &section))
diff --git a/src/swanctl/swanctl.conf b/src/swanctl/swanctl.conf
index 0808cf5..faafecc 100644
--- a/src/swanctl/swanctl.conf
+++ b/src/swanctl/swanctl.conf
@@ -286,6 +286,18 @@
 
     # }
 
+    # PKCS#12 decryption passphrase for a container in the pkcs12 folder.
+    # pkcs12<suffix> {
+
+        # File name in the pkcs12 folder for which this passphrase should be
+        # used.
+        # file =
+
+        # Value of decryption passphrase for PKCS#12 container.
+        # secret =
+
+    # }
+
 # }
 
 # Section defining named pools.
@@ -294,7 +306,7 @@
     # Section defining a single pool with a unique name.
     # <name> {
 
-        # Subnet defining addresses allocated in pool.
+        # Addresses allocated in pool.
         # addrs =
 
         # Comma separated list of additional attributes from type <attr>.
diff --git a/src/swanctl/swanctl.conf.5.main b/src/swanctl/swanctl.conf.5.main
index 8943b62..a770b28 100644
--- a/src/swanctl/swanctl.conf.5.main
+++ b/src/swanctl/swanctl.conf.5.main
@@ -251,7 +251,12 @@ performs a reauthentication procedure instead.
 With the default value IKE rekeying is scheduled every 4 hours, minus the
 configured
 .RB "" "rand_time" "."
-
+If a
+.RB "" "reauth_time" ""
+is configured,
+.RB "" "rekey_time" ""
+defaults to zero disabling rekeying; explicitly set both to enforce rekeying and
+reauthentication.
 
 .TP
 .BR connections.<conn>.over_time " [10% of rekey_time/reauth_time]"
@@ -363,6 +368,37 @@ IKE identity to use for authentication round. When using certificate
 authentication, the IKE identity must be contained in the certificate, either as
 subject or as subjectAltName.
 
+The identity can be an IP address, a fully\-qualified domain name, an email
+address or a Distinguished Name for which the ID type is determined
+automatically and the string is converted to the appropriate encoding. To
+enforce a specific identity type, a prefix may be used, followed by a colon (:).
+If the number sign (#) follows the colon, the remaining data is interpreted as
+hex encoding, otherwise the string is used as\-is as the identification data.
+Note that this implies that no conversion is performed for non\-string
+identities. For example,
+.RI "" "ipv4:10.0.0.1" ""
+does not create a valid ID_IPV4_ADDR
+IKE identity, as it does not get converted to binary 0x0a000001. Instead, one
+could use
+.RI "" "ipv4:#0a000001" ""
+to get a valid identity, but just using the implicit
+type with automatic conversion is usually simpler. The same applies to the ASN1
+encoded types. The following prefixes are known:
+.RI "" "ipv4" ","
+.RI "" "ipv6" ","
+.RI "" "rfc822" ","
+.RI "" "email" ","
+.RI "" "userfqdn" ","
+.RI "" "fqdn" ","
+.RI "" "dns" ","
+.RI "" "asn1dn" ","
+.RI "" "asn1gn" ""
+and
+.RI "" "keyid" "."
+Custom type
+prefixes may be specified by surrounding the numerical type value by curly
+brackets.
+
 .TP
 .BR connections.<conn>.local<suffix>.eap_id " [id]"
 Client EAP\-Identity to use in EAP\-Identity exchange and the EAP method.
@@ -397,9 +433,10 @@ omitted.
 
 .TP
 .BR connections.<conn>.remote<suffix>.id " [%any]"
-IKE identity to expect for authentication round. When using certificate
-authentication, the IKE identity must be contained in the certificate, either as
-subject or as subjectAltName.
+IKE identity to expect for authentication round. Refer to the
+.RI "" "local" ""
+.RI "" "id" ""
+section for details.
 
 .TP
 .BR connections.<conn>.remote<suffix>.groups " []"
@@ -725,9 +762,11 @@ uses dynamic reqids, allocated incrementally.
 
 .TP
 .BR connections.<conn>.children.<child>.mark_in " [0/0x00000000]"
-Netfilter mark and mask for input traffic. On Linux Netfilter may apply marks to
-each packet coming from a tunnel having that option set. The mark may then be
-used by Netfilter to match rules.
+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
 mask if omitted is 0xffffffff.
@@ -736,7 +775,9 @@ mask if omitted is 0xffffffff.
 .BR 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.
+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
 mask if omitted is 0xffffffff.
@@ -925,6 +966,23 @@ folder for which this passphrase should be used.
 Value of decryption passphrase for PKCS#8 key.
 
 .TP
+.B secrets.pkcs12<suffix>
+.br
+PKCS#12 decryption passphrase for a container in the
+.RI "" "pkcs12" ""
+folder.
+
+.TP
+.BR secrets.pkcs12<suffix>.file " []"
+File name in the
+.RI "" "pkcs12" ""
+folder for which this passphrase should be used.
+
+.TP
+.BR secrets.pkcs12<suffix>.secret " []"
+Value of decryption passphrase for PKCS#12 container.
+
+.TP
 .B pools
 .br
 Section defining named pools. Named pools may be referenced by connections with
@@ -939,9 +997,9 @@ Section defining a single pool with a unique name.
 
 .TP
 .BR pools.<name>.addrs " []"
-Subnet defining addresses allocated in pool. Accepts a single CIDR subnet
-defining the pool to allocate addresses from. Pools must be unique and
-non\-overlapping.
+Subnet or range defining addresses allocated in pool. Accepts a single CIDR
+subnet defining the pool to allocate addresses from, or an address range
+(<from>\-<to>).  Pools must be unique and non\-overlapping.
 
 .TP
 .BR pools.<name>.<attr> " []"
diff --git a/src/swanctl/swanctl.h b/src/swanctl/swanctl.h
index bd7e003..cb570cd 100644
--- a/src/swanctl/swanctl.h
+++ b/src/swanctl/swanctl.h
@@ -66,4 +66,9 @@
  */
 #define SWANCTL_PKCS8DIR SWANCTLDIR "/pkcs8"
 
+/**
+ * Directory for PKCS#12 containers
+ */
+#define SWANCTL_PKCS12DIR SWANCTLDIR "/pkcs12"
+
 #endif /** SWANCTL_H_ @}*/
diff --git a/src/swanctl/swanctl.opt b/src/swanctl/swanctl.opt
index f1e47a9..b6ef175 100644
--- a/src/swanctl/swanctl.opt
+++ b/src/swanctl/swanctl.opt
@@ -220,7 +220,9 @@ connections.<conn>.rekey_time = 4h
 	IKEv1 performs a reauthentication procedure instead.
 
 	With the default value IKE rekeying is scheduled every 4 hours, minus the
-	configured **rand_time**.
+	configured **rand_time**. If a **reauth_time** is configured, **rekey_time**
+	defaults to zero disabling rekeying; explicitly set both to enforce
+	rekeying and reauthentication.
 
 connections.<conn>.over_time = 10% of rekey_time/reauth_time
 	Hard IKE_SA lifetime if rekey/reauth does not complete, as time.
@@ -303,6 +305,22 @@ connections.<conn>.local<suffix>.id =
 	authentication, the IKE identity must be contained in the certificate,
 	either as subject or as subjectAltName.
 
+	The identity can be an IP address, a fully-qualified domain name, an email
+	address or a Distinguished Name for which the ID type is determined
+	automatically and the string is converted to the appropriate encoding. To
+	enforce a specific identity type, a prefix may be used, followed by a colon
+	(:). If the number sign (#) follows the colon, the remaining data is
+	interpreted as hex encoding, otherwise the string is used as-is as the
+	identification data. Note that this implies that no conversion is performed
+	for non-string identities. For example, _ipv4:10.0.0.1_ does not create a
+	valid ID_IPV4_ADDR IKE identity, as it does not get converted to binary
+	0x0a000001. Instead, one could use _ipv4:#0a000001_ to get a valid identity,
+	but just using the implicit type with automatic conversion is usually
+	simpler. The same applies to the ASN1 encoded types. The following prefixes
+	are known: _ipv4_, _ipv6_, _rfc822_, _email_, _userfqdn_, _fqdn_, _dns_,
+	_asn1dn_, _asn1gn_ and _keyid_. Custom type prefixes may be specified by
+	surrounding the numerical type value by curly brackets.
+
 connections.<conn>.local<suffix>.eap_id = id
 	Client EAP-Identity to use in EAP-Identity exchange and the EAP method.
 
@@ -335,9 +353,8 @@ connections.<conn>.remote<suffix> {}
 connections.<conn>.remote<suffix>.id = %any
 	IKE identity to expect for authentication round.
 
-	IKE identity to expect for authentication round. When using certificate
-	authentication, the IKE identity must be contained in the certificate,
-	either as subject or as subjectAltName.
+	IKE identity to expect for authentication round. Refer to the _local_ _id_
+	section for details.
 
 connections.<conn>.remote<suffix>.groups =
 	Authorization group memberships to require.
@@ -607,9 +624,10 @@ connections.<conn>.children.<child>.reqid = 0
 connections.<conn>.children.<child>.mark_in = 0/0x00000000
 	Netfilter mark and mask for input traffic.
 
-	Netfilter mark and mask for input traffic. On Linux Netfilter may apply
-	marks to each packet coming from a tunnel having that option set. The
-	mark may then be used by Netfilter to match rules.
+	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.
 
 	An additional mask may be appended to the mark, separated by _/_. The
 	default mask if omitted is 0xffffffff.
@@ -619,7 +637,8 @@ 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.
+	Netfilter rules to select specific tunnels for outgoing traffic. The
+	special value _%unique_ sets a unique mark on each CHILD_SA instance.
 
 	An additional mask may be appended to the mark, separated by _/_. The
 	default mask if omitted is 0xffffffff.
@@ -756,6 +775,15 @@ secrets.pkcs8<suffix>.file =
 secrets.pkcs8<suffix>.secret
 	Value of decryption passphrase for PKCS#8 key.
 
+secrets.pkcs12<suffix> { # }
+	PKCS#12 decryption passphrase for a container in the _pkcs12_ folder.
+
+secrets.pkcs12<suffix>.file =
+	File name in the _pkcs12_ folder for which this passphrase should be used.
+
+secrets.pkcs12<suffix>.secret
+	Value of decryption passphrase for PKCS#12 container.
+
 pools { # }
 	Section defining named pools.
 
@@ -767,11 +795,11 @@ pools.<name> { # }
 	Section defining a single pool with a unique name.
 
 pools.<name>.addrs =
-	Subnet defining addresses allocated in pool.
+	Addresses allocated in pool.
 
-	Subnet defining addresses allocated in pool. Accepts a single CIDR subnet
-	defining the pool to allocate addresses from. Pools must be unique and
-	non-overlapping.
+	Subnet or range defining addresses allocated in pool. Accepts a single CIDR
+	subnet defining the pool to allocate addresses from, or an address range
+	(<from>-<to>).  Pools must be unique and non-overlapping.
 
 pools.<name>.<attr> =
 	Comma separated list of additional attributes from type <attr>.
diff --git a/testing/Makefile.in b/testing/Makefile.in
index c151a87..b66c2be 100644
--- a/testing/Makefile.in
+++ b/testing/Makefile.in
@@ -142,6 +142,7 @@ DLLIB = @DLLIB@
 DLLTOOL = @DLLTOOL@
 DSYMUTIL = @DSYMUTIL@
 DUMPBIN = @DUMPBIN@
+EASY_INSTALL = @EASY_INSTALL@
 ECHO_C = @ECHO_C@
 ECHO_N = @ECHO_N@
 ECHO_T = @ECHO_T@
@@ -202,10 +203,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
 PLUGIN_CFLAGS = @PLUGIN_CFLAGS@
 PTHREADLIB = @PTHREADLIB@
 PYTHON = @PYTHON@
+PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@
 PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
 PYTHON_PLATFORM = @PYTHON_PLATFORM@
 PYTHON_PREFIX = @PYTHON_PREFIX@
 PYTHON_VERSION = @PYTHON_VERSION@
+PY_TEST = @PY_TEST@
 RANLIB = @RANLIB@
 RTLIB = @RTLIB@
 RUBY = @RUBY@
@@ -279,6 +282,8 @@ json_CFLAGS = @json_CFLAGS@
 json_LIBS = @json_LIBS@
 libdir = @libdir@
 libexecdir = @libexecdir@
+libiptc_CFLAGS = @libiptc_CFLAGS@
+libiptc_LIBS = @libiptc_LIBS@
 linux_headers = @linux_headers@
 localedir = @localedir@
 localstatedir = @localstatedir@
diff --git a/testing/config/kernel/config-3.18 b/testing/config/kernel/config-3.18
new file mode 100644
index 0000000..345d4f5
--- /dev/null
+++ b/testing/config/kernel/config-3.18
@@ -0,0 +1,2165 @@
+#
+# Automatically generated file; DO NOT EDIT.
+# Linux/x86 3.18.0 Kernel Configuration
+#
+CONFIG_64BIT=y
+CONFIG_X86_64=y
+CONFIG_X86=y
+CONFIG_INSTRUCTION_DECODER=y
+CONFIG_PERF_EVENTS_INTEL_UNCORE=y
+CONFIG_OUTPUT_FORMAT="elf64-x86-64"
+CONFIG_ARCH_DEFCONFIG="arch/x86/configs/x86_64_defconfig"
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_HAVE_LATENCYTOP_SUPPORT=y
+CONFIG_MMU=y
+CONFIG_NEED_DMA_MAP_STATE=y
+CONFIG_NEED_SG_DMA_LENGTH=y
+CONFIG_GENERIC_ISA_DMA=y
+CONFIG_GENERIC_BUG=y
+CONFIG_GENERIC_BUG_RELATIVE_POINTERS=y
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_ARCH_MAY_HAVE_PC_FDC=y
+CONFIG_RWSEM_XCHGADD_ALGORITHM=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_ARCH_HAS_CPU_RELAX=y
+CONFIG_ARCH_HAS_CACHE_LINE_SIZE=y
+CONFIG_HAVE_SETUP_PER_CPU_AREA=y
+CONFIG_NEED_PER_CPU_EMBED_FIRST_CHUNK=y
+CONFIG_NEED_PER_CPU_PAGE_FIRST_CHUNK=y
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
+CONFIG_ARCH_SUSPEND_POSSIBLE=y
+CONFIG_ARCH_WANT_HUGE_PMD_SHARE=y
+CONFIG_ARCH_WANT_GENERAL_HUGETLB=y
+CONFIG_ZONE_DMA32=y
+CONFIG_AUDIT_ARCH=y
+CONFIG_ARCH_SUPPORTS_OPTIMIZED_INLINING=y
+CONFIG_ARCH_SUPPORTS_DEBUG_PAGEALLOC=y
+CONFIG_ARCH_HWEIGHT_CFLAGS="-fcall-saved-rdi -fcall-saved-rsi -fcall-saved-rdx -fcall-saved-rcx -fcall-saved-r8 -fcall-saved-r9 -fcall-saved-r10 -fcall-saved-r11"
+CONFIG_ARCH_SUPPORTS_UPROBES=y
+CONFIG_FIX_EARLYCON_MEM=y
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+CONFIG_IRQ_WORK=y
+CONFIG_BUILDTIME_EXTABLE_SORT=y
+
+#
+# General setup
+#
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+CONFIG_CROSS_COMPILE=""
+# CONFIG_COMPILE_TEST is not set
+CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
+CONFIG_HAVE_KERNEL_GZIP=y
+CONFIG_HAVE_KERNEL_BZIP2=y
+CONFIG_HAVE_KERNEL_LZMA=y
+CONFIG_HAVE_KERNEL_XZ=y
+CONFIG_HAVE_KERNEL_LZO=y
+CONFIG_HAVE_KERNEL_LZ4=y
+CONFIG_KERNEL_GZIP=y
+# CONFIG_KERNEL_BZIP2 is not set
+# CONFIG_KERNEL_LZMA is not set
+# CONFIG_KERNEL_XZ is not set
+# CONFIG_KERNEL_LZO is not set
+# CONFIG_KERNEL_LZ4 is not set
+CONFIG_DEFAULT_HOSTNAME="(none)"
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+CONFIG_SYSVIPC_SYSCTL=y
+CONFIG_POSIX_MQUEUE=y
+CONFIG_POSIX_MQUEUE_SYSCTL=y
+CONFIG_CROSS_MEMORY_ATTACH=y
+# CONFIG_FHANDLE is not set
+CONFIG_USELIB=y
+# CONFIG_AUDIT is not set
+CONFIG_HAVE_ARCH_AUDITSYSCALL=y
+
+#
+# IRQ subsystem
+#
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_GENERIC_IRQ_SHOW=y
+CONFIG_GENERIC_IRQ_LEGACY_ALLOC_HWIRQ=y
+CONFIG_IRQ_DOMAIN=y
+CONFIG_IRQ_FORCED_THREADING=y
+CONFIG_SPARSE_IRQ=y
+CONFIG_CLOCKSOURCE_WATCHDOG=y
+CONFIG_ARCH_CLOCKSOURCE_DATA=y
+CONFIG_CLOCKSOURCE_VALIDATE_LAST_CYCLE=y
+CONFIG_GENERIC_TIME_VSYSCALL=y
+CONFIG_GENERIC_CLOCKEVENTS=y
+CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
+CONFIG_GENERIC_CLOCKEVENTS_BROADCAST=y
+CONFIG_GENERIC_CLOCKEVENTS_MIN_ADJUST=y
+CONFIG_GENERIC_CMOS_UPDATE=y
+
+#
+# Timers subsystem
+#
+CONFIG_TICK_ONESHOT=y
+CONFIG_NO_HZ_COMMON=y
+# CONFIG_HZ_PERIODIC is not set
+CONFIG_NO_HZ_IDLE=y
+CONFIG_NO_HZ=y
+CONFIG_HIGH_RES_TIMERS=y
+
+#
+# CPU/Task time and stats accounting
+#
+CONFIG_TICK_CPU_ACCOUNTING=y
+# CONFIG_VIRT_CPU_ACCOUNTING_GEN is not set
+# CONFIG_IRQ_TIME_ACCOUNTING is not set
+CONFIG_BSD_PROCESS_ACCT=y
+# CONFIG_BSD_PROCESS_ACCT_V3 is not set
+# CONFIG_TASKSTATS is not set
+
+#
+# RCU Subsystem
+#
+CONFIG_TINY_RCU=y
+# CONFIG_PREEMPT_RCU is not set
+# CONFIG_TASKS_RCU is not set
+# CONFIG_RCU_STALL_COMMON is not set
+# CONFIG_TREE_RCU_TRACE is not set
+CONFIG_BUILD_BIN2C=y
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_LOG_BUF_SHIFT=14
+CONFIG_HAVE_UNSTABLE_SCHED_CLOCK=y
+CONFIG_ARCH_SUPPORTS_NUMA_BALANCING=y
+CONFIG_ARCH_SUPPORTS_INT128=y
+# CONFIG_CGROUPS is not set
+# CONFIG_CHECKPOINT_RESTORE is not set
+CONFIG_NAMESPACES=y
+# CONFIG_UTS_NS is not set
+# CONFIG_IPC_NS is not set
+# CONFIG_USER_NS is not set
+# CONFIG_PID_NS is not set
+# CONFIG_NET_NS is not set
+# CONFIG_SCHED_AUTOGROUP is not set
+# CONFIG_SYSFS_DEPRECATED is not set
+# CONFIG_RELAY is not set
+# CONFIG_BLK_DEV_INITRD is not set
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
+CONFIG_SYSCTL_EXCEPTION_TRACE=y
+CONFIG_HAVE_PCSPKR_PLATFORM=y
+CONFIG_BPF=y
+# CONFIG_EXPERT is not set
+CONFIG_SGETMASK_SYSCALL=y
+CONFIG_SYSFS_SYSCALL=y
+# CONFIG_SYSCTL_SYSCALL is not set
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_ALL is not set
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_ELF_CORE=y
+CONFIG_PCSPKR_PLATFORM=y
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=y
+CONFIG_EPOLL=y
+CONFIG_SIGNALFD=y
+CONFIG_TIMERFD=y
+CONFIG_EVENTFD=y
+# CONFIG_BPF_SYSCALL is not set
+CONFIG_SHMEM=y
+CONFIG_AIO=y
+CONFIG_ADVISE_SYSCALLS=y
+CONFIG_PCI_QUIRKS=y
+# CONFIG_EMBEDDED is not set
+CONFIG_HAVE_PERF_EVENTS=y
+
+#
+# Kernel Performance Events And Counters
+#
+CONFIG_PERF_EVENTS=y
+# CONFIG_DEBUG_PERF_USE_VMALLOC is not set
+CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_COMPAT_BRK=y
+CONFIG_SLAB=y
+# CONFIG_SLUB is not set
+# CONFIG_PROFILING is not set
+CONFIG_HAVE_OPROFILE=y
+CONFIG_OPROFILE_NMI_TIMER=y
+# CONFIG_JUMP_LABEL is not set
+# CONFIG_UPROBES is not set
+# CONFIG_HAVE_64BIT_ALIGNED_ACCESS is not set
+CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS=y
+CONFIG_ARCH_USE_BUILTIN_BSWAP=y
+CONFIG_HAVE_IOREMAP_PROT=y
+CONFIG_HAVE_KPROBES=y
+CONFIG_HAVE_KRETPROBES=y
+CONFIG_HAVE_OPTPROBES=y
+CONFIG_HAVE_KPROBES_ON_FTRACE=y
+CONFIG_HAVE_ARCH_TRACEHOOK=y
+CONFIG_HAVE_DMA_ATTRS=y
+CONFIG_HAVE_DMA_CONTIGUOUS=y
+CONFIG_GENERIC_SMP_IDLE_THREAD=y
+CONFIG_HAVE_REGS_AND_STACK_ACCESS_API=y
+CONFIG_HAVE_DMA_API_DEBUG=y
+CONFIG_HAVE_HW_BREAKPOINT=y
+CONFIG_HAVE_MIXED_BREAKPOINTS_REGS=y
+CONFIG_HAVE_USER_RETURN_NOTIFIER=y
+CONFIG_HAVE_PERF_EVENTS_NMI=y
+CONFIG_HAVE_PERF_REGS=y
+CONFIG_HAVE_PERF_USER_STACK_DUMP=y
+CONFIG_HAVE_ARCH_JUMP_LABEL=y
+CONFIG_ARCH_HAVE_NMI_SAFE_CMPXCHG=y
+CONFIG_HAVE_CMPXCHG_LOCAL=y
+CONFIG_HAVE_CMPXCHG_DOUBLE=y
+CONFIG_HAVE_ARCH_SECCOMP_FILTER=y
+CONFIG_SECCOMP_FILTER=y
+CONFIG_HAVE_CC_STACKPROTECTOR=y
+CONFIG_CC_STACKPROTECTOR=y
+# CONFIG_CC_STACKPROTECTOR_NONE is not set
+CONFIG_CC_STACKPROTECTOR_REGULAR=y
+# CONFIG_CC_STACKPROTECTOR_STRONG is not set
+CONFIG_HAVE_CONTEXT_TRACKING=y
+CONFIG_HAVE_VIRT_CPU_ACCOUNTING_GEN=y
+CONFIG_HAVE_IRQ_TIME_ACCOUNTING=y
+CONFIG_HAVE_ARCH_TRANSPARENT_HUGEPAGE=y
+CONFIG_HAVE_ARCH_SOFT_DIRTY=y
+CONFIG_MODULES_USE_ELF_RELA=y
+CONFIG_HAVE_IRQ_EXIT_ON_IRQ_STACK=y
+
+#
+# GCOV-based kernel profiling
+#
+# CONFIG_HAVE_GENERIC_DMA_COHERENT is not set
+CONFIG_SLABINFO=y
+CONFIG_RT_MUTEXES=y
+CONFIG_BASE_SMALL=0
+# CONFIG_MODULES is not set
+CONFIG_BLOCK=y
+# CONFIG_BLK_DEV_BSG is not set
+# CONFIG_BLK_DEV_BSGLIB is not set
+# CONFIG_BLK_DEV_INTEGRITY is not set
+# CONFIG_BLK_CMDLINE_PARSER is not set
+
+#
+# Partition Types
+#
+# CONFIG_PARTITION_ADVANCED is not set
+CONFIG_MSDOS_PARTITION=y
+CONFIG_EFI_PARTITION=y
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+# CONFIG_DEFAULT_DEADLINE is not set
+CONFIG_DEFAULT_CFQ=y
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="cfq"
+CONFIG_INLINE_SPIN_UNLOCK_IRQ=y
+CONFIG_INLINE_READ_UNLOCK=y
+CONFIG_INLINE_READ_UNLOCK_IRQ=y
+CONFIG_INLINE_WRITE_UNLOCK=y
+CONFIG_INLINE_WRITE_UNLOCK_IRQ=y
+CONFIG_ARCH_SUPPORTS_ATOMIC_RMW=y
+CONFIG_ARCH_USE_QUEUE_RWLOCK=y
+CONFIG_FREEZER=y
+
+#
+# Processor type and features
+#
+CONFIG_ZONE_DMA=y
+# CONFIG_SMP is not set
+CONFIG_X86_FEATURE_NAMES=y
+CONFIG_X86_MPPARSE=y
+CONFIG_X86_EXTENDED_PLATFORM=y
+# CONFIG_X86_GOLDFISH is not set
+# CONFIG_X86_INTEL_LPSS is not set
+CONFIG_IOSF_MBI=y
+CONFIG_SCHED_OMIT_FRAME_POINTER=y
+# CONFIG_HYPERVISOR_GUEST is not set
+CONFIG_NO_BOOTMEM=y
+# CONFIG_MEMTEST is not set
+# CONFIG_MK8 is not set
+# CONFIG_MPSC is not set
+CONFIG_MCORE2=y
+# CONFIG_MATOM is not set
+# CONFIG_GENERIC_CPU is not set
+CONFIG_X86_INTERNODE_CACHE_SHIFT=6
+CONFIG_X86_L1_CACHE_SHIFT=6
+CONFIG_X86_INTEL_USERCOPY=y
+CONFIG_X86_USE_PPRO_CHECKSUM=y
+CONFIG_X86_P6_NOP=y
+CONFIG_X86_TSC=y
+CONFIG_X86_CMPXCHG64=y
+CONFIG_X86_CMOV=y
+CONFIG_X86_MINIMUM_CPU_FAMILY=64
+CONFIG_X86_DEBUGCTLMSR=y
+CONFIG_CPU_SUP_INTEL=y
+CONFIG_CPU_SUP_AMD=y
+CONFIG_CPU_SUP_CENTAUR=y
+CONFIG_HPET_TIMER=y
+CONFIG_DMI=y
+CONFIG_GART_IOMMU=y
+# CONFIG_CALGARY_IOMMU is not set
+CONFIG_SWIOTLB=y
+CONFIG_IOMMU_HELPER=y
+CONFIG_NR_CPUS=1
+CONFIG_PREEMPT_NONE=y
+# CONFIG_PREEMPT_VOLUNTARY is not set
+# CONFIG_PREEMPT is not set
+CONFIG_X86_LOCAL_APIC=y
+CONFIG_X86_IO_APIC=y
+# CONFIG_X86_REROUTE_FOR_BROKEN_BOOT_IRQS is not set
+# CONFIG_X86_MCE is not set
+CONFIG_X86_16BIT=y
+CONFIG_X86_ESPFIX64=y
+# CONFIG_I8K is not set
+# CONFIG_MICROCODE is not set
+# CONFIG_MICROCODE_INTEL_EARLY is not set
+# CONFIG_MICROCODE_AMD_EARLY is not set
+# CONFIG_X86_MSR is not set
+# CONFIG_X86_CPUID is not set
+CONFIG_ARCH_PHYS_ADDR_T_64BIT=y
+CONFIG_ARCH_DMA_ADDR_T_64BIT=y
+CONFIG_DIRECT_GBPAGES=y
+CONFIG_ARCH_SPARSEMEM_ENABLE=y
+CONFIG_ARCH_SPARSEMEM_DEFAULT=y
+CONFIG_ARCH_SELECT_MEMORY_MODEL=y
+CONFIG_ARCH_MEMORY_PROBE=y
+CONFIG_ARCH_PROC_KCORE_TEXT=y
+CONFIG_ILLEGAL_POINTER_VALUE=0xdead000000000000
+CONFIG_SELECT_MEMORY_MODEL=y
+CONFIG_SPARSEMEM_MANUAL=y
+CONFIG_SPARSEMEM=y
+CONFIG_HAVE_MEMORY_PRESENT=y
+CONFIG_SPARSEMEM_EXTREME=y
+CONFIG_SPARSEMEM_VMEMMAP_ENABLE=y
+CONFIG_SPARSEMEM_ALLOC_MEM_MAP_TOGETHER=y
+CONFIG_SPARSEMEM_VMEMMAP=y
+CONFIG_HAVE_MEMBLOCK=y
+CONFIG_HAVE_MEMBLOCK_NODE_MAP=y
+CONFIG_ARCH_DISCARD_MEMBLOCK=y
+CONFIG_MEMORY_ISOLATION=y
+CONFIG_HAVE_BOOTMEM_INFO_NODE=y
+CONFIG_MEMORY_HOTPLUG=y
+CONFIG_MEMORY_HOTPLUG_SPARSE=y
+CONFIG_MEMORY_HOTREMOVE=y
+CONFIG_PAGEFLAGS_EXTENDED=y
+CONFIG_SPLIT_PTLOCK_CPUS=4
+CONFIG_ARCH_ENABLE_SPLIT_PMD_PTLOCK=y
+CONFIG_MEMORY_BALLOON=y
+# CONFIG_COMPACTION is not set
+CONFIG_MIGRATION=y
+CONFIG_PHYS_ADDR_T_64BIT=y
+CONFIG_ZONE_DMA_FLAG=1
+CONFIG_BOUNCE=y
+CONFIG_VIRT_TO_BUS=y
+# CONFIG_KSM is not set
+CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
+# CONFIG_TRANSPARENT_HUGEPAGE is not set
+CONFIG_NEED_PER_CPU_KM=y
+# CONFIG_CLEANCACHE is not set
+# CONFIG_FRONTSWAP is not set
+# CONFIG_CMA is not set
+# CONFIG_ZPOOL is not set
+# CONFIG_ZBUD is not set
+# CONFIG_ZSMALLOC is not set
+CONFIG_GENERIC_EARLY_IOREMAP=y
+# CONFIG_X86_CHECK_BIOS_CORRUPTION is not set
+CONFIG_X86_RESERVE_LOW=64
+CONFIG_MTRR=y
+CONFIG_MTRR_SANITIZER=y
+CONFIG_MTRR_SANITIZER_ENABLE_DEFAULT=0
+CONFIG_MTRR_SANITIZER_SPARE_REG_NR_DEFAULT=1
+CONFIG_X86_PAT=y
+CONFIG_ARCH_USES_PG_UNCACHED=y
+CONFIG_ARCH_RANDOM=y
+CONFIG_X86_SMAP=y
+# CONFIG_EFI is not set
+CONFIG_SECCOMP=y
+# CONFIG_HZ_100 is not set
+CONFIG_HZ_250=y
+# CONFIG_HZ_300 is not set
+# CONFIG_HZ_1000 is not set
+CONFIG_HZ=250
+CONFIG_SCHED_HRTICK=y
+# CONFIG_KEXEC is not set
+# CONFIG_CRASH_DUMP is not set
+CONFIG_PHYSICAL_START=0x1000000
+CONFIG_RELOCATABLE=y
+# CONFIG_RANDOMIZE_BASE is not set
+CONFIG_PHYSICAL_ALIGN=0x1000000
+# CONFIG_CMDLINE_BOOL is not set
+CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
+CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y
+
+#
+# Power management and ACPI options
+#
+CONFIG_SUSPEND=y
+CONFIG_SUSPEND_FREEZER=y
+# CONFIG_HIBERNATION is not set
+CONFIG_PM_SLEEP=y
+# CONFIG_PM_AUTOSLEEP is not set
+# CONFIG_PM_WAKELOCKS is not set
+# CONFIG_PM_RUNTIME is not set
+CONFIG_PM=y
+# CONFIG_PM_DEBUG is not set
+# CONFIG_WQ_POWER_EFFICIENT_DEFAULT is not set
+CONFIG_ACPI=y
+CONFIG_ACPI_LEGACY_TABLES_LOOKUP=y
+CONFIG_ARCH_MIGHT_HAVE_ACPI_PDC=y
+CONFIG_ACPI_SLEEP=y
+# CONFIG_ACPI_PROCFS_POWER is not set
+# CONFIG_ACPI_EC_DEBUGFS is not set
+CONFIG_ACPI_AC=y
+CONFIG_ACPI_BATTERY=y
+CONFIG_ACPI_BUTTON=y
+CONFIG_ACPI_FAN=y
+# CONFIG_ACPI_DOCK is not set
+CONFIG_ACPI_PROCESSOR=y
+# CONFIG_ACPI_PROCESSOR_AGGREGATOR is not set
+CONFIG_ACPI_THERMAL=y
+# CONFIG_ACPI_CUSTOM_DSDT is not set
+# CONFIG_ACPI_DEBUG is not set
+# CONFIG_ACPI_PCI_SLOT is not set
+CONFIG_X86_PM_TIMER=y
+# CONFIG_ACPI_CONTAINER is not set
+# CONFIG_ACPI_HOTPLUG_MEMORY is not set
+# CONFIG_ACPI_SBS is not set
+# CONFIG_ACPI_HED is not set
+# CONFIG_ACPI_REDUCED_HARDWARE_ONLY is not set
+CONFIG_HAVE_ACPI_APEI=y
+CONFIG_HAVE_ACPI_APEI_NMI=y
+# CONFIG_ACPI_APEI is not set
+# CONFIG_SFI is not set
+
+#
+# CPU Frequency scaling
+#
+# CONFIG_CPU_FREQ is not set
+
+#
+# CPU Idle
+#
+CONFIG_CPU_IDLE=y
+CONFIG_CPU_IDLE_GOV_LADDER=y
+CONFIG_CPU_IDLE_GOV_MENU=y
+# CONFIG_ARCH_NEEDS_CPU_IDLE_COUPLED is not set
+# CONFIG_INTEL_IDLE is not set
+
+#
+# Memory power savings
+#
+# CONFIG_I7300_IDLE is not set
+
+#
+# Bus options (PCI etc.)
+#
+CONFIG_PCI=y
+CONFIG_PCI_DIRECT=y
+# CONFIG_PCI_MMCONFIG is not set
+CONFIG_PCI_DOMAINS=y
+# CONFIG_PCIEPORTBUS is not set
+CONFIG_PCI_MSI=y
+# CONFIG_PCI_DEBUG is not set
+# CONFIG_PCI_REALLOC_ENABLE_AUTO is not set
+# CONFIG_PCI_STUB is not set
+CONFIG_HT_IRQ=y
+# CONFIG_PCI_IOV is not set
+# CONFIG_PCI_PRI is not set
+# CONFIG_PCI_PASID is not set
+# CONFIG_PCI_IOAPIC is not set
+CONFIG_PCI_LABEL=y
+
+#
+# PCI host controller drivers
+#
+CONFIG_ISA_DMA_API=y
+CONFIG_AMD_NB=y
+# CONFIG_PCCARD is not set
+# CONFIG_HOTPLUG_PCI is not set
+# CONFIG_RAPIDIO is not set
+# CONFIG_X86_SYSFB is not set
+
+#
+# Executable file formats / Emulations
+#
+CONFIG_BINFMT_ELF=y
+CONFIG_ARCH_BINFMT_ELF_RANDOMIZE_PIE=y
+# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
+CONFIG_BINFMT_SCRIPT=y
+# CONFIG_HAVE_AOUT is not set
+# CONFIG_BINFMT_MISC is not set
+CONFIG_COREDUMP=y
+# CONFIG_IA32_EMULATION is not set
+CONFIG_X86_DEV_DMA_OPS=y
+CONFIG_PMC_ATOM=y
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+# CONFIG_PACKET_DIAG is not set
+CONFIG_UNIX=y
+# CONFIG_UNIX_DIAG is not set
+CONFIG_XFRM=y
+CONFIG_XFRM_ALGO=y
+CONFIG_XFRM_USER=y
+CONFIG_XFRM_SUB_POLICY=y
+CONFIG_XFRM_MIGRATE=y
+CONFIG_XFRM_STATISTICS=y
+CONFIG_XFRM_IPCOMP=y
+CONFIG_NET_KEY=y
+CONFIG_NET_KEY_MIGRATE=y
+CONFIG_INET=y
+# CONFIG_IP_MULTICAST is not set
+CONFIG_IP_ADVANCED_ROUTER=y
+# CONFIG_IP_FIB_TRIE_STATS is not set
+CONFIG_IP_MULTIPLE_TABLES=y
+# CONFIG_IP_ROUTE_MULTIPATH is not set
+# CONFIG_IP_ROUTE_VERBOSE is not set
+CONFIG_IP_ROUTE_CLASSID=y
+# CONFIG_IP_PNP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE_DEMUX is not set
+CONFIG_NET_IP_TUNNEL=y
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_NET_IPVTI is not set
+CONFIG_NET_UDP_TUNNEL=y
+# CONFIG_NET_FOU is not set
+# CONFIG_GENEVE is not set
+CONFIG_INET_AH=y
+CONFIG_INET_ESP=y
+CONFIG_INET_IPCOMP=y
+CONFIG_INET_XFRM_TUNNEL=y
+CONFIG_INET_TUNNEL=y
+CONFIG_INET_XFRM_MODE_TRANSPORT=y
+CONFIG_INET_XFRM_MODE_TUNNEL=y
+CONFIG_INET_XFRM_MODE_BEET=y
+# CONFIG_INET_LRO is not set
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+# CONFIG_INET_UDP_DIAG is not set
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
+# CONFIG_TCP_MD5SIG is not set
+CONFIG_IPV6=y
+# CONFIG_IPV6_ROUTER_PREF is not set
+CONFIG_IPV6_OPTIMISTIC_DAD=y
+CONFIG_INET6_AH=y
+CONFIG_INET6_ESP=y
+CONFIG_INET6_IPCOMP=y
+CONFIG_IPV6_MIP6=y
+CONFIG_INET6_XFRM_TUNNEL=y
+CONFIG_INET6_TUNNEL=y
+CONFIG_INET6_XFRM_MODE_TRANSPORT=y
+CONFIG_INET6_XFRM_MODE_TUNNEL=y
+CONFIG_INET6_XFRM_MODE_BEET=y
+# CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set
+# CONFIG_IPV6_VTI is not set
+# CONFIG_IPV6_SIT is not set
+CONFIG_IPV6_TUNNEL=y
+CONFIG_IPV6_GRE=y
+CONFIG_IPV6_MULTIPLE_TABLES=y
+CONFIG_IPV6_SUBTREES=y
+# CONFIG_IPV6_MROUTE is not set
+# CONFIG_NETWORK_SECMARK is not set
+# CONFIG_NET_PTP_CLASSIFY is not set
+# CONFIG_NETWORK_PHY_TIMESTAMPING is not set
+CONFIG_NETFILTER=y
+# CONFIG_NETFILTER_DEBUG is not set
+CONFIG_NETFILTER_ADVANCED=y
+
+#
+# Core Netfilter Configuration
+#
+CONFIG_NETFILTER_NETLINK=y
+# CONFIG_NETFILTER_NETLINK_ACCT is not set
+CONFIG_NETFILTER_NETLINK_QUEUE=y
+CONFIG_NETFILTER_NETLINK_LOG=y
+CONFIG_NF_CONNTRACK=y
+CONFIG_NF_LOG_COMMON=y
+CONFIG_NF_CONNTRACK_MARK=y
+# CONFIG_NF_CONNTRACK_ZONES is not set
+CONFIG_NF_CONNTRACK_PROCFS=y
+CONFIG_NF_CONNTRACK_EVENTS=y
+# CONFIG_NF_CONNTRACK_TIMEOUT is not set
+# CONFIG_NF_CONNTRACK_TIMESTAMP is not set
+# CONFIG_NF_CT_PROTO_DCCP is not set
+# CONFIG_NF_CT_PROTO_SCTP is not set
+CONFIG_NF_CT_PROTO_UDPLITE=y
+# CONFIG_NF_CONNTRACK_AMANDA is not set
+# CONFIG_NF_CONNTRACK_FTP is not set
+# CONFIG_NF_CONNTRACK_H323 is not set
+# CONFIG_NF_CONNTRACK_IRC is not set
+# CONFIG_NF_CONNTRACK_NETBIOS_NS is not set
+# CONFIG_NF_CONNTRACK_SNMP is not set
+# CONFIG_NF_CONNTRACK_PPTP is not set
+CONFIG_NF_CONNTRACK_SANE=y
+# CONFIG_NF_CONNTRACK_SIP is not set
+# CONFIG_NF_CONNTRACK_TFTP is not set
+CONFIG_NF_CT_NETLINK=y
+# CONFIG_NF_CT_NETLINK_TIMEOUT is not set
+# CONFIG_NETFILTER_NETLINK_QUEUE_CT is not set
+CONFIG_NF_NAT=y
+CONFIG_NF_NAT_NEEDED=y
+CONFIG_NF_NAT_PROTO_UDPLITE=y
+# CONFIG_NF_NAT_AMANDA is not set
+# CONFIG_NF_NAT_FTP is not set
+# CONFIG_NF_NAT_IRC is not set
+# CONFIG_NF_NAT_SIP is not set
+# CONFIG_NF_NAT_TFTP is not set
+# CONFIG_NF_TABLES is not set
+CONFIG_NETFILTER_XTABLES=y
+
+#
+# Xtables combined modules
+#
+CONFIG_NETFILTER_XT_MARK=y
+CONFIG_NETFILTER_XT_CONNMARK=y
+CONFIG_NETFILTER_XT_SET=y
+
+#
+# Xtables targets
+#
+# CONFIG_NETFILTER_XT_TARGET_CHECKSUM is not set
+CONFIG_NETFILTER_XT_TARGET_CLASSIFY=y
+CONFIG_NETFILTER_XT_TARGET_CONNMARK=y
+CONFIG_NETFILTER_XT_TARGET_CT=y
+CONFIG_NETFILTER_XT_TARGET_DSCP=y
+CONFIG_NETFILTER_XT_TARGET_HL=y
+# CONFIG_NETFILTER_XT_TARGET_HMARK is not set
+# CONFIG_NETFILTER_XT_TARGET_IDLETIMER is not set
+CONFIG_NETFILTER_XT_TARGET_LOG=y
+CONFIG_NETFILTER_XT_TARGET_MARK=y
+CONFIG_NETFILTER_XT_NAT=y
+CONFIG_NETFILTER_XT_TARGET_NETMAP=y
+CONFIG_NETFILTER_XT_TARGET_NFLOG=y
+CONFIG_NETFILTER_XT_TARGET_NFQUEUE=y
+CONFIG_NETFILTER_XT_TARGET_NOTRACK=y
+# CONFIG_NETFILTER_XT_TARGET_RATEEST is not set
+CONFIG_NETFILTER_XT_TARGET_REDIRECT=y
+# CONFIG_NETFILTER_XT_TARGET_TEE is not set
+# CONFIG_NETFILTER_XT_TARGET_TPROXY is not set
+CONFIG_NETFILTER_XT_TARGET_TRACE=y
+CONFIG_NETFILTER_XT_TARGET_TCPMSS=y
+# CONFIG_NETFILTER_XT_TARGET_TCPOPTSTRIP is not set
+
+#
+# Xtables matches
+#
+CONFIG_NETFILTER_XT_MATCH_ADDRTYPE=y
+# CONFIG_NETFILTER_XT_MATCH_BPF is not set
+CONFIG_NETFILTER_XT_MATCH_CLUSTER=y
+CONFIG_NETFILTER_XT_MATCH_COMMENT=y
+CONFIG_NETFILTER_XT_MATCH_CONNBYTES=y
+# CONFIG_NETFILTER_XT_MATCH_CONNLABEL is not set
+CONFIG_NETFILTER_XT_MATCH_CONNLIMIT=y
+CONFIG_NETFILTER_XT_MATCH_CONNMARK=y
+CONFIG_NETFILTER_XT_MATCH_CONNTRACK=y
+# CONFIG_NETFILTER_XT_MATCH_CPU is not set
+CONFIG_NETFILTER_XT_MATCH_DCCP=y
+CONFIG_NETFILTER_XT_MATCH_DEVGROUP=y
+CONFIG_NETFILTER_XT_MATCH_DSCP=y
+CONFIG_NETFILTER_XT_MATCH_ECN=y
+CONFIG_NETFILTER_XT_MATCH_ESP=y
+CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=y
+CONFIG_NETFILTER_XT_MATCH_HELPER=y
+CONFIG_NETFILTER_XT_MATCH_HL=y
+# CONFIG_NETFILTER_XT_MATCH_IPCOMP is not set
+# CONFIG_NETFILTER_XT_MATCH_IPRANGE is not set
+CONFIG_NETFILTER_XT_MATCH_L2TP=y
+CONFIG_NETFILTER_XT_MATCH_LENGTH=y
+CONFIG_NETFILTER_XT_MATCH_LIMIT=y
+CONFIG_NETFILTER_XT_MATCH_MAC=y
+CONFIG_NETFILTER_XT_MATCH_MARK=y
+CONFIG_NETFILTER_XT_MATCH_MULTIPORT=y
+# CONFIG_NETFILTER_XT_MATCH_NFACCT is not set
+# CONFIG_NETFILTER_XT_MATCH_OSF is not set
+# CONFIG_NETFILTER_XT_MATCH_OWNER is not set
+CONFIG_NETFILTER_XT_MATCH_POLICY=y
+CONFIG_NETFILTER_XT_MATCH_PKTTYPE=y
+CONFIG_NETFILTER_XT_MATCH_QUOTA=y
+# CONFIG_NETFILTER_XT_MATCH_RATEEST is not set
+CONFIG_NETFILTER_XT_MATCH_REALM=y
+# CONFIG_NETFILTER_XT_MATCH_RECENT is not set
+CONFIG_NETFILTER_XT_MATCH_SCTP=y
+# CONFIG_NETFILTER_XT_MATCH_SOCKET is not set
+CONFIG_NETFILTER_XT_MATCH_STATE=y
+CONFIG_NETFILTER_XT_MATCH_STATISTIC=y
+CONFIG_NETFILTER_XT_MATCH_STRING=y
+CONFIG_NETFILTER_XT_MATCH_TCPMSS=y
+# CONFIG_NETFILTER_XT_MATCH_TIME is not set
+CONFIG_NETFILTER_XT_MATCH_U32=y
+CONFIG_IP_SET=y
+CONFIG_IP_SET_MAX=256
+CONFIG_IP_SET_BITMAP_IP=y
+CONFIG_IP_SET_BITMAP_IPMAC=y
+CONFIG_IP_SET_BITMAP_PORT=y
+CONFIG_IP_SET_HASH_IP=y
+# CONFIG_IP_SET_HASH_IPMARK is not set
+CONFIG_IP_SET_HASH_IPPORT=y
+CONFIG_IP_SET_HASH_IPPORTIP=y
+CONFIG_IP_SET_HASH_IPPORTNET=y
+# CONFIG_IP_SET_HASH_MAC is not set
+# CONFIG_IP_SET_HASH_NETPORTNET is not set
+CONFIG_IP_SET_HASH_NET=y
+# CONFIG_IP_SET_HASH_NETNET is not set
+CONFIG_IP_SET_HASH_NETPORT=y
+# CONFIG_IP_SET_HASH_NETIFACE is not set
+CONFIG_IP_SET_LIST_SET=y
+# CONFIG_IP_VS is not set
+
+#
+# IP: Netfilter Configuration
+#
+CONFIG_NF_DEFRAG_IPV4=y
+CONFIG_NF_CONNTRACK_IPV4=y
+CONFIG_NF_CONNTRACK_PROC_COMPAT=y
+# CONFIG_NF_LOG_ARP is not set
+CONFIG_NF_LOG_IPV4=y
+CONFIG_NF_REJECT_IPV4=y
+CONFIG_NF_NAT_IPV4=y
+CONFIG_NF_NAT_MASQUERADE_IPV4=y
+# CONFIG_NF_NAT_PPTP is not set
+# CONFIG_NF_NAT_H323 is not set
+CONFIG_IP_NF_IPTABLES=y
+CONFIG_IP_NF_MATCH_AH=y
+CONFIG_IP_NF_MATCH_ECN=y
+# CONFIG_IP_NF_MATCH_RPFILTER is not set
+CONFIG_IP_NF_MATCH_TTL=y
+CONFIG_IP_NF_FILTER=y
+CONFIG_IP_NF_TARGET_REJECT=y
+# CONFIG_IP_NF_TARGET_SYNPROXY is not set
+CONFIG_IP_NF_NAT=y
+CONFIG_IP_NF_TARGET_MASQUERADE=y
+CONFIG_IP_NF_TARGET_NETMAP=y
+CONFIG_IP_NF_TARGET_REDIRECT=y
+CONFIG_IP_NF_MANGLE=y
+CONFIG_IP_NF_TARGET_CLUSTERIP=y
+CONFIG_IP_NF_TARGET_ECN=y
+CONFIG_IP_NF_TARGET_TTL=y
+CONFIG_IP_NF_RAW=y
+CONFIG_IP_NF_ARPTABLES=y
+CONFIG_IP_NF_ARPFILTER=y
+CONFIG_IP_NF_ARP_MANGLE=y
+
+#
+# IPv6: Netfilter Configuration
+#
+CONFIG_NF_DEFRAG_IPV6=y
+CONFIG_NF_CONNTRACK_IPV6=y
+CONFIG_NF_REJECT_IPV6=y
+CONFIG_NF_LOG_IPV6=y
+CONFIG_NF_NAT_IPV6=y
+CONFIG_NF_NAT_MASQUERADE_IPV6=y
+CONFIG_IP6_NF_IPTABLES=y
+CONFIG_IP6_NF_MATCH_AH=y
+CONFIG_IP6_NF_MATCH_EUI64=y
+CONFIG_IP6_NF_MATCH_FRAG=y
+CONFIG_IP6_NF_MATCH_OPTS=y
+CONFIG_IP6_NF_MATCH_HL=y
+CONFIG_IP6_NF_MATCH_IPV6HEADER=y
+CONFIG_IP6_NF_MATCH_MH=y
+# CONFIG_IP6_NF_MATCH_RPFILTER is not set
+CONFIG_IP6_NF_MATCH_RT=y
+CONFIG_IP6_NF_TARGET_HL=y
+CONFIG_IP6_NF_FILTER=y
+CONFIG_IP6_NF_TARGET_REJECT=y
+# CONFIG_IP6_NF_TARGET_SYNPROXY is not set
+CONFIG_IP6_NF_MANGLE=y
+CONFIG_IP6_NF_RAW=y
+# CONFIG_IP6_NF_NAT is not set
+# CONFIG_IP_DCCP is not set
+# CONFIG_IP_SCTP is not set
+# CONFIG_RDS is not set
+# CONFIG_TIPC is not set
+# CONFIG_ATM is not set
+CONFIG_L2TP=y
+# CONFIG_L2TP_V3 is not set
+# CONFIG_BRIDGE is not set
+CONFIG_HAVE_NET_DSA=y
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_PHONET is not set
+# CONFIG_6LOWPAN is not set
+# CONFIG_IEEE802154 is not set
+# CONFIG_NET_SCHED is not set
+# CONFIG_DCB is not set
+# CONFIG_BATMAN_ADV is not set
+# CONFIG_OPENVSWITCH is not set
+# CONFIG_VSOCKETS is not set
+# CONFIG_NETLINK_MMAP is not set
+# CONFIG_NETLINK_DIAG is not set
+# CONFIG_NET_MPLS_GSO is not set
+# CONFIG_HSR is not set
+CONFIG_NET_RX_BUSY_POLL=y
+CONFIG_BQL=y
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_CAN is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+# CONFIG_AF_RXRPC is not set
+CONFIG_FIB_RULES=y
+CONFIG_WIRELESS=y
+# CONFIG_CFG80211 is not set
+# CONFIG_LIB80211 is not set
+
+#
+# CFG80211 needs to be enabled for MAC80211
+#
+# CONFIG_WIMAX is not set
+# CONFIG_RFKILL is not set
+CONFIG_NET_9P=y
+CONFIG_NET_9P_VIRTIO=y
+# CONFIG_NET_9P_DEBUG is not set
+# CONFIG_CAIF is not set
+# CONFIG_CEPH_LIB is not set
+# CONFIG_NFC is not set
+CONFIG_HAVE_BPF_JIT=y
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_UEVENT_HELPER=y
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+# CONFIG_DEVTMPFS is not set
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+CONFIG_FW_LOADER=y
+CONFIG_FIRMWARE_IN_KERNEL=y
+CONFIG_EXTRA_FIRMWARE=""
+# CONFIG_FW_LOADER_USER_HELPER_FALLBACK is not set
+CONFIG_ALLOW_DEV_COREDUMP=y
+# CONFIG_DEBUG_DRIVER is not set
+# CONFIG_DEBUG_DEVRES is not set
+# CONFIG_SYS_HYPERVISOR is not set
+# CONFIG_GENERIC_CPU_DEVICES is not set
+CONFIG_GENERIC_CPU_AUTOPROBE=y
+# CONFIG_DMA_SHARED_BUFFER is not set
+
+#
+# Bus devices
+#
+# CONFIG_CONNECTOR is not set
+# CONFIG_MTD is not set
+CONFIG_ARCH_MIGHT_HAVE_PC_PARPORT=y
+# CONFIG_PARPORT is not set
+CONFIG_PNP=y
+CONFIG_PNP_DEBUG_MESSAGES=y
+
+#
+# Protocols
+#
+CONFIG_PNPACPI=y
+CONFIG_BLK_DEV=y
+# CONFIG_BLK_DEV_NULL_BLK is not set
+# CONFIG_BLK_DEV_FD is not set
+# CONFIG_BLK_DEV_PCIESSD_MTIP32XX is not set
+# CONFIG_BLK_CPQ_CISS_DA is not set
+# CONFIG_BLK_DEV_DAC960 is not set
+# CONFIG_BLK_DEV_UMEM is not set
+# CONFIG_BLK_DEV_COW_COMMON is not set
+CONFIG_BLK_DEV_LOOP=y
+CONFIG_BLK_DEV_LOOP_MIN_COUNT=8
+# CONFIG_BLK_DEV_CRYPTOLOOP is not set
+# CONFIG_BLK_DEV_DRBD is not set
+CONFIG_BLK_DEV_NBD=y
+# CONFIG_BLK_DEV_NVME is not set
+# CONFIG_BLK_DEV_SKD is not set
+# CONFIG_BLK_DEV_SX8 is not set
+# CONFIG_BLK_DEV_RAM is not set
+# CONFIG_CDROM_PKTCDVD is not set
+# CONFIG_ATA_OVER_ETH is not set
+CONFIG_VIRTIO_BLK=y
+# CONFIG_BLK_DEV_HD is not set
+# CONFIG_BLK_DEV_RBD is not set
+# CONFIG_BLK_DEV_RSXX is not set
+
+#
+# Misc devices
+#
+# CONFIG_SENSORS_LIS3LV02D is not set
+# CONFIG_DUMMY_IRQ is not set
+# CONFIG_IBM_ASM is not set
+# CONFIG_PHANTOM is not set
+# CONFIG_SGI_IOC4 is not set
+# CONFIG_TIFM_CORE is not set
+# CONFIG_ENCLOSURE_SERVICES is not set
+# CONFIG_HP_ILO is not set
+# CONFIG_SRAM is not set
+# CONFIG_C2PORT is not set
+
+#
+# EEPROM support
+#
+# CONFIG_EEPROM_93CX6 is not set
+# CONFIG_CB710_CORE is not set
+
+#
+# Texas Instruments shared transport line discipline
+#
+
+#
+# Altera FPGA firmware download module
+#
+# CONFIG_VMWARE_VMCI is not set
+
+#
+# Intel MIC Bus Driver
+#
+# CONFIG_INTEL_MIC_BUS is not set
+
+#
+# Intel MIC Host Driver
+#
+
+#
+# Intel MIC Card Driver
+#
+# CONFIG_GENWQE is not set
+# CONFIG_ECHO is not set
+# CONFIG_CXL_BASE is not set
+CONFIG_HAVE_IDE=y
+# CONFIG_IDE is not set
+
+#
+# SCSI device support
+#
+CONFIG_SCSI_MOD=y
+# CONFIG_RAID_ATTRS is not set
+# CONFIG_SCSI is not set
+# CONFIG_SCSI_DMA is not set
+# CONFIG_SCSI_NETLINK is not set
+# CONFIG_ATA is not set
+# CONFIG_MD is not set
+# CONFIG_FUSION is not set
+
+#
+# IEEE 1394 (FireWire) support
+#
+# CONFIG_FIREWIRE is not set
+# CONFIG_FIREWIRE_NOSY is not set
+# CONFIG_I2O is not set
+# CONFIG_MACINTOSH_DRIVERS is not set
+CONFIG_NETDEVICES=y
+CONFIG_NET_CORE=y
+# CONFIG_BONDING is not set
+CONFIG_DUMMY=y
+# CONFIG_EQUALIZER is not set
+# CONFIG_NET_TEAM is not set
+# CONFIG_MACVLAN is not set
+# CONFIG_VXLAN is not set
+# CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
+CONFIG_TUN=y
+# CONFIG_VETH is not set
+CONFIG_VIRTIO_NET=y
+# CONFIG_NLMON is not set
+# CONFIG_ARCNET is not set
+
+#
+# CAIF transport drivers
+#
+# CONFIG_VHOST_NET is not set
+
+#
+# Distributed Switch Architecture drivers
+#
+# CONFIG_NET_DSA_MV88E6XXX is not set
+# CONFIG_NET_DSA_MV88E6060 is not set
+# CONFIG_NET_DSA_MV88E6XXX_NEED_PPU is not set
+# CONFIG_NET_DSA_MV88E6131 is not set
+# CONFIG_NET_DSA_MV88E6123_61_65 is not set
+# CONFIG_NET_DSA_MV88E6171 is not set
+# CONFIG_NET_DSA_BCM_SF2 is not set
+CONFIG_ETHERNET=y
+CONFIG_NET_VENDOR_3COM=y
+# CONFIG_VORTEX is not set
+# CONFIG_TYPHOON is not set
+CONFIG_NET_VENDOR_ADAPTEC=y
+# CONFIG_ADAPTEC_STARFIRE is not set
+CONFIG_NET_VENDOR_AGERE=y
+# CONFIG_ET131X is not set
+CONFIG_NET_VENDOR_ALTEON=y
+# CONFIG_ACENIC is not set
+# CONFIG_ALTERA_TSE is not set
+CONFIG_NET_VENDOR_AMD=y
+# CONFIG_AMD8111_ETH is not set
+# CONFIG_PCNET32 is not set
+# CONFIG_NET_XGENE is not set
+# CONFIG_NET_VENDOR_ARC is not set
+CONFIG_NET_VENDOR_ATHEROS=y
+# CONFIG_ATL2 is not set
+# CONFIG_ATL1 is not set
+# CONFIG_ATL1E is not set
+# CONFIG_ATL1C is not set
+# CONFIG_ALX is not set
+CONFIG_NET_VENDOR_BROADCOM=y
+# CONFIG_B44 is not set
+# CONFIG_BNX2 is not set
+# CONFIG_CNIC is not set
+# CONFIG_TIGON3 is not set
+# CONFIG_BNX2X is not set
+CONFIG_NET_VENDOR_BROCADE=y
+# CONFIG_BNA is not set
+CONFIG_NET_VENDOR_CHELSIO=y
+# CONFIG_CHELSIO_T1 is not set
+# CONFIG_CHELSIO_T3 is not set
+# CONFIG_CHELSIO_T4 is not set
+# CONFIG_CHELSIO_T4VF is not set
+CONFIG_NET_VENDOR_CISCO=y
+# CONFIG_ENIC is not set
+# CONFIG_CX_ECAT is not set
+# CONFIG_DNET is not set
+CONFIG_NET_VENDOR_DEC=y
+# CONFIG_NET_TULIP is not set
+CONFIG_NET_VENDOR_DLINK=y
+# CONFIG_DL2K is not set
+# CONFIG_SUNDANCE is not set
+CONFIG_NET_VENDOR_EMULEX=y
+# CONFIG_BE2NET is not set
+CONFIG_NET_VENDOR_EXAR=y
+# CONFIG_S2IO is not set
+# CONFIG_VXGE is not set
+CONFIG_NET_VENDOR_HP=y
+# CONFIG_HP100 is not set
+CONFIG_NET_VENDOR_INTEL=y
+# CONFIG_E100 is not set
+# CONFIG_E1000 is not set
+# CONFIG_E1000E is not set
+# CONFIG_IGB is not set
+# CONFIG_IGBVF is not set
+# CONFIG_IXGB is not set
+# CONFIG_IXGBE is not set
+# CONFIG_IXGBEVF is not set
+# CONFIG_I40E is not set
+# CONFIG_I40EVF is not set
+# CONFIG_FM10K is not set
+CONFIG_NET_VENDOR_I825XX=y
+# CONFIG_IP1000 is not set
+# CONFIG_JME is not set
+CONFIG_NET_VENDOR_MARVELL=y
+# CONFIG_MVMDIO is not set
+# CONFIG_SKGE is not set
+# CONFIG_SKY2 is not set
+CONFIG_NET_VENDOR_MELLANOX=y
+# CONFIG_MLX4_EN is not set
+# CONFIG_MLX4_CORE is not set
+# CONFIG_MLX5_CORE is not set
+CONFIG_NET_VENDOR_MICREL=y
+# CONFIG_KS8851_MLL is not set
+# CONFIG_KSZ884X_PCI is not set
+CONFIG_NET_VENDOR_MYRI=y
+# CONFIG_MYRI10GE is not set
+# CONFIG_FEALNX is not set
+CONFIG_NET_VENDOR_NATSEMI=y
+# CONFIG_NATSEMI is not set
+# CONFIG_NS83820 is not set
+CONFIG_NET_VENDOR_8390=y
+# CONFIG_NE2K_PCI is not set
+CONFIG_NET_VENDOR_NVIDIA=y
+# CONFIG_FORCEDETH is not set
+CONFIG_NET_VENDOR_OKI=y
+# CONFIG_ETHOC is not set
+CONFIG_NET_PACKET_ENGINE=y
+# CONFIG_HAMACHI is not set
+# CONFIG_YELLOWFIN is not set
+CONFIG_NET_VENDOR_QLOGIC=y
+# CONFIG_QLA3XXX is not set
+# CONFIG_QLCNIC is not set
+# CONFIG_QLGE is not set
+# CONFIG_NETXEN_NIC is not set
+CONFIG_NET_VENDOR_QUALCOMM=y
+CONFIG_NET_VENDOR_REALTEK=y
+# CONFIG_8139CP is not set
+# CONFIG_8139TOO is not set
+# CONFIG_R8169 is not set
+CONFIG_NET_VENDOR_RDC=y
+# CONFIG_R6040 is not set
+CONFIG_NET_VENDOR_SAMSUNG=y
+# CONFIG_SXGBE_ETH is not set
+CONFIG_NET_VENDOR_SEEQ=y
+CONFIG_NET_VENDOR_SILAN=y
+# CONFIG_SC92031 is not set
+CONFIG_NET_VENDOR_SIS=y
+# CONFIG_SIS900 is not set
+# CONFIG_SIS190 is not set
+# CONFIG_SFC is not set
+CONFIG_NET_VENDOR_SMSC=y
+# CONFIG_EPIC100 is not set
+# CONFIG_SMSC911X is not set
+# CONFIG_SMSC9420 is not set
+CONFIG_NET_VENDOR_STMICRO=y
+# CONFIG_STMMAC_ETH is not set
+CONFIG_NET_VENDOR_SUN=y
+# CONFIG_HAPPYMEAL is not set
+# CONFIG_SUNGEM is not set
+# CONFIG_CASSINI is not set
+# CONFIG_NIU is not set
+CONFIG_NET_VENDOR_TEHUTI=y
+# CONFIG_TEHUTI is not set
+CONFIG_NET_VENDOR_TI=y
+# CONFIG_TLAN is not set
+CONFIG_NET_VENDOR_VIA=y
+# CONFIG_VIA_RHINE is not set
+# CONFIG_VIA_VELOCITY is not set
+CONFIG_NET_VENDOR_WIZNET=y
+# CONFIG_WIZNET_W5100 is not set
+# CONFIG_WIZNET_W5300 is not set
+# CONFIG_FDDI is not set
+# CONFIG_HIPPI is not set
+# CONFIG_NET_SB1000 is not set
+# CONFIG_PHYLIB is not set
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+
+#
+# Host-side USB support is needed for USB Network Adapter support
+#
+CONFIG_WLAN=y
+# CONFIG_PRISM54 is not set
+# CONFIG_HOSTAP is not set
+# CONFIG_WL_TI is not set
+
+#
+# Enable WiMAX (Networking options) to see the WiMAX drivers
+#
+# CONFIG_WAN is not set
+# CONFIG_VMXNET3 is not set
+# CONFIG_ISDN is not set
+
+#
+# Input device support
+#
+CONFIG_INPUT=y
+# CONFIG_INPUT_FF_MEMLESS is not set
+# CONFIG_INPUT_POLLDEV is not set
+# CONFIG_INPUT_SPARSEKMAP is not set
+# CONFIG_INPUT_MATRIXKMAP is not set
+
+#
+# Userland interfaces
+#
+CONFIG_INPUT_MOUSEDEV=y
+CONFIG_INPUT_MOUSEDEV_PSAUX=y
+CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
+# CONFIG_INPUT_JOYDEV is not set
+CONFIG_INPUT_EVDEV=y
+# CONFIG_INPUT_EVBUG is not set
+
+#
+# Input Device Drivers
+#
+CONFIG_INPUT_KEYBOARD=y
+CONFIG_KEYBOARD_ATKBD=y
+# CONFIG_KEYBOARD_LKKBD is not set
+# CONFIG_KEYBOARD_NEWTON is not set
+# CONFIG_KEYBOARD_OPENCORES is not set
+# CONFIG_KEYBOARD_STOWAWAY is not set
+# CONFIG_KEYBOARD_SUNKBD is not set
+# CONFIG_KEYBOARD_XTKBD is not set
+CONFIG_INPUT_MOUSE=y
+CONFIG_MOUSE_PS2=y
+CONFIG_MOUSE_PS2_ALPS=y
+CONFIG_MOUSE_PS2_LOGIPS2PP=y
+CONFIG_MOUSE_PS2_SYNAPTICS=y
+CONFIG_MOUSE_PS2_CYPRESS=y
+CONFIG_MOUSE_PS2_LIFEBOOK=y
+CONFIG_MOUSE_PS2_TRACKPOINT=y
+# CONFIG_MOUSE_PS2_ELANTECH is not set
+# CONFIG_MOUSE_PS2_SENTELIC is not set
+# CONFIG_MOUSE_PS2_TOUCHKIT is not set
+# CONFIG_MOUSE_SERIAL is not set
+# CONFIG_MOUSE_APPLETOUCH is not set
+# CONFIG_MOUSE_BCM5974 is not set
+# CONFIG_MOUSE_VSXXXAA is not set
+# CONFIG_MOUSE_SYNAPTICS_USB is not set
+# CONFIG_INPUT_JOYSTICK is not set
+# CONFIG_INPUT_TABLET is not set
+# CONFIG_INPUT_TOUCHSCREEN is not set
+# CONFIG_INPUT_MISC is not set
+
+#
+# Hardware I/O ports
+#
+CONFIG_SERIO=y
+CONFIG_ARCH_MIGHT_HAVE_PC_SERIO=y
+CONFIG_SERIO_I8042=y
+CONFIG_SERIO_SERPORT=y
+# CONFIG_SERIO_CT82C710 is not set
+# CONFIG_SERIO_PCIPS2 is not set
+CONFIG_SERIO_LIBPS2=y
+# CONFIG_SERIO_RAW is not set
+# CONFIG_SERIO_ALTERA_PS2 is not set
+# CONFIG_SERIO_PS2MULT is not set
+# CONFIG_SERIO_ARC_PS2 is not set
+# CONFIG_GAMEPORT is not set
+
+#
+# Character devices
+#
+CONFIG_TTY=y
+CONFIG_VT=y
+CONFIG_CONSOLE_TRANSLATIONS=y
+CONFIG_VT_CONSOLE=y
+CONFIG_VT_CONSOLE_SLEEP=y
+CONFIG_HW_CONSOLE=y
+# CONFIG_VT_HW_CONSOLE_BINDING is not set
+CONFIG_UNIX98_PTYS=y
+# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
+CONFIG_LEGACY_PTYS=y
+CONFIG_LEGACY_PTY_COUNT=256
+# CONFIG_SERIAL_NONSTANDARD is not set
+# CONFIG_NOZOMI is not set
+# CONFIG_N_GSM is not set
+# CONFIG_TRACE_SINK is not set
+CONFIG_DEVKMEM=y
+
+#
+# Serial drivers
+#
+# CONFIG_SERIAL_8250 is not set
+
+#
+# Non-8250 serial port support
+#
+# CONFIG_SERIAL_MFD_HSU is not set
+# CONFIG_SERIAL_JSM is not set
+# CONFIG_SERIAL_SCCNXP is not set
+# CONFIG_SERIAL_ALTERA_JTAGUART is not set
+# CONFIG_SERIAL_ALTERA_UART is not set
+# CONFIG_SERIAL_ARC is not set
+# CONFIG_SERIAL_RP2 is not set
+# CONFIG_SERIAL_FSL_LPUART is not set
+CONFIG_HVC_DRIVER=y
+CONFIG_VIRTIO_CONSOLE=y
+# CONFIG_IPMI_HANDLER is not set
+# CONFIG_HW_RANDOM is not set
+# CONFIG_NVRAM is not set
+# CONFIG_R3964 is not set
+# CONFIG_APPLICOM is not set
+# CONFIG_MWAVE is not set
+# CONFIG_RAW_DRIVER is not set
+# CONFIG_HPET is not set
+# CONFIG_HANGCHECK_TIMER is not set
+# CONFIG_TCG_TPM is not set
+# CONFIG_TELCLOCK is not set
+CONFIG_DEVPORT=y
+# CONFIG_XILLYBUS is not set
+
+#
+# I2C support
+#
+# CONFIG_I2C is not set
+# CONFIG_SPI is not set
+# CONFIG_SPMI is not set
+# CONFIG_HSI is not set
+
+#
+# PPS support
+#
+# CONFIG_PPS is not set
+
+#
+# PPS generators support
+#
+
+#
+# PTP clock support
+#
+# CONFIG_PTP_1588_CLOCK is not set
+
+#
+# Enable PHYLIB and NETWORK_PHY_TIMESTAMPING to see the additional clocks.
+#
+CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y
+# CONFIG_GPIOLIB is not set
+# CONFIG_W1 is not set
+CONFIG_POWER_SUPPLY=y
+# CONFIG_POWER_SUPPLY_DEBUG is not set
+# CONFIG_PDA_POWER is not set
+# CONFIG_TEST_POWER is not set
+# CONFIG_BATTERY_DS2780 is not set
+# CONFIG_BATTERY_DS2781 is not set
+# CONFIG_BATTERY_BQ27x00 is not set
+# CONFIG_CHARGER_MAX8903 is not set
+# CONFIG_POWER_RESET is not set
+# CONFIG_POWER_AVS is not set
+CONFIG_HWMON=y
+# CONFIG_HWMON_VID is not set
+# CONFIG_HWMON_DEBUG_CHIP is not set
+
+#
+# Native drivers
+#
+# CONFIG_SENSORS_ABITUGURU is not set
+# CONFIG_SENSORS_ABITUGURU3 is not set
+# CONFIG_SENSORS_K8TEMP is not set
+# CONFIG_SENSORS_K10TEMP is not set
+# CONFIG_SENSORS_FAM15H_POWER is not set
+# CONFIG_SENSORS_APPLESMC is not set
+# CONFIG_SENSORS_I5K_AMB is not set
+# CONFIG_SENSORS_F71805F is not set
+# CONFIG_SENSORS_F71882FG is not set
+# CONFIG_SENSORS_CORETEMP is not set
+# CONFIG_SENSORS_IT87 is not set
+# CONFIG_SENSORS_MAX197 is not set
+# CONFIG_SENSORS_PC87360 is not set
+# CONFIG_SENSORS_PC87427 is not set
+# CONFIG_SENSORS_NTC_THERMISTOR is not set
+# CONFIG_SENSORS_NCT6683 is not set
+# CONFIG_SENSORS_NCT6775 is not set
+# CONFIG_SENSORS_SIS5595 is not set
+# CONFIG_SENSORS_SMSC47M1 is not set
+# CONFIG_SENSORS_SMSC47B397 is not set
+# CONFIG_SENSORS_SCH56XX_COMMON is not set
+# CONFIG_SENSORS_VIA_CPUTEMP is not set
+# CONFIG_SENSORS_VIA686A is not set
+# CONFIG_SENSORS_VT1211 is not set
+# CONFIG_SENSORS_VT8231 is not set
+# CONFIG_SENSORS_W83627HF is not set
+# CONFIG_SENSORS_W83627EHF is not set
+
+#
+# ACPI drivers
+#
+# CONFIG_SENSORS_ACPI_POWER is not set
+# CONFIG_SENSORS_ATK0110 is not set
+CONFIG_THERMAL=y
+CONFIG_THERMAL_HWMON=y
+CONFIG_THERMAL_DEFAULT_GOV_STEP_WISE=y
+# CONFIG_THERMAL_DEFAULT_GOV_FAIR_SHARE is not set
+# CONFIG_THERMAL_DEFAULT_GOV_USER_SPACE is not set
+# CONFIG_THERMAL_GOV_FAIR_SHARE is not set
+CONFIG_THERMAL_GOV_STEP_WISE=y
+# CONFIG_THERMAL_GOV_BANG_BANG is not set
+# CONFIG_THERMAL_GOV_USER_SPACE is not set
+# CONFIG_THERMAL_EMULATION is not set
+# CONFIG_INTEL_POWERCLAMP is not set
+# CONFIG_INTEL_SOC_DTS_THERMAL is not set
+# CONFIG_INT340X_THERMAL is not set
+
+#
+# Texas Instruments thermal drivers
+#
+# CONFIG_WATCHDOG is not set
+CONFIG_SSB_POSSIBLE=y
+
+#
+# Sonics Silicon Backplane
+#
+# CONFIG_SSB is not set
+CONFIG_BCMA_POSSIBLE=y
+
+#
+# Broadcom specific AMBA
+#
+# CONFIG_BCMA is not set
+
+#
+# Multifunction device drivers
+#
+# CONFIG_MFD_CORE is not set
+# CONFIG_MFD_CROS_EC is not set
+# CONFIG_HTC_PASIC3 is not set
+# CONFIG_LPC_ICH is not set
+# CONFIG_LPC_SCH is not set
+# CONFIG_MFD_JANZ_CMODIO is not set
+# CONFIG_MFD_KEMPLD is not set
+# CONFIG_MFD_RDC321X is not set
+# CONFIG_MFD_RTSX_PCI is not set
+# CONFIG_MFD_SM501 is not set
+# CONFIG_ABX500_CORE is not set
+# CONFIG_MFD_SYSCON is not set
+# CONFIG_MFD_TI_AM335X_TSCADC is not set
+# CONFIG_MFD_TMIO is not set
+# CONFIG_MFD_VX855 is not set
+# CONFIG_REGULATOR is not set
+# CONFIG_MEDIA_SUPPORT is not set
+
+#
+# Graphics support
+#
+# CONFIG_AGP is not set
+CONFIG_VGA_ARB=y
+CONFIG_VGA_ARB_MAX_GPUS=16
+# CONFIG_VGA_SWITCHEROO is not set
+
+#
+# Direct Rendering Manager
+#
+# CONFIG_DRM is not set
+
+#
+# Frame buffer Devices
+#
+# CONFIG_FB is not set
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+# CONFIG_VGASTATE is not set
+
+#
+# Console display driver support
+#
+CONFIG_VGA_CONSOLE=y
+# CONFIG_VGACON_SOFT_SCROLLBACK is not set
+CONFIG_DUMMY_CONSOLE=y
+CONFIG_SOUND=y
+# CONFIG_SOUND_OSS_CORE is not set
+# CONFIG_SND is not set
+# CONFIG_SOUND_PRIME is not set
+
+#
+# HID support
+#
+CONFIG_HID=y
+# CONFIG_HID_BATTERY_STRENGTH is not set
+# CONFIG_HIDRAW is not set
+# CONFIG_UHID is not set
+CONFIG_HID_GENERIC=y
+
+#
+# Special HID drivers
+#
+CONFIG_HID_A4TECH=y
+# CONFIG_HID_ACRUX is not set
+CONFIG_HID_APPLE=y
+# CONFIG_HID_AUREAL is not set
+CONFIG_HID_BELKIN=y
+CONFIG_HID_CHERRY=y
+CONFIG_HID_CHICONY=y
+CONFIG_HID_CYPRESS=y
+# CONFIG_HID_DRAGONRISE is not set
+# CONFIG_HID_EMS_FF is not set
+# CONFIG_HID_ELECOM is not set
+CONFIG_HID_EZKEY=y
+# CONFIG_HID_KEYTOUCH is not set
+# CONFIG_HID_KYE is not set
+# CONFIG_HID_UCLOGIC is not set
+# CONFIG_HID_WALTOP is not set
+# CONFIG_HID_GYRATION is not set
+# CONFIG_HID_ICADE is not set
+# CONFIG_HID_TWINHAN is not set
+CONFIG_HID_KENSINGTON=y
+# CONFIG_HID_LCPOWER is not set
+# CONFIG_HID_LENOVO is not set
+CONFIG_HID_LOGITECH=y
+# CONFIG_LOGITECH_FF is not set
+# CONFIG_LOGIRUMBLEPAD2_FF is not set
+# CONFIG_LOGIG940_FF is not set
+# CONFIG_LOGIWHEELS_FF is not set
+# CONFIG_HID_MAGICMOUSE is not set
+CONFIG_HID_MICROSOFT=y
+CONFIG_HID_MONTEREY=y
+# CONFIG_HID_MULTITOUCH is not set
+# CONFIG_HID_ORTEK is not set
+# CONFIG_HID_PANTHERLORD is not set
+# CONFIG_HID_PETALYNX is not set
+# CONFIG_HID_PICOLCD is not set
+# CONFIG_HID_PRIMAX is not set
+# CONFIG_HID_SAITEK is not set
+# CONFIG_HID_SAMSUNG is not set
+# CONFIG_HID_SPEEDLINK is not set
+# CONFIG_HID_STEELSERIES is not set
+# CONFIG_HID_SUNPLUS is not set
+# CONFIG_HID_RMI is not set
+# CONFIG_HID_GREENASIA is not set
+# CONFIG_HID_SMARTJOYPLUS is not set
+# CONFIG_HID_TIVO is not set
+# CONFIG_HID_TOPSEED is not set
+# CONFIG_HID_THRUSTMASTER is not set
+# CONFIG_HID_WACOM is not set
+# CONFIG_HID_XINMO is not set
+# CONFIG_HID_ZEROPLUS is not set
+# CONFIG_HID_ZYDACRON is not set
+# CONFIG_HID_SENSOR_HUB is not set
+CONFIG_USB_OHCI_LITTLE_ENDIAN=y
+CONFIG_USB_SUPPORT=y
+CONFIG_USB_ARCH_HAS_HCD=y
+# CONFIG_USB is not set
+
+#
+# USB port drivers
+#
+
+#
+# USB Physical Layer drivers
+#
+# CONFIG_USB_PHY is not set
+# CONFIG_NOP_USB_XCEIV is not set
+# CONFIG_USB_GADGET is not set
+# CONFIG_UWB is not set
+# CONFIG_MMC is not set
+# CONFIG_MEMSTICK is not set
+# CONFIG_NEW_LEDS is not set
+# CONFIG_ACCESSIBILITY is not set
+# CONFIG_INFINIBAND is not set
+# CONFIG_EDAC is not set
+CONFIG_RTC_LIB=y
+# CONFIG_RTC_CLASS is not set
+# CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
+# CONFIG_UIO is not set
+# CONFIG_VIRT_DRIVERS is not set
+CONFIG_VIRTIO=y
+
+#
+# Virtio drivers
+#
+CONFIG_VIRTIO_PCI=y
+CONFIG_VIRTIO_BALLOON=y
+CONFIG_VIRTIO_MMIO=y
+# CONFIG_VIRTIO_MMIO_CMDLINE_DEVICES is not set
+
+#
+# Microsoft Hyper-V guest support
+#
+# CONFIG_STAGING is not set
+CONFIG_X86_PLATFORM_DEVICES=y
+# CONFIG_ACERHDF is not set
+# CONFIG_ASUS_LAPTOP is not set
+# CONFIG_DELL_SMO8800 is not set
+# CONFIG_FUJITSU_TABLET is not set
+# CONFIG_HP_ACCEL is not set
+# CONFIG_HP_WIRELESS is not set
+# CONFIG_THINKPAD_ACPI is not set
+# CONFIG_SENSORS_HDAPS is not set
+# CONFIG_INTEL_MENLOW is not set
+# CONFIG_ACPI_WMI is not set
+# CONFIG_TOPSTAR_LAPTOP is not set
+# CONFIG_TOSHIBA_BT_RFKILL is not set
+# CONFIG_TOSHIBA_HAPS is not set
+# CONFIG_ACPI_CMPC is not set
+# CONFIG_INTEL_IPS is not set
+# CONFIG_IBM_RTL is not set
+# CONFIG_SAMSUNG_Q10 is not set
+# CONFIG_INTEL_RST is not set
+# CONFIG_INTEL_SMARTCONNECT is not set
+# CONFIG_PVPANIC is not set
+# CONFIG_CHROME_PLATFORMS is not set
+
+#
+# SOC (System On Chip) specific Drivers
+#
+# CONFIG_SOC_TI is not set
+
+#
+# Hardware Spinlock drivers
+#
+
+#
+# Clock Source drivers
+#
+CONFIG_CLKEVT_I8253=y
+CONFIG_I8253_LOCK=y
+CONFIG_CLKBLD_I8253=y
+# CONFIG_ATMEL_PIT is not set
+# CONFIG_SH_TIMER_CMT is not set
+# CONFIG_SH_TIMER_MTU2 is not set
+# CONFIG_SH_TIMER_TMU is not set
+# CONFIG_EM_TIMER_STI is not set
+# CONFIG_MAILBOX is not set
+CONFIG_IOMMU_SUPPORT=y
+# CONFIG_AMD_IOMMU is not set
+# CONFIG_INTEL_IOMMU is not set
+# CONFIG_IRQ_REMAP is not set
+
+#
+# Remoteproc drivers
+#
+# CONFIG_STE_MODEM_RPROC is not set
+
+#
+# Rpmsg drivers
+#
+
+#
+# SOC (System On Chip) specific Drivers
+#
+# CONFIG_PM_DEVFREQ is not set
+# CONFIG_EXTCON is not set
+# CONFIG_MEMORY is not set
+# CONFIG_IIO is not set
+# CONFIG_NTB is not set
+# CONFIG_VME_BUS is not set
+# CONFIG_PWM is not set
+# CONFIG_IPACK_BUS is not set
+# CONFIG_RESET_CONTROLLER is not set
+# CONFIG_FMC is not set
+
+#
+# PHY Subsystem
+#
+# CONFIG_GENERIC_PHY is not set
+# CONFIG_BCM_KONA_USB2_PHY is not set
+# CONFIG_POWERCAP is not set
+# CONFIG_MCB is not set
+# CONFIG_THUNDERBOLT is not set
+
+#
+# Firmware Drivers
+#
+# CONFIG_EDD is not set
+CONFIG_FIRMWARE_MEMMAP=y
+# CONFIG_DELL_RBU is not set
+# CONFIG_DCDBAS is not set
+CONFIG_DMIID=y
+# CONFIG_DMI_SYSFS is not set
+CONFIG_DMI_SCAN_MACHINE_NON_EFI_FALLBACK=y
+# CONFIG_ISCSI_IBFT_FIND is not set
+# CONFIG_GOOGLE_FIRMWARE is not set
+
+#
+# File systems
+#
+CONFIG_DCACHE_WORD_ACCESS=y
+CONFIG_EXT2_FS=y
+# CONFIG_EXT2_FS_XATTR is not set
+# CONFIG_EXT2_FS_XIP is not set
+CONFIG_EXT3_FS=y
+# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set
+# CONFIG_EXT3_FS_XATTR is not set
+# CONFIG_EXT4_FS is not set
+CONFIG_JBD=y
+CONFIG_REISERFS_FS=y
+# CONFIG_REISERFS_CHECK is not set
+# CONFIG_REISERFS_PROC_INFO is not set
+# CONFIG_REISERFS_FS_XATTR is not set
+# CONFIG_JFS_FS is not set
+# CONFIG_XFS_FS is not set
+# CONFIG_GFS2_FS is not set
+# CONFIG_BTRFS_FS is not set
+# CONFIG_NILFS2_FS is not set
+CONFIG_FS_POSIX_ACL=y
+CONFIG_FILE_LOCKING=y
+CONFIG_FSNOTIFY=y
+CONFIG_DNOTIFY=y
+CONFIG_INOTIFY_USER=y
+# CONFIG_FANOTIFY is not set
+CONFIG_QUOTA=y
+# CONFIG_QUOTA_NETLINK_INTERFACE is not set
+CONFIG_PRINT_QUOTA_WARNING=y
+# CONFIG_QUOTA_DEBUG is not set
+# CONFIG_QFMT_V1 is not set
+# CONFIG_QFMT_V2 is not set
+CONFIG_QUOTACTL=y
+CONFIG_AUTOFS4_FS=y
+# CONFIG_FUSE_FS is not set
+# CONFIG_OVERLAY_FS is not set
+
+#
+# Caches
+#
+# CONFIG_FSCACHE is not set
+
+#
+# CD-ROM/DVD Filesystems
+#
+CONFIG_ISO9660_FS=y
+CONFIG_JOLIET=y
+# CONFIG_ZISOFS is not set
+# CONFIG_UDF_FS is not set
+
+#
+# DOS/FAT/NT Filesystems
+#
+# CONFIG_MSDOS_FS is not set
+# CONFIG_VFAT_FS is not set
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_PROC_KCORE=y
+CONFIG_PROC_SYSCTL=y
+CONFIG_PROC_PAGE_MONITOR=y
+CONFIG_KERNFS=y
+CONFIG_SYSFS=y
+CONFIG_TMPFS=y
+# CONFIG_TMPFS_POSIX_ACL is not set
+# CONFIG_TMPFS_XATTR is not set
+# CONFIG_HUGETLBFS is not set
+# CONFIG_HUGETLB_PAGE is not set
+# CONFIG_CONFIGFS_FS is not set
+CONFIG_MISC_FILESYSTEMS=y
+# CONFIG_ADFS_FS is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_HFSPLUS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EFS_FS is not set
+# CONFIG_LOGFS is not set
+# CONFIG_CRAMFS is not set
+# CONFIG_SQUASHFS is not set
+# CONFIG_VXFS_FS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_OMFS_FS is not set
+# CONFIG_HPFS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_QNX6FS_FS is not set
+# CONFIG_ROMFS_FS is not set
+# CONFIG_PSTORE is not set
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
+# CONFIG_F2FS_FS is not set
+CONFIG_NETWORK_FILESYSTEMS=y
+# CONFIG_NFS_FS is not set
+# CONFIG_NFSD is not set
+# CONFIG_CEPH_FS is not set
+# CONFIG_CIFS is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_CODA_FS is not set
+# CONFIG_AFS_FS is not set
+CONFIG_9P_FS=y
+CONFIG_9P_FS_POSIX_ACL=y
+# CONFIG_9P_FS_SECURITY is not set
+CONFIG_NLS=y
+CONFIG_NLS_DEFAULT="iso8859-1"
+# CONFIG_NLS_CODEPAGE_437 is not set
+# CONFIG_NLS_CODEPAGE_737 is not set
+# CONFIG_NLS_CODEPAGE_775 is not set
+# CONFIG_NLS_CODEPAGE_850 is not set
+# CONFIG_NLS_CODEPAGE_852 is not set
+# CONFIG_NLS_CODEPAGE_855 is not set
+# CONFIG_NLS_CODEPAGE_857 is not set
+# CONFIG_NLS_CODEPAGE_860 is not set
+# CONFIG_NLS_CODEPAGE_861 is not set
+# CONFIG_NLS_CODEPAGE_862 is not set
+# CONFIG_NLS_CODEPAGE_863 is not set
+# CONFIG_NLS_CODEPAGE_864 is not set
+# CONFIG_NLS_CODEPAGE_865 is not set
+# CONFIG_NLS_CODEPAGE_866 is not set
+# CONFIG_NLS_CODEPAGE_869 is not set
+# CONFIG_NLS_CODEPAGE_936 is not set
+# CONFIG_NLS_CODEPAGE_950 is not set
+# CONFIG_NLS_CODEPAGE_932 is not set
+# CONFIG_NLS_CODEPAGE_949 is not set
+# CONFIG_NLS_CODEPAGE_874 is not set
+# CONFIG_NLS_ISO8859_8 is not set
+# CONFIG_NLS_CODEPAGE_1250 is not set
+# CONFIG_NLS_CODEPAGE_1251 is not set
+# CONFIG_NLS_ASCII is not set
+# CONFIG_NLS_ISO8859_1 is not set
+# CONFIG_NLS_ISO8859_2 is not set
+# CONFIG_NLS_ISO8859_3 is not set
+# CONFIG_NLS_ISO8859_4 is not set
+# CONFIG_NLS_ISO8859_5 is not set
+# CONFIG_NLS_ISO8859_6 is not set
+# CONFIG_NLS_ISO8859_7 is not set
+# CONFIG_NLS_ISO8859_9 is not set
+# CONFIG_NLS_ISO8859_13 is not set
+# CONFIG_NLS_ISO8859_14 is not set
+# CONFIG_NLS_ISO8859_15 is not set
+# CONFIG_NLS_KOI8_R is not set
+# CONFIG_NLS_KOI8_U is not set
+# CONFIG_NLS_MAC_ROMAN is not set
+# CONFIG_NLS_MAC_CELTIC is not set
+# CONFIG_NLS_MAC_CENTEURO is not set
+# CONFIG_NLS_MAC_CROATIAN is not set
+# CONFIG_NLS_MAC_CYRILLIC is not set
+# CONFIG_NLS_MAC_GAELIC is not set
+# CONFIG_NLS_MAC_GREEK is not set
+# CONFIG_NLS_MAC_ICELAND is not set
+# CONFIG_NLS_MAC_INUIT is not set
+# CONFIG_NLS_MAC_ROMANIAN is not set
+# CONFIG_NLS_MAC_TURKISH is not set
+# CONFIG_NLS_UTF8 is not set
+
+#
+# Kernel hacking
+#
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
+
+#
+# printk and dmesg options
+#
+# CONFIG_PRINTK_TIME is not set
+CONFIG_MESSAGE_LOGLEVEL_DEFAULT=4
+# CONFIG_BOOT_PRINTK_DELAY is not set
+
+#
+# Compile-time checks and compiler options
+#
+CONFIG_DEBUG_INFO=y
+# CONFIG_DEBUG_INFO_REDUCED is not set
+# CONFIG_DEBUG_INFO_SPLIT is not set
+# CONFIG_DEBUG_INFO_DWARF4 is not set
+CONFIG_ENABLE_WARN_DEPRECATED=y
+CONFIG_ENABLE_MUST_CHECK=y
+CONFIG_FRAME_WARN=1024
+# CONFIG_STRIP_ASM_SYMS is not set
+# CONFIG_READABLE_ASM is not set
+# CONFIG_UNUSED_SYMBOLS is not set
+# CONFIG_DEBUG_FS is not set
+# CONFIG_HEADERS_CHECK is not set
+# CONFIG_DEBUG_SECTION_MISMATCH is not set
+CONFIG_ARCH_WANT_FRAME_POINTERS=y
+CONFIG_FRAME_POINTER=y
+# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set
+# CONFIG_MAGIC_SYSRQ is not set
+CONFIG_DEBUG_KERNEL=y
+
+#
+# Memory Debugging
+#
+# CONFIG_DEBUG_PAGEALLOC is not set
+# CONFIG_DEBUG_OBJECTS is not set
+# CONFIG_DEBUG_SLAB is not set
+CONFIG_HAVE_DEBUG_KMEMLEAK=y
+# CONFIG_DEBUG_KMEMLEAK is not set
+# CONFIG_DEBUG_STACK_USAGE is not set
+# CONFIG_DEBUG_VM is not set
+# CONFIG_DEBUG_VIRTUAL is not set
+CONFIG_DEBUG_MEMORY_INIT=y
+CONFIG_HAVE_DEBUG_STACKOVERFLOW=y
+# CONFIG_DEBUG_STACKOVERFLOW is not set
+CONFIG_HAVE_ARCH_KMEMCHECK=y
+# CONFIG_DEBUG_SHIRQ is not set
+
+#
+# Debug Lockups and Hangs
+#
+# CONFIG_LOCKUP_DETECTOR is not set
+CONFIG_DETECT_HUNG_TASK=y
+CONFIG_DEFAULT_HUNG_TASK_TIMEOUT=120
+# CONFIG_BOOTPARAM_HUNG_TASK_PANIC is not set
+CONFIG_BOOTPARAM_HUNG_TASK_PANIC_VALUE=0
+# CONFIG_PANIC_ON_OOPS is not set
+CONFIG_PANIC_ON_OOPS_VALUE=0
+CONFIG_PANIC_TIMEOUT=0
+# CONFIG_SCHED_DEBUG is not set
+# CONFIG_SCHEDSTATS is not set
+# CONFIG_SCHED_STACK_END_CHECK is not set
+# CONFIG_TIMER_STATS is not set
+
+#
+# Lock Debugging (spinlocks, mutexes, etc...)
+#
+# CONFIG_DEBUG_RT_MUTEXES is not set
+# CONFIG_DEBUG_SPINLOCK is not set
+# CONFIG_DEBUG_MUTEXES is not set
+# CONFIG_DEBUG_WW_MUTEX_SLOWPATH is not set
+# CONFIG_DEBUG_LOCK_ALLOC is not set
+# CONFIG_PROVE_LOCKING is not set
+# CONFIG_LOCK_STAT is not set
+# CONFIG_DEBUG_ATOMIC_SLEEP is not set
+# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
+# CONFIG_LOCK_TORTURE_TEST is not set
+# CONFIG_STACKTRACE is not set
+# CONFIG_DEBUG_KOBJECT is not set
+CONFIG_DEBUG_BUGVERBOSE=y
+# CONFIG_DEBUG_LIST is not set
+# CONFIG_DEBUG_PI_LIST is not set
+# CONFIG_DEBUG_SG is not set
+# CONFIG_DEBUG_NOTIFIERS is not set
+# CONFIG_DEBUG_CREDENTIALS is not set
+
+#
+# RCU Debugging
+#
+# CONFIG_SPARSE_RCU_POINTER is not set
+# CONFIG_TORTURE_TEST is not set
+# CONFIG_RCU_TORTURE_TEST is not set
+# CONFIG_RCU_TRACE is not set
+# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
+# CONFIG_NOTIFIER_ERROR_INJECTION is not set
+# CONFIG_FAULT_INJECTION is not set
+# CONFIG_LATENCYTOP is not set
+CONFIG_ARCH_HAS_DEBUG_STRICT_USER_COPY_CHECKS=y
+# CONFIG_DEBUG_STRICT_USER_COPY_CHECKS is not set
+CONFIG_USER_STACKTRACE_SUPPORT=y
+CONFIG_HAVE_FUNCTION_TRACER=y
+CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
+CONFIG_HAVE_FUNCTION_GRAPH_FP_TEST=y
+CONFIG_HAVE_DYNAMIC_FTRACE=y
+CONFIG_HAVE_DYNAMIC_FTRACE_WITH_REGS=y
+CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
+CONFIG_HAVE_SYSCALL_TRACEPOINTS=y
+CONFIG_HAVE_FENTRY=y
+CONFIG_HAVE_C_RECORDMCOUNT=y
+CONFIG_TRACING_SUPPORT=y
+CONFIG_FTRACE=y
+# CONFIG_FUNCTION_TRACER is not set
+# CONFIG_IRQSOFF_TRACER is not set
+# CONFIG_SCHED_TRACER is not set
+# CONFIG_ENABLE_DEFAULT_TRACERS is not set
+# CONFIG_FTRACE_SYSCALLS is not set
+# CONFIG_TRACER_SNAPSHOT is not set
+CONFIG_BRANCH_PROFILE_NONE=y
+# CONFIG_PROFILE_ANNOTATED_BRANCHES is not set
+# CONFIG_PROFILE_ALL_BRANCHES is not set
+# CONFIG_STACK_TRACER is not set
+# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_UPROBE_EVENT is not set
+# CONFIG_PROBE_EVENTS is not set
+# CONFIG_MMIOTRACE is not set
+# CONFIG_TRACEPOINT_BENCHMARK is not set
+
+#
+# Runtime Testing
+#
+# CONFIG_TEST_LIST_SORT is not set
+# CONFIG_BACKTRACE_SELF_TEST is not set
+# CONFIG_RBTREE_TEST is not set
+# CONFIG_ATOMIC64_SELFTEST is not set
+# CONFIG_TEST_STRING_HELPERS is not set
+# CONFIG_TEST_KSTRTOX is not set
+# CONFIG_TEST_RHASHTABLE is not set
+# CONFIG_PROVIDE_OHCI1394_DMA_INIT is not set
+# CONFIG_DMA_API_DEBUG is not set
+# CONFIG_TEST_FIRMWARE is not set
+# CONFIG_TEST_UDELAY is not set
+# CONFIG_SAMPLES is not set
+CONFIG_HAVE_ARCH_KGDB=y
+# CONFIG_KGDB is not set
+# CONFIG_STRICT_DEVMEM is not set
+CONFIG_X86_VERBOSE_BOOTUP=y
+CONFIG_EARLY_PRINTK=y
+# CONFIG_EARLY_PRINTK_DBGP is not set
+# CONFIG_X86_PTDUMP is not set
+CONFIG_DEBUG_RODATA=y
+CONFIG_DEBUG_RODATA_TEST=y
+CONFIG_DOUBLEFAULT=y
+# CONFIG_DEBUG_TLBFLUSH is not set
+# CONFIG_IOMMU_DEBUG is not set
+# CONFIG_IOMMU_STRESS is not set
+CONFIG_HAVE_MMIOTRACE_SUPPORT=y
+CONFIG_IO_DELAY_TYPE_0X80=0
+CONFIG_IO_DELAY_TYPE_0XED=1
+CONFIG_IO_DELAY_TYPE_UDELAY=2
+CONFIG_IO_DELAY_TYPE_NONE=3
+CONFIG_IO_DELAY_0X80=y
+# CONFIG_IO_DELAY_0XED is not set
+# CONFIG_IO_DELAY_UDELAY is not set
+# CONFIG_IO_DELAY_NONE is not set
+CONFIG_DEFAULT_IO_DELAY_TYPE=0
+# CONFIG_CPA_DEBUG is not set
+# CONFIG_OPTIMIZE_INLINING is not set
+# CONFIG_DEBUG_NMI_SELFTEST is not set
+# CONFIG_X86_DEBUG_STATIC_CPU_HAS is not set
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+# CONFIG_SECURITY_DMESG_RESTRICT is not set
+# CONFIG_SECURITY is not set
+# CONFIG_SECURITYFS is not set
+CONFIG_DEFAULT_SECURITY_DAC=y
+CONFIG_DEFAULT_SECURITY=""
+CONFIG_CRYPTO=y
+
+#
+# Crypto core or helper
+#
+CONFIG_CRYPTO_ALGAPI=y
+CONFIG_CRYPTO_ALGAPI2=y
+CONFIG_CRYPTO_AEAD=y
+CONFIG_CRYPTO_AEAD2=y
+CONFIG_CRYPTO_BLKCIPHER=y
+CONFIG_CRYPTO_BLKCIPHER2=y
+CONFIG_CRYPTO_HASH=y
+CONFIG_CRYPTO_HASH2=y
+CONFIG_CRYPTO_RNG=y
+CONFIG_CRYPTO_RNG2=y
+CONFIG_CRYPTO_PCOMP=y
+CONFIG_CRYPTO_PCOMP2=y
+CONFIG_CRYPTO_MANAGER=y
+CONFIG_CRYPTO_MANAGER2=y
+CONFIG_CRYPTO_USER=y
+CONFIG_CRYPTO_MANAGER_DISABLE_TESTS=y
+CONFIG_CRYPTO_GF128MUL=y
+CONFIG_CRYPTO_NULL=y
+CONFIG_CRYPTO_WORKQUEUE=y
+CONFIG_CRYPTO_CRYPTD=y
+# CONFIG_CRYPTO_MCRYPTD is not set
+CONFIG_CRYPTO_AUTHENC=y
+CONFIG_CRYPTO_ABLK_HELPER=y
+CONFIG_CRYPTO_GLUE_HELPER_X86=y
+
+#
+# Authenticated Encryption with Associated Data
+#
+CONFIG_CRYPTO_CCM=y
+CONFIG_CRYPTO_GCM=y
+CONFIG_CRYPTO_SEQIV=y
+
+#
+# Block modes
+#
+CONFIG_CRYPTO_CBC=y
+CONFIG_CRYPTO_CTR=y
+# CONFIG_CRYPTO_CTS is not set
+CONFIG_CRYPTO_ECB=y
+CONFIG_CRYPTO_LRW=y
+CONFIG_CRYPTO_PCBC=y
+CONFIG_CRYPTO_XTS=y
+
+#
+# Hash modes
+#
+CONFIG_CRYPTO_CMAC=y
+CONFIG_CRYPTO_HMAC=y
+CONFIG_CRYPTO_XCBC=y
+# CONFIG_CRYPTO_VMAC is not set
+
+#
+# Digest
+#
+CONFIG_CRYPTO_CRC32C=y
+# CONFIG_CRYPTO_CRC32C_INTEL is not set
+# CONFIG_CRYPTO_CRC32 is not set
+# CONFIG_CRYPTO_CRC32_PCLMUL is not set
+# CONFIG_CRYPTO_CRCT10DIF is not set
+CONFIG_CRYPTO_GHASH=y
+CONFIG_CRYPTO_MD4=y
+CONFIG_CRYPTO_MD5=y
+CONFIG_CRYPTO_MICHAEL_MIC=y
+CONFIG_CRYPTO_RMD128=y
+CONFIG_CRYPTO_RMD160=y
+CONFIG_CRYPTO_RMD256=y
+CONFIG_CRYPTO_RMD320=y
+CONFIG_CRYPTO_SHA1=y
+# CONFIG_CRYPTO_SHA1_SSSE3 is not set
+CONFIG_CRYPTO_SHA256_SSSE3=y
+CONFIG_CRYPTO_SHA512_SSSE3=y
+# CONFIG_CRYPTO_SHA1_MB is not set
+CONFIG_CRYPTO_SHA256=y
+CONFIG_CRYPTO_SHA512=y
+CONFIG_CRYPTO_TGR192=y
+CONFIG_CRYPTO_WP512=y
+# CONFIG_CRYPTO_GHASH_CLMUL_NI_INTEL is not set
+
+#
+# Ciphers
+#
+CONFIG_CRYPTO_AES=y
+CONFIG_CRYPTO_AES_X86_64=y
+CONFIG_CRYPTO_AES_NI_INTEL=y
+CONFIG_CRYPTO_ANUBIS=y
+CONFIG_CRYPTO_ARC4=y
+CONFIG_CRYPTO_BLOWFISH=y
+CONFIG_CRYPTO_BLOWFISH_COMMON=y
+CONFIG_CRYPTO_BLOWFISH_X86_64=y
+CONFIG_CRYPTO_CAMELLIA=y
+CONFIG_CRYPTO_CAMELLIA_X86_64=y
+CONFIG_CRYPTO_CAMELLIA_AESNI_AVX_X86_64=y
+CONFIG_CRYPTO_CAMELLIA_AESNI_AVX2_X86_64=y
+CONFIG_CRYPTO_CAST_COMMON=y
+CONFIG_CRYPTO_CAST5=y
+CONFIG_CRYPTO_CAST5_AVX_X86_64=y
+CONFIG_CRYPTO_CAST6=y
+CONFIG_CRYPTO_CAST6_AVX_X86_64=y
+CONFIG_CRYPTO_DES=y
+# CONFIG_CRYPTO_DES3_EDE_X86_64 is not set
+CONFIG_CRYPTO_FCRYPT=y
+CONFIG_CRYPTO_KHAZAD=y
+CONFIG_CRYPTO_SALSA20=y
+CONFIG_CRYPTO_SALSA20_X86_64=y
+CONFIG_CRYPTO_SEED=y
+CONFIG_CRYPTO_SERPENT=y
+CONFIG_CRYPTO_SERPENT_SSE2_X86_64=y
+CONFIG_CRYPTO_SERPENT_AVX_X86_64=y
+CONFIG_CRYPTO_SERPENT_AVX2_X86_64=y
+CONFIG_CRYPTO_TEA=y
+CONFIG_CRYPTO_TWOFISH=y
+CONFIG_CRYPTO_TWOFISH_COMMON=y
+CONFIG_CRYPTO_TWOFISH_X86_64=y
+CONFIG_CRYPTO_TWOFISH_X86_64_3WAY=y
+CONFIG_CRYPTO_TWOFISH_AVX_X86_64=y
+
+#
+# Compression
+#
+CONFIG_CRYPTO_DEFLATE=y
+CONFIG_CRYPTO_ZLIB=y
+CONFIG_CRYPTO_LZO=y
+CONFIG_CRYPTO_LZ4=y
+CONFIG_CRYPTO_LZ4HC=y
+
+#
+# Random Number Generation
+#
+# CONFIG_CRYPTO_ANSI_CPRNG is not set
+# CONFIG_CRYPTO_DRBG_MENU is not set
+CONFIG_CRYPTO_USER_API=y
+CONFIG_CRYPTO_USER_API_HASH=y
+CONFIG_CRYPTO_USER_API_SKCIPHER=y
+# CONFIG_CRYPTO_HW is not set
+CONFIG_HAVE_KVM=y
+CONFIG_VIRTUALIZATION=y
+# CONFIG_KVM is not set
+# CONFIG_BINARY_PRINTF is not set
+
+#
+# Library routines
+#
+CONFIG_BITREVERSE=y
+CONFIG_GENERIC_STRNCPY_FROM_USER=y
+CONFIG_GENERIC_STRNLEN_USER=y
+CONFIG_GENERIC_NET_UTILS=y
+CONFIG_GENERIC_FIND_FIRST_BIT=y
+CONFIG_GENERIC_PCI_IOMAP=y
+CONFIG_GENERIC_IOMAP=y
+CONFIG_GENERIC_IO=y
+CONFIG_ARCH_USE_CMPXCHG_LOCKREF=y
+CONFIG_ARCH_HAS_FAST_MULTIPLIER=y
+CONFIG_CRC_CCITT=y
+CONFIG_CRC16=y
+# CONFIG_CRC_T10DIF is not set
+CONFIG_CRC_ITU_T=y
+CONFIG_CRC32=y
+# CONFIG_CRC32_SELFTEST is not set
+CONFIG_CRC32_SLICEBY8=y
+# CONFIG_CRC32_SLICEBY4 is not set
+# CONFIG_CRC32_SARWATE is not set
+# CONFIG_CRC32_BIT is not set
+CONFIG_CRC7=y
+CONFIG_LIBCRC32C=y
+# CONFIG_CRC8 is not set
+# CONFIG_AUDIT_ARCH_COMPAT_GENERIC is not set
+# CONFIG_RANDOM32_SELFTEST is not set
+CONFIG_ZLIB_INFLATE=y
+CONFIG_ZLIB_DEFLATE=y
+CONFIG_LZO_COMPRESS=y
+CONFIG_LZO_DECOMPRESS=y
+CONFIG_LZ4_COMPRESS=y
+CONFIG_LZ4HC_COMPRESS=y
+CONFIG_LZ4_DECOMPRESS=y
+# CONFIG_XZ_DEC is not set
+# CONFIG_XZ_DEC_BCJ is not set
+CONFIG_TEXTSEARCH=y
+CONFIG_TEXTSEARCH_KMP=y
+CONFIG_TEXTSEARCH_BM=y
+CONFIG_TEXTSEARCH_FSM=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT_MAP=y
+CONFIG_HAS_DMA=y
+CONFIG_DQL=y
+CONFIG_NLATTR=y
+CONFIG_ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE=y
+CONFIG_AVERAGE=y
+# CONFIG_CORDIC is not set
+# CONFIG_DDR is not set
+CONFIG_ARCH_HAS_SG_CHAIN=y
diff --git a/testing/config/kernel/config-3.19 b/testing/config/kernel/config-3.19
new file mode 100644
index 0000000..8520b31
--- /dev/null
+++ b/testing/config/kernel/config-3.19
@@ -0,0 +1,2181 @@
+#
+# Automatically generated file; DO NOT EDIT.
+# Linux/x86 3.19.0 Kernel Configuration
+#
+CONFIG_64BIT=y
+CONFIG_X86_64=y
+CONFIG_X86=y
+CONFIG_INSTRUCTION_DECODER=y
+CONFIG_PERF_EVENTS_INTEL_UNCORE=y
+CONFIG_OUTPUT_FORMAT="elf64-x86-64"
+CONFIG_ARCH_DEFCONFIG="arch/x86/configs/x86_64_defconfig"
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_HAVE_LATENCYTOP_SUPPORT=y
+CONFIG_MMU=y
+CONFIG_NEED_DMA_MAP_STATE=y
+CONFIG_NEED_SG_DMA_LENGTH=y
+CONFIG_GENERIC_ISA_DMA=y
+CONFIG_GENERIC_BUG=y
+CONFIG_GENERIC_BUG_RELATIVE_POINTERS=y
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_ARCH_MAY_HAVE_PC_FDC=y
+CONFIG_RWSEM_XCHGADD_ALGORITHM=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_ARCH_HAS_CPU_RELAX=y
+CONFIG_ARCH_HAS_CACHE_LINE_SIZE=y
+CONFIG_HAVE_SETUP_PER_CPU_AREA=y
+CONFIG_NEED_PER_CPU_EMBED_FIRST_CHUNK=y
+CONFIG_NEED_PER_CPU_PAGE_FIRST_CHUNK=y
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
+CONFIG_ARCH_SUSPEND_POSSIBLE=y
+CONFIG_ARCH_WANT_HUGE_PMD_SHARE=y
+CONFIG_ARCH_WANT_GENERAL_HUGETLB=y
+CONFIG_ZONE_DMA32=y
+CONFIG_AUDIT_ARCH=y
+CONFIG_ARCH_SUPPORTS_OPTIMIZED_INLINING=y
+CONFIG_ARCH_SUPPORTS_DEBUG_PAGEALLOC=y
+CONFIG_ARCH_HWEIGHT_CFLAGS="-fcall-saved-rdi -fcall-saved-rsi -fcall-saved-rdx -fcall-saved-rcx -fcall-saved-r8 -fcall-saved-r9 -fcall-saved-r10 -fcall-saved-r11"
+CONFIG_ARCH_SUPPORTS_UPROBES=y
+CONFIG_FIX_EARLYCON_MEM=y
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+CONFIG_IRQ_WORK=y
+CONFIG_BUILDTIME_EXTABLE_SORT=y
+
+#
+# General setup
+#
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+CONFIG_CROSS_COMPILE=""
+# CONFIG_COMPILE_TEST is not set
+CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
+CONFIG_HAVE_KERNEL_GZIP=y
+CONFIG_HAVE_KERNEL_BZIP2=y
+CONFIG_HAVE_KERNEL_LZMA=y
+CONFIG_HAVE_KERNEL_XZ=y
+CONFIG_HAVE_KERNEL_LZO=y
+CONFIG_HAVE_KERNEL_LZ4=y
+CONFIG_KERNEL_GZIP=y
+# CONFIG_KERNEL_BZIP2 is not set
+# CONFIG_KERNEL_LZMA is not set
+# CONFIG_KERNEL_XZ is not set
+# CONFIG_KERNEL_LZO is not set
+# CONFIG_KERNEL_LZ4 is not set
+CONFIG_DEFAULT_HOSTNAME="(none)"
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+CONFIG_SYSVIPC_SYSCTL=y
+CONFIG_POSIX_MQUEUE=y
+CONFIG_POSIX_MQUEUE_SYSCTL=y
+CONFIG_CROSS_MEMORY_ATTACH=y
+# CONFIG_FHANDLE is not set
+CONFIG_USELIB=y
+# CONFIG_AUDIT is not set
+CONFIG_HAVE_ARCH_AUDITSYSCALL=y
+
+#
+# IRQ subsystem
+#
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_GENERIC_IRQ_SHOW=y
+CONFIG_GENERIC_IRQ_LEGACY_ALLOC_HWIRQ=y
+CONFIG_IRQ_DOMAIN=y
+CONFIG_GENERIC_MSI_IRQ=y
+CONFIG_IRQ_FORCED_THREADING=y
+CONFIG_SPARSE_IRQ=y
+CONFIG_CLOCKSOURCE_WATCHDOG=y
+CONFIG_ARCH_CLOCKSOURCE_DATA=y
+CONFIG_CLOCKSOURCE_VALIDATE_LAST_CYCLE=y
+CONFIG_GENERIC_TIME_VSYSCALL=y
+CONFIG_GENERIC_CLOCKEVENTS=y
+CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
+CONFIG_GENERIC_CLOCKEVENTS_BROADCAST=y
+CONFIG_GENERIC_CLOCKEVENTS_MIN_ADJUST=y
+CONFIG_GENERIC_CMOS_UPDATE=y
+
+#
+# Timers subsystem
+#
+CONFIG_TICK_ONESHOT=y
+CONFIG_NO_HZ_COMMON=y
+# CONFIG_HZ_PERIODIC is not set
+CONFIG_NO_HZ_IDLE=y
+CONFIG_NO_HZ=y
+CONFIG_HIGH_RES_TIMERS=y
+
+#
+# CPU/Task time and stats accounting
+#
+CONFIG_TICK_CPU_ACCOUNTING=y
+# CONFIG_VIRT_CPU_ACCOUNTING_GEN is not set
+# CONFIG_IRQ_TIME_ACCOUNTING is not set
+CONFIG_BSD_PROCESS_ACCT=y
+# CONFIG_BSD_PROCESS_ACCT_V3 is not set
+# CONFIG_TASKSTATS is not set
+
+#
+# RCU Subsystem
+#
+CONFIG_TINY_RCU=y
+# CONFIG_TASKS_RCU is not set
+# CONFIG_RCU_STALL_COMMON is not set
+# CONFIG_TREE_RCU_TRACE is not set
+CONFIG_BUILD_BIN2C=y
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_LOG_BUF_SHIFT=14
+CONFIG_HAVE_UNSTABLE_SCHED_CLOCK=y
+CONFIG_ARCH_SUPPORTS_NUMA_BALANCING=y
+CONFIG_ARCH_SUPPORTS_INT128=y
+# CONFIG_CGROUPS is not set
+# CONFIG_CHECKPOINT_RESTORE is not set
+CONFIG_NAMESPACES=y
+# CONFIG_UTS_NS is not set
+# CONFIG_IPC_NS is not set
+# CONFIG_USER_NS is not set
+# CONFIG_PID_NS is not set
+# CONFIG_NET_NS is not set
+# CONFIG_SCHED_AUTOGROUP is not set
+# CONFIG_SYSFS_DEPRECATED is not set
+# CONFIG_RELAY is not set
+# CONFIG_BLK_DEV_INITRD is not set
+CONFIG_INIT_FALLBACK=y
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
+CONFIG_SYSCTL_EXCEPTION_TRACE=y
+CONFIG_HAVE_PCSPKR_PLATFORM=y
+CONFIG_BPF=y
+# CONFIG_EXPERT is not set
+CONFIG_SGETMASK_SYSCALL=y
+CONFIG_SYSFS_SYSCALL=y
+# CONFIG_SYSCTL_SYSCALL is not set
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_ALL is not set
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_ELF_CORE=y
+CONFIG_PCSPKR_PLATFORM=y
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=y
+CONFIG_EPOLL=y
+CONFIG_SIGNALFD=y
+CONFIG_TIMERFD=y
+CONFIG_EVENTFD=y
+# CONFIG_BPF_SYSCALL is not set
+CONFIG_SHMEM=y
+CONFIG_AIO=y
+CONFIG_ADVISE_SYSCALLS=y
+CONFIG_PCI_QUIRKS=y
+# CONFIG_EMBEDDED is not set
+CONFIG_HAVE_PERF_EVENTS=y
+
+#
+# Kernel Performance Events And Counters
+#
+CONFIG_PERF_EVENTS=y
+# CONFIG_DEBUG_PERF_USE_VMALLOC is not set
+CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_COMPAT_BRK=y
+CONFIG_SLAB=y
+# CONFIG_SLUB is not set
+# CONFIG_PROFILING is not set
+CONFIG_HAVE_OPROFILE=y
+CONFIG_OPROFILE_NMI_TIMER=y
+# CONFIG_JUMP_LABEL is not set
+# CONFIG_UPROBES is not set
+# CONFIG_HAVE_64BIT_ALIGNED_ACCESS is not set
+CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS=y
+CONFIG_ARCH_USE_BUILTIN_BSWAP=y
+CONFIG_HAVE_IOREMAP_PROT=y
+CONFIG_HAVE_KPROBES=y
+CONFIG_HAVE_KRETPROBES=y
+CONFIG_HAVE_OPTPROBES=y
+CONFIG_HAVE_KPROBES_ON_FTRACE=y
+CONFIG_HAVE_ARCH_TRACEHOOK=y
+CONFIG_HAVE_DMA_ATTRS=y
+CONFIG_HAVE_DMA_CONTIGUOUS=y
+CONFIG_GENERIC_SMP_IDLE_THREAD=y
+CONFIG_HAVE_REGS_AND_STACK_ACCESS_API=y
+CONFIG_HAVE_DMA_API_DEBUG=y
+CONFIG_HAVE_HW_BREAKPOINT=y
+CONFIG_HAVE_MIXED_BREAKPOINTS_REGS=y
+CONFIG_HAVE_USER_RETURN_NOTIFIER=y
+CONFIG_HAVE_PERF_EVENTS_NMI=y
+CONFIG_HAVE_PERF_REGS=y
+CONFIG_HAVE_PERF_USER_STACK_DUMP=y
+CONFIG_HAVE_ARCH_JUMP_LABEL=y
+CONFIG_ARCH_HAVE_NMI_SAFE_CMPXCHG=y
+CONFIG_HAVE_CMPXCHG_LOCAL=y
+CONFIG_HAVE_CMPXCHG_DOUBLE=y
+CONFIG_HAVE_ARCH_SECCOMP_FILTER=y
+CONFIG_SECCOMP_FILTER=y
+CONFIG_HAVE_CC_STACKPROTECTOR=y
+CONFIG_CC_STACKPROTECTOR=y
+# CONFIG_CC_STACKPROTECTOR_NONE is not set
+CONFIG_CC_STACKPROTECTOR_REGULAR=y
+# CONFIG_CC_STACKPROTECTOR_STRONG is not set
+CONFIG_HAVE_CONTEXT_TRACKING=y
+CONFIG_HAVE_VIRT_CPU_ACCOUNTING_GEN=y
+CONFIG_HAVE_IRQ_TIME_ACCOUNTING=y
+CONFIG_HAVE_ARCH_TRANSPARENT_HUGEPAGE=y
+CONFIG_HAVE_ARCH_SOFT_DIRTY=y
+CONFIG_MODULES_USE_ELF_RELA=y
+CONFIG_HAVE_IRQ_EXIT_ON_IRQ_STACK=y
+
+#
+# GCOV-based kernel profiling
+#
+CONFIG_ARCH_HAS_GCOV_PROFILE_ALL=y
+# CONFIG_HAVE_GENERIC_DMA_COHERENT is not set
+CONFIG_SLABINFO=y
+CONFIG_RT_MUTEXES=y
+CONFIG_BASE_SMALL=0
+# CONFIG_MODULES is not set
+CONFIG_BLOCK=y
+# CONFIG_BLK_DEV_BSG is not set
+# CONFIG_BLK_DEV_BSGLIB is not set
+# CONFIG_BLK_DEV_INTEGRITY is not set
+# CONFIG_BLK_CMDLINE_PARSER is not set
+
+#
+# Partition Types
+#
+# CONFIG_PARTITION_ADVANCED is not set
+CONFIG_MSDOS_PARTITION=y
+CONFIG_EFI_PARTITION=y
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+# CONFIG_DEFAULT_DEADLINE is not set
+CONFIG_DEFAULT_CFQ=y
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="cfq"
+CONFIG_INLINE_SPIN_UNLOCK_IRQ=y
+CONFIG_INLINE_READ_UNLOCK=y
+CONFIG_INLINE_READ_UNLOCK_IRQ=y
+CONFIG_INLINE_WRITE_UNLOCK=y
+CONFIG_INLINE_WRITE_UNLOCK_IRQ=y
+CONFIG_ARCH_SUPPORTS_ATOMIC_RMW=y
+CONFIG_ARCH_USE_QUEUE_RWLOCK=y
+CONFIG_FREEZER=y
+
+#
+# Processor type and features
+#
+CONFIG_ZONE_DMA=y
+# CONFIG_SMP is not set
+CONFIG_X86_FEATURE_NAMES=y
+CONFIG_X86_MPPARSE=y
+CONFIG_X86_EXTENDED_PLATFORM=y
+# CONFIG_X86_GOLDFISH is not set
+# CONFIG_X86_INTEL_LPSS is not set
+CONFIG_IOSF_MBI=y
+CONFIG_SCHED_OMIT_FRAME_POINTER=y
+# CONFIG_HYPERVISOR_GUEST is not set
+CONFIG_NO_BOOTMEM=y
+# CONFIG_MEMTEST is not set
+# CONFIG_MK8 is not set
+# CONFIG_MPSC is not set
+CONFIG_MCORE2=y
+# CONFIG_MATOM is not set
+# CONFIG_GENERIC_CPU is not set
+CONFIG_X86_INTERNODE_CACHE_SHIFT=6
+CONFIG_X86_L1_CACHE_SHIFT=6
+CONFIG_X86_INTEL_USERCOPY=y
+CONFIG_X86_USE_PPRO_CHECKSUM=y
+CONFIG_X86_P6_NOP=y
+CONFIG_X86_TSC=y
+CONFIG_X86_CMPXCHG64=y
+CONFIG_X86_CMOV=y
+CONFIG_X86_MINIMUM_CPU_FAMILY=64
+CONFIG_X86_DEBUGCTLMSR=y
+CONFIG_CPU_SUP_INTEL=y
+CONFIG_CPU_SUP_AMD=y
+CONFIG_CPU_SUP_CENTAUR=y
+CONFIG_HPET_TIMER=y
+CONFIG_DMI=y
+CONFIG_GART_IOMMU=y
+# CONFIG_CALGARY_IOMMU is not set
+CONFIG_SWIOTLB=y
+CONFIG_IOMMU_HELPER=y
+CONFIG_NR_CPUS=1
+CONFIG_PREEMPT_NONE=y
+# CONFIG_PREEMPT_VOLUNTARY is not set
+# CONFIG_PREEMPT is not set
+CONFIG_X86_UP_APIC_MSI=y
+CONFIG_X86_LOCAL_APIC=y
+CONFIG_X86_IO_APIC=y
+# CONFIG_X86_REROUTE_FOR_BROKEN_BOOT_IRQS is not set
+# CONFIG_X86_MCE is not set
+CONFIG_X86_16BIT=y
+CONFIG_X86_ESPFIX64=y
+CONFIG_X86_VSYSCALL_EMULATION=y
+# CONFIG_I8K is not set
+# CONFIG_MICROCODE is not set
+# CONFIG_MICROCODE_INTEL_EARLY is not set
+# CONFIG_MICROCODE_AMD_EARLY is not set
+# CONFIG_X86_MSR is not set
+# CONFIG_X86_CPUID is not set
+CONFIG_ARCH_PHYS_ADDR_T_64BIT=y
+CONFIG_ARCH_DMA_ADDR_T_64BIT=y
+CONFIG_DIRECT_GBPAGES=y
+CONFIG_ARCH_SPARSEMEM_ENABLE=y
+CONFIG_ARCH_SPARSEMEM_DEFAULT=y
+CONFIG_ARCH_SELECT_MEMORY_MODEL=y
+CONFIG_ARCH_MEMORY_PROBE=y
+CONFIG_ARCH_PROC_KCORE_TEXT=y
+CONFIG_ILLEGAL_POINTER_VALUE=0xdead000000000000
+CONFIG_SELECT_MEMORY_MODEL=y
+CONFIG_SPARSEMEM_MANUAL=y
+CONFIG_SPARSEMEM=y
+CONFIG_HAVE_MEMORY_PRESENT=y
+CONFIG_SPARSEMEM_EXTREME=y
+CONFIG_SPARSEMEM_VMEMMAP_ENABLE=y
+CONFIG_SPARSEMEM_ALLOC_MEM_MAP_TOGETHER=y
+CONFIG_SPARSEMEM_VMEMMAP=y
+CONFIG_HAVE_MEMBLOCK=y
+CONFIG_HAVE_MEMBLOCK_NODE_MAP=y
+CONFIG_ARCH_DISCARD_MEMBLOCK=y
+CONFIG_MEMORY_ISOLATION=y
+CONFIG_HAVE_BOOTMEM_INFO_NODE=y
+CONFIG_MEMORY_HOTPLUG=y
+CONFIG_MEMORY_HOTPLUG_SPARSE=y
+CONFIG_MEMORY_HOTREMOVE=y
+CONFIG_PAGEFLAGS_EXTENDED=y
+CONFIG_SPLIT_PTLOCK_CPUS=4
+CONFIG_ARCH_ENABLE_SPLIT_PMD_PTLOCK=y
+CONFIG_MEMORY_BALLOON=y
+# CONFIG_COMPACTION is not set
+CONFIG_MIGRATION=y
+CONFIG_PHYS_ADDR_T_64BIT=y
+CONFIG_ZONE_DMA_FLAG=1
+CONFIG_BOUNCE=y
+CONFIG_VIRT_TO_BUS=y
+# CONFIG_KSM is not set
+CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
+# CONFIG_TRANSPARENT_HUGEPAGE is not set
+CONFIG_NEED_PER_CPU_KM=y
+# CONFIG_CLEANCACHE is not set
+# CONFIG_FRONTSWAP is not set
+# CONFIG_CMA is not set
+# CONFIG_ZPOOL is not set
+# CONFIG_ZBUD is not set
+# CONFIG_ZSMALLOC is not set
+CONFIG_GENERIC_EARLY_IOREMAP=y
+# CONFIG_X86_CHECK_BIOS_CORRUPTION is not set
+CONFIG_X86_RESERVE_LOW=64
+CONFIG_MTRR=y
+CONFIG_MTRR_SANITIZER=y
+CONFIG_MTRR_SANITIZER_ENABLE_DEFAULT=0
+CONFIG_MTRR_SANITIZER_SPARE_REG_NR_DEFAULT=1
+CONFIG_X86_PAT=y
+CONFIG_ARCH_USES_PG_UNCACHED=y
+CONFIG_ARCH_RANDOM=y
+CONFIG_X86_SMAP=y
+# CONFIG_X86_INTEL_MPX is not set
+# CONFIG_EFI is not set
+CONFIG_SECCOMP=y
+# CONFIG_HZ_100 is not set
+CONFIG_HZ_250=y
+# CONFIG_HZ_300 is not set
+# CONFIG_HZ_1000 is not set
+CONFIG_HZ=250
+CONFIG_SCHED_HRTICK=y
+# CONFIG_KEXEC is not set
+# CONFIG_CRASH_DUMP is not set
+CONFIG_PHYSICAL_START=0x1000000
+CONFIG_RELOCATABLE=y
+# CONFIG_RANDOMIZE_BASE is not set
+CONFIG_PHYSICAL_ALIGN=0x1000000
+# CONFIG_CMDLINE_BOOL is not set
+CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
+CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y
+
+#
+# Power management and ACPI options
+#
+CONFIG_SUSPEND=y
+CONFIG_SUSPEND_FREEZER=y
+# CONFIG_HIBERNATION is not set
+CONFIG_PM_SLEEP=y
+# CONFIG_PM_AUTOSLEEP is not set
+# CONFIG_PM_WAKELOCKS is not set
+CONFIG_PM=y
+# CONFIG_PM_DEBUG is not set
+# CONFIG_WQ_POWER_EFFICIENT_DEFAULT is not set
+CONFIG_ACPI=y
+CONFIG_ACPI_LEGACY_TABLES_LOOKUP=y
+CONFIG_ARCH_MIGHT_HAVE_ACPI_PDC=y
+CONFIG_ACPI_SLEEP=y
+# CONFIG_ACPI_PROCFS_POWER is not set
+# CONFIG_ACPI_EC_DEBUGFS is not set
+CONFIG_ACPI_AC=y
+CONFIG_ACPI_BATTERY=y
+CONFIG_ACPI_BUTTON=y
+CONFIG_ACPI_FAN=y
+# CONFIG_ACPI_DOCK is not set
+CONFIG_ACPI_PROCESSOR=y
+# CONFIG_ACPI_PROCESSOR_AGGREGATOR is not set
+CONFIG_ACPI_THERMAL=y
+# CONFIG_ACPI_CUSTOM_DSDT is not set
+# CONFIG_ACPI_DEBUG is not set
+# CONFIG_ACPI_PCI_SLOT is not set
+CONFIG_X86_PM_TIMER=y
+# CONFIG_ACPI_CONTAINER is not set
+# CONFIG_ACPI_HOTPLUG_MEMORY is not set
+# CONFIG_ACPI_SBS is not set
+# CONFIG_ACPI_HED is not set
+# CONFIG_ACPI_REDUCED_HARDWARE_ONLY is not set
+CONFIG_HAVE_ACPI_APEI=y
+CONFIG_HAVE_ACPI_APEI_NMI=y
+# CONFIG_ACPI_APEI is not set
+# CONFIG_PMIC_OPREGION is not set
+# CONFIG_SFI is not set
+
+#
+# CPU Frequency scaling
+#
+# CONFIG_CPU_FREQ is not set
+
+#
+# CPU Idle
+#
+CONFIG_CPU_IDLE=y
+CONFIG_CPU_IDLE_GOV_LADDER=y
+CONFIG_CPU_IDLE_GOV_MENU=y
+# CONFIG_ARCH_NEEDS_CPU_IDLE_COUPLED is not set
+# CONFIG_INTEL_IDLE is not set
+
+#
+# Memory power savings
+#
+# CONFIG_I7300_IDLE is not set
+
+#
+# Bus options (PCI etc.)
+#
+CONFIG_PCI=y
+CONFIG_PCI_DIRECT=y
+# CONFIG_PCI_MMCONFIG is not set
+CONFIG_PCI_DOMAINS=y
+# CONFIG_PCIEPORTBUS is not set
+CONFIG_PCI_MSI=y
+# CONFIG_PCI_DEBUG is not set
+# CONFIG_PCI_REALLOC_ENABLE_AUTO is not set
+# CONFIG_PCI_STUB is not set
+CONFIG_HT_IRQ=y
+# CONFIG_PCI_IOV is not set
+# CONFIG_PCI_PRI is not set
+# CONFIG_PCI_PASID is not set
+CONFIG_PCI_LABEL=y
+
+#
+# PCI host controller drivers
+#
+CONFIG_ISA_DMA_API=y
+CONFIG_AMD_NB=y
+# CONFIG_PCCARD is not set
+# CONFIG_HOTPLUG_PCI is not set
+# CONFIG_RAPIDIO is not set
+# CONFIG_X86_SYSFB is not set
+
+#
+# Executable file formats / Emulations
+#
+CONFIG_BINFMT_ELF=y
+CONFIG_ARCH_BINFMT_ELF_RANDOMIZE_PIE=y
+# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
+CONFIG_BINFMT_SCRIPT=y
+# CONFIG_HAVE_AOUT is not set
+# CONFIG_BINFMT_MISC is not set
+CONFIG_COREDUMP=y
+# CONFIG_IA32_EMULATION is not set
+CONFIG_X86_DEV_DMA_OPS=y
+CONFIG_PMC_ATOM=y
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+# CONFIG_PACKET_DIAG is not set
+CONFIG_UNIX=y
+# CONFIG_UNIX_DIAG is not set
+CONFIG_XFRM=y
+CONFIG_XFRM_ALGO=y
+CONFIG_XFRM_USER=y
+CONFIG_XFRM_SUB_POLICY=y
+CONFIG_XFRM_MIGRATE=y
+CONFIG_XFRM_STATISTICS=y
+CONFIG_XFRM_IPCOMP=y
+CONFIG_NET_KEY=y
+CONFIG_NET_KEY_MIGRATE=y
+CONFIG_INET=y
+# CONFIG_IP_MULTICAST is not set
+CONFIG_IP_ADVANCED_ROUTER=y
+# CONFIG_IP_FIB_TRIE_STATS is not set
+CONFIG_IP_MULTIPLE_TABLES=y
+# CONFIG_IP_ROUTE_MULTIPATH is not set
+# CONFIG_IP_ROUTE_VERBOSE is not set
+CONFIG_IP_ROUTE_CLASSID=y
+# CONFIG_IP_PNP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE_DEMUX is not set
+CONFIG_NET_IP_TUNNEL=y
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_NET_IPVTI is not set
+CONFIG_NET_UDP_TUNNEL=y
+# CONFIG_NET_FOU is not set
+# CONFIG_GENEVE is not set
+CONFIG_INET_AH=y
+CONFIG_INET_ESP=y
+CONFIG_INET_IPCOMP=y
+CONFIG_INET_XFRM_TUNNEL=y
+CONFIG_INET_TUNNEL=y
+CONFIG_INET_XFRM_MODE_TRANSPORT=y
+CONFIG_INET_XFRM_MODE_TUNNEL=y
+CONFIG_INET_XFRM_MODE_BEET=y
+# CONFIG_INET_LRO is not set
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+# CONFIG_INET_UDP_DIAG is not set
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
+# CONFIG_TCP_MD5SIG is not set
+CONFIG_IPV6=y
+# CONFIG_IPV6_ROUTER_PREF is not set
+CONFIG_IPV6_OPTIMISTIC_DAD=y
+CONFIG_INET6_AH=y
+CONFIG_INET6_ESP=y
+CONFIG_INET6_IPCOMP=y
+CONFIG_IPV6_MIP6=y
+CONFIG_INET6_XFRM_TUNNEL=y
+CONFIG_INET6_TUNNEL=y
+CONFIG_INET6_XFRM_MODE_TRANSPORT=y
+CONFIG_INET6_XFRM_MODE_TUNNEL=y
+CONFIG_INET6_XFRM_MODE_BEET=y
+# CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set
+# CONFIG_IPV6_VTI is not set
+# CONFIG_IPV6_SIT is not set
+CONFIG_IPV6_TUNNEL=y
+CONFIG_IPV6_GRE=y
+CONFIG_IPV6_MULTIPLE_TABLES=y
+CONFIG_IPV6_SUBTREES=y
+# CONFIG_IPV6_MROUTE is not set
+# CONFIG_NETWORK_SECMARK is not set
+# CONFIG_NET_PTP_CLASSIFY is not set
+# CONFIG_NETWORK_PHY_TIMESTAMPING is not set
+CONFIG_NETFILTER=y
+# CONFIG_NETFILTER_DEBUG is not set
+CONFIG_NETFILTER_ADVANCED=y
+
+#
+# Core Netfilter Configuration
+#
+CONFIG_NETFILTER_NETLINK=y
+# CONFIG_NETFILTER_NETLINK_ACCT is not set
+CONFIG_NETFILTER_NETLINK_QUEUE=y
+CONFIG_NETFILTER_NETLINK_LOG=y
+CONFIG_NF_CONNTRACK=y
+CONFIG_NF_LOG_COMMON=y
+CONFIG_NF_CONNTRACK_MARK=y
+# CONFIG_NF_CONNTRACK_ZONES is not set
+CONFIG_NF_CONNTRACK_PROCFS=y
+CONFIG_NF_CONNTRACK_EVENTS=y
+# CONFIG_NF_CONNTRACK_TIMEOUT is not set
+# CONFIG_NF_CONNTRACK_TIMESTAMP is not set
+# CONFIG_NF_CT_PROTO_DCCP is not set
+# CONFIG_NF_CT_PROTO_SCTP is not set
+CONFIG_NF_CT_PROTO_UDPLITE=y
+# CONFIG_NF_CONNTRACK_AMANDA is not set
+# CONFIG_NF_CONNTRACK_FTP is not set
+# CONFIG_NF_CONNTRACK_H323 is not set
+# CONFIG_NF_CONNTRACK_IRC is not set
+# CONFIG_NF_CONNTRACK_NETBIOS_NS is not set
+# CONFIG_NF_CONNTRACK_SNMP is not set
+# CONFIG_NF_CONNTRACK_PPTP is not set
+CONFIG_NF_CONNTRACK_SANE=y
+# CONFIG_NF_CONNTRACK_SIP is not set
+# CONFIG_NF_CONNTRACK_TFTP is not set
+CONFIG_NF_CT_NETLINK=y
+# CONFIG_NF_CT_NETLINK_TIMEOUT is not set
+# CONFIG_NETFILTER_NETLINK_QUEUE_CT is not set
+CONFIG_NF_NAT=y
+CONFIG_NF_NAT_NEEDED=y
+CONFIG_NF_NAT_PROTO_UDPLITE=y
+# CONFIG_NF_NAT_AMANDA is not set
+# CONFIG_NF_NAT_FTP is not set
+# CONFIG_NF_NAT_IRC is not set
+# CONFIG_NF_NAT_SIP is not set
+# CONFIG_NF_NAT_TFTP is not set
+CONFIG_NF_NAT_REDIRECT=y
+# CONFIG_NF_TABLES is not set
+CONFIG_NETFILTER_XTABLES=y
+
+#
+# Xtables combined modules
+#
+CONFIG_NETFILTER_XT_MARK=y
+CONFIG_NETFILTER_XT_CONNMARK=y
+CONFIG_NETFILTER_XT_SET=y
+
+#
+# Xtables targets
+#
+# CONFIG_NETFILTER_XT_TARGET_CHECKSUM is not set
+CONFIG_NETFILTER_XT_TARGET_CLASSIFY=y
+CONFIG_NETFILTER_XT_TARGET_CONNMARK=y
+CONFIG_NETFILTER_XT_TARGET_CT=y
+CONFIG_NETFILTER_XT_TARGET_DSCP=y
+CONFIG_NETFILTER_XT_TARGET_HL=y
+# CONFIG_NETFILTER_XT_TARGET_HMARK is not set
+# CONFIG_NETFILTER_XT_TARGET_IDLETIMER is not set
+CONFIG_NETFILTER_XT_TARGET_LOG=y
+CONFIG_NETFILTER_XT_TARGET_MARK=y
+CONFIG_NETFILTER_XT_NAT=y
+CONFIG_NETFILTER_XT_TARGET_NETMAP=y
+CONFIG_NETFILTER_XT_TARGET_NFLOG=y
+CONFIG_NETFILTER_XT_TARGET_NFQUEUE=y
+CONFIG_NETFILTER_XT_TARGET_NOTRACK=y
+# CONFIG_NETFILTER_XT_TARGET_RATEEST is not set
+CONFIG_NETFILTER_XT_TARGET_REDIRECT=y
+# CONFIG_NETFILTER_XT_TARGET_TEE is not set
+# CONFIG_NETFILTER_XT_TARGET_TPROXY is not set
+CONFIG_NETFILTER_XT_TARGET_TRACE=y
+CONFIG_NETFILTER_XT_TARGET_TCPMSS=y
+# CONFIG_NETFILTER_XT_TARGET_TCPOPTSTRIP is not set
+
+#
+# Xtables matches
+#
+CONFIG_NETFILTER_XT_MATCH_ADDRTYPE=y
+# CONFIG_NETFILTER_XT_MATCH_BPF is not set
+CONFIG_NETFILTER_XT_MATCH_CLUSTER=y
+CONFIG_NETFILTER_XT_MATCH_COMMENT=y
+CONFIG_NETFILTER_XT_MATCH_CONNBYTES=y
+# CONFIG_NETFILTER_XT_MATCH_CONNLABEL is not set
+CONFIG_NETFILTER_XT_MATCH_CONNLIMIT=y
+CONFIG_NETFILTER_XT_MATCH_CONNMARK=y
+CONFIG_NETFILTER_XT_MATCH_CONNTRACK=y
+# CONFIG_NETFILTER_XT_MATCH_CPU is not set
+CONFIG_NETFILTER_XT_MATCH_DCCP=y
+CONFIG_NETFILTER_XT_MATCH_DEVGROUP=y
+CONFIG_NETFILTER_XT_MATCH_DSCP=y
+CONFIG_NETFILTER_XT_MATCH_ECN=y
+CONFIG_NETFILTER_XT_MATCH_ESP=y
+CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=y
+CONFIG_NETFILTER_XT_MATCH_HELPER=y
+CONFIG_NETFILTER_XT_MATCH_HL=y
+# CONFIG_NETFILTER_XT_MATCH_IPCOMP is not set
+# CONFIG_NETFILTER_XT_MATCH_IPRANGE is not set
+CONFIG_NETFILTER_XT_MATCH_L2TP=y
+CONFIG_NETFILTER_XT_MATCH_LENGTH=y
+CONFIG_NETFILTER_XT_MATCH_LIMIT=y
+CONFIG_NETFILTER_XT_MATCH_MAC=y
+CONFIG_NETFILTER_XT_MATCH_MARK=y
+CONFIG_NETFILTER_XT_MATCH_MULTIPORT=y
+# CONFIG_NETFILTER_XT_MATCH_NFACCT is not set
+# CONFIG_NETFILTER_XT_MATCH_OSF is not set
+# CONFIG_NETFILTER_XT_MATCH_OWNER is not set
+CONFIG_NETFILTER_XT_MATCH_POLICY=y
+CONFIG_NETFILTER_XT_MATCH_PKTTYPE=y
+CONFIG_NETFILTER_XT_MATCH_QUOTA=y
+# CONFIG_NETFILTER_XT_MATCH_RATEEST is not set
+CONFIG_NETFILTER_XT_MATCH_REALM=y
+# CONFIG_NETFILTER_XT_MATCH_RECENT is not set
+CONFIG_NETFILTER_XT_MATCH_SCTP=y
+# CONFIG_NETFILTER_XT_MATCH_SOCKET is not set
+CONFIG_NETFILTER_XT_MATCH_STATE=y
+CONFIG_NETFILTER_XT_MATCH_STATISTIC=y
+CONFIG_NETFILTER_XT_MATCH_STRING=y
+CONFIG_NETFILTER_XT_MATCH_TCPMSS=y
+# CONFIG_NETFILTER_XT_MATCH_TIME is not set
+CONFIG_NETFILTER_XT_MATCH_U32=y
+CONFIG_IP_SET=y
+CONFIG_IP_SET_MAX=256
+CONFIG_IP_SET_BITMAP_IP=y
+CONFIG_IP_SET_BITMAP_IPMAC=y
+CONFIG_IP_SET_BITMAP_PORT=y
+CONFIG_IP_SET_HASH_IP=y
+# CONFIG_IP_SET_HASH_IPMARK is not set
+CONFIG_IP_SET_HASH_IPPORT=y
+CONFIG_IP_SET_HASH_IPPORTIP=y
+CONFIG_IP_SET_HASH_IPPORTNET=y
+# CONFIG_IP_SET_HASH_MAC is not set
+# CONFIG_IP_SET_HASH_NETPORTNET is not set
+CONFIG_IP_SET_HASH_NET=y
+# CONFIG_IP_SET_HASH_NETNET is not set
+CONFIG_IP_SET_HASH_NETPORT=y
+# CONFIG_IP_SET_HASH_NETIFACE is not set
+CONFIG_IP_SET_LIST_SET=y
+# CONFIG_IP_VS is not set
+
+#
+# IP: Netfilter Configuration
+#
+CONFIG_NF_DEFRAG_IPV4=y
+CONFIG_NF_CONNTRACK_IPV4=y
+CONFIG_NF_CONNTRACK_PROC_COMPAT=y
+# CONFIG_NF_LOG_ARP is not set
+CONFIG_NF_LOG_IPV4=y
+CONFIG_NF_REJECT_IPV4=y
+CONFIG_NF_NAT_IPV4=y
+CONFIG_NF_NAT_MASQUERADE_IPV4=y
+# CONFIG_NF_NAT_PPTP is not set
+# CONFIG_NF_NAT_H323 is not set
+CONFIG_IP_NF_IPTABLES=y
+CONFIG_IP_NF_MATCH_AH=y
+CONFIG_IP_NF_MATCH_ECN=y
+# CONFIG_IP_NF_MATCH_RPFILTER is not set
+CONFIG_IP_NF_MATCH_TTL=y
+CONFIG_IP_NF_FILTER=y
+CONFIG_IP_NF_TARGET_REJECT=y
+# CONFIG_IP_NF_TARGET_SYNPROXY is not set
+CONFIG_IP_NF_NAT=y
+CONFIG_IP_NF_TARGET_MASQUERADE=y
+CONFIG_IP_NF_TARGET_NETMAP=y
+CONFIG_IP_NF_TARGET_REDIRECT=y
+CONFIG_IP_NF_MANGLE=y
+CONFIG_IP_NF_TARGET_CLUSTERIP=y
+CONFIG_IP_NF_TARGET_ECN=y
+CONFIG_IP_NF_TARGET_TTL=y
+CONFIG_IP_NF_RAW=y
+CONFIG_IP_NF_ARPTABLES=y
+CONFIG_IP_NF_ARPFILTER=y
+CONFIG_IP_NF_ARP_MANGLE=y
+
+#
+# IPv6: Netfilter Configuration
+#
+CONFIG_NF_DEFRAG_IPV6=y
+CONFIG_NF_CONNTRACK_IPV6=y
+CONFIG_NF_REJECT_IPV6=y
+CONFIG_NF_LOG_IPV6=y
+CONFIG_NF_NAT_IPV6=y
+CONFIG_NF_NAT_MASQUERADE_IPV6=y
+CONFIG_IP6_NF_IPTABLES=y
+CONFIG_IP6_NF_MATCH_AH=y
+CONFIG_IP6_NF_MATCH_EUI64=y
+CONFIG_IP6_NF_MATCH_FRAG=y
+CONFIG_IP6_NF_MATCH_OPTS=y
+CONFIG_IP6_NF_MATCH_HL=y
+CONFIG_IP6_NF_MATCH_IPV6HEADER=y
+CONFIG_IP6_NF_MATCH_MH=y
+# CONFIG_IP6_NF_MATCH_RPFILTER is not set
+CONFIG_IP6_NF_MATCH_RT=y
+CONFIG_IP6_NF_TARGET_HL=y
+CONFIG_IP6_NF_FILTER=y
+CONFIG_IP6_NF_TARGET_REJECT=y
+# CONFIG_IP6_NF_TARGET_SYNPROXY is not set
+CONFIG_IP6_NF_MANGLE=y
+CONFIG_IP6_NF_RAW=y
+# CONFIG_IP6_NF_NAT is not set
+# CONFIG_IP_DCCP is not set
+# CONFIG_IP_SCTP is not set
+# CONFIG_RDS is not set
+# CONFIG_TIPC is not set
+# CONFIG_ATM is not set
+CONFIG_L2TP=y
+# CONFIG_L2TP_V3 is not set
+# CONFIG_BRIDGE is not set
+CONFIG_HAVE_NET_DSA=y
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_PHONET is not set
+# CONFIG_6LOWPAN is not set
+# CONFIG_IEEE802154 is not set
+# CONFIG_NET_SCHED is not set
+# CONFIG_DCB is not set
+# CONFIG_BATMAN_ADV is not set
+# CONFIG_OPENVSWITCH is not set
+# CONFIG_VSOCKETS is not set
+# CONFIG_NETLINK_MMAP is not set
+# CONFIG_NETLINK_DIAG is not set
+# CONFIG_NET_MPLS_GSO is not set
+# CONFIG_HSR is not set
+# CONFIG_NET_SWITCHDEV is not set
+CONFIG_NET_RX_BUSY_POLL=y
+CONFIG_BQL=y
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_CAN is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+# CONFIG_AF_RXRPC is not set
+CONFIG_FIB_RULES=y
+CONFIG_WIRELESS=y
+# CONFIG_CFG80211 is not set
+# CONFIG_LIB80211 is not set
+
+#
+# CFG80211 needs to be enabled for MAC80211
+#
+# CONFIG_WIMAX is not set
+# CONFIG_RFKILL is not set
+CONFIG_NET_9P=y
+CONFIG_NET_9P_VIRTIO=y
+# CONFIG_NET_9P_DEBUG is not set
+# CONFIG_CAIF is not set
+# CONFIG_CEPH_LIB is not set
+# CONFIG_NFC is not set
+CONFIG_HAVE_BPF_JIT=y
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_UEVENT_HELPER=y
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+# CONFIG_DEVTMPFS is not set
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+CONFIG_FW_LOADER=y
+CONFIG_FIRMWARE_IN_KERNEL=y
+CONFIG_EXTRA_FIRMWARE=""
+# CONFIG_FW_LOADER_USER_HELPER_FALLBACK is not set
+CONFIG_ALLOW_DEV_COREDUMP=y
+# CONFIG_DEBUG_DRIVER is not set
+# CONFIG_DEBUG_DEVRES is not set
+# CONFIG_SYS_HYPERVISOR is not set
+# CONFIG_GENERIC_CPU_DEVICES is not set
+CONFIG_GENERIC_CPU_AUTOPROBE=y
+# CONFIG_DMA_SHARED_BUFFER is not set
+
+#
+# Bus devices
+#
+# CONFIG_CONNECTOR is not set
+# CONFIG_MTD is not set
+CONFIG_ARCH_MIGHT_HAVE_PC_PARPORT=y
+# CONFIG_PARPORT is not set
+CONFIG_PNP=y
+CONFIG_PNP_DEBUG_MESSAGES=y
+
+#
+# Protocols
+#
+CONFIG_PNPACPI=y
+CONFIG_BLK_DEV=y
+# CONFIG_BLK_DEV_NULL_BLK is not set
+# CONFIG_BLK_DEV_FD is not set
+# CONFIG_BLK_DEV_PCIESSD_MTIP32XX is not set
+# CONFIG_BLK_CPQ_CISS_DA is not set
+# CONFIG_BLK_DEV_DAC960 is not set
+# CONFIG_BLK_DEV_UMEM is not set
+# CONFIG_BLK_DEV_COW_COMMON is not set
+CONFIG_BLK_DEV_LOOP=y
+CONFIG_BLK_DEV_LOOP_MIN_COUNT=8
+# CONFIG_BLK_DEV_CRYPTOLOOP is not set
+# CONFIG_BLK_DEV_DRBD is not set
+CONFIG_BLK_DEV_NBD=y
+# CONFIG_BLK_DEV_NVME is not set
+# CONFIG_BLK_DEV_SKD is not set
+# CONFIG_BLK_DEV_SX8 is not set
+# CONFIG_BLK_DEV_RAM is not set
+# CONFIG_CDROM_PKTCDVD is not set
+# CONFIG_ATA_OVER_ETH is not set
+CONFIG_VIRTIO_BLK=y
+# CONFIG_BLK_DEV_HD is not set
+# CONFIG_BLK_DEV_RBD is not set
+# CONFIG_BLK_DEV_RSXX is not set
+
+#
+# Misc devices
+#
+# CONFIG_SENSORS_LIS3LV02D is not set
+# CONFIG_DUMMY_IRQ is not set
+# CONFIG_IBM_ASM is not set
+# CONFIG_PHANTOM is not set
+# CONFIG_SGI_IOC4 is not set
+# CONFIG_TIFM_CORE is not set
+# CONFIG_ENCLOSURE_SERVICES is not set
+# CONFIG_HP_ILO is not set
+# CONFIG_SRAM is not set
+# CONFIG_C2PORT is not set
+
+#
+# EEPROM support
+#
+# CONFIG_EEPROM_93CX6 is not set
+# CONFIG_CB710_CORE is not set
+
+#
+# Texas Instruments shared transport line discipline
+#
+
+#
+# Altera FPGA firmware download module
+#
+# CONFIG_VMWARE_VMCI is not set
+
+#
+# Intel MIC Bus Driver
+#
+# CONFIG_INTEL_MIC_BUS is not set
+
+#
+# Intel MIC Host Driver
+#
+
+#
+# Intel MIC Card Driver
+#
+# CONFIG_GENWQE is not set
+# CONFIG_ECHO is not set
+# CONFIG_CXL_BASE is not set
+CONFIG_HAVE_IDE=y
+# CONFIG_IDE is not set
+
+#
+# SCSI device support
+#
+CONFIG_SCSI_MOD=y
+# CONFIG_RAID_ATTRS is not set
+# CONFIG_SCSI is not set
+# CONFIG_SCSI_DMA is not set
+# CONFIG_SCSI_NETLINK is not set
+# CONFIG_ATA is not set
+# CONFIG_MD is not set
+# CONFIG_FUSION is not set
+
+#
+# IEEE 1394 (FireWire) support
+#
+# CONFIG_FIREWIRE is not set
+# CONFIG_FIREWIRE_NOSY is not set
+# CONFIG_I2O is not set
+# CONFIG_MACINTOSH_DRIVERS is not set
+CONFIG_NETDEVICES=y
+CONFIG_NET_CORE=y
+# CONFIG_BONDING is not set
+CONFIG_DUMMY=y
+# CONFIG_EQUALIZER is not set
+# CONFIG_NET_TEAM is not set
+# CONFIG_MACVLAN is not set
+# CONFIG_IPVLAN is not set
+# CONFIG_VXLAN is not set
+# CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
+CONFIG_TUN=y
+# CONFIG_VETH is not set
+CONFIG_VIRTIO_NET=y
+# CONFIG_NLMON is not set
+# CONFIG_ARCNET is not set
+
+#
+# CAIF transport drivers
+#
+# CONFIG_VHOST_NET is not set
+
+#
+# Distributed Switch Architecture drivers
+#
+# CONFIG_NET_DSA_MV88E6XXX is not set
+# CONFIG_NET_DSA_MV88E6060 is not set
+# CONFIG_NET_DSA_MV88E6XXX_NEED_PPU is not set
+# CONFIG_NET_DSA_MV88E6131 is not set
+# CONFIG_NET_DSA_MV88E6123_61_65 is not set
+# CONFIG_NET_DSA_MV88E6171 is not set
+# CONFIG_NET_DSA_MV88E6352 is not set
+# CONFIG_NET_DSA_BCM_SF2 is not set
+CONFIG_ETHERNET=y
+CONFIG_NET_VENDOR_3COM=y
+# CONFIG_VORTEX is not set
+# CONFIG_TYPHOON is not set
+CONFIG_NET_VENDOR_ADAPTEC=y
+# CONFIG_ADAPTEC_STARFIRE is not set
+CONFIG_NET_VENDOR_AGERE=y
+# CONFIG_ET131X is not set
+CONFIG_NET_VENDOR_ALTEON=y
+# CONFIG_ACENIC is not set
+# CONFIG_ALTERA_TSE is not set
+CONFIG_NET_VENDOR_AMD=y
+# CONFIG_AMD8111_ETH is not set
+# CONFIG_PCNET32 is not set
+# CONFIG_NET_XGENE is not set
+# CONFIG_NET_VENDOR_ARC is not set
+CONFIG_NET_VENDOR_ATHEROS=y
+# CONFIG_ATL2 is not set
+# CONFIG_ATL1 is not set
+# CONFIG_ATL1E is not set
+# CONFIG_ATL1C is not set
+# CONFIG_ALX is not set
+CONFIG_NET_VENDOR_BROADCOM=y
+# CONFIG_B44 is not set
+# CONFIG_BCMGENET is not set
+# CONFIG_BNX2 is not set
+# CONFIG_CNIC is not set
+# CONFIG_TIGON3 is not set
+# CONFIG_BNX2X is not set
+CONFIG_NET_VENDOR_BROCADE=y
+# CONFIG_BNA is not set
+CONFIG_NET_VENDOR_CHELSIO=y
+# CONFIG_CHELSIO_T1 is not set
+# CONFIG_CHELSIO_T3 is not set
+# CONFIG_CHELSIO_T4 is not set
+# CONFIG_CHELSIO_T4VF is not set
+CONFIG_NET_VENDOR_CISCO=y
+# CONFIG_ENIC is not set
+# CONFIG_CX_ECAT is not set
+# CONFIG_DNET is not set
+CONFIG_NET_VENDOR_DEC=y
+# CONFIG_NET_TULIP is not set
+CONFIG_NET_VENDOR_DLINK=y
+# CONFIG_DL2K is not set
+# CONFIG_SUNDANCE is not set
+CONFIG_NET_VENDOR_EMULEX=y
+# CONFIG_BE2NET is not set
+CONFIG_NET_VENDOR_EXAR=y
+# CONFIG_S2IO is not set
+# CONFIG_VXGE is not set
+CONFIG_NET_VENDOR_HP=y
+# CONFIG_HP100 is not set
+CONFIG_NET_VENDOR_INTEL=y
+# CONFIG_E100 is not set
+# CONFIG_E1000 is not set
+# CONFIG_E1000E is not set
+# CONFIG_IGB is not set
+# CONFIG_IGBVF is not set
+# CONFIG_IXGB is not set
+# CONFIG_IXGBE is not set
+# CONFIG_IXGBEVF is not set
+# CONFIG_I40E is not set
+# CONFIG_I40EVF is not set
+# CONFIG_FM10K is not set
+CONFIG_NET_VENDOR_I825XX=y
+# CONFIG_IP1000 is not set
+# CONFIG_JME is not set
+CONFIG_NET_VENDOR_MARVELL=y
+# CONFIG_MVMDIO is not set
+# CONFIG_SKGE is not set
+# CONFIG_SKY2 is not set
+CONFIG_NET_VENDOR_MELLANOX=y
+# CONFIG_MLX4_EN is not set
+# CONFIG_MLX4_CORE is not set
+# CONFIG_MLX5_CORE is not set
+CONFIG_NET_VENDOR_MICREL=y
+# CONFIG_KS8851_MLL is not set
+# CONFIG_KSZ884X_PCI is not set
+CONFIG_NET_VENDOR_MYRI=y
+# CONFIG_MYRI10GE is not set
+# CONFIG_FEALNX is not set
+CONFIG_NET_VENDOR_NATSEMI=y
+# CONFIG_NATSEMI is not set
+# CONFIG_NS83820 is not set
+CONFIG_NET_VENDOR_8390=y
+# CONFIG_NE2K_PCI is not set
+CONFIG_NET_VENDOR_NVIDIA=y
+# CONFIG_FORCEDETH is not set
+CONFIG_NET_VENDOR_OKI=y
+# CONFIG_ETHOC is not set
+CONFIG_NET_PACKET_ENGINE=y
+# CONFIG_HAMACHI is not set
+# CONFIG_YELLOWFIN is not set
+CONFIG_NET_VENDOR_QLOGIC=y
+# CONFIG_QLA3XXX is not set
+# CONFIG_QLCNIC is not set
+# CONFIG_QLGE is not set
+# CONFIG_NETXEN_NIC is not set
+CONFIG_NET_VENDOR_QUALCOMM=y
+CONFIG_NET_VENDOR_REALTEK=y
+# CONFIG_8139CP is not set
+# CONFIG_8139TOO is not set
+# CONFIG_R8169 is not set
+CONFIG_NET_VENDOR_RDC=y
+# CONFIG_R6040 is not set
+CONFIG_NET_VENDOR_ROCKER=y
+CONFIG_NET_VENDOR_SAMSUNG=y
+# CONFIG_SXGBE_ETH is not set
+CONFIG_NET_VENDOR_SEEQ=y
+CONFIG_NET_VENDOR_SILAN=y
+# CONFIG_SC92031 is not set
+CONFIG_NET_VENDOR_SIS=y
+# CONFIG_SIS900 is not set
+# CONFIG_SIS190 is not set
+# CONFIG_SFC is not set
+CONFIG_NET_VENDOR_SMSC=y
+# CONFIG_EPIC100 is not set
+# CONFIG_SMSC911X is not set
+# CONFIG_SMSC9420 is not set
+CONFIG_NET_VENDOR_STMICRO=y
+# CONFIG_STMMAC_ETH is not set
+CONFIG_NET_VENDOR_SUN=y
+# CONFIG_HAPPYMEAL is not set
+# CONFIG_SUNGEM is not set
+# CONFIG_CASSINI is not set
+# CONFIG_NIU is not set
+CONFIG_NET_VENDOR_TEHUTI=y
+# CONFIG_TEHUTI is not set
+CONFIG_NET_VENDOR_TI=y
+# CONFIG_TLAN is not set
+CONFIG_NET_VENDOR_VIA=y
+# CONFIG_VIA_RHINE is not set
+# CONFIG_VIA_VELOCITY is not set
+CONFIG_NET_VENDOR_WIZNET=y
+# CONFIG_WIZNET_W5100 is not set
+# CONFIG_WIZNET_W5300 is not set
+# CONFIG_FDDI is not set
+# CONFIG_HIPPI is not set
+# CONFIG_NET_SB1000 is not set
+# CONFIG_PHYLIB is not set
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+
+#
+# Host-side USB support is needed for USB Network Adapter support
+#
+CONFIG_WLAN=y
+# CONFIG_PRISM54 is not set
+# CONFIG_HOSTAP is not set
+# CONFIG_WL_TI is not set
+
+#
+# Enable WiMAX (Networking options) to see the WiMAX drivers
+#
+# CONFIG_WAN is not set
+# CONFIG_VMXNET3 is not set
+# CONFIG_ISDN is not set
+
+#
+# Input device support
+#
+CONFIG_INPUT=y
+# CONFIG_INPUT_FF_MEMLESS is not set
+# CONFIG_INPUT_POLLDEV is not set
+# CONFIG_INPUT_SPARSEKMAP is not set
+# CONFIG_INPUT_MATRIXKMAP is not set
+
+#
+# Userland interfaces
+#
+CONFIG_INPUT_MOUSEDEV=y
+CONFIG_INPUT_MOUSEDEV_PSAUX=y
+CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
+# CONFIG_INPUT_JOYDEV is not set
+CONFIG_INPUT_EVDEV=y
+# CONFIG_INPUT_EVBUG is not set
+
+#
+# Input Device Drivers
+#
+CONFIG_INPUT_KEYBOARD=y
+CONFIG_KEYBOARD_ATKBD=y
+# CONFIG_KEYBOARD_LKKBD is not set
+# CONFIG_KEYBOARD_NEWTON is not set
+# CONFIG_KEYBOARD_OPENCORES is not set
+# CONFIG_KEYBOARD_STOWAWAY is not set
+# CONFIG_KEYBOARD_SUNKBD is not set
+# CONFIG_KEYBOARD_XTKBD is not set
+CONFIG_INPUT_MOUSE=y
+CONFIG_MOUSE_PS2=y
+CONFIG_MOUSE_PS2_ALPS=y
+CONFIG_MOUSE_PS2_LOGIPS2PP=y
+CONFIG_MOUSE_PS2_SYNAPTICS=y
+CONFIG_MOUSE_PS2_CYPRESS=y
+CONFIG_MOUSE_PS2_LIFEBOOK=y
+CONFIG_MOUSE_PS2_TRACKPOINT=y
+# CONFIG_MOUSE_PS2_ELANTECH is not set
+# CONFIG_MOUSE_PS2_SENTELIC is not set
+# CONFIG_MOUSE_PS2_TOUCHKIT is not set
+# CONFIG_MOUSE_SERIAL is not set
+# CONFIG_MOUSE_APPLETOUCH is not set
+# CONFIG_MOUSE_BCM5974 is not set
+# CONFIG_MOUSE_VSXXXAA is not set
+# CONFIG_MOUSE_SYNAPTICS_USB is not set
+# CONFIG_INPUT_JOYSTICK is not set
+# CONFIG_INPUT_TABLET is not set
+# CONFIG_INPUT_TOUCHSCREEN is not set
+# CONFIG_INPUT_MISC is not set
+
+#
+# Hardware I/O ports
+#
+CONFIG_SERIO=y
+CONFIG_ARCH_MIGHT_HAVE_PC_SERIO=y
+CONFIG_SERIO_I8042=y
+CONFIG_SERIO_SERPORT=y
+# CONFIG_SERIO_CT82C710 is not set
+# CONFIG_SERIO_PCIPS2 is not set
+CONFIG_SERIO_LIBPS2=y
+# CONFIG_SERIO_RAW is not set
+# CONFIG_SERIO_ALTERA_PS2 is not set
+# CONFIG_SERIO_PS2MULT is not set
+# CONFIG_SERIO_ARC_PS2 is not set
+# CONFIG_GAMEPORT is not set
+
+#
+# Character devices
+#
+CONFIG_TTY=y
+CONFIG_VT=y
+CONFIG_CONSOLE_TRANSLATIONS=y
+CONFIG_VT_CONSOLE=y
+CONFIG_VT_CONSOLE_SLEEP=y
+CONFIG_HW_CONSOLE=y
+# CONFIG_VT_HW_CONSOLE_BINDING is not set
+CONFIG_UNIX98_PTYS=y
+# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
+CONFIG_LEGACY_PTYS=y
+CONFIG_LEGACY_PTY_COUNT=256
+# CONFIG_SERIAL_NONSTANDARD is not set
+# CONFIG_NOZOMI is not set
+# CONFIG_N_GSM is not set
+# CONFIG_TRACE_SINK is not set
+CONFIG_DEVKMEM=y
+
+#
+# Serial drivers
+#
+# CONFIG_SERIAL_8250 is not set
+
+#
+# Non-8250 serial port support
+#
+# CONFIG_SERIAL_MFD_HSU is not set
+# CONFIG_SERIAL_JSM is not set
+# CONFIG_SERIAL_SCCNXP is not set
+# CONFIG_SERIAL_ALTERA_JTAGUART is not set
+# CONFIG_SERIAL_ALTERA_UART is not set
+# CONFIG_SERIAL_ARC is not set
+# CONFIG_SERIAL_RP2 is not set
+# CONFIG_SERIAL_FSL_LPUART is not set
+CONFIG_HVC_DRIVER=y
+CONFIG_VIRTIO_CONSOLE=y
+# CONFIG_IPMI_HANDLER is not set
+# CONFIG_HW_RANDOM is not set
+# CONFIG_NVRAM is not set
+# CONFIG_R3964 is not set
+# CONFIG_APPLICOM is not set
+# CONFIG_MWAVE is not set
+# CONFIG_RAW_DRIVER is not set
+# CONFIG_HPET is not set
+# CONFIG_HANGCHECK_TIMER is not set
+# CONFIG_TCG_TPM is not set
+# CONFIG_TELCLOCK is not set
+CONFIG_DEVPORT=y
+# CONFIG_XILLYBUS is not set
+
+#
+# I2C support
+#
+# CONFIG_I2C is not set
+# CONFIG_SPI is not set
+# CONFIG_SPMI is not set
+# CONFIG_HSI is not set
+
+#
+# PPS support
+#
+# CONFIG_PPS is not set
+
+#
+# PPS generators support
+#
+
+#
+# PTP clock support
+#
+# CONFIG_PTP_1588_CLOCK is not set
+
+#
+# Enable PHYLIB and NETWORK_PHY_TIMESTAMPING to see the additional clocks.
+#
+CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y
+# CONFIG_GPIOLIB is not set
+# CONFIG_W1 is not set
+CONFIG_POWER_SUPPLY=y
+# CONFIG_POWER_SUPPLY_DEBUG is not set
+# CONFIG_PDA_POWER is not set
+# CONFIG_TEST_POWER is not set
+# CONFIG_BATTERY_DS2780 is not set
+# CONFIG_BATTERY_DS2781 is not set
+# CONFIG_BATTERY_BQ27x00 is not set
+# CONFIG_CHARGER_MAX8903 is not set
+# CONFIG_POWER_RESET is not set
+# CONFIG_POWER_AVS is not set
+CONFIG_HWMON=y
+# CONFIG_HWMON_VID is not set
+# CONFIG_HWMON_DEBUG_CHIP is not set
+
+#
+# Native drivers
+#
+# CONFIG_SENSORS_ABITUGURU is not set
+# CONFIG_SENSORS_ABITUGURU3 is not set
+# CONFIG_SENSORS_K8TEMP is not set
+# CONFIG_SENSORS_K10TEMP is not set
+# CONFIG_SENSORS_FAM15H_POWER is not set
+# CONFIG_SENSORS_APPLESMC is not set
+# CONFIG_SENSORS_I5K_AMB is not set
+# CONFIG_SENSORS_F71805F is not set
+# CONFIG_SENSORS_F71882FG is not set
+# CONFIG_SENSORS_I5500 is not set
+# CONFIG_SENSORS_CORETEMP is not set
+# CONFIG_SENSORS_IT87 is not set
+# CONFIG_SENSORS_MAX197 is not set
+# CONFIG_SENSORS_PC87360 is not set
+# CONFIG_SENSORS_PC87427 is not set
+# CONFIG_SENSORS_NTC_THERMISTOR is not set
+# CONFIG_SENSORS_NCT6683 is not set
+# CONFIG_SENSORS_NCT6775 is not set
+# CONFIG_SENSORS_SIS5595 is not set
+# CONFIG_SENSORS_SMSC47M1 is not set
+# CONFIG_SENSORS_SMSC47B397 is not set
+# CONFIG_SENSORS_SCH56XX_COMMON is not set
+# CONFIG_SENSORS_VIA_CPUTEMP is not set
+# CONFIG_SENSORS_VIA686A is not set
+# CONFIG_SENSORS_VT1211 is not set
+# CONFIG_SENSORS_VT8231 is not set
+# CONFIG_SENSORS_W83627HF is not set
+# CONFIG_SENSORS_W83627EHF is not set
+
+#
+# ACPI drivers
+#
+# CONFIG_SENSORS_ACPI_POWER is not set
+# CONFIG_SENSORS_ATK0110 is not set
+CONFIG_THERMAL=y
+CONFIG_THERMAL_HWMON=y
+CONFIG_THERMAL_DEFAULT_GOV_STEP_WISE=y
+# CONFIG_THERMAL_DEFAULT_GOV_FAIR_SHARE is not set
+# CONFIG_THERMAL_DEFAULT_GOV_USER_SPACE is not set
+# CONFIG_THERMAL_GOV_FAIR_SHARE is not set
+CONFIG_THERMAL_GOV_STEP_WISE=y
+# CONFIG_THERMAL_GOV_BANG_BANG is not set
+# CONFIG_THERMAL_GOV_USER_SPACE is not set
+# CONFIG_THERMAL_EMULATION is not set
+# CONFIG_INTEL_POWERCLAMP is not set
+# CONFIG_INTEL_SOC_DTS_THERMAL is not set
+# CONFIG_INT340X_THERMAL is not set
+
+#
+# Texas Instruments thermal drivers
+#
+# CONFIG_WATCHDOG is not set
+CONFIG_SSB_POSSIBLE=y
+
+#
+# Sonics Silicon Backplane
+#
+# CONFIG_SSB is not set
+CONFIG_BCMA_POSSIBLE=y
+
+#
+# Broadcom specific AMBA
+#
+# CONFIG_BCMA is not set
+
+#
+# Multifunction device drivers
+#
+# CONFIG_MFD_CORE is not set
+# CONFIG_MFD_CROS_EC is not set
+# CONFIG_HTC_PASIC3 is not set
+# CONFIG_LPC_ICH is not set
+# CONFIG_LPC_SCH is not set
+# CONFIG_MFD_JANZ_CMODIO is not set
+# CONFIG_MFD_KEMPLD is not set
+# CONFIG_MFD_RDC321X is not set
+# CONFIG_MFD_RTSX_PCI is not set
+# CONFIG_MFD_SM501 is not set
+# CONFIG_ABX500_CORE is not set
+# CONFIG_MFD_SYSCON is not set
+# CONFIG_MFD_TI_AM335X_TSCADC is not set
+# CONFIG_MFD_TMIO is not set
+# CONFIG_MFD_VX855 is not set
+# CONFIG_REGULATOR is not set
+# CONFIG_MEDIA_SUPPORT is not set
+
+#
+# Graphics support
+#
+# CONFIG_AGP is not set
+CONFIG_VGA_ARB=y
+CONFIG_VGA_ARB_MAX_GPUS=16
+# CONFIG_VGA_SWITCHEROO is not set
+
+#
+# Direct Rendering Manager
+#
+# CONFIG_DRM is not set
+
+#
+# Frame buffer Devices
+#
+# CONFIG_FB is not set
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+# CONFIG_VGASTATE is not set
+
+#
+# Console display driver support
+#
+CONFIG_VGA_CONSOLE=y
+# CONFIG_VGACON_SOFT_SCROLLBACK is not set
+CONFIG_DUMMY_CONSOLE=y
+CONFIG_SOUND=y
+# CONFIG_SOUND_OSS_CORE is not set
+# CONFIG_SND is not set
+# CONFIG_SOUND_PRIME is not set
+
+#
+# HID support
+#
+CONFIG_HID=y
+# CONFIG_HID_BATTERY_STRENGTH is not set
+# CONFIG_HIDRAW is not set
+# CONFIG_UHID is not set
+CONFIG_HID_GENERIC=y
+
+#
+# Special HID drivers
+#
+CONFIG_HID_A4TECH=y
+# CONFIG_HID_ACRUX is not set
+CONFIG_HID_APPLE=y
+# CONFIG_HID_AUREAL is not set
+CONFIG_HID_BELKIN=y
+CONFIG_HID_CHERRY=y
+CONFIG_HID_CHICONY=y
+CONFIG_HID_CYPRESS=y
+# CONFIG_HID_DRAGONRISE is not set
+# CONFIG_HID_EMS_FF is not set
+# CONFIG_HID_ELECOM is not set
+CONFIG_HID_EZKEY=y
+# CONFIG_HID_KEYTOUCH is not set
+# CONFIG_HID_KYE is not set
+# CONFIG_HID_UCLOGIC is not set
+# CONFIG_HID_WALTOP is not set
+# CONFIG_HID_GYRATION is not set
+# CONFIG_HID_ICADE is not set
+# CONFIG_HID_TWINHAN is not set
+CONFIG_HID_KENSINGTON=y
+# CONFIG_HID_LCPOWER is not set
+# CONFIG_HID_LENOVO is not set
+CONFIG_HID_LOGITECH=y
+# CONFIG_HID_LOGITECH_HIDPP is not set
+# CONFIG_LOGITECH_FF is not set
+# CONFIG_LOGIRUMBLEPAD2_FF is not set
+# CONFIG_LOGIG940_FF is not set
+# CONFIG_LOGIWHEELS_FF is not set
+# CONFIG_HID_MAGICMOUSE is not set
+CONFIG_HID_MICROSOFT=y
+CONFIG_HID_MONTEREY=y
+# CONFIG_HID_MULTITOUCH is not set
+# CONFIG_HID_ORTEK is not set
+# CONFIG_HID_PANTHERLORD is not set
+# CONFIG_HID_PETALYNX is not set
+# CONFIG_HID_PICOLCD is not set
+CONFIG_HID_PLANTRONICS=y
+# CONFIG_HID_PRIMAX is not set
+# CONFIG_HID_SAITEK is not set
+# CONFIG_HID_SAMSUNG is not set
+# CONFIG_HID_SPEEDLINK is not set
+# CONFIG_HID_STEELSERIES is not set
+# CONFIG_HID_SUNPLUS is not set
+# CONFIG_HID_RMI is not set
+# CONFIG_HID_GREENASIA is not set
+# CONFIG_HID_SMARTJOYPLUS is not set
+# CONFIG_HID_TIVO is not set
+# CONFIG_HID_TOPSEED is not set
+# CONFIG_HID_THRUSTMASTER is not set
+# CONFIG_HID_WACOM is not set
+# CONFIG_HID_XINMO is not set
+# CONFIG_HID_ZEROPLUS is not set
+# CONFIG_HID_ZYDACRON is not set
+# CONFIG_HID_SENSOR_HUB is not set
+CONFIG_USB_OHCI_LITTLE_ENDIAN=y
+CONFIG_USB_SUPPORT=y
+CONFIG_USB_ARCH_HAS_HCD=y
+# CONFIG_USB is not set
+
+#
+# USB port drivers
+#
+
+#
+# USB Physical Layer drivers
+#
+# CONFIG_USB_PHY is not set
+# CONFIG_NOP_USB_XCEIV is not set
+# CONFIG_USB_GADGET is not set
+# CONFIG_UWB is not set
+# CONFIG_MMC is not set
+# CONFIG_MEMSTICK is not set
+# CONFIG_NEW_LEDS is not set
+# CONFIG_ACCESSIBILITY is not set
+# CONFIG_INFINIBAND is not set
+# CONFIG_EDAC is not set
+CONFIG_RTC_LIB=y
+# CONFIG_RTC_CLASS is not set
+# CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
+# CONFIG_UIO is not set
+# CONFIG_VIRT_DRIVERS is not set
+CONFIG_VIRTIO=y
+
+#
+# Virtio drivers
+#
+CONFIG_VIRTIO_PCI=y
+CONFIG_VIRTIO_BALLOON=y
+CONFIG_VIRTIO_MMIO=y
+# CONFIG_VIRTIO_MMIO_CMDLINE_DEVICES is not set
+
+#
+# Microsoft Hyper-V guest support
+#
+# CONFIG_STAGING is not set
+CONFIG_X86_PLATFORM_DEVICES=y
+# CONFIG_ACERHDF is not set
+# CONFIG_ASUS_LAPTOP is not set
+# CONFIG_DELL_SMO8800 is not set
+# CONFIG_FUJITSU_TABLET is not set
+# CONFIG_HP_ACCEL is not set
+# CONFIG_HP_WIRELESS is not set
+# CONFIG_THINKPAD_ACPI is not set
+# CONFIG_SENSORS_HDAPS is not set
+# CONFIG_INTEL_MENLOW is not set
+# CONFIG_ACPI_WMI is not set
+# CONFIG_TOPSTAR_LAPTOP is not set
+# CONFIG_TOSHIBA_BT_RFKILL is not set
+# CONFIG_TOSHIBA_HAPS is not set
+# CONFIG_ACPI_CMPC is not set
+# CONFIG_INTEL_IPS is not set
+# CONFIG_IBM_RTL is not set
+# CONFIG_SAMSUNG_Q10 is not set
+# CONFIG_INTEL_RST is not set
+# CONFIG_INTEL_SMARTCONNECT is not set
+# CONFIG_PVPANIC is not set
+# CONFIG_CHROME_PLATFORMS is not set
+
+#
+# Hardware Spinlock drivers
+#
+
+#
+# Clock Source drivers
+#
+CONFIG_CLKEVT_I8253=y
+CONFIG_I8253_LOCK=y
+CONFIG_CLKBLD_I8253=y
+# CONFIG_ATMEL_PIT is not set
+# CONFIG_SH_TIMER_CMT is not set
+# CONFIG_SH_TIMER_MTU2 is not set
+# CONFIG_SH_TIMER_TMU is not set
+# CONFIG_EM_TIMER_STI is not set
+# CONFIG_MAILBOX is not set
+CONFIG_IOMMU_SUPPORT=y
+# CONFIG_AMD_IOMMU is not set
+# CONFIG_INTEL_IOMMU is not set
+# CONFIG_IRQ_REMAP is not set
+
+#
+# Remoteproc drivers
+#
+# CONFIG_STE_MODEM_RPROC is not set
+
+#
+# Rpmsg drivers
+#
+
+#
+# SOC (System On Chip) specific Drivers
+#
+# CONFIG_SOC_TI is not set
+# CONFIG_PM_DEVFREQ is not set
+# CONFIG_EXTCON is not set
+# CONFIG_MEMORY is not set
+# CONFIG_IIO is not set
+# CONFIG_NTB is not set
+# CONFIG_VME_BUS is not set
+# CONFIG_PWM is not set
+# CONFIG_IPACK_BUS is not set
+# CONFIG_RESET_CONTROLLER is not set
+# CONFIG_FMC is not set
+
+#
+# PHY Subsystem
+#
+# CONFIG_GENERIC_PHY is not set
+# CONFIG_BCM_KONA_USB2_PHY is not set
+# CONFIG_POWERCAP is not set
+# CONFIG_MCB is not set
+# CONFIG_THUNDERBOLT is not set
+
+#
+# Android
+#
+# CONFIG_ANDROID is not set
+
+#
+# Firmware Drivers
+#
+# CONFIG_EDD is not set
+CONFIG_FIRMWARE_MEMMAP=y
+# CONFIG_DELL_RBU is not set
+# CONFIG_DCDBAS is not set
+CONFIG_DMIID=y
+# CONFIG_DMI_SYSFS is not set
+CONFIG_DMI_SCAN_MACHINE_NON_EFI_FALLBACK=y
+# CONFIG_ISCSI_IBFT_FIND is not set
+# CONFIG_GOOGLE_FIRMWARE is not set
+
+#
+# File systems
+#
+CONFIG_DCACHE_WORD_ACCESS=y
+CONFIG_EXT2_FS=y
+# CONFIG_EXT2_FS_XATTR is not set
+# CONFIG_EXT2_FS_XIP is not set
+CONFIG_EXT3_FS=y
+# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set
+# CONFIG_EXT3_FS_XATTR is not set
+# CONFIG_EXT4_FS is not set
+CONFIG_JBD=y
+CONFIG_REISERFS_FS=y
+# CONFIG_REISERFS_CHECK is not set
+# CONFIG_REISERFS_PROC_INFO is not set
+# CONFIG_REISERFS_FS_XATTR is not set
+# CONFIG_JFS_FS is not set
+# CONFIG_XFS_FS is not set
+# CONFIG_GFS2_FS is not set
+# CONFIG_BTRFS_FS is not set
+# CONFIG_NILFS2_FS is not set
+CONFIG_FS_POSIX_ACL=y
+CONFIG_FILE_LOCKING=y
+CONFIG_FSNOTIFY=y
+CONFIG_DNOTIFY=y
+CONFIG_INOTIFY_USER=y
+# CONFIG_FANOTIFY is not set
+CONFIG_QUOTA=y
+# CONFIG_QUOTA_NETLINK_INTERFACE is not set
+CONFIG_PRINT_QUOTA_WARNING=y
+# CONFIG_QUOTA_DEBUG is not set
+# CONFIG_QFMT_V1 is not set
+# CONFIG_QFMT_V2 is not set
+CONFIG_QUOTACTL=y
+CONFIG_AUTOFS4_FS=y
+# CONFIG_FUSE_FS is not set
+# CONFIG_OVERLAY_FS is not set
+
+#
+# Caches
+#
+# CONFIG_FSCACHE is not set
+
+#
+# CD-ROM/DVD Filesystems
+#
+CONFIG_ISO9660_FS=y
+CONFIG_JOLIET=y
+# CONFIG_ZISOFS is not set
+# CONFIG_UDF_FS is not set
+
+#
+# DOS/FAT/NT Filesystems
+#
+# CONFIG_MSDOS_FS is not set
+# CONFIG_VFAT_FS is not set
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_PROC_KCORE=y
+CONFIG_PROC_SYSCTL=y
+CONFIG_PROC_PAGE_MONITOR=y
+CONFIG_KERNFS=y
+CONFIG_SYSFS=y
+CONFIG_TMPFS=y
+# CONFIG_TMPFS_POSIX_ACL is not set
+# CONFIG_TMPFS_XATTR is not set
+# CONFIG_HUGETLBFS is not set
+# CONFIG_HUGETLB_PAGE is not set
+# CONFIG_CONFIGFS_FS is not set
+CONFIG_MISC_FILESYSTEMS=y
+# CONFIG_ADFS_FS is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_HFSPLUS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EFS_FS is not set
+# CONFIG_LOGFS is not set
+# CONFIG_CRAMFS is not set
+# CONFIG_SQUASHFS is not set
+# CONFIG_VXFS_FS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_OMFS_FS is not set
+# CONFIG_HPFS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_QNX6FS_FS is not set
+# CONFIG_ROMFS_FS is not set
+# CONFIG_PSTORE is not set
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
+# CONFIG_F2FS_FS is not set
+CONFIG_NETWORK_FILESYSTEMS=y
+# CONFIG_NFS_FS is not set
+# CONFIG_NFSD is not set
+# CONFIG_CEPH_FS is not set
+# CONFIG_CIFS is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_CODA_FS is not set
+# CONFIG_AFS_FS is not set
+CONFIG_9P_FS=y
+CONFIG_9P_FS_POSIX_ACL=y
+# CONFIG_9P_FS_SECURITY is not set
+CONFIG_NLS=y
+CONFIG_NLS_DEFAULT="iso8859-1"
+# CONFIG_NLS_CODEPAGE_437 is not set
+# CONFIG_NLS_CODEPAGE_737 is not set
+# CONFIG_NLS_CODEPAGE_775 is not set
+# CONFIG_NLS_CODEPAGE_850 is not set
+# CONFIG_NLS_CODEPAGE_852 is not set
+# CONFIG_NLS_CODEPAGE_855 is not set
+# CONFIG_NLS_CODEPAGE_857 is not set
+# CONFIG_NLS_CODEPAGE_860 is not set
+# CONFIG_NLS_CODEPAGE_861 is not set
+# CONFIG_NLS_CODEPAGE_862 is not set
+# CONFIG_NLS_CODEPAGE_863 is not set
+# CONFIG_NLS_CODEPAGE_864 is not set
+# CONFIG_NLS_CODEPAGE_865 is not set
+# CONFIG_NLS_CODEPAGE_866 is not set
+# CONFIG_NLS_CODEPAGE_869 is not set
+# CONFIG_NLS_CODEPAGE_936 is not set
+# CONFIG_NLS_CODEPAGE_950 is not set
+# CONFIG_NLS_CODEPAGE_932 is not set
+# CONFIG_NLS_CODEPAGE_949 is not set
+# CONFIG_NLS_CODEPAGE_874 is not set
+# CONFIG_NLS_ISO8859_8 is not set
+# CONFIG_NLS_CODEPAGE_1250 is not set
+# CONFIG_NLS_CODEPAGE_1251 is not set
+# CONFIG_NLS_ASCII is not set
+# CONFIG_NLS_ISO8859_1 is not set
+# CONFIG_NLS_ISO8859_2 is not set
+# CONFIG_NLS_ISO8859_3 is not set
+# CONFIG_NLS_ISO8859_4 is not set
+# CONFIG_NLS_ISO8859_5 is not set
+# CONFIG_NLS_ISO8859_6 is not set
+# CONFIG_NLS_ISO8859_7 is not set
+# CONFIG_NLS_ISO8859_9 is not set
+# CONFIG_NLS_ISO8859_13 is not set
+# CONFIG_NLS_ISO8859_14 is not set
+# CONFIG_NLS_ISO8859_15 is not set
+# CONFIG_NLS_KOI8_R is not set
+# CONFIG_NLS_KOI8_U is not set
+# CONFIG_NLS_MAC_ROMAN is not set
+# CONFIG_NLS_MAC_CELTIC is not set
+# CONFIG_NLS_MAC_CENTEURO is not set
+# CONFIG_NLS_MAC_CROATIAN is not set
+# CONFIG_NLS_MAC_CYRILLIC is not set
+# CONFIG_NLS_MAC_GAELIC is not set
+# CONFIG_NLS_MAC_GREEK is not set
+# CONFIG_NLS_MAC_ICELAND is not set
+# CONFIG_NLS_MAC_INUIT is not set
+# CONFIG_NLS_MAC_ROMANIAN is not set
+# CONFIG_NLS_MAC_TURKISH is not set
+# CONFIG_NLS_UTF8 is not set
+
+#
+# Kernel hacking
+#
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
+
+#
+# printk and dmesg options
+#
+# CONFIG_PRINTK_TIME is not set
+CONFIG_MESSAGE_LOGLEVEL_DEFAULT=4
+# CONFIG_BOOT_PRINTK_DELAY is not set
+
+#
+# Compile-time checks and compiler options
+#
+CONFIG_DEBUG_INFO=y
+# CONFIG_DEBUG_INFO_REDUCED is not set
+# CONFIG_DEBUG_INFO_SPLIT is not set
+# CONFIG_DEBUG_INFO_DWARF4 is not set
+CONFIG_ENABLE_WARN_DEPRECATED=y
+CONFIG_ENABLE_MUST_CHECK=y
+CONFIG_FRAME_WARN=1024
+# CONFIG_STRIP_ASM_SYMS is not set
+# CONFIG_READABLE_ASM is not set
+# CONFIG_UNUSED_SYMBOLS is not set
+# CONFIG_PAGE_OWNER is not set
+# CONFIG_DEBUG_FS is not set
+# CONFIG_HEADERS_CHECK is not set
+# CONFIG_DEBUG_SECTION_MISMATCH is not set
+CONFIG_ARCH_WANT_FRAME_POINTERS=y
+CONFIG_FRAME_POINTER=y
+# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set
+# CONFIG_MAGIC_SYSRQ is not set
+CONFIG_DEBUG_KERNEL=y
+
+#
+# Memory Debugging
+#
+# CONFIG_PAGE_EXTENSION is not set
+# CONFIG_DEBUG_PAGEALLOC is not set
+# CONFIG_DEBUG_OBJECTS is not set
+# CONFIG_DEBUG_SLAB is not set
+CONFIG_HAVE_DEBUG_KMEMLEAK=y
+# CONFIG_DEBUG_KMEMLEAK is not set
+# CONFIG_DEBUG_STACK_USAGE is not set
+# CONFIG_DEBUG_VM is not set
+# CONFIG_DEBUG_VIRTUAL is not set
+CONFIG_DEBUG_MEMORY_INIT=y
+CONFIG_HAVE_DEBUG_STACKOVERFLOW=y
+# CONFIG_DEBUG_STACKOVERFLOW is not set
+CONFIG_HAVE_ARCH_KMEMCHECK=y
+# CONFIG_DEBUG_SHIRQ is not set
+
+#
+# Debug Lockups and Hangs
+#
+# CONFIG_LOCKUP_DETECTOR is not set
+CONFIG_DETECT_HUNG_TASK=y
+CONFIG_DEFAULT_HUNG_TASK_TIMEOUT=120
+# CONFIG_BOOTPARAM_HUNG_TASK_PANIC is not set
+CONFIG_BOOTPARAM_HUNG_TASK_PANIC_VALUE=0
+# CONFIG_PANIC_ON_OOPS is not set
+CONFIG_PANIC_ON_OOPS_VALUE=0
+CONFIG_PANIC_TIMEOUT=0
+# CONFIG_SCHED_DEBUG is not set
+# CONFIG_SCHEDSTATS is not set
+# CONFIG_SCHED_STACK_END_CHECK is not set
+# CONFIG_TIMER_STATS is not set
+
+#
+# Lock Debugging (spinlocks, mutexes, etc...)
+#
+# CONFIG_DEBUG_RT_MUTEXES is not set
+# CONFIG_DEBUG_SPINLOCK is not set
+# CONFIG_DEBUG_MUTEXES is not set
+# CONFIG_DEBUG_WW_MUTEX_SLOWPATH is not set
+# CONFIG_DEBUG_LOCK_ALLOC is not set
+# CONFIG_PROVE_LOCKING is not set
+# CONFIG_LOCK_STAT is not set
+# CONFIG_DEBUG_ATOMIC_SLEEP is not set
+# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
+# CONFIG_LOCK_TORTURE_TEST is not set
+# CONFIG_STACKTRACE is not set
+# CONFIG_DEBUG_KOBJECT is not set
+CONFIG_DEBUG_BUGVERBOSE=y
+# CONFIG_DEBUG_LIST is not set
+# CONFIG_DEBUG_PI_LIST is not set
+# CONFIG_DEBUG_SG is not set
+# CONFIG_DEBUG_NOTIFIERS is not set
+# CONFIG_DEBUG_CREDENTIALS is not set
+
+#
+# RCU Debugging
+#
+# CONFIG_SPARSE_RCU_POINTER is not set
+# CONFIG_TORTURE_TEST is not set
+# CONFIG_RCU_TORTURE_TEST is not set
+# CONFIG_RCU_TRACE is not set
+# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
+# CONFIG_NOTIFIER_ERROR_INJECTION is not set
+# CONFIG_FAULT_INJECTION is not set
+# CONFIG_LATENCYTOP is not set
+CONFIG_ARCH_HAS_DEBUG_STRICT_USER_COPY_CHECKS=y
+# CONFIG_DEBUG_STRICT_USER_COPY_CHECKS is not set
+CONFIG_USER_STACKTRACE_SUPPORT=y
+CONFIG_HAVE_FUNCTION_TRACER=y
+CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
+CONFIG_HAVE_FUNCTION_GRAPH_FP_TEST=y
+CONFIG_HAVE_DYNAMIC_FTRACE=y
+CONFIG_HAVE_DYNAMIC_FTRACE_WITH_REGS=y
+CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
+CONFIG_HAVE_SYSCALL_TRACEPOINTS=y
+CONFIG_HAVE_FENTRY=y
+CONFIG_HAVE_C_RECORDMCOUNT=y
+CONFIG_TRACING_SUPPORT=y
+CONFIG_FTRACE=y
+# CONFIG_FUNCTION_TRACER is not set
+# CONFIG_IRQSOFF_TRACER is not set
+# CONFIG_SCHED_TRACER is not set
+# CONFIG_ENABLE_DEFAULT_TRACERS is not set
+# CONFIG_FTRACE_SYSCALLS is not set
+# CONFIG_TRACER_SNAPSHOT is not set
+CONFIG_BRANCH_PROFILE_NONE=y
+# CONFIG_PROFILE_ANNOTATED_BRANCHES is not set
+# CONFIG_PROFILE_ALL_BRANCHES is not set
+# CONFIG_STACK_TRACER is not set
+# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_UPROBE_EVENT is not set
+# CONFIG_PROBE_EVENTS is not set
+# CONFIG_MMIOTRACE is not set
+# CONFIG_TRACEPOINT_BENCHMARK is not set
+
+#
+# Runtime Testing
+#
+# CONFIG_TEST_LIST_SORT is not set
+# CONFIG_BACKTRACE_SELF_TEST is not set
+# CONFIG_RBTREE_TEST is not set
+# CONFIG_ATOMIC64_SELFTEST is not set
+# CONFIG_TEST_STRING_HELPERS is not set
+# CONFIG_TEST_KSTRTOX is not set
+# CONFIG_TEST_RHASHTABLE is not set
+# CONFIG_PROVIDE_OHCI1394_DMA_INIT is not set
+# CONFIG_DMA_API_DEBUG is not set
+# CONFIG_TEST_FIRMWARE is not set
+# CONFIG_TEST_UDELAY is not set
+# CONFIG_SAMPLES is not set
+CONFIG_HAVE_ARCH_KGDB=y
+# CONFIG_KGDB is not set
+# CONFIG_STRICT_DEVMEM is not set
+CONFIG_X86_VERBOSE_BOOTUP=y
+CONFIG_EARLY_PRINTK=y
+# CONFIG_EARLY_PRINTK_DBGP is not set
+# CONFIG_X86_PTDUMP is not set
+CONFIG_DEBUG_RODATA=y
+CONFIG_DEBUG_RODATA_TEST=y
+CONFIG_DOUBLEFAULT=y
+# CONFIG_DEBUG_TLBFLUSH is not set
+# CONFIG_IOMMU_DEBUG is not set
+# CONFIG_IOMMU_STRESS is not set
+CONFIG_HAVE_MMIOTRACE_SUPPORT=y
+CONFIG_IO_DELAY_TYPE_0X80=0
+CONFIG_IO_DELAY_TYPE_0XED=1
+CONFIG_IO_DELAY_TYPE_UDELAY=2
+CONFIG_IO_DELAY_TYPE_NONE=3
+CONFIG_IO_DELAY_0X80=y
+# CONFIG_IO_DELAY_0XED is not set
+# CONFIG_IO_DELAY_UDELAY is not set
+# CONFIG_IO_DELAY_NONE is not set
+CONFIG_DEFAULT_IO_DELAY_TYPE=0
+# CONFIG_CPA_DEBUG is not set
+# CONFIG_OPTIMIZE_INLINING is not set
+# CONFIG_DEBUG_NMI_SELFTEST is not set
+# CONFIG_X86_DEBUG_STATIC_CPU_HAS is not set
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+# CONFIG_SECURITY_DMESG_RESTRICT is not set
+# CONFIG_SECURITY is not set
+# CONFIG_SECURITYFS is not set
+CONFIG_DEFAULT_SECURITY_DAC=y
+CONFIG_DEFAULT_SECURITY=""
+CONFIG_CRYPTO=y
+
+#
+# Crypto core or helper
+#
+CONFIG_CRYPTO_ALGAPI=y
+CONFIG_CRYPTO_ALGAPI2=y
+CONFIG_CRYPTO_AEAD=y
+CONFIG_CRYPTO_AEAD2=y
+CONFIG_CRYPTO_BLKCIPHER=y
+CONFIG_CRYPTO_BLKCIPHER2=y
+CONFIG_CRYPTO_HASH=y
+CONFIG_CRYPTO_HASH2=y
+CONFIG_CRYPTO_RNG=y
+CONFIG_CRYPTO_RNG2=y
+CONFIG_CRYPTO_PCOMP=y
+CONFIG_CRYPTO_PCOMP2=y
+CONFIG_CRYPTO_MANAGER=y
+CONFIG_CRYPTO_MANAGER2=y
+CONFIG_CRYPTO_USER=y
+CONFIG_CRYPTO_MANAGER_DISABLE_TESTS=y
+CONFIG_CRYPTO_GF128MUL=y
+CONFIG_CRYPTO_NULL=y
+CONFIG_CRYPTO_WORKQUEUE=y
+CONFIG_CRYPTO_CRYPTD=y
+# CONFIG_CRYPTO_MCRYPTD is not set
+CONFIG_CRYPTO_AUTHENC=y
+CONFIG_CRYPTO_ABLK_HELPER=y
+CONFIG_CRYPTO_GLUE_HELPER_X86=y
+
+#
+# Authenticated Encryption with Associated Data
+#
+CONFIG_CRYPTO_CCM=y
+CONFIG_CRYPTO_GCM=y
+CONFIG_CRYPTO_SEQIV=y
+
+#
+# Block modes
+#
+CONFIG_CRYPTO_CBC=y
+CONFIG_CRYPTO_CTR=y
+# CONFIG_CRYPTO_CTS is not set
+CONFIG_CRYPTO_ECB=y
+CONFIG_CRYPTO_LRW=y
+CONFIG_CRYPTO_PCBC=y
+CONFIG_CRYPTO_XTS=y
+
+#
+# Hash modes
+#
+CONFIG_CRYPTO_CMAC=y
+CONFIG_CRYPTO_HMAC=y
+CONFIG_CRYPTO_XCBC=y
+# CONFIG_CRYPTO_VMAC is not set
+
+#
+# Digest
+#
+CONFIG_CRYPTO_CRC32C=y
+# CONFIG_CRYPTO_CRC32C_INTEL is not set
+# CONFIG_CRYPTO_CRC32 is not set
+# CONFIG_CRYPTO_CRC32_PCLMUL is not set
+# CONFIG_CRYPTO_CRCT10DIF is not set
+CONFIG_CRYPTO_GHASH=y
+CONFIG_CRYPTO_MD4=y
+CONFIG_CRYPTO_MD5=y
+CONFIG_CRYPTO_MICHAEL_MIC=y
+CONFIG_CRYPTO_RMD128=y
+CONFIG_CRYPTO_RMD160=y
+CONFIG_CRYPTO_RMD256=y
+CONFIG_CRYPTO_RMD320=y
+CONFIG_CRYPTO_SHA1=y
+# CONFIG_CRYPTO_SHA1_SSSE3 is not set
+CONFIG_CRYPTO_SHA256_SSSE3=y
+CONFIG_CRYPTO_SHA512_SSSE3=y
+# CONFIG_CRYPTO_SHA1_MB is not set
+CONFIG_CRYPTO_SHA256=y
+CONFIG_CRYPTO_SHA512=y
+CONFIG_CRYPTO_TGR192=y
+CONFIG_CRYPTO_WP512=y
+# CONFIG_CRYPTO_GHASH_CLMUL_NI_INTEL is not set
+
+#
+# Ciphers
+#
+CONFIG_CRYPTO_AES=y
+CONFIG_CRYPTO_AES_X86_64=y
+CONFIG_CRYPTO_AES_NI_INTEL=y
+CONFIG_CRYPTO_ANUBIS=y
+CONFIG_CRYPTO_ARC4=y
+CONFIG_CRYPTO_BLOWFISH=y
+CONFIG_CRYPTO_BLOWFISH_COMMON=y
+CONFIG_CRYPTO_BLOWFISH_X86_64=y
+CONFIG_CRYPTO_CAMELLIA=y
+CONFIG_CRYPTO_CAMELLIA_X86_64=y
+CONFIG_CRYPTO_CAMELLIA_AESNI_AVX_X86_64=y
+CONFIG_CRYPTO_CAMELLIA_AESNI_AVX2_X86_64=y
+CONFIG_CRYPTO_CAST_COMMON=y
+CONFIG_CRYPTO_CAST5=y
+CONFIG_CRYPTO_CAST5_AVX_X86_64=y
+CONFIG_CRYPTO_CAST6=y
+CONFIG_CRYPTO_CAST6_AVX_X86_64=y
+CONFIG_CRYPTO_DES=y
+# CONFIG_CRYPTO_DES3_EDE_X86_64 is not set
+CONFIG_CRYPTO_FCRYPT=y
+CONFIG_CRYPTO_KHAZAD=y
+CONFIG_CRYPTO_SALSA20=y
+CONFIG_CRYPTO_SALSA20_X86_64=y
+CONFIG_CRYPTO_SEED=y
+CONFIG_CRYPTO_SERPENT=y
+CONFIG_CRYPTO_SERPENT_SSE2_X86_64=y
+CONFIG_CRYPTO_SERPENT_AVX_X86_64=y
+CONFIG_CRYPTO_SERPENT_AVX2_X86_64=y
+CONFIG_CRYPTO_TEA=y
+CONFIG_CRYPTO_TWOFISH=y
+CONFIG_CRYPTO_TWOFISH_COMMON=y
+CONFIG_CRYPTO_TWOFISH_X86_64=y
+CONFIG_CRYPTO_TWOFISH_X86_64_3WAY=y
+CONFIG_CRYPTO_TWOFISH_AVX_X86_64=y
+
+#
+# Compression
+#
+CONFIG_CRYPTO_DEFLATE=y
+CONFIG_CRYPTO_ZLIB=y
+CONFIG_CRYPTO_LZO=y
+CONFIG_CRYPTO_LZ4=y
+CONFIG_CRYPTO_LZ4HC=y
+
+#
+# Random Number Generation
+#
+# CONFIG_CRYPTO_ANSI_CPRNG is not set
+# CONFIG_CRYPTO_DRBG_MENU is not set
+CONFIG_CRYPTO_USER_API=y
+CONFIG_CRYPTO_USER_API_HASH=y
+CONFIG_CRYPTO_USER_API_SKCIPHER=y
+# CONFIG_CRYPTO_HW is not set
+CONFIG_HAVE_KVM=y
+CONFIG_VIRTUALIZATION=y
+# CONFIG_KVM is not set
+# CONFIG_BINARY_PRINTF is not set
+
+#
+# Library routines
+#
+CONFIG_BITREVERSE=y
+CONFIG_GENERIC_STRNCPY_FROM_USER=y
+CONFIG_GENERIC_STRNLEN_USER=y
+CONFIG_GENERIC_NET_UTILS=y
+CONFIG_GENERIC_FIND_FIRST_BIT=y
+CONFIG_GENERIC_PCI_IOMAP=y
+CONFIG_GENERIC_IOMAP=y
+CONFIG_GENERIC_IO=y
+CONFIG_ARCH_USE_CMPXCHG_LOCKREF=y
+CONFIG_ARCH_HAS_FAST_MULTIPLIER=y
+CONFIG_CRC_CCITT=y
+CONFIG_CRC16=y
+# CONFIG_CRC_T10DIF is not set
+CONFIG_CRC_ITU_T=y
+CONFIG_CRC32=y
+# CONFIG_CRC32_SELFTEST is not set
+CONFIG_CRC32_SLICEBY8=y
+# CONFIG_CRC32_SLICEBY4 is not set
+# CONFIG_CRC32_SARWATE is not set
+# CONFIG_CRC32_BIT is not set
+CONFIG_CRC7=y
+CONFIG_LIBCRC32C=y
+# CONFIG_CRC8 is not set
+# CONFIG_AUDIT_ARCH_COMPAT_GENERIC is not set
+# CONFIG_RANDOM32_SELFTEST is not set
+CONFIG_ZLIB_INFLATE=y
+CONFIG_ZLIB_DEFLATE=y
+CONFIG_LZO_COMPRESS=y
+CONFIG_LZO_DECOMPRESS=y
+CONFIG_LZ4_COMPRESS=y
+CONFIG_LZ4HC_COMPRESS=y
+CONFIG_LZ4_DECOMPRESS=y
+# CONFIG_XZ_DEC is not set
+# CONFIG_XZ_DEC_BCJ is not set
+CONFIG_TEXTSEARCH=y
+CONFIG_TEXTSEARCH_KMP=y
+CONFIG_TEXTSEARCH_BM=y
+CONFIG_TEXTSEARCH_FSM=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT_MAP=y
+CONFIG_HAS_DMA=y
+CONFIG_DQL=y
+CONFIG_NLATTR=y
+CONFIG_ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE=y
+CONFIG_AVERAGE=y
+# CONFIG_CORDIC is not set
+# CONFIG_DDR is not set
+CONFIG_ARCH_HAS_SG_CHAIN=y
diff --git a/testing/hosts/winnetou/etc/openssl/bliss/strongswan_blissCert.der b/testing/hosts/winnetou/etc/openssl/bliss/strongswan_blissCert.der
new file mode 100644
index 0000000..cbc7e09
Binary files /dev/null and b/testing/hosts/winnetou/etc/openssl/bliss/strongswan_blissCert.der differ
diff --git a/testing/hosts/winnetou/etc/openssl/bliss/strongswan_blissKey.der b/testing/hosts/winnetou/etc/openssl/bliss/strongswan_blissKey.der
new file mode 100644
index 0000000..76cafc1
Binary files /dev/null and b/testing/hosts/winnetou/etc/openssl/bliss/strongswan_blissKey.der differ
diff --git a/testing/hosts/winnetou/etc/openssl/certs/rfc3779/0b5362afd8838bafb66c854732b490d5d8318261 b/testing/hosts/winnetou/etc/openssl/certs/rfc3779/0b5362afd8838bafb66c854732b490d5d8318261
deleted file mode 100644
index c987753..0000000
Binary files a/testing/hosts/winnetou/etc/openssl/certs/rfc3779/0b5362afd8838bafb66c854732b490d5d8318261 and /dev/null differ
diff --git a/testing/hosts/winnetou/etc/openssl/certs/rfc3779/35ef6b73537e090d3b09359bfee642eafa6192eb b/testing/hosts/winnetou/etc/openssl/certs/rfc3779/35ef6b73537e090d3b09359bfee642eafa6192eb
new file mode 100644
index 0000000..016c412
Binary files /dev/null and b/testing/hosts/winnetou/etc/openssl/certs/rfc3779/35ef6b73537e090d3b09359bfee642eafa6192eb differ
diff --git a/testing/hosts/winnetou/etc/openssl/certs/rfc3779/533394399c61128c957881790d70511537798da1 b/testing/hosts/winnetou/etc/openssl/certs/rfc3779/533394399c61128c957881790d70511537798da1
deleted file mode 100644
index 0f2a0ec..0000000
Binary files a/testing/hosts/winnetou/etc/openssl/certs/rfc3779/533394399c61128c957881790d70511537798da1 and /dev/null differ
diff --git a/testing/hosts/winnetou/etc/openssl/certs/rfc3779/6645da3911d7f86e5410b698e2a441f1e2e4491a b/testing/hosts/winnetou/etc/openssl/certs/rfc3779/6645da3911d7f86e5410b698e2a441f1e2e4491a
new file mode 100644
index 0000000..1a40299
Binary files /dev/null and b/testing/hosts/winnetou/etc/openssl/certs/rfc3779/6645da3911d7f86e5410b698e2a441f1e2e4491a differ
diff --git a/testing/hosts/winnetou/etc/openssl/certs/rfc3779/6b5aec8fe9dcb8d0f707490abc84ab0890a7d2da b/testing/hosts/winnetou/etc/openssl/certs/rfc3779/6b5aec8fe9dcb8d0f707490abc84ab0890a7d2da
deleted file mode 100644
index 489030d..0000000
Binary files a/testing/hosts/winnetou/etc/openssl/certs/rfc3779/6b5aec8fe9dcb8d0f707490abc84ab0890a7d2da and /dev/null differ
diff --git a/testing/hosts/winnetou/etc/openssl/certs/rfc3779/b8a73c3433f4e341cc7c4ae42989f0a23a956488 b/testing/hosts/winnetou/etc/openssl/certs/rfc3779/b8a73c3433f4e341cc7c4ae42989f0a23a956488
deleted file mode 100644
index 863f652..0000000
Binary files a/testing/hosts/winnetou/etc/openssl/certs/rfc3779/b8a73c3433f4e341cc7c4ae42989f0a23a956488 and /dev/null differ
diff --git a/testing/hosts/winnetou/etc/openssl/certs/rfc3779/e2d52f0f42f61f786f1c570a4acc8fa8d72a329f b/testing/hosts/winnetou/etc/openssl/certs/rfc3779/e2d52f0f42f61f786f1c570a4acc8fa8d72a329f
new file mode 100644
index 0000000..49f4ad7
Binary files /dev/null and b/testing/hosts/winnetou/etc/openssl/certs/rfc3779/e2d52f0f42f61f786f1c570a4acc8fa8d72a329f differ
diff --git a/testing/hosts/winnetou/etc/openssl/certs/rfc3779/f22389d26d00a7ddb5ff61f3b2e66022b18b2e3d b/testing/hosts/winnetou/etc/openssl/certs/rfc3779/f22389d26d00a7ddb5ff61f3b2e66022b18b2e3d
new file mode 100644
index 0000000..267516b
Binary files /dev/null and b/testing/hosts/winnetou/etc/openssl/certs/rfc3779/f22389d26d00a7ddb5ff61f3b2e66022b18b2e3d differ
diff --git a/testing/hosts/winnetou/etc/openssl/duck/duckCert.pem b/testing/hosts/winnetou/etc/openssl/duck/duckCert.pem
index bb205a0..2076242 100644
--- a/testing/hosts/winnetou/etc/openssl/duck/duckCert.pem
+++ b/testing/hosts/winnetou/etc/openssl/duck/duckCert.pem
@@ -1,23 +1,23 @@
 -----BEGIN CERTIFICATE-----
-MIID0jCCArqgAwIBAgIBBTANBgkqhkiG9w0BAQsFADBRMQswCQYDVQQGEwJDSDEZ
+MIID0jCCArqgAwIBAgIBCjANBgkqhkiG9w0BAQsFADBRMQswCQYDVQQGEwJDSDEZ
 MBcGA1UEChMQTGludXggc3Ryb25nU3dhbjERMA8GA1UECxMIUmVzZWFyY2gxFDAS
-BgNVBAMTC1Jlc2VhcmNoIENBMB4XDTA5MTEwNDE2MTUwM1oXDTE1MTEwMzE2MTUw
-M1owVjELMAkGA1UEBhMCQ0gxGTAXBgNVBAoTEExpbnV4IHN0cm9uZ1N3YW4xETAP
+BgNVBAMTC1Jlc2VhcmNoIENBMB4XDTE0MTEyODIyMDcwOFoXDTE5MDQwMTIyMDcw
+OFowVjELMAkGA1UEBhMCQ0gxGTAXBgNVBAoTEExpbnV4IHN0cm9uZ1N3YW4xETAP
 BgNVBAsTCFJlc2VhcmNoMRkwFwYDVQQDExBEdWNrIFJlc2VhcmNoIENBMIIBIjAN
-BgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEApIBRSgHCxHhMjsVZo4PtFnENkHNu
-MfyRDsc7m1KRDVt8N4h/EcbduU7xeq/RjxZSmlc1q6EWEgDv3KwDYY0sX+qrpQKa
-ub5AgsRa2fOOR9xfyf0Q7Nc3oR3keWqQUiigCuaw9NQRtdMm/JFdXLNY3r60tBsO
-UHOJAPZNoGPey5UL9ZjjsN6ROUVTh0NAkFwkmnTRwmUvY5bi/T7ulsSkO9BrfqKD
-h/pliP7uZANd0ZpPcrIc68WwrelpI1zu0kYGqu/y8HZpuPuAXtGqS2jctrjSieeY
-i9wFLnS2tgV3ID4LzEEICSeqVqOvYgGKbarqLkARdxmdRKM9QYpu+5J+YQIDAQAB
-o4GvMIGsMA8GA1UdEwEB/wQFMAMBAf8wCwYDVR0PBAQDAgEGMB0GA1UdDgQWBBR2
-KqikMafGcY8wJbwCZpvLF1SNIDBtBgNVHSMEZjBkgBTndfCg8q0gzc1gI8zHyA8p
+BgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAu984h2mkpbWJZc9Ydka6jC84EkPz
+w6tqtEkIdftEawgc5gvlC80JXLTwnQySMTb49KByyt44S59ZWE6SHHV0u2P2ihiw
+1duoY7NE+RZwODEsWVgnDRZmyume2Bj+Hpkugm6o+rL7jiGxhvNLeoFZK3RyD6IR
+IcEfZeAv7URGz7xdrzmK/vWXukfEnU8DlrFDSQUb3NaJS5tVVVLFuTWQBSjuT3NX
+7mdNHnpjcwT9/ruyOaNQ0DV2Bgz1nCiOup+oW396/AInb03CQ+wIqQpB9reWma0w
+F0Bc9lZxnv9ppYgBPsOTjE3yyyeTptzk9Gw+DFV1cw8Crm+aew5VH18oEwIDAQAB
+o4GvMIGsMA8GA1UdEwEB/wQFMAMBAf8wCwYDVR0PBAQDAgEGMB0GA1UdDgQWBBSK
+cODKpRxkbyuSuXNcAayQG/35NTBtBgNVHSMEZjBkgBTndfCg8q0gzc1gI8zHyA8p
 891UIKFJpEcwRTELMAkGA1UEBhMCQ0gxGTAXBgNVBAoTEExpbnV4IHN0cm9uZ1N3
-YW4xGzAZBgNVBAMTEnN0cm9uZ1N3YW4gUm9vdCBDQYIBDzANBgkqhkiG9w0BAQsF
-AAOCAQEAsHR1vDlz2sPQpD9xnt1PL4qX7XWSSM6d+QG3cjdiKCjH8t78ecEm1duv
-YozLg6SYHGUF9qYuPz2SAZjQjmIWLlkQpBfQm8/orG+jbsQl5HkXFYX0UWAKZFGx
-rjHnOzmQxnmIWHky4uMDT/UmhmWy6kuCmZbKeeOqkBR2gVxfLyzelTSbF4ntEm1C
-1XqqtM4OfTOD5QUPD+6rZ5RoIPId9+2A8pJ2NyCUCf47FbkmYzU5+oiChhcGzsC5
-wDlgP32NA88kSiSJ2p2ZveYveRqcyZXZDAiTxRaIwJY0bt2Dk4wKicvy6vPdLA5v
-DSlBqDpnqK8tEI9V9YeroihTcygrEg==
+YW4xGzAZBgNVBAMTEnN0cm9uZ1N3YW4gUm9vdCBDQYIBIDANBgkqhkiG9w0BAQsF
+AAOCAQEAMtm7ldvd45818Ghl8+Z7PfCnRXDPbikyCJn5PXkuR3TSB62ekJSGT1Rd
+i2rnDoIZpfSzDQSpKH616MuWtwJoomJh8n9wCzbdUv1sn1cfgjDSkgLqIbm/Xpc4
+zUcHnZFdwvMr3sq/xSO/SgkfgTHi8bFLLp2RQwPNsNycT94nNE7DRjSeRenpuEPM
+4t4xIZCoUyX3sdusHvh+dDu4iuIVQoM0zaW9p7pVh210ALt0jac3HW0rQXtbfchE
+VeuDLZ0G7baFZ9LLLWpuQB4zPRUET7puvzabsf+sHpO54y+zXRaB0tbiFIurt4gF
+5n7mN4ssNQdcD86W5lnI9pT5s1uvdw==
 -----END CERTIFICATE-----
diff --git a/testing/hosts/winnetou/etc/openssl/duck/duckKey.pem b/testing/hosts/winnetou/etc/openssl/duck/duckKey.pem
index 5fff907..a5b46cc 100644
--- a/testing/hosts/winnetou/etc/openssl/duck/duckKey.pem
+++ b/testing/hosts/winnetou/etc/openssl/duck/duckKey.pem
@@ -1,27 +1,27 @@
 -----BEGIN RSA PRIVATE KEY-----
-MIIEpQIBAAKCAQEApIBRSgHCxHhMjsVZo4PtFnENkHNuMfyRDsc7m1KRDVt8N4h/
-EcbduU7xeq/RjxZSmlc1q6EWEgDv3KwDYY0sX+qrpQKaub5AgsRa2fOOR9xfyf0Q
-7Nc3oR3keWqQUiigCuaw9NQRtdMm/JFdXLNY3r60tBsOUHOJAPZNoGPey5UL9Zjj
-sN6ROUVTh0NAkFwkmnTRwmUvY5bi/T7ulsSkO9BrfqKDh/pliP7uZANd0ZpPcrIc
-68WwrelpI1zu0kYGqu/y8HZpuPuAXtGqS2jctrjSieeYi9wFLnS2tgV3ID4LzEEI
-CSeqVqOvYgGKbarqLkARdxmdRKM9QYpu+5J+YQIDAQABAoIBADfb0r6cpnRsnSKF
-5RBfReyu6vo4GB0lNGSeRqFRgivU+vMoiG2S58t7AQi2FyTNYbNDFdh31LS8WLbI
-OkWv2HehijN4FO4pqmI9JtSHnbLNJEHEizDBTASLz/9irisX3HCXMVORh4oEb2Ko
-QdmulOjePSJDZbLv6H/JI0bpYsgiAw26KEoB8cnHwiApF69a4uPJA6gW98nsabyq
-9NQVW5QAmUFDnzA6upFRBUeBBpufYMvP82zfntFx72yLBmXgBnyZW23WwZfQZSzw
-FChhl40mwykOE8jpeGgxmdWyPc29roF+kuvaOUaSF2nmyl4qhLCISdr0eHXHAGDH
-2RjVJ6ECgYEA0YW38d4309J1QegK5vhPWehnxpZHpK86DENevYaS7zRcCu1BRZc0
-aBAceTYCZHYofOWmeIns0qtMfzzuemPCiOZWy9VYgJrJ0YkmNin3DM1/13pWiKqn
-EkQCFa6K5AiB0umTOwJoAHlJYlJ2k4bw7Rm/LtiHC2fnRq2KJeKmg60CgYEAyP30
-5D8sUkih9rRfZRHAPo0x1qJpJQC+cFUBMIuOXFIz37TqbZcGDkRRb+ewywNxT73t
-TfVDvR7tD3cYTi78dVz539Dwl9mt10QLGsQJ4825uY/LQqUe8F2qz+E3lWqoo+yJ
-WlTAqbHI2a4g4CjFC4/+i6lKQ+NpmJLZIPz3HAUCgYEAiduy4Ti2gPAb6OZ1re05
-wM1y4q5kq04EIqd9QbS3Hx7TZPkgllpbyBC5u2M3BcTc9PjhpLQTl7XQGnQL8YmM
-KSlteKaCmfO+0NitxLut6sWX1T6Qi1HFpfYLbRqwFkQmr5CyKAR4S7+B8miRzpXe
-FhN3wKoFiRKvkMiEelL7/u0CgYEAnh4TWsBL+MuFBxTs+xDU4SCotYZ9GwwTxUFK
-N0uCiiRtBK9JwT8PF4gtXNCzZ3Jk4Ou0VSD+0jgTHJh/eXpDR30GYkn4DC3GMdQo
-vDy+3wSH+HAj4mEODuBRMUqnNJd85cB+aZ7FFnpzXLQ8zrukEC2OfYaHkxLDjrDv
-uaDoMZUCgYEAhD89Cj849LXbJEmjX0MGUCCBO9EBR2Ux2nbuB+TQnvwz7VT0Jkds
-Db1IfljoDefqzyFfH/0Z3bNg4EpidAG3BMC4MwY7WzR1rfnXwNluaWM5gmUzFNw0
-mBGXonIf6nRMIO9eeTFI8VfFb6BYvosNxz+9QA/5rpamGN1cKdMjgPc=
+MIIEpQIBAAKCAQEAu984h2mkpbWJZc9Ydka6jC84EkPzw6tqtEkIdftEawgc5gvl
+C80JXLTwnQySMTb49KByyt44S59ZWE6SHHV0u2P2ihiw1duoY7NE+RZwODEsWVgn
+DRZmyume2Bj+Hpkugm6o+rL7jiGxhvNLeoFZK3RyD6IRIcEfZeAv7URGz7xdrzmK
+/vWXukfEnU8DlrFDSQUb3NaJS5tVVVLFuTWQBSjuT3NX7mdNHnpjcwT9/ruyOaNQ
+0DV2Bgz1nCiOup+oW396/AInb03CQ+wIqQpB9reWma0wF0Bc9lZxnv9ppYgBPsOT
+jE3yyyeTptzk9Gw+DFV1cw8Crm+aew5VH18oEwIDAQABAoIBADxEv72xBkCinBEt
+ExPeXLnb7ADwC6MZuoFbbHtsv+YWFC84YaIHhJlY8ldvUPa4y+SuFCVAZI7d76uE
+iRrYEzqKNuzWPuRcMwjI2beOmzFrlO6UePKZ3R/7EhoA6oSmX2U4Wr0R7eEKrgi8
+w9no5NIr6Ota8mQBsDDeWoGjBZReLHcagK3P+LG7B9EfMbdedd4c+sAYypmbhjvf
+pj2AE08D/eI1j9Jd0w9J4oVNel1p7iYT5wYnZzdHcJdAWHlzFrKFQVVfJBBviskX
+dm8GUOP0ZdOc0xYAyVcFAyu1x0JBkrFM5zOs6UAsRSzP5PQ/J8VFK7BQAv9/TX1D
+eZi2DwECgYEA3mPpG0VRsZXDF63KlWnCn7cl6i+CAhMxYVCVn8RwBGc7Q8Xtw+9b
+y7VktDGTcgcZIxDh/T17FBAn2ZL28tbssRxnRD+lQG1pf86RKLU+HXQ4Ppt7CbA0
+G2oV7+qxA2At3yknHmeIyvzBp+OuCc2XboOhshN5ncgMXl9EzRsCilUCgYEA2EPT
+dXf57rG4k9mcjdohIdutBB+mOXS8K9fbg+V/l+bmGxINWKxF4w2N3pulw4380TRr
+caYI7dxjpmCopnxNEhBiyOuBOEEqdGxdm69CNSO/hFDE92pQECl+6+AIa9Kv/Z3+
+Wdxwo447xgz1wDclhEcVW9rD6sAshpLQREOvIMcCgYEAjxrDmeTVWO0CCW6v+c2A
+i74TC8teYW9wSyrL3W9OlcbIACiRg4+3BjLHhpyQQMQIjOQESC0T0ilDO2KyvjlH
+PgEFAoniEL9XMAMAra1TNyjeOItcdTOJlEqDq0redUmiuwOERLBi+hwDkcGU8IH3
+fAoANtMJY1qjeubbIxDKZbECgYEAleJkMtzFBq57m1TNkO6l2d5zShFZVibWp5hC
+Fma/iJrJzec0Asna4eMp+Sdsuly05JVtBeYp+Bivo8cH++LYU3Wx0UiPVVqsvuW/
+9r9/pm6xNFX6PPOcq6bmxTmO/JOXz7FpcAQ8uM5CFSA0TlSqFsRhRDkZYaBw+4/S
+8gzq2k8CgYEAz/0eK0YPxxh4NHwXVWEsMeTDmC37BmoXU5oOmcgFHmhWXFSvvJLn
+OB5QojTUuEsU9soHqk8F5oCt8DTz/LkJt+lygcSZ+qDOLJ0c9fGxDIp0s3HxiX4G
+BwiYDDqLzFNi6TOQsk15rWWVC9W+PaxsfkrdewvW4ZT695ZWxsKAHP8=
 -----END RSA PRIVATE KEY-----
diff --git a/testing/hosts/winnetou/etc/openssl/duck/index.txt b/testing/hosts/winnetou/etc/openssl/duck/index.txt
index 759a85b..70a88fc 100644
--- a/testing/hosts/winnetou/etc/openssl/duck/index.txt
+++ b/testing/hosts/winnetou/etc/openssl/duck/index.txt
@@ -1 +1 @@
-V	141103162335Z		01	unknown	/C=CH/O=Linux strongSwan/OU=Duck Research/CN=carol at strongswan.org
+V	190225221822Z		01	unknown	/C=CH/O=Linux strongSwan/OU=Duck Research/CN=carol at strongswan.org
diff --git a/testing/hosts/winnetou/etc/openssl/duck/newcerts/01.pem b/testing/hosts/winnetou/etc/openssl/duck/newcerts/01.pem
index 4e13b52..70b953e 100644
--- a/testing/hosts/winnetou/etc/openssl/duck/newcerts/01.pem
+++ b/testing/hosts/winnetou/etc/openssl/duck/newcerts/01.pem
@@ -1,24 +1,24 @@
 -----BEGIN CERTIFICATE-----
 MIIEBzCCAu+gAwIBAgIBATANBgkqhkiG9w0BAQsFADBWMQswCQYDVQQGEwJDSDEZ
 MBcGA1UEChMQTGludXggc3Ryb25nU3dhbjERMA8GA1UECxMIUmVzZWFyY2gxGTAX
-BgNVBAMTEER1Y2sgUmVzZWFyY2ggQ0EwHhcNMDkxMTA0MTYyMzM1WhcNMTQxMTAz
-MTYyMzM1WjBfMQswCQYDVQQGEwJDSDEZMBcGA1UEChMQTGludXggc3Ryb25nU3dh
+BgNVBAMTEER1Y2sgUmVzZWFyY2ggQ0EwHhcNMTQxMTI4MjIxODIyWhcNMTkwMjI1
+MjIxODIyWjBfMQswCQYDVQQGEwJDSDEZMBcGA1UEChMQTGludXggc3Ryb25nU3dh
 bjEWMBQGA1UECxMNRHVjayBSZXNlYXJjaDEdMBsGA1UEAxQUY2Fyb2xAc3Ryb25n
-c3dhbi5vcmcwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC6LueCi67Y
-IGRDKP5bkysGWZHrFrztq7elIFCPPSUxyIOYo4Upzr5WsvO0dIfcZY3agV2NcAI2
-30sATlfTUp+obedZMHbzE3VBvQuLjgK42ox2XIXDj23Vy496mVqlwUQulhBcAhMb
-jnBb4T0aR7WCnJvfzyckEyWrTN0ajRyQhJEmTn+spYNQX/2lg6hEn/K1T/3Py7sG
-veeF6BRenHR5L60NSK7qV7AU+hM4R0UIvgwYqzxSStgGS9G6Bwj9QTOWwSV1tuii
-ABiRdZSBoON0uMMpRjgEzuVe0f4VbOCIEXO8MtdpCu7Rwa9tc8OwneLcGCYVomr5
-7KKRJdvC5As3AgMBAAGjgdYwgdMwCQYDVR0TBAIwADALBgNVHQ8EBAMCA6gwHQYD
-VR0OBBYEFFSYDz2TYOMxfyrIx20NhPPHTCOIMHkGA1UdIwRyMHCAFHYqqKQxp8Zx
-jzAlvAJmm8sXVI0goVWkUzBRMQswCQYDVQQGEwJDSDEZMBcGA1UEChMQTGludXgg
+c3dhbi5vcmcwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDNBbHnfLRk
+Lvxh9V7x/NoSs5qavpr8F51LnYpIfppgMvBDjpdeSnBPOOPakPlfUhKSvXIesESv
+QI1HJOlGftswL9A5B1lTnsH65sqpgqgj67grh386U3O9ZccFhUj8Dw6TUo/qe4pK
+sWDwUX/LG3mjOx/rOGvX8WxvZU7JVXXhU4g8TpIV3JRTQ+lF82z3qoS6dAfRt4xh
+6pyLuMYbu6UtX5Al0iJDvpsWr9ZbKI2f8Dhkr0sZFRHl7Gs5jTN1Ra1EF0jCjIzo
+6AkkY+ITBssvVvMFpeN/jb0ZhvLcRFU56lvLkmrj/InKUsk9qNm80+/wFBUzJ5N7
+GezXmBIPwXdlAgMBAAGjgdYwgdMwCQYDVR0TBAIwADALBgNVHQ8EBAMCA6gwHQYD
+VR0OBBYEFLPw4VsFnIRIKhjd/OF7delHM9kiMHkGA1UdIwRyMHCAFIpw4MqlHGRv
+K5K5c1wBrJAb/fk1oVWkUzBRMQswCQYDVQQGEwJDSDEZMBcGA1UEChMQTGludXgg
 c3Ryb25nU3dhbjERMA8GA1UECxMIUmVzZWFyY2gxFDASBgNVBAMTC1Jlc2VhcmNo
-IENBggEFMB8GA1UdEQQYMBaBFGNhcm9sQHN0cm9uZ3N3YW4ub3JnMA0GCSqGSIb3
-DQEBCwUAA4IBAQBIpl8SH4Nytgr6KvmXzns80u615WnDmP6oJrnwIZUkunVns8HH
-TFUVjvDKoQ+8CvuaH9Ifo2dokGjtGObeO4Y38y0xBIkUO+JpwfTa3SeCEhdOZb3G
-4e9WxHhV9IGfRyPsXQG+3JpAMaHYH+PNKiv7RBTq6rGaHzvgUEXRMTbv/bJI+Fs6
-Yfd/XxIur/ftVh4dZocyC74MUyXy5tyZJkHe1aBszOa0iT1852fq93lNUQPQqw0O
-3q3Lg7CvbNSdWqeAMqUgeBqh6oQItY9Exrwh0tfuCsjZ0oWXUBghsuiV+GTmZ6ok
-BiGmSmtX5OD4UtKcicuMRqnK2MYJHp1z1goE
+IENBggEKMB8GA1UdEQQYMBaBFGNhcm9sQHN0cm9uZ3N3YW4ub3JnMA0GCSqGSIb3
+DQEBCwUAA4IBAQCi2vUHTZtkUGMAQsztQBLDwtqS7D+1ydO2BU/wkNRn4M7Zlkjq
+O2JBgwGmeWpnZWPdNo+A5ECqcVYXp0XQw/24zxV92StTN7mGvPKVM6bYExcCT8x6
+tVkzlfyjJaVdBgl12jkQA4v6Efwc0P6nunYfxYIrfoFA4kjMnAbxLfPKFEj8b8NW
+E9gvOEPy9hOv2dJEKyNxau+O5oGRZ46zSotcS0n34huoMEkXpUnpGOgZw8cl8xpP
+ffHiAJqZYgqU6B++HQO6M6IQ0nQmX6OxGz+5VhEmuizgWB0B1L65BlzAysdavLZN
+Yn4RdcYfpdbUgj5oRapiwWaQxpGImyQ1JBIU
 -----END CERTIFICATE-----
diff --git a/testing/hosts/winnetou/etc/openssl/generate-crl b/testing/hosts/winnetou/etc/openssl/generate-crl
index 839816b..f064bdb 100755
--- a/testing/hosts/winnetou/etc/openssl/generate-crl
+++ b/testing/hosts/winnetou/etc/openssl/generate-crl
@@ -44,4 +44,6 @@ cd /etc/openssl/rfc3779
 openssl ca -gencrl -crldays 15 -config /etc/openssl/rfc3779/openssl.cnf -out crl.pem
 openssl crl -in crl.pem -outform der -out strongswan_rfc3779.crl
 cp strongswan_rfc3779.crl ${ROOT}
-
+cd /etc/openssl/bliss
+pki --signcrl --cacert strongswan_blissCert.der --cakey strongswan_blissKey.der --lifetime 30 --digest sha512 > strongswan_bliss.crl
+cp strongswan_bliss.crl ${ROOT}
diff --git a/testing/hosts/winnetou/etc/openssl/index.txt b/testing/hosts/winnetou/etc/openssl/index.txt
index 49264a5..ba3349c 100644
--- a/testing/hosts/winnetou/etc/openssl/index.txt
+++ b/testing/hosts/winnetou/etc/openssl/index.txt
@@ -27,7 +27,7 @@ R	140826100818Z	140827143358Z,superseded	1A	unknown	/C=CH/O=Linux strongSwan/OU=
 R	140826103106Z	090827103405Z,keyCompromise	1B	unknown	/C=CH/O=Linux strongSwan/OU=Research/CN=carol at strongswan.org
 R	140826103739Z	140827143427Z,superseded	1C	unknown	/C=CH/O=Linux strongSwan/OU=Accounting/CN=dave at strongswan.org
 R	140826104451Z	140827143432Z,superseded	1D	unknown	/C=CH/O=Linux strongSwan/OU=Research/CN=carol at strongswan.org
-V	141123125153Z		1E	unknown	/C=CH/O=Linux strongSwan/OU=OCSP Signing Authority/CN=ocsp.strongswan.org
+R	141123125153Z	141128194312Z,superseded	1E	unknown	/C=CH/O=Linux strongSwan/OU=OCSP Signing Authority/CN=ocsp.strongswan.org
 V	150226210530Z		1F	unknown	/C=CH/O=Linux strongSwan/OU=Authorization Authority/CN=aa at strongswan.org
 V	190404095350Z		20	unknown	/C=CH/O=Linux strongSwan/OU=Research/CN=Research CA
 V	190404095433Z		21	unknown	/C=CH/O=Linux strongSwan/OU=Sales/CN=Sales CA
@@ -47,3 +47,4 @@ V	190826145626Z		2E	unknown	/C=CH/O=Linux strongSwan/OU=Research/CN=bob at strongsw
 R	190826150222Z	140827150343Z,keyCompromise	2F	unknown	/C=CH/O=Linux strongSwan/OU=Research/CN=carol at strongswan.org
 V	190826150536Z		30	unknown	/C=CH/O=Linux strongSwan/OU=Research/CN=carol at strongswan.org
 V	190826151202Z		31	unknown	/C=CH/O=Linux strongSwan/OU=Accounting/CN=dave at strongswan.org
+V	191127201436Z		32	unknown	/C=CH/O=Linux strongSwan/OU=OCSP Signing Authority/CN=ocsp.strongswan.org
diff --git a/testing/hosts/winnetou/etc/openssl/index.txt.old b/testing/hosts/winnetou/etc/openssl/index.txt.old
index cd5ddfd..b3ff1c5 100644
--- a/testing/hosts/winnetou/etc/openssl/index.txt.old
+++ b/testing/hosts/winnetou/etc/openssl/index.txt.old
@@ -27,7 +27,7 @@ R	140826100818Z	140827143358Z,superseded	1A	unknown	/C=CH/O=Linux strongSwan/OU=
 R	140826103106Z	090827103405Z,keyCompromise	1B	unknown	/C=CH/O=Linux strongSwan/OU=Research/CN=carol at strongswan.org
 R	140826103739Z	140827143427Z,superseded	1C	unknown	/C=CH/O=Linux strongSwan/OU=Accounting/CN=dave at strongswan.org
 R	140826104451Z	140827143432Z,superseded	1D	unknown	/C=CH/O=Linux strongSwan/OU=Research/CN=carol at strongswan.org
-V	141123125153Z		1E	unknown	/C=CH/O=Linux strongSwan/OU=OCSP Signing Authority/CN=ocsp.strongswan.org
+R	141123125153Z	141128194312Z,superseded	1E	unknown	/C=CH/O=Linux strongSwan/OU=OCSP Signing Authority/CN=ocsp.strongswan.org
 V	150226210530Z		1F	unknown	/C=CH/O=Linux strongSwan/OU=Authorization Authority/CN=aa at strongswan.org
 V	190404095350Z		20	unknown	/C=CH/O=Linux strongSwan/OU=Research/CN=Research CA
 V	190404095433Z		21	unknown	/C=CH/O=Linux strongSwan/OU=Sales/CN=Sales CA
@@ -46,3 +46,4 @@ V	190826145436Z		2D	unknown	/C=CH/O=Linux strongSwan/OU=Sales/CN=alice at strongswa
 V	190826145626Z		2E	unknown	/C=CH/O=Linux strongSwan/OU=Research/CN=bob at strongswan.org
 R	190826150222Z	140827150343Z,keyCompromise	2F	unknown	/C=CH/O=Linux strongSwan/OU=Research/CN=carol at strongswan.org
 V	190826150536Z		30	unknown	/C=CH/O=Linux strongSwan/OU=Research/CN=carol at strongswan.org
+V	190826151202Z		31	unknown	/C=CH/O=Linux strongSwan/OU=Accounting/CN=dave at strongswan.org
diff --git a/testing/hosts/winnetou/etc/openssl/newcerts/32.pem b/testing/hosts/winnetou/etc/openssl/newcerts/32.pem
new file mode 100644
index 0000000..f7c90d3
--- /dev/null
+++ b/testing/hosts/winnetou/etc/openssl/newcerts/32.pem
@@ -0,0 +1,25 @@
+-----BEGIN CERTIFICATE-----
+MIIEQzCCAyugAwIBAgIBMjANBgkqhkiG9w0BAQsFADBFMQswCQYDVQQGEwJDSDEZ
+MBcGA1UEChMQTGludXggc3Ryb25nU3dhbjEbMBkGA1UEAxMSc3Ryb25nU3dhbiBS
+b290IENBMB4XDTE0MTEyODIwMTQzNloXDTE5MTEyNzIwMTQzNlowZzELMAkGA1UE
+BhMCQ0gxGTAXBgNVBAoTEExpbnV4IHN0cm9uZ1N3YW4xHzAdBgNVBAsTFk9DU1Ag
+U2lnbmluZyBBdXRob3JpdHkxHDAaBgNVBAMTE29jc3Auc3Ryb25nc3dhbi5vcmcw
+ggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCcEKXgcanpPoLMCxFLx1Br
+9WYJGHxMIi6eGfHHFObA56DpDxEUfRA88wvOgcq/PxSjAJZLePO9VQLU+sdK9+u9
+7INf7AMQ7CSRfHgkjEAt2SK4iWAk01I957qdwbvTTsBvmEAiKtqpQVcKbkokx1dC
+J7prB4TjJWQlxihMAfgRQEX8EWE1c2vmzQ8fVkEc37E/kWpwDYlKtVidn+Nrt5j7
+SuE+HKZOE9zc2hRXU9IE/5hgHmPd0sIkmusTYqr+feeS3x6FfiWn/xIMlf4eTQ6F
+55EgdUsem4su0y30i369aMviOL5Rc9OAyT/eH5AU/5BBy9M/y0Sep3wgdrOLsD3h
+AgMBAAGjggEaMIIBFjAJBgNVHRMEAjAAMAsGA1UdDwQEAwIDqDAdBgNVHQ4EFgQU
+DPBHE7nzb272+F6creQm6ORqEkIwbQYDVR0jBGYwZIAUXafdcAZRMn7ntm2zteXg
+YOouTe+hSaRHMEUxCzAJBgNVBAYTAkNIMRkwFwYDVQQKExBMaW51eCBzdHJvbmdT
+d2FuMRswGQYDVQQDExJzdHJvbmdTd2FuIFJvb3QgQ0GCAQAwHgYDVR0RBBcwFYIT
+b2NzcC5zdHJvbmdzd2FuLm9yZzATBgNVHSUEDDAKBggrBgEFBQcDCTA5BgNVHR8E
+MjAwMC6gLKAqhihodHRwOi8vY3JsLnN0cm9uZ3N3YW4ub3JnL3N0cm9uZ3N3YW4u
+Y3JsMA0GCSqGSIb3DQEBCwUAA4IBAQBvnya63noZrXlKv5daWjqGTmpftPIvK5KA
+tyQlZn4eSY0GDK4M9HPtPmg1o+gYJnQr9STADh737clPb3P05xzc1LLBiQ+laLZ4
+8KpZ4od5QSMTPCzYgx2LQxqKQz9PjbeLP1wcMLxRsluiwPJu9KnfZBDvHsow/UU8
+SPg62z3p17SZxoCk/87Q3eyZkI7BFJJtyrq4yiRf7lFjaLyw1SnM7sjwOMzoQBVO
+bj21Spn1XQ/1X+DiCB3pFvsGEU0ZdfWKrURNeYgh+KX6S1q0mDusOwIunpR0z2Nx
+Oc8QA3YT5fse48k3sUlRuKY+YSQZqj/vG12cHjBGGQRwmpbaTBHT
+-----END CERTIFICATE-----
diff --git a/testing/hosts/winnetou/etc/openssl/ocspCert.pem b/testing/hosts/winnetou/etc/openssl/ocspCert.pem
index f84d1a8..f7c90d3 100644
--- a/testing/hosts/winnetou/etc/openssl/ocspCert.pem
+++ b/testing/hosts/winnetou/etc/openssl/ocspCert.pem
@@ -1,25 +1,25 @@
 -----BEGIN CERTIFICATE-----
-MIIEQzCCAyugAwIBAgIBHjANBgkqhkiG9w0BAQsFADBFMQswCQYDVQQGEwJDSDEZ
+MIIEQzCCAyugAwIBAgIBMjANBgkqhkiG9w0BAQsFADBFMQswCQYDVQQGEwJDSDEZ
 MBcGA1UEChMQTGludXggc3Ryb25nU3dhbjEbMBkGA1UEAxMSc3Ryb25nU3dhbiBS
-b290IENBMB4XDTA5MTEyNDEyNTE1M1oXDTE0MTEyMzEyNTE1M1owZzELMAkGA1UE
+b290IENBMB4XDTE0MTEyODIwMTQzNloXDTE5MTEyNzIwMTQzNlowZzELMAkGA1UE
 BhMCQ0gxGTAXBgNVBAoTEExpbnV4IHN0cm9uZ1N3YW4xHzAdBgNVBAsTFk9DU1Ag
 U2lnbmluZyBBdXRob3JpdHkxHDAaBgNVBAMTE29jc3Auc3Ryb25nc3dhbi5vcmcw
-ggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC8BT5LvsaxM0gOw9QM74ML
-vbxXXxTv9W0L//oBnPohbVyueSl0/r2rcIeYa0g1eePgwRRBHwr356Om2mv/zXTp
-lQA4qtY6YMZkoeYCOVhO/fJ4CGO213qWeWIYOe4njTuiPUiI20PWancgaic5UOAC
-UBnyes94I5kB1OWx0THma4Sv0HdBRoWwO+ZqAA87fpV/Wagi6ElJBcjLbO5Hpy3J
-dFvrjNWZwuJw2+qHQ4QOT4McpusfIjgXaZtyEpVIcbJ7knNSq+MapdP0RBS6wzXa
-kWx9tMIAB9gKUfENTNl60ZnmqI0KgKiR3Yqia/bbsD7JcangOcOjWA2H0LKnnLdp
+ggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCcEKXgcanpPoLMCxFLx1Br
+9WYJGHxMIi6eGfHHFObA56DpDxEUfRA88wvOgcq/PxSjAJZLePO9VQLU+sdK9+u9
+7INf7AMQ7CSRfHgkjEAt2SK4iWAk01I957qdwbvTTsBvmEAiKtqpQVcKbkokx1dC
+J7prB4TjJWQlxihMAfgRQEX8EWE1c2vmzQ8fVkEc37E/kWpwDYlKtVidn+Nrt5j7
+SuE+HKZOE9zc2hRXU9IE/5hgHmPd0sIkmusTYqr+feeS3x6FfiWn/xIMlf4eTQ6F
+55EgdUsem4su0y30i369aMviOL5Rc9OAyT/eH5AU/5BBy9M/y0Sep3wgdrOLsD3h
 AgMBAAGjggEaMIIBFjAJBgNVHRMEAjAAMAsGA1UdDwQEAwIDqDAdBgNVHQ4EFgQU
-NJFukTK/NSVDzCh074LCV5J5E3MwbQYDVR0jBGYwZIAUXafdcAZRMn7ntm2zteXg
+DPBHE7nzb272+F6creQm6ORqEkIwbQYDVR0jBGYwZIAUXafdcAZRMn7ntm2zteXg
 YOouTe+hSaRHMEUxCzAJBgNVBAYTAkNIMRkwFwYDVQQKExBMaW51eCBzdHJvbmdT
 d2FuMRswGQYDVQQDExJzdHJvbmdTd2FuIFJvb3QgQ0GCAQAwHgYDVR0RBBcwFYIT
 b2NzcC5zdHJvbmdzd2FuLm9yZzATBgNVHSUEDDAKBggrBgEFBQcDCTA5BgNVHR8E
 MjAwMC6gLKAqhihodHRwOi8vY3JsLnN0cm9uZ3N3YW4ub3JnL3N0cm9uZ3N3YW4u
-Y3JsMA0GCSqGSIb3DQEBCwUAA4IBAQBteNdmkKbr3bUJSKTaJ/qssbyPjL7MjAmi
-QA1sSq5yIh7Ir23xEq/XQFF51N2yDNuXhLYk1fWou8BL+X9x97BlQkp9/nZ+BdJG
-uH2zOUxcsfq57jtwMzlXGrmVUTMAJRtMqrSnVa9jbW+IF2p/sJfeSRRqJ2qwQoDW
-ppvvBF4RfdWOVCCidtRmWKycEtP1ylSYyiHswVWhL2gLXQRQ0l5wJdgT2URRDopC
-CBiE5mHOWn17gTWQw9SdGbY37o9jXNrY8GRgOeubHFRmdXa1Cli5P5HhIZygUBWX
-tn5BvNDEIUz11/AT+HfpdMSKDiAXMq44wqWoYoUXsaLTIp+Vt6NM
+Y3JsMA0GCSqGSIb3DQEBCwUAA4IBAQBvnya63noZrXlKv5daWjqGTmpftPIvK5KA
+tyQlZn4eSY0GDK4M9HPtPmg1o+gYJnQr9STADh737clPb3P05xzc1LLBiQ+laLZ4
+8KpZ4od5QSMTPCzYgx2LQxqKQz9PjbeLP1wcMLxRsluiwPJu9KnfZBDvHsow/UU8
+SPg62z3p17SZxoCk/87Q3eyZkI7BFJJtyrq4yiRf7lFjaLyw1SnM7sjwOMzoQBVO
+bj21Spn1XQ/1X+DiCB3pFvsGEU0ZdfWKrURNeYgh+KX6S1q0mDusOwIunpR0z2Nx
+Oc8QA3YT5fse48k3sUlRuKY+YSQZqj/vG12cHjBGGQRwmpbaTBHT
 -----END CERTIFICATE-----
diff --git a/testing/hosts/winnetou/etc/openssl/ocspKey.pem b/testing/hosts/winnetou/etc/openssl/ocspKey.pem
index d25396b..13a81f2 100644
--- a/testing/hosts/winnetou/etc/openssl/ocspKey.pem
+++ b/testing/hosts/winnetou/etc/openssl/ocspKey.pem
@@ -1,27 +1,27 @@
 -----BEGIN RSA PRIVATE KEY-----
-MIIEowIBAAKCAQEAvAU+S77GsTNIDsPUDO+DC728V18U7/VtC//6AZz6IW1crnkp
-dP69q3CHmGtINXnj4MEUQR8K9+ejptpr/8106ZUAOKrWOmDGZKHmAjlYTv3yeAhj
-ttd6lnliGDnuJ407oj1IiNtD1mp3IGonOVDgAlAZ8nrPeCOZAdTlsdEx5muEr9B3
-QUaFsDvmagAPO36Vf1moIuhJSQXIy2zuR6ctyXRb64zVmcLicNvqh0OEDk+DHKbr
-HyI4F2mbchKVSHGye5JzUqvjGqXT9EQUusM12pFsfbTCAAfYClHxDUzZetGZ5qiN
-CoCokd2Komv227A+yXGp4DnDo1gNh9Cyp5y3aQIDAQABAoIBACKheJrs9Z3XyzLl
-AN6tEt8LwG/7VFjqRH6MVFkNt8iGYybDrE4fSYIVRPRe9jrbS4yvI3LnK9cDdFIc
-Mv43sov/ZL4LQVAZWRFZ/Ip2U3yhK5LOQMeBotOqYdYCfYoNaml0jjKe6DzK+Uwg
-IT9eVRQ3+r99vU7sh5cdxnzdAirlXAGdy2QxdF1lyC/49H6jxS7qxuxHPqI0P8VR
-9xVKIXaAKaxcijg47slC386/yEbO96morZuJX+F+iaQ37T0nV3tTergbwDtit3xo
-cOdsHan9zGHE1ayKh8DkBinD+BpiLZdapRvcSm2wAKlamXfI3GIAB5r/3B1NW9yb
-rsThgc0CgYEA4CN+fNaFYQmLMK33wZfXvcadaktSWWXmnqPVLIWRddUH3SA5qEJB
-RwuuLgcfmlmZqBqSOj4pDTtAoNooqA9Ryi0Ugzpvmn5iPevfixQoLix4mn1/bvbF
-bo4CX7Vb7mUdfXpu7PwVNALNfaW6fgKM79LoqX4yZ4k/yFuYl+JTIGcCgYEA1r9k
-mTi/5royyVX0vV7uwyKrXQ8VRVhnVeT2nG1KkuQqUraUQG8WD9J9uxvbZxhsrax1
-Hg1iCAobzlEL2XoX2y+dN+81o2tm9qcy3L7+g6M/+7nQmU+fbGdBkcWq72dZC4ev
-K6grD+gl0uQmdVc7m+3lErojNAlvxTSK1BKrR68CgYA2CxjijO8YGK8BC9FjUnNo
-hM1L5eFzQMi8k5BA7evG15jPzodYdLE8qipTWtBZ7STJja6YcIiBcjoBDtkivJ7h
-+sCpa5uhSrvxZkA+Tpvpljt2NLBXVxT/tSoJXbdO4f6cVLsOVTHfmpVlqGIxI/hL
-kzUaOR16LXO9oahHZwDYHQKBgHPg60PS35p9NxJ1k47sPyKE/rtEfFHjFj+/QWO/
-hdIl1MC1TOJIDzuSdc4Vhhrnjx1YRgplZlS4P7DhAufjfiQEWW3pYqRAPFs0dbmw
-Rl56JPiMmAdic8BnJ3all0uAFQinutpv8Gyw9FgMTMRcwgmuIUIttvlJbkqXw6IU
-QOB5AoGBAJkTG5alPABxJG9ZuEE+iWCPAV1671FXT115D5wlKOY3CImuhsEW085X
-uGZz7WDZWFZJres8RiRlpK035MAg6lUG3trC9+wOluRNehT6h0Vwru8TxjLBxPcc
-yjdSVDH61FQLSKWIGLH9VVLX03NXqi3qxVGrrulUSW5h/HR2s3f7
+MIIEowIBAAKCAQEAnBCl4HGp6T6CzAsRS8dQa/VmCRh8TCIunhnxxxTmwOeg6Q8R
+FH0QPPMLzoHKvz8UowCWS3jzvVUC1PrHSvfrveyDX+wDEOwkkXx4JIxALdkiuIlg
+JNNSPee6ncG7007Ab5hAIiraqUFXCm5KJMdXQie6aweE4yVkJcYoTAH4EUBF/BFh
+NXNr5s0PH1ZBHN+xP5FqcA2JSrVYnZ/ja7eY+0rhPhymThPc3NoUV1PSBP+YYB5j
+3dLCJJrrE2Kq/n3nkt8ehX4lp/8SDJX+Hk0OheeRIHVLHpuLLtMt9It+vWjL4ji+
+UXPTgMk/3h+QFP+QQcvTP8tEnqd8IHazi7A94QIDAQABAoIBAEP6NGZY3AuOgOZj
+g7sgK/V6RGF92tZGpUuUPW3bus8XlU0ulN/5wZLqwp/GhQtcbJ67aLujCXfUiZE/
+UoNjDboCRQ8I/CTo1tzP/Hze4i2WQLtkiw4/RblVMEH62tclnEh/Zp/7TpcesM0I
+UR9H/MgCCf8InWdbKA4UDAVfbjAEws/72QSMnhhsdUfNMKKFiaaDz596MXpI3AWY
+SsenVmcqhMTP819DEem7GTSyOZbx482i7tr1Ix/HB/WlXoTZLB4IFsUOjbtQkoym
+fJHftuCsuN6xg6xUq28zaWqcZzDje7pavqmexXfxvG7a8jXFGY/sagWIHSIp32la
+0WoUO2ECgYEAy0pG09+zY5pHsHoNrSEsN3wIXOv4EIwwEuk4ZTqBPyh/lbHozHDp
+JlO+ObJVzRG/NS4RnlJUicmAUtI7CSpdvTD1OclROBF3DPwiu18zEJTqXkGDcVyt
+bmy8JQDZPYt4mE/TsuRN3uoc9+2jc1ZL6zvS3u6s0EV5j4SYxrn/oQ0CgYEAxIe5
+uBvR+wRXeWddRbIAKxQJa1PR4WDbIQWGm8TlXpcBWsyaqId3AIg9IoQH9AtFvl5F
++6QHjhl5jNK/PkzNM/xAMbS4X4S32zDVUtmJXheyze65lQvXVfUFQUCyb5DeBtvk
+XOf6k5WfM8rAzCb4PNwp+U21vQW7dfOSWp1yEyUCgYEAv3QHeljOYHqXE4wPP0Lj
+mqmUUrbk2+i7CcRdGXDc8jdY2QlBfvDDkxYBK+NZTRVup03ox9svxMhhsx5M/RfK
+SnhGKxL/C7ffD/qRVzeUJwSoKPa4LNYke7+p/YtsDLtCauebL3o2ID8J4zEJ44Cd
+ZT/lG5FabZdQoao2G8pmBi0CgYBrdG5mLMflwJz3Yz3LUqTm6OCxjzXtTeDiMDxG
+RSTIUDZMaByT0uWNI/CRQ7F5jQRILxGColADMQiVp9ErBiEYsG6E/vPkPhOsxAmP
+cCO8j6aTFFjiFoRZmkuSPwaRG5taErbM2YXXVfKjBdPei9wkophMmGGrBUxXFKNL
+6lQqBQKBgFeDuiesvRr+3KUxO6FiRXdGzkhFpfVaSxnFpvyd03vByTsuI5AugjHt
+UPHkOxnrXYg2bZwHSy5fvhUs18FdcucfJnsVl+/Clhl5jkeQzSOszoPx8lvhcck5
+uzlqo+L2XXWN3MaiBHvboA/duTiSQAvcPaEi8gpprxvLHojz/P9R
 -----END RSA PRIVATE KEY-----
diff --git a/testing/hosts/winnetou/etc/openssl/research/index.txt b/testing/hosts/winnetou/etc/openssl/research/index.txt
index 0565c76..25f5737 100644
--- a/testing/hosts/winnetou/etc/openssl/research/index.txt
+++ b/testing/hosts/winnetou/etc/openssl/research/index.txt
@@ -2,8 +2,9 @@ R	100322070423Z	100407091025Z,superseded	01	unknown	/C=CH/O=Linux strongSwan/OU=
 R	100615195710Z	100703145747Z,superseded	02	unknown	/C=CH/O=Linux strongSwan/OU=Sales/CN=Sales CA
 R	120323210330Z	140324140605Z,superseded	03	unknown	/C=CH/O=Linux strongSwan/OU=Research OCSP Signing Authority/CN=ocsp.research.strongswan.org
 R	140323203747Z	140324142334Z,superseded	04	unknown	/C=CH/O=Linux strongSwan/OU=Research no CDP/CN=carol at strongswan.org
-V	151103161503Z		05	unknown	/C=CH/O=Linux strongSwan/OU=Research/CN=Duck Research CA
+R	151103161503Z	141128215838Z,superseded	05	unknown	/C=CH/O=Linux strongSwan/OU=Research/CN=Duck Research CA
 V	150406092057Z		06	unknown	/C=CH/O=Linux strongSwan/OU=Research/CN=carol at strongswan.org
 V	150702151839Z		07	unknown	/C=CH/O=Linux strongSwan/OU=Sales/CN=Sales CA
 V	190323140633Z		08	unknown	/C=CH/O=Linux strongSwan/OU=Research OCSP Signing Authority/CN=ocsp.research.strongswan.org
 V	190323142352Z		09	unknown	/C=CH/O=Linux strongSwan/OU=Research no CDP/CN=carol at strongswan.org
+V	190401220708Z		0A	unknown	/C=CH/O=Linux strongSwan/OU=Research/CN=Duck Research CA
diff --git a/testing/hosts/winnetou/etc/openssl/research/index.txt.old b/testing/hosts/winnetou/etc/openssl/research/index.txt.old
index 8a0231b..3fc101e 100644
--- a/testing/hosts/winnetou/etc/openssl/research/index.txt.old
+++ b/testing/hosts/winnetou/etc/openssl/research/index.txt.old
@@ -2,7 +2,8 @@ R	100322070423Z	100407091025Z,superseded	01	unknown	/C=CH/O=Linux strongSwan/OU=
 R	100615195710Z	100703145747Z,superseded	02	unknown	/C=CH/O=Linux strongSwan/OU=Sales/CN=Sales CA
 R	120323210330Z	140324140605Z,superseded	03	unknown	/C=CH/O=Linux strongSwan/OU=Research OCSP Signing Authority/CN=ocsp.research.strongswan.org
 R	140323203747Z	140324142334Z,superseded	04	unknown	/C=CH/O=Linux strongSwan/OU=Research no CDP/CN=carol at strongswan.org
-V	151103161503Z		05	unknown	/C=CH/O=Linux strongSwan/OU=Research/CN=Duck Research CA
+R	151103161503Z	141128215838Z,superseded	05	unknown	/C=CH/O=Linux strongSwan/OU=Research/CN=Duck Research CA
 V	150406092057Z		06	unknown	/C=CH/O=Linux strongSwan/OU=Research/CN=carol at strongswan.org
 V	150702151839Z		07	unknown	/C=CH/O=Linux strongSwan/OU=Sales/CN=Sales CA
 V	190323140633Z		08	unknown	/C=CH/O=Linux strongSwan/OU=Research OCSP Signing Authority/CN=ocsp.research.strongswan.org
+V	190323142352Z		09	unknown	/C=CH/O=Linux strongSwan/OU=Research no CDP/CN=carol at strongswan.org
diff --git a/testing/hosts/winnetou/etc/openssl/research/newcerts/0A.pem b/testing/hosts/winnetou/etc/openssl/research/newcerts/0A.pem
new file mode 100644
index 0000000..2076242
--- /dev/null
+++ b/testing/hosts/winnetou/etc/openssl/research/newcerts/0A.pem
@@ -0,0 +1,23 @@
+-----BEGIN CERTIFICATE-----
+MIID0jCCArqgAwIBAgIBCjANBgkqhkiG9w0BAQsFADBRMQswCQYDVQQGEwJDSDEZ
+MBcGA1UEChMQTGludXggc3Ryb25nU3dhbjERMA8GA1UECxMIUmVzZWFyY2gxFDAS
+BgNVBAMTC1Jlc2VhcmNoIENBMB4XDTE0MTEyODIyMDcwOFoXDTE5MDQwMTIyMDcw
+OFowVjELMAkGA1UEBhMCQ0gxGTAXBgNVBAoTEExpbnV4IHN0cm9uZ1N3YW4xETAP
+BgNVBAsTCFJlc2VhcmNoMRkwFwYDVQQDExBEdWNrIFJlc2VhcmNoIENBMIIBIjAN
+BgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAu984h2mkpbWJZc9Ydka6jC84EkPz
+w6tqtEkIdftEawgc5gvlC80JXLTwnQySMTb49KByyt44S59ZWE6SHHV0u2P2ihiw
+1duoY7NE+RZwODEsWVgnDRZmyume2Bj+Hpkugm6o+rL7jiGxhvNLeoFZK3RyD6IR
+IcEfZeAv7URGz7xdrzmK/vWXukfEnU8DlrFDSQUb3NaJS5tVVVLFuTWQBSjuT3NX
+7mdNHnpjcwT9/ruyOaNQ0DV2Bgz1nCiOup+oW396/AInb03CQ+wIqQpB9reWma0w
+F0Bc9lZxnv9ppYgBPsOTjE3yyyeTptzk9Gw+DFV1cw8Crm+aew5VH18oEwIDAQAB
+o4GvMIGsMA8GA1UdEwEB/wQFMAMBAf8wCwYDVR0PBAQDAgEGMB0GA1UdDgQWBBSK
+cODKpRxkbyuSuXNcAayQG/35NTBtBgNVHSMEZjBkgBTndfCg8q0gzc1gI8zHyA8p
+891UIKFJpEcwRTELMAkGA1UEBhMCQ0gxGTAXBgNVBAoTEExpbnV4IHN0cm9uZ1N3
+YW4xGzAZBgNVBAMTEnN0cm9uZ1N3YW4gUm9vdCBDQYIBIDANBgkqhkiG9w0BAQsF
+AAOCAQEAMtm7ldvd45818Ghl8+Z7PfCnRXDPbikyCJn5PXkuR3TSB62ekJSGT1Rd
+i2rnDoIZpfSzDQSpKH616MuWtwJoomJh8n9wCzbdUv1sn1cfgjDSkgLqIbm/Xpc4
+zUcHnZFdwvMr3sq/xSO/SgkfgTHi8bFLLp2RQwPNsNycT94nNE7DRjSeRenpuEPM
+4t4xIZCoUyX3sdusHvh+dDu4iuIVQoM0zaW9p7pVh210ALt0jac3HW0rQXtbfchE
+VeuDLZ0G7baFZ9LLLWpuQB4zPRUET7puvzabsf+sHpO54y+zXRaB0tbiFIurt4gF
+5n7mN4ssNQdcD86W5lnI9pT5s1uvdw==
+-----END CERTIFICATE-----
diff --git a/testing/hosts/winnetou/etc/openssl/research/serial b/testing/hosts/winnetou/etc/openssl/research/serial
index d9bb888..eb589e9 100644
--- a/testing/hosts/winnetou/etc/openssl/research/serial
+++ b/testing/hosts/winnetou/etc/openssl/research/serial
@@ -1 +1 @@
-0A
+0B
diff --git a/testing/hosts/winnetou/etc/openssl/research/serial.old b/testing/hosts/winnetou/etc/openssl/research/serial.old
index 86397e5..d9bb888 100644
--- a/testing/hosts/winnetou/etc/openssl/research/serial.old
+++ b/testing/hosts/winnetou/etc/openssl/research/serial.old
@@ -1 +1 @@
-09
+0A
diff --git a/testing/hosts/winnetou/etc/openssl/rfc3779/.rand b/testing/hosts/winnetou/etc/openssl/rfc3779/.rand
index 20107f5..b41b220 100644
Binary files a/testing/hosts/winnetou/etc/openssl/rfc3779/.rand and b/testing/hosts/winnetou/etc/openssl/rfc3779/.rand differ
diff --git a/testing/hosts/winnetou/etc/openssl/rfc3779/index.txt b/testing/hosts/winnetou/etc/openssl/rfc3779/index.txt
index 9adf263..bfafdee 100644
--- a/testing/hosts/winnetou/etc/openssl/rfc3779/index.txt
+++ b/testing/hosts/winnetou/etc/openssl/rfc3779/index.txt
@@ -1,4 +1,8 @@
-V	141222133356Z		01	unknown	/C=CH/O=Linux strongSwan/OU=RFC3779/CN=moon.strongswan.org
-V	141222133521Z		02	unknown	/C=CH/O=Linux strongSwan/OU=RFC3779/CN=sun.strongswan.org
-V	141222133612Z		03	unknown	/C=CH/O=Linux strongSwan/OU=RFC3779/CN=carol at strongswan.org
-V	141222133736Z		04	unknown	/C=CH/O=Linux strongSwan/OU=RFC3779/CN=dave at strongswan.org
+R	141222133356Z	141227062317Z,superseded	01	unknown	/C=CH/O=Linux strongSwan/OU=RFC3779/CN=moon.strongswan.org
+R	141222133521Z	141227062321Z,superseded	02	unknown	/C=CH/O=Linux strongSwan/OU=RFC3779/CN=sun.strongswan.org
+R	141222133612Z	141227062326Z,superseded	03	unknown	/C=CH/O=Linux strongSwan/OU=RFC3779/CN=carol at strongswan.org
+R	141222133736Z	141227062335Z,superseded	04	unknown	/C=CH/O=Linux strongSwan/OU=RFC3779/CN=dave at strongswan.org
+V	191221064542Z		05	unknown	/C=CH/O=Linux strongSwan/OU=RFC3779/CN=moon.strongswan.org
+V	191221064900Z		06	unknown	/C=CH/O=Linux strongSwan/OU=RFC3779/CN=sun.strongswan.org
+V	191221085130Z		07	unknown	/C=CH/O=Linux strongSwan/OU=RFC3779/CN=carol at strongswan.org
+V	191221085457Z		08	unknown	/C=CH/O=Linux strongSwan/OU=RFC3779/CN=dave at strongswan.org
diff --git a/testing/hosts/winnetou/etc/openssl/rfc3779/index.txt.old b/testing/hosts/winnetou/etc/openssl/rfc3779/index.txt.old
index be48eee..56242a3 100644
--- a/testing/hosts/winnetou/etc/openssl/rfc3779/index.txt.old
+++ b/testing/hosts/winnetou/etc/openssl/rfc3779/index.txt.old
@@ -1,3 +1,7 @@
-V	141222133356Z		01	unknown	/C=CH/O=Linux strongSwan/OU=RFC3779/CN=moon.strongswan.org
-V	141222133521Z		02	unknown	/C=CH/O=Linux strongSwan/OU=RFC3779/CN=sun.strongswan.org
-V	141222133612Z		03	unknown	/C=CH/O=Linux strongSwan/OU=RFC3779/CN=carol at strongswan.org
+R	141222133356Z	141227062317Z,superseded	01	unknown	/C=CH/O=Linux strongSwan/OU=RFC3779/CN=moon.strongswan.org
+R	141222133521Z	141227062321Z,superseded	02	unknown	/C=CH/O=Linux strongSwan/OU=RFC3779/CN=sun.strongswan.org
+R	141222133612Z	141227062326Z,superseded	03	unknown	/C=CH/O=Linux strongSwan/OU=RFC3779/CN=carol at strongswan.org
+R	141222133736Z	141227062335Z,superseded	04	unknown	/C=CH/O=Linux strongSwan/OU=RFC3779/CN=dave at strongswan.org
+V	191221064542Z		05	unknown	/C=CH/O=Linux strongSwan/OU=RFC3779/CN=moon.strongswan.org
+V	191221064900Z		06	unknown	/C=CH/O=Linux strongSwan/OU=RFC3779/CN=sun.strongswan.org
+V	191221085130Z		07	unknown	/C=CH/O=Linux strongSwan/OU=RFC3779/CN=carol at strongswan.org
diff --git a/testing/hosts/winnetou/etc/openssl/rfc3779/newcerts/05.pem b/testing/hosts/winnetou/etc/openssl/rfc3779/newcerts/05.pem
new file mode 100644
index 0000000..124e2ae
--- /dev/null
+++ b/testing/hosts/winnetou/etc/openssl/rfc3779/newcerts/05.pem
@@ -0,0 +1,28 @@
+-----BEGIN CERTIFICATE-----
+MIIEuDCCA6CgAwIBAgIBBTANBgkqhkiG9w0BAQsFADBaMQswCQYDVQQGEwJDSDEZ
+MBcGA1UEChMQTGludXggc3Ryb25nU3dhbjEQMA4GA1UECxMHUkZDMzc3OTEeMBwG
+A1UEAxMVc3Ryb25nU3dhbiBSRkMzNzc5IENBMB4XDTE0MTIyNzA2NDU0MloXDTE5
+MTIyMTA2NDU0MlowWDELMAkGA1UEBhMCQ0gxGTAXBgNVBAoTEExpbnV4IHN0cm9u
+Z1N3YW4xEDAOBgNVBAsTB1JGQzM3NzkxHDAaBgNVBAMTE21vb24uc3Ryb25nc3dh
+bi5vcmcwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDYeHiAGNal9DT6
+GgCewdXa4Nf/46YgbhZNmSpi/zH+XmA7JLS6eoVt5vJ/LJEHSzkRoEetptAILenu
+uakByawEoPZgkCYZgJB9opGEOoWIwTitaF0ZVV8diNQtnl+rkvwPpxWybvIwOwRA
+PUIenoQPkVhfd/ALaRl88pG0rcAW0MMSCNuQwELwSIK2rQALs94Qm5yM0bZ+dqV2
+jnSISit5doRZ4vIYghJPKPqFKb1zUw1siCDPev43S+xqwTjhJ0zncq/QigySyivd
+D8qs8KMkan+XNx9XSjW14YWp27RVpIeANlikiHh0/St0lBsR+P9sDp+Yvr+U95EK
+KOgrqac3AgMBAAGjggGJMIIBhTAJBgNVHRMEAjAAMAsGA1UdDwQEAwIDqDAdBgNV
+HQ4EFgQUQcvdnqQfLJx2utB9szVLhZCmp84wgYwGA1UdIwSBhDCBgYAUIX+n6zfQ
+owsfodxCBh4RXzzSEBShXqRcMFoxCzAJBgNVBAYTAkNIMRkwFwYDVQQKExBMaW51
+eCBzdHJvbmdTd2FuMRAwDgYDVQQLEwdSRkMzNzc5MR4wHAYDVQQDExVzdHJvbmdT
+d2FuIFJGQzM3NzkgQ0GCCQDyr+ZHsk6LRjAeBgNVHREEFzAVghNtb29uLnN0cm9u
+Z3N3YW4ub3JnMBMGA1UdJQQMMAoGCCsGAQUFBwMBMEEGA1UdHwQ6MDgwNqA0oDKG
+MGh0dHA6Ly9jcmwuc3Ryb25nc3dhbi5vcmcvc3Ryb25nc3dhbl9yZmMzNzc5LmNy
+bDBFBggrBgEFBQcBBwEB/wQ2MDQwEgQCAAEwDAMDAAoBAwUAwKgAATAeBAIAAjAY
+AxEA/sAAAAAAAAAAAAAAAAAAAQMDAP7BMA0GCSqGSIb3DQEBCwUAA4IBAQAi0XQL
+aEHg8aXBiXSTHuvxDieJB3Q83kpXOry16Ij5PKx9cdM2Gtmxz8YkwPEgq0r7vWNo
+830A4CnOJszQyIpY7CIygPj1wy3kFGGPkL7R4p00qSKpCEg8Fq85R4LmiyXIEZ+5
+lUtan7xka4ySMKKocm2rbXHyHXjis8AzU7NZN5QpEMkGLTaQPwHad4FUBFOolNE2
+NLoQ3xp9NPTyqfy1CkCHcyG18yRPciU4m8Cubyb+zBHyBADm9Q0P3++vznsU8LrR
+pzjRqS0e+FD2bzdXH/2g7Ge8+b6xzWRVMxZ8e2f5O9jQUY6q4SicuAX8SM/bgDPu
+Mc/lk4Nl8pHRO+Xm
+-----END CERTIFICATE-----
diff --git a/testing/hosts/winnetou/etc/openssl/rfc3779/newcerts/06.pem b/testing/hosts/winnetou/etc/openssl/rfc3779/newcerts/06.pem
new file mode 100644
index 0000000..a93121d
--- /dev/null
+++ b/testing/hosts/winnetou/etc/openssl/rfc3779/newcerts/06.pem
@@ -0,0 +1,28 @@
+-----BEGIN CERTIFICATE-----
+MIIEtjCCA56gAwIBAgIBBjANBgkqhkiG9w0BAQsFADBaMQswCQYDVQQGEwJDSDEZ
+MBcGA1UEChMQTGludXggc3Ryb25nU3dhbjEQMA4GA1UECxMHUkZDMzc3OTEeMBwG
+A1UEAxMVc3Ryb25nU3dhbiBSRkMzNzc5IENBMB4XDTE0MTIyNzA2NDkwMFoXDTE5
+MTIyMTA2NDkwMFowVzELMAkGA1UEBhMCQ0gxGTAXBgNVBAoTEExpbnV4IHN0cm9u
+Z1N3YW4xEDAOBgNVBAsTB1JGQzM3NzkxGzAZBgNVBAMTEnN1bi5zdHJvbmdzd2Fu
+Lm9yZzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAO+7A6hhF+4kxCv5
+oR9DEpv1gnpGmPpn6i7JfuLGIJ9phQ3bUnSMIx8+mp3JE4SLXINLcyCHilK74tIf
+pwYx2K0c2txTFIWLQvBaHWohJ9Sgg4ElVXmSa/b0Nym5FcttdcRgNGd/+DLPs9Tw
+ZoieGvJcZWiOBP+xxPbEo2xcoi3GetPN+XSW+m1BvU88Ysrp0o+4+rLPB5iipUB1
+Iksb51SvF4iG4BHfoTKGlHLwVyjJnp7YnYJtjY6Xaw1GbCf6wcwLlq71uoMj39cd
+0clncpi/s13K2Sh0YHiCcQD5vIkP9BRmobWAXseBZevYI/rU5dz761EqHf72TRrd
+bM3/KycCAwEAAaOCAYgwggGEMAkGA1UdEwQCMAAwCwYDVR0PBAQDAgOoMB0GA1Ud
+DgQWBBTPOzV+XXFm2wEX9j+NxqVXiRBq7TCBjAYDVR0jBIGEMIGBgBQhf6frN9Cj
+Cx+h3EIGHhFfPNIQFKFepFwwWjELMAkGA1UEBhMCQ0gxGTAXBgNVBAoTEExpbnV4
+IHN0cm9uZ1N3YW4xEDAOBgNVBAsTB1JGQzM3NzkxHjAcBgNVBAMTFXN0cm9uZ1N3
+YW4gUkZDMzc3OSBDQYIJAPKv5keyTotGMB0GA1UdEQQWMBSCEnN1bi5zdHJvbmdz
+d2FuLm9yZzATBgNVHSUEDDAKBggrBgEFBQcDATBBBgNVHR8EOjA4MDagNKAyhjBo
+dHRwOi8vY3JsLnN0cm9uZ3N3YW4ub3JnL3N0cm9uZ3N3YW5fcmZjMzc3OS5jcmww
+RQYIKwYBBQUHAQcBAf8ENjA0MBIEAgABMAwDAwAKAgMFAMCoAAIwHgQCAAIwGAMR
+AP7AAAAAAAAAAAAAAAAAAAIDAwD+wjANBgkqhkiG9w0BAQsFAAOCAQEAgJDWuKCu
+7H/K4U7xFRarSKtj9oMAAsq2vLSQqJTUg6fdTnFIlH3OBPcwEzFwVx30QlQyls1p
+nHm/cptV/3cxvqCvdnT2dVspJu+9a5D+zZNeLAtWZuyRN6Nlmeqj1Nnp6eEHEBrg
+oXMzmAf0ulzIZJsEVYwJSCXm0AMOlyvoIYqKxty3L2VZ1iAU1z15lnFhcvamraGx
+k7yaI9ujVR4xQZOOgh05pUrEKaXI3XR1rIoL3NV3ws/JgHch/CQw/If7x4VQmGcD
+yJbKkKn0S18TJr0KhPqbM4+inldEwyX/zjGmlHezy0em5qTRYwupFIQNwZZkTXug
+NnBR3lf2HB2lWA==
+-----END CERTIFICATE-----
diff --git a/testing/hosts/winnetou/etc/openssl/rfc3779/newcerts/07.pem b/testing/hosts/winnetou/etc/openssl/rfc3779/newcerts/07.pem
new file mode 100644
index 0000000..bf8a491
--- /dev/null
+++ b/testing/hosts/winnetou/etc/openssl/rfc3779/newcerts/07.pem
@@ -0,0 +1,27 @@
+-----BEGIN CERTIFICATE-----
+MIIEojCCA4qgAwIBAgIBBzANBgkqhkiG9w0BAQsFADBaMQswCQYDVQQGEwJDSDEZ
+MBcGA1UEChMQTGludXggc3Ryb25nU3dhbjEQMA4GA1UECxMHUkZDMzc3OTEeMBwG
+A1UEAxMVc3Ryb25nU3dhbiBSRkMzNzc5IENBMB4XDTE0MTIyNzA4NTEzMFoXDTE5
+MTIyMTA4NTEzMFowWTELMAkGA1UEBhMCQ0gxGTAXBgNVBAoTEExpbnV4IHN0cm9u
+Z1N3YW4xEDAOBgNVBAsTB1JGQzM3NzkxHTAbBgNVBAMUFGNhcm9sQHN0cm9uZ3N3
+YW4ub3JnMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAsSlxt8LQf1wJ
+u1rDltyU0dEjEqA+TxWQYi+gMakDGmWmFec1XELjKv3kcYp2McydNPq63fw9XXbu
+a/jMtmEZdFc/dpWYvsyXfyL0OOhh50PlwN++e0xxcZS4NQ6wz57bHgARzMoCisNr
+xcN0F44S0Zyn8edHkE4XV4c0p+ojB6cw5LieSMGIBQjKGCd2a3eZYhTCs6hI0vhQ
+Q1jDLyOvSWo+raa/uDTBYXCVYdN3lbHCPiXPuMY1CwZkGcANd6vBK5YBNiZFquBj
+FhIk8SBUkoEkUQMx+pMk3hGmq5aZXGxm9rHN8Xim/AewWRcKJJKdlLAAHmZD0jx2
+g/E0LGu01wIDAQABo4IBcjCCAW4wCQYDVR0TBAIwADALBgNVHQ8EBAMCA6gwHQYD
+VR0OBBYEFNs9CUs7SNJewkkfo1Bg7bcUEzPXMIGMBgNVHSMEgYQwgYGAFCF/p+s3
+0KMLH6HcQgYeEV880hAUoV6kXDBaMQswCQYDVQQGEwJDSDEZMBcGA1UEChMQTGlu
+dXggc3Ryb25nU3dhbjEQMA4GA1UECxMHUkZDMzc3OTEeMBwGA1UEAxMVc3Ryb25n
+U3dhbiBSRkMzNzc5IENBggkA8q/mR7JOi0YwHwYDVR0RBBgwFoEUY2Fyb2xAc3Ry
+b25nc3dhbi5vcmcwQQYDVR0fBDowODA2oDSgMoYwaHR0cDovL2NybC5zdHJvbmdz
+d2FuLm9yZy9zdHJvbmdzd2FuX3JmYzM3NzkuY3JsMEIGCCsGAQUFBwEHAQH/BDMw
+MTAUBAIAATAOAwUACgMAAQMFAMCoAGQwGQQCAAIwEwMRAP7AAAAAAAAAAAAAAAAA
+ABAwDQYJKoZIhvcNAQELBQADggEBAEYqXkheXXHiC5JnrZm5QUo11Vu4CtNRGeg0
+atuG8ZNHgQfa7wjjeCDNpj3lHvyegYsSMo7wGwN7DugH0mmXKZF9XHc4sU7/aUvl
+mX52tDuUoCGD0/yFuKLlYOfwmsquC9snYDW7cJXaqMON/OMLcU44OR8E1oiw2ePT
+FqyGFbfparp+Q8I7VHwJBs+mDphdNUlFbpuO9m2eEtqdYVyXlfUnbFpMMyWxxIY/
+6CIyWcRRKeWRRXxkk/dSeEWgsfWY7ITK9blP5nhIsgpCoEguGc6h4RL65VdH+Sy0
+9MLpesyGe6qkdrrg4nyaY82uuFXhUo0YiP0ddUw8eNaefFqEzL0=
+-----END CERTIFICATE-----
diff --git a/testing/hosts/winnetou/etc/openssl/rfc3779/newcerts/08.pem b/testing/hosts/winnetou/etc/openssl/rfc3779/newcerts/08.pem
new file mode 100644
index 0000000..88ce01e
--- /dev/null
+++ b/testing/hosts/winnetou/etc/openssl/rfc3779/newcerts/08.pem
@@ -0,0 +1,27 @@
+-----BEGIN CERTIFICATE-----
+MIIEoDCCA4igAwIBAgIBCDANBgkqhkiG9w0BAQsFADBaMQswCQYDVQQGEwJDSDEZ
+MBcGA1UEChMQTGludXggc3Ryb25nU3dhbjEQMA4GA1UECxMHUkZDMzc3OTEeMBwG
+A1UEAxMVc3Ryb25nU3dhbiBSRkMzNzc5IENBMB4XDTE0MTIyNzA4NTQ1N1oXDTE5
+MTIyMTA4NTQ1N1owWDELMAkGA1UEBhMCQ0gxGTAXBgNVBAoTEExpbnV4IHN0cm9u
+Z1N3YW4xEDAOBgNVBAsTB1JGQzM3NzkxHDAaBgNVBAMUE2RhdmVAc3Ryb25nc3dh
+bi5vcmcwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDpJKRQ2CEG39rO
+8nX7RpY+Ed5tyx+rkug3HrSInie+fgkDnLES2U1X3wvM2OczLp6L1ccROv+SzEW+
+OKfCZSz7T4GLwaRodi9KtHvfOCsbDx/vkFFwui2yt9rVUSpcbk1OiVQsA9R0G6vz
+eqFIL9GtrtHWQ+dkvWy61i2A+T1X2QfhVfzvj5msL3CuZU6fnwGYD4LZz8RUGlB4
+WkSFWCctfQfgK+lpfuzq6OFFkARzxZ55D0MzgAvXY6osS8gMdiSD50Zlik7qZVvn
+RO0j6TOg0WKinzguAokAyDCsaoqsOvi27QalfH48PUM+aUzHNCKnD6pswebHou3m
+mvG3rH+9AgMBAAGjggFxMIIBbTAJBgNVHRMEAjAAMAsGA1UdDwQEAwIDqDAdBgNV
+HQ4EFgQUsBjPeVTm7TUTaXtmfv09yQS2mV8wgYwGA1UdIwSBhDCBgYAUIX+n6zfQ
+owsfodxCBh4RXzzSEBShXqRcMFoxCzAJBgNVBAYTAkNIMRkwFwYDVQQKExBMaW51
+eCBzdHJvbmdTd2FuMRAwDgYDVQQLEwdSRkMzNzc5MR4wHAYDVQQDExVzdHJvbmdT
+d2FuIFJGQzM3NzkgQ0GCCQDyr+ZHsk6LRjAeBgNVHREEFzAVgRNkYXZlQHN0cm9u
+Z3N3YW4ub3JnMEEGA1UdHwQ6MDgwNqA0oDKGMGh0dHA6Ly9jcmwuc3Ryb25nc3dh
+bi5vcmcvc3Ryb25nc3dhbl9yZmMzNzc5LmNybDBCBggrBgEFBQcBBwEB/wQzMDEw
+FAQCAAEwDgMFAAoDAAIDBQDAqADIMBkEAgACMBMDEQD+wAAAAAAAAAAAAAAAAAAg
+MA0GCSqGSIb3DQEBCwUAA4IBAQCNyAyUvqeCgWnPEMkfFFb1kBbd3me3aLRxXFb4
+TY44L6SBiFNy1s3UyFCLw1xXnSMgTpvZqHmB7fnzX7Aj6BNkPFIThEiHYN85ai4t
+U9bO2nqwXfIINFt2Qlokd0QWHzDsL/o9Mmqs38ymlfIbsgwh7gCZ2HhGlOb7+QNU
+IaDVIcKqBr07wX7qO/fEjKgFSkUT5eFNwQmyT3zUaE1PixK5w1hRxvs/KAsLgbfe
+5ofLD88rfxvkqLwhRNU8PUzqIpqxfV1P+wS/k78z0tG+JI8yeEkcksuj9UOzlTr2
+jWL1QoxUEinR3N4dTqsW4u/Jz7R4MHdO+l9RoYZpQA8LV8s3
+-----END CERTIFICATE-----
diff --git a/testing/hosts/winnetou/etc/openssl/rfc3779/openssl.cnf b/testing/hosts/winnetou/etc/openssl/rfc3779/openssl.cnf
index 9ec4b01..e8a0a2e 100644
--- a/testing/hosts/winnetou/etc/openssl/rfc3779/openssl.cnf
+++ b/testing/hosts/winnetou/etc/openssl/rfc3779/openssl.cnf
@@ -40,7 +40,7 @@ x509_extensions = host_ext		  # The extensions to add to the cert
 
 crl_extensions	= crl_ext  		  # The extensions to add to the CRL
 
-default_days    = 1825                    # how long to certify for
+default_days    = 1820                    # how long to certify for
 default_crl_days= 30			  # how long before next CRL
 default_md      = sha256                  # which md to use.
 preserve        = no                      # keep passed DN ordering
@@ -153,6 +153,13 @@ sbgp-ipAddrBlock = critical, @host-addr-section
 
 [host-addr-section]
 
+#moon networks
+#IPv4.0 = 192.168.0.1
+#IPv4.1 = 10.1.0.0/16
+#IPv6.0 = fec0::1
+#IPv6.1 = fec1::/16
+
+#sun networks
 IPv4.0 = 192.168.0.2
 IPv4.1 = 10.2.0.0/16
 IPv6.0 = fec0::2
@@ -176,6 +183,12 @@ sbgp-ipAddrBlock = critical, @user-addr-section
 
 [user-addr-section]
 
+#carol networks
+#IPv4.0 = 192.168.0.100
+#IPv4.1 = 10.3.0.1
+#IPv6.0 = fec0::10
+
+#dave networks
 IPv4.0 = 192.168.0.200
 IPv4.1 = 10.3.0.2
 IPv6.0 = fec0::20
diff --git a/testing/hosts/winnetou/etc/openssl/rfc3779/serial b/testing/hosts/winnetou/etc/openssl/rfc3779/serial
index eeee65e..86397e5 100644
--- a/testing/hosts/winnetou/etc/openssl/rfc3779/serial
+++ b/testing/hosts/winnetou/etc/openssl/rfc3779/serial
@@ -1 +1 @@
-05
+09
diff --git a/testing/hosts/winnetou/etc/openssl/rfc3779/serial.old b/testing/hosts/winnetou/etc/openssl/rfc3779/serial.old
index 6496923..adb9de8 100644
--- a/testing/hosts/winnetou/etc/openssl/rfc3779/serial.old
+++ b/testing/hosts/winnetou/etc/openssl/rfc3779/serial.old
@@ -1 +1 @@
-04
+08
diff --git a/testing/hosts/winnetou/etc/openssl/serial b/testing/hosts/winnetou/etc/openssl/serial
index f5c8955..bb95160 100644
--- a/testing/hosts/winnetou/etc/openssl/serial
+++ b/testing/hosts/winnetou/etc/openssl/serial
@@ -1 +1 @@
-32
+33
diff --git a/testing/hosts/winnetou/etc/openssl/serial.old b/testing/hosts/winnetou/etc/openssl/serial.old
index e85087a..f5c8955 100644
--- a/testing/hosts/winnetou/etc/openssl/serial.old
+++ b/testing/hosts/winnetou/etc/openssl/serial.old
@@ -1 +1 @@
-31
+32
diff --git a/testing/scripts/build-baseimage b/testing/scripts/build-baseimage
index 075fd8e..c927934 100755
--- a/testing/scripts/build-baseimage
+++ b/testing/scripts/build-baseimage
@@ -21,7 +21,7 @@ INC=$INC,less,acpid,acpi-support-base,libldns-dev,libunbound-dev,dnsutils,screen
 INC=$INC,gnat,gprbuild,libahven3-dev,libxmlada4.1-dev,libgmpada3-dev
 INC=$INC,libalog0.4.1-base-dev,hostapd,libsoup2.4-dev,ca-certificates,unzip
 INC=$INC,python,python-setuptools,python-dev,python-pip
-INC=$INC,libjson0-dev,libxslt1-dev,libapache2-mod-wsgi
+INC=$INC,libjson0-dev,libxslt1-dev,libapache2-mod-wsgi,iptables-dev
 SERVICES="apache2 dbus isc-dhcp-server slapd bind9"
 INC=$INC,${SERVICES// /,}
 
diff --git a/testing/scripts/recipes/013_strongswan.mk b/testing/scripts/recipes/013_strongswan.mk
index 2b7bde5..d58de95 100644
--- a/testing/scripts/recipes/013_strongswan.mk
+++ b/testing/scripts/recipes/013_strongswan.mk
@@ -70,6 +70,8 @@ CONFIG_OPTS = \
 	--enable-socket-dynamic \
 	--enable-dhcp \
 	--enable-farp \
+	--enable-connmark \
+	--enable-forecast \
 	--enable-addrblock \
 	--enable-ctr \
 	--enable-ccm \
@@ -92,7 +94,8 @@ CONFIG_OPTS = \
 	--enable-tkm \
 	--enable-ntru \
 	--enable-lookip \
-	--enable-swanctl
+	--enable-swanctl \
+	--enable-bliss
 
 export ADA_PROJECT_PATH=/usr/local/ada/lib/gnat
 
diff --git a/testing/tests/ha/both-active/description.txt b/testing/tests/ha/both-active/description.txt
index 4c64fff..2d04e74 100644
--- a/testing/tests/ha/both-active/description.txt
+++ b/testing/tests/ha/both-active/description.txt
@@ -4,5 +4,5 @@ to the virtual gateway <b>mars</b> implemented by the two real gateways
 based on <b>ClusterIP</b>. Depending on the hash of the IP addresses of the peers
 and the SPIs, the inbound and outbound CHILD_SAs are either assigned to
 segment 1 managed by <b>alice</b> or segment 2 handled by <b>moon</b>.
-The IKEv2 protocol is managed by <b>moon</b> exclusively with passive
-IKE_SAs installed on the backup gateway <b>alice</b>.
+The IKEv2 protocol is managed by <b>alice</b> exclusively with passive
+IKE_SAs installed on the backup gateway <b>moon</b>.
diff --git a/testing/tests/ikev1/double-nat-net/evaltest.dat b/testing/tests/ikev1/double-nat-net/evaltest.dat
index 52c5619..8f5ffdb 100644
--- a/testing/tests/ikev1/double-nat-net/evaltest.dat
+++ b/testing/tests/ikev1/double-nat-net/evaltest.dat
@@ -1,7 +1,7 @@
 alice::ipsec status 2> /dev/null::nat-t.*ESTABLISHED.*alice at strongswan.org.*bob at strongswan.org::YES
 bob::  ipsec status 2> /dev/null::nat-t.*ESTABLISHED.*bob at strongswan.org.*alice at strongswan.org::YES
-alice::ipsec status 2> /dev/null::nat-t.*INSTALLED, TUNNEL, ESP in UDP::YES
-bob::  ipsec status 2> /dev/null::nat-t.*INSTALLED, TUNNEL, ESP in UDP::YES
+alice::ipsec status 2> /dev/null::nat-t.*INSTALLED, TUNNEL.*ESP in UDP::YES
+bob::  ipsec status 2> /dev/null::nat-t.*INSTALLED, TUNNEL.*ESP in UDP::YES
 alice::ping -c 1 PH_IP_SUN1::64 bytes from PH_IP_SUN1: icmp_req=1::YES
 moon::tcpdump::IP moon.strongswan.org.* > sun.strongswan.org.4500: UDP::YES
 moon::tcpdump::IP sun.strongswan.org.4500 > moon.strongswan.org.*: UDP::YES
diff --git a/testing/tests/ikev1/double-nat/evaltest.dat b/testing/tests/ikev1/double-nat/evaltest.dat
index 9ddad2d..5f06226 100644
--- a/testing/tests/ikev1/double-nat/evaltest.dat
+++ b/testing/tests/ikev1/double-nat/evaltest.dat
@@ -1,7 +1,7 @@
 alice::ipsec status 2> /dev/null::nat-t.*ESTABLISHED.*alice at strongswan.org.*bob at strongswan.org::YES
 bob::  ipsec status 2> /dev/null::nat-t.*ESTABLISHED.*bob at strongswan.org.*alice at strongswan.org::YES
-alice::ipsec status 2> /dev/null::nat-t.*INSTALLED, TUNNEL, ESP in UDP::YES
-bob::  ipsec status 2> /dev/null::nat-t.*INSTALLED, TUNNEL, ESP in UDP::YES
+alice::ipsec status 2> /dev/null::nat-t.*INSTALLED, TUNNEL.*ESP in UDP::YES
+bob::  ipsec status 2> /dev/null::nat-t.*INSTALLED, TUNNEL.*ESP in UDP::YES
 alice::ping -c 1 PH_IP_BOB::64 bytes from PH_IP_BOB: icmp_req=1::YES
 moon::tcpdump::IP moon.strongswan.org.* > sun.strongswan.org.4500: UDP::YES
 moon::tcpdump::IP sun.strongswan.org.4500 > moon.strongswan.org.*: UDP::YES
diff --git a/testing/tests/ikev1/nat-rw/evaltest.dat b/testing/tests/ikev1/nat-rw/evaltest.dat
index 387dbae..36d9f84 100644
--- a/testing/tests/ikev1/nat-rw/evaltest.dat
+++ b/testing/tests/ikev1/nat-rw/evaltest.dat
@@ -2,10 +2,10 @@ alice::ipsec status 2> /dev/null::nat-t.*ESTABLISHED.*alice at strongswan.org.*sun.
 venus::ipsec status 2> /dev/null::nat-t.*ESTABLISHED.*venus.strongswan.org.*sun.strongswan.org::YES
 sun::  ipsec status 2> /dev/null::nat-t\[1]: ESTABLISHED.*sun.strongswan.org.*alice at strongswan.org::YES
 sun::  ipsec status 2> /dev/null::nat-t\[2]: ESTABLISHED.*sun.strongswan.org.*venus.strongswan.org::YES
-alice::ipsec status 2> /dev/null::nat-t.*INSTALLED, TUNNEL, ESP in UDP::YES
-venus::ipsec status 2> /dev/null::nat-t.*INSTALLED, TUNNEL, ESP in UDP::YES
-sun::  ipsec status 2> /dev/null::nat-t[{]1}.*INSTALLED, TUNNEL, ESP in UDP::YES
-sun::  ipsec status 2> /dev/null::nat-t[{]2}.*INSTALLED, TUNNEL, ESP in UDP::YES
+alice::ipsec status 2> /dev/null::nat-t.*INSTALLED, TUNNEL.*ESP in UDP::YES
+venus::ipsec status 2> /dev/null::nat-t.*INSTALLED, TUNNEL.*ESP in UDP::YES
+sun::  ipsec status 2> /dev/null::nat-t[{]1}.*INSTALLED, TUNNEL.*ESP in UDP::YES
+sun::  ipsec status 2> /dev/null::nat-t[{]2}.*INSTALLED, TUNNEL.*ESP in UDP::YES
 alice::ping -c 1 PH_IP_BOB::64 bytes from PH_IP_BOB: icmp_req=1::YES
 venus::ping -c 1 PH_IP_BOB::64 bytes from PH_IP_BOB: icmp_req=1::YES
 moon:: sleep 6::no output expected::NO
diff --git a/testing/tests/ikev1/nat-virtual-ip/hosts/moon/etc/nat_updown b/testing/tests/ikev1/nat-virtual-ip/hosts/moon/etc/nat_updown
index aab1df6..b8b1fdd 100755
--- a/testing/tests/ikev1/nat-virtual-ip/hosts/moon/etc/nat_updown
+++ b/testing/tests/ikev1/nat-virtual-ip/hosts/moon/etc/nat_updown
@@ -1,4 +1,4 @@
-#! /bin/sh
+#!/bin/sh
 # NAT updown script
 #
 # Copyright (C) 2010 Andreas Steffen <andreas.steffen at strongswan.org>
@@ -13,7 +13,6 @@
 # or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 # for more details.
 
-# things that this script gets (from ipsec_pluto(8) man page)
 #
 #      PLUTO_VERSION
 #              indicates  what  version of this interface is being
@@ -32,15 +31,20 @@
 #              is the name of the  connection  for  which  we  are
 #              routing.
 #
-#       PLUTO_NEXT_HOP
-#              is the next hop to which packets bound for the peer
-#              must be sent.
-#
 #       PLUTO_INTERFACE
 #              is the name of the ipsec interface to be used.
 #
 #       PLUTO_REQID
-#              is the requid of the ESP policy
+#              is the requid of the AH|ESP policy
+#
+#       PLUTO_PROTO
+#              is the negotiated IPsec protocol, ah|esp
+#
+#       PLUTO_IPCOMP
+#              is not empty if IPComp was negotiated
+#
+#       PLUTO_UNIQUEID
+#              is the unique identifier of the associated IKE_SA
 #
 #       PLUTO_ME
 #              is the IP address of our host.
@@ -54,25 +58,21 @@
 #              host's own IP address / max (where max  is  32  for
 #              IPv4 and 128 for IPv6).
 #
-#       PLUTO_MY_CLIENT_NET
-#              is the IP address of our client net.  If the client
-#              is just the host, this will be the  host's  own  IP
-#              address.
-#
-#       PLUTO_MY_CLIENT_MASK
-#              is  the  mask for our client net.  If the client is
-#              just the host, this will be 255.255.255.255.
-#
 #       PLUTO_MY_SOURCEIP
-#              if non-empty, then the source address for the route will be
-#              set to this IP address.
+#       PLUTO_MY_SOURCEIP4_$i
+#       PLUTO_MY_SOURCEIP6_$i
+#              contains IPv4/IPv6 virtual IP received from a responder,
+#              $i enumerates from 1 to the number of IP per address family.
+#              PLUTO_MY_SOURCEIP is a legacy variable and equals to the first
+#              virtual IP, IPv4 or IPv6.
 #
 #       PLUTO_MY_PROTOCOL
 #              is the IP protocol that will be transported.
 #
 #       PLUTO_MY_PORT
 #              is  the  UDP/TCP  port  to  which  the IPsec SA  is
-#              restricted on our side.
+#              restricted on our side.  For ICMP/ICMPv6 this contains the
+#              message type, and PLUTO_PEER_PORT the message code.
 #
 #       PLUTO_PEER
 #              is the IP address of our peer.
@@ -80,31 +80,38 @@
 #       PLUTO_PEER_ID
 #              is the ID of our peer.
 #
-#       PLUTO_PEER_CA
-#              is the CA which issued the cert of our peer.
-#
 #       PLUTO_PEER_CLIENT
 #              is the IP address / count of the peer's client sub-
 #              net.   If the client is just the peer, this will be
 #              the peer's own IP address / max (where  max  is  32
 #              for IPv4 and 128 for IPv6).
 #
-#       PLUTO_PEER_CLIENT_NET
-#              is the IP address of the peer's client net.  If the
-#              client is just the peer, this will  be  the  peer's
-#              own IP address.
-#
-#       PLUTO_PEER_CLIENT_MASK
-#              is  the  mask  for  the  peer's client net.  If the
-#              client   is   just   the   peer,   this   will   be
-#              255.255.255.255.
-#
 #       PLUTO_PEER_PROTOCOL
 #              is the IP protocol that will be transported.
 #
 #       PLUTO_PEER_PORT
 #              is  the  UDP/TCP  port  to  which  the IPsec SA  is
-#              restricted on the peer side.
+#              restricted on the peer side.  For ICMP/ICMPv6 this contains the
+#              message code, and PLUTO_MY_PORT the message type.
+#
+#       PLUTO_XAUTH_ID
+#              is an optional user ID employed by the XAUTH protocol
+#
+#       PLUTO_MARK_IN
+#              is an optional XFRM mark set on the inbound IPsec SA
+#
+#       PLUTO_MARK_OUT
+#              is an optional XFRM mark set on the outbound IPsec SA
+#
+#       PLUTO_UDP_ENC
+#              contains the remote UDP port in the case of ESP_IN_UDP
+#              encapsulation
+#
+#       PLUTO_DNS4_$i
+#       PLUTO_DNS6_$i
+#              contains IPv4/IPv6 DNS server attribute received from a
+#              responder, $i enumerates from 1 to the number of servers per
+#              address family.
 #
 
 # define a minimum PATH environment in case it is not set
@@ -129,22 +136,22 @@ up-client:)
 	# If you are doing a custom version, firewall commands go here.
 	iptables -A FORWARD -i eth1 -o $PLUTO_INTERFACE -s PH_IP_ALICE \
 	    -d $PLUTO_PEER_CLIENT -j ACCEPT
-        iptables -A FORWARD -o eth1 -i $PLUTO_INTERFACE -d PH_IP_ALICE \
-            -s $PLUTO_PEER_CLIENT -j ACCEPT
+	iptables -A FORWARD -o eth1 -i $PLUTO_INTERFACE -d PH_IP_ALICE \
+	    -s $PLUTO_PEER_CLIENT -j ACCEPT
 	iptables -t nat -A POSTROUTING -o $PLUTO_INTERFACE -s PH_IP_ALICE \
 	    -d $PLUTO_PEER_CLIENT -j SNAT --to-source $PLUTO_MY_SOURCEIP
-	echo "inserted NAT rule mapping PH_IP_ALICE to virtual IP $PLUTO_MY_SOURCEIP" >&2 
+	echo "inserted NAT rule mapping PH_IP_ALICE to virtual IP $PLUTO_MY_SOURCEIP" >&2
 	;;
 down-client:)
 	# connection to my client subnet going down
 	# If you are doing a custom version, firewall commands go here.
-        iptables -D FORWARD -i eth1 -o $PLUTO_INTERFACE -s PH_IP_ALICE \
-            -d $PLUTO_PEER_CLIENT -j ACCEPT
-        iptables -D FORWARD -o eth1 -i $PLUTO_INTERFACE -d PH_IP_ALICE \
-            -s $PLUTO_PEER_CLIENT -j ACCEPT
-         iptables -t nat -D POSTROUTING -o $PLUTO_INTERFACE -s PH_IP_ALICE \
-            -d $PLUTO_PEER_CLIENT -j SNAT --to-source $PLUTO_MY_SOURCEIP
-        echo "deleted NAT rule mapping PH_IP_ALICE to virtual IP $PLUTO_MY_SOURCEIP" >&2    
+	iptables -D FORWARD -i eth1 -o $PLUTO_INTERFACE -s PH_IP_ALICE \
+	    -d $PLUTO_PEER_CLIENT -j ACCEPT
+	iptables -D FORWARD -o eth1 -i $PLUTO_INTERFACE -d PH_IP_ALICE \
+	    -s $PLUTO_PEER_CLIENT -j ACCEPT
+	iptables -t nat -D POSTROUTING -o $PLUTO_INTERFACE -s PH_IP_ALICE \
+	    -d $PLUTO_PEER_CLIENT -j SNAT --to-source $PLUTO_MY_SOURCEIP
+	echo "deleted NAT rule mapping PH_IP_ALICE to virtual IP $PLUTO_MY_SOURCEIP" >&2
 	;;
 *)	echo "$0: unknown verb \`$PLUTO_VERB' or parameter \`$1'" >&2
 	exit 1
diff --git a/testing/tests/ikev1/net2net-fragmentation/evaltest.dat b/testing/tests/ikev1/net2net-fragmentation/evaltest.dat
index 842eda0..2dd5a40 100644
--- a/testing/tests/ikev1/net2net-fragmentation/evaltest.dat
+++ b/testing/tests/ikev1/net2net-fragmentation/evaltest.dat
@@ -1,7 +1,7 @@
 moon::cat /var/log/daemon.log::received FRAGMENTATION vendor ID::YES
 sun::cat /var/log/daemon.log::received FRAGMENTATION vendor ID::YES
-moon::cat /var/log/daemon.log::splitting IKE message with length of 1468 bytes into 2 fragments::YES
-sun::cat /var/log/daemon.log::splitting IKE message with length of 1388 bytes into 2 fragments::YES
+moon::cat /var/log/daemon.log::splitting IKE message with length of .*bytes into 2 fragments::YES
+sun::cat /var/log/daemon.log::splitting IKE message with length of .*bytes into 2 fragments::YES
 moon::cat /var/log/daemon.log::received fragment #1, waiting for complete IKE message::YES
 moon::cat /var/log/daemon.log::received fragment #2, reassembling fragmented IKE message::YES
 sun::cat /var/log/daemon.log::received fragment #1, waiting for complete IKE message::YES
diff --git a/testing/tests/ikev2/critical-extension/hosts/moon/etc/ipsec.d/private/moonKey.pem b/testing/tests/ikev2/critical-extension/hosts/moon/etc/ipsec.d/private/moonKey.pem
new file mode 100644
index 0000000..4d99866
--- /dev/null
+++ b/testing/tests/ikev2/critical-extension/hosts/moon/etc/ipsec.d/private/moonKey.pem
@@ -0,0 +1,27 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIIEowIBAAKCAQEAyi9jPdS7ugWGIVsVoDEvc/UzEk8LM5ua4Tu2SLArTEaODwHm
+MPvvkhl7dwj12//qfklihpZtdazxO9XkN3oYIdgt4QLq35ljtIkEGgsPn3a3niFQ
+qjkCDj+lKmd9u4ecmGKR5PFUL+LwSU6cXJVNT6p1oXqntWZS8bFu+9y0Zpf30Lf1
+ILyZAgU2WTjSzTHyvu0w52GlbALZ3ILwze/J1DRHtqmPdiiu0qwSekqVBIOPZudR
+fl4LBnLIFlR0vOaJ9zpvxuPHKyxFSY3bvAsXsEkVYG/pTyVsx3fELFNFYP+75arN
+2UTMjbTSq6+KKUr1WwOmoBpU14Qwq3g4l1PChwIDAQABAoIBACBFB/Xqajv6fbn9
+K6pxrz02uXwGmacXAtVIDoPzejWmXS4QA4l17HrJDmelSnhelDKry8nnYHkTrTz7
+mn0wQ4HDWy86o/okJUG/TKRLd6bf79aRQqqohqd3iQkHk43GyzuXH+oGioVKF0fc
+ACDWw4wfjL7FMNdHCZ4Bz9DrHO/ysHe9B6rvSYm3VZRhSxaneIkaLkkDadKpVx3f
+XNFlMxY4qKPJYYSoJZ61iMqrO7+rnA93tmyDDs8PKU3BtnpfNrdePgleJHhk8Zqy
+Ev2/NOCSUxbKE8NCtLpGTs+T0qjjnu4k3WPd3ZOBAan0uPDekHZeHB/aXGLhYcxx
+J5SurqECgYEA+F1gppkER5Jtoaudt/CUpdQ1sR9wxf75VBqJ4FiYABGQz9xlG4oj
+zL/o572s0iV3bwFpnQa+WuWrxGkP6ZuB/Z82npc0N/vLou/b4dxvg4n7K+eOOEf0
+8FMjsse2tqTIXKCqcmQnR0NPQ1jwuvEKsXP5w/JOlnRXAXnd4jxsJI0CgYEA0GaT
+61ySttUW9jC3mxuY6jkQy8TEQqR3nOFvWwmCXIWOpN/MTTPus+Telxp/pdKhU+mo
+PmX3Unyne5PvwleWDq3YzltX5ZDZGJ5UJlKuNnfGIzQ6OcHRbb7zBpQG6qSRPuug
+bgo688hTnb1L59nK88zWVK45euf6pyuoI+SwIGMCgYEA7yvE8knyhBXvezuv0z1b
+eGHmHp5/VDwY0DQKSEAoiBBiWrkLqLybgwXf/KJ8dZZc8En08aFX2GLJyYe/KiB1
+ys3ypEBJqgvRayP+o/9KZ+qNNRd0rqAksPXvL7ABNNt0kzapTSVDae3Yu6s/j1am
+DIL5qAeERIDedG5uDPpQzdUCgYB7MtjpP63ABhLv8XbpbBQnCxtByw3W89F+Xcrt
+v55gQdhE4cSuMzA/CuMH4vNpPS6AI9aBJNhj3CtKo/cOJachAGb1/wvkO5ALvLW0
+fhZdPstUTnDJain7vfF/hwzbs/PlhXgu9T9KlLfRvXFdG+Sd4g8mumRiozcLkoRw
+y6XPTwKBgDJP+s9wXmdG90HST/aqC7FKrVXLpB63dY5swNUfQP6sa0pFnON0r0JC
+h/YCsGFFIAebQ2uOkM3g3f9nkwTp7910ov+/5uThvRI2w2BBPy0mVuALPjyyF1Z2
+cb9zpyKiIuXoXRCf4sd8r1lR9bn0Fxx0Svpxf+fpMGSI5quHNBKY
+-----END RSA PRIVATE KEY-----
diff --git a/testing/tests/ikev2/critical-extension/hosts/sun/etc/ipsec.d/private/sunKey.pem b/testing/tests/ikev2/critical-extension/hosts/sun/etc/ipsec.d/private/sunKey.pem
new file mode 100644
index 0000000..d8fad9a
--- /dev/null
+++ b/testing/tests/ikev2/critical-extension/hosts/sun/etc/ipsec.d/private/sunKey.pem
@@ -0,0 +1,27 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIIEpAIBAAKCAQEA35VUimfpDmNpT/8Q3qnoDlxJ9R+EErSYVraVoUVmH9jSHroB
+eqqtDdf3XuHtg2xKTryijBj2H0jeA7HuE1UGwmvZWN1gL5vSrk1OFrT38DmaKa/+
+mtiPqjTJrDGg+OgOz1iHsPsp/4Xx+SCTSy2Ucllfront02sVduDXEGV34Snk6vYV
+sRn1BZSlFBO6F2k23/j1i7FDn0N6Zj0hFvCysoIcfSYasmwN2p5vRqn7xC9JceMK
+3V+v0w0pZoAUBAspAjh7R1rWe08IRAt4Tzff401EGAa5+TQqoZPd4BeqvFr0AQhQ
+mdVw97FB2pQyNxSlcVvxY3NFYHwSCHcEMroWwQIDAQABAoIBADH51hjN2zk9HVgl
+QmcTAWzcUie5cLMhrP+M9mtC8O3jcCwwFY6OwfnbMU8DHy0GMqHg5lB8b99UUVPw
+HLAzjDw/ESkc6pgZs4EEhJTsxJLsvTnePgHssEgyXnXf7gRVEqJkPohfy+Zy0UCH
+eIUQXiMlOQ7xg7iDMhwNa+UdWSt539DztSKilQn2xdPZjFnMT0/prvl4NA/8Zn54
+/SdWDq5yRdLWb6EK1V7yJ3687GXR1jzGtgy7TXuncUJVTYgX7RdP1Tn6gWD8YAQ/
+RfT0DdWYm4WHSgSb9/NW8lBZH2yy3hg+lNgofXEvTfBkO5QyW31LIr0tCV6zhJIc
+Y9MxaKUCgYEA9sktaXfhPLe0ECjdeQEOq5EKuDrCviSKCOuAV4BDSOsdw6+5LWfY
+Vb/oke8N70lL3RCblcj1pOKWUi2O/SpEJdDRduiw2gM9cXt3/bChSTHC4TsIxxN/
+Db9OGg72kZ4sRY5Au+zyAAQYBwXhFWux194Jk5qK0JblNG9J5QMqZDcCgYEA5+5h
+BgHUMEO+pdME5lAiSc5PcNTejpA6j+OikCh4/HFXy3C/dLx+Cs1+egw64c8iVaIv
+NEo7n7E9I0e3XqanPRXhMnBRrP+39OVsWPmZ18Li2Hi84KwJyi8Y11l3XJOqaYpF
+wMVUuZpxR0dfG5k/5GwT/tEkmQBglOgG3m2zUMcCgYEA4m3Vd9ahV5dp5AXKpzKc
+JjiPMFfhxJo7+FEz0ZUCp03qYljBu/Jy4MKS/grrqyiCLdQGHNlk4SNxLvdUId78
+5gGBnuuDEJU2dAAIKUE9yq2YlBUZSacOxStI2snt28/X6P3LUWHm7LLU5OS1D3Vf
+mKPF/6MlSJuas5CEqVZNN+MCgYBH9Qh7IaQgmVQUBKVXg3Mv7OduvUyTdKIGtHxi
+N3xZ7hxsDP4JjNWaKmlcGmFGX8pqQRheI83d3NJ4GK8GmbP3Wst0p65fezMqsudr
+r30QmPFicgs/tYCQDw6o+aPzwAi2F+VOSqrfrtAIaldSq7hL+VA21dKB+cD9UgOX
+jPd+TwKBgQCbKeg2QNS2qhPIG9eaqJDROuxmxb/07d7OBctgMgxVvKhqW9hW42Sy
+gJ59fyz5QjFBaSfcOdf4gkKyEawVo45/q6ymIQU37R4vF4CW9Z3CfaIbwJp7LcHV
+zH07so/HNsZua6GWCSCLJU5MeCRiZzk2RFiS9KIaLP4gZndv4lXOiQ==
+-----END RSA PRIVATE KEY-----
diff --git a/testing/tests/ikev2/double-nat-net/evaltest.dat b/testing/tests/ikev2/double-nat-net/evaltest.dat
index 52c5619..8f5ffdb 100644
--- a/testing/tests/ikev2/double-nat-net/evaltest.dat
+++ b/testing/tests/ikev2/double-nat-net/evaltest.dat
@@ -1,7 +1,7 @@
 alice::ipsec status 2> /dev/null::nat-t.*ESTABLISHED.*alice at strongswan.org.*bob at strongswan.org::YES
 bob::  ipsec status 2> /dev/null::nat-t.*ESTABLISHED.*bob at strongswan.org.*alice at strongswan.org::YES
-alice::ipsec status 2> /dev/null::nat-t.*INSTALLED, TUNNEL, ESP in UDP::YES
-bob::  ipsec status 2> /dev/null::nat-t.*INSTALLED, TUNNEL, ESP in UDP::YES
+alice::ipsec status 2> /dev/null::nat-t.*INSTALLED, TUNNEL.*ESP in UDP::YES
+bob::  ipsec status 2> /dev/null::nat-t.*INSTALLED, TUNNEL.*ESP in UDP::YES
 alice::ping -c 1 PH_IP_SUN1::64 bytes from PH_IP_SUN1: icmp_req=1::YES
 moon::tcpdump::IP moon.strongswan.org.* > sun.strongswan.org.4500: UDP::YES
 moon::tcpdump::IP sun.strongswan.org.4500 > moon.strongswan.org.*: UDP::YES
diff --git a/testing/tests/ikev2/double-nat/evaltest.dat b/testing/tests/ikev2/double-nat/evaltest.dat
index 9ddad2d..5f06226 100644
--- a/testing/tests/ikev2/double-nat/evaltest.dat
+++ b/testing/tests/ikev2/double-nat/evaltest.dat
@@ -1,7 +1,7 @@
 alice::ipsec status 2> /dev/null::nat-t.*ESTABLISHED.*alice at strongswan.org.*bob at strongswan.org::YES
 bob::  ipsec status 2> /dev/null::nat-t.*ESTABLISHED.*bob at strongswan.org.*alice at strongswan.org::YES
-alice::ipsec status 2> /dev/null::nat-t.*INSTALLED, TUNNEL, ESP in UDP::YES
-bob::  ipsec status 2> /dev/null::nat-t.*INSTALLED, TUNNEL, ESP in UDP::YES
+alice::ipsec status 2> /dev/null::nat-t.*INSTALLED, TUNNEL.*ESP in UDP::YES
+bob::  ipsec status 2> /dev/null::nat-t.*INSTALLED, TUNNEL.*ESP in UDP::YES
 alice::ping -c 1 PH_IP_BOB::64 bytes from PH_IP_BOB: icmp_req=1::YES
 moon::tcpdump::IP moon.strongswan.org.* > sun.strongswan.org.4500: UDP::YES
 moon::tcpdump::IP sun.strongswan.org.4500 > moon.strongswan.org.*: UDP::YES
diff --git a/testing/tests/ikev2/forecast/description.txt b/testing/tests/ikev2/forecast/description.txt
new file mode 100644
index 0000000..db67b9c
--- /dev/null
+++ b/testing/tests/ikev2/forecast/description.txt
@@ -0,0 +1,8 @@
+The roadwarriors <b>carol</b> and <b>dave</b> set up a connection each to
+gateway <b>moon</b> and request a <b>virtual IP</b>. <b>moon</b> negotiates
+broadcast and multicast traffic selectors with the clients, and uses
+<i>%unique</i> marks to avoid any policy conflicts. The enabled <i>forecast</i>
+plugin on <b>moon</b> installs the required Netfilter rules to make use of these
+policies, and additionally starts forwarding broadcast and multicast packets
+between the clients.<br/>
+To test forwarding, the hosts send multicast and broadcast ping messages.
diff --git a/testing/tests/ikev2/forecast/evaltest.dat b/testing/tests/ikev2/forecast/evaltest.dat
new file mode 100644
index 0000000..6babe57
--- /dev/null
+++ b/testing/tests/ikev2/forecast/evaltest.dat
@@ -0,0 +1,20 @@
+carol::ipsec status 2> /dev/null::home.*ESTABLISHED.*carol at strongswan.org.*moon.strongswan.org::YES
+carol::ipsec status 2> /dev/null::home.*INSTALLED, TUNNEL::YES
+dave:: ipsec status 2> /dev/null::home.*ESTABLISHED.*dave at strongswan.org.*moon.strongswan.org::YES
+dave:: ipsec status 2> /dev/null::home.*INSTALLED, TUNNEL::YES
+moon:: ipsec status 2> /dev/null::rw.*ESTABLISHED.*moon.strongswan.org.*carol at strongswan.org::YES
+moon:: ipsec status 2> /dev/null::rw.*ESTABLISHED.*moon.strongswan.org.*dave at strongswan.org::YES
+moon:: ipsec status 2> /dev/null::rw.*INSTALLED, TUNNEL, reqid 1::YES
+moon:: ipsec status 2> /dev/null::rw.*INSTALLED, TUNNEL, reqid 2::YES
+alice::ping -W 1 -c 1 239.0.0.1 2>&1> /dev/null
+carol::ping -W 1 -c 1 239.0.0.2 2>&1> /dev/null
+dave::ping -W 1 -c 1 239.0.0.3 2>&1> /dev/null
+carol::ping -W 1 -c 1 -b 10.1.255.255 2>&1> /dev/null
+dave::ping -W 1 -c 1 -b 10.1.255.255 2>&1> /dev/null
+moon::iptables -t mangle -L -n -v
+carol::tcpdump::IP alice.strongswan.org > 239.0.0.1: ICMP echo request::YES
+dave::tcpdump::IP alice.strongswan.org > 239.0.0.1: ICMP echo request::YES
+carol::tcpdump::IP 10.1.0.130 > 239.0.0.3: ICMP echo request::YES
+dave::tcpdump::IP 10.1.0.129 > 239.0.0.2: ICMP echo request::YES
+carol::tcpdump::IP 10.1.0.130 > 10.1.255.255: ICMP echo request::YES
+dave::tcpdump::IP 10.1.0.129 > 10.1.255.255: ICMP echo request::YES
diff --git a/testing/tests/ikev2/forecast/hosts/carol/etc/ipsec.conf b/testing/tests/ikev2/forecast/hosts/carol/etc/ipsec.conf
new file mode 100644
index 0000000..4cd6283
--- /dev/null
+++ b/testing/tests/ikev2/forecast/hosts/carol/etc/ipsec.conf
@@ -0,0 +1,21 @@
+# /etc/ipsec.conf - strongSwan IPsec configuration file
+
+config setup
+
+conn %default
+	ikelifetime=60m
+	keylife=20m
+	rekeymargin=3m
+	keyingtries=1
+	keyexchange=ikev2
+
+conn home
+	left=PH_IP_CAROL
+	leftsourceip=%config
+	leftsubnet=0.0.0.0/0
+	leftcert=carolCert.pem
+	leftid=carol at strongswan.org
+	right=PH_IP_MOON
+	rightsubnet=0.0.0.0/0
+	rightid=@moon.strongswan.org
+	auto=add
diff --git a/testing/tests/ikev2/forecast/hosts/carol/etc/strongswan.conf b/testing/tests/ikev2/forecast/hosts/carol/etc/strongswan.conf
new file mode 100644
index 0000000..7b81476
--- /dev/null
+++ b/testing/tests/ikev2/forecast/hosts/carol/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 resolve
+}
diff --git a/testing/tests/ikev2/forecast/hosts/dave/etc/ipsec.conf b/testing/tests/ikev2/forecast/hosts/dave/etc/ipsec.conf
new file mode 100644
index 0000000..e2255d9
--- /dev/null
+++ b/testing/tests/ikev2/forecast/hosts/dave/etc/ipsec.conf
@@ -0,0 +1,21 @@
+# /etc/ipsec.conf - strongSwan IPsec configuration file
+
+config setup
+
+conn %default
+	ikelifetime=60m
+	keylife=20m
+	rekeymargin=3m
+	keyingtries=1
+	keyexchange=ikev2
+
+conn home
+	left=PH_IP_DAVE
+	leftsourceip=%config
+	leftsubnet=0.0.0.0/0
+	leftcert=daveCert.pem
+	leftid=dave at strongswan.org
+	right=PH_IP_MOON
+	rightsubnet=0.0.0.0/0
+	rightid=@moon.strongswan.org
+	auto=add
diff --git a/testing/tests/ikev2/forecast/hosts/dave/etc/strongswan.conf b/testing/tests/ikev2/forecast/hosts/dave/etc/strongswan.conf
new file mode 100644
index 0000000..7b81476
--- /dev/null
+++ b/testing/tests/ikev2/forecast/hosts/dave/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 resolve
+}
diff --git a/testing/tests/ikev2/forecast/hosts/moon/etc/ipsec.conf b/testing/tests/ikev2/forecast/hosts/moon/etc/ipsec.conf
new file mode 100644
index 0000000..fde2e91
--- /dev/null
+++ b/testing/tests/ikev2/forecast/hosts/moon/etc/ipsec.conf
@@ -0,0 +1,22 @@
+# /etc/ipsec.conf - strongSwan IPsec configuration file
+
+config setup
+
+conn %default
+	ikelifetime=60m
+	keylife=20m
+	rekeymargin=3m
+	keyingtries=1
+	keyexchange=ikev2
+
+conn rw
+	left=PH_IP_MOON
+	leftcert=moonCert.pem
+	leftid=@moon.strongswan.org
+	leftsubnet=10.1.0.0/16,224.0.0.0/4
+	right=%any
+	rightid=*@strongswan.org
+	rightsourceip=10.1.0.128/26
+	rightsubnet=%dynamic,224.0.0.0/4,10.1.255.255
+	mark=%unique
+	auto=add
diff --git a/testing/tests/ikev2/forecast/hosts/moon/etc/strongswan.conf b/testing/tests/ikev2/forecast/hosts/moon/etc/strongswan.conf
new file mode 100644
index 0000000..986ef32
--- /dev/null
+++ b/testing/tests/ikev2/forecast/hosts/moon/etc/strongswan.conf
@@ -0,0 +1,16 @@
+# /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 attr forecast
+  syslog {
+    daemon {
+      net = 2
+    }
+  }
+  plugins {
+    forecast {
+      interface = eth1
+      reinject = rw
+    }
+  }
+}
diff --git a/testing/tests/ikev2/forecast/posttest.dat b/testing/tests/ikev2/forecast/posttest.dat
new file mode 100644
index 0000000..1865a1c
--- /dev/null
+++ b/testing/tests/ikev2/forecast/posttest.dat
@@ -0,0 +1,6 @@
+moon::ipsec stop
+carol::ipsec stop
+dave::ipsec stop
+moon::iptables-restore < /etc/iptables.flush
+carol::iptables-restore < /etc/iptables.flush
+dave::iptables-restore < /etc/iptables.flush
diff --git a/testing/tests/ikev2/forecast/pretest.dat b/testing/tests/ikev2/forecast/pretest.dat
new file mode 100644
index 0000000..206bf5b
--- /dev/null
+++ b/testing/tests/ikev2/forecast/pretest.dat
@@ -0,0 +1,7 @@
+carol::ipsec start
+dave::ipsec start
+moon::ipsec start
+carol::sleep 2
+carol::ipsec up home
+dave::ipsec up home
+carol::sleep 1
diff --git a/testing/tests/ikev2/forecast/test.conf b/testing/tests/ikev2/forecast/test.conf
new file mode 100644
index 0000000..13b3927
--- /dev/null
+++ b/testing/tests/ikev2/forecast/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 carol winnetou dave"
+
+# Corresponding block diagram
+#
+DIAGRAM="a-m-c-w-d.png"
+
+# Guest instances on which tcpdump is to be started
+#
+TCPDUMPHOSTS="moon carol dave"
+
+# Guest instances on which IPsec is started
+# Used for IPsec logging purposes
+#
+IPSECHOSTS="moon carol dave"
diff --git a/testing/tests/ikev2/host2host-transport-connmark/description.txt b/testing/tests/ikev2/host2host-transport-connmark/description.txt
new file mode 100644
index 0000000..6660279
--- /dev/null
+++ b/testing/tests/ikev2/host2host-transport-connmark/description.txt
@@ -0,0 +1,8 @@
+An IPsec <b>transport-mode</b> connection between the natted host <b>alice</b>
+and gateway <b>sun</b> is successfully set up. The client <b>venus</b> behind
+the same NAT as client <b>alice</b> also establishes the same <b>transport-mode</b>
+connection. <b>sun</b> uses the connmark plugin and a <b>%unique</b> mark on
+the CHILD_SAs to select the correct return path SA using connection tracking.
+This allows <b>sun</b> to talk to both nodes for client initiated flows, even
+if the SAs are actually both over <b>moon</b>.<br/>
+To test the connection, both hosts establish an SSH connection to <b>sun</b>.
diff --git a/testing/tests/ikev2/host2host-transport-connmark/evaltest.dat b/testing/tests/ikev2/host2host-transport-connmark/evaltest.dat
new file mode 100644
index 0000000..04a35c1
--- /dev/null
+++ b/testing/tests/ikev2/host2host-transport-connmark/evaltest.dat
@@ -0,0 +1,7 @@
+sun:: ipsec status 2> /dev/null::nat-t.*ESTABLISHED.*sun.strongswan.org.*venus.strongswan.org::YES
+sun:: ipsec status 2> /dev/null::nat-t.*ESTABLISHED.*sun.strongswan.org.*alice at strongswan.org::YES
+alice::ipsec status 2> /dev/null::nat-t.*INSTALLED, TRANSPORT, reqid 1::YES
+venus::ipsec status 2> /dev/null::nat-t.*INSTALLED, TRANSPORT, reqid 1::YES
+alice::ssh 192.168.0.2 'echo alice-echo && exit'::alice-echo::YES
+venus::ssh 192.168.0.2 'echo venus-echo && exit'::venus-echo::YES
+sun::iptables -t mangle -L -n -v
diff --git a/testing/tests/ikev2/host2host-transport-connmark/hosts/alice/etc/ipsec.conf b/testing/tests/ikev2/host2host-transport-connmark/hosts/alice/etc/ipsec.conf
new file mode 100644
index 0000000..9000ebc
--- /dev/null
+++ b/testing/tests/ikev2/host2host-transport-connmark/hosts/alice/etc/ipsec.conf
@@ -0,0 +1,17 @@
+# /etc/ipsec.conf - strongSwan IPsec configuration file
+
+config setup
+
+conn %default
+	ikelifetime=60m
+	keylife=20m
+	rekeymargin=3m
+	keyingtries=1
+
+conn nat-t
+	leftcert=aliceCert.pem
+	leftid=alice at strongswan.org
+	right=192.168.0.2
+	rightid=@sun.strongswan.org
+	type=transport
+	auto=add
diff --git a/testing/tests/ikev2/host2host-transport-connmark/hosts/sun/etc/ipsec.conf b/testing/tests/ikev2/host2host-transport-connmark/hosts/sun/etc/ipsec.conf
new file mode 100644
index 0000000..220059c
--- /dev/null
+++ b/testing/tests/ikev2/host2host-transport-connmark/hosts/sun/etc/ipsec.conf
@@ -0,0 +1,18 @@
+# /etc/ipsec.conf - strongSwan IPsec configuration file
+
+config setup
+
+conn %default
+	ikelifetime=60m
+	keylife=20m
+	rekeymargin=3m
+	keyingtries=1
+	left=192.168.0.2
+	leftcert=sunCert.pem
+	leftid=@sun.strongswan.org
+
+conn nat-t
+	right=%any
+	type=transport
+	mark=%unique
+	auto=add
diff --git a/testing/tests/ikev2/host2host-transport-connmark/hosts/sun/etc/strongswan.conf b/testing/tests/ikev2/host2host-transport-connmark/hosts/sun/etc/strongswan.conf
new file mode 100644
index 0000000..1311e5b
--- /dev/null
+++ b/testing/tests/ikev2/host2host-transport-connmark/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 connmark
+}
diff --git a/testing/tests/ikev2/host2host-transport-connmark/hosts/venus/etc/ipsec.conf b/testing/tests/ikev2/host2host-transport-connmark/hosts/venus/etc/ipsec.conf
new file mode 100644
index 0000000..cea239a
--- /dev/null
+++ b/testing/tests/ikev2/host2host-transport-connmark/hosts/venus/etc/ipsec.conf
@@ -0,0 +1,17 @@
+# /etc/ipsec.conf - strongSwan IPsec configuration file
+
+config setup
+
+conn %default
+	ikelifetime=60m
+	keylife=20m
+	rekeymargin=3m
+	keyingtries=1
+
+conn nat-t
+	leftcert=venusCert.pem
+	leftid=venus at strongswan.org
+	right=192.168.0.2
+	rightid=@sun.strongswan.org
+	type=transport
+	auto=add
diff --git a/testing/tests/ikev2/host2host-transport-connmark/posttest.dat b/testing/tests/ikev2/host2host-transport-connmark/posttest.dat
new file mode 100644
index 0000000..144be6c
--- /dev/null
+++ b/testing/tests/ikev2/host2host-transport-connmark/posttest.dat
@@ -0,0 +1,5 @@
+alice::ipsec stop
+venus::ipsec stop
+sun::ipsec stop
+moon::iptables-restore < /etc/iptables.flush
+sun::iptables-restore < /etc/iptables.flush
diff --git a/testing/tests/ikev2/host2host-transport-connmark/pretest.dat b/testing/tests/ikev2/host2host-transport-connmark/pretest.dat
new file mode 100644
index 0000000..ab64084
--- /dev/null
+++ b/testing/tests/ikev2/host2host-transport-connmark/pretest.dat
@@ -0,0 +1,11 @@
+moon::iptables-restore < /etc/iptables.rules
+moon::iptables -t nat -A POSTROUTING -o eth0 -s 10.1.0.0/16 -j MASQUERADE
+moon::iptables -A FORWARD -i eth1 -o eth0 -s 10.1.0.0/16  -j ACCEPT
+moon::iptables -A FORWARD -i eth0 -o eth1 -d 10.1.0.0/16  -j ACCEPT
+alice::ipsec start
+venus::ipsec start
+sun::ipsec start
+alice::expect-connection nat-t
+venus::expect-connection nat-t
+alice::ipsec up nat-t
+venus::ipsec up nat-t
diff --git a/testing/tests/ikev2/host2host-transport-connmark/test.conf b/testing/tests/ikev2/host2host-transport-connmark/test.conf
new file mode 100644
index 0000000..8c2face
--- /dev/null
+++ b/testing/tests/ikev2/host2host-transport-connmark/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"
+
+# Corresponding block diagram
+#
+DIAGRAM="a-m-w-s-b.png"
+
+# Guest instances on which tcpdump is to be started
+#
+TCPDUMPHOSTS="sun alice venus moon"
+
+# Guest instances on which IPsec is started
+# Used for IPsec logging purposes
+#
+IPSECHOSTS="alice venus sun"
diff --git a/testing/tests/ikev2/host2host-transport-nat/description.txt b/testing/tests/ikev2/host2host-transport-nat/description.txt
index 6f18a88..fc7186c 100644
--- a/testing/tests/ikev2/host2host-transport-nat/description.txt
+++ b/testing/tests/ikev2/host2host-transport-nat/description.txt
@@ -9,5 +9,6 @@ rules that let pass the decrypted IP packets. In order to test the host-to-host
 dropped when the IPsec policies are consulted (increases the <em>XfrmInTmplMismatch</em> counter
 in <em>/proc/net/xfrm_stat</em>).</li>
 <li>A similar issue arises when <b>venus</b> also establishes an IPsec <b>transport-mode</b> connection to
-<b>sun</b>, due to the conflicting IPsec policies <b>sun</b> declines such a connection.</li>
+<b>sun</b>. Due to the conflicting IPsec policies <b>sun</b> will use the newer SA from
+<b>venus</b> to send traffic to the common transport mode address.</li>
 </ol>
diff --git a/testing/tests/ikev2/host2host-transport-nat/evaltest.dat b/testing/tests/ikev2/host2host-transport-nat/evaltest.dat
index faa9fb2..0ec50bc 100644
--- a/testing/tests/ikev2/host2host-transport-nat/evaltest.dat
+++ b/testing/tests/ikev2/host2host-transport-nat/evaltest.dat
@@ -1,12 +1,9 @@
 alice::ipsec status 2> /dev/null::nat-t.*ESTABLISHED.*alice at strongswan.org.*sun.strongswan.org::YES
 sun:: ipsec status 2> /dev/null::nat-t.*ESTABLISHED.*sun.strongswan.org.*alice at strongswan.org::YES
-alice::ipsec status 2> /dev/null::nat-t.*INSTALLED, TRANSPORT::YES
-sun:: ipsec status 2> /dev/null::nat-t.*INSTALLED, TRANSPORT::YES
-alice::ping -c 1 PH_IP_SUN::64 bytes from PH_IP_SUN: icmp_req=1::YES
-venus::ping -c 1 -W 1 PH_IP_SUN::64 bytes from PH_IP_SUN: icmp_req=1::NO
-venus::ipsec up nat-t::received TS_UNACCEPTABLE notify::YES
-sun::cat /var/log/daemon.log::unable to install policy::YES
+alice::ipsec status 2> /dev/null::nat-t.*INSTALLED, TRANSPORT, reqid 1::YES
+venus::ipsec status 2> /dev/null::nat-t.*INSTALLED, TRANSPORT, reqid 1::YES
+sun:: ipsec status 2> /dev/null::nat-t.*INSTALLED, TRANSPORT, reqid 1::YES
+alice::ping -c 1 -W 1 PH_IP_SUN::64 bytes from PH_IP_SUN: icmp_req=1::NO
+venus::ping -c 1 -W 1 PH_IP_SUN::64 bytes from PH_IP_SUN: icmp_req=1::YES
 sun::tcpdump::IP moon.strongswan.org.* > sun.strongswan.org.*: UDP::YES
 sun::tcpdump::IP sun.strongswan.org.* > moon.strongswan.org.*: UDP::YES
-sun::tcpdump::IP moon.strongswan.org > sun.strongswan.org: ICMP echo request::YES
-sun::tcpdump::IP sun.strongswan.org > moon.strongswan.org: ICMP echo reply::NO
diff --git a/testing/tests/ikev2/host2host-transport-nat/pretest.dat b/testing/tests/ikev2/host2host-transport-nat/pretest.dat
index fe0f17d..2d26070 100644
--- a/testing/tests/ikev2/host2host-transport-nat/pretest.dat
+++ b/testing/tests/ikev2/host2host-transport-nat/pretest.dat
@@ -10,3 +10,4 @@ sun::ipsec start
 alice::expect-connection nat-t
 venus::expect-connection nat-t
 alice::ipsec up nat-t
+venus::ipsec up nat-t
diff --git a/testing/tests/ikev2/mult-auth-rsa-eap-sim-id/evaltest.dat b/testing/tests/ikev2/mult-auth-rsa-eap-sim-id/evaltest.dat
index 65a003d..8457ae0 100644
--- a/testing/tests/ikev2/mult-auth-rsa-eap-sim-id/evaltest.dat
+++ b/testing/tests/ikev2/mult-auth-rsa-eap-sim-id/evaltest.dat
@@ -1,6 +1,6 @@
 moon:: cat /var/log/daemon.log::parsed IKE_AUTH request.*N(AUTH_FOLLOWS)::YES
-moon:: cat /var/log/daemon.log::authentication of .*carol at strongswan.org.* with RSA signature successful::YES
-carol::cat /var/log/daemon.log::authentication of .*moon.strongswan.org.* with RSA signature successful::YES
+moon:: cat /var/log/daemon.log::authentication of .*carol at strongswan.org.* with RSA.* successful::YES
+carol::cat /var/log/daemon.log::authentication of .*moon.strongswan.org.* with RSA.* successful::YES
 carol::cat /var/log/daemon.log::server requested EAP_SIM authentication::YES
 moon:: cat /var/log/daemon.log::received EAP identity .*228060123456001::YES
 moon:: cat /var/log/daemon.log::authentication of .*228060123456001 at strongswan.org.* with EAP successful::YES
@@ -9,8 +9,8 @@ carol::ipsec status 2> /dev/null::home.*ESTABLISHED.*228060123456001 at strongswan.
 carol::ping -c 1 PH_IP_ALICE::64 bytes from PH_IP_ALICE: icmp_req=1::YES
 moon::tcpdump::IP carol.strongswan.org > moon.strongswan.org: ESP::YES
 moon::tcpdump::IP moon.strongswan.org > carol.strongswan.org: ESP::YES
-moon::cat /var/log/daemon.log::authentication of .*dave at strongswan.org.* with RSA signature successful::YES
-dave::cat /var/log/daemon.log::authentication of .*moon.strongswan.org.* with RSA signature successful::YES
+moon::cat /var/log/daemon.log::authentication of .*dave at strongswan.org.* with RSA.* successful::YES
+dave::cat /var/log/daemon.log::authentication of .*moon.strongswan.org.* with RSA.* successful::YES
 dave::cat /var/log/daemon.log::server requested EAP_SIM authentication::YES
 moon::cat /var/log/daemon.log::received EAP identity .*228060123456002::YES
 moon::cat /var/log/daemon.log::RADIUS authentication of '228060123456002' failed::YES
diff --git a/testing/tests/ikev2/multi-level-ca-pathlen/hosts/carol/etc/ipsec.d/certs/carolCert.pem b/testing/tests/ikev2/multi-level-ca-pathlen/hosts/carol/etc/ipsec.d/certs/carolCert.pem
index 4e13b52..70b953e 100644
--- a/testing/tests/ikev2/multi-level-ca-pathlen/hosts/carol/etc/ipsec.d/certs/carolCert.pem
+++ b/testing/tests/ikev2/multi-level-ca-pathlen/hosts/carol/etc/ipsec.d/certs/carolCert.pem
@@ -1,24 +1,24 @@
 -----BEGIN CERTIFICATE-----
 MIIEBzCCAu+gAwIBAgIBATANBgkqhkiG9w0BAQsFADBWMQswCQYDVQQGEwJDSDEZ
 MBcGA1UEChMQTGludXggc3Ryb25nU3dhbjERMA8GA1UECxMIUmVzZWFyY2gxGTAX
-BgNVBAMTEER1Y2sgUmVzZWFyY2ggQ0EwHhcNMDkxMTA0MTYyMzM1WhcNMTQxMTAz
-MTYyMzM1WjBfMQswCQYDVQQGEwJDSDEZMBcGA1UEChMQTGludXggc3Ryb25nU3dh
+BgNVBAMTEER1Y2sgUmVzZWFyY2ggQ0EwHhcNMTQxMTI4MjIxODIyWhcNMTkwMjI1
+MjIxODIyWjBfMQswCQYDVQQGEwJDSDEZMBcGA1UEChMQTGludXggc3Ryb25nU3dh
 bjEWMBQGA1UECxMNRHVjayBSZXNlYXJjaDEdMBsGA1UEAxQUY2Fyb2xAc3Ryb25n
-c3dhbi5vcmcwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC6LueCi67Y
-IGRDKP5bkysGWZHrFrztq7elIFCPPSUxyIOYo4Upzr5WsvO0dIfcZY3agV2NcAI2
-30sATlfTUp+obedZMHbzE3VBvQuLjgK42ox2XIXDj23Vy496mVqlwUQulhBcAhMb
-jnBb4T0aR7WCnJvfzyckEyWrTN0ajRyQhJEmTn+spYNQX/2lg6hEn/K1T/3Py7sG
-veeF6BRenHR5L60NSK7qV7AU+hM4R0UIvgwYqzxSStgGS9G6Bwj9QTOWwSV1tuii
-ABiRdZSBoON0uMMpRjgEzuVe0f4VbOCIEXO8MtdpCu7Rwa9tc8OwneLcGCYVomr5
-7KKRJdvC5As3AgMBAAGjgdYwgdMwCQYDVR0TBAIwADALBgNVHQ8EBAMCA6gwHQYD
-VR0OBBYEFFSYDz2TYOMxfyrIx20NhPPHTCOIMHkGA1UdIwRyMHCAFHYqqKQxp8Zx
-jzAlvAJmm8sXVI0goVWkUzBRMQswCQYDVQQGEwJDSDEZMBcGA1UEChMQTGludXgg
+c3dhbi5vcmcwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDNBbHnfLRk
+Lvxh9V7x/NoSs5qavpr8F51LnYpIfppgMvBDjpdeSnBPOOPakPlfUhKSvXIesESv
+QI1HJOlGftswL9A5B1lTnsH65sqpgqgj67grh386U3O9ZccFhUj8Dw6TUo/qe4pK
+sWDwUX/LG3mjOx/rOGvX8WxvZU7JVXXhU4g8TpIV3JRTQ+lF82z3qoS6dAfRt4xh
+6pyLuMYbu6UtX5Al0iJDvpsWr9ZbKI2f8Dhkr0sZFRHl7Gs5jTN1Ra1EF0jCjIzo
+6AkkY+ITBssvVvMFpeN/jb0ZhvLcRFU56lvLkmrj/InKUsk9qNm80+/wFBUzJ5N7
+GezXmBIPwXdlAgMBAAGjgdYwgdMwCQYDVR0TBAIwADALBgNVHQ8EBAMCA6gwHQYD
+VR0OBBYEFLPw4VsFnIRIKhjd/OF7delHM9kiMHkGA1UdIwRyMHCAFIpw4MqlHGRv
+K5K5c1wBrJAb/fk1oVWkUzBRMQswCQYDVQQGEwJDSDEZMBcGA1UEChMQTGludXgg
 c3Ryb25nU3dhbjERMA8GA1UECxMIUmVzZWFyY2gxFDASBgNVBAMTC1Jlc2VhcmNo
-IENBggEFMB8GA1UdEQQYMBaBFGNhcm9sQHN0cm9uZ3N3YW4ub3JnMA0GCSqGSIb3
-DQEBCwUAA4IBAQBIpl8SH4Nytgr6KvmXzns80u615WnDmP6oJrnwIZUkunVns8HH
-TFUVjvDKoQ+8CvuaH9Ifo2dokGjtGObeO4Y38y0xBIkUO+JpwfTa3SeCEhdOZb3G
-4e9WxHhV9IGfRyPsXQG+3JpAMaHYH+PNKiv7RBTq6rGaHzvgUEXRMTbv/bJI+Fs6
-Yfd/XxIur/ftVh4dZocyC74MUyXy5tyZJkHe1aBszOa0iT1852fq93lNUQPQqw0O
-3q3Lg7CvbNSdWqeAMqUgeBqh6oQItY9Exrwh0tfuCsjZ0oWXUBghsuiV+GTmZ6ok
-BiGmSmtX5OD4UtKcicuMRqnK2MYJHp1z1goE
+IENBggEKMB8GA1UdEQQYMBaBFGNhcm9sQHN0cm9uZ3N3YW4ub3JnMA0GCSqGSIb3
+DQEBCwUAA4IBAQCi2vUHTZtkUGMAQsztQBLDwtqS7D+1ydO2BU/wkNRn4M7Zlkjq
+O2JBgwGmeWpnZWPdNo+A5ECqcVYXp0XQw/24zxV92StTN7mGvPKVM6bYExcCT8x6
+tVkzlfyjJaVdBgl12jkQA4v6Efwc0P6nunYfxYIrfoFA4kjMnAbxLfPKFEj8b8NW
+E9gvOEPy9hOv2dJEKyNxau+O5oGRZ46zSotcS0n34huoMEkXpUnpGOgZw8cl8xpP
+ffHiAJqZYgqU6B++HQO6M6IQ0nQmX6OxGz+5VhEmuizgWB0B1L65BlzAysdavLZN
+Yn4RdcYfpdbUgj5oRapiwWaQxpGImyQ1JBIU
 -----END CERTIFICATE-----
diff --git a/testing/tests/ikev2/multi-level-ca-pathlen/hosts/carol/etc/ipsec.d/private/carolKey.pem b/testing/tests/ikev2/multi-level-ca-pathlen/hosts/carol/etc/ipsec.d/private/carolKey.pem
index 48727ed..ce60672 100644
--- a/testing/tests/ikev2/multi-level-ca-pathlen/hosts/carol/etc/ipsec.d/private/carolKey.pem
+++ b/testing/tests/ikev2/multi-level-ca-pathlen/hosts/carol/etc/ipsec.d/private/carolKey.pem
@@ -1,27 +1,27 @@
 -----BEGIN RSA PRIVATE KEY-----
-MIIEpAIBAAKCAQEAui7ngouu2CBkQyj+W5MrBlmR6xa87au3pSBQjz0lMciDmKOF
-Kc6+VrLztHSH3GWN2oFdjXACNt9LAE5X01KfqG3nWTB28xN1Qb0Li44CuNqMdlyF
-w49t1cuPeplapcFELpYQXAITG45wW+E9Gke1gpyb388nJBMlq0zdGo0ckISRJk5/
-rKWDUF/9pYOoRJ/ytU/9z8u7Br3nhegUXpx0eS+tDUiu6lewFPoTOEdFCL4MGKs8
-UkrYBkvRugcI/UEzlsEldbboogAYkXWUgaDjdLjDKUY4BM7lXtH+FWzgiBFzvDLX
-aQru0cGvbXPDsJ3i3BgmFaJq+eyikSXbwuQLNwIDAQABAoIBAGK7cOXXsTbHpqO+
-33QsjQpnAWyLuFDJWS/l/RKYuFq4HKEbRgivrFxJtdciXNHRwPH43GWe2m3C6AEX
-ipd0H1qwPZkcjFfHH81mtPKismrY6tfxpLXaH8LamhHHtTxlSwTxa2d/aiaY2JjA
-zyhakrTa3AZJ0lXdGYLH1hC4eEdiPghIqwL8YNB0V2ldq+bMdtQ1i3dcmseV9TI2
-DEAKWzjc7oIcuY9HtfEEAIPzSSqwrM7wUWd9dk70o7b05eK9pnTF59Lnk5U1J1Ag
-QnXBHBZfLVDnTYd+dFWM8wUIpO0n6ccUToINppwSejyOs726jUuWGZCthxLBsFZp
-5Pj9B6ECgYEA3lRxGRJsAfMoyOc4kLfDmlDtrP88knRlqRW7mVYjclhMbVtrtaTP
-44VqmxKIVNQt1p5hB/Gn4kbhC7OnUja/FVHdosEjFhYNh+QCisyaS2V7RNyEidJX
-Q61V8v0Z7MxHxxDljVvWfSdAUDRrFwWYxRXZJWwStEmtdAbiZa6aydkCgYEA1mEV
-2D+gaR+oBouqcZMiSAjV/qHbnfw4EC2XFCw84JMPerBwl4noWCgvgf0lRirbI+Ar
-PDOfoclLnDQRgnqkK4okSIW0SddxttbKdDhhZ2c2CoyKxUqN7/NEyy/tZ2WZRcmX
-LILTLXzi/9qq8lF9odjIl5KKsRpXhqMsf5b1w48CgYEAqDT8yDo+yw7b6Xu+OQc/
-Ds5xs3P7sNYtX8qYfz9DXCxfzlDfYbMKsZlr+V0BFiTddUWoJal4GeMEOqU2TyYq
-VYf1hkBXOkt++zPPlJGNnsNtisDH6bng2cwXfdpttdEr8Pjgo5063r9GkifGacmL
-Nnj8K6rjT9F6UJEw0jtS0qkCgYAi3RMSYfaSYgWPWvNTGRyAHn++s0/l93iemOty
-6mbUFtZzm3IUEudoPtDLEQIY0StmQDSHy9VwGC5lrsoSMCO2uPaBnMzfHVxu4at3
-Dxw4Fr7hJE4FG8TNewB7EsZHBGzSvqAJKxVw1liMR2F5musVgQ3OKJTJjIEjcjHw
-Zfp93QKBgQCPp6SH510qK9Rf+HjeWXJpOB2ByruC5rBgqrxE4rbIB3/fAl86a3Kq
-Q1VqdGb+CW0FlkPshDmmdi3IoCliXywadSaXi/unPfPTel0pQAC8NM7WpPoaUfnS
-QgL5iNXshicKoE8U6PRhYvn81zVpt4bFn3DZRgIlau2GQnijLkGvQw==
+MIIEpAIBAAKCAQEAzQWx53y0ZC78YfVe8fzaErOamr6a/BedS52KSH6aYDLwQ46X
+XkpwTzjj2pD5X1ISkr1yHrBEr0CNRyTpRn7bMC/QOQdZU57B+ubKqYKoI+u4K4d/
+OlNzvWXHBYVI/A8Ok1KP6nuKSrFg8FF/yxt5ozsf6zhr1/Fsb2VOyVV14VOIPE6S
+FdyUU0PpRfNs96qEunQH0beMYeqci7jGG7ulLV+QJdIiQ76bFq/WWyiNn/A4ZK9L
+GRUR5exrOY0zdUWtRBdIwoyM6OgJJGPiEwbLL1bzBaXjf429GYby3ERVOepby5Jq
+4/yJylLJPajZvNPv8BQVMyeTexns15gSD8F3ZQIDAQABAoIBABliJR6V7/efYZv3
+NyQavB0oo3GZO7MOcWkVPjOviQl0BQ84LkF8Ud9dGcjLvjQxAx+r2N83z6krAtLW
+HROfTR/wK4WEBWk29KlNvbWy+YJJAupQwk3EW0YNvdBPKjQa4SEYTb0oQnzw7SGT
+1ZCd/DdbcJ48xA1eVKCOGG0Q6aFV702mUszjZfrnyqr+zxx8ZE+YhKSXB0eGjv2+
++kiJMf25ZpgP5Pu5AAX0/KRN9E5orbr5pdFTBgOIJ6Sdsnr/q/tJaU/bPVJEtFvd
+BqSVtz87ftTdZVH5zMBkXPVwlWczQiK5J6igrMBcrHhnKUmt54kh9bEUmt2ZrBOx
+xmEV/wECgYEA+a+LjA3lZgk5Qy4qKvXe4EHvRSK513ZxN8gBvj4wA7JmEGv76gMw
+5o1DbpNOqumeyjrtsqVzjAu3GpowX4dfHRal9CZ57dtedjWlHPnnDtSMKzmJXiJb
+HzYPngpjxfAjrZNIBlQZeAhtYCQUDM/SSitcnP1gp3DEdVyxFNafmuECgYEA0jUA
+F0hSddYBo4tG84gnHQ6L0ftqn3K0UD9EcFAG2Zxv7dqSGdmCq6wo/q1UeKDVLjCX
+OteuqzDG+ka6DmbcLwj9VRMQP9lqUbtGOzwyWxYdcMUZnMtWHpuvcsyHLrAKqTxJ
+0Be7hlXCbSrh62CBpAgv91NMghZup3Tpku8qkQUCgYEAyWNp7uEWciJmaWVG5bfC
+uKb10pGby8ngr9lGbqfCGnk+EWjHm4xPWOX/yaRPA1PDm+HD7x+7/u1EFtTex25s
+rQ2jdTXDirIxkq7aKnD2iOOu2v5haefUD2yPVC2VJAX5APuWUGRs1oAVmEIBWgQV
+3XT0EjvcRbGTBAZrXh9uRIECgYEAzBclZXWUilAj+zOoyZ4xy6Zp3pAqL3Fg3GDx
+A9LPM80NZ3RFUc+7bQ6UJuEHGK+fC1+mFT1/mzqaljjBQGZh9VDXFhiSOEvRTFV1
+lOGXSpSoNOtJONC7ZrBloiIuRggp8bJVQDMqoPz27qMqAiwK8sX4PDumFs/M081R
+UpXfUDkCgYAOa/VoXgDlFMun1qEu6LFZcLhA6SyHRT0yT9WSYkHjcQusvJAZEM67
+lfUd1J57tG6+HS7z0wBkO72HG0YZDD8dhgzsYGChUHD+yq+OZ2FHnZWRSnnHq4zD
+ZBjS8PGcVu/4Ojx6B8GI41UgmdqH+US+AA6nYceb74NeIigXjtXUdA==
 -----END RSA PRIVATE KEY-----
diff --git a/testing/tests/ikev2/multi-level-ca-pathlen/hosts/moon/etc/ipsec.d/cacerts/duckCert.pem b/testing/tests/ikev2/multi-level-ca-pathlen/hosts/moon/etc/ipsec.d/cacerts/duckCert.pem
index bb205a0..2076242 100644
--- a/testing/tests/ikev2/multi-level-ca-pathlen/hosts/moon/etc/ipsec.d/cacerts/duckCert.pem
+++ b/testing/tests/ikev2/multi-level-ca-pathlen/hosts/moon/etc/ipsec.d/cacerts/duckCert.pem
@@ -1,23 +1,23 @@
 -----BEGIN CERTIFICATE-----
-MIID0jCCArqgAwIBAgIBBTANBgkqhkiG9w0BAQsFADBRMQswCQYDVQQGEwJDSDEZ
+MIID0jCCArqgAwIBAgIBCjANBgkqhkiG9w0BAQsFADBRMQswCQYDVQQGEwJDSDEZ
 MBcGA1UEChMQTGludXggc3Ryb25nU3dhbjERMA8GA1UECxMIUmVzZWFyY2gxFDAS
-BgNVBAMTC1Jlc2VhcmNoIENBMB4XDTA5MTEwNDE2MTUwM1oXDTE1MTEwMzE2MTUw
-M1owVjELMAkGA1UEBhMCQ0gxGTAXBgNVBAoTEExpbnV4IHN0cm9uZ1N3YW4xETAP
+BgNVBAMTC1Jlc2VhcmNoIENBMB4XDTE0MTEyODIyMDcwOFoXDTE5MDQwMTIyMDcw
+OFowVjELMAkGA1UEBhMCQ0gxGTAXBgNVBAoTEExpbnV4IHN0cm9uZ1N3YW4xETAP
 BgNVBAsTCFJlc2VhcmNoMRkwFwYDVQQDExBEdWNrIFJlc2VhcmNoIENBMIIBIjAN
-BgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEApIBRSgHCxHhMjsVZo4PtFnENkHNu
-MfyRDsc7m1KRDVt8N4h/EcbduU7xeq/RjxZSmlc1q6EWEgDv3KwDYY0sX+qrpQKa
-ub5AgsRa2fOOR9xfyf0Q7Nc3oR3keWqQUiigCuaw9NQRtdMm/JFdXLNY3r60tBsO
-UHOJAPZNoGPey5UL9ZjjsN6ROUVTh0NAkFwkmnTRwmUvY5bi/T7ulsSkO9BrfqKD
-h/pliP7uZANd0ZpPcrIc68WwrelpI1zu0kYGqu/y8HZpuPuAXtGqS2jctrjSieeY
-i9wFLnS2tgV3ID4LzEEICSeqVqOvYgGKbarqLkARdxmdRKM9QYpu+5J+YQIDAQAB
-o4GvMIGsMA8GA1UdEwEB/wQFMAMBAf8wCwYDVR0PBAQDAgEGMB0GA1UdDgQWBBR2
-KqikMafGcY8wJbwCZpvLF1SNIDBtBgNVHSMEZjBkgBTndfCg8q0gzc1gI8zHyA8p
+BgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAu984h2mkpbWJZc9Ydka6jC84EkPz
+w6tqtEkIdftEawgc5gvlC80JXLTwnQySMTb49KByyt44S59ZWE6SHHV0u2P2ihiw
+1duoY7NE+RZwODEsWVgnDRZmyume2Bj+Hpkugm6o+rL7jiGxhvNLeoFZK3RyD6IR
+IcEfZeAv7URGz7xdrzmK/vWXukfEnU8DlrFDSQUb3NaJS5tVVVLFuTWQBSjuT3NX
+7mdNHnpjcwT9/ruyOaNQ0DV2Bgz1nCiOup+oW396/AInb03CQ+wIqQpB9reWma0w
+F0Bc9lZxnv9ppYgBPsOTjE3yyyeTptzk9Gw+DFV1cw8Crm+aew5VH18oEwIDAQAB
+o4GvMIGsMA8GA1UdEwEB/wQFMAMBAf8wCwYDVR0PBAQDAgEGMB0GA1UdDgQWBBSK
+cODKpRxkbyuSuXNcAayQG/35NTBtBgNVHSMEZjBkgBTndfCg8q0gzc1gI8zHyA8p
 891UIKFJpEcwRTELMAkGA1UEBhMCQ0gxGTAXBgNVBAoTEExpbnV4IHN0cm9uZ1N3
-YW4xGzAZBgNVBAMTEnN0cm9uZ1N3YW4gUm9vdCBDQYIBDzANBgkqhkiG9w0BAQsF
-AAOCAQEAsHR1vDlz2sPQpD9xnt1PL4qX7XWSSM6d+QG3cjdiKCjH8t78ecEm1duv
-YozLg6SYHGUF9qYuPz2SAZjQjmIWLlkQpBfQm8/orG+jbsQl5HkXFYX0UWAKZFGx
-rjHnOzmQxnmIWHky4uMDT/UmhmWy6kuCmZbKeeOqkBR2gVxfLyzelTSbF4ntEm1C
-1XqqtM4OfTOD5QUPD+6rZ5RoIPId9+2A8pJ2NyCUCf47FbkmYzU5+oiChhcGzsC5
-wDlgP32NA88kSiSJ2p2ZveYveRqcyZXZDAiTxRaIwJY0bt2Dk4wKicvy6vPdLA5v
-DSlBqDpnqK8tEI9V9YeroihTcygrEg==
+YW4xGzAZBgNVBAMTEnN0cm9uZ1N3YW4gUm9vdCBDQYIBIDANBgkqhkiG9w0BAQsF
+AAOCAQEAMtm7ldvd45818Ghl8+Z7PfCnRXDPbikyCJn5PXkuR3TSB62ekJSGT1Rd
+i2rnDoIZpfSzDQSpKH616MuWtwJoomJh8n9wCzbdUv1sn1cfgjDSkgLqIbm/Xpc4
+zUcHnZFdwvMr3sq/xSO/SgkfgTHi8bFLLp2RQwPNsNycT94nNE7DRjSeRenpuEPM
+4t4xIZCoUyX3sdusHvh+dDu4iuIVQoM0zaW9p7pVh210ALt0jac3HW0rQXtbfchE
+VeuDLZ0G7baFZ9LLLWpuQB4zPRUET7puvzabsf+sHpO54y+zXRaB0tbiFIurt4gF
+5n7mN4ssNQdcD86W5lnI9pT5s1uvdw==
 -----END CERTIFICATE-----
diff --git a/testing/tests/ikev2/nat-rw-mark/evaltest.dat b/testing/tests/ikev2/nat-rw-mark/evaltest.dat
index bb8e856..c5390fb 100644
--- a/testing/tests/ikev2/nat-rw-mark/evaltest.dat
+++ b/testing/tests/ikev2/nat-rw-mark/evaltest.dat
@@ -1,7 +1,7 @@
 alice::ipsec status 2> /dev/null::nat-t.*ESTABLISHED.*alice at strongswan.org.*sun.strongswan.org::YES
 venus::ipsec status 2> /dev/null::nat-t.*ESTABLISHED.*venus.strongswan.org.*sun.strongswan.org::YES
-alice::ipsec status 2> /dev/null::nat-t.*INSTALLED, TUNNEL, ESP in UDP::YES
-venus::ipsec status 2> /dev/null::nat-t.*INSTALLED, TUNNEL, ESP in UDP::YES
+alice::ipsec status 2> /dev/null::nat-t.*INSTALLED, TUNNEL.*ESP in UDP::YES
+venus::ipsec status 2> /dev/null::nat-t.*INSTALLED, TUNNEL.*ESP in UDP::YES
 sun::  ipsec status 2> /dev/null::alice.*ESTABLISHED.*sun.strongswan.org.*alice at strongswan.org::YES
 sun::  ipsec status 2> /dev/null::venus.*ESTABLISHED.*sun.strongswan.org.*venus.strongswan.org::YES
 sun::  ipsec statusall 2> /dev/null::alice.*10.2.0.0/16 === 10.1.0.0/25::YES
diff --git a/testing/tests/ikev2/nat-rw-mark/hosts/sun/etc/mark_updown b/testing/tests/ikev2/nat-rw-mark/hosts/sun/etc/mark_updown
index 421335f..e0c15f5 100755
--- a/testing/tests/ikev2/nat-rw-mark/hosts/sun/etc/mark_updown
+++ b/testing/tests/ikev2/nat-rw-mark/hosts/sun/etc/mark_updown
@@ -1,4 +1,4 @@
-#! /bin/sh
+#!/bin/sh
 # updown script setting inbound marks on ESP traffic in the mangle chain
 #
 # Copyright (C) 2003-2004 Nigel Meteringham
@@ -22,8 +22,6 @@
 # that, and use the (left/right)updown parameters in ipsec.conf to make
 # strongSwan use yours instead of this default one.
 
-# things that this script gets (from ipsec_pluto(8) man page)
-#
 #      PLUTO_VERSION
 #              indicates  what  version of this interface is being
 #              used.  This document describes version  1.1.   This
@@ -41,15 +39,20 @@
 #              is the name of the  connection  for  which  we  are
 #              routing.
 #
-#       PLUTO_NEXT_HOP
-#              is the next hop to which packets bound for the peer
-#              must be sent.
-#
 #       PLUTO_INTERFACE
 #              is the name of the ipsec interface to be used.
 #
 #       PLUTO_REQID
-#              is the requid of the ESP policy
+#              is the requid of the AH|ESP policy
+#
+#       PLUTO_PROTO
+#              is the negotiated IPsec protocol, ah|esp
+#
+#       PLUTO_IPCOMP
+#              is not empty if IPComp was negotiated
+#
+#       PLUTO_UNIQUEID
+#              is the unique identifier of the associated IKE_SA
 #
 #       PLUTO_ME
 #              is the IP address of our host.
@@ -63,15 +66,6 @@
 #              host's own IP address / max (where max  is  32  for
 #              IPv4 and 128 for IPv6).
 #
-#       PLUTO_MY_CLIENT_NET
-#              is the IP address of our client net.  If the client
-#              is just the host, this will be the  host's  own  IP
-#              address.
-#
-#       PLUTO_MY_CLIENT_MASK
-#              is  the  mask for our client net.  If the client is
-#              just the host, this will be 255.255.255.255.
-#
 #       PLUTO_MY_SOURCEIP
 #       PLUTO_MY_SOURCEIP4_$i
 #       PLUTO_MY_SOURCEIP6_$i
@@ -85,7 +79,8 @@
 #
 #       PLUTO_MY_PORT
 #              is  the  UDP/TCP  port  to  which  the IPsec SA  is
-#              restricted on our side.
+#              restricted on our side.  For ICMP/ICMPv6 this contains the
+#              message type, and PLUTO_PEER_PORT the message code.
 #
 #       PLUTO_PEER
 #              is the IP address of our peer.
@@ -93,31 +88,19 @@
 #       PLUTO_PEER_ID
 #              is the ID of our peer.
 #
-#       PLUTO_PEER_CA
-#              is the CA which issued the cert of our peer.
-#
 #       PLUTO_PEER_CLIENT
 #              is the IP address / count of the peer's client sub-
 #              net.   If the client is just the peer, this will be
 #              the peer's own IP address / max (where  max  is  32
 #              for IPv4 and 128 for IPv6).
 #
-#       PLUTO_PEER_CLIENT_NET
-#              is the IP address of the peer's client net.  If the
-#              client is just the peer, this will  be  the  peer's
-#              own IP address.
-#
-#       PLUTO_PEER_CLIENT_MASK
-#              is  the  mask  for  the  peer's client net.  If the
-#              client   is   just   the   peer,   this   will   be
-#              255.255.255.255.
-#
 #       PLUTO_PEER_PROTOCOL
 #              is the IP protocol that will be transported.
 #
 #       PLUTO_PEER_PORT
 #              is  the  UDP/TCP  port  to  which  the IPsec SA  is
-#              restricted on the peer side.
+#              restricted on the peer side.  For ICMP/ICMPv6 this contains the
+#              message code, and PLUTO_MY_PORT the message type.
 #
 #       PLUTO_XAUTH_ID
 #              is an optional user ID employed by the XAUTH protocol
@@ -143,7 +126,7 @@
 PATH="/sbin:/bin:/usr/sbin:/usr/bin:/usr/sbin:/usr/local/sbin"
 export PATH
 
-# uncomment to log VPN connections
+# comment to disable logging VPN connections to syslog
 VPN_LOGGING=1
 #
 # tag put in front of each log entry:
@@ -157,21 +140,11 @@ FAC_PRIO=local0.notice
 #
 # local0.notice                   -/var/log/vpn
 
-# in order to use source IP routing the Linux kernel options
-# CONFIG_IP_ADVANCED_ROUTER and CONFIG_IP_MULTIPLE_TABLES
-# must be enabled
-#
-# special routing table for sourceip routes
-SOURCEIP_ROUTING_TABLE=220
-#
-# priority of the sourceip routing table
-SOURCEIP_ROUTING_TABLE_PRIO=220
-
 # check interface version
 case "$PLUTO_VERSION" in
-1.[0|1])	# Older Pluto?!?  Play it safe, script may be using new features.
+1.[0|1])	# Older release?!?  Play it safe, script may be using new features.
 	echo "$0: obsolete interface version \`$PLUTO_VERSION'," >&2
-	echo "$0: 	called by obsolete Pluto?" >&2
+	echo "$0: 	called by obsolete release?" >&2
 	exit 2
 	;;
 1.*)	;;
@@ -193,119 +166,45 @@ custom:*)		# custom parameters (see above CAUTION comment)
 	;;
 esac
 
-# utility functions for route manipulation
-# Meddling with this stuff should not be necessary and requires great care.
-uproute() {
-	doroute add
-	ip route flush cache
-}
-downroute() {
-	doroute delete
-	ip route flush cache
-}
-
-addsource() {
-	st=0
-	if ! ip -o route get ${PLUTO_MY_SOURCEIP%/*} | grep -q ^local
-	then
-	    it="ip addr add ${PLUTO_MY_SOURCEIP%/*}/32 dev $PLUTO_INTERFACE"
-	    oops="`eval $it 2>&1`"
-	    st=$?
-	    if test " $oops" = " " -a " $st" != " 0"
-	    then
-		oops="silent error, exit status $st"
-	    fi
-	    if test " $oops" != " " -o " $st" != " 0"
-	    then
-		echo "$0: addsource \`$it' failed ($oops)" >&2
-	    fi
-	fi
-	return $st
-}
-
-doroute() {
-	st=0
-
-	if [ -z "$PLUTO_MY_SOURCEIP" ]
-	then
-	    for dir in /etc/sysconfig /etc/conf.d; do
-		if [ -f "$dir/defaultsource" ]
-		then
-		    . "$dir/defaultsource"
-		fi
-	    done
-
-	    if [ -n "$DEFAULTSOURCE" ]
-	    then
-		PLUTO_MY_SOURCEIP=$DEFAULTSOURCE
-	    fi
-        fi
-
-	if [ -z "$KLIPS" -a -z "$PLUTO_MY_SOURCEIP" ]
-	then
-	    # leave because no route entry is required
-	    return $st
-	fi
+IPSEC_POLICY="-m policy --pol ipsec --proto $PLUTO_PROTO --reqid $PLUTO_REQID"
+IPSEC_POLICY_IN="$IPSEC_POLICY --dir in"
+IPSEC_POLICY_OUT="$IPSEC_POLICY --dir out"
 
-	parms1="$PLUTO_PEER_CLIENT"
+# use protocol specific options to set ports
+case "$PLUTO_MY_PROTOCOL" in
+1)	# ICMP
+	ICMP_TYPE_OPTION="--icmp-type"
+	;;
+58)	# ICMPv6
+	ICMP_TYPE_OPTION="--icmpv6-type"
+	;;
+*)
+	;;
+esac
 
-	if [ -n "$PLUTO_NEXT_HOP" ]
+# are there port numbers?
+if [ "$PLUTO_MY_PORT" != 0 ]
+then
+	if [ -n "$ICMP_TYPE_OPTION" ]
 	then
-	    parms2="via $PLUTO_NEXT_HOP"
+		S_MY_PORT="$ICMP_TYPE_OPTION $PLUTO_MY_PORT"
+		D_MY_PORT="$ICMP_TYPE_OPTION $PLUTO_MY_PORT"
 	else
-	    parms2="via $PLUTO_PEER"
-	fi
-	parms2="$parms2 dev $PLUTO_INTERFACE"
-
-	parms3=
-	if [ -n "$PLUTO_MY_SOURCEIP" ]
-	then
-	    if test "$1" = "add"
-	    then
-		addsource
-		if ! ip rule list | grep -q "lookup $SOURCEIP_ROUTING_TABLE"
-		then
-		    ip rule add pref $SOURCEIP_ROUTING_TABLE_PRIO table $SOURCEIP_ROUTING_TABLE
-		fi
-	    fi
-	    parms3="$parms3 src ${PLUTO_MY_SOURCEIP%/*} table $SOURCEIP_ROUTING_TABLE"
-	fi
-
-	case "$PLUTO_PEER_CLIENT_NET/$PLUTO_PEER_CLIENT_MASK" in
-	"0.0.0.0/0.0.0.0")
-		# opportunistic encryption work around
-		# need to provide route that eclipses default, without
-		# replacing it.
-		it="ip route $1 0.0.0.0/1 $parms2 $parms3 &&
-			ip route $1 128.0.0.0/1 $parms2 $parms3"
-		;;
-	*)	it="ip route $1 $parms1 $parms2 $parms3"
-		;;
-	esac
-	oops="`eval $it 2>&1`"
-	st=$?
-	if test " $oops" = " " -a " $st" != " 0"
-	then
-	    oops="silent error, exit status $st"
+		S_MY_PORT="--sport $PLUTO_MY_PORT"
+		D_MY_PORT="--dport $PLUTO_MY_PORT"
 	fi
-	if test " $oops" != " " -o " $st" != " 0"
+fi
+if [ "$PLUTO_PEER_PORT" != 0 ]
+then
+	if [ -n "$ICMP_TYPE_OPTION" ]
 	then
-	    echo "$0: doroute \`$it' failed ($oops)" >&2
+		# the syntax is --icmp[v6]-type type[/code], so add it to the existing option
+		S_MY_PORT="$S_MY_PORT/$PLUTO_PEER_PORT"
+		D_MY_PORT="$D_MY_PORT/$PLUTO_PEER_PORT"
+	else
+		S_PEER_PORT="--sport $PLUTO_PEER_PORT"
+		D_PEER_PORT="--dport $PLUTO_PEER_PORT"
 	fi
-	return $st
-}
-
-# in the presence of KLIPS and ipsecN interfaces do not use IPSEC_POLICY
-if [ `echo "$PLUTO_INTERFACE" | grep "ipsec"` ]
-then
-	KLIPS=1
-	IPSEC_POLICY_IN=""
-	IPSEC_POLICY_OUT=""
-else
-	KLIPS=
-	IPSEC_POLICY="-m policy --pol ipsec --proto esp --reqid $PLUTO_REQID"
-	IPSEC_POLICY_IN="$IPSEC_POLICY --dir in"
-	IPSEC_POLICY_OUT="$IPSEC_POLICY --dir out"
 fi
 
 # is there an inbound mark to be set?
@@ -313,82 +212,18 @@ if [ -n "$PLUTO_MARK_IN" ]
 then
 	if [ -n "$PLUTO_UDP_ENC" ]
 	then
-	    SET_MARK="-p udp --sport $PLUTO_UDP_ENC"
+		SET_MARK="-p udp --sport $PLUTO_UDP_ENC"
 	else
-		SET_MARK="-p esp"
+		SET_MARK="-p $PLUTO_PROTO"
 	fi
 	SET_MARK="$SET_MARK -s $PLUTO_PEER -j MARK --set-mark $PLUTO_MARK_IN"
 fi
 
-# are there port numbers?
-if [ "$PLUTO_MY_PORT" != 0 ]
-then
-	S_MY_PORT="--sport $PLUTO_MY_PORT"
-	D_MY_PORT="--dport $PLUTO_MY_PORT"
-fi
-if [ "$PLUTO_PEER_PORT" != 0 ]
-then
-	S_PEER_PORT="--sport $PLUTO_PEER_PORT"
-	D_PEER_PORT="--dport $PLUTO_PEER_PORT"
-fi
-
 # resolve octal escape sequences
 PLUTO_MY_ID=`printf "$PLUTO_MY_ID"`
 PLUTO_PEER_ID=`printf "$PLUTO_PEER_ID"`
 
-# the big choice
 case "$PLUTO_VERB:$1" in
-prepare-host:*|prepare-client:*)
-	if [ -z "$KLIPS" -a -z "$PLUTO_MY_SOURCEIP" ]
-	then
-	    # exit because no route will be added,
-	    # so that existing routes can stay
-	    exit 0
-	fi
-
-	# delete possibly-existing route (preliminary to adding a route)
-	case "$PLUTO_PEER_CLIENT_NET/$PLUTO_PEER_CLIENT_MASK" in
-	"0.0.0.0/0.0.0.0")
-		# need to provide route that eclipses default, without
-		# replacing it.
-		parms1="0.0.0.0/1"
-		parms2="128.0.0.0/1"
-		it="ip route delete $parms1 2>&1 ; ip route delete $parms2 2>&1"
-		oops="`ip route delete $parms1 2>&1 ; ip route delete $parms2 2>&1`"
-		;;
-	*)
-		parms="$PLUTO_PEER_CLIENT"
-		it="ip route delete $parms 2>&1"
-		oops="`ip route delete $parms 2>&1`"
-		;;
-	esac
-	status="$?"
-	if test " $oops" = " " -a " $status" != " 0"
-	then
-		oops="silent error, exit status $status"
-	fi
-	case "$oops" in
-	*'RTNETLINK answers: No such process'*)
-		# This is what route (currently -- not documented!) gives
-		# for "could not find such a route".
-		oops=
-		status=0
-		;;
-	esac
-	if test " $oops" != " " -o " $status" != " 0"
-	then
-		echo "$0: \`$it' failed ($oops)" >&2
-	fi
-	exit $status
-	;;
-route-host:*|route-client:*)
-	# connection to me or my client subnet being routed
-	uproute
-	;;
-unroute-host:*|unroute-client:*)
-	# connection to me or my client subnet being unrouted
-	downroute
-	;;
 up-host:)
 	# connection to me coming up
 	# If you are doing a custom version, firewall commands go here.
@@ -403,6 +238,14 @@ up-host:)
 	    -s $PLUTO_ME $S_MY_PORT $IPSEC_POLICY_OUT \
 	    -d $PLUTO_PEER_CLIENT $D_PEER_PORT -j ACCEPT
 	#
+	# allow IPIP traffic because of the implicit SA created by the kernel if
+	# IPComp is used (for small inbound packets that are not compressed)
+	if [ -n "$PLUTO_IPCOMP" ]
+	then
+	  iptables -I INPUT 1 -i $PLUTO_INTERFACE -p 4 \
+	      -s $PLUTO_PEER -d $PLUTO_ME $IPSEC_POLICY_IN -j ACCEPT
+	fi
+	#
 	# log IPsec host connection setup
 	if [ $VPN_LOGGING ]
 	then
@@ -430,6 +273,13 @@ down-host:)
 	    -s $PLUTO_ME $S_MY_PORT $IPSEC_POLICY_OUT \
 	    -d $PLUTO_PEER_CLIENT $D_PEER_PORT -j ACCEPT
 	#
+	# IPIP exception teardown
+	if [ -n "$PLUTO_IPCOMP" ]
+	then
+	  iptables -D INPUT -i $PLUTO_INTERFACE -p 4 \
+	      -s $PLUTO_PEER -d $PLUTO_ME $IPSEC_POLICY_IN -j ACCEPT
+	fi
+	#
 	# log IPsec host connection teardown
 	if [ $VPN_LOGGING ]
 	then
@@ -472,6 +322,15 @@ up-client:)
 	      -d $PLUTO_PEER_CLIENT $D_PEER_PORT $IPSEC_POLICY_OUT -j ACCEPT
 	fi
 	#
+	# allow IPIP traffic because of the implicit SA created by the kernel if
+	# IPComp is used (for small inbound packets that are not compressed).
+	# INPUT is correct here even for forwarded traffic.
+	if [ -n "$PLUTO_IPCOMP" ]
+	then
+	  iptables -I INPUT 1 -i $PLUTO_INTERFACE -p 4 \
+	      -s $PLUTO_PEER -d $PLUTO_ME $IPSEC_POLICY_IN -j ACCEPT
+	fi
+	#
 	# log IPsec client connection setup
 	if [ $VPN_LOGGING ]
 	then
@@ -518,6 +377,13 @@ down-client:)
 	         $IPSEC_POLICY_OUT -j ACCEPT
 	fi
 	#
+	# IPIP exception teardown
+	if [ -n "$PLUTO_IPCOMP" ]
+	then
+	  iptables -D INPUT -i $PLUTO_INTERFACE -p 4 \
+	      -s $PLUTO_PEER -d $PLUTO_ME $IPSEC_POLICY_IN -j ACCEPT
+	fi
+	#
 	# log IPsec client connection teardown
 	if [ $VPN_LOGGING ]
 	then
diff --git a/testing/tests/ikev2/nat-rw-psk/evaltest.dat b/testing/tests/ikev2/nat-rw-psk/evaltest.dat
index 6ec29c7..86fc197 100644
--- a/testing/tests/ikev2/nat-rw-psk/evaltest.dat
+++ b/testing/tests/ikev2/nat-rw-psk/evaltest.dat
@@ -1,6 +1,6 @@
-alice::ipsec status 2> /dev/null::nat-t.*INSTALLED, TUNNEL, ESP in UDP::YES
-venus::ipsec status 2> /dev/null::nat-t.*INSTALLED. TUNNEL, ESP in UDP::YES
-sun::  ipsec status 2> /dev/null::nat-t.*INSTALLED, TUNNEL, ESP in UDP::YES
+alice::ipsec status 2> /dev/null::nat-t.*INSTALLED, TUNNEL.*ESP in UDP::YES
+venus::ipsec status 2> /dev/null::nat-t.*INSTALLED. TUNNEL.*ESP in UDP::YES
+sun::  ipsec status 2> /dev/null::nat-t.*INSTALLED, TUNNEL.*ESP in UDP::YES
 sun::  ipsec status 2> /dev/null::nat-t.*\[PH_IP_ALICE\]::YES
 sun::  ipsec status 2> /dev/null::nat-t.*\[PH_IP_VENUS\]::YES
 alice::ping -c 1 PH_IP_BOB::64 bytes from PH_IP_BOB: icmp_req=1::YES
diff --git a/testing/tests/ikev2/nat-rw/evaltest.dat b/testing/tests/ikev2/nat-rw/evaltest.dat
index 387dbae..36d9f84 100644
--- a/testing/tests/ikev2/nat-rw/evaltest.dat
+++ b/testing/tests/ikev2/nat-rw/evaltest.dat
@@ -2,10 +2,10 @@ alice::ipsec status 2> /dev/null::nat-t.*ESTABLISHED.*alice at strongswan.org.*sun.
 venus::ipsec status 2> /dev/null::nat-t.*ESTABLISHED.*venus.strongswan.org.*sun.strongswan.org::YES
 sun::  ipsec status 2> /dev/null::nat-t\[1]: ESTABLISHED.*sun.strongswan.org.*alice at strongswan.org::YES
 sun::  ipsec status 2> /dev/null::nat-t\[2]: ESTABLISHED.*sun.strongswan.org.*venus.strongswan.org::YES
-alice::ipsec status 2> /dev/null::nat-t.*INSTALLED, TUNNEL, ESP in UDP::YES
-venus::ipsec status 2> /dev/null::nat-t.*INSTALLED, TUNNEL, ESP in UDP::YES
-sun::  ipsec status 2> /dev/null::nat-t[{]1}.*INSTALLED, TUNNEL, ESP in UDP::YES
-sun::  ipsec status 2> /dev/null::nat-t[{]2}.*INSTALLED, TUNNEL, ESP in UDP::YES
+alice::ipsec status 2> /dev/null::nat-t.*INSTALLED, TUNNEL.*ESP in UDP::YES
+venus::ipsec status 2> /dev/null::nat-t.*INSTALLED, TUNNEL.*ESP in UDP::YES
+sun::  ipsec status 2> /dev/null::nat-t[{]1}.*INSTALLED, TUNNEL.*ESP in UDP::YES
+sun::  ipsec status 2> /dev/null::nat-t[{]2}.*INSTALLED, TUNNEL.*ESP in UDP::YES
 alice::ping -c 1 PH_IP_BOB::64 bytes from PH_IP_BOB: icmp_req=1::YES
 venus::ping -c 1 PH_IP_BOB::64 bytes from PH_IP_BOB: icmp_req=1::YES
 moon:: sleep 6::no output expected::NO
diff --git a/testing/tests/ikev2/nat-virtual-ip/hosts/moon/etc/nat_updown b/testing/tests/ikev2/nat-virtual-ip/hosts/moon/etc/nat_updown
index aab1df6..1afd70d 100755
--- a/testing/tests/ikev2/nat-virtual-ip/hosts/moon/etc/nat_updown
+++ b/testing/tests/ikev2/nat-virtual-ip/hosts/moon/etc/nat_updown
@@ -1,4 +1,4 @@
-#! /bin/sh
+#!/bin/sh
 # NAT updown script
 #
 # Copyright (C) 2010 Andreas Steffen <andreas.steffen at strongswan.org>
@@ -13,8 +13,6 @@
 # or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 # for more details.
 
-# things that this script gets (from ipsec_pluto(8) man page)
-#
 #      PLUTO_VERSION
 #              indicates  what  version of this interface is being
 #              used.  This document describes version  1.1.   This
@@ -32,15 +30,20 @@
 #              is the name of the  connection  for  which  we  are
 #              routing.
 #
-#       PLUTO_NEXT_HOP
-#              is the next hop to which packets bound for the peer
-#              must be sent.
-#
 #       PLUTO_INTERFACE
 #              is the name of the ipsec interface to be used.
 #
 #       PLUTO_REQID
-#              is the requid of the ESP policy
+#              is the requid of the AH|ESP policy
+#
+#       PLUTO_PROTO
+#              is the negotiated IPsec protocol, ah|esp
+#
+#       PLUTO_IPCOMP
+#              is not empty if IPComp was negotiated
+#
+#       PLUTO_UNIQUEID
+#              is the unique identifier of the associated IKE_SA
 #
 #       PLUTO_ME
 #              is the IP address of our host.
@@ -54,25 +57,21 @@
 #              host's own IP address / max (where max  is  32  for
 #              IPv4 and 128 for IPv6).
 #
-#       PLUTO_MY_CLIENT_NET
-#              is the IP address of our client net.  If the client
-#              is just the host, this will be the  host's  own  IP
-#              address.
-#
-#       PLUTO_MY_CLIENT_MASK
-#              is  the  mask for our client net.  If the client is
-#              just the host, this will be 255.255.255.255.
-#
 #       PLUTO_MY_SOURCEIP
-#              if non-empty, then the source address for the route will be
-#              set to this IP address.
+#       PLUTO_MY_SOURCEIP4_$i
+#       PLUTO_MY_SOURCEIP6_$i
+#              contains IPv4/IPv6 virtual IP received from a responder,
+#              $i enumerates from 1 to the number of IP per address family.
+#              PLUTO_MY_SOURCEIP is a legacy variable and equals to the first
+#              virtual IP, IPv4 or IPv6.
 #
 #       PLUTO_MY_PROTOCOL
 #              is the IP protocol that will be transported.
 #
 #       PLUTO_MY_PORT
 #              is  the  UDP/TCP  port  to  which  the IPsec SA  is
-#              restricted on our side.
+#              restricted on our side.  For ICMP/ICMPv6 this contains the
+#              message type, and PLUTO_PEER_PORT the message code.
 #
 #       PLUTO_PEER
 #              is the IP address of our peer.
@@ -80,31 +79,38 @@
 #       PLUTO_PEER_ID
 #              is the ID of our peer.
 #
-#       PLUTO_PEER_CA
-#              is the CA which issued the cert of our peer.
-#
 #       PLUTO_PEER_CLIENT
 #              is the IP address / count of the peer's client sub-
 #              net.   If the client is just the peer, this will be
 #              the peer's own IP address / max (where  max  is  32
 #              for IPv4 and 128 for IPv6).
 #
-#       PLUTO_PEER_CLIENT_NET
-#              is the IP address of the peer's client net.  If the
-#              client is just the peer, this will  be  the  peer's
-#              own IP address.
-#
-#       PLUTO_PEER_CLIENT_MASK
-#              is  the  mask  for  the  peer's client net.  If the
-#              client   is   just   the   peer,   this   will   be
-#              255.255.255.255.
-#
 #       PLUTO_PEER_PROTOCOL
 #              is the IP protocol that will be transported.
 #
 #       PLUTO_PEER_PORT
 #              is  the  UDP/TCP  port  to  which  the IPsec SA  is
-#              restricted on the peer side.
+#              restricted on the peer side.  For ICMP/ICMPv6 this contains the
+#              message code, and PLUTO_MY_PORT the message type.
+#
+#       PLUTO_XAUTH_ID
+#              is an optional user ID employed by the XAUTH protocol
+#
+#       PLUTO_MARK_IN
+#              is an optional XFRM mark set on the inbound IPsec SA
+#
+#       PLUTO_MARK_OUT
+#              is an optional XFRM mark set on the outbound IPsec SA
+#
+#       PLUTO_UDP_ENC
+#              contains the remote UDP port in the case of ESP_IN_UDP
+#              encapsulation
+#
+#       PLUTO_DNS4_$i
+#       PLUTO_DNS6_$i
+#              contains IPv4/IPv6 DNS server attribute received from a
+#              responder, $i enumerates from 1 to the number of servers per
+#              address family.
 #
 
 # define a minimum PATH environment in case it is not set
@@ -129,22 +135,22 @@ up-client:)
 	# If you are doing a custom version, firewall commands go here.
 	iptables -A FORWARD -i eth1 -o $PLUTO_INTERFACE -s PH_IP_ALICE \
 	    -d $PLUTO_PEER_CLIENT -j ACCEPT
-        iptables -A FORWARD -o eth1 -i $PLUTO_INTERFACE -d PH_IP_ALICE \
-            -s $PLUTO_PEER_CLIENT -j ACCEPT
+	iptables -A FORWARD -o eth1 -i $PLUTO_INTERFACE -d PH_IP_ALICE \
+	    -s $PLUTO_PEER_CLIENT -j ACCEPT
 	iptables -t nat -A POSTROUTING -o $PLUTO_INTERFACE -s PH_IP_ALICE \
 	    -d $PLUTO_PEER_CLIENT -j SNAT --to-source $PLUTO_MY_SOURCEIP
-	echo "inserted NAT rule mapping PH_IP_ALICE to virtual IP $PLUTO_MY_SOURCEIP" >&2 
+	echo "inserted NAT rule mapping PH_IP_ALICE to virtual IP $PLUTO_MY_SOURCEIP" >&2
 	;;
 down-client:)
 	# connection to my client subnet going down
 	# If you are doing a custom version, firewall commands go here.
-        iptables -D FORWARD -i eth1 -o $PLUTO_INTERFACE -s PH_IP_ALICE \
-            -d $PLUTO_PEER_CLIENT -j ACCEPT
-        iptables -D FORWARD -o eth1 -i $PLUTO_INTERFACE -d PH_IP_ALICE \
-            -s $PLUTO_PEER_CLIENT -j ACCEPT
-         iptables -t nat -D POSTROUTING -o $PLUTO_INTERFACE -s PH_IP_ALICE \
-            -d $PLUTO_PEER_CLIENT -j SNAT --to-source $PLUTO_MY_SOURCEIP
-        echo "deleted NAT rule mapping PH_IP_ALICE to virtual IP $PLUTO_MY_SOURCEIP" >&2    
+	iptables -D FORWARD -i eth1 -o $PLUTO_INTERFACE -s PH_IP_ALICE \
+	    -d $PLUTO_PEER_CLIENT -j ACCEPT
+	iptables -D FORWARD -o eth1 -i $PLUTO_INTERFACE -d PH_IP_ALICE \
+	    -s $PLUTO_PEER_CLIENT -j ACCEPT
+	iptables -t nat -D POSTROUTING -o $PLUTO_INTERFACE -s PH_IP_ALICE \
+	    -d $PLUTO_PEER_CLIENT -j SNAT --to-source $PLUTO_MY_SOURCEIP
+	echo "deleted NAT rule mapping PH_IP_ALICE to virtual IP $PLUTO_MY_SOURCEIP" >&2
 	;;
 *)	echo "$0: unknown verb \`$PLUTO_VERB' or parameter \`$1'" >&2
 	exit 1
diff --git a/testing/tests/ikev2/net2net-cert-sha2/description.txt b/testing/tests/ikev2/net2net-cert-sha2/description.txt
new file mode 100644
index 0000000..c659b4c
--- /dev/null
+++ b/testing/tests/ikev2/net2net-cert-sha2/description.txt
@@ -0,0 +1,7 @@
+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> using SHA-2 to create signatures
+as enabled by the IKEv2 Signature Authentication extension described in <b>RFC 7427</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.
+In order to test both tunnel and firewall, client <b>alice</b> behind gateway <b>moon</b>
+pings client <b>bob</b> located behind gateway <b>sun</b>.
diff --git a/testing/tests/ikev2/net2net-cert-sha2/evaltest.dat b/testing/tests/ikev2/net2net-cert-sha2/evaltest.dat
new file mode 100644
index 0000000..65737ba
--- /dev/null
+++ b/testing/tests/ikev2/net2net-cert-sha2/evaltest.dat
@@ -0,0 +1,9 @@
+moon:: cat /var/log/daemon.log::authentication of.*sun.strongswan.org.*with RSA_EMSA_PKCS1_SHA512 successful::YES
+moon::ipsec status 2> /dev/null::net-net.*ESTABLISHED.*moon.strongswan.org.*sun.strongswan.org::YES
+sun:: cat /var/log/daemon.log::authentication of.*moon.strongswan.org.*with RSA_EMSA_PKCS1_SHA384 successful::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
+alice::ping -c 1 PH_IP_BOB::64 bytes from PH_IP_BOB: icmp_req=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-cert-sha2/hosts/moon/etc/ipsec.conf b/testing/tests/ikev2/net2net-cert-sha2/hosts/moon/etc/ipsec.conf
new file mode 100644
index 0000000..5af6d2b
--- /dev/null
+++ b/testing/tests/ikev2/net2net-cert-sha2/hosts/moon/etc/ipsec.conf
@@ -0,0 +1,23 @@
+# /etc/ipsec.conf - strongSwan IPsec configuration file
+
+config setup
+
+conn %default
+	ikelifetime=60m
+	keylife=20m
+	rekeymargin=3m
+	keyingtries=1
+	keyexchange=ikev2
+	mobike=no
+
+conn net-net
+	left=PH_IP_MOON
+	leftcert=moonCert.pem
+	leftauth=rsa-sha384
+	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-cert-sha2/hosts/moon/etc/strongswan.conf b/testing/tests/ikev2/net2net-cert-sha2/hosts/moon/etc/strongswan.conf
new file mode 100644
index 0000000..2127105
--- /dev/null
+++ b/testing/tests/ikev2/net2net-cert-sha2/hosts/moon/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 stroke kernel-netlink socket-default updown
+}
diff --git a/testing/tests/ikev2/net2net-cert-sha2/hosts/sun/etc/ipsec.conf b/testing/tests/ikev2/net2net-cert-sha2/hosts/sun/etc/ipsec.conf
new file mode 100644
index 0000000..3c3d1e5
--- /dev/null
+++ b/testing/tests/ikev2/net2net-cert-sha2/hosts/sun/etc/ipsec.conf
@@ -0,0 +1,23 @@
+# /etc/ipsec.conf - strongSwan IPsec configuration file
+
+config setup
+
+conn %default
+	ikelifetime=60m
+	keylife=20m
+	rekeymargin=3m
+    keyingtries=1
+	keyexchange=ikev2
+	mobike=no
+
+conn net-net
+	left=PH_IP_SUN
+	leftcert=sunCert.pem
+	leftauth=rsa-sha512
+	leftid=@sun.strongswan.org
+	leftsubnet=10.2.0.0/16
+	leftfirewall=yes
+	right=PH_IP_MOON
+	rightid=@moon.strongswan.org
+	rightsubnet=10.1.0.0/16
+	auto=add
diff --git a/testing/tests/ikev2/net2net-cert-sha2/hosts/sun/etc/strongswan.conf b/testing/tests/ikev2/net2net-cert-sha2/hosts/sun/etc/strongswan.conf
new file mode 100644
index 0000000..2127105
--- /dev/null
+++ b/testing/tests/ikev2/net2net-cert-sha2/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 stroke kernel-netlink socket-default updown
+}
diff --git a/testing/tests/ikev2/net2net-cert-sha2/posttest.dat b/testing/tests/ikev2/net2net-cert-sha2/posttest.dat
new file mode 100644
index 0000000..837738f
--- /dev/null
+++ b/testing/tests/ikev2/net2net-cert-sha2/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-cert-sha2/pretest.dat b/testing/tests/ikev2/net2net-cert-sha2/pretest.dat
new file mode 100644
index 0000000..81a98fa
--- /dev/null
+++ b/testing/tests/ikev2/net2net-cert-sha2/pretest.dat
@@ -0,0 +1,6 @@
+moon::iptables-restore < /etc/iptables.rules
+sun::iptables-restore < /etc/iptables.rules
+moon::ipsec start
+sun::ipsec start
+moon::sleep 1
+moon::ipsec up net-net
diff --git a/testing/tests/ikev2/net2net-cert-sha2/test.conf b/testing/tests/ikev2/net2net-cert-sha2/test.conf
new file mode 100644
index 0000000..afa2acc
--- /dev/null
+++ b/testing/tests/ikev2/net2net-cert-sha2/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/ikev2/net2net-cert/hosts/moon/etc/strongswan.conf b/testing/tests/ikev2/net2net-cert/hosts/moon/etc/strongswan.conf
index a262950..6e5c240 100644
--- a/testing/tests/ikev2/net2net-cert/hosts/moon/etc/strongswan.conf
+++ b/testing/tests/ikev2/net2net-cert/hosts/moon/etc/strongswan.conf
@@ -3,4 +3,5 @@
 charon {
   load = aes des sha1 sha2 md5 pem pkcs1 gmp random nonce x509 curl revocation hmac stroke kernel-netlink socket-default updown
   multiple_authentication = no
+  signature_authentication = no
 }
diff --git a/testing/tests/ikev2/net2net-cert/hosts/sun/etc/strongswan.conf b/testing/tests/ikev2/net2net-cert/hosts/sun/etc/strongswan.conf
index a262950..6e5c240 100644
--- a/testing/tests/ikev2/net2net-cert/hosts/sun/etc/strongswan.conf
+++ b/testing/tests/ikev2/net2net-cert/hosts/sun/etc/strongswan.conf
@@ -3,4 +3,5 @@
 charon {
   load = aes des sha1 sha2 md5 pem pkcs1 gmp random nonce x509 curl revocation hmac stroke kernel-netlink socket-default updown
   multiple_authentication = no
+  signature_authentication = no
 }
diff --git a/testing/tests/ikev2/net2net-fragmentation/evaltest.dat b/testing/tests/ikev2/net2net-fragmentation/evaltest.dat
index 7f227fd..c7437c8 100644
--- a/testing/tests/ikev2/net2net-fragmentation/evaltest.dat
+++ b/testing/tests/ikev2/net2net-fragmentation/evaltest.dat
@@ -1,7 +1,7 @@
 moon::cat /var/log/daemon.log::IKE_SA_INIT request 0.*FRAG_SUP::YES
 sun::cat /var/log/daemon.log::IKE_SA_INIT response 0.*FRAG_SUP::YES
-moon::cat /var/log/daemon.log::splitting IKE message with length of 1804 bytes into 2 fragments::YES
-sun::cat /var/log/daemon.log::splitting IKE message with length of 1596 bytes into 2 fragments::YES
+moon::cat /var/log/daemon.log::splitting IKE message with length of .*bytes into 2 fragments::YES
+sun::cat /var/log/daemon.log::splitting IKE message with length of .*bytes into 2 fragments::YES
 moon::cat /var/log/daemon.log::received fragment #1 of 2, waiting for complete IKE message::YES
 moon::cat /var/log/daemon.log::received fragment #2 of 2, reassembling fragmented IKE message::YES
 sun::cat /var/log/daemon.log::received fragment #1 of 2, waiting for complete IKE message::YES
diff --git a/testing/tests/ikev2/net2net-rfc3779/hosts/moon/etc/ipsec.d/certs/moonCert.pem b/testing/tests/ikev2/net2net-rfc3779/hosts/moon/etc/ipsec.d/certs/moonCert.pem
index 7f5f8d7..124e2ae 100644
--- a/testing/tests/ikev2/net2net-rfc3779/hosts/moon/etc/ipsec.d/certs/moonCert.pem
+++ b/testing/tests/ikev2/net2net-rfc3779/hosts/moon/etc/ipsec.d/certs/moonCert.pem
@@ -1,28 +1,28 @@
 -----BEGIN CERTIFICATE-----
-MIIEuDCCA6CgAwIBAgIBATANBgkqhkiG9w0BAQsFADBaMQswCQYDVQQGEwJDSDEZ
+MIIEuDCCA6CgAwIBAgIBBTANBgkqhkiG9w0BAQsFADBaMQswCQYDVQQGEwJDSDEZ
 MBcGA1UEChMQTGludXggc3Ryb25nU3dhbjEQMA4GA1UECxMHUkZDMzc3OTEeMBwG
-A1UEAxMVc3Ryb25nU3dhbiBSRkMzNzc5IENBMB4XDTA5MTIyMzEzMzM1NloXDTE0
-MTIyMjEzMzM1NlowWDELMAkGA1UEBhMCQ0gxGTAXBgNVBAoTEExpbnV4IHN0cm9u
+A1UEAxMVc3Ryb25nU3dhbiBSRkMzNzc5IENBMB4XDTE0MTIyNzA2NDU0MloXDTE5
+MTIyMTA2NDU0MlowWDELMAkGA1UEBhMCQ0gxGTAXBgNVBAoTEExpbnV4IHN0cm9u
 Z1N3YW4xEDAOBgNVBAsTB1JGQzM3NzkxHDAaBgNVBAMTE21vb24uc3Ryb25nc3dh
-bi5vcmcwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDTKaLLTmKX45Qm
-RjIaBSxBwofzqqkZWtl1mu0cDp6rGWr//hC31OO9MbLeRZBX0UBtuKouceAjdrwG
-aK7ChR0Ft+qlLZ6Z9BH2Dna4vTdESsB3Sn+uXuU4WNdwmmJuRBXfl/7h/Rt+34Cs
-BP82/RtR4GVpS7u73iSLlN4RaeWdySTqhtYH4cKt1H9MiSbwwomwdLedQo3UoOeU
-lkWPrzFKT3gzU4vHr1sgpbF54o/iBr5/YyJpUT9UVeDTffAEMxnAe8/Q/a3pgSLO
-wJ3HnSvcSH0w8zuH1YXOtfmqsphkwVBJGiLzUHWlYxVIAoCKdrv4eoSJLqlL5b51
-vGkmL83RAgMBAAGjggGJMIIBhTAJBgNVHRMEAjAAMAsGA1UdDwQEAwIDqDAdBgNV
-HQ4EFgQU5zzmRRlKa8+cm1g4RYg4lKNkQz4wgYwGA1UdIwSBhDCBgYAUIX+n6zfQ
+bi5vcmcwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDYeHiAGNal9DT6
+GgCewdXa4Nf/46YgbhZNmSpi/zH+XmA7JLS6eoVt5vJ/LJEHSzkRoEetptAILenu
+uakByawEoPZgkCYZgJB9opGEOoWIwTitaF0ZVV8diNQtnl+rkvwPpxWybvIwOwRA
+PUIenoQPkVhfd/ALaRl88pG0rcAW0MMSCNuQwELwSIK2rQALs94Qm5yM0bZ+dqV2
+jnSISit5doRZ4vIYghJPKPqFKb1zUw1siCDPev43S+xqwTjhJ0zncq/QigySyivd
+D8qs8KMkan+XNx9XSjW14YWp27RVpIeANlikiHh0/St0lBsR+P9sDp+Yvr+U95EK
+KOgrqac3AgMBAAGjggGJMIIBhTAJBgNVHRMEAjAAMAsGA1UdDwQEAwIDqDAdBgNV
+HQ4EFgQUQcvdnqQfLJx2utB9szVLhZCmp84wgYwGA1UdIwSBhDCBgYAUIX+n6zfQ
 owsfodxCBh4RXzzSEBShXqRcMFoxCzAJBgNVBAYTAkNIMRkwFwYDVQQKExBMaW51
 eCBzdHJvbmdTd2FuMRAwDgYDVQQLEwdSRkMzNzc5MR4wHAYDVQQDExVzdHJvbmdT
 d2FuIFJGQzM3NzkgQ0GCCQDyr+ZHsk6LRjAeBgNVHREEFzAVghNtb29uLnN0cm9u
 Z3N3YW4ub3JnMBMGA1UdJQQMMAoGCCsGAQUFBwMBMEEGA1UdHwQ6MDgwNqA0oDKG
 MGh0dHA6Ly9jcmwuc3Ryb25nc3dhbi5vcmcvc3Ryb25nc3dhbl9yZmMzNzc5LmNy
 bDBFBggrBgEFBQcBBwEB/wQ2MDQwEgQCAAEwDAMDAAoBAwUAwKgAATAeBAIAAjAY
-AxEA/sAAAAAAAAAAAAAAAAAAAQMDAP7BMA0GCSqGSIb3DQEBCwUAA4IBAQBVFKeX
-QIH5Zk0dp/7u/V0TKqu5vZ9x6ZrshAZ9nzbLgmSP+++yDXmlQe0D0i2Men4D095S
-smFqw1nMWM5oEPpP58+jhCOHzn7InMp+SRRBkX2j06wT9qbynAHiIun/qcdq13w1
-Fs0PiKVQZbbz72mwl9J3Hkj/JkLtOX00wMPqIFU6veeagGiwOW7KkehFUVqoD9+O
-vgkHnUti2XzgskEGcEWmE1EYv7Qo0OdZB15oNoUV5i8WelfmWO+nz9/QKciATNoC
-kAUVcEV9XY9sSKjazdyG6QfEd3l6lQ+KAt8MnqA89i0yIQ1lg+3Jfe67SMvM1gy6
-Y0Y2hqCja6SsIjVc
+AxEA/sAAAAAAAAAAAAAAAAAAAQMDAP7BMA0GCSqGSIb3DQEBCwUAA4IBAQAi0XQL
+aEHg8aXBiXSTHuvxDieJB3Q83kpXOry16Ij5PKx9cdM2Gtmxz8YkwPEgq0r7vWNo
+830A4CnOJszQyIpY7CIygPj1wy3kFGGPkL7R4p00qSKpCEg8Fq85R4LmiyXIEZ+5
+lUtan7xka4ySMKKocm2rbXHyHXjis8AzU7NZN5QpEMkGLTaQPwHad4FUBFOolNE2
+NLoQ3xp9NPTyqfy1CkCHcyG18yRPciU4m8Cubyb+zBHyBADm9Q0P3++vznsU8LrR
+pzjRqS0e+FD2bzdXH/2g7Ge8+b6xzWRVMxZ8e2f5O9jQUY6q4SicuAX8SM/bgDPu
+Mc/lk4Nl8pHRO+Xm
 -----END CERTIFICATE-----
diff --git a/testing/tests/ikev2/net2net-rfc3779/hosts/moon/etc/ipsec.d/private/moonKey.pem b/testing/tests/ikev2/net2net-rfc3779/hosts/moon/etc/ipsec.d/private/moonKey.pem
index 8295f97..11607c8 100644
--- a/testing/tests/ikev2/net2net-rfc3779/hosts/moon/etc/ipsec.d/private/moonKey.pem
+++ b/testing/tests/ikev2/net2net-rfc3779/hosts/moon/etc/ipsec.d/private/moonKey.pem
@@ -1,27 +1,27 @@
 -----BEGIN RSA PRIVATE KEY-----
-MIIEpAIBAAKCAQEA0ymiy05il+OUJkYyGgUsQcKH86qpGVrZdZrtHA6eqxlq//4Q
-t9TjvTGy3kWQV9FAbbiqLnHgI3a8BmiuwoUdBbfqpS2emfQR9g52uL03RErAd0p/
-rl7lOFjXcJpibkQV35f+4f0bft+ArAT/Nv0bUeBlaUu7u94ki5TeEWnlnckk6obW
-B+HCrdR/TIkm8MKJsHS3nUKN1KDnlJZFj68xSk94M1OLx69bIKWxeeKP4ga+f2Mi
-aVE/VFXg033wBDMZwHvP0P2t6YEizsCdx50r3Eh9MPM7h9WFzrX5qrKYZMFQSRoi
-81B1pWMVSAKAina7+HqEiS6pS+W+dbxpJi/N0QIDAQABAoIBAQCSHbx1XB8jJSot
-teMTWEMAmgCDHrN2RQQ2ueaaxI8MrED7NK4S1rBkCVDRN2ejLLudcOvpyYikYZPI
-B4XuOjgT7ejjNYcK1vXawrVqLhxhGCzIHvftC+MnM2qYk2vLCzfriXyomgD9sOCT
-p72GKmxOIq1pyCr228eEApYLjLCDlhso3PrCo7recUq7f56rLjvb4gfcfor6mJUd
-yIppZUnDFJnsRXup1G4L9Y9RNYtlkcDqem/Q49d5+AHCYH6R8YI0Iz3JnzZjalsq
-+IA6RJqHBTeOpiyCmHlUmVE/3YUm8n7w7RRngMOLjKdiTKHT+8EcHmyUorqW3Yea
-zCIe5C6FAoGBAO23egrSbamyWXcIOqx1GX9gzYmQ2nSKYUtRhsE8eNErw0zp4FKv
-AA7CAmoWEzjDJPSkUzDAajoZiH8+DIZ4IkwKbYjtq0vr1yCbx/PBKVN/JHGZ/Ao/
-dc/lQrNseza34NBrREN/gUytjefFMJ4YStSZCMuy3gP1Fqk6YCy/dObbAoGBAONn
-UqjmZYqoK0+jnGWdPOtXZ4bu8UoHc8/1MaVn3pq8bYh3PayFKpDKtcD1ZeXHCxL2
-1Y+Eid/DoZ2/RZbxT2mhi2mVZZCWc0xuML3Vz0B9bqi3ZfRLVP2u87fn//mGrD+9
-yy9PeIBv8UvjOhev6hZDBhPAVMsyjiw+wSX6kW/DAoGBAMBcrbSeLcGZok3xadFu
-fPCXvBtrDWwrIqpZUauDLN1PBZ5yz2T5WhmXI28HaAyR1ZDmfK9BtXRIfy1AX9Bc
-3JweAB9C/E/Wi+JGTVrR34hCpZIMImmEiuhtxDj/OwG/cHwXoUjhoBcVhnScHEiC
-reM152k21/Pp26mbpIHxeD7rAoGAaRy4S5P7uaTUKEKzJxEQOKQ1GVzXMWXSdXyb
-zx38+j9AzgR4AIepTjY03xVPXW+swb5Qpr8Xz9Oon7bq3sN59pSSUWKaCMRSVTDV
-3Nm4q9GO1fO377zmc0BsLUTSwC8s7WW4Ro0QYSXdPjuw/YP1ywZ+B6EuUKJ0ryTu
-uLRih2sCgYBm15N97b7Rp+aAti045iBla9/KH8z7szczIndpFWR4wjaI9tt0i9GR
-OZs7LFq0MYdg8JiXITyVcuqsUbdAP3TvsXGDHdatbDcrXM/DYuP6dPqMuGBKdnEn
-gIFT1z8mhv4Im3JKpuckMrIQ5vWhljcRZgiEJYZfEAkLJo7ePG2VzA==
+MIIEowIBAAKCAQEA2Hh4gBjWpfQ0+hoAnsHV2uDX/+OmIG4WTZkqYv8x/l5gOyS0
+unqFbebyfyyRB0s5EaBHrabQCC3p7rmpAcmsBKD2YJAmGYCQfaKRhDqFiME4rWhd
+GVVfHYjULZ5fq5L8D6cVsm7yMDsEQD1CHp6ED5FYX3fwC2kZfPKRtK3AFtDDEgjb
+kMBC8EiCtq0AC7PeEJucjNG2fnaldo50iEoreXaEWeLyGIISTyj6hSm9c1MNbIgg
+z3r+N0vsasE44SdM53Kv0IoMksor3Q/KrPCjJGp/lzcfV0o1teGFqdu0VaSHgDZY
+pIh4dP0rdJQbEfj/bA6fmL6/lPeRCijoK6mnNwIDAQABAoIBAAutG9rU/CcBcCYZ
+ZvUpQW7H9/6uedR/+6X94AJs/3ZYAtrN1Q3F9BKEhYoEjmIVVaO0wIkGWWxHhbnB
+u/MDvMqXIBL/U37Gp4SPU0gNnAxPV85KtdLa/wFp0wAO7dwkVoJFoe74+wlM9aK9
+ayaZqEfqsBieMI19Asnxj5huUtEoIiU9ekz6HLeALwy6OxJLrempDugDe2icaWSt
+pLIU3ZXmzVbOFLNtq+KMpanQzamAvSTUq5Wmuz+C6nTEv+JjGWFblX8pM2ACA6cV
+VouefUFfKpMXjHTlsvw0JiDzLeYRxRZZMxnTxzbnoigZfW6ZDxP2w9KRv/7LuSj/
+ktqfVKkCgYEA8qlkPka0cfIKcjloe6oNEMt0dX6V+5LmS59DRnnhu+6FuIVncS7/
+intBGag603wJvGlA7HuUAZbcr4ilDIe1cUm0d8rftjvw0uOBU/gfNVmxhpFzs8Ku
+4Fry6lKow1ecqFQ1i4VZi2qQJVv3m6tRojMTh6xVA9/FLD9iiu3V2dMCgYEA5F6I
+HV1sqY2Q8aU48dch+I1ItrqiURwY7qejuIprpXBoRQPQV3OoYgJcKtdlSKrbDGQd
+iJmL0aoy/ONThrfOtygQtth/f79ktKZZHja8Ew+0/lzfxMSb69kl6Rxx9OKJILPE
+caezhYFGozEKwLddcrqxrSd3Fvz78CVRRiAx2o0CgYEA4g0wh98f24Hpf0zBa2oX
+b8zIOWfp2giXply/tBh4U7S4NxN3MHXisaNuGrOf0UEcZLr8MxBP6UcbYB3/+vM0
+8EsD5hBEZKPkDODIqmtazz015jD7QrsaY3/2CJlmA0tLcXe4xbc8mmZzz4mj2Q04
+J8xC5kGAlPJQ4I5PgzJZ4+cCgYAHyqHiPpnCfy3+0KBMwAZMsKVWdq+rDMZc/iM7
+3J0nm9oy4JpvIWcRUPtMCuVNwWaP2aqYSoTWtnPe5PKomgTXgupvEpvnA+SvtS09
+NqjcDaEjPI/16q9XMKV2ep34uPHsx7VgG1SorWx3jOjNAnSRwYTmX35UrnT6EIvh
+VJ/e0QKBgCgI41QtJ4ShFxpSdxzy3Gfz/EFTUGIjtmXQe/7GixxoXJkpGXCGhToU
+KVF+HUEYKOQ1vX9SNUyY+1LyqO3vj+QzuJ0q4GrtEY7vxDH817QvJLecj5i22Hof
+50MqUdow2BnOSFuJvWhR1DdodRX3vh1awod/CoIufnfEI4MuMO6H
 -----END RSA PRIVATE KEY-----
diff --git a/testing/tests/ikev2/net2net-rfc3779/hosts/sun/etc/ipsec.d/certs/sunCert.pem b/testing/tests/ikev2/net2net-rfc3779/hosts/sun/etc/ipsec.d/certs/sunCert.pem
index 9ccd47a..a93121d 100644
--- a/testing/tests/ikev2/net2net-rfc3779/hosts/sun/etc/ipsec.d/certs/sunCert.pem
+++ b/testing/tests/ikev2/net2net-rfc3779/hosts/sun/etc/ipsec.d/certs/sunCert.pem
@@ -1,28 +1,28 @@
 -----BEGIN CERTIFICATE-----
-MIIEtjCCA56gAwIBAgIBAjANBgkqhkiG9w0BAQsFADBaMQswCQYDVQQGEwJDSDEZ
+MIIEtjCCA56gAwIBAgIBBjANBgkqhkiG9w0BAQsFADBaMQswCQYDVQQGEwJDSDEZ
 MBcGA1UEChMQTGludXggc3Ryb25nU3dhbjEQMA4GA1UECxMHUkZDMzc3OTEeMBwG
-A1UEAxMVc3Ryb25nU3dhbiBSRkMzNzc5IENBMB4XDTA5MTIyMzEzMzUyMVoXDTE0
-MTIyMjEzMzUyMVowVzELMAkGA1UEBhMCQ0gxGTAXBgNVBAoTEExpbnV4IHN0cm9u
+A1UEAxMVc3Ryb25nU3dhbiBSRkMzNzc5IENBMB4XDTE0MTIyNzA2NDkwMFoXDTE5
+MTIyMTA2NDkwMFowVzELMAkGA1UEBhMCQ0gxGTAXBgNVBAoTEExpbnV4IHN0cm9u
 Z1N3YW4xEDAOBgNVBAsTB1JGQzM3NzkxGzAZBgNVBAMTEnN1bi5zdHJvbmdzd2Fu
-Lm9yZzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAK1HhvoVh/fM14RE
-CTXr4to9ZEeGSqHLl5du+eYZl1fC7qLYaCtlaH+eLfDsCgYpe+XsDLHIxpTK9R6k
-XgLP1Jraxz3rtv5qJKkV3aDTjQ2d+cFc0EgiZmn53VEmI/IlcJS/VZzHhNvEJk7H
-k0YpoazpGPtNzFGaehV5mXUAeVPx4RH8fjcSiPbuPS3WC7cqtYvVwk97dj05VfEC
-VnG+90+eFKztvawBzNGwGQ7xZV7kSiPHNyGAV0qrKvhXZ0VPnm/OEiGCAlIo8uno
-Yb/4UMM/a5usCaA9Hgbf8+qqmrzavSUkFEa0y/p9bOBHaqfNP002xktbqBCCodRr
-6QgmiysCAwEAAaOCAYgwggGEMAkGA1UdEwQCMAAwCwYDVR0PBAQDAgOoMB0GA1Ud
-DgQWBBTaKhy7PH1ihWsD+3/bJQ3e3Isj+DCBjAYDVR0jBIGEMIGBgBQhf6frN9Cj
+Lm9yZzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAO+7A6hhF+4kxCv5
+oR9DEpv1gnpGmPpn6i7JfuLGIJ9phQ3bUnSMIx8+mp3JE4SLXINLcyCHilK74tIf
+pwYx2K0c2txTFIWLQvBaHWohJ9Sgg4ElVXmSa/b0Nym5FcttdcRgNGd/+DLPs9Tw
+ZoieGvJcZWiOBP+xxPbEo2xcoi3GetPN+XSW+m1BvU88Ysrp0o+4+rLPB5iipUB1
+Iksb51SvF4iG4BHfoTKGlHLwVyjJnp7YnYJtjY6Xaw1GbCf6wcwLlq71uoMj39cd
+0clncpi/s13K2Sh0YHiCcQD5vIkP9BRmobWAXseBZevYI/rU5dz761EqHf72TRrd
+bM3/KycCAwEAAaOCAYgwggGEMAkGA1UdEwQCMAAwCwYDVR0PBAQDAgOoMB0GA1Ud
+DgQWBBTPOzV+XXFm2wEX9j+NxqVXiRBq7TCBjAYDVR0jBIGEMIGBgBQhf6frN9Cj
 Cx+h3EIGHhFfPNIQFKFepFwwWjELMAkGA1UEBhMCQ0gxGTAXBgNVBAoTEExpbnV4
 IHN0cm9uZ1N3YW4xEDAOBgNVBAsTB1JGQzM3NzkxHjAcBgNVBAMTFXN0cm9uZ1N3
 YW4gUkZDMzc3OSBDQYIJAPKv5keyTotGMB0GA1UdEQQWMBSCEnN1bi5zdHJvbmdz
 d2FuLm9yZzATBgNVHSUEDDAKBggrBgEFBQcDATBBBgNVHR8EOjA4MDagNKAyhjBo
 dHRwOi8vY3JsLnN0cm9uZ3N3YW4ub3JnL3N0cm9uZ3N3YW5fcmZjMzc3OS5jcmww
 RQYIKwYBBQUHAQcBAf8ENjA0MBIEAgABMAwDAwAKAgMFAMCoAAIwHgQCAAIwGAMR
-AP7AAAAAAAAAAAAAAAAAAAIDAwD+wjANBgkqhkiG9w0BAQsFAAOCAQEAOqdCIldA
-mPp2aAWVPBiKXNrk4VJoIGlwZaUtYNxGQ46wUqAro/taKwZd4B1yvwsX/cHX3Y6j
-C1mQtiXw9onJm1qJM1a804U9yPcgdI+9RMiU0hA+aVmyMlS6WQsKFubU17qP2Ljd
-4hOwVQ681Hi8zfQjJdYpaO1yLcpy2dkotreJS3wA24ssnskRBI/cuAN0dfbV6SDQ
-TK91qz0emHoK3efgtvX4oEpsxI4NrwMstaZSVsHn4npKTGYu82dmPoK6WPblGEHZ
-Iavl08lGcYBV5I2ZGuWOekWQzUuBSveV3AFjieeaDIG3Ue3AKaihn6dCLz6l+t7E
-dXN+1axy9zQ34g==
+AP7AAAAAAAAAAAAAAAAAAAIDAwD+wjANBgkqhkiG9w0BAQsFAAOCAQEAgJDWuKCu
+7H/K4U7xFRarSKtj9oMAAsq2vLSQqJTUg6fdTnFIlH3OBPcwEzFwVx30QlQyls1p
+nHm/cptV/3cxvqCvdnT2dVspJu+9a5D+zZNeLAtWZuyRN6Nlmeqj1Nnp6eEHEBrg
+oXMzmAf0ulzIZJsEVYwJSCXm0AMOlyvoIYqKxty3L2VZ1iAU1z15lnFhcvamraGx
+k7yaI9ujVR4xQZOOgh05pUrEKaXI3XR1rIoL3NV3ws/JgHch/CQw/If7x4VQmGcD
+yJbKkKn0S18TJr0KhPqbM4+inldEwyX/zjGmlHezy0em5qTRYwupFIQNwZZkTXug
+NnBR3lf2HB2lWA==
 -----END CERTIFICATE-----
diff --git a/testing/tests/ikev2/net2net-rfc3779/hosts/sun/etc/ipsec.d/private/sunKey.pem b/testing/tests/ikev2/net2net-rfc3779/hosts/sun/etc/ipsec.d/private/sunKey.pem
index 6e047af..55f5f80 100644
--- a/testing/tests/ikev2/net2net-rfc3779/hosts/sun/etc/ipsec.d/private/sunKey.pem
+++ b/testing/tests/ikev2/net2net-rfc3779/hosts/sun/etc/ipsec.d/private/sunKey.pem
@@ -1,27 +1,27 @@
 -----BEGIN RSA PRIVATE KEY-----
-MIIEowIBAAKCAQEArUeG+hWH98zXhEQJNevi2j1kR4ZKocuXl2755hmXV8Luotho
-K2Vof54t8OwKBil75ewMscjGlMr1HqReAs/UmtrHPeu2/mokqRXdoNONDZ35wVzQ
-SCJmafndUSYj8iVwlL9VnMeE28QmTseTRimhrOkY+03MUZp6FXmZdQB5U/HhEfx+
-NxKI9u49LdYLtyq1i9XCT3t2PTlV8QJWcb73T54UrO29rAHM0bAZDvFlXuRKI8c3
-IYBXSqsq+FdnRU+eb84SIYICUijy6ehhv/hQwz9rm6wJoD0eBt/z6qqavNq9JSQU
-RrTL+n1s4Edqp80/TTbGS1uoEIKh1GvpCCaLKwIDAQABAoIBAHKb86/nm9YPu6B1
-K65phdMZdgFE1oorUenMcid6V7qpaRN2lXfWjAaUxggq5vpqZ9OMjFzu0kHJ99S7
-nJ65fgKqn8vZ42BlLjhUCRH9urb9/Rqi2/RKJHkF1hd9ZZscnlkUMHkRElQVac0D
-feqTUKdASdC2BWUYCpW3pwNXO+iD5bA9/wB2J/RYYmm6Qo7UZQU8C0lken/8EOEL
-/ch0ID7C5PC0vWvLT0fM9j2JKDq8T6NRhF1MluISGDOp4pW7tEbkHo5I6zD0aPO2
-K9leN3aSUYsOVJk39VXkThwgJ4lqNEXI2xRbtW8sAf7TL1YDxLR2JN3UGvy/By5B
-UblJUnECgYEA2nO+iXScKd3qqmHrdXcxf2ExZQr8QgTAsZOkb6LQ9kGQll0lBcFc
-T2HlobzOaQktpF44C41zf2QpGDllbpyNT8VyQkI+CJ4pntjtKPkoPkxUeVlciFsm
-7THqCGe0zQBWDnXFVfTKR12aRwkhjG+QCQyyaAaV8YztEsDI5SRCjykCgYEAyxAb
-t/NTh9DBDrfJCkT21Rm9Ow70vhDaAyQLq3nJMF+BTXYDrnVMmFHCIHd+nbNP0CLs
-cV/fWAF6626ko5B6ewPFQ4wXRvtNAiDNZSfeaZgvxCrvoDgVrHWhfwHSXWFqny0o
-WHwIJJQvdkLW9BHwbpAQRoD1c2sy7pWIVTEyljMCgYEA0zZXwkUp/FzhWG2moANn
-qzZI8N4nOpmnycnrkjiE+6Q27PsQIblrzCDmSnPnyqyiIasrWxgf1Mr95LsR9FmP
-U9Ke/6tWmTR7H2e0HgqRO3LHtjCNhBVF1M6O7iN/Lzqk+gQqkUpGDaxVz1rnwgXX
-6LgLAwNjFJJiYeBeHRbq98kCgYAwBdg4UbBgf0sY+vftmM+zKAorjGbvCDc25PBp
-ljyxVvTSZ+WI/a6mmzdIzFnCW+S1OX0ndt/wBTGXuivvjryYmRSu29OpcscMiMtq
-b9pWqKorP2g6QOlHRu5xhfHFKcO4b0qKWpLma7Epy7bgM9njm+htdBQYPrLl37FF
-TIRFJwKBgGnZR5rm5iCrcIoAUMlH4/5ye5BPjHDn1NNv7Q7PZR9jhaEuoiBgvk6v
-h+YVi9A9nhbaqS4/rumsNPlObeIw78713pendaWCjC4hA0urrJ4fElfuaIyZMyKE
-FD64V78iaYVlmwKMJxZUnS1EFzb0XQZM7wxhB/i0wwjh+48rBHbd
+MIIEpAIBAAKCAQEA77sDqGEX7iTEK/mhH0MSm/WCekaY+mfqLsl+4sYgn2mFDdtS
+dIwjHz6anckThItcg0tzIIeKUrvi0h+nBjHYrRza3FMUhYtC8FodaiEn1KCDgSVV
+eZJr9vQ3KbkVy211xGA0Z3/4Ms+z1PBmiJ4a8lxlaI4E/7HE9sSjbFyiLcZ60835
+dJb6bUG9TzxiyunSj7j6ss8HmKKlQHUiSxvnVK8XiIbgEd+hMoaUcvBXKMmentid
+gm2NjpdrDUZsJ/rBzAuWrvW6gyPf1x3RyWdymL+zXcrZKHRgeIJxAPm8iQ/0FGah
+tYBex4Fl69gj+tTl3PvrUSod/vZNGt1szf8rJwIDAQABAoIBAQDf/YrzXpTva+bn
+d7y16wOOORyKh0AUZ9eFk7s8xAZjLEKnqc8nGnEOln39A417AIOWIX8WW85Ac1EB
+J5X10ck0JovP5Mh95prK3Egzi3sdzkRQ/MMablb2TUTldQwKIOIyc/lC42zSfQL3
+6Q7Eg4WGAhK2WEwPZNg2AZD4hKz7unK+IAar9uLi39E4iVzDavzwK5y+fsy3HVFD
+cJbPWAr4+4teinF5wkRzK7OInwkPc9IrUF/9wp1ZWp/Rc1YEkCVwmu5v7kPzALI0
+SLwYLil8mXfvG0VZjYIlhCSOJJRuw/0JR2cCDJ9WFppK+YKNh+uLoPXhJxbXM8fB
+BmCHhpdRAoGBAPpc7DhUQv8mxGCOy9O/ec50GTPj0bWD0WLrJoqvHu+LyN8OwTdG
+KMdV4Mp/tpAWbAlKH22/+7P/QCOCwByHQaUisnbkqx+5/JhZsQB7rLAdQ8SHLdj2
+iO2+6cgYPOFm6W4QT7/vl4BHAK4Glw5NPyS5sN9JBTY4bpzFHunsRe27AoGBAPUg
+zoUZnZ/6g+8XRSH77aLAbKScMBGusyxfhFAesqaXcrCrg8FG6Wcpuv2HsBE1v0d0
+7/1oJdT+p+uB2V3iZqTOeJeOCVYXgU82NRZl7R8hqYzkD8rFUZVg6hlm2xi+IUpE
+ya4itKWIckSvnexEqiBov7k8sPmb7R/7HWGWUOuFAoGADz8PZ5LCDbW3qcWoZfm4
+Gjl5u245PBuN6b82NqXZdW8GyYalf483NoRlTw+d94JWC+7GoTFay6hUqJTyzAn0
+lnDZe2ILhcAWwNRdchEWABeYI+Szhw3kYs4IgJXxRyy0NG6r3J1jlX09bluaYVWU
+7dCdE8vnlFi1a7iZXFd2HrcCgYBknEGHqdrjdbw/Hwr2BuQjf91Xtu+X4l+SH+Y7
+yE3FSLX/Q3aBluxntl4Uf2PJvIi0+I8kMGIOyTL827/u4+UDUed3NQop9t3ROEuT
+1OP9eiCQPm8o59IzgKK1KF1XC3q4dAFfYslIg/d6r6Ye+pPlV3kRu5Jb8R7jmHsX
+uc2ezQKBgQDgouR4ipkb+sQcMKkhzHUEx67aHEVH69v2R9lm8YgPHjvPCA++DgPZ
+dwWALnW5wKRfdGy4b1yTIICUgjKIIlD2owJB/J5Z4SzrzbOAEJkNURGAhp6njsf+
+QYRyoXLOb/8jAQqLx9hOB8L2gsRSDddvvYw/DTP2cKM8vJtYFWam+A==
 -----END RSA PRIVATE KEY-----
diff --git a/testing/tests/ikev2/net2net-same-nets/hosts/sun/etc/mark_updown b/testing/tests/ikev2/net2net-same-nets/hosts/sun/etc/mark_updown
index bdba3fb..e9ab41c 100755
--- a/testing/tests/ikev2/net2net-same-nets/hosts/sun/etc/mark_updown
+++ b/testing/tests/ikev2/net2net-same-nets/hosts/sun/etc/mark_updown
@@ -1,4 +1,4 @@
-#! /bin/sh
+#!/bin/sh
 # updown script setting inbound marks on ESP traffic in the mangle chain
 #
 # Copyright (C) 2003-2004 Nigel Meteringham
@@ -22,8 +22,6 @@
 # that, and use the (left/right)updown parameters in ipsec.conf to make
 # strongSwan use yours instead of this default one.
 
-# things that this script gets (from ipsec_pluto(8) man page)
-#
 #      PLUTO_VERSION
 #              indicates  what  version of this interface is being
 #              used.  This document describes version  1.1.   This
@@ -41,15 +39,20 @@
 #              is the name of the  connection  for  which  we  are
 #              routing.
 #
-#       PLUTO_NEXT_HOP
-#              is the next hop to which packets bound for the peer
-#              must be sent.
-#
 #       PLUTO_INTERFACE
 #              is the name of the ipsec interface to be used.
 #
 #       PLUTO_REQID
-#              is the requid of the ESP policy
+#              is the requid of the AH|ESP policy
+#
+#       PLUTO_PROTO
+#              is the negotiated IPsec protocol, ah|esp
+#
+#       PLUTO_IPCOMP
+#              is not empty if IPComp was negotiated
+#
+#       PLUTO_UNIQUEID
+#              is the unique identifier of the associated IKE_SA
 #
 #       PLUTO_ME
 #              is the IP address of our host.
@@ -63,15 +66,6 @@
 #              host's own IP address / max (where max  is  32  for
 #              IPv4 and 128 for IPv6).
 #
-#       PLUTO_MY_CLIENT_NET
-#              is the IP address of our client net.  If the client
-#              is just the host, this will be the  host's  own  IP
-#              address.
-#
-#       PLUTO_MY_CLIENT_MASK
-#              is  the  mask for our client net.  If the client is
-#              just the host, this will be 255.255.255.255.
-#
 #       PLUTO_MY_SOURCEIP
 #       PLUTO_MY_SOURCEIP4_$i
 #       PLUTO_MY_SOURCEIP6_$i
@@ -85,7 +79,8 @@
 #
 #       PLUTO_MY_PORT
 #              is  the  UDP/TCP  port  to  which  the IPsec SA  is
-#              restricted on our side.
+#              restricted on our side.  For ICMP/ICMPv6 this contains the
+#              message type, and PLUTO_PEER_PORT the message code.
 #
 #       PLUTO_PEER
 #              is the IP address of our peer.
@@ -93,31 +88,19 @@
 #       PLUTO_PEER_ID
 #              is the ID of our peer.
 #
-#       PLUTO_PEER_CA
-#              is the CA which issued the cert of our peer.
-#
 #       PLUTO_PEER_CLIENT
 #              is the IP address / count of the peer's client sub-
 #              net.   If the client is just the peer, this will be
 #              the peer's own IP address / max (where  max  is  32
 #              for IPv4 and 128 for IPv6).
 #
-#       PLUTO_PEER_CLIENT_NET
-#              is the IP address of the peer's client net.  If the
-#              client is just the peer, this will  be  the  peer's
-#              own IP address.
-#
-#       PLUTO_PEER_CLIENT_MASK
-#              is  the  mask  for  the  peer's client net.  If the
-#              client   is   just   the   peer,   this   will   be
-#              255.255.255.255.
-#
 #       PLUTO_PEER_PROTOCOL
 #              is the IP protocol that will be transported.
 #
 #       PLUTO_PEER_PORT
 #              is  the  UDP/TCP  port  to  which  the IPsec SA  is
-#              restricted on the peer side.
+#              restricted on the peer side.  For ICMP/ICMPv6 this contains the
+#              message code, and PLUTO_MY_PORT the message type.
 #
 #       PLUTO_XAUTH_ID
 #              is an optional user ID employed by the XAUTH protocol
@@ -186,7 +169,6 @@ fi
 PLUTO_MY_ID=`printf "$PLUTO_MY_ID"`
 PLUTO_PEER_ID=`printf "$PLUTO_PEER_ID"`
 
-# the big choice
 case "$PLUTO_VERB:$1" in
 up-client:)
 	# connection to my client subnet coming up
diff --git a/testing/tests/ikev2/reauth-mbb-virtual-ip/description.txt b/testing/tests/ikev2/reauth-mbb-virtual-ip/description.txt
new file mode 100644
index 0000000..dfec6a3
--- /dev/null
+++ b/testing/tests/ikev2/reauth-mbb-virtual-ip/description.txt
@@ -0,0 +1,8 @@
+This scenario tests <b>make-before-break reauthentication</b> using overlapping
+IKE_SAs by setting the <i>make_before_break</i> strongswan.conf option for
+clients using an assigned virtual IP. The initiator <b>carol</b> reauthenticates
+the IKE_SA with host <b>moon</b> using <b>ikelifetime=10s</b>, but does not
+close the old IKE_SA before the replacement CHILD_SA using the same virtual IP
+is in place. A constant ping from <b>carol</b> to client <b>alice</b>
+hiding in the subnet behind <b>moon</b> tests if the CHILD_SA works during the
+whole procedure.
diff --git a/testing/tests/ikev2/reauth-mbb-virtual-ip/evaltest.dat b/testing/tests/ikev2/reauth-mbb-virtual-ip/evaltest.dat
new file mode 100644
index 0000000..5094574
--- /dev/null
+++ b/testing/tests/ikev2/reauth-mbb-virtual-ip/evaltest.dat
@@ -0,0 +1,7 @@
+moon:: ipsec status 2> /dev/null::rw\[1]: ESTABLISHED.*moon.strongswan.org.*carol at strongswan.org::YES
+carol::ipsec status 2> /dev/null::home\[1]: ESTABLISHED.*carol at strongswan.org.*moon.strongswan.org::YES
+carol::ping -c 8 PH_IP_ALICE::64 bytes from PH_IP_ALICE::YES
+moon:: ipsec status 2> /dev/null::rw\[2]: ESTABLISHED.*moon.strongswan.org.*carol at strongswan.org::YES
+carol::ipsec status 2> /dev/null::home\[2]: ESTABLISHED.*carol at strongswan.org.*moon.strongswan.org::YES
+moon::tcpdump::IP carol.strongswan.org > moon.strongswan.org: ESP::YES
+moon::tcpdump::IP moon.strongswan.org > carol.strongswan.org: ESP::YES
diff --git a/testing/tests/ikev2/reauth-mbb-virtual-ip/hosts/carol/etc/ipsec.conf b/testing/tests/ikev2/reauth-mbb-virtual-ip/hosts/carol/etc/ipsec.conf
new file mode 100644
index 0000000..6447b1c
--- /dev/null
+++ b/testing/tests/ikev2/reauth-mbb-virtual-ip/hosts/carol/etc/ipsec.conf
@@ -0,0 +1,22 @@
+# /etc/ipsec.conf - strongSwan IPsec configuration file
+
+config setup
+
+conn %default
+	keylife=20m
+	ikelifetime=10s
+	rekeymargin=5s
+	rekeyfuzz=0%
+	keyingtries=1
+
+conn home
+	left=PH_IP_CAROL
+	leftcert=carolCert.pem
+	leftid=carol at strongswan.org
+	leftsourceip=%config
+	leftfirewall=yes
+	right=PH_IP_MOON
+	rightid=@moon.strongswan.org
+	rightsubnet=10.1.0.0/16
+	keyexchange=ikev2
+	auto=add
diff --git a/testing/tests/ikev2/reauth-mbb-virtual-ip/hosts/carol/etc/strongswan.conf b/testing/tests/ikev2/reauth-mbb-virtual-ip/hosts/carol/etc/strongswan.conf
new file mode 100644
index 0000000..f89437e
--- /dev/null
+++ b/testing/tests/ikev2/reauth-mbb-virtual-ip/hosts/carol/etc/strongswan.conf
@@ -0,0 +1,7 @@
+# /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
+
+  make_before_break = yes
+}
diff --git a/testing/tests/ikev2/reauth-mbb-virtual-ip/hosts/moon/etc/ipsec.conf b/testing/tests/ikev2/reauth-mbb-virtual-ip/hosts/moon/etc/ipsec.conf
new file mode 100644
index 0000000..121ea7e
--- /dev/null
+++ b/testing/tests/ikev2/reauth-mbb-virtual-ip/hosts/moon/etc/ipsec.conf
@@ -0,0 +1,20 @@
+# /etc/ipsec.conf - strongSwan IPsec configuration file
+
+config setup
+
+conn %default
+	ikelifetime=30m
+	keylife=20m
+	rekeymargin=0s
+	keyingtries=1
+
+conn rw
+	left=PH_IP_MOON
+	leftcert=moonCert.pem
+	leftid=@moon.strongswan.org
+	leftsubnet=10.1.0.0/16
+	leftfirewall=yes
+	right=%any
+	rightsourceip=10.3.0.0/24
+	keyexchange=ikev2
+	auto=add
diff --git a/testing/tests/ikev2/reauth-mbb-virtual-ip/hosts/moon/etc/strongswan.conf b/testing/tests/ikev2/reauth-mbb-virtual-ip/hosts/moon/etc/strongswan.conf
new file mode 100644
index 0000000..f585edf
--- /dev/null
+++ b/testing/tests/ikev2/reauth-mbb-virtual-ip/hosts/moon/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/ikev2/reauth-mbb-virtual-ip/posttest.dat b/testing/tests/ikev2/reauth-mbb-virtual-ip/posttest.dat
new file mode 100644
index 0000000..046d4cf
--- /dev/null
+++ b/testing/tests/ikev2/reauth-mbb-virtual-ip/posttest.dat
@@ -0,0 +1,4 @@
+moon::ipsec stop
+carol::ipsec stop
+moon::iptables-restore < /etc/iptables.flush
+carol::iptables-restore < /etc/iptables.flush
diff --git a/testing/tests/ikev2/reauth-mbb-virtual-ip/pretest.dat b/testing/tests/ikev2/reauth-mbb-virtual-ip/pretest.dat
new file mode 100644
index 0000000..baacc16
--- /dev/null
+++ b/testing/tests/ikev2/reauth-mbb-virtual-ip/pretest.dat
@@ -0,0 +1,6 @@
+moon::iptables-restore < /etc/iptables.rules
+carol::iptables-restore < /etc/iptables.rules
+moon::ipsec start
+carol::ipsec start
+carol::sleep 1
+carol::ipsec up home
diff --git a/testing/tests/ikev2/reauth-mbb-virtual-ip/test.conf b/testing/tests/ikev2/reauth-mbb-virtual-ip/test.conf
new file mode 100644
index 0000000..4a5fc47
--- /dev/null
+++ b/testing/tests/ikev2/reauth-mbb-virtual-ip/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 carol winnetou"
+
+# Corresponding block diagram
+#
+DIAGRAM="a-m-c-w.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="moon carol"
diff --git a/testing/tests/ikev2/reauth-mbb/description.txt b/testing/tests/ikev2/reauth-mbb/description.txt
new file mode 100644
index 0000000..ab92d7d
--- /dev/null
+++ b/testing/tests/ikev2/reauth-mbb/description.txt
@@ -0,0 +1,7 @@
+This scenario tests <b>make-before-break reauthentication</b> using overlapping
+IKE_SAs by setting the <i>make_before_break</i> strongswan.conf option. The
+initiator <b>carol</b> reauthenticates the IKE_SA with host <b>moon</b> using
+<b>ikelifetime=10s</b>, but does not close the old IKE_SA before the replacement
+CHILD_SA is in place. A constant ping from <b>carol</b> to client <b>alice</b>
+hiding in the subnet behind <b>moon</b> tests if the CHILD_SA works during the
+whole procedure.
diff --git a/testing/tests/ikev2/reauth-mbb/evaltest.dat b/testing/tests/ikev2/reauth-mbb/evaltest.dat
new file mode 100644
index 0000000..5094574
--- /dev/null
+++ b/testing/tests/ikev2/reauth-mbb/evaltest.dat
@@ -0,0 +1,7 @@
+moon:: ipsec status 2> /dev/null::rw\[1]: ESTABLISHED.*moon.strongswan.org.*carol at strongswan.org::YES
+carol::ipsec status 2> /dev/null::home\[1]: ESTABLISHED.*carol at strongswan.org.*moon.strongswan.org::YES
+carol::ping -c 8 PH_IP_ALICE::64 bytes from PH_IP_ALICE::YES
+moon:: ipsec status 2> /dev/null::rw\[2]: ESTABLISHED.*moon.strongswan.org.*carol at strongswan.org::YES
+carol::ipsec status 2> /dev/null::home\[2]: ESTABLISHED.*carol at strongswan.org.*moon.strongswan.org::YES
+moon::tcpdump::IP carol.strongswan.org > moon.strongswan.org: ESP::YES
+moon::tcpdump::IP moon.strongswan.org > carol.strongswan.org: ESP::YES
diff --git a/testing/tests/ikev2/reauth-mbb/hosts/carol/etc/ipsec.conf b/testing/tests/ikev2/reauth-mbb/hosts/carol/etc/ipsec.conf
new file mode 100644
index 0000000..f46405a
--- /dev/null
+++ b/testing/tests/ikev2/reauth-mbb/hosts/carol/etc/ipsec.conf
@@ -0,0 +1,21 @@
+# /etc/ipsec.conf - strongSwan IPsec configuration file
+
+config setup
+
+conn %default
+	keylife=20m
+	ikelifetime=10s
+	rekeymargin=5s
+	rekeyfuzz=0%
+	keyingtries=1
+
+conn home
+	left=PH_IP_CAROL
+	leftcert=carolCert.pem
+	leftid=carol at strongswan.org
+	leftfirewall=yes
+	right=PH_IP_MOON
+	rightid=@moon.strongswan.org
+	rightsubnet=10.1.0.0/16
+	keyexchange=ikev2
+	auto=add
diff --git a/testing/tests/ikev2/reauth-mbb/hosts/carol/etc/strongswan.conf b/testing/tests/ikev2/reauth-mbb/hosts/carol/etc/strongswan.conf
new file mode 100644
index 0000000..f89437e
--- /dev/null
+++ b/testing/tests/ikev2/reauth-mbb/hosts/carol/etc/strongswan.conf
@@ -0,0 +1,7 @@
+# /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
+
+  make_before_break = yes
+}
diff --git a/testing/tests/ikev2/reauth-mbb/hosts/moon/etc/ipsec.conf b/testing/tests/ikev2/reauth-mbb/hosts/moon/etc/ipsec.conf
new file mode 100644
index 0000000..2f45574
--- /dev/null
+++ b/testing/tests/ikev2/reauth-mbb/hosts/moon/etc/ipsec.conf
@@ -0,0 +1,19 @@
+# /etc/ipsec.conf - strongSwan IPsec configuration file
+
+config setup
+
+conn %default
+	ikelifetime=30m
+	keylife=20m
+	rekeymargin=0s
+	keyingtries=1
+
+conn rw
+	left=PH_IP_MOON
+	leftcert=moonCert.pem
+	leftid=@moon.strongswan.org
+	leftsubnet=10.1.0.0/16
+	leftfirewall=yes
+	right=%any
+	keyexchange=ikev2
+	auto=add
diff --git a/testing/tests/ikev2/reauth-mbb/hosts/moon/etc/strongswan.conf b/testing/tests/ikev2/reauth-mbb/hosts/moon/etc/strongswan.conf
new file mode 100644
index 0000000..f585edf
--- /dev/null
+++ b/testing/tests/ikev2/reauth-mbb/hosts/moon/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/ikev2/reauth-mbb/posttest.dat b/testing/tests/ikev2/reauth-mbb/posttest.dat
new file mode 100644
index 0000000..046d4cf
--- /dev/null
+++ b/testing/tests/ikev2/reauth-mbb/posttest.dat
@@ -0,0 +1,4 @@
+moon::ipsec stop
+carol::ipsec stop
+moon::iptables-restore < /etc/iptables.flush
+carol::iptables-restore < /etc/iptables.flush
diff --git a/testing/tests/ikev2/reauth-mbb/pretest.dat b/testing/tests/ikev2/reauth-mbb/pretest.dat
new file mode 100644
index 0000000..baacc16
--- /dev/null
+++ b/testing/tests/ikev2/reauth-mbb/pretest.dat
@@ -0,0 +1,6 @@
+moon::iptables-restore < /etc/iptables.rules
+carol::iptables-restore < /etc/iptables.rules
+moon::ipsec start
+carol::ipsec start
+carol::sleep 1
+carol::ipsec up home
diff --git a/testing/tests/ikev2/reauth-mbb/test.conf b/testing/tests/ikev2/reauth-mbb/test.conf
new file mode 100644
index 0000000..4a5fc47
--- /dev/null
+++ b/testing/tests/ikev2/reauth-mbb/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 carol winnetou"
+
+# Corresponding block diagram
+#
+DIAGRAM="a-m-c-w.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="moon carol"
diff --git a/testing/tests/ikev2/rw-eap-aka-id-rsa/evaltest.dat b/testing/tests/ikev2/rw-eap-aka-id-rsa/evaltest.dat
index d59eef5..20f1f13 100644
--- a/testing/tests/ikev2/rw-eap-aka-id-rsa/evaltest.dat
+++ b/testing/tests/ikev2/rw-eap-aka-id-rsa/evaltest.dat
@@ -1,4 +1,4 @@
-carol::cat /var/log/daemon.log::authentication of 'moon.strongswan.org' with RSA signature successful::YES
+carol::cat /var/log/daemon.log::authentication of 'moon.strongswan.org' with RSA.* successful::YES
 carol::cat /var/log/daemon.log::server requested EAP_AKA authentication::YES
 carol::cat /var/log/daemon.log::authentication of 'moon.strongswan.org' with EAP successful::YES
 moon:: cat /var/log/daemon.log::received EAP identity.*carol::YES
diff --git a/testing/tests/ikev2/rw-eap-aka-rsa/evaltest.dat b/testing/tests/ikev2/rw-eap-aka-rsa/evaltest.dat
index 0ea4e21..77e306b 100644
--- a/testing/tests/ikev2/rw-eap-aka-rsa/evaltest.dat
+++ b/testing/tests/ikev2/rw-eap-aka-rsa/evaltest.dat
@@ -1,4 +1,4 @@
-carol::cat /var/log/daemon.log::authentication of 'moon.strongswan.org' with RSA signature successful::YES
+carol::cat /var/log/daemon.log::authentication of 'moon.strongswan.org' with RSA.* successful::YES
 carol::cat /var/log/daemon.log::server requested EAP_AKA authentication::YES
 carol::cat /var/log/daemon.log::authentication of 'moon.strongswan.org' with EAP successful::YES
 moon:: cat /var/log/daemon.log::authentication of 'carol at strongswan.org' with EAP successful::YES
diff --git a/testing/tests/ikev2/rw-eap-aka-rsa/hosts/carol/etc/ipsec.conf b/testing/tests/ikev2/rw-eap-aka-rsa/hosts/carol/etc/ipsec.conf
index b4825fb..c2efc3f 100644
--- a/testing/tests/ikev2/rw-eap-aka-rsa/hosts/carol/etc/ipsec.conf
+++ b/testing/tests/ikev2/rw-eap-aka-rsa/hosts/carol/etc/ipsec.conf
@@ -11,7 +11,6 @@ conn %default
 
 conn home
 	left=PH_IP_CAROL
-	leftnexthop=%direct
 	leftid=carol at strongswan.org
 	leftauth=eap
 	leftfirewall=yes
diff --git a/testing/tests/ikev2/rw-eap-dynamic/evaltest.dat b/testing/tests/ikev2/rw-eap-dynamic/evaltest.dat
index 6a20b8e..e09765f 100644
--- a/testing/tests/ikev2/rw-eap-dynamic/evaltest.dat
+++ b/testing/tests/ikev2/rw-eap-dynamic/evaltest.dat
@@ -1,7 +1,7 @@
-carol::cat /var/log/daemon.log::authentication of 'moon.strongswan.org' with RSA signature successful::YES
+carol::cat /var/log/daemon.log::authentication of 'moon.strongswan.org' with RSA.* successful::YES
 carol::cat /var/log/daemon.log::authentication of 'moon.strongswan.org' with EAP successful::YES
 carol::cat /var/log/daemon.log::EAP method EAP_MD5 succeeded, no MSK established::YES
-dave:: cat /var/log/daemon.log::authentication of 'moon.strongswan.org' with RSA signature successful::YES
+dave:: cat /var/log/daemon.log::authentication of 'moon.strongswan.org' with RSA.* successful::YES
 dave:: cat /var/log/daemon.log::requesting EAP_TLS authentication, sending EAP_NAK::YES
 dave:: cat /var/log/daemon.log::authentication of 'moon.strongswan.org' with EAP successful::YES
 dave:: cat /var/log/daemon.log::EAP method EAP_TLS succeeded, MSK established::YES
diff --git a/testing/tests/ikev2/rw-eap-framed-ip-radius/evaltest.dat b/testing/tests/ikev2/rw-eap-framed-ip-radius/evaltest.dat
index 1460ec8..10ce861 100644
--- a/testing/tests/ikev2/rw-eap-framed-ip-radius/evaltest.dat
+++ b/testing/tests/ikev2/rw-eap-framed-ip-radius/evaltest.dat
@@ -1,4 +1,4 @@
-carol::cat /var/log/daemon.log::authentication of .*moon.strongswan.org.* with RSA signature successful::YES
+carol::cat /var/log/daemon.log::authentication of .*moon.strongswan.org.* with RSA.* successful::YES
 moon ::cat /var/log/daemon.log::received EAP identity .*carol::YES
 carol::cat /var/log/daemon.log::server requested EAP_MD5 authentication::YES
 carol::cat /var/log/daemon.log::authentication of .*moon.strongswan.org.* with EAP successful::YES
@@ -8,7 +8,7 @@ carol::ipsec status 2> /dev/null::home.*ESTABLISHED.*PH_IP_CAROL.*moon.strongswa
 moon ::ipsec status 2> /dev/null::rw-eap[{]1}.*INSTALLED, TUNNEL::YES
 carol::ipsec status 2> /dev/null::home.*INSTALLED, TUNNEL::YES
 carol::cat /var/log/daemon.log::installing new virtual IP 10.3.0.1::YES
-dave ::cat /var/log/daemon.log::authentication of .*moon.strongswan.org.* with RSA signature successful::YES
+dave ::cat /var/log/daemon.log::authentication of .*moon.strongswan.org.* with RSA.* successful::YES
 moon ::cat /var/log/daemon.log::received EAP identity .*dave::YES
 dave ::cat /var/log/daemon.log::server requested EAP_MD5 authentication::YES
 dave ::cat /var/log/daemon.log::authentication of .*moon.strongswan.org.* with EAP successful::YES
diff --git a/testing/tests/ikev2/rw-eap-md5-class-radius/evaltest.dat b/testing/tests/ikev2/rw-eap-md5-class-radius/evaltest.dat
index aa6d429..47a4977 100644
--- a/testing/tests/ikev2/rw-eap-md5-class-radius/evaltest.dat
+++ b/testing/tests/ikev2/rw-eap-md5-class-radius/evaltest.dat
@@ -1,4 +1,4 @@
-carol::cat /var/log/daemon.log::authentication of .*moon.strongswan.org.* with RSA signature successful::YES
+carol::cat /var/log/daemon.log::authentication of .*moon.strongswan.org.* with RSA.* successful::YES
 moon ::cat /var/log/daemon.log::received EAP identity .*carol::YES
 carol::cat /var/log/daemon.log::server requested EAP_MD5 authentication::YES
 carol::cat /var/log/daemon.log::authentication of .*moon.strongswan.org.* with EAP successful::YES
@@ -8,7 +8,7 @@ carol::ipsec status 2> /dev/null::alice.*ESTABLISHED.*PH_IP_CAROL.*moon.strongsw
 moon ::ipsec status 2> /dev/null::research.*INSTALLED, TUNNEL::YES
 carol::ipsec status 2> /dev/null::alice.*INSTALLED, TUNNEL::YES
 carol::ipsec status 2> /dev/null::venus.*INSTALLED, TUNNEL::NO
-dave ::cat /var/log/daemon.log::authentication of .*moon.strongswan.org.* with RSA signature successful::YES
+dave ::cat /var/log/daemon.log::authentication of .*moon.strongswan.org.* with RSA.* successful::YES
 moon ::cat /var/log/daemon.log::received EAP identity .*dave::YES
 dave ::cat /var/log/daemon.log::server requested EAP_MD5 authentication::YES
 dave ::cat /var/log/daemon.log::authentication of .*moon.strongswan.org.* with EAP successful::YES
diff --git a/testing/tests/ikev2/rw-eap-md5-id-prompt/evaltest.dat b/testing/tests/ikev2/rw-eap-md5-id-prompt/evaltest.dat
index 42d2c31..5853deb 100644
--- a/testing/tests/ikev2/rw-eap-md5-id-prompt/evaltest.dat
+++ b/testing/tests/ikev2/rw-eap-md5-id-prompt/evaltest.dat
@@ -1,6 +1,6 @@
 carol::cat /var/log/daemon.log::configured EAP-Identity carol::YES
 carol::cat /var/log/daemon.log::added EAP secret for carol moon.strongswan.org::YES
-carol::cat /var/log/daemon.log::authentication of 'moon.strongswan.org' with RSA signature successful::YES
+carol::cat /var/log/daemon.log::authentication of 'moon.strongswan.org' with RSA.* successful::YES
 carol::cat /var/log/daemon.log::authentication of 'moon.strongswan.org' with EAP successful::YES
 moon:: cat /var/log/daemon.log::authentication of 'PH_IP_CAROL' with EAP successful::YES
 moon:: cat /var/log/daemon.log::received EAP identity.*carol::YES
diff --git a/testing/tests/ikev2/rw-eap-md5-id-radius/evaltest.dat b/testing/tests/ikev2/rw-eap-md5-id-radius/evaltest.dat
index 8f81339..109407b 100644
--- a/testing/tests/ikev2/rw-eap-md5-id-radius/evaltest.dat
+++ b/testing/tests/ikev2/rw-eap-md5-id-radius/evaltest.dat
@@ -1,4 +1,4 @@
-carol::cat /var/log/daemon.log::authentication of .*moon.strongswan.org.* with RSA signature successful::YES
+carol::cat /var/log/daemon.log::authentication of .*moon.strongswan.org.* with RSA.* successful::YES
 moon:: cat /var/log/daemon.log::received EAP identity .*carol::YES
 carol::cat /var/log/daemon.log::server requested EAP_MD5 authentication::YES
 carol::cat /var/log/daemon.log::authentication of .*moon.strongswan.org.* with EAP successful::YES
diff --git a/testing/tests/ikev2/rw-eap-md5-id-radius/hosts/carol/etc/ipsec.conf b/testing/tests/ikev2/rw-eap-md5-id-radius/hosts/carol/etc/ipsec.conf
index 881971e..87c37f3 100644
--- a/testing/tests/ikev2/rw-eap-md5-id-radius/hosts/carol/etc/ipsec.conf
+++ b/testing/tests/ikev2/rw-eap-md5-id-radius/hosts/carol/etc/ipsec.conf
@@ -11,7 +11,6 @@ conn %default
 
 conn home
 	left=PH_IP_CAROL
-	leftnexthop=%direct
 	leftid=carol at strongswan.org
 	leftauth=eap
 	leftfirewall=yes
diff --git a/testing/tests/ikev2/rw-eap-md5-radius/evaltest.dat b/testing/tests/ikev2/rw-eap-md5-radius/evaltest.dat
index a8019b3..49045c9 100644
--- a/testing/tests/ikev2/rw-eap-md5-radius/evaltest.dat
+++ b/testing/tests/ikev2/rw-eap-md5-radius/evaltest.dat
@@ -1,4 +1,4 @@
-carol::cat /var/log/daemon.log::authentication of 'moon.strongswan.org' with RSA signature successful::YES
+carol::cat /var/log/daemon.log::authentication of 'moon.strongswan.org' with RSA.* successful::YES
 carol::cat /var/log/daemon.log::server requested EAP_MD5 authentication::YES
 carol::cat /var/log/daemon.log::authentication of 'moon.strongswan.org' with EAP successful::YES
 moon:: cat /var/log/daemon.log::authentication of 'carol at strongswan.org' with EAP successful::YES
diff --git a/testing/tests/ikev2/rw-eap-md5-radius/hosts/carol/etc/ipsec.conf b/testing/tests/ikev2/rw-eap-md5-radius/hosts/carol/etc/ipsec.conf
index b4825fb..c2efc3f 100644
--- a/testing/tests/ikev2/rw-eap-md5-radius/hosts/carol/etc/ipsec.conf
+++ b/testing/tests/ikev2/rw-eap-md5-radius/hosts/carol/etc/ipsec.conf
@@ -11,7 +11,6 @@ conn %default
 
 conn home
 	left=PH_IP_CAROL
-	leftnexthop=%direct
 	leftid=carol at strongswan.org
 	leftauth=eap
 	leftfirewall=yes
diff --git a/testing/tests/ikev2/rw-eap-md5-rsa/evaltest.dat b/testing/tests/ikev2/rw-eap-md5-rsa/evaltest.dat
index 84f41fd..88ab87d 100644
--- a/testing/tests/ikev2/rw-eap-md5-rsa/evaltest.dat
+++ b/testing/tests/ikev2/rw-eap-md5-rsa/evaltest.dat
@@ -1,4 +1,4 @@
-carol::cat /var/log/daemon.log::authentication of 'moon.strongswan.org' with RSA signature successful::YES
+carol::cat /var/log/daemon.log::authentication of 'moon.strongswan.org' with RSA.* successful::YES
 carol::cat /var/log/daemon.log::authentication of 'moon.strongswan.org' with EAP successful::YES
 moon:: cat /var/log/daemon.log::authentication of 'carol at strongswan.org' with EAP successful::YES
 moon:: ipsec status 2> /dev/null::rw-eap.*ESTABLISHED.*moon.strongswan.org.*carol at strongswan.org::YES
diff --git a/testing/tests/ikev2/rw-eap-md5-rsa/hosts/carol/etc/ipsec.conf b/testing/tests/ikev2/rw-eap-md5-rsa/hosts/carol/etc/ipsec.conf
index b4825fb..c2efc3f 100644
--- a/testing/tests/ikev2/rw-eap-md5-rsa/hosts/carol/etc/ipsec.conf
+++ b/testing/tests/ikev2/rw-eap-md5-rsa/hosts/carol/etc/ipsec.conf
@@ -11,7 +11,6 @@ conn %default
 
 conn home
 	left=PH_IP_CAROL
-	leftnexthop=%direct
 	leftid=carol at strongswan.org
 	leftauth=eap
 	leftfirewall=yes
diff --git a/testing/tests/ikev2/rw-eap-mschapv2-id-rsa/evaltest.dat b/testing/tests/ikev2/rw-eap-mschapv2-id-rsa/evaltest.dat
index 010f483..892fdd6 100644
--- a/testing/tests/ikev2/rw-eap-mschapv2-id-rsa/evaltest.dat
+++ b/testing/tests/ikev2/rw-eap-mschapv2-id-rsa/evaltest.dat
@@ -1,4 +1,4 @@
-carol::cat /var/log/daemon.log::authentication of .*moon.strongswan.org.* with RSA signature successful::YES
+carol::cat /var/log/daemon.log::authentication of .*moon.strongswan.org.* with RSA.* successful::YES
 carol::cat /var/log/daemon.log::server requested EAP_MSCHAPV2 authentication::YES
 carol::cat /var/log/daemon.log::authentication of .*moon.strongswan.org.* with EAP successful::YES
 moon:: cat /var/log/daemon.log::received EAP identity.*carol::YES
diff --git a/testing/tests/ikev2/rw-eap-peap-radius/evaltest.dat b/testing/tests/ikev2/rw-eap-peap-radius/evaltest.dat
index 95c29b7..d3d97dc 100644
--- a/testing/tests/ikev2/rw-eap-peap-radius/evaltest.dat
+++ b/testing/tests/ikev2/rw-eap-peap-radius/evaltest.dat
@@ -1,9 +1,9 @@
-carol::cat /var/log/daemon.log::authentication of 'moon.strongswan.org' with RSA signature successful::YES
+carol::cat /var/log/daemon.log::authentication of 'moon.strongswan.org' with RSA.* successful::YES
 carol::cat /var/log/daemon.log::server requested EAP_PEAP authentication::YES
 carol::cat /var/log/daemon.log::server requested EAP_MD5 authentication::YES
 carol::cat /var/log/daemon.log::EAP method EAP_PEAP succeeded, MSK established::YES
 carol::cat /var/log/daemon.log::authentication of 'moon.strongswan.org' with EAP successful::YES
-dave:: cat /var/log/daemon.log::authentication of 'moon.strongswan.org' with RSA signature successful::YES
+dave:: cat /var/log/daemon.log::authentication of 'moon.strongswan.org' with RSA.* successful::YES
 dave:: cat /var/log/daemon.log::server requested EAP_PEAP authentication::YES
 dave:: cat /var/log/daemon.log::server requested EAP_MD5 authentication::YES
 dave:: cat /var/log/daemon.log::received EAP_FAILURE, EAP authentication failed::YES
diff --git a/testing/tests/ikev2/rw-eap-sim-id-radius/evaltest.dat b/testing/tests/ikev2/rw-eap-sim-id-radius/evaltest.dat
index f1a68bc..0dfc89e 100644
--- a/testing/tests/ikev2/rw-eap-sim-id-radius/evaltest.dat
+++ b/testing/tests/ikev2/rw-eap-sim-id-radius/evaltest.dat
@@ -1,4 +1,4 @@
-carol::cat /var/log/daemon.log::authentication of 'moon.strongswan.org' with RSA signature successful::YES
+carol::cat /var/log/daemon.log::authentication of 'moon.strongswan.org' with RSA.* successful::YES
 moon:: cat /var/log/daemon.log::received EAP identity .*228060123456001::YES
 carol::cat /var/log/daemon.log::server requested EAP_SIM authentication::YES
 carol::cat /var/log/daemon.log::authentication of 'moon.strongswan.org' with EAP successful::YES
diff --git a/testing/tests/ikev2/rw-eap-sim-radius/evaltest.dat b/testing/tests/ikev2/rw-eap-sim-radius/evaltest.dat
index 21cfe42..a514f48 100644
--- a/testing/tests/ikev2/rw-eap-sim-radius/evaltest.dat
+++ b/testing/tests/ikev2/rw-eap-sim-radius/evaltest.dat
@@ -1,4 +1,4 @@
-carol::cat /var/log/daemon.log::authentication of 'moon.strongswan.org' with RSA signature successful::YES
+carol::cat /var/log/daemon.log::authentication of 'moon.strongswan.org' with RSA.* successful::YES
 carol::cat /var/log/daemon.log::server requested EAP_SIM authentication::YES
 carol::cat /var/log/daemon.log::authentication of 'moon.strongswan.org' with EAP successful::YES
 moon:: cat /var/log/daemon.log::authentication of 'carol at strongswan.org' with EAP successful::YES
diff --git a/testing/tests/ikev2/rw-eap-sim-rsa/evaltest.dat b/testing/tests/ikev2/rw-eap-sim-rsa/evaltest.dat
index ab27b45..f33e7bc 100644
--- a/testing/tests/ikev2/rw-eap-sim-rsa/evaltest.dat
+++ b/testing/tests/ikev2/rw-eap-sim-rsa/evaltest.dat
@@ -1,4 +1,4 @@
-carol::cat /var/log/daemon.log::authentication of 'moon.strongswan.org' with RSA signature successful::YES
+carol::cat /var/log/daemon.log::authentication of 'moon.strongswan.org' with RSA.* successful::YES
 carol::cat /var/log/daemon.log::authentication of 'moon.strongswan.org' with EAP successful::YES
 moon:: cat /var/log/daemon.log::authentication of 'carol at strongswan.org' with EAP successful::YES
 moon:: ipsec status 2> /dev/null::rw-eap-sim.*ESTABLISHED.*moon.strongswan.org.*carol at strongswan.org::YES
diff --git a/testing/tests/ikev2/rw-eap-sim-rsa/hosts/carol/etc/ipsec.conf b/testing/tests/ikev2/rw-eap-sim-rsa/hosts/carol/etc/ipsec.conf
index b4825fb..c2efc3f 100644
--- a/testing/tests/ikev2/rw-eap-sim-rsa/hosts/carol/etc/ipsec.conf
+++ b/testing/tests/ikev2/rw-eap-sim-rsa/hosts/carol/etc/ipsec.conf
@@ -11,7 +11,6 @@ conn %default
 
 conn home
 	left=PH_IP_CAROL
-	leftnexthop=%direct
 	leftid=carol at strongswan.org
 	leftauth=eap
 	leftfirewall=yes
diff --git a/testing/tests/ikev2/rw-eap-tls-radius/evaltest.dat b/testing/tests/ikev2/rw-eap-tls-radius/evaltest.dat
index 7584e14..75349b0 100644
--- a/testing/tests/ikev2/rw-eap-tls-radius/evaltest.dat
+++ b/testing/tests/ikev2/rw-eap-tls-radius/evaltest.dat
@@ -1,4 +1,4 @@
-carol::cat /var/log/daemon.log::authentication of 'C=CH, O=Linux strongSwan, CN=moon.strongswan.org' with RSA signature successful::YES
+carol::cat /var/log/daemon.log::authentication of 'C=CH, O=Linux strongSwan, CN=moon.strongswan.org' with RSA.* successful::YES
 carol::cat /var/log/daemon.log::server requested EAP_TLS authentication::YES
 carol::cat /var/log/daemon.log::authentication of 'C=CH, O=Linux strongSwan, CN=moon.strongswan.org' with EAP successful::YES
 moon:: cat /var/log/daemon.log::authentication of 'C=CH, O=Linux strongSwan, OU=Research, CN=carol at strongswan.org' with EAP successful::YES
diff --git a/testing/tests/ikev2/rw-eap-ttls-radius/evaltest.dat b/testing/tests/ikev2/rw-eap-ttls-radius/evaltest.dat
index a471a2c..f250c0c 100644
--- a/testing/tests/ikev2/rw-eap-ttls-radius/evaltest.dat
+++ b/testing/tests/ikev2/rw-eap-ttls-radius/evaltest.dat
@@ -1,9 +1,9 @@
-carol::cat /var/log/daemon.log::authentication of 'moon.strongswan.org' with RSA signature successful::YES
+carol::cat /var/log/daemon.log::authentication of 'moon.strongswan.org' with RSA.* successful::YES
 carol::cat /var/log/daemon.log::server requested EAP_TTLS authentication::YES
 carol::cat /var/log/daemon.log::server requested EAP_MD5 authentication::YES
 carol::cat /var/log/daemon.log::EAP method EAP_TTLS succeeded, MSK established::YES
 carol::cat /var/log/daemon.log::authentication of 'moon.strongswan.org' with EAP successful::YES
-dave:: cat /var/log/daemon.log::authentication of 'moon.strongswan.org' with RSA signature successful::YES
+dave:: cat /var/log/daemon.log::authentication of 'moon.strongswan.org' with RSA.* successful::YES
 dave:: cat /var/log/daemon.log::server requested EAP_TTLS authentication::YES
 dave:: cat /var/log/daemon.log::server requested EAP_MD5 authentication::YES
 dave:: cat /var/log/daemon.log::received EAP_FAILURE, EAP authentication failed::YES
diff --git a/testing/tests/ikev2/rw-mark-in-out/hosts/sun/etc/mark_updown b/testing/tests/ikev2/rw-mark-in-out/hosts/sun/etc/mark_updown
index 421335f..b8b45e3 100755
--- a/testing/tests/ikev2/rw-mark-in-out/hosts/sun/etc/mark_updown
+++ b/testing/tests/ikev2/rw-mark-in-out/hosts/sun/etc/mark_updown
@@ -1,4 +1,4 @@
-#! /bin/sh
+#!/bin/sh
 # updown script setting inbound marks on ESP traffic in the mangle chain
 #
 # Copyright (C) 2003-2004 Nigel Meteringham
@@ -22,8 +22,6 @@
 # that, and use the (left/right)updown parameters in ipsec.conf to make
 # strongSwan use yours instead of this default one.
 
-# things that this script gets (from ipsec_pluto(8) man page)
-#
 #      PLUTO_VERSION
 #              indicates  what  version of this interface is being
 #              used.  This document describes version  1.1.   This
@@ -41,15 +39,20 @@
 #              is the name of the  connection  for  which  we  are
 #              routing.
 #
-#       PLUTO_NEXT_HOP
-#              is the next hop to which packets bound for the peer
-#              must be sent.
-#
 #       PLUTO_INTERFACE
 #              is the name of the ipsec interface to be used.
 #
 #       PLUTO_REQID
-#              is the requid of the ESP policy
+#              is the requid of the AH|ESP policy
+#
+#       PLUTO_PROTO
+#              is the negotiated IPsec protocol, ah|esp
+#
+#       PLUTO_IPCOMP
+#              is not empty if IPComp was negotiated
+#
+#       PLUTO_UNIQUEID
+#              is the unique identifier of the associated IKE_SA
 #
 #       PLUTO_ME
 #              is the IP address of our host.
@@ -63,15 +66,6 @@
 #              host's own IP address / max (where max  is  32  for
 #              IPv4 and 128 for IPv6).
 #
-#       PLUTO_MY_CLIENT_NET
-#              is the IP address of our client net.  If the client
-#              is just the host, this will be the  host's  own  IP
-#              address.
-#
-#       PLUTO_MY_CLIENT_MASK
-#              is  the  mask for our client net.  If the client is
-#              just the host, this will be 255.255.255.255.
-#
 #       PLUTO_MY_SOURCEIP
 #       PLUTO_MY_SOURCEIP4_$i
 #       PLUTO_MY_SOURCEIP6_$i
@@ -85,7 +79,8 @@
 #
 #       PLUTO_MY_PORT
 #              is  the  UDP/TCP  port  to  which  the IPsec SA  is
-#              restricted on our side.
+#              restricted on our side.  For ICMP/ICMPv6 this contains the
+#              message type, and PLUTO_PEER_PORT the message code.
 #
 #       PLUTO_PEER
 #              is the IP address of our peer.
@@ -93,31 +88,19 @@
 #       PLUTO_PEER_ID
 #              is the ID of our peer.
 #
-#       PLUTO_PEER_CA
-#              is the CA which issued the cert of our peer.
-#
 #       PLUTO_PEER_CLIENT
 #              is the IP address / count of the peer's client sub-
 #              net.   If the client is just the peer, this will be
 #              the peer's own IP address / max (where  max  is  32
 #              for IPv4 and 128 for IPv6).
 #
-#       PLUTO_PEER_CLIENT_NET
-#              is the IP address of the peer's client net.  If the
-#              client is just the peer, this will  be  the  peer's
-#              own IP address.
-#
-#       PLUTO_PEER_CLIENT_MASK
-#              is  the  mask  for  the  peer's client net.  If the
-#              client   is   just   the   peer,   this   will   be
-#              255.255.255.255.
-#
 #       PLUTO_PEER_PROTOCOL
 #              is the IP protocol that will be transported.
 #
 #       PLUTO_PEER_PORT
 #              is  the  UDP/TCP  port  to  which  the IPsec SA  is
-#              restricted on the peer side.
+#              restricted on the peer side.  For ICMP/ICMPv6 this contains the
+#              message code, and PLUTO_MY_PORT the message type.
 #
 #       PLUTO_XAUTH_ID
 #              is an optional user ID employed by the XAUTH protocol
@@ -143,7 +126,7 @@
 PATH="/sbin:/bin:/usr/sbin:/usr/bin:/usr/sbin:/usr/local/sbin"
 export PATH
 
-# uncomment to log VPN connections
+# comment to disable logging VPN connections to syslog
 VPN_LOGGING=1
 #
 # tag put in front of each log entry:
@@ -157,21 +140,11 @@ FAC_PRIO=local0.notice
 #
 # local0.notice                   -/var/log/vpn
 
-# in order to use source IP routing the Linux kernel options
-# CONFIG_IP_ADVANCED_ROUTER and CONFIG_IP_MULTIPLE_TABLES
-# must be enabled
-#
-# special routing table for sourceip routes
-SOURCEIP_ROUTING_TABLE=220
-#
-# priority of the sourceip routing table
-SOURCEIP_ROUTING_TABLE_PRIO=220
-
 # check interface version
 case "$PLUTO_VERSION" in
-1.[0|1])	# Older Pluto?!?  Play it safe, script may be using new features.
+1.[0|1])	# Older release?!?  Play it safe, script may be using new features.
 	echo "$0: obsolete interface version \`$PLUTO_VERSION'," >&2
-	echo "$0: 	called by obsolete Pluto?" >&2
+	echo "$0: 	called by obsolete release?" >&2
 	exit 2
 	;;
 1.*)	;;
@@ -193,119 +166,45 @@ custom:*)		# custom parameters (see above CAUTION comment)
 	;;
 esac
 
-# utility functions for route manipulation
-# Meddling with this stuff should not be necessary and requires great care.
-uproute() {
-	doroute add
-	ip route flush cache
-}
-downroute() {
-	doroute delete
-	ip route flush cache
-}
-
-addsource() {
-	st=0
-	if ! ip -o route get ${PLUTO_MY_SOURCEIP%/*} | grep -q ^local
-	then
-	    it="ip addr add ${PLUTO_MY_SOURCEIP%/*}/32 dev $PLUTO_INTERFACE"
-	    oops="`eval $it 2>&1`"
-	    st=$?
-	    if test " $oops" = " " -a " $st" != " 0"
-	    then
-		oops="silent error, exit status $st"
-	    fi
-	    if test " $oops" != " " -o " $st" != " 0"
-	    then
-		echo "$0: addsource \`$it' failed ($oops)" >&2
-	    fi
-	fi
-	return $st
-}
-
-doroute() {
-	st=0
-
-	if [ -z "$PLUTO_MY_SOURCEIP" ]
-	then
-	    for dir in /etc/sysconfig /etc/conf.d; do
-		if [ -f "$dir/defaultsource" ]
-		then
-		    . "$dir/defaultsource"
-		fi
-	    done
-
-	    if [ -n "$DEFAULTSOURCE" ]
-	    then
-		PLUTO_MY_SOURCEIP=$DEFAULTSOURCE
-	    fi
-        fi
-
-	if [ -z "$KLIPS" -a -z "$PLUTO_MY_SOURCEIP" ]
-	then
-	    # leave because no route entry is required
-	    return $st
-	fi
+IPSEC_POLICY="-m policy --pol ipsec --proto $PLUTO_PROTO --reqid $PLUTO_REQID"
+IPSEC_POLICY_IN="$IPSEC_POLICY --dir in"
+IPSEC_POLICY_OUT="$IPSEC_POLICY --dir out"
 
-	parms1="$PLUTO_PEER_CLIENT"
+# use protocol specific options to set ports
+case "$PLUTO_MY_PROTOCOL" in
+1)	# ICMP
+	ICMP_TYPE_OPTION="--icmp-type"
+	;;
+58)	# ICMPv6
+	ICMP_TYPE_OPTION="--icmpv6-type"
+	;;
+*)
+	;;
+esac
 
-	if [ -n "$PLUTO_NEXT_HOP" ]
+# are there port numbers?
+if [ "$PLUTO_MY_PORT" != 0 ]
+then
+	if [ -n "$ICMP_TYPE_OPTION" ]
 	then
-	    parms2="via $PLUTO_NEXT_HOP"
+		S_MY_PORT="$ICMP_TYPE_OPTION $PLUTO_MY_PORT"
+		D_MY_PORT="$ICMP_TYPE_OPTION $PLUTO_MY_PORT"
 	else
-	    parms2="via $PLUTO_PEER"
-	fi
-	parms2="$parms2 dev $PLUTO_INTERFACE"
-
-	parms3=
-	if [ -n "$PLUTO_MY_SOURCEIP" ]
-	then
-	    if test "$1" = "add"
-	    then
-		addsource
-		if ! ip rule list | grep -q "lookup $SOURCEIP_ROUTING_TABLE"
-		then
-		    ip rule add pref $SOURCEIP_ROUTING_TABLE_PRIO table $SOURCEIP_ROUTING_TABLE
-		fi
-	    fi
-	    parms3="$parms3 src ${PLUTO_MY_SOURCEIP%/*} table $SOURCEIP_ROUTING_TABLE"
-	fi
-
-	case "$PLUTO_PEER_CLIENT_NET/$PLUTO_PEER_CLIENT_MASK" in
-	"0.0.0.0/0.0.0.0")
-		# opportunistic encryption work around
-		# need to provide route that eclipses default, without
-		# replacing it.
-		it="ip route $1 0.0.0.0/1 $parms2 $parms3 &&
-			ip route $1 128.0.0.0/1 $parms2 $parms3"
-		;;
-	*)	it="ip route $1 $parms1 $parms2 $parms3"
-		;;
-	esac
-	oops="`eval $it 2>&1`"
-	st=$?
-	if test " $oops" = " " -a " $st" != " 0"
-	then
-	    oops="silent error, exit status $st"
+		S_MY_PORT="--sport $PLUTO_MY_PORT"
+		D_MY_PORT="--dport $PLUTO_MY_PORT"
 	fi
-	if test " $oops" != " " -o " $st" != " 0"
+fi
+if [ "$PLUTO_PEER_PORT" != 0 ]
+then
+	if [ -n "$ICMP_TYPE_OPTION" ]
 	then
-	    echo "$0: doroute \`$it' failed ($oops)" >&2
+		# the syntax is --icmp[v6]-type type[/code], so add it to the existing option
+		S_MY_PORT="$S_MY_PORT/$PLUTO_PEER_PORT"
+		D_MY_PORT="$D_MY_PORT/$PLUTO_PEER_PORT"
+	else
+		S_PEER_PORT="--sport $PLUTO_PEER_PORT"
+		D_PEER_PORT="--dport $PLUTO_PEER_PORT"
 	fi
-	return $st
-}
-
-# in the presence of KLIPS and ipsecN interfaces do not use IPSEC_POLICY
-if [ `echo "$PLUTO_INTERFACE" | grep "ipsec"` ]
-then
-	KLIPS=1
-	IPSEC_POLICY_IN=""
-	IPSEC_POLICY_OUT=""
-else
-	KLIPS=
-	IPSEC_POLICY="-m policy --pol ipsec --proto esp --reqid $PLUTO_REQID"
-	IPSEC_POLICY_IN="$IPSEC_POLICY --dir in"
-	IPSEC_POLICY_OUT="$IPSEC_POLICY --dir out"
 fi
 
 # is there an inbound mark to be set?
@@ -320,75 +219,11 @@ then
 	SET_MARK="$SET_MARK -s $PLUTO_PEER -j MARK --set-mark $PLUTO_MARK_IN"
 fi
 
-# are there port numbers?
-if [ "$PLUTO_MY_PORT" != 0 ]
-then
-	S_MY_PORT="--sport $PLUTO_MY_PORT"
-	D_MY_PORT="--dport $PLUTO_MY_PORT"
-fi
-if [ "$PLUTO_PEER_PORT" != 0 ]
-then
-	S_PEER_PORT="--sport $PLUTO_PEER_PORT"
-	D_PEER_PORT="--dport $PLUTO_PEER_PORT"
-fi
-
 # resolve octal escape sequences
 PLUTO_MY_ID=`printf "$PLUTO_MY_ID"`
 PLUTO_PEER_ID=`printf "$PLUTO_PEER_ID"`
 
-# the big choice
 case "$PLUTO_VERB:$1" in
-prepare-host:*|prepare-client:*)
-	if [ -z "$KLIPS" -a -z "$PLUTO_MY_SOURCEIP" ]
-	then
-	    # exit because no route will be added,
-	    # so that existing routes can stay
-	    exit 0
-	fi
-
-	# delete possibly-existing route (preliminary to adding a route)
-	case "$PLUTO_PEER_CLIENT_NET/$PLUTO_PEER_CLIENT_MASK" in
-	"0.0.0.0/0.0.0.0")
-		# need to provide route that eclipses default, without
-		# replacing it.
-		parms1="0.0.0.0/1"
-		parms2="128.0.0.0/1"
-		it="ip route delete $parms1 2>&1 ; ip route delete $parms2 2>&1"
-		oops="`ip route delete $parms1 2>&1 ; ip route delete $parms2 2>&1`"
-		;;
-	*)
-		parms="$PLUTO_PEER_CLIENT"
-		it="ip route delete $parms 2>&1"
-		oops="`ip route delete $parms 2>&1`"
-		;;
-	esac
-	status="$?"
-	if test " $oops" = " " -a " $status" != " 0"
-	then
-		oops="silent error, exit status $status"
-	fi
-	case "$oops" in
-	*'RTNETLINK answers: No such process'*)
-		# This is what route (currently -- not documented!) gives
-		# for "could not find such a route".
-		oops=
-		status=0
-		;;
-	esac
-	if test " $oops" != " " -o " $status" != " 0"
-	then
-		echo "$0: \`$it' failed ($oops)" >&2
-	fi
-	exit $status
-	;;
-route-host:*|route-client:*)
-	# connection to me or my client subnet being routed
-	uproute
-	;;
-unroute-host:*|unroute-client:*)
-	# connection to me or my client subnet being unrouted
-	downroute
-	;;
 up-host:)
 	# connection to me coming up
 	# If you are doing a custom version, firewall commands go here.
@@ -403,6 +238,14 @@ up-host:)
 	    -s $PLUTO_ME $S_MY_PORT $IPSEC_POLICY_OUT \
 	    -d $PLUTO_PEER_CLIENT $D_PEER_PORT -j ACCEPT
 	#
+	# allow IPIP traffic because of the implicit SA created by the kernel if
+	# IPComp is used (for small inbound packets that are not compressed)
+	if [ -n "$PLUTO_IPCOMP" ]
+	then
+	  iptables -I INPUT 1 -i $PLUTO_INTERFACE -p 4 \
+	      -s $PLUTO_PEER -d $PLUTO_ME $IPSEC_POLICY_IN -j ACCEPT
+	fi
+	#
 	# log IPsec host connection setup
 	if [ $VPN_LOGGING ]
 	then
@@ -430,6 +273,13 @@ down-host:)
 	    -s $PLUTO_ME $S_MY_PORT $IPSEC_POLICY_OUT \
 	    -d $PLUTO_PEER_CLIENT $D_PEER_PORT -j ACCEPT
 	#
+	# IPIP exception teardown
+	if [ -n "$PLUTO_IPCOMP" ]
+	then
+	  iptables -D INPUT -i $PLUTO_INTERFACE -p 4 \
+	      -s $PLUTO_PEER -d $PLUTO_ME $IPSEC_POLICY_IN -j ACCEPT
+	fi
+	#
 	# log IPsec host connection teardown
 	if [ $VPN_LOGGING ]
 	then
@@ -472,6 +322,15 @@ up-client:)
 	      -d $PLUTO_PEER_CLIENT $D_PEER_PORT $IPSEC_POLICY_OUT -j ACCEPT
 	fi
 	#
+	# allow IPIP traffic because of the implicit SA created by the kernel if
+	# IPComp is used (for small inbound packets that are not compressed).
+	# INPUT is correct here even for forwarded traffic.
+	if [ -n "$PLUTO_IPCOMP" ]
+	then
+	  iptables -I INPUT 1 -i $PLUTO_INTERFACE -p 4 \
+	      -s $PLUTO_PEER -d $PLUTO_ME $IPSEC_POLICY_IN -j ACCEPT
+	fi
+	#
 	# log IPsec client connection setup
 	if [ $VPN_LOGGING ]
 	then
@@ -518,6 +377,13 @@ down-client:)
 	         $IPSEC_POLICY_OUT -j ACCEPT
 	fi
 	#
+	# IPIP exception teardown
+	if [ -n "$PLUTO_IPCOMP" ]
+	then
+	  iptables -D INPUT -i $PLUTO_INTERFACE -p 4 \
+	      -s $PLUTO_PEER -d $PLUTO_ME $IPSEC_POLICY_IN -j ACCEPT
+	fi
+	#
 	# log IPsec client connection teardown
 	if [ $VPN_LOGGING ]
 	then
diff --git a/testing/tests/ikev2/rw-ntru-bliss/description.txt b/testing/tests/ikev2/rw-ntru-bliss/description.txt
new file mode 100644
index 0000000..b81fdb7
--- /dev/null
+++ b/testing/tests/ikev2/rw-ntru-bliss/description.txt
@@ -0,0 +1,15 @@
+The roadwarriors <b>carol</b> and <b>dave</b> set up a connection each to gateway <b>moon</b>.
+The key exchange is based on NTRU encryption with a cryptographical strength of 128 bit and
+192 bit for <b>carol</b> and <b>dave</b>, respectively. Authentication is based on the BLISS
+algorithm with strengths 128 bits (BLISS I), 160 bits (BLISS III) and 192 bits (BLISS IV) for
+<b>carol</b>, <b>dave</b> and <b>moon</b>, respectively.
+<p>
+Both <b>carol</b> and <b>dave</b> request a <b>virtual IP</b> via the IKEv2 configuration payload
+by using the <b>leftsourceip=%config</b> parameter. The gateway <b>moon</b> assigns virtual
+IP addresses from a simple pool defined by <b>rightsourceip=10.3.0.0/28</b> in a monotonously
+increasing order. 
+<p>
+<b>leftfirewall=yes</b> automatically inserts iptables-based firewall rules that let pass
+the tunneled traffic. In order to test the tunnels, <b>carol</b> and <b>dave</b> then ping
+the client <b>alice</b> behind the gateway <b>moon</b>. The source IP addresses of the two
+pings will be the virtual IPs <b>carol1</b> and <b>dave1</b>, respectively.
diff --git a/testing/tests/ikev2/rw-ntru-bliss/evaltest.dat b/testing/tests/ikev2/rw-ntru-bliss/evaltest.dat
new file mode 100644
index 0000000..5a88b66
--- /dev/null
+++ b/testing/tests/ikev2/rw-ntru-bliss/evaltest.dat
@@ -0,0 +1,26 @@
+carol::cat /var/log/daemon.log::authentication of.*moon.strongswan.org.*with BLISS_WITH_SHA512 successful::YES
+carol::ipsec statusall 2> /dev/null::home.*IKE proposal: AES_CBC_128/HMAC_SHA2_256_128/PRF_HMAC_SHA2_256/NTRU_128::YES
+carol::ipsec status 2> /dev/null::home.*ESTABLISHED.*carol at strongswan.org.*moon.strongswan.org::YES
+carol::ipsec status 2> /dev/null::home.*INSTALLED, TUNNEL::YES
+carol::ping -c 1 PH_IP_ALICE::64 bytes from PH_IP_ALICE: icmp_req=1::YES
+dave::cat /var/log/daemon.log::authentication of.*moon.strongswan.org.*with BLISS_WITH_SHA512 successful::YES
+dave:: ipsec statusall 2> /dev/null::home.*IKE proposal: AES_CBC_192/HMAC_SHA2_384_192/PRF_HMAC_SHA2_384/NTRU_192::YES
+dave:: ipsec status 2> /dev/null::home.*ESTABLISHED.*dave at strongswan.org.*moon.strongswan.org::YES
+dave:: ipsec status 2> /dev/null::home.*INSTALLED, TUNNEL::YES
+dave:: ping -c 1 PH_IP_ALICE::64 bytes from PH_IP_ALICE: icmp_req=1::YES
+moon:: cat /var/log/daemon.log::authentication of.*carol at strongswan.org.*with BLISS_WITH_SHA256 successful::YES
+moon:: cat /var/log/daemon.log::authentication of.*dave at strongswan.org.*with BLISS_WITH_SHA384 successful::YES
+moon:: ipsec statusall 2> /dev/null::rw\[1]: IKE proposal: AES_CBC_128/HMAC_SHA2_256_128/PRF_HMAC_SHA2_256/NTRU_128::YES
+moon:: ipsec statusall 2> /dev/null::rw\[2]: IKE proposal: AES_CBC_192/HMAC_SHA2_384_192/PRF_HMAC_SHA2_384/NTRU_192::YES
+moon:: ipsec status 2> /dev/null::rw\[1]: ESTABLISHED.*moon.strongswan.org.*carol at strongswan.org::YES
+moon:: ipsec status 2> /dev/null::rw\[2]: ESTABLISHED.*moon.strongswan.org.*dave at strongswan.org::YES
+moon:: ipsec status 2> /dev/null::rw[{]1}.*INSTALLED, TUNNEL::ESP
+moon:: ipsec status 2> /dev/null::rw[{]2}.*INSTALLED, TUNNEL::ESP
+moon::tcpdump::IP carol.strongswan.org > moon.strongswan.org: ESP::YES
+moon::tcpdump::IP moon.strongswan.org > carol.strongswan.org: ESP::YES
+moon::tcpdump::IP dave.strongswan.org > moon.strongswan.org: ESP::YES
+moon::tcpdump::IP moon.strongswan.org > dave.strongswan.org: ESP::YES
+alice::tcpdump::IP carol1.strongswan.org > alice.strongswan.org: ICMP echo request::YES
+alice::tcpdump::IP alice.strongswan.org > carol1.strongswan.org: ICMP echo reply::YES
+alice::tcpdump::IP dave1.strongswan.org > alice.strongswan.org: ICMP echo request::YES
+alice::tcpdump::IP alice.strongswan.org > dave1.strongswan.org: ICMP echo reply::YES
diff --git a/testing/tests/ikev2/rw-ntru-bliss/hosts/carol/etc/ipsec.conf b/testing/tests/ikev2/rw-ntru-bliss/hosts/carol/etc/ipsec.conf
new file mode 100644
index 0000000..f13e47a
--- /dev/null
+++ b/testing/tests/ikev2/rw-ntru-bliss/hosts/carol/etc/ipsec.conf
@@ -0,0 +1,25 @@
+# /etc/ipsec.conf - strongSwan IPsec configuration file
+
+config setup
+
+conn %default
+	ikelifetime=60m
+	keylife=20m
+	rekeymargin=3m
+	keyingtries=1
+	keyexchange=ikev2
+	ike=aes128-sha256-ntru128!
+	esp=aes128-sha256!
+	authby=pubkey
+	fragmentation=yes
+
+conn home
+	left=PH_IP_CAROL
+	leftsourceip=%config
+	leftcert=carolCert.der
+	leftid=carol at strongswan.org
+	leftfirewall=yes
+	right=PH_IP_MOON
+	rightsubnet=10.1.0.0/16
+	rightid=moon.strongswan.org
+	auto=add
diff --git a/testing/tests/ikev2/rw-ntru-bliss/hosts/carol/etc/ipsec.d/cacerts/strongswan_blissCert.der b/testing/tests/ikev2/rw-ntru-bliss/hosts/carol/etc/ipsec.d/cacerts/strongswan_blissCert.der
new file mode 100644
index 0000000..cbc7e09
Binary files /dev/null and b/testing/tests/ikev2/rw-ntru-bliss/hosts/carol/etc/ipsec.d/cacerts/strongswan_blissCert.der differ
diff --git a/testing/tests/ikev2/rw-ntru-bliss/hosts/carol/etc/ipsec.d/certs/carolCert.der b/testing/tests/ikev2/rw-ntru-bliss/hosts/carol/etc/ipsec.d/certs/carolCert.der
new file mode 100644
index 0000000..491e245
Binary files /dev/null and b/testing/tests/ikev2/rw-ntru-bliss/hosts/carol/etc/ipsec.d/certs/carolCert.der differ
diff --git a/testing/tests/ikev2/rw-ntru-bliss/hosts/carol/etc/ipsec.d/private/carolKey.der b/testing/tests/ikev2/rw-ntru-bliss/hosts/carol/etc/ipsec.d/private/carolKey.der
new file mode 100644
index 0000000..b2831a8
Binary files /dev/null and b/testing/tests/ikev2/rw-ntru-bliss/hosts/carol/etc/ipsec.d/private/carolKey.der differ
diff --git a/testing/tests/ikev2/rw-ntru-bliss/hosts/carol/etc/ipsec.secrets b/testing/tests/ikev2/rw-ntru-bliss/hosts/carol/etc/ipsec.secrets
new file mode 100644
index 0000000..c222564
--- /dev/null
+++ b/testing/tests/ikev2/rw-ntru-bliss/hosts/carol/etc/ipsec.secrets
@@ -0,0 +1,3 @@
+# /etc/ipsec.secrets - strongSwan IPsec secrets file
+
+: BLISS carolKey.der
diff --git a/testing/tests/ikev2/rw-ntru-bliss/hosts/carol/etc/strongswan.conf b/testing/tests/ikev2/rw-ntru-bliss/hosts/carol/etc/strongswan.conf
new file mode 100644
index 0000000..ab824c9
--- /dev/null
+++ b/testing/tests/ikev2/rw-ntru-bliss/hosts/carol/etc/strongswan.conf
@@ -0,0 +1,7 @@
+# /etc/strongswan.conf - strongSwan configuration file
+
+charon {
+  load = aes sha1 sha2 random nonce ntru bliss x509 revocation pem pkcs1 curl hmac stroke kernel-netlink socket-default updown
+  send_vendor_id = yes
+  fragment_size = 1500
+}
diff --git a/testing/tests/ikev2/rw-ntru-bliss/hosts/dave/etc/ipsec.conf b/testing/tests/ikev2/rw-ntru-bliss/hosts/dave/etc/ipsec.conf
new file mode 100644
index 0000000..5f605a4
--- /dev/null
+++ b/testing/tests/ikev2/rw-ntru-bliss/hosts/dave/etc/ipsec.conf
@@ -0,0 +1,25 @@
+# /etc/ipsec.conf - strongSwan IPsec configuration file
+
+config setup
+
+conn %default
+	ikelifetime=60m
+	keylife=20m
+	rekeymargin=3m
+	keyingtries=1
+	keyexchange=ikev2
+	ike=aes192-sha384-ntru192!
+	esp=aes192-sha384!
+	authby=pubkey
+	fragmentation=yes
+
+conn home
+	left=PH_IP_DAVE
+	leftsourceip=%config
+	leftcert=daveCert.der
+	leftid=dave at strongswan.org
+	leftfirewall=yes
+	right=PH_IP_MOON
+	rightsubnet=10.1.0.0/16
+	rightid=moon.strongswan.org
+	auto=add
diff --git a/testing/tests/ikev2/rw-ntru-bliss/hosts/dave/etc/ipsec.d/cacerts/strongswan_blissCert.der b/testing/tests/ikev2/rw-ntru-bliss/hosts/dave/etc/ipsec.d/cacerts/strongswan_blissCert.der
new file mode 100644
index 0000000..cbc7e09
Binary files /dev/null and b/testing/tests/ikev2/rw-ntru-bliss/hosts/dave/etc/ipsec.d/cacerts/strongswan_blissCert.der differ
diff --git a/testing/tests/ikev2/rw-ntru-bliss/hosts/dave/etc/ipsec.d/certs/daveCert.der b/testing/tests/ikev2/rw-ntru-bliss/hosts/dave/etc/ipsec.d/certs/daveCert.der
new file mode 100644
index 0000000..83a2137
Binary files /dev/null and b/testing/tests/ikev2/rw-ntru-bliss/hosts/dave/etc/ipsec.d/certs/daveCert.der differ
diff --git a/testing/tests/ikev2/rw-ntru-bliss/hosts/dave/etc/ipsec.d/private/daveKey.der b/testing/tests/ikev2/rw-ntru-bliss/hosts/dave/etc/ipsec.d/private/daveKey.der
new file mode 100644
index 0000000..0ec528d
Binary files /dev/null and b/testing/tests/ikev2/rw-ntru-bliss/hosts/dave/etc/ipsec.d/private/daveKey.der differ
diff --git a/testing/tests/ikev2/rw-ntru-bliss/hosts/dave/etc/ipsec.secrets b/testing/tests/ikev2/rw-ntru-bliss/hosts/dave/etc/ipsec.secrets
new file mode 100644
index 0000000..fe26432
--- /dev/null
+++ b/testing/tests/ikev2/rw-ntru-bliss/hosts/dave/etc/ipsec.secrets
@@ -0,0 +1,3 @@
+# /etc/ipsec.secrets - strongSwan IPsec secrets file
+
+: BLISS daveKey.der
diff --git a/testing/tests/ikev2/rw-ntru-bliss/hosts/dave/etc/strongswan.conf b/testing/tests/ikev2/rw-ntru-bliss/hosts/dave/etc/strongswan.conf
new file mode 100644
index 0000000..ab824c9
--- /dev/null
+++ b/testing/tests/ikev2/rw-ntru-bliss/hosts/dave/etc/strongswan.conf
@@ -0,0 +1,7 @@
+# /etc/strongswan.conf - strongSwan configuration file
+
+charon {
+  load = aes sha1 sha2 random nonce ntru bliss x509 revocation pem pkcs1 curl hmac stroke kernel-netlink socket-default updown
+  send_vendor_id = yes
+  fragment_size = 1500
+}
diff --git a/testing/tests/ikev2/rw-ntru-bliss/hosts/moon/etc/ipsec.conf b/testing/tests/ikev2/rw-ntru-bliss/hosts/moon/etc/ipsec.conf
new file mode 100644
index 0000000..2a9b33a
--- /dev/null
+++ b/testing/tests/ikev2/rw-ntru-bliss/hosts/moon/etc/ipsec.conf
@@ -0,0 +1,25 @@
+# /etc/ipsec.conf - strongSwan IPsec configuration file
+
+config setup
+
+conn %default
+	ikelifetime=60m
+	keylife=20m
+	rekeymargin=3m
+	keyingtries=1
+	keyexchange=ikev2
+	ike=aes128-sha256-ntru128,aes192-sha384-ntru192!
+	esp=aes128-sha256,aes192-sha384!
+	authby=pubkey
+	fragmentation=yes
+
+conn rw
+	left=PH_IP_MOON
+	leftsubnet=10.1.0.0/16
+	leftcert=moonCert.der
+	leftauth=bliss-sha512
+	leftid=moon.strongswan.org
+	leftfirewall=yes
+	right=%any
+	rightsourceip=10.3.0.0/28
+	auto=add
diff --git a/testing/tests/ikev2/rw-ntru-bliss/hosts/moon/etc/ipsec.d/cacerts/strongswan_blissCert.der b/testing/tests/ikev2/rw-ntru-bliss/hosts/moon/etc/ipsec.d/cacerts/strongswan_blissCert.der
new file mode 100644
index 0000000..cbc7e09
Binary files /dev/null and b/testing/tests/ikev2/rw-ntru-bliss/hosts/moon/etc/ipsec.d/cacerts/strongswan_blissCert.der differ
diff --git a/testing/tests/ikev2/rw-ntru-bliss/hosts/moon/etc/ipsec.d/certs/moonCert.der b/testing/tests/ikev2/rw-ntru-bliss/hosts/moon/etc/ipsec.d/certs/moonCert.der
new file mode 100644
index 0000000..1ab7d21
Binary files /dev/null and b/testing/tests/ikev2/rw-ntru-bliss/hosts/moon/etc/ipsec.d/certs/moonCert.der differ
diff --git a/testing/tests/ikev2/rw-ntru-bliss/hosts/moon/etc/ipsec.d/private/moonKey.der b/testing/tests/ikev2/rw-ntru-bliss/hosts/moon/etc/ipsec.d/private/moonKey.der
new file mode 100644
index 0000000..c989f91
Binary files /dev/null and b/testing/tests/ikev2/rw-ntru-bliss/hosts/moon/etc/ipsec.d/private/moonKey.der differ
diff --git a/testing/tests/ikev2/rw-ntru-bliss/hosts/moon/etc/ipsec.secrets b/testing/tests/ikev2/rw-ntru-bliss/hosts/moon/etc/ipsec.secrets
new file mode 100644
index 0000000..b4a9ee6
--- /dev/null
+++ b/testing/tests/ikev2/rw-ntru-bliss/hosts/moon/etc/ipsec.secrets
@@ -0,0 +1,3 @@
+# /etc/ipsec.secrets - strongSwan IPsec secrets file
+
+: BLISS moonKey.der
diff --git a/testing/tests/ikev2/rw-ntru-bliss/hosts/moon/etc/strongswan.conf b/testing/tests/ikev2/rw-ntru-bliss/hosts/moon/etc/strongswan.conf
new file mode 100644
index 0000000..ab824c9
--- /dev/null
+++ b/testing/tests/ikev2/rw-ntru-bliss/hosts/moon/etc/strongswan.conf
@@ -0,0 +1,7 @@
+# /etc/strongswan.conf - strongSwan configuration file
+
+charon {
+  load = aes sha1 sha2 random nonce ntru bliss x509 revocation pem pkcs1 curl hmac stroke kernel-netlink socket-default updown
+  send_vendor_id = yes
+  fragment_size = 1500
+}
diff --git a/testing/tests/ikev2/rw-ntru-bliss/posttest.dat b/testing/tests/ikev2/rw-ntru-bliss/posttest.dat
new file mode 100644
index 0000000..9ba8c5f
--- /dev/null
+++ b/testing/tests/ikev2/rw-ntru-bliss/posttest.dat
@@ -0,0 +1,9 @@
+carol::ipsec stop
+dave::ipsec stop
+moon::ipsec stop
+moon::iptables-restore < /etc/iptables.flush
+carol::iptables-restore < /etc/iptables.flush
+dave::iptables-restore < /etc/iptables.flush
+moon::rm /etc/ipsec.d/cacerts/strongswan_blissCert.der
+carol::rm /etc/ipsec.d/cacerts/strongswan_blissCert.der
+dave::rm /etc/ipsec.d/cacerts/strongswan_blissCert.der
diff --git a/testing/tests/ikev2/rw-ntru-bliss/pretest.dat b/testing/tests/ikev2/rw-ntru-bliss/pretest.dat
new file mode 100644
index 0000000..2424943
--- /dev/null
+++ b/testing/tests/ikev2/rw-ntru-bliss/pretest.dat
@@ -0,0 +1,13 @@
+moon::iptables-restore < /etc/iptables.rules
+carol::iptables-restore < /etc/iptables.rules
+dave::iptables-restore < /etc/iptables.rules
+moon::rm /etc/ipsec.d/cacerts/strongswanCert.pem
+carol::rm /etc/ipsec.d/cacerts/strongswanCert.pem
+dave::rm /etc/ipsec.d/cacerts/strongswanCert.pem
+carol::ipsec start
+dave::ipsec start
+moon::ipsec start
+carol::sleep 2 
+carol::ipsec up home
+dave::ipsec up home
+carol::sleep 1
diff --git a/testing/tests/ikev2/rw-ntru-bliss/test.conf b/testing/tests/ikev2/rw-ntru-bliss/test.conf
new file mode 100644
index 0000000..164b07f
--- /dev/null
+++ b/testing/tests/ikev2/rw-ntru-bliss/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 carol winnetou dave"
+
+# Corresponding block diagram
+#
+DIAGRAM="a-m-c-w-d.png"
+
+# Guest instances on which tcpdump is to be started
+#
+TCPDUMPHOSTS="moon alice"
+
+# Guest instances on which IPsec is started
+# Used for IPsec logging purposes
+#
+IPSECHOSTS="moon carol dave"
diff --git a/testing/tests/ikev2/rw-psk-rsa-mixed/evaltest.dat b/testing/tests/ikev2/rw-psk-rsa-mixed/evaltest.dat
index ab398a3..55b2957 100644
--- a/testing/tests/ikev2/rw-psk-rsa-mixed/evaltest.dat
+++ b/testing/tests/ikev2/rw-psk-rsa-mixed/evaltest.dat
@@ -2,8 +2,8 @@ moon:: cat /var/log/daemon.log::authentication of 'carol at strongswan.org' with pr
 moon:: cat /var/log/daemon.log::authentication of 'PH_IP_MOON' (myself) with pre-shared key::YES
 moon:: ipsec status 2> /dev/null::rw-psk.*INSTALLED, TUNNEL::YES
 carol::ipsec status 2> /dev/null::home.*ESTABLISHED.*carol at strongswan.org.*\[PH_IP_MOON]::YES
-moon:: cat /var/log/daemon.log::authentication of 'dave at strongswan.org' with RSA signature successful::YES
-moon:: cat /var/log/daemon.log::authentication of 'moon.strongswan.org' (myself) with RSA signature successful::YES
+moon:: cat /var/log/daemon.log::authentication of 'dave at strongswan.org' with RSA.* successful::YES
+moon:: cat /var/log/daemon.log::authentication of 'moon.strongswan.org' (myself) with RSA.* successful::YES
 moon:: ipsec status 2> /dev/null::rw-rsasig.*INSTALLED, TUNNEL::YES
 dave:: ipsec status 2> /dev/null::home.*ESTABLISHED.*dave at strongswan.org.*moon.strongswan.org::YES
 carol::ping -c 1 PH_IP_ALICE::64 bytes from PH_IP_ALICE: icmp_req=1::YES
diff --git a/testing/tests/ikev2/rw-psk-rsa-split/evaltest.dat b/testing/tests/ikev2/rw-psk-rsa-split/evaltest.dat
index 1648c95..1206ea4 100644
--- a/testing/tests/ikev2/rw-psk-rsa-split/evaltest.dat
+++ b/testing/tests/ikev2/rw-psk-rsa-split/evaltest.dat
@@ -1,6 +1,6 @@
 moon:: cat /var/log/daemon.log::authentication of 'carol at strongswan.org' with pre-shared key successful::YES
 moon:: cat /var/log/daemon.log::authentication of 'dave at strongswan.org' with pre-shared key successful::YES
-moon:: cat /var/log/daemon.log::authentication of 'moon.strongswan.org' (myself) with RSA signature successful::YES
+moon:: cat /var/log/daemon.log::authentication of 'moon.strongswan.org' (myself) with RSA.* successful::YES
 carol::ipsec status 2> /dev/null::home.*ESTABLISHED.*carol at strongswan.org.*moon.strongswan.org::YES
 dave:: ipsec status 2> /dev/null::home.*ESTABLISHED.*dave at strongswan.org.*moon.strongswan.org::YES
 moon:: ipsec status 2> /dev/null::rw\[1]: ESTABLISHED.*moon.strongswan.org.*carol at strongswan.org::YES
diff --git a/testing/tests/ikev2/rw-radius-accounting/evaltest.dat b/testing/tests/ikev2/rw-radius-accounting/evaltest.dat
index ccbc769..b192f78 100644
--- a/testing/tests/ikev2/rw-radius-accounting/evaltest.dat
+++ b/testing/tests/ikev2/rw-radius-accounting/evaltest.dat
@@ -1,4 +1,4 @@
-carol::cat /var/log/daemon.log::authentication of .*moon.strongswan.org.* with RSA signature successful::YES
+carol::cat /var/log/daemon.log::authentication of .*moon.strongswan.org.* with RSA.* successful::YES
 moon:: cat /var/log/daemon.log::received EAP identity .*carol::YES
 carol::cat /var/log/daemon.log::server requested EAP_MD5 authentication::YES
 carol::cat /var/log/daemon.log::authentication of .*moon.strongswan.org.* with EAP successful::YES
diff --git a/testing/tests/ikev2/rw-radius-accounting/hosts/carol/etc/ipsec.conf b/testing/tests/ikev2/rw-radius-accounting/hosts/carol/etc/ipsec.conf
index 438e1c1..6ebb7c3 100644
--- a/testing/tests/ikev2/rw-radius-accounting/hosts/carol/etc/ipsec.conf
+++ b/testing/tests/ikev2/rw-radius-accounting/hosts/carol/etc/ipsec.conf
@@ -11,7 +11,6 @@ conn %default
 
 conn home
 	left=PH_IP_CAROL
-	leftnexthop=%direct
 	leftid=carol at strongswan.org
 	leftauth=eap
 	leftfirewall=yes
diff --git a/testing/tests/ikev2/rw-sig-auth/description.txt b/testing/tests/ikev2/rw-sig-auth/description.txt
new file mode 100644
index 0000000..569d7e0
--- /dev/null
+++ b/testing/tests/ikev2/rw-sig-auth/description.txt
@@ -0,0 +1,10 @@
+The roadwarriors <b>carol</b> an <b>dave</b> set up a connection to gateway
+<b>moon</b>. They authenticate themselves using <b>RSA signatures</b> but
+they use different hash algorithms. <b>moon</b> uses signature scheme constraints
+to only allow access to the <b>research</b> and <b>accounting</b> subnets if
+specific algorithms are used. <b>Note:</b> Because the client certificate's are signed
+with SHA-256 we have to accept that algorithm too because signature schemes in
+<b>rightauth</b> are also used as constraints for the whole certificate chain.
+Therefore, <b>carol</b> obtains access to the <b>research</b> subnet behind gateway
+<b>moon</b> whereas <b>dave</b> has access to the <b>accounting</b> subnet, but not
+vice-versa.
diff --git a/testing/tests/ikev2/rw-sig-auth/evaltest.dat b/testing/tests/ikev2/rw-sig-auth/evaltest.dat
new file mode 100644
index 0000000..261475f
--- /dev/null
+++ b/testing/tests/ikev2/rw-sig-auth/evaltest.dat
@@ -0,0 +1,20 @@
+carol::cat /var/log/daemon.log::authentication of .*moon.strongswan.org.* with RSA.* successful::YES
+moon ::cat /var/log/daemon.log::authentication of .*carol at strongswan.org.* with RSA_EMSA_PKCS1_SHA384 successful::YES
+moon ::ipsec status 2> /dev/null::research.*ESTABLISHED.*moon.strongswan.org.*PH_IP_CAROL::YES
+carol::ipsec status 2> /dev/null::alice.*ESTABLISHED.*PH_IP_CAROL.*moon.strongswan.org::YES
+moon ::ipsec status 2> /dev/null::research.*INSTALLED, TUNNEL::YES
+carol::ipsec status 2> /dev/null::alice.*INSTALLED, TUNNEL::YES
+carol::ipsec status 2> /dev/null::venus.*INSTALLED, TUNNEL::NO
+dave ::cat /var/log/daemon.log::authentication of .*moon.strongswan.org.* with RSA.* successful::YES
+moon ::cat /var/log/daemon.log::authentication of .*dave at strongswan.org.* with RSA_EMSA_PKCS1_SHA512 successful::YES
+moon ::ipsec status 2> /dev/null::accounting.*ESTABLISHED.*moon.strongswan.org.*PH_IP_DAVE::YES
+dave ::ipsec status 2> /dev/null::alice.*ESTABLISHED.*PH_IP_DAVE.*moon.strongswan.org::YES
+moon ::ipsec status 2> /dev/null::accounting.*INSTALLED, TUNNEL::YES
+dave ::ipsec status 2> /dev/null::alice.*INSTALLED, TUNNEL::NO
+dave ::ipsec status 2> /dev/null::venus.*INSTALLED, TUNNEL::YES
+carol::ping -c 1 PH_IP_ALICE::64 bytes from PH_IP_ALICE: icmp_req=1::YES
+dave::ping -c 1 PH_IP_VENUS::64 bytes from PH_IP_VENUS: icmp_req=1::YES
+moon::tcpdump::IP carol.strongswan.org > moon.strongswan.org: ESP::YES
+moon::tcpdump::IP moon.strongswan.org > carol.strongswan.org: ESP::YES
+moon::tcpdump::IP dave.strongswan.org > moon.strongswan.org: ESP::YES
+moon::tcpdump::IP moon.strongswan.org > dave.strongswan.org: ESP::YES
diff --git a/testing/tests/ikev2/rw-sig-auth/hosts/carol/etc/ipsec.conf b/testing/tests/ikev2/rw-sig-auth/hosts/carol/etc/ipsec.conf
new file mode 100644
index 0000000..b1aa2d9
--- /dev/null
+++ b/testing/tests/ikev2/rw-sig-auth/hosts/carol/etc/ipsec.conf
@@ -0,0 +1,29 @@
+# /etc/ipsec.conf - strongSwan IPsec configuration file
+
+config setup
+
+conn %default
+	ikelifetime=60m
+	keylife=20m
+	rekeymargin=3m
+	keyingtries=1
+	keyexchange=ikev2
+
+conn alice
+	rightsubnet=10.1.0.10/32
+	also=home
+	auto=add
+
+conn venus
+	rightsubnet=10.1.0.20/32
+	also=home
+	auto=add
+
+conn home
+	left=%any
+	leftcert=carolCert.pem
+	leftauth=pubkey-sha384
+	leftfirewall=yes
+	right=PH_IP_MOON
+	rightid=@moon.strongswan.org
+	rightauth=pubkey
diff --git a/testing/tests/ikev2/rw-sig-auth/hosts/carol/etc/strongswan.conf b/testing/tests/ikev2/rw-sig-auth/hosts/carol/etc/strongswan.conf
new file mode 100644
index 0000000..044d73a
--- /dev/null
+++ b/testing/tests/ikev2/rw-sig-auth/hosts/carol/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 fips-prf updown
+}
diff --git a/testing/tests/ikev2/rw-sig-auth/hosts/dave/etc/ipsec.conf b/testing/tests/ikev2/rw-sig-auth/hosts/dave/etc/ipsec.conf
new file mode 100644
index 0000000..eef3e26
--- /dev/null
+++ b/testing/tests/ikev2/rw-sig-auth/hosts/dave/etc/ipsec.conf
@@ -0,0 +1,29 @@
+# /etc/ipsec.conf - strongSwan IPsec configuration file
+
+config setup
+
+conn %default
+	ikelifetime=60m
+	keylife=20m
+	rekeymargin=3m
+	keyingtries=1
+	keyexchange=ikev2
+
+conn alice
+	rightsubnet=10.1.0.10/32
+	also=home
+	auto=add
+
+conn venus
+	rightsubnet=10.1.0.20/32
+	also=home
+	auto=add
+
+conn home
+	left=%any
+	leftcert=daveCert.pem
+	leftauth=pubkey-sha512
+	leftfirewall=yes
+	right=PH_IP_MOON
+	rightid=@moon.strongswan.org
+	rightauth=pubkey
diff --git a/testing/tests/ikev2/rw-sig-auth/hosts/dave/etc/strongswan.conf b/testing/tests/ikev2/rw-sig-auth/hosts/dave/etc/strongswan.conf
new file mode 100644
index 0000000..044d73a
--- /dev/null
+++ b/testing/tests/ikev2/rw-sig-auth/hosts/dave/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 fips-prf updown
+}
diff --git a/testing/tests/ikev2/rw-sig-auth/hosts/moon/etc/ipsec.conf b/testing/tests/ikev2/rw-sig-auth/hosts/moon/etc/ipsec.conf
new file mode 100644
index 0000000..9f9051e
--- /dev/null
+++ b/testing/tests/ikev2/rw-sig-auth/hosts/moon/etc/ipsec.conf
@@ -0,0 +1,30 @@
+# /etc/ipsec.conf - strongSwan IPsec configuration file
+
+config setup
+
+conn %default
+	ikelifetime=60m
+	keylife=20m
+	rekeymargin=3m
+	keyingtries=1
+	keyexchange=ikev2
+
+conn research
+	rightauth=pubkey-sha384-sha256
+	leftsubnet=10.1.0.0/28
+	also=rw
+	auto=add
+
+conn accounting
+	rightauth=pubkey-sha512-sha256
+	leftsubnet=10.1.0.16/28
+	also=rw
+	auto=add
+
+conn rw
+	left=PH_IP_MOON
+	leftid=@moon.strongswan.org
+	leftcert=moonCert.pem
+	leftauth=pubkey
+	leftfirewall=yes
+	right=%any
diff --git a/testing/tests/ikev2/rw-sig-auth/hosts/moon/etc/ipsec.secrets b/testing/tests/ikev2/rw-sig-auth/hosts/moon/etc/ipsec.secrets
new file mode 100644
index 0000000..e86d6aa
--- /dev/null
+++ b/testing/tests/ikev2/rw-sig-auth/hosts/moon/etc/ipsec.secrets
@@ -0,0 +1,3 @@
+# /etc/ipsec.secrets - strongSwan IPsec secrets file
+
+: RSA moonKey.pem
diff --git a/testing/tests/ikev2/rw-sig-auth/hosts/moon/etc/strongswan.conf b/testing/tests/ikev2/rw-sig-auth/hosts/moon/etc/strongswan.conf
new file mode 100644
index 0000000..044d73a
--- /dev/null
+++ b/testing/tests/ikev2/rw-sig-auth/hosts/moon/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 fips-prf updown
+}
diff --git a/testing/tests/ikev2/rw-sig-auth/posttest.dat b/testing/tests/ikev2/rw-sig-auth/posttest.dat
new file mode 100644
index 0000000..1865a1c
--- /dev/null
+++ b/testing/tests/ikev2/rw-sig-auth/posttest.dat
@@ -0,0 +1,6 @@
+moon::ipsec stop
+carol::ipsec stop
+dave::ipsec stop
+moon::iptables-restore < /etc/iptables.flush
+carol::iptables-restore < /etc/iptables.flush
+dave::iptables-restore < /etc/iptables.flush
diff --git a/testing/tests/ikev2/rw-sig-auth/pretest.dat b/testing/tests/ikev2/rw-sig-auth/pretest.dat
new file mode 100644
index 0000000..bec31cc
--- /dev/null
+++ b/testing/tests/ikev2/rw-sig-auth/pretest.dat
@@ -0,0 +1,12 @@
+moon::iptables-restore < /etc/iptables.rules
+carol::iptables-restore < /etc/iptables.rules
+dave::iptables-restore < /etc/iptables.rules
+moon::ipsec start
+carol::ipsec start
+dave::ipsec start
+carol::sleep 1
+carol::ipsec up alice
+carol::ipsec up venus
+dave::ipsec up alice
+dave::ipsec up venus
+dave::sleep 1
diff --git a/testing/tests/ikev2/rw-sig-auth/test.conf b/testing/tests/ikev2/rw-sig-auth/test.conf
new file mode 100644
index 0000000..b9e97e4
--- /dev/null
+++ b/testing/tests/ikev2/rw-sig-auth/test.conf
@@ -0,0 +1,26 @@
+#!/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 venus moon carol winnetou moon"
+
+# Corresponding block diagram
+#
+DIAGRAM="a-v-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="moon carol dave"
+
+# Guest instances on which FreeRadius is started
+#
+RADIUSHOSTS=""
+
diff --git a/testing/tests/ikev2/rw-whitelist/evaltest.dat b/testing/tests/ikev2/rw-whitelist/evaltest.dat
index 9418d6e..3522c3d 100644
--- a/testing/tests/ikev2/rw-whitelist/evaltest.dat
+++ b/testing/tests/ikev2/rw-whitelist/evaltest.dat
@@ -1,6 +1,6 @@
 moon:: cat /var/log/daemon.log::whitelist functionality was already enabled::YES
-moon:: cat /var/log/daemon.log::authentication of 'carol at strongswan.org' with RSA signature successful::YES
-moon:: cat /var/log/daemon.log::authentication of 'dave at strongswan.org' with RSA signature successful::YES
+moon:: cat /var/log/daemon.log::authentication of 'carol at strongswan.org' with RSA.* successful::YES
+moon:: cat /var/log/daemon.log::authentication of 'dave at strongswan.org' with RSA.* successful::YES
 moon:: cat /var/log/daemon.log::peer identity 'dave at strongswan.org' not whitelisted::YES
 carol::ipsec status 2> /dev/null::home.*INSTALLED, TUNNEL::YES
 carol::ping -c 1 PH_IP_ALICE::64 bytes from PH_IP_ALICE: icmp_req=1::YES
diff --git a/testing/tests/ipv6/net2net-rfc3779-ikev2/hosts/moon/etc/ipsec.d/certs/moonCert.pem b/testing/tests/ipv6/net2net-rfc3779-ikev2/hosts/moon/etc/ipsec.d/certs/moonCert.pem
index 7f5f8d7..124e2ae 100644
--- a/testing/tests/ipv6/net2net-rfc3779-ikev2/hosts/moon/etc/ipsec.d/certs/moonCert.pem
+++ b/testing/tests/ipv6/net2net-rfc3779-ikev2/hosts/moon/etc/ipsec.d/certs/moonCert.pem
@@ -1,28 +1,28 @@
 -----BEGIN CERTIFICATE-----
-MIIEuDCCA6CgAwIBAgIBATANBgkqhkiG9w0BAQsFADBaMQswCQYDVQQGEwJDSDEZ
+MIIEuDCCA6CgAwIBAgIBBTANBgkqhkiG9w0BAQsFADBaMQswCQYDVQQGEwJDSDEZ
 MBcGA1UEChMQTGludXggc3Ryb25nU3dhbjEQMA4GA1UECxMHUkZDMzc3OTEeMBwG
-A1UEAxMVc3Ryb25nU3dhbiBSRkMzNzc5IENBMB4XDTA5MTIyMzEzMzM1NloXDTE0
-MTIyMjEzMzM1NlowWDELMAkGA1UEBhMCQ0gxGTAXBgNVBAoTEExpbnV4IHN0cm9u
+A1UEAxMVc3Ryb25nU3dhbiBSRkMzNzc5IENBMB4XDTE0MTIyNzA2NDU0MloXDTE5
+MTIyMTA2NDU0MlowWDELMAkGA1UEBhMCQ0gxGTAXBgNVBAoTEExpbnV4IHN0cm9u
 Z1N3YW4xEDAOBgNVBAsTB1JGQzM3NzkxHDAaBgNVBAMTE21vb24uc3Ryb25nc3dh
-bi5vcmcwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDTKaLLTmKX45Qm
-RjIaBSxBwofzqqkZWtl1mu0cDp6rGWr//hC31OO9MbLeRZBX0UBtuKouceAjdrwG
-aK7ChR0Ft+qlLZ6Z9BH2Dna4vTdESsB3Sn+uXuU4WNdwmmJuRBXfl/7h/Rt+34Cs
-BP82/RtR4GVpS7u73iSLlN4RaeWdySTqhtYH4cKt1H9MiSbwwomwdLedQo3UoOeU
-lkWPrzFKT3gzU4vHr1sgpbF54o/iBr5/YyJpUT9UVeDTffAEMxnAe8/Q/a3pgSLO
-wJ3HnSvcSH0w8zuH1YXOtfmqsphkwVBJGiLzUHWlYxVIAoCKdrv4eoSJLqlL5b51
-vGkmL83RAgMBAAGjggGJMIIBhTAJBgNVHRMEAjAAMAsGA1UdDwQEAwIDqDAdBgNV
-HQ4EFgQU5zzmRRlKa8+cm1g4RYg4lKNkQz4wgYwGA1UdIwSBhDCBgYAUIX+n6zfQ
+bi5vcmcwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDYeHiAGNal9DT6
+GgCewdXa4Nf/46YgbhZNmSpi/zH+XmA7JLS6eoVt5vJ/LJEHSzkRoEetptAILenu
+uakByawEoPZgkCYZgJB9opGEOoWIwTitaF0ZVV8diNQtnl+rkvwPpxWybvIwOwRA
+PUIenoQPkVhfd/ALaRl88pG0rcAW0MMSCNuQwELwSIK2rQALs94Qm5yM0bZ+dqV2
+jnSISit5doRZ4vIYghJPKPqFKb1zUw1siCDPev43S+xqwTjhJ0zncq/QigySyivd
+D8qs8KMkan+XNx9XSjW14YWp27RVpIeANlikiHh0/St0lBsR+P9sDp+Yvr+U95EK
+KOgrqac3AgMBAAGjggGJMIIBhTAJBgNVHRMEAjAAMAsGA1UdDwQEAwIDqDAdBgNV
+HQ4EFgQUQcvdnqQfLJx2utB9szVLhZCmp84wgYwGA1UdIwSBhDCBgYAUIX+n6zfQ
 owsfodxCBh4RXzzSEBShXqRcMFoxCzAJBgNVBAYTAkNIMRkwFwYDVQQKExBMaW51
 eCBzdHJvbmdTd2FuMRAwDgYDVQQLEwdSRkMzNzc5MR4wHAYDVQQDExVzdHJvbmdT
 d2FuIFJGQzM3NzkgQ0GCCQDyr+ZHsk6LRjAeBgNVHREEFzAVghNtb29uLnN0cm9u
 Z3N3YW4ub3JnMBMGA1UdJQQMMAoGCCsGAQUFBwMBMEEGA1UdHwQ6MDgwNqA0oDKG
 MGh0dHA6Ly9jcmwuc3Ryb25nc3dhbi5vcmcvc3Ryb25nc3dhbl9yZmMzNzc5LmNy
 bDBFBggrBgEFBQcBBwEB/wQ2MDQwEgQCAAEwDAMDAAoBAwUAwKgAATAeBAIAAjAY
-AxEA/sAAAAAAAAAAAAAAAAAAAQMDAP7BMA0GCSqGSIb3DQEBCwUAA4IBAQBVFKeX
-QIH5Zk0dp/7u/V0TKqu5vZ9x6ZrshAZ9nzbLgmSP+++yDXmlQe0D0i2Men4D095S
-smFqw1nMWM5oEPpP58+jhCOHzn7InMp+SRRBkX2j06wT9qbynAHiIun/qcdq13w1
-Fs0PiKVQZbbz72mwl9J3Hkj/JkLtOX00wMPqIFU6veeagGiwOW7KkehFUVqoD9+O
-vgkHnUti2XzgskEGcEWmE1EYv7Qo0OdZB15oNoUV5i8WelfmWO+nz9/QKciATNoC
-kAUVcEV9XY9sSKjazdyG6QfEd3l6lQ+KAt8MnqA89i0yIQ1lg+3Jfe67SMvM1gy6
-Y0Y2hqCja6SsIjVc
+AxEA/sAAAAAAAAAAAAAAAAAAAQMDAP7BMA0GCSqGSIb3DQEBCwUAA4IBAQAi0XQL
+aEHg8aXBiXSTHuvxDieJB3Q83kpXOry16Ij5PKx9cdM2Gtmxz8YkwPEgq0r7vWNo
+830A4CnOJszQyIpY7CIygPj1wy3kFGGPkL7R4p00qSKpCEg8Fq85R4LmiyXIEZ+5
+lUtan7xka4ySMKKocm2rbXHyHXjis8AzU7NZN5QpEMkGLTaQPwHad4FUBFOolNE2
+NLoQ3xp9NPTyqfy1CkCHcyG18yRPciU4m8Cubyb+zBHyBADm9Q0P3++vznsU8LrR
+pzjRqS0e+FD2bzdXH/2g7Ge8+b6xzWRVMxZ8e2f5O9jQUY6q4SicuAX8SM/bgDPu
+Mc/lk4Nl8pHRO+Xm
 -----END CERTIFICATE-----
diff --git a/testing/tests/ipv6/net2net-rfc3779-ikev2/hosts/moon/etc/ipsec.d/private/moonKey.pem b/testing/tests/ipv6/net2net-rfc3779-ikev2/hosts/moon/etc/ipsec.d/private/moonKey.pem
index 8295f97..11607c8 100644
--- a/testing/tests/ipv6/net2net-rfc3779-ikev2/hosts/moon/etc/ipsec.d/private/moonKey.pem
+++ b/testing/tests/ipv6/net2net-rfc3779-ikev2/hosts/moon/etc/ipsec.d/private/moonKey.pem
@@ -1,27 +1,27 @@
 -----BEGIN RSA PRIVATE KEY-----
-MIIEpAIBAAKCAQEA0ymiy05il+OUJkYyGgUsQcKH86qpGVrZdZrtHA6eqxlq//4Q
-t9TjvTGy3kWQV9FAbbiqLnHgI3a8BmiuwoUdBbfqpS2emfQR9g52uL03RErAd0p/
-rl7lOFjXcJpibkQV35f+4f0bft+ArAT/Nv0bUeBlaUu7u94ki5TeEWnlnckk6obW
-B+HCrdR/TIkm8MKJsHS3nUKN1KDnlJZFj68xSk94M1OLx69bIKWxeeKP4ga+f2Mi
-aVE/VFXg033wBDMZwHvP0P2t6YEizsCdx50r3Eh9MPM7h9WFzrX5qrKYZMFQSRoi
-81B1pWMVSAKAina7+HqEiS6pS+W+dbxpJi/N0QIDAQABAoIBAQCSHbx1XB8jJSot
-teMTWEMAmgCDHrN2RQQ2ueaaxI8MrED7NK4S1rBkCVDRN2ejLLudcOvpyYikYZPI
-B4XuOjgT7ejjNYcK1vXawrVqLhxhGCzIHvftC+MnM2qYk2vLCzfriXyomgD9sOCT
-p72GKmxOIq1pyCr228eEApYLjLCDlhso3PrCo7recUq7f56rLjvb4gfcfor6mJUd
-yIppZUnDFJnsRXup1G4L9Y9RNYtlkcDqem/Q49d5+AHCYH6R8YI0Iz3JnzZjalsq
-+IA6RJqHBTeOpiyCmHlUmVE/3YUm8n7w7RRngMOLjKdiTKHT+8EcHmyUorqW3Yea
-zCIe5C6FAoGBAO23egrSbamyWXcIOqx1GX9gzYmQ2nSKYUtRhsE8eNErw0zp4FKv
-AA7CAmoWEzjDJPSkUzDAajoZiH8+DIZ4IkwKbYjtq0vr1yCbx/PBKVN/JHGZ/Ao/
-dc/lQrNseza34NBrREN/gUytjefFMJ4YStSZCMuy3gP1Fqk6YCy/dObbAoGBAONn
-UqjmZYqoK0+jnGWdPOtXZ4bu8UoHc8/1MaVn3pq8bYh3PayFKpDKtcD1ZeXHCxL2
-1Y+Eid/DoZ2/RZbxT2mhi2mVZZCWc0xuML3Vz0B9bqi3ZfRLVP2u87fn//mGrD+9
-yy9PeIBv8UvjOhev6hZDBhPAVMsyjiw+wSX6kW/DAoGBAMBcrbSeLcGZok3xadFu
-fPCXvBtrDWwrIqpZUauDLN1PBZ5yz2T5WhmXI28HaAyR1ZDmfK9BtXRIfy1AX9Bc
-3JweAB9C/E/Wi+JGTVrR34hCpZIMImmEiuhtxDj/OwG/cHwXoUjhoBcVhnScHEiC
-reM152k21/Pp26mbpIHxeD7rAoGAaRy4S5P7uaTUKEKzJxEQOKQ1GVzXMWXSdXyb
-zx38+j9AzgR4AIepTjY03xVPXW+swb5Qpr8Xz9Oon7bq3sN59pSSUWKaCMRSVTDV
-3Nm4q9GO1fO377zmc0BsLUTSwC8s7WW4Ro0QYSXdPjuw/YP1ywZ+B6EuUKJ0ryTu
-uLRih2sCgYBm15N97b7Rp+aAti045iBla9/KH8z7szczIndpFWR4wjaI9tt0i9GR
-OZs7LFq0MYdg8JiXITyVcuqsUbdAP3TvsXGDHdatbDcrXM/DYuP6dPqMuGBKdnEn
-gIFT1z8mhv4Im3JKpuckMrIQ5vWhljcRZgiEJYZfEAkLJo7ePG2VzA==
+MIIEowIBAAKCAQEA2Hh4gBjWpfQ0+hoAnsHV2uDX/+OmIG4WTZkqYv8x/l5gOyS0
+unqFbebyfyyRB0s5EaBHrabQCC3p7rmpAcmsBKD2YJAmGYCQfaKRhDqFiME4rWhd
+GVVfHYjULZ5fq5L8D6cVsm7yMDsEQD1CHp6ED5FYX3fwC2kZfPKRtK3AFtDDEgjb
+kMBC8EiCtq0AC7PeEJucjNG2fnaldo50iEoreXaEWeLyGIISTyj6hSm9c1MNbIgg
+z3r+N0vsasE44SdM53Kv0IoMksor3Q/KrPCjJGp/lzcfV0o1teGFqdu0VaSHgDZY
+pIh4dP0rdJQbEfj/bA6fmL6/lPeRCijoK6mnNwIDAQABAoIBAAutG9rU/CcBcCYZ
+ZvUpQW7H9/6uedR/+6X94AJs/3ZYAtrN1Q3F9BKEhYoEjmIVVaO0wIkGWWxHhbnB
+u/MDvMqXIBL/U37Gp4SPU0gNnAxPV85KtdLa/wFp0wAO7dwkVoJFoe74+wlM9aK9
+ayaZqEfqsBieMI19Asnxj5huUtEoIiU9ekz6HLeALwy6OxJLrempDugDe2icaWSt
+pLIU3ZXmzVbOFLNtq+KMpanQzamAvSTUq5Wmuz+C6nTEv+JjGWFblX8pM2ACA6cV
+VouefUFfKpMXjHTlsvw0JiDzLeYRxRZZMxnTxzbnoigZfW6ZDxP2w9KRv/7LuSj/
+ktqfVKkCgYEA8qlkPka0cfIKcjloe6oNEMt0dX6V+5LmS59DRnnhu+6FuIVncS7/
+intBGag603wJvGlA7HuUAZbcr4ilDIe1cUm0d8rftjvw0uOBU/gfNVmxhpFzs8Ku
+4Fry6lKow1ecqFQ1i4VZi2qQJVv3m6tRojMTh6xVA9/FLD9iiu3V2dMCgYEA5F6I
+HV1sqY2Q8aU48dch+I1ItrqiURwY7qejuIprpXBoRQPQV3OoYgJcKtdlSKrbDGQd
+iJmL0aoy/ONThrfOtygQtth/f79ktKZZHja8Ew+0/lzfxMSb69kl6Rxx9OKJILPE
+caezhYFGozEKwLddcrqxrSd3Fvz78CVRRiAx2o0CgYEA4g0wh98f24Hpf0zBa2oX
+b8zIOWfp2giXply/tBh4U7S4NxN3MHXisaNuGrOf0UEcZLr8MxBP6UcbYB3/+vM0
+8EsD5hBEZKPkDODIqmtazz015jD7QrsaY3/2CJlmA0tLcXe4xbc8mmZzz4mj2Q04
+J8xC5kGAlPJQ4I5PgzJZ4+cCgYAHyqHiPpnCfy3+0KBMwAZMsKVWdq+rDMZc/iM7
+3J0nm9oy4JpvIWcRUPtMCuVNwWaP2aqYSoTWtnPe5PKomgTXgupvEpvnA+SvtS09
+NqjcDaEjPI/16q9XMKV2ep34uPHsx7VgG1SorWx3jOjNAnSRwYTmX35UrnT6EIvh
+VJ/e0QKBgCgI41QtJ4ShFxpSdxzy3Gfz/EFTUGIjtmXQe/7GixxoXJkpGXCGhToU
+KVF+HUEYKOQ1vX9SNUyY+1LyqO3vj+QzuJ0q4GrtEY7vxDH817QvJLecj5i22Hof
+50MqUdow2BnOSFuJvWhR1DdodRX3vh1awod/CoIufnfEI4MuMO6H
 -----END RSA PRIVATE KEY-----
diff --git a/testing/tests/ipv6/net2net-rfc3779-ikev2/hosts/sun/etc/ipsec.d/certs/sunCert.pem b/testing/tests/ipv6/net2net-rfc3779-ikev2/hosts/sun/etc/ipsec.d/certs/sunCert.pem
index 9ccd47a..a93121d 100644
--- a/testing/tests/ipv6/net2net-rfc3779-ikev2/hosts/sun/etc/ipsec.d/certs/sunCert.pem
+++ b/testing/tests/ipv6/net2net-rfc3779-ikev2/hosts/sun/etc/ipsec.d/certs/sunCert.pem
@@ -1,28 +1,28 @@
 -----BEGIN CERTIFICATE-----
-MIIEtjCCA56gAwIBAgIBAjANBgkqhkiG9w0BAQsFADBaMQswCQYDVQQGEwJDSDEZ
+MIIEtjCCA56gAwIBAgIBBjANBgkqhkiG9w0BAQsFADBaMQswCQYDVQQGEwJDSDEZ
 MBcGA1UEChMQTGludXggc3Ryb25nU3dhbjEQMA4GA1UECxMHUkZDMzc3OTEeMBwG
-A1UEAxMVc3Ryb25nU3dhbiBSRkMzNzc5IENBMB4XDTA5MTIyMzEzMzUyMVoXDTE0
-MTIyMjEzMzUyMVowVzELMAkGA1UEBhMCQ0gxGTAXBgNVBAoTEExpbnV4IHN0cm9u
+A1UEAxMVc3Ryb25nU3dhbiBSRkMzNzc5IENBMB4XDTE0MTIyNzA2NDkwMFoXDTE5
+MTIyMTA2NDkwMFowVzELMAkGA1UEBhMCQ0gxGTAXBgNVBAoTEExpbnV4IHN0cm9u
 Z1N3YW4xEDAOBgNVBAsTB1JGQzM3NzkxGzAZBgNVBAMTEnN1bi5zdHJvbmdzd2Fu
-Lm9yZzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAK1HhvoVh/fM14RE
-CTXr4to9ZEeGSqHLl5du+eYZl1fC7qLYaCtlaH+eLfDsCgYpe+XsDLHIxpTK9R6k
-XgLP1Jraxz3rtv5qJKkV3aDTjQ2d+cFc0EgiZmn53VEmI/IlcJS/VZzHhNvEJk7H
-k0YpoazpGPtNzFGaehV5mXUAeVPx4RH8fjcSiPbuPS3WC7cqtYvVwk97dj05VfEC
-VnG+90+eFKztvawBzNGwGQ7xZV7kSiPHNyGAV0qrKvhXZ0VPnm/OEiGCAlIo8uno
-Yb/4UMM/a5usCaA9Hgbf8+qqmrzavSUkFEa0y/p9bOBHaqfNP002xktbqBCCodRr
-6QgmiysCAwEAAaOCAYgwggGEMAkGA1UdEwQCMAAwCwYDVR0PBAQDAgOoMB0GA1Ud
-DgQWBBTaKhy7PH1ihWsD+3/bJQ3e3Isj+DCBjAYDVR0jBIGEMIGBgBQhf6frN9Cj
+Lm9yZzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAO+7A6hhF+4kxCv5
+oR9DEpv1gnpGmPpn6i7JfuLGIJ9phQ3bUnSMIx8+mp3JE4SLXINLcyCHilK74tIf
+pwYx2K0c2txTFIWLQvBaHWohJ9Sgg4ElVXmSa/b0Nym5FcttdcRgNGd/+DLPs9Tw
+ZoieGvJcZWiOBP+xxPbEo2xcoi3GetPN+XSW+m1BvU88Ysrp0o+4+rLPB5iipUB1
+Iksb51SvF4iG4BHfoTKGlHLwVyjJnp7YnYJtjY6Xaw1GbCf6wcwLlq71uoMj39cd
+0clncpi/s13K2Sh0YHiCcQD5vIkP9BRmobWAXseBZevYI/rU5dz761EqHf72TRrd
+bM3/KycCAwEAAaOCAYgwggGEMAkGA1UdEwQCMAAwCwYDVR0PBAQDAgOoMB0GA1Ud
+DgQWBBTPOzV+XXFm2wEX9j+NxqVXiRBq7TCBjAYDVR0jBIGEMIGBgBQhf6frN9Cj
 Cx+h3EIGHhFfPNIQFKFepFwwWjELMAkGA1UEBhMCQ0gxGTAXBgNVBAoTEExpbnV4
 IHN0cm9uZ1N3YW4xEDAOBgNVBAsTB1JGQzM3NzkxHjAcBgNVBAMTFXN0cm9uZ1N3
 YW4gUkZDMzc3OSBDQYIJAPKv5keyTotGMB0GA1UdEQQWMBSCEnN1bi5zdHJvbmdz
 d2FuLm9yZzATBgNVHSUEDDAKBggrBgEFBQcDATBBBgNVHR8EOjA4MDagNKAyhjBo
 dHRwOi8vY3JsLnN0cm9uZ3N3YW4ub3JnL3N0cm9uZ3N3YW5fcmZjMzc3OS5jcmww
 RQYIKwYBBQUHAQcBAf8ENjA0MBIEAgABMAwDAwAKAgMFAMCoAAIwHgQCAAIwGAMR
-AP7AAAAAAAAAAAAAAAAAAAIDAwD+wjANBgkqhkiG9w0BAQsFAAOCAQEAOqdCIldA
-mPp2aAWVPBiKXNrk4VJoIGlwZaUtYNxGQ46wUqAro/taKwZd4B1yvwsX/cHX3Y6j
-C1mQtiXw9onJm1qJM1a804U9yPcgdI+9RMiU0hA+aVmyMlS6WQsKFubU17qP2Ljd
-4hOwVQ681Hi8zfQjJdYpaO1yLcpy2dkotreJS3wA24ssnskRBI/cuAN0dfbV6SDQ
-TK91qz0emHoK3efgtvX4oEpsxI4NrwMstaZSVsHn4npKTGYu82dmPoK6WPblGEHZ
-Iavl08lGcYBV5I2ZGuWOekWQzUuBSveV3AFjieeaDIG3Ue3AKaihn6dCLz6l+t7E
-dXN+1axy9zQ34g==
+AP7AAAAAAAAAAAAAAAAAAAIDAwD+wjANBgkqhkiG9w0BAQsFAAOCAQEAgJDWuKCu
+7H/K4U7xFRarSKtj9oMAAsq2vLSQqJTUg6fdTnFIlH3OBPcwEzFwVx30QlQyls1p
+nHm/cptV/3cxvqCvdnT2dVspJu+9a5D+zZNeLAtWZuyRN6Nlmeqj1Nnp6eEHEBrg
+oXMzmAf0ulzIZJsEVYwJSCXm0AMOlyvoIYqKxty3L2VZ1iAU1z15lnFhcvamraGx
+k7yaI9ujVR4xQZOOgh05pUrEKaXI3XR1rIoL3NV3ws/JgHch/CQw/If7x4VQmGcD
+yJbKkKn0S18TJr0KhPqbM4+inldEwyX/zjGmlHezy0em5qTRYwupFIQNwZZkTXug
+NnBR3lf2HB2lWA==
 -----END CERTIFICATE-----
diff --git a/testing/tests/ipv6/net2net-rfc3779-ikev2/hosts/sun/etc/ipsec.d/private/sunKey.pem b/testing/tests/ipv6/net2net-rfc3779-ikev2/hosts/sun/etc/ipsec.d/private/sunKey.pem
index 6e047af..55f5f80 100644
--- a/testing/tests/ipv6/net2net-rfc3779-ikev2/hosts/sun/etc/ipsec.d/private/sunKey.pem
+++ b/testing/tests/ipv6/net2net-rfc3779-ikev2/hosts/sun/etc/ipsec.d/private/sunKey.pem
@@ -1,27 +1,27 @@
 -----BEGIN RSA PRIVATE KEY-----
-MIIEowIBAAKCAQEArUeG+hWH98zXhEQJNevi2j1kR4ZKocuXl2755hmXV8Luotho
-K2Vof54t8OwKBil75ewMscjGlMr1HqReAs/UmtrHPeu2/mokqRXdoNONDZ35wVzQ
-SCJmafndUSYj8iVwlL9VnMeE28QmTseTRimhrOkY+03MUZp6FXmZdQB5U/HhEfx+
-NxKI9u49LdYLtyq1i9XCT3t2PTlV8QJWcb73T54UrO29rAHM0bAZDvFlXuRKI8c3
-IYBXSqsq+FdnRU+eb84SIYICUijy6ehhv/hQwz9rm6wJoD0eBt/z6qqavNq9JSQU
-RrTL+n1s4Edqp80/TTbGS1uoEIKh1GvpCCaLKwIDAQABAoIBAHKb86/nm9YPu6B1
-K65phdMZdgFE1oorUenMcid6V7qpaRN2lXfWjAaUxggq5vpqZ9OMjFzu0kHJ99S7
-nJ65fgKqn8vZ42BlLjhUCRH9urb9/Rqi2/RKJHkF1hd9ZZscnlkUMHkRElQVac0D
-feqTUKdASdC2BWUYCpW3pwNXO+iD5bA9/wB2J/RYYmm6Qo7UZQU8C0lken/8EOEL
-/ch0ID7C5PC0vWvLT0fM9j2JKDq8T6NRhF1MluISGDOp4pW7tEbkHo5I6zD0aPO2
-K9leN3aSUYsOVJk39VXkThwgJ4lqNEXI2xRbtW8sAf7TL1YDxLR2JN3UGvy/By5B
-UblJUnECgYEA2nO+iXScKd3qqmHrdXcxf2ExZQr8QgTAsZOkb6LQ9kGQll0lBcFc
-T2HlobzOaQktpF44C41zf2QpGDllbpyNT8VyQkI+CJ4pntjtKPkoPkxUeVlciFsm
-7THqCGe0zQBWDnXFVfTKR12aRwkhjG+QCQyyaAaV8YztEsDI5SRCjykCgYEAyxAb
-t/NTh9DBDrfJCkT21Rm9Ow70vhDaAyQLq3nJMF+BTXYDrnVMmFHCIHd+nbNP0CLs
-cV/fWAF6626ko5B6ewPFQ4wXRvtNAiDNZSfeaZgvxCrvoDgVrHWhfwHSXWFqny0o
-WHwIJJQvdkLW9BHwbpAQRoD1c2sy7pWIVTEyljMCgYEA0zZXwkUp/FzhWG2moANn
-qzZI8N4nOpmnycnrkjiE+6Q27PsQIblrzCDmSnPnyqyiIasrWxgf1Mr95LsR9FmP
-U9Ke/6tWmTR7H2e0HgqRO3LHtjCNhBVF1M6O7iN/Lzqk+gQqkUpGDaxVz1rnwgXX
-6LgLAwNjFJJiYeBeHRbq98kCgYAwBdg4UbBgf0sY+vftmM+zKAorjGbvCDc25PBp
-ljyxVvTSZ+WI/a6mmzdIzFnCW+S1OX0ndt/wBTGXuivvjryYmRSu29OpcscMiMtq
-b9pWqKorP2g6QOlHRu5xhfHFKcO4b0qKWpLma7Epy7bgM9njm+htdBQYPrLl37FF
-TIRFJwKBgGnZR5rm5iCrcIoAUMlH4/5ye5BPjHDn1NNv7Q7PZR9jhaEuoiBgvk6v
-h+YVi9A9nhbaqS4/rumsNPlObeIw78713pendaWCjC4hA0urrJ4fElfuaIyZMyKE
-FD64V78iaYVlmwKMJxZUnS1EFzb0XQZM7wxhB/i0wwjh+48rBHbd
+MIIEpAIBAAKCAQEA77sDqGEX7iTEK/mhH0MSm/WCekaY+mfqLsl+4sYgn2mFDdtS
+dIwjHz6anckThItcg0tzIIeKUrvi0h+nBjHYrRza3FMUhYtC8FodaiEn1KCDgSVV
+eZJr9vQ3KbkVy211xGA0Z3/4Ms+z1PBmiJ4a8lxlaI4E/7HE9sSjbFyiLcZ60835
+dJb6bUG9TzxiyunSj7j6ss8HmKKlQHUiSxvnVK8XiIbgEd+hMoaUcvBXKMmentid
+gm2NjpdrDUZsJ/rBzAuWrvW6gyPf1x3RyWdymL+zXcrZKHRgeIJxAPm8iQ/0FGah
+tYBex4Fl69gj+tTl3PvrUSod/vZNGt1szf8rJwIDAQABAoIBAQDf/YrzXpTva+bn
+d7y16wOOORyKh0AUZ9eFk7s8xAZjLEKnqc8nGnEOln39A417AIOWIX8WW85Ac1EB
+J5X10ck0JovP5Mh95prK3Egzi3sdzkRQ/MMablb2TUTldQwKIOIyc/lC42zSfQL3
+6Q7Eg4WGAhK2WEwPZNg2AZD4hKz7unK+IAar9uLi39E4iVzDavzwK5y+fsy3HVFD
+cJbPWAr4+4teinF5wkRzK7OInwkPc9IrUF/9wp1ZWp/Rc1YEkCVwmu5v7kPzALI0
+SLwYLil8mXfvG0VZjYIlhCSOJJRuw/0JR2cCDJ9WFppK+YKNh+uLoPXhJxbXM8fB
+BmCHhpdRAoGBAPpc7DhUQv8mxGCOy9O/ec50GTPj0bWD0WLrJoqvHu+LyN8OwTdG
+KMdV4Mp/tpAWbAlKH22/+7P/QCOCwByHQaUisnbkqx+5/JhZsQB7rLAdQ8SHLdj2
+iO2+6cgYPOFm6W4QT7/vl4BHAK4Glw5NPyS5sN9JBTY4bpzFHunsRe27AoGBAPUg
+zoUZnZ/6g+8XRSH77aLAbKScMBGusyxfhFAesqaXcrCrg8FG6Wcpuv2HsBE1v0d0
+7/1oJdT+p+uB2V3iZqTOeJeOCVYXgU82NRZl7R8hqYzkD8rFUZVg6hlm2xi+IUpE
+ya4itKWIckSvnexEqiBov7k8sPmb7R/7HWGWUOuFAoGADz8PZ5LCDbW3qcWoZfm4
+Gjl5u245PBuN6b82NqXZdW8GyYalf483NoRlTw+d94JWC+7GoTFay6hUqJTyzAn0
+lnDZe2ILhcAWwNRdchEWABeYI+Szhw3kYs4IgJXxRyy0NG6r3J1jlX09bluaYVWU
+7dCdE8vnlFi1a7iZXFd2HrcCgYBknEGHqdrjdbw/Hwr2BuQjf91Xtu+X4l+SH+Y7
+yE3FSLX/Q3aBluxntl4Uf2PJvIi0+I8kMGIOyTL827/u4+UDUed3NQop9t3ROEuT
+1OP9eiCQPm8o59IzgKK1KF1XC3q4dAFfYslIg/d6r6Ye+pPlV3kRu5Jb8R7jmHsX
+uc2ezQKBgQDgouR4ipkb+sQcMKkhzHUEx67aHEVH69v2R9lm8YgPHjvPCA++DgPZ
+dwWALnW5wKRfdGy4b1yTIICUgjKIIlD2owJB/J5Z4SzrzbOAEJkNURGAhp6njsf+
+QYRyoXLOb/8jAQqLx9hOB8L2gsRSDddvvYw/DTP2cKM8vJtYFWam+A==
 -----END RSA PRIVATE KEY-----
diff --git a/testing/tests/ipv6/rw-rfc3779-ikev2/hosts/carol/etc/ipsec.d/certs/carolCert.pem b/testing/tests/ipv6/rw-rfc3779-ikev2/hosts/carol/etc/ipsec.d/certs/carolCert.pem
index 3243bc2..bf8a491 100644
--- a/testing/tests/ipv6/rw-rfc3779-ikev2/hosts/carol/etc/ipsec.d/certs/carolCert.pem
+++ b/testing/tests/ipv6/rw-rfc3779-ikev2/hosts/carol/etc/ipsec.d/certs/carolCert.pem
@@ -1,27 +1,27 @@
 -----BEGIN CERTIFICATE-----
-MIIEojCCA4qgAwIBAgIBAzANBgkqhkiG9w0BAQsFADBaMQswCQYDVQQGEwJDSDEZ
+MIIEojCCA4qgAwIBAgIBBzANBgkqhkiG9w0BAQsFADBaMQswCQYDVQQGEwJDSDEZ
 MBcGA1UEChMQTGludXggc3Ryb25nU3dhbjEQMA4GA1UECxMHUkZDMzc3OTEeMBwG
-A1UEAxMVc3Ryb25nU3dhbiBSRkMzNzc5IENBMB4XDTA5MTIyMzEzMzYxMloXDTE0
-MTIyMjEzMzYxMlowWTELMAkGA1UEBhMCQ0gxGTAXBgNVBAoTEExpbnV4IHN0cm9u
+A1UEAxMVc3Ryb25nU3dhbiBSRkMzNzc5IENBMB4XDTE0MTIyNzA4NTEzMFoXDTE5
+MTIyMTA4NTEzMFowWTELMAkGA1UEBhMCQ0gxGTAXBgNVBAoTEExpbnV4IHN0cm9u
 Z1N3YW4xEDAOBgNVBAsTB1JGQzM3NzkxHTAbBgNVBAMUFGNhcm9sQHN0cm9uZ3N3
-YW4ub3JnMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEArD8OrNy0w+T2
-cru3RQgskGCGppwpvLH/QZVHD/UbumxjKVTrz4FskqN39sFxDFDSre1bps+F7jW/
-zmOFe7c7jmZhK1mPnbviYTS4LXdo1j02pPeBNBk4b6VAIKPaYmO3UIoZZ4SPnnVZ
-P7Aj3mU1ztsTbUQqgRmTsdfqiPaBNZ0zylWYPDOkTS+1sbRQHkgdZvw4fYno+Rd+
-hDK1scggL4kRg4uGvFojYciSxo5lC53Am4r8T2zI0aI6L8g57j4cX1XYQwM3tkHM
-2BiCRM/c1wQc+vn+xp1oh/GYM4qoSoZyLTD9A0gqmbnF9//wvSmwpDpSkDoHZ5O3
-Ur6HZ8mByQIDAQABo4IBcjCCAW4wCQYDVR0TBAIwADALBgNVHQ8EBAMCA6gwHQYD
-VR0OBBYEFL9rU6QFDLvUOEIFNZROVYWN5v++MIGMBgNVHSMEgYQwgYGAFCF/p+s3
+YW4ub3JnMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAsSlxt8LQf1wJ
+u1rDltyU0dEjEqA+TxWQYi+gMakDGmWmFec1XELjKv3kcYp2McydNPq63fw9XXbu
+a/jMtmEZdFc/dpWYvsyXfyL0OOhh50PlwN++e0xxcZS4NQ6wz57bHgARzMoCisNr
+xcN0F44S0Zyn8edHkE4XV4c0p+ojB6cw5LieSMGIBQjKGCd2a3eZYhTCs6hI0vhQ
+Q1jDLyOvSWo+raa/uDTBYXCVYdN3lbHCPiXPuMY1CwZkGcANd6vBK5YBNiZFquBj
+FhIk8SBUkoEkUQMx+pMk3hGmq5aZXGxm9rHN8Xim/AewWRcKJJKdlLAAHmZD0jx2
+g/E0LGu01wIDAQABo4IBcjCCAW4wCQYDVR0TBAIwADALBgNVHQ8EBAMCA6gwHQYD
+VR0OBBYEFNs9CUs7SNJewkkfo1Bg7bcUEzPXMIGMBgNVHSMEgYQwgYGAFCF/p+s3
 0KMLH6HcQgYeEV880hAUoV6kXDBaMQswCQYDVQQGEwJDSDEZMBcGA1UEChMQTGlu
 dXggc3Ryb25nU3dhbjEQMA4GA1UECxMHUkZDMzc3OTEeMBwGA1UEAxMVc3Ryb25n
 U3dhbiBSRkMzNzc5IENBggkA8q/mR7JOi0YwHwYDVR0RBBgwFoEUY2Fyb2xAc3Ry
 b25nc3dhbi5vcmcwQQYDVR0fBDowODA2oDSgMoYwaHR0cDovL2NybC5zdHJvbmdz
 d2FuLm9yZy9zdHJvbmdzd2FuX3JmYzM3NzkuY3JsMEIGCCsGAQUFBwEHAQH/BDMw
 MTAUBAIAATAOAwUACgMAAQMFAMCoAGQwGQQCAAIwEwMRAP7AAAAAAAAAAAAAAAAA
-ABAwDQYJKoZIhvcNAQELBQADggEBAHhgG8qqLZX3uXDVX9uBZM8jErI78pyL9F8q
-ibTW5UPp+rbbMDY7tphBbFkg5Q0pzJhOzB6I6Oy/QWVVEC20DE7lhOpMu7auS3Gn
-z1t6DCIDR9NYXtKs6UXcMA0PSQ1r7iHQWvtZ0uD998k6UQfZCCOwBbonng2DAp/m
-FKkaCYiZmJw2YBwf+oVNLQp2fHI61uoguiiRQ4AV5Htho0z6MDqpMyrg2F7Uf2cq
-kQY/ZyvMe8VG5KuiaMJPIMdJPnRED2R4qiyHe8eDXgGYHsNhkt7VHRRgo3izqIdG
-1oCv+CHQ2XSK+4dA42U0Vw7V/ExmcLy99bZfCEZwNWG6Y/5Qwww=
+ABAwDQYJKoZIhvcNAQELBQADggEBAEYqXkheXXHiC5JnrZm5QUo11Vu4CtNRGeg0
+atuG8ZNHgQfa7wjjeCDNpj3lHvyegYsSMo7wGwN7DugH0mmXKZF9XHc4sU7/aUvl
+mX52tDuUoCGD0/yFuKLlYOfwmsquC9snYDW7cJXaqMON/OMLcU44OR8E1oiw2ePT
+FqyGFbfparp+Q8I7VHwJBs+mDphdNUlFbpuO9m2eEtqdYVyXlfUnbFpMMyWxxIY/
+6CIyWcRRKeWRRXxkk/dSeEWgsfWY7ITK9blP5nhIsgpCoEguGc6h4RL65VdH+Sy0
+9MLpesyGe6qkdrrg4nyaY82uuFXhUo0YiP0ddUw8eNaefFqEzL0=
 -----END CERTIFICATE-----
diff --git a/testing/tests/ipv6/rw-rfc3779-ikev2/hosts/carol/etc/ipsec.d/private/carolKey.pem b/testing/tests/ipv6/rw-rfc3779-ikev2/hosts/carol/etc/ipsec.d/private/carolKey.pem
index 2751627..a756221 100644
--- a/testing/tests/ipv6/rw-rfc3779-ikev2/hosts/carol/etc/ipsec.d/private/carolKey.pem
+++ b/testing/tests/ipv6/rw-rfc3779-ikev2/hosts/carol/etc/ipsec.d/private/carolKey.pem
@@ -1,27 +1,27 @@
 -----BEGIN RSA PRIVATE KEY-----
-MIIEowIBAAKCAQEArD8OrNy0w+T2cru3RQgskGCGppwpvLH/QZVHD/UbumxjKVTr
-z4FskqN39sFxDFDSre1bps+F7jW/zmOFe7c7jmZhK1mPnbviYTS4LXdo1j02pPeB
-NBk4b6VAIKPaYmO3UIoZZ4SPnnVZP7Aj3mU1ztsTbUQqgRmTsdfqiPaBNZ0zylWY
-PDOkTS+1sbRQHkgdZvw4fYno+Rd+hDK1scggL4kRg4uGvFojYciSxo5lC53Am4r8
-T2zI0aI6L8g57j4cX1XYQwM3tkHM2BiCRM/c1wQc+vn+xp1oh/GYM4qoSoZyLTD9
-A0gqmbnF9//wvSmwpDpSkDoHZ5O3Ur6HZ8mByQIDAQABAoIBAQCSb+WlFtpjtPPF
-JUwxVzqz4Cx510gwkU+GzUemDGdvfZhsWjNEri7FGE70LQ9UPh5vGd2SmtmtZGrW
-J4wjWus6LFYuCa1sl4BlzfFLTjqF8XLUm0twJITzfhVf6o3OmiIOSepBNNT5DaE7
-4R8NgxRU8bG5cnuEWF9VklBl8tR04/VHIfTHltt1p69aQ6UoECBLd+/8RBIj+L/P
-TzXbgLJn7dT8DrOA9rv1p0G1reADwvclKfag4S/xyC54anRsmMNWQLE0D+QzKL29
-nXqU1wjIHBtgY7uM0svtyrMXiNi0XEBWqDdOMwCZ66TU6eGIzDDevG+q8PXmuW6v
-NGxoipcRAoGBANJy4uNj2SnMTdIyoe0wFjmjntKb7DX2Ie0aZr3kygQ7VJUH6w7Z
-mZXNhRf8CpaD20lnyqRjhgq1gwOrLZWpAajNPJ6uCHUVSI8+qwdMVdPSZyxRlal9
-gshsGofkiqEGa/5BW4+yDgi1C4BV+lmN8jn4ilKe4JvFGuz+F31ntDXlAoGBANGH
-WKCq4u9MCxM2R2ESKkLM+vlTxRB4meMt6iPn9e0yJ1BVXTILRp7hfUwKc4ivI/SO
-rc4UA3I5i6QR7TVPOVreqw/CDEmjQLhTSOWY3lHbNz1q53p8Yh6JdytaA4YYgm+I
-pFL+Hh/UpPEAY1ZzsSP7KhBd7ViKblz7/Act614VAoGAXTkFJqNpZGmbI3zIXBBM
-GBZR2Yu2dCTm3GgwkPfTQVKi4i2Sw45Cyagzx+8fJZOdRQQUMQPhMcc8FRjz5XLr
-SEI6EzSWjH70GHgzPNVkw6NVjr1JJb5ye6PfkMj9W91DY2rCS4IdU2AXiy8K6jbF
-0UY2x+iXKImEpuzbrPKOUr0CgYB1lHdGyj7JPKomYNpTfecbT34zdi/rG1J4Kybu
-eVgHgJKRQSYoVC2QMUen6WGGPYp2za55K7/3VJWpP6oWtVuhQ71I/YL5u9Qw3APX
-XB6+Xr80Bw7ZLH2/VzL5r+y0ToK75jkYnaP4BtN8rtQQCqJIZ8TmJF9xxVVDduCq
-grlHNQKBgF06eOplOy8W7euuhvEfoxv05ZVjcFv3bFzlYPb0fBfq4Ziw97SzidH9
-Wbq3gujut9gJCKZT6BJfZtqrPeVhWp+S2SD3bDCsjNZLRBEdzdyRB5CpmDE5OQBH
-EtzpR4nQa/2RJ7wRP/306PE1sQPtTpNvGIgBIUxWvt5gzyVhO1sG
+MIIEpAIBAAKCAQEAsSlxt8LQf1wJu1rDltyU0dEjEqA+TxWQYi+gMakDGmWmFec1
+XELjKv3kcYp2McydNPq63fw9XXbua/jMtmEZdFc/dpWYvsyXfyL0OOhh50PlwN++
+e0xxcZS4NQ6wz57bHgARzMoCisNrxcN0F44S0Zyn8edHkE4XV4c0p+ojB6cw5Lie
+SMGIBQjKGCd2a3eZYhTCs6hI0vhQQ1jDLyOvSWo+raa/uDTBYXCVYdN3lbHCPiXP
+uMY1CwZkGcANd6vBK5YBNiZFquBjFhIk8SBUkoEkUQMx+pMk3hGmq5aZXGxm9rHN
+8Xim/AewWRcKJJKdlLAAHmZD0jx2g/E0LGu01wIDAQABAoIBAQCKdl7HhX5ZHAEL
+KjwVq56wgekMhKtOOgdXheuJBJRFTE7LbaI50pkjn72ss8/+yfHQV2o3Vw5K/0oG
+nzS4EhnH4Ozb7L2t2c9J8XK5C36BNoLaBMUmLq+3WsnBxhKQopKU1u8ShIwKEgQo
+U8NnKYYxx2NHYECBW1dI9IZF+muYbVg420PJ4DiFMSTy5+o+UsI8X0ymV2RYZAfg
+qO8WgQYHZca2ffJ4rJHi8wf4IzaH//65vP+Ij7FGzfXmBd3A9F1wP7skBYZRYPp6
+MtZ5cxfNUwkGtkmt1KaEnsmg4F1/jaB0h5+xT4pj6NqaatvoKZ5zd8zpcGktuptO
+zhTa63hpAoGBAOkxtwWaJAHj1GH1CzIkCP4siySSgphtcjP96XdcIaTuGx8gp/YU
+0Bj3irK3KpVNrcLgc8KzylfMiAETMlRnEb28wSfqkegCR4Lrrsw3YjEAcVPC9Vtb
+/wQHc9wUGCt0OUv7EE7alB/cKnjTQzF6ZgTGTUhGv4CuL6XjhEzqiA0bAoGBAMJ8
+5V/wjaDkRDHRtaDI7xX2j4uPE7FoQYCSVtKOil3rmIrmgBCXTtWB8EQ9o3Ux6sOl
+lmA3sSF1ajyPu8e2+QhQF9wAF5mvN80aPj0KXKCv6Qx/H6Tjpg3eqVr6rucOyH58
+gKnuo1YISFcjcMkNEOZy6//7SkmAAN/p0Dgk6h71AoGAVKSC9jmY0EbOFDBJvA1w
+ZjHs331+ga1YQp7rWzPJ0n/KwGWuEZhEYIuZgH0Tq9XiOFYYLpfr3iqTQzCgmBpB
+Skl1IvP1uez53/+EFwQTVA4BFJIzVNHzopbB6yQwEbXCBl4+8SBNm7Lih7DHNvJi
+jWEdNBrZ7+9JxEDtCK4oa/kCgYBbaHwd9V97aQ2sJJYq9YV5WyLoQtzMmuV+Wkk4
+OQpLTjmpvuAd7B9/Nc0JJbc3k7h1L9RXcJVt1lOSFzP4j8TH5WzxV5HAB5xAZ78s
+zTvvwf3Ug8MJqn0XM7mBKyUdL9OHr1iBhcl62/W0DtIpjFyPEyBcdWza0rCWjLvy
+R1dKKQKBgQCKTLKYv0c1h2e5i4mNCGWhR83x+k1ChZZLwoEC9f65tjrbOG0UEHAn
+oz9N0m6jCQvnzvN8cHgFl8yoWmnOjEnsSDFQlIRvAXGzHd4ahMB+75WbLi31H2bv
+XvZyakeTVfoOVArNUwLSHozr0VIUjnRirLht939dlFj4FLih/igWFA==
 -----END RSA PRIVATE KEY-----
diff --git a/testing/tests/ipv6/rw-rfc3779-ikev2/hosts/dave/etc/ipsec.d/certs/daveCert.pem b/testing/tests/ipv6/rw-rfc3779-ikev2/hosts/dave/etc/ipsec.d/certs/daveCert.pem
index dffbc67..88ce01e 100644
--- a/testing/tests/ipv6/rw-rfc3779-ikev2/hosts/dave/etc/ipsec.d/certs/daveCert.pem
+++ b/testing/tests/ipv6/rw-rfc3779-ikev2/hosts/dave/etc/ipsec.d/certs/daveCert.pem
@@ -1,27 +1,27 @@
 -----BEGIN CERTIFICATE-----
-MIIEoDCCA4igAwIBAgIBBDANBgkqhkiG9w0BAQsFADBaMQswCQYDVQQGEwJDSDEZ
+MIIEoDCCA4igAwIBAgIBCDANBgkqhkiG9w0BAQsFADBaMQswCQYDVQQGEwJDSDEZ
 MBcGA1UEChMQTGludXggc3Ryb25nU3dhbjEQMA4GA1UECxMHUkZDMzc3OTEeMBwG
-A1UEAxMVc3Ryb25nU3dhbiBSRkMzNzc5IENBMB4XDTA5MTIyMzEzMzczNloXDTE0
-MTIyMjEzMzczNlowWDELMAkGA1UEBhMCQ0gxGTAXBgNVBAoTEExpbnV4IHN0cm9u
+A1UEAxMVc3Ryb25nU3dhbiBSRkMzNzc5IENBMB4XDTE0MTIyNzA4NTQ1N1oXDTE5
+MTIyMTA4NTQ1N1owWDELMAkGA1UEBhMCQ0gxGTAXBgNVBAoTEExpbnV4IHN0cm9u
 Z1N3YW4xEDAOBgNVBAsTB1JGQzM3NzkxHDAaBgNVBAMUE2RhdmVAc3Ryb25nc3dh
-bi5vcmcwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDPLwvUPUNIZnbX
-eyz8U0COp5RM7ZLFT2iJmSGxznZ30phUNHSy3WX9V8h2kQ2fBks2x0KYWEg8Lh2y
-ggZipePRpuHRnZlcll5/HY/YOUgdV2GE6euNiWKcDB6uE51sxZ+on5KasI9EJMdp
-hJpytYUFjx6pExsoqWMQLigrT6A4bYogkweOZHiUyHiqgtUQcHnmmKwxgeUAkZCb
-00dk7CYnXNQZ1uHj/08TDwrS37SGXfWEIcBGEx/awqlF+s2HTI6zw7NC2HhQsiSp
-Yo1nz8TBr/8XnO9KyYUg04TMkcQqBFDt/qiUswLRLapn9HSyd43BxaF+YuvJ1+ip
-M4G05K1nAgMBAAGjggFxMIIBbTAJBgNVHRMEAjAAMAsGA1UdDwQEAwIDqDAdBgNV
-HQ4EFgQUJ/+79KP+Ea9vdAIMkUYx++cu6R0wgYwGA1UdIwSBhDCBgYAUIX+n6zfQ
+bi5vcmcwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDpJKRQ2CEG39rO
+8nX7RpY+Ed5tyx+rkug3HrSInie+fgkDnLES2U1X3wvM2OczLp6L1ccROv+SzEW+
+OKfCZSz7T4GLwaRodi9KtHvfOCsbDx/vkFFwui2yt9rVUSpcbk1OiVQsA9R0G6vz
+eqFIL9GtrtHWQ+dkvWy61i2A+T1X2QfhVfzvj5msL3CuZU6fnwGYD4LZz8RUGlB4
+WkSFWCctfQfgK+lpfuzq6OFFkARzxZ55D0MzgAvXY6osS8gMdiSD50Zlik7qZVvn
+RO0j6TOg0WKinzguAokAyDCsaoqsOvi27QalfH48PUM+aUzHNCKnD6pswebHou3m
+mvG3rH+9AgMBAAGjggFxMIIBbTAJBgNVHRMEAjAAMAsGA1UdDwQEAwIDqDAdBgNV
+HQ4EFgQUsBjPeVTm7TUTaXtmfv09yQS2mV8wgYwGA1UdIwSBhDCBgYAUIX+n6zfQ
 owsfodxCBh4RXzzSEBShXqRcMFoxCzAJBgNVBAYTAkNIMRkwFwYDVQQKExBMaW51
 eCBzdHJvbmdTd2FuMRAwDgYDVQQLEwdSRkMzNzc5MR4wHAYDVQQDExVzdHJvbmdT
 d2FuIFJGQzM3NzkgQ0GCCQDyr+ZHsk6LRjAeBgNVHREEFzAVgRNkYXZlQHN0cm9u
 Z3N3YW4ub3JnMEEGA1UdHwQ6MDgwNqA0oDKGMGh0dHA6Ly9jcmwuc3Ryb25nc3dh
 bi5vcmcvc3Ryb25nc3dhbl9yZmMzNzc5LmNybDBCBggrBgEFBQcBBwEB/wQzMDEw
 FAQCAAEwDgMFAAoDAAIDBQDAqADIMBkEAgACMBMDEQD+wAAAAAAAAAAAAAAAAAAg
-MA0GCSqGSIb3DQEBCwUAA4IBAQBlOlqceKqgr0putV9fUf2vekg5QtZGDtHFUOTH
-0gDIe2DJ60bWY5IXpjj2KtzRdoP448fpPaprrh8VEljWoVvAF8LaePKGggqwcG+D
-Z7ioDYlnV1j+/NnbZGM/hPqa841dh5jesTuTAF2giMod6P6eMiiRcnl9X3ltgSWp
-Ahk5C8CNYw+sISJcCHtFQHdKOM4QN7wAWksvpjMWkSDQgf/rnDUgW8DXAwX/9K4V
-G2etJ6/8drpjB115p6h+GYz8xFG28/MSf9BqNX03dBs5oyko2+FgSrb3ACK+pAO4
-Cpi2NKZfUH+M7Loo4baI+f5iavpDjDfar8KTiV610DAp0W2S
+MA0GCSqGSIb3DQEBCwUAA4IBAQCNyAyUvqeCgWnPEMkfFFb1kBbd3me3aLRxXFb4
+TY44L6SBiFNy1s3UyFCLw1xXnSMgTpvZqHmB7fnzX7Aj6BNkPFIThEiHYN85ai4t
+U9bO2nqwXfIINFt2Qlokd0QWHzDsL/o9Mmqs38ymlfIbsgwh7gCZ2HhGlOb7+QNU
+IaDVIcKqBr07wX7qO/fEjKgFSkUT5eFNwQmyT3zUaE1PixK5w1hRxvs/KAsLgbfe
+5ofLD88rfxvkqLwhRNU8PUzqIpqxfV1P+wS/k78z0tG+JI8yeEkcksuj9UOzlTr2
+jWL1QoxUEinR3N4dTqsW4u/Jz7R4MHdO+l9RoYZpQA8LV8s3
 -----END CERTIFICATE-----
diff --git a/testing/tests/ipv6/rw-rfc3779-ikev2/hosts/dave/etc/ipsec.d/private/daveKey.pem b/testing/tests/ipv6/rw-rfc3779-ikev2/hosts/dave/etc/ipsec.d/private/daveKey.pem
index e79cbdd..f72970c 100644
--- a/testing/tests/ipv6/rw-rfc3779-ikev2/hosts/dave/etc/ipsec.d/private/daveKey.pem
+++ b/testing/tests/ipv6/rw-rfc3779-ikev2/hosts/dave/etc/ipsec.d/private/daveKey.pem
@@ -1,27 +1,27 @@
 -----BEGIN RSA PRIVATE KEY-----
-MIIEpAIBAAKCAQEAzy8L1D1DSGZ213ss/FNAjqeUTO2SxU9oiZkhsc52d9KYVDR0
-st1l/VfIdpENnwZLNsdCmFhIPC4dsoIGYqXj0abh0Z2ZXJZefx2P2DlIHVdhhOnr
-jYlinAwerhOdbMWfqJ+SmrCPRCTHaYSacrWFBY8eqRMbKKljEC4oK0+gOG2KIJMH
-jmR4lMh4qoLVEHB55pisMYHlAJGQm9NHZOwmJ1zUGdbh4/9PEw8K0t+0hl31hCHA
-RhMf2sKpRfrNh0yOs8OzQth4ULIkqWKNZ8/Ewa//F5zvSsmFINOEzJHEKgRQ7f6o
-lLMC0S2qZ/R0sneNwcWhfmLrydfoqTOBtOStZwIDAQABAoIBAQCW49qnnl6MMiPH
-V6wxsKhJvP6i8Dt+fBDUdbQ2fPmG1teeK/357ojC89XJlGbpNHo+0OxNa65gNe3m
-/g+MdOjw3auFMFRrPBBiX7NNdJpy1Brv5DVrhW1N3P3TJfH3MA7RjjYFdyVAKdEZ
-pjud41mX7N4VoRacjJDbTeJveLRlowB2gPcxhNZlF6gPP1ZaHwR/b1+0qOTcsxj3
-hqC7zdmMM8UGQ38S3ba7dldlCVAvJgylRX+LPTx5x32wMntaSmBy0cdRqfHtznij
-MZQnJiUuAvlQyjCbt0j7jycBZrMfgS+hESHaUG7wdJUraL40hlX2L4RfIyMtriwB
-9Xe5fVABAoGBAP3Bphf6k/QxbCrVyyw3Q13MMug63bj3mqhjwOJUoEu+3O4+5Qcw
-bIKEOxDFy82lwVHEnYU2tyxVcLBoXP0kMVkrWQIuDSPrneSQxIO1npBZTvBIvWSr
-Yh3kJa15zlF4JxljwXfjLskInRlL45gBiG8FbSuDtXTxPJBtlrIHE0lnAoGBANED
-/Ct5cocPPTYDGq7FxkGEOFoZM1OTsnL68NmcOhp69uWOAgNCIZEifYBz/SSx1ISJ
-QjDdie3BQ0zp2CZe5Fujtz0oT4VPsrJUcND6fZnG79aA2P2S4tXOdVbElB4fOWuT
-Sd1WOmgOFAn+B907PsP2BEh2BPO2/eqy3hN38PwBAoGAZzAJ9JJG+/PlAn4xwmcu
-k8Pnp5vYcdDuKS93ThIPpP2WJaOZypSca26N/kIQoC2ZMUD8tSEM15Be5L1rotzG
-3HXOGh7T5Rl4+WsNHmoKcrR+byOFMJyop3MRBzwS8/oiHCb+k1vkuIcyKwk7IaLt
-8geI3zsN3OIEOM73iqlp5F0CgYBbSWFGX4l8oVQ7lcl+kZRQIv41o5H+K6ChhSXR
-9OCPlirlAUuxvp1IdQbZJk9mSmCl7gjBrNBDzcel/O/RelpEB9HM3SE1+SPzrNuE
-+hIHKpKvXaDnxtJZTQ2EcuC58ysx56c4CyQBNDzeTFuE7Q4xqe4e86SgCMkHS02g
-tR7EAQKBgQCRoTsOFcCK2jXBhfcuwcrnrTJmf6LFxW08Mfl9qxKUjz20bx6jgv7f
-TrRUHavmVrrGkAc6eTtoa+2cC5ffSBWHeCD48omb+DZGPF54UbEYyRUb5umKbfI3
-M3WiHTTpeTOx2MmPwiAHhPuaWMV9jWkRG01+wIX4HybGYeEAVHE9lg==
+MIIEpAIBAAKCAQEA6SSkUNghBt/azvJ1+0aWPhHebcsfq5LoNx60iJ4nvn4JA5yx
+EtlNV98LzNjnMy6ei9XHETr/ksxFvjinwmUs+0+Bi8GkaHYvSrR73zgrGw8f75BR
+cLotsrfa1VEqXG5NTolULAPUdBur83qhSC/Rra7R1kPnZL1sutYtgPk9V9kH4VX8
+74+ZrC9wrmVOn58BmA+C2c/EVBpQeFpEhVgnLX0H4CvpaX7s6ujhRZAEc8WeeQ9D
+M4AL12OqLEvIDHYkg+dGZYpO6mVb50TtI+kzoNFiop84LgKJAMgwrGqKrDr4tu0G
+pXx+PD1DPmlMxzQipw+qbMHmx6Lt5prxt6x/vQIDAQABAoIBAB6pVf7X3cgUqqcq
+1f9c8idpnDIeU6Tx5h5RqHaLLjjsRG04L0WGVJio2dlv8UAW8nz7eXm3o6L/wHBa
+7R0wxzCp7SSfK+sdF+0gPWZG8cxWOeH8vekwYxAtA9eoHAUZ8IrSnsJHIqq+dOfJ
+iep/d3j7E9e1CHqEOwd7YXKj1MB3p0Ivhyx0k9GvlbAKRiJPGhbxD+hu86lRMsEt
+su6eG5JlvKyBAgNIcx29UITj5k8MbK2MeuCIZfry0yOaOsGkQkjAtyaiTIw8g2IQ
+AhuuCLqVYtkpMiIfryV74b+CtQMQoU0z2Z74SZ4hJWFlbeG4Vtzq1HeDf4y1S3mm
+B1Mx7CECgYEA9IKw6Fh7SBmJa5jPw7Uttvm2iDslsOR3nrPNOfMWwSK3i0j4OCIE
+kCqKnJJfj2JeBupfHrIJzJ2+otGauxQt3I65VOo0PwQBb90xIHAiXdsYoXadB6MC
+XUo0zKrDWC0EVyVwN+nyaCJVwsKm4XomHgSvitUSNA0dSTATfPXwQJkCgYEA9Bk1
+VN2KG6Bjcm2ISls+OOKgp2kG68ayG4ZXg+xt06+qsYq0+BwCrottQpXFpMVJbE/z
+/6U294PBqJ9Z7LATptMzWhTKyO0pGBHvy8LUz/3qBF7yJFN2s+QbmKf4RIhfSDNU
+CD2bPI17Kgj3sipEcbiwz9U6wpzp+IDnAfPdWsUCgYBl/5ri4f5TnmuIGhAZuRvf
+552wiNP5TeVkq+bh1LlaSiw9C2yYpgA3T7fRBvKcMtG8msqhWG3kEK305/FfN1TG
+XDeN58FxxC8BRkl3GbAMbRiCSqPJCsQyvID4HAgvYWAdJn4ApTQ9Io2aGG9bQgRi
+o1vDU40rb4kW/dozV7koiQKBgQDoQgwiweElREkbmejyhzr/OXQPlrmFIjxaQEuJ
+NS+TGjTaVda3tT9AAV5m2seCbk3ch37tIrDYdj+QSH9x3F/2fkMAVYRWBoLxai+2
+u51ugnVmz0irE9eAd21ipYBvBStUMbKlXKkWxrAIYRv+JIWXh1qFhqgwgMmHMG+d
+xgI62QKBgQC2WYhZvLGrJ5g9G8E9pqOAz0FlxBqbPXJDe9n4Il8huF/+i678covC
+dtbo1il8qcs0Lmm8M6vj78Meh+k4L0y7YAjUsaLpQ9rwNaZMHP+GyZWE5ygmtNhE
+DP13WKX5SEbDZbClEgX+gHRmywC5m6hDSx21iekhbTfnUm2FQTA83w==
 -----END RSA PRIVATE KEY-----
diff --git a/testing/tests/ipv6/rw-rfc3779-ikev2/hosts/moon/etc/ipsec.d/certs/moonCert.pem b/testing/tests/ipv6/rw-rfc3779-ikev2/hosts/moon/etc/ipsec.d/certs/moonCert.pem
index 7f5f8d7..124e2ae 100644
--- a/testing/tests/ipv6/rw-rfc3779-ikev2/hosts/moon/etc/ipsec.d/certs/moonCert.pem
+++ b/testing/tests/ipv6/rw-rfc3779-ikev2/hosts/moon/etc/ipsec.d/certs/moonCert.pem
@@ -1,28 +1,28 @@
 -----BEGIN CERTIFICATE-----
-MIIEuDCCA6CgAwIBAgIBATANBgkqhkiG9w0BAQsFADBaMQswCQYDVQQGEwJDSDEZ
+MIIEuDCCA6CgAwIBAgIBBTANBgkqhkiG9w0BAQsFADBaMQswCQYDVQQGEwJDSDEZ
 MBcGA1UEChMQTGludXggc3Ryb25nU3dhbjEQMA4GA1UECxMHUkZDMzc3OTEeMBwG
-A1UEAxMVc3Ryb25nU3dhbiBSRkMzNzc5IENBMB4XDTA5MTIyMzEzMzM1NloXDTE0
-MTIyMjEzMzM1NlowWDELMAkGA1UEBhMCQ0gxGTAXBgNVBAoTEExpbnV4IHN0cm9u
+A1UEAxMVc3Ryb25nU3dhbiBSRkMzNzc5IENBMB4XDTE0MTIyNzA2NDU0MloXDTE5
+MTIyMTA2NDU0MlowWDELMAkGA1UEBhMCQ0gxGTAXBgNVBAoTEExpbnV4IHN0cm9u
 Z1N3YW4xEDAOBgNVBAsTB1JGQzM3NzkxHDAaBgNVBAMTE21vb24uc3Ryb25nc3dh
-bi5vcmcwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDTKaLLTmKX45Qm
-RjIaBSxBwofzqqkZWtl1mu0cDp6rGWr//hC31OO9MbLeRZBX0UBtuKouceAjdrwG
-aK7ChR0Ft+qlLZ6Z9BH2Dna4vTdESsB3Sn+uXuU4WNdwmmJuRBXfl/7h/Rt+34Cs
-BP82/RtR4GVpS7u73iSLlN4RaeWdySTqhtYH4cKt1H9MiSbwwomwdLedQo3UoOeU
-lkWPrzFKT3gzU4vHr1sgpbF54o/iBr5/YyJpUT9UVeDTffAEMxnAe8/Q/a3pgSLO
-wJ3HnSvcSH0w8zuH1YXOtfmqsphkwVBJGiLzUHWlYxVIAoCKdrv4eoSJLqlL5b51
-vGkmL83RAgMBAAGjggGJMIIBhTAJBgNVHRMEAjAAMAsGA1UdDwQEAwIDqDAdBgNV
-HQ4EFgQU5zzmRRlKa8+cm1g4RYg4lKNkQz4wgYwGA1UdIwSBhDCBgYAUIX+n6zfQ
+bi5vcmcwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDYeHiAGNal9DT6
+GgCewdXa4Nf/46YgbhZNmSpi/zH+XmA7JLS6eoVt5vJ/LJEHSzkRoEetptAILenu
+uakByawEoPZgkCYZgJB9opGEOoWIwTitaF0ZVV8diNQtnl+rkvwPpxWybvIwOwRA
+PUIenoQPkVhfd/ALaRl88pG0rcAW0MMSCNuQwELwSIK2rQALs94Qm5yM0bZ+dqV2
+jnSISit5doRZ4vIYghJPKPqFKb1zUw1siCDPev43S+xqwTjhJ0zncq/QigySyivd
+D8qs8KMkan+XNx9XSjW14YWp27RVpIeANlikiHh0/St0lBsR+P9sDp+Yvr+U95EK
+KOgrqac3AgMBAAGjggGJMIIBhTAJBgNVHRMEAjAAMAsGA1UdDwQEAwIDqDAdBgNV
+HQ4EFgQUQcvdnqQfLJx2utB9szVLhZCmp84wgYwGA1UdIwSBhDCBgYAUIX+n6zfQ
 owsfodxCBh4RXzzSEBShXqRcMFoxCzAJBgNVBAYTAkNIMRkwFwYDVQQKExBMaW51
 eCBzdHJvbmdTd2FuMRAwDgYDVQQLEwdSRkMzNzc5MR4wHAYDVQQDExVzdHJvbmdT
 d2FuIFJGQzM3NzkgQ0GCCQDyr+ZHsk6LRjAeBgNVHREEFzAVghNtb29uLnN0cm9u
 Z3N3YW4ub3JnMBMGA1UdJQQMMAoGCCsGAQUFBwMBMEEGA1UdHwQ6MDgwNqA0oDKG
 MGh0dHA6Ly9jcmwuc3Ryb25nc3dhbi5vcmcvc3Ryb25nc3dhbl9yZmMzNzc5LmNy
 bDBFBggrBgEFBQcBBwEB/wQ2MDQwEgQCAAEwDAMDAAoBAwUAwKgAATAeBAIAAjAY
-AxEA/sAAAAAAAAAAAAAAAAAAAQMDAP7BMA0GCSqGSIb3DQEBCwUAA4IBAQBVFKeX
-QIH5Zk0dp/7u/V0TKqu5vZ9x6ZrshAZ9nzbLgmSP+++yDXmlQe0D0i2Men4D095S
-smFqw1nMWM5oEPpP58+jhCOHzn7InMp+SRRBkX2j06wT9qbynAHiIun/qcdq13w1
-Fs0PiKVQZbbz72mwl9J3Hkj/JkLtOX00wMPqIFU6veeagGiwOW7KkehFUVqoD9+O
-vgkHnUti2XzgskEGcEWmE1EYv7Qo0OdZB15oNoUV5i8WelfmWO+nz9/QKciATNoC
-kAUVcEV9XY9sSKjazdyG6QfEd3l6lQ+KAt8MnqA89i0yIQ1lg+3Jfe67SMvM1gy6
-Y0Y2hqCja6SsIjVc
+AxEA/sAAAAAAAAAAAAAAAAAAAQMDAP7BMA0GCSqGSIb3DQEBCwUAA4IBAQAi0XQL
+aEHg8aXBiXSTHuvxDieJB3Q83kpXOry16Ij5PKx9cdM2Gtmxz8YkwPEgq0r7vWNo
+830A4CnOJszQyIpY7CIygPj1wy3kFGGPkL7R4p00qSKpCEg8Fq85R4LmiyXIEZ+5
+lUtan7xka4ySMKKocm2rbXHyHXjis8AzU7NZN5QpEMkGLTaQPwHad4FUBFOolNE2
+NLoQ3xp9NPTyqfy1CkCHcyG18yRPciU4m8Cubyb+zBHyBADm9Q0P3++vznsU8LrR
+pzjRqS0e+FD2bzdXH/2g7Ge8+b6xzWRVMxZ8e2f5O9jQUY6q4SicuAX8SM/bgDPu
+Mc/lk4Nl8pHRO+Xm
 -----END CERTIFICATE-----
diff --git a/testing/tests/ipv6/rw-rfc3779-ikev2/hosts/moon/etc/ipsec.d/private/moonKey.pem b/testing/tests/ipv6/rw-rfc3779-ikev2/hosts/moon/etc/ipsec.d/private/moonKey.pem
index 8295f97..11607c8 100644
--- a/testing/tests/ipv6/rw-rfc3779-ikev2/hosts/moon/etc/ipsec.d/private/moonKey.pem
+++ b/testing/tests/ipv6/rw-rfc3779-ikev2/hosts/moon/etc/ipsec.d/private/moonKey.pem
@@ -1,27 +1,27 @@
 -----BEGIN RSA PRIVATE KEY-----
-MIIEpAIBAAKCAQEA0ymiy05il+OUJkYyGgUsQcKH86qpGVrZdZrtHA6eqxlq//4Q
-t9TjvTGy3kWQV9FAbbiqLnHgI3a8BmiuwoUdBbfqpS2emfQR9g52uL03RErAd0p/
-rl7lOFjXcJpibkQV35f+4f0bft+ArAT/Nv0bUeBlaUu7u94ki5TeEWnlnckk6obW
-B+HCrdR/TIkm8MKJsHS3nUKN1KDnlJZFj68xSk94M1OLx69bIKWxeeKP4ga+f2Mi
-aVE/VFXg033wBDMZwHvP0P2t6YEizsCdx50r3Eh9MPM7h9WFzrX5qrKYZMFQSRoi
-81B1pWMVSAKAina7+HqEiS6pS+W+dbxpJi/N0QIDAQABAoIBAQCSHbx1XB8jJSot
-teMTWEMAmgCDHrN2RQQ2ueaaxI8MrED7NK4S1rBkCVDRN2ejLLudcOvpyYikYZPI
-B4XuOjgT7ejjNYcK1vXawrVqLhxhGCzIHvftC+MnM2qYk2vLCzfriXyomgD9sOCT
-p72GKmxOIq1pyCr228eEApYLjLCDlhso3PrCo7recUq7f56rLjvb4gfcfor6mJUd
-yIppZUnDFJnsRXup1G4L9Y9RNYtlkcDqem/Q49d5+AHCYH6R8YI0Iz3JnzZjalsq
-+IA6RJqHBTeOpiyCmHlUmVE/3YUm8n7w7RRngMOLjKdiTKHT+8EcHmyUorqW3Yea
-zCIe5C6FAoGBAO23egrSbamyWXcIOqx1GX9gzYmQ2nSKYUtRhsE8eNErw0zp4FKv
-AA7CAmoWEzjDJPSkUzDAajoZiH8+DIZ4IkwKbYjtq0vr1yCbx/PBKVN/JHGZ/Ao/
-dc/lQrNseza34NBrREN/gUytjefFMJ4YStSZCMuy3gP1Fqk6YCy/dObbAoGBAONn
-UqjmZYqoK0+jnGWdPOtXZ4bu8UoHc8/1MaVn3pq8bYh3PayFKpDKtcD1ZeXHCxL2
-1Y+Eid/DoZ2/RZbxT2mhi2mVZZCWc0xuML3Vz0B9bqi3ZfRLVP2u87fn//mGrD+9
-yy9PeIBv8UvjOhev6hZDBhPAVMsyjiw+wSX6kW/DAoGBAMBcrbSeLcGZok3xadFu
-fPCXvBtrDWwrIqpZUauDLN1PBZ5yz2T5WhmXI28HaAyR1ZDmfK9BtXRIfy1AX9Bc
-3JweAB9C/E/Wi+JGTVrR34hCpZIMImmEiuhtxDj/OwG/cHwXoUjhoBcVhnScHEiC
-reM152k21/Pp26mbpIHxeD7rAoGAaRy4S5P7uaTUKEKzJxEQOKQ1GVzXMWXSdXyb
-zx38+j9AzgR4AIepTjY03xVPXW+swb5Qpr8Xz9Oon7bq3sN59pSSUWKaCMRSVTDV
-3Nm4q9GO1fO377zmc0BsLUTSwC8s7WW4Ro0QYSXdPjuw/YP1ywZ+B6EuUKJ0ryTu
-uLRih2sCgYBm15N97b7Rp+aAti045iBla9/KH8z7szczIndpFWR4wjaI9tt0i9GR
-OZs7LFq0MYdg8JiXITyVcuqsUbdAP3TvsXGDHdatbDcrXM/DYuP6dPqMuGBKdnEn
-gIFT1z8mhv4Im3JKpuckMrIQ5vWhljcRZgiEJYZfEAkLJo7ePG2VzA==
+MIIEowIBAAKCAQEA2Hh4gBjWpfQ0+hoAnsHV2uDX/+OmIG4WTZkqYv8x/l5gOyS0
+unqFbebyfyyRB0s5EaBHrabQCC3p7rmpAcmsBKD2YJAmGYCQfaKRhDqFiME4rWhd
+GVVfHYjULZ5fq5L8D6cVsm7yMDsEQD1CHp6ED5FYX3fwC2kZfPKRtK3AFtDDEgjb
+kMBC8EiCtq0AC7PeEJucjNG2fnaldo50iEoreXaEWeLyGIISTyj6hSm9c1MNbIgg
+z3r+N0vsasE44SdM53Kv0IoMksor3Q/KrPCjJGp/lzcfV0o1teGFqdu0VaSHgDZY
+pIh4dP0rdJQbEfj/bA6fmL6/lPeRCijoK6mnNwIDAQABAoIBAAutG9rU/CcBcCYZ
+ZvUpQW7H9/6uedR/+6X94AJs/3ZYAtrN1Q3F9BKEhYoEjmIVVaO0wIkGWWxHhbnB
+u/MDvMqXIBL/U37Gp4SPU0gNnAxPV85KtdLa/wFp0wAO7dwkVoJFoe74+wlM9aK9
+ayaZqEfqsBieMI19Asnxj5huUtEoIiU9ekz6HLeALwy6OxJLrempDugDe2icaWSt
+pLIU3ZXmzVbOFLNtq+KMpanQzamAvSTUq5Wmuz+C6nTEv+JjGWFblX8pM2ACA6cV
+VouefUFfKpMXjHTlsvw0JiDzLeYRxRZZMxnTxzbnoigZfW6ZDxP2w9KRv/7LuSj/
+ktqfVKkCgYEA8qlkPka0cfIKcjloe6oNEMt0dX6V+5LmS59DRnnhu+6FuIVncS7/
+intBGag603wJvGlA7HuUAZbcr4ilDIe1cUm0d8rftjvw0uOBU/gfNVmxhpFzs8Ku
+4Fry6lKow1ecqFQ1i4VZi2qQJVv3m6tRojMTh6xVA9/FLD9iiu3V2dMCgYEA5F6I
+HV1sqY2Q8aU48dch+I1ItrqiURwY7qejuIprpXBoRQPQV3OoYgJcKtdlSKrbDGQd
+iJmL0aoy/ONThrfOtygQtth/f79ktKZZHja8Ew+0/lzfxMSb69kl6Rxx9OKJILPE
+caezhYFGozEKwLddcrqxrSd3Fvz78CVRRiAx2o0CgYEA4g0wh98f24Hpf0zBa2oX
+b8zIOWfp2giXply/tBh4U7S4NxN3MHXisaNuGrOf0UEcZLr8MxBP6UcbYB3/+vM0
+8EsD5hBEZKPkDODIqmtazz015jD7QrsaY3/2CJlmA0tLcXe4xbc8mmZzz4mj2Q04
+J8xC5kGAlPJQ4I5PgzJZ4+cCgYAHyqHiPpnCfy3+0KBMwAZMsKVWdq+rDMZc/iM7
+3J0nm9oy4JpvIWcRUPtMCuVNwWaP2aqYSoTWtnPe5PKomgTXgupvEpvnA+SvtS09
+NqjcDaEjPI/16q9XMKV2ep34uPHsx7VgG1SorWx3jOjNAnSRwYTmX35UrnT6EIvh
+VJ/e0QKBgCgI41QtJ4ShFxpSdxzy3Gfz/EFTUGIjtmXQe/7GixxoXJkpGXCGhToU
+KVF+HUEYKOQ1vX9SNUyY+1LyqO3vj+QzuJ0q4GrtEY7vxDH817QvJLecj5i22Hof
+50MqUdow2BnOSFuJvWhR1DdodRX3vh1awod/CoIufnfEI4MuMO6H
 -----END RSA PRIVATE KEY-----
diff --git a/testing/tests/libipsec/host2host-cert/hosts/moon/etc/updown b/testing/tests/libipsec/host2host-cert/hosts/moon/etc/updown
index aea6d85..7c51026 100755
--- a/testing/tests/libipsec/host2host-cert/hosts/moon/etc/updown
+++ b/testing/tests/libipsec/host2host-cert/hosts/moon/etc/updown
@@ -1,5 +1,5 @@
-#! /bin/sh
-# iproute2 version, default updown script
+#!/bin/sh
+# default updown script
 #
 # Copyright (C) 2003-2004 Nigel Meteringham
 # Copyright (C) 2003-2004 Tuomo Soini
@@ -22,8 +22,6 @@
 # that, and use the (left/right)updown parameters in ipsec.conf to make
 # strongSwan use yours instead of this default one.
 
-# things that this script gets (from ipsec_pluto(8) man page)
-#
 #      PLUTO_VERSION
 #              indicates  what  version of this interface is being
 #              used.  This document describes version  1.1.   This
@@ -41,15 +39,17 @@
 #              is the name of the  connection  for  which  we  are
 #              routing.
 #
-#       PLUTO_NEXT_HOP
-#              is the next hop to which packets bound for the peer
-#              must be sent.
-#
 #       PLUTO_INTERFACE
 #              is the name of the ipsec interface to be used.
 #
 #       PLUTO_REQID
-#              is the requid of the ESP policy
+#              is the requid of the AH|ESP policy
+#
+#       PLUTO_PROTO
+#              is the negotiated IPsec protocol, ah|esp
+#
+#       PLUTO_IPCOMP
+#              is not empty if IPComp was negotiated
 #
 #       PLUTO_UNIQUEID
 #              is the unique identifier of the associated IKE_SA
@@ -66,15 +66,6 @@
 #              host's own IP address / max (where max  is  32  for
 #              IPv4 and 128 for IPv6).
 #
-#       PLUTO_MY_CLIENT_NET
-#              is the IP address of our client net.  If the client
-#              is just the host, this will be the  host's  own  IP
-#              address.
-#
-#       PLUTO_MY_CLIENT_MASK
-#              is  the  mask for our client net.  If the client is
-#              just the host, this will be 255.255.255.255.
-#
 #       PLUTO_MY_SOURCEIP
 #       PLUTO_MY_SOURCEIP4_$i
 #       PLUTO_MY_SOURCEIP6_$i
@@ -88,7 +79,8 @@
 #
 #       PLUTO_MY_PORT
 #              is  the  UDP/TCP  port  to  which  the IPsec SA  is
-#              restricted on our side.
+#              restricted on our side.  For ICMP/ICMPv6 this contains the
+#              message type, and PLUTO_PEER_PORT the message code.
 #
 #       PLUTO_PEER
 #              is the IP address of our peer.
@@ -96,31 +88,19 @@
 #       PLUTO_PEER_ID
 #              is the ID of our peer.
 #
-#       PLUTO_PEER_CA
-#              is the CA which issued the cert of our peer.
-#
 #       PLUTO_PEER_CLIENT
 #              is the IP address / count of the peer's client sub-
 #              net.   If the client is just the peer, this will be
 #              the peer's own IP address / max (where  max  is  32
 #              for IPv4 and 128 for IPv6).
 #
-#       PLUTO_PEER_CLIENT_NET
-#              is the IP address of the peer's client net.  If the
-#              client is just the peer, this will  be  the  peer's
-#              own IP address.
-#
-#       PLUTO_PEER_CLIENT_MASK
-#              is  the  mask  for  the  peer's client net.  If the
-#              client   is   just   the   peer,   this   will   be
-#              255.255.255.255.
-#
 #       PLUTO_PEER_PROTOCOL
 #              is the IP protocol that will be transported.
 #
 #       PLUTO_PEER_PORT
 #              is  the  UDP/TCP  port  to  which  the IPsec SA  is
-#              restricted on the peer side.
+#              restricted on the peer side.  For ICMP/ICMPv6 this contains the
+#              message code, and PLUTO_MY_PORT the message type.
 #
 #       PLUTO_XAUTH_ID
 #              is an optional user ID employed by the XAUTH protocol
@@ -146,7 +126,7 @@
 PATH="/sbin:/bin:/usr/sbin:/usr/bin:/usr/sbin"
 export PATH
 
-# uncomment to log VPN connections
+# comment to disable logging VPN connections to syslog
 VPN_LOGGING=1
 #
 # tag put in front of each log entry:
@@ -160,21 +140,11 @@ FAC_PRIO=local0.notice
 #
 # local0.notice                   -/var/log/vpn
 
-# in order to use source IP routing the Linux kernel options
-# CONFIG_IP_ADVANCED_ROUTER and CONFIG_IP_MULTIPLE_TABLES
-# must be enabled
-#
-# special routing table for sourceip routes
-SOURCEIP_ROUTING_TABLE=220
-#
-# priority of the sourceip routing table
-SOURCEIP_ROUTING_TABLE_PRIO=220
-
 # check interface version
 case "$PLUTO_VERSION" in
-1.[0|1])	# Older Pluto?!?  Play it safe, script may be using new features.
+1.[0|1])	# Older release?!?  Play it safe, script may be using new features.
 	echo "$0: obsolete interface version \`$PLUTO_VERSION'," >&2
-	echo "$0: 	called by obsolete Pluto?" >&2
+	echo "$0: 	called by obsolete release?" >&2
 	exit 2
 	;;
 1.*)	;;
@@ -196,190 +166,52 @@ custom:*)		# custom parameters (see above CAUTION comment)
 	;;
 esac
 
-# utility functions for route manipulation
-# Meddling with this stuff should not be necessary and requires great care.
-uproute() {
-	doroute add
-	ip route flush cache
-}
-downroute() {
-	doroute delete
-	ip route flush cache
-}
-
-addsource() {
-	st=0
-	if ! ip -o route get ${PLUTO_MY_SOURCEIP%/*} | grep -q ^local
-	then
-	    it="ip addr add ${PLUTO_MY_SOURCEIP%/*}/32 dev $PLUTO_INTERFACE"
-	    oops="`eval $it 2>&1`"
-	    st=$?
-	    if test " $oops" = " " -a " $st" != " 0"
-	    then
-		oops="silent error, exit status $st"
-	    fi
-	    if test " $oops" != " " -o " $st" != " 0"
-	    then
-		echo "$0: addsource \`$it' failed ($oops)" >&2
-	    fi
-	fi
-	return $st
-}
-
-doroute() {
-	st=0
-
-	if [ -z "$PLUTO_MY_SOURCEIP" ]
-	then
-	    for dir in /etc/sysconfig /etc/conf.d; do
-		if [ -f "$dir/defaultsource" ]
-		then
-		    . "$dir/defaultsource"
-		fi
-	    done
-
-	    if [ -n "$DEFAULTSOURCE" ]
-	    then
-		PLUTO_MY_SOURCEIP=$DEFAULTSOURCE
-	    fi
-        fi
-
-	if [ -z "$KLIPS" -a -z "$PLUTO_MY_SOURCEIP" ]
-	then
-	    # leave because no route entry is required
-	    return $st
-	fi
-
-	parms1="$PLUTO_PEER_CLIENT"
-
-	if [ -n "$PLUTO_NEXT_HOP" ]
-	then
-	    parms2="via $PLUTO_NEXT_HOP"
-	else
-	    parms2="via $PLUTO_PEER"
-	fi
-	parms2="$parms2 dev $PLUTO_INTERFACE"
-
-	parms3=
-	if [ -n "$PLUTO_MY_SOURCEIP" ]
-	then
-	    if test "$1" = "add"
-	    then
-		addsource
-		if ! ip rule list | grep -q "lookup $SOURCEIP_ROUTING_TABLE"
-		then
-		    ip rule add pref $SOURCEIP_ROUTING_TABLE_PRIO table $SOURCEIP_ROUTING_TABLE
-		fi
-	    fi
-	    parms3="$parms3 src ${PLUTO_MY_SOURCEIP%/*} table $SOURCEIP_ROUTING_TABLE"
-	fi
+IPSEC_POLICY="-m policy --pol ipsec --proto $PLUTO_PROTO --reqid $PLUTO_REQID"
+IPSEC_POLICY_IN="$IPSEC_POLICY --dir in"
+IPSEC_POLICY_OUT="$IPSEC_POLICY --dir out"
 
-	case "$PLUTO_PEER_CLIENT_NET/$PLUTO_PEER_CLIENT_MASK" in
-	"0.0.0.0/0.0.0.0")
-		# opportunistic encryption work around
-		# need to provide route that eclipses default, without
-		# replacing it.
-		it="ip route $1 0.0.0.0/1 $parms2 $parms3 &&
-			ip route $1 128.0.0.0/1 $parms2 $parms3"
-		;;
-	*)	it="ip route $1 $parms1 $parms2 $parms3"
-		;;
-	esac
-	oops="`eval $it 2>&1`"
-	st=$?
-	if test " $oops" = " " -a " $st" != " 0"
-	then
-	    oops="silent error, exit status $st"
-	fi
-	if test " $oops" != " " -o " $st" != " 0"
-	then
-	    echo "$0: doroute \`$it' failed ($oops)" >&2
-	fi
-	return $st
-}
-
-# in the presence of KLIPS and ipsecN interfaces do not use IPSEC_POLICY
-if [ `echo "$PLUTO_INTERFACE" | grep "ipsec"` ]
-then
-	KLIPS=1
-	IPSEC_POLICY_IN=""
-	IPSEC_POLICY_OUT=""
-else
-	KLIPS=
-	IPSEC_POLICY="-m policy --pol ipsec --proto esp --reqid $PLUTO_REQID"
-	IPSEC_POLICY_IN="$IPSEC_POLICY --dir in"
-	IPSEC_POLICY_OUT="$IPSEC_POLICY --dir out"
-fi
+# use protocol specific options to set ports
+case "$PLUTO_MY_PROTOCOL" in
+1)	# ICMP
+	ICMP_TYPE_OPTION="--icmp-type"
+	;;
+58)	# ICMPv6
+	ICMP_TYPE_OPTION="--icmpv6-type"
+	;;
+*)
+	;;
+esac
 
 # are there port numbers?
 if [ "$PLUTO_MY_PORT" != 0 ]
 then
-	S_MY_PORT="--sport $PLUTO_MY_PORT"
-	D_MY_PORT="--dport $PLUTO_MY_PORT"
+	if [ -n "$ICMP_TYPE_OPTION" ]
+	then
+		S_MY_PORT="$ICMP_TYPE_OPTION $PLUTO_MY_PORT"
+		D_MY_PORT="$ICMP_TYPE_OPTION $PLUTO_MY_PORT"
+	else
+		S_MY_PORT="--sport $PLUTO_MY_PORT"
+		D_MY_PORT="--dport $PLUTO_MY_PORT"
+	fi
 fi
 if [ "$PLUTO_PEER_PORT" != 0 ]
 then
-	S_PEER_PORT="--sport $PLUTO_PEER_PORT"
-	D_PEER_PORT="--dport $PLUTO_PEER_PORT"
+	if [ -n "$ICMP_TYPE_OPTION" ]
+	then
+		# the syntax is --icmp[v6]-type type[/code], so add it to the existing option
+		S_MY_PORT="$S_MY_PORT/$PLUTO_PEER_PORT"
+		D_MY_PORT="$D_MY_PORT/$PLUTO_PEER_PORT"
+	else
+		S_PEER_PORT="--sport $PLUTO_PEER_PORT"
+		D_PEER_PORT="--dport $PLUTO_PEER_PORT"
+	fi
 fi
 
 # resolve octal escape sequences
 PLUTO_MY_ID=`printf "$PLUTO_MY_ID"`
 PLUTO_PEER_ID=`printf "$PLUTO_PEER_ID"`
 
-# the big choice
 case "$PLUTO_VERB:$1" in
-prepare-host:*|prepare-client:*)
-	if [ -z "$KLIPS" -a -z "$PLUTO_MY_SOURCEIP" ]
-	then
-	    # exit because no route will be added,
-	    # so that existing routes can stay
-	    exit 0
-	fi
-
-	# delete possibly-existing route (preliminary to adding a route)
-	case "$PLUTO_PEER_CLIENT_NET/$PLUTO_PEER_CLIENT_MASK" in
-	"0.0.0.0/0.0.0.0")
-		# need to provide route that eclipses default, without
-		# replacing it.
-		parms1="0.0.0.0/1"
-		parms2="128.0.0.0/1"
-		it="ip route delete $parms1 2>&1 ; ip route delete $parms2 2>&1"
-		oops="`ip route delete $parms1 2>&1 ; ip route delete $parms2 2>&1`"
-		;;
-	*)
-		parms="$PLUTO_PEER_CLIENT"
-		it="ip route delete $parms 2>&1"
-		oops="`ip route delete $parms 2>&1`"
-		;;
-	esac
-	status="$?"
-	if test " $oops" = " " -a " $status" != " 0"
-	then
-		oops="silent error, exit status $status"
-	fi
-	case "$oops" in
-	*'RTNETLINK answers: No such process'*)
-		# This is what route (currently -- not documented!) gives
-		# for "could not find such a route".
-		oops=
-		status=0
-		;;
-	esac
-	if test " $oops" != " " -o " $status" != " 0"
-	then
-		echo "$0: \`$it' failed ($oops)" >&2
-	fi
-	exit $status
-	;;
-route-host:*|route-client:*)
-	# connection to me or my client subnet being routed
-	uproute
-	;;
-unroute-host:*|unroute-client:*)
-	# connection to me or my client subnet being unrouted
-	downroute
-	;;
 up-host:)
 	# connection to me coming up
 	# If you are doing a custom version, firewall commands go here.
@@ -421,6 +253,14 @@ up-host:iptables)
 	    -s $PLUTO_ME $S_MY_PORT $IPSEC_POLICY_OUT \
 	    -d $PLUTO_PEER_CLIENT $D_PEER_PORT -j ACCEPT
 	#
+	# allow IPIP traffic because of the implicit SA created by the kernel if
+	# IPComp is used (for small inbound packets that are not compressed)
+	if [ -n "$PLUTO_IPCOMP" ]
+	then
+	  iptables -I INPUT 1 -i $PLUTO_INTERFACE -p 4 \
+	      -s $PLUTO_PEER -d $PLUTO_ME $IPSEC_POLICY_IN -j ACCEPT
+	fi
+	#
 	# log IPsec host connection setup
 	if [ $VPN_LOGGING ]
 	then
@@ -445,6 +285,13 @@ down-host:iptables)
 	    -s $PLUTO_ME $S_MY_PORT $IPSEC_POLICY_OUT \
 	    -d $PLUTO_PEER_CLIENT $D_PEER_PORT -j ACCEPT
 	#
+	# IPIP exception teardown
+	if [ -n "$PLUTO_IPCOMP" ]
+	then
+	  iptables -D INPUT -i $PLUTO_INTERFACE -p 4 \
+	      -s $PLUTO_PEER -d $PLUTO_ME $IPSEC_POLICY_IN -j ACCEPT
+	fi
+	#
 	# log IPsec host connection teardown
 	if [ $VPN_LOGGING ]
 	then
@@ -484,6 +331,15 @@ up-client:iptables)
 	      -d $PLUTO_PEER_CLIENT $D_PEER_PORT $IPSEC_POLICY_OUT -j ACCEPT
 	fi
 	#
+	# allow IPIP traffic because of the implicit SA created by the kernel if
+	# IPComp is used (for small inbound packets that are not compressed).
+	# INPUT is correct here even for forwarded traffic.
+	if [ -n "$PLUTO_IPCOMP" ]
+	then
+	  iptables -I INPUT 1 -i $PLUTO_INTERFACE -p 4 \
+	      -s $PLUTO_PEER -d $PLUTO_ME $IPSEC_POLICY_IN -j ACCEPT
+	fi
+	#
 	# log IPsec client connection setup
 	if [ $VPN_LOGGING ]
 	then
@@ -527,6 +383,13 @@ down-client:iptables)
 	         $IPSEC_POLICY_OUT -j ACCEPT
 	fi
 	#
+	# IPIP exception teardown
+	if [ -n "$PLUTO_IPCOMP" ]
+	then
+	  iptables -D INPUT -i $PLUTO_INTERFACE -p 4 \
+	      -s $PLUTO_PEER -d $PLUTO_ME $IPSEC_POLICY_IN -j ACCEPT
+	fi
+	#
 	# log IPsec client connection teardown
 	if [ $VPN_LOGGING ]
 	then
@@ -543,16 +406,6 @@ down-client:iptables)
 #
 # IPv6
 #
-prepare-host-v6:*|prepare-client-v6:*)
-	;;
-route-host-v6:*|route-client-v6:*)
-	# connection to me or my client subnet being routed
-	#uproute_v6
-	;;
-unroute-host-v6:*|unroute-client-v6:*)
-	# connection to me or my client subnet being unrouted
-	#downroute_v6
-	;;
 up-host-v6:)
 	# connection to me coming up
 	# If you are doing a custom version, firewall commands go here.
diff --git a/testing/tests/libipsec/host2host-cert/hosts/sun/etc/updown b/testing/tests/libipsec/host2host-cert/hosts/sun/etc/updown
index aea6d85..7c51026 100755
--- a/testing/tests/libipsec/host2host-cert/hosts/sun/etc/updown
+++ b/testing/tests/libipsec/host2host-cert/hosts/sun/etc/updown
@@ -1,5 +1,5 @@
-#! /bin/sh
-# iproute2 version, default updown script
+#!/bin/sh
+# default updown script
 #
 # Copyright (C) 2003-2004 Nigel Meteringham
 # Copyright (C) 2003-2004 Tuomo Soini
@@ -22,8 +22,6 @@
 # that, and use the (left/right)updown parameters in ipsec.conf to make
 # strongSwan use yours instead of this default one.
 
-# things that this script gets (from ipsec_pluto(8) man page)
-#
 #      PLUTO_VERSION
 #              indicates  what  version of this interface is being
 #              used.  This document describes version  1.1.   This
@@ -41,15 +39,17 @@
 #              is the name of the  connection  for  which  we  are
 #              routing.
 #
-#       PLUTO_NEXT_HOP
-#              is the next hop to which packets bound for the peer
-#              must be sent.
-#
 #       PLUTO_INTERFACE
 #              is the name of the ipsec interface to be used.
 #
 #       PLUTO_REQID
-#              is the requid of the ESP policy
+#              is the requid of the AH|ESP policy
+#
+#       PLUTO_PROTO
+#              is the negotiated IPsec protocol, ah|esp
+#
+#       PLUTO_IPCOMP
+#              is not empty if IPComp was negotiated
 #
 #       PLUTO_UNIQUEID
 #              is the unique identifier of the associated IKE_SA
@@ -66,15 +66,6 @@
 #              host's own IP address / max (where max  is  32  for
 #              IPv4 and 128 for IPv6).
 #
-#       PLUTO_MY_CLIENT_NET
-#              is the IP address of our client net.  If the client
-#              is just the host, this will be the  host's  own  IP
-#              address.
-#
-#       PLUTO_MY_CLIENT_MASK
-#              is  the  mask for our client net.  If the client is
-#              just the host, this will be 255.255.255.255.
-#
 #       PLUTO_MY_SOURCEIP
 #       PLUTO_MY_SOURCEIP4_$i
 #       PLUTO_MY_SOURCEIP6_$i
@@ -88,7 +79,8 @@
 #
 #       PLUTO_MY_PORT
 #              is  the  UDP/TCP  port  to  which  the IPsec SA  is
-#              restricted on our side.
+#              restricted on our side.  For ICMP/ICMPv6 this contains the
+#              message type, and PLUTO_PEER_PORT the message code.
 #
 #       PLUTO_PEER
 #              is the IP address of our peer.
@@ -96,31 +88,19 @@
 #       PLUTO_PEER_ID
 #              is the ID of our peer.
 #
-#       PLUTO_PEER_CA
-#              is the CA which issued the cert of our peer.
-#
 #       PLUTO_PEER_CLIENT
 #              is the IP address / count of the peer's client sub-
 #              net.   If the client is just the peer, this will be
 #              the peer's own IP address / max (where  max  is  32
 #              for IPv4 and 128 for IPv6).
 #
-#       PLUTO_PEER_CLIENT_NET
-#              is the IP address of the peer's client net.  If the
-#              client is just the peer, this will  be  the  peer's
-#              own IP address.
-#
-#       PLUTO_PEER_CLIENT_MASK
-#              is  the  mask  for  the  peer's client net.  If the
-#              client   is   just   the   peer,   this   will   be
-#              255.255.255.255.
-#
 #       PLUTO_PEER_PROTOCOL
 #              is the IP protocol that will be transported.
 #
 #       PLUTO_PEER_PORT
 #              is  the  UDP/TCP  port  to  which  the IPsec SA  is
-#              restricted on the peer side.
+#              restricted on the peer side.  For ICMP/ICMPv6 this contains the
+#              message code, and PLUTO_MY_PORT the message type.
 #
 #       PLUTO_XAUTH_ID
 #              is an optional user ID employed by the XAUTH protocol
@@ -146,7 +126,7 @@
 PATH="/sbin:/bin:/usr/sbin:/usr/bin:/usr/sbin"
 export PATH
 
-# uncomment to log VPN connections
+# comment to disable logging VPN connections to syslog
 VPN_LOGGING=1
 #
 # tag put in front of each log entry:
@@ -160,21 +140,11 @@ FAC_PRIO=local0.notice
 #
 # local0.notice                   -/var/log/vpn
 
-# in order to use source IP routing the Linux kernel options
-# CONFIG_IP_ADVANCED_ROUTER and CONFIG_IP_MULTIPLE_TABLES
-# must be enabled
-#
-# special routing table for sourceip routes
-SOURCEIP_ROUTING_TABLE=220
-#
-# priority of the sourceip routing table
-SOURCEIP_ROUTING_TABLE_PRIO=220
-
 # check interface version
 case "$PLUTO_VERSION" in
-1.[0|1])	# Older Pluto?!?  Play it safe, script may be using new features.
+1.[0|1])	# Older release?!?  Play it safe, script may be using new features.
 	echo "$0: obsolete interface version \`$PLUTO_VERSION'," >&2
-	echo "$0: 	called by obsolete Pluto?" >&2
+	echo "$0: 	called by obsolete release?" >&2
 	exit 2
 	;;
 1.*)	;;
@@ -196,190 +166,52 @@ custom:*)		# custom parameters (see above CAUTION comment)
 	;;
 esac
 
-# utility functions for route manipulation
-# Meddling with this stuff should not be necessary and requires great care.
-uproute() {
-	doroute add
-	ip route flush cache
-}
-downroute() {
-	doroute delete
-	ip route flush cache
-}
-
-addsource() {
-	st=0
-	if ! ip -o route get ${PLUTO_MY_SOURCEIP%/*} | grep -q ^local
-	then
-	    it="ip addr add ${PLUTO_MY_SOURCEIP%/*}/32 dev $PLUTO_INTERFACE"
-	    oops="`eval $it 2>&1`"
-	    st=$?
-	    if test " $oops" = " " -a " $st" != " 0"
-	    then
-		oops="silent error, exit status $st"
-	    fi
-	    if test " $oops" != " " -o " $st" != " 0"
-	    then
-		echo "$0: addsource \`$it' failed ($oops)" >&2
-	    fi
-	fi
-	return $st
-}
-
-doroute() {
-	st=0
-
-	if [ -z "$PLUTO_MY_SOURCEIP" ]
-	then
-	    for dir in /etc/sysconfig /etc/conf.d; do
-		if [ -f "$dir/defaultsource" ]
-		then
-		    . "$dir/defaultsource"
-		fi
-	    done
-
-	    if [ -n "$DEFAULTSOURCE" ]
-	    then
-		PLUTO_MY_SOURCEIP=$DEFAULTSOURCE
-	    fi
-        fi
-
-	if [ -z "$KLIPS" -a -z "$PLUTO_MY_SOURCEIP" ]
-	then
-	    # leave because no route entry is required
-	    return $st
-	fi
-
-	parms1="$PLUTO_PEER_CLIENT"
-
-	if [ -n "$PLUTO_NEXT_HOP" ]
-	then
-	    parms2="via $PLUTO_NEXT_HOP"
-	else
-	    parms2="via $PLUTO_PEER"
-	fi
-	parms2="$parms2 dev $PLUTO_INTERFACE"
-
-	parms3=
-	if [ -n "$PLUTO_MY_SOURCEIP" ]
-	then
-	    if test "$1" = "add"
-	    then
-		addsource
-		if ! ip rule list | grep -q "lookup $SOURCEIP_ROUTING_TABLE"
-		then
-		    ip rule add pref $SOURCEIP_ROUTING_TABLE_PRIO table $SOURCEIP_ROUTING_TABLE
-		fi
-	    fi
-	    parms3="$parms3 src ${PLUTO_MY_SOURCEIP%/*} table $SOURCEIP_ROUTING_TABLE"
-	fi
+IPSEC_POLICY="-m policy --pol ipsec --proto $PLUTO_PROTO --reqid $PLUTO_REQID"
+IPSEC_POLICY_IN="$IPSEC_POLICY --dir in"
+IPSEC_POLICY_OUT="$IPSEC_POLICY --dir out"
 
-	case "$PLUTO_PEER_CLIENT_NET/$PLUTO_PEER_CLIENT_MASK" in
-	"0.0.0.0/0.0.0.0")
-		# opportunistic encryption work around
-		# need to provide route that eclipses default, without
-		# replacing it.
-		it="ip route $1 0.0.0.0/1 $parms2 $parms3 &&
-			ip route $1 128.0.0.0/1 $parms2 $parms3"
-		;;
-	*)	it="ip route $1 $parms1 $parms2 $parms3"
-		;;
-	esac
-	oops="`eval $it 2>&1`"
-	st=$?
-	if test " $oops" = " " -a " $st" != " 0"
-	then
-	    oops="silent error, exit status $st"
-	fi
-	if test " $oops" != " " -o " $st" != " 0"
-	then
-	    echo "$0: doroute \`$it' failed ($oops)" >&2
-	fi
-	return $st
-}
-
-# in the presence of KLIPS and ipsecN interfaces do not use IPSEC_POLICY
-if [ `echo "$PLUTO_INTERFACE" | grep "ipsec"` ]
-then
-	KLIPS=1
-	IPSEC_POLICY_IN=""
-	IPSEC_POLICY_OUT=""
-else
-	KLIPS=
-	IPSEC_POLICY="-m policy --pol ipsec --proto esp --reqid $PLUTO_REQID"
-	IPSEC_POLICY_IN="$IPSEC_POLICY --dir in"
-	IPSEC_POLICY_OUT="$IPSEC_POLICY --dir out"
-fi
+# use protocol specific options to set ports
+case "$PLUTO_MY_PROTOCOL" in
+1)	# ICMP
+	ICMP_TYPE_OPTION="--icmp-type"
+	;;
+58)	# ICMPv6
+	ICMP_TYPE_OPTION="--icmpv6-type"
+	;;
+*)
+	;;
+esac
 
 # are there port numbers?
 if [ "$PLUTO_MY_PORT" != 0 ]
 then
-	S_MY_PORT="--sport $PLUTO_MY_PORT"
-	D_MY_PORT="--dport $PLUTO_MY_PORT"
+	if [ -n "$ICMP_TYPE_OPTION" ]
+	then
+		S_MY_PORT="$ICMP_TYPE_OPTION $PLUTO_MY_PORT"
+		D_MY_PORT="$ICMP_TYPE_OPTION $PLUTO_MY_PORT"
+	else
+		S_MY_PORT="--sport $PLUTO_MY_PORT"
+		D_MY_PORT="--dport $PLUTO_MY_PORT"
+	fi
 fi
 if [ "$PLUTO_PEER_PORT" != 0 ]
 then
-	S_PEER_PORT="--sport $PLUTO_PEER_PORT"
-	D_PEER_PORT="--dport $PLUTO_PEER_PORT"
+	if [ -n "$ICMP_TYPE_OPTION" ]
+	then
+		# the syntax is --icmp[v6]-type type[/code], so add it to the existing option
+		S_MY_PORT="$S_MY_PORT/$PLUTO_PEER_PORT"
+		D_MY_PORT="$D_MY_PORT/$PLUTO_PEER_PORT"
+	else
+		S_PEER_PORT="--sport $PLUTO_PEER_PORT"
+		D_PEER_PORT="--dport $PLUTO_PEER_PORT"
+	fi
 fi
 
 # resolve octal escape sequences
 PLUTO_MY_ID=`printf "$PLUTO_MY_ID"`
 PLUTO_PEER_ID=`printf "$PLUTO_PEER_ID"`
 
-# the big choice
 case "$PLUTO_VERB:$1" in
-prepare-host:*|prepare-client:*)
-	if [ -z "$KLIPS" -a -z "$PLUTO_MY_SOURCEIP" ]
-	then
-	    # exit because no route will be added,
-	    # so that existing routes can stay
-	    exit 0
-	fi
-
-	# delete possibly-existing route (preliminary to adding a route)
-	case "$PLUTO_PEER_CLIENT_NET/$PLUTO_PEER_CLIENT_MASK" in
-	"0.0.0.0/0.0.0.0")
-		# need to provide route that eclipses default, without
-		# replacing it.
-		parms1="0.0.0.0/1"
-		parms2="128.0.0.0/1"
-		it="ip route delete $parms1 2>&1 ; ip route delete $parms2 2>&1"
-		oops="`ip route delete $parms1 2>&1 ; ip route delete $parms2 2>&1`"
-		;;
-	*)
-		parms="$PLUTO_PEER_CLIENT"
-		it="ip route delete $parms 2>&1"
-		oops="`ip route delete $parms 2>&1`"
-		;;
-	esac
-	status="$?"
-	if test " $oops" = " " -a " $status" != " 0"
-	then
-		oops="silent error, exit status $status"
-	fi
-	case "$oops" in
-	*'RTNETLINK answers: No such process'*)
-		# This is what route (currently -- not documented!) gives
-		# for "could not find such a route".
-		oops=
-		status=0
-		;;
-	esac
-	if test " $oops" != " " -o " $status" != " 0"
-	then
-		echo "$0: \`$it' failed ($oops)" >&2
-	fi
-	exit $status
-	;;
-route-host:*|route-client:*)
-	# connection to me or my client subnet being routed
-	uproute
-	;;
-unroute-host:*|unroute-client:*)
-	# connection to me or my client subnet being unrouted
-	downroute
-	;;
 up-host:)
 	# connection to me coming up
 	# If you are doing a custom version, firewall commands go here.
@@ -421,6 +253,14 @@ up-host:iptables)
 	    -s $PLUTO_ME $S_MY_PORT $IPSEC_POLICY_OUT \
 	    -d $PLUTO_PEER_CLIENT $D_PEER_PORT -j ACCEPT
 	#
+	# allow IPIP traffic because of the implicit SA created by the kernel if
+	# IPComp is used (for small inbound packets that are not compressed)
+	if [ -n "$PLUTO_IPCOMP" ]
+	then
+	  iptables -I INPUT 1 -i $PLUTO_INTERFACE -p 4 \
+	      -s $PLUTO_PEER -d $PLUTO_ME $IPSEC_POLICY_IN -j ACCEPT
+	fi
+	#
 	# log IPsec host connection setup
 	if [ $VPN_LOGGING ]
 	then
@@ -445,6 +285,13 @@ down-host:iptables)
 	    -s $PLUTO_ME $S_MY_PORT $IPSEC_POLICY_OUT \
 	    -d $PLUTO_PEER_CLIENT $D_PEER_PORT -j ACCEPT
 	#
+	# IPIP exception teardown
+	if [ -n "$PLUTO_IPCOMP" ]
+	then
+	  iptables -D INPUT -i $PLUTO_INTERFACE -p 4 \
+	      -s $PLUTO_PEER -d $PLUTO_ME $IPSEC_POLICY_IN -j ACCEPT
+	fi
+	#
 	# log IPsec host connection teardown
 	if [ $VPN_LOGGING ]
 	then
@@ -484,6 +331,15 @@ up-client:iptables)
 	      -d $PLUTO_PEER_CLIENT $D_PEER_PORT $IPSEC_POLICY_OUT -j ACCEPT
 	fi
 	#
+	# allow IPIP traffic because of the implicit SA created by the kernel if
+	# IPComp is used (for small inbound packets that are not compressed).
+	# INPUT is correct here even for forwarded traffic.
+	if [ -n "$PLUTO_IPCOMP" ]
+	then
+	  iptables -I INPUT 1 -i $PLUTO_INTERFACE -p 4 \
+	      -s $PLUTO_PEER -d $PLUTO_ME $IPSEC_POLICY_IN -j ACCEPT
+	fi
+	#
 	# log IPsec client connection setup
 	if [ $VPN_LOGGING ]
 	then
@@ -527,6 +383,13 @@ down-client:iptables)
 	         $IPSEC_POLICY_OUT -j ACCEPT
 	fi
 	#
+	# IPIP exception teardown
+	if [ -n "$PLUTO_IPCOMP" ]
+	then
+	  iptables -D INPUT -i $PLUTO_INTERFACE -p 4 \
+	      -s $PLUTO_PEER -d $PLUTO_ME $IPSEC_POLICY_IN -j ACCEPT
+	fi
+	#
 	# log IPsec client connection teardown
 	if [ $VPN_LOGGING ]
 	then
@@ -543,16 +406,6 @@ down-client:iptables)
 #
 # IPv6
 #
-prepare-host-v6:*|prepare-client-v6:*)
-	;;
-route-host-v6:*|route-client-v6:*)
-	# connection to me or my client subnet being routed
-	#uproute_v6
-	;;
-unroute-host-v6:*|unroute-client-v6:*)
-	# connection to me or my client subnet being unrouted
-	#downroute_v6
-	;;
 up-host-v6:)
 	# connection to me coming up
 	# If you are doing a custom version, firewall commands go here.
diff --git a/testing/tests/libipsec/net2net-3des/hosts/moon/etc/updown b/testing/tests/libipsec/net2net-3des/hosts/moon/etc/updown
index 1a68ada..1b362e6 100755
--- a/testing/tests/libipsec/net2net-3des/hosts/moon/etc/updown
+++ b/testing/tests/libipsec/net2net-3des/hosts/moon/etc/updown
@@ -1,5 +1,5 @@
-#! /bin/sh
-# iproute2 version, default updown script
+#!/bin/sh
+# default updown script
 #
 # Copyright (C) 2003-2004 Nigel Meteringham
 # Copyright (C) 2003-2004 Tuomo Soini
@@ -22,8 +22,6 @@
 # that, and use the (left/right)updown parameters in ipsec.conf to make
 # strongSwan use yours instead of this default one.
 
-# things that this script gets (from ipsec_pluto(8) man page)
-#
 #      PLUTO_VERSION
 #              indicates  what  version of this interface is being
 #              used.  This document describes version  1.1.   This
@@ -41,15 +39,17 @@
 #              is the name of the  connection  for  which  we  are
 #              routing.
 #
-#       PLUTO_NEXT_HOP
-#              is the next hop to which packets bound for the peer
-#              must be sent.
-#
 #       PLUTO_INTERFACE
 #              is the name of the ipsec interface to be used.
 #
 #       PLUTO_REQID
-#              is the requid of the ESP policy
+#              is the requid of the AH|ESP policy
+#
+#       PLUTO_PROTO
+#              is the negotiated IPsec protocol, ah|esp
+#
+#       PLUTO_IPCOMP
+#              is not empty if IPComp was negotiated
 #
 #       PLUTO_UNIQUEID
 #              is the unique identifier of the associated IKE_SA
@@ -66,15 +66,6 @@
 #              host's own IP address / max (where max  is  32  for
 #              IPv4 and 128 for IPv6).
 #
-#       PLUTO_MY_CLIENT_NET
-#              is the IP address of our client net.  If the client
-#              is just the host, this will be the  host's  own  IP
-#              address.
-#
-#       PLUTO_MY_CLIENT_MASK
-#              is  the  mask for our client net.  If the client is
-#              just the host, this will be 255.255.255.255.
-#
 #       PLUTO_MY_SOURCEIP
 #       PLUTO_MY_SOURCEIP4_$i
 #       PLUTO_MY_SOURCEIP6_$i
@@ -88,7 +79,8 @@
 #
 #       PLUTO_MY_PORT
 #              is  the  UDP/TCP  port  to  which  the IPsec SA  is
-#              restricted on our side.
+#              restricted on our side.  For ICMP/ICMPv6 this contains the
+#              message type, and PLUTO_PEER_PORT the message code.
 #
 #       PLUTO_PEER
 #              is the IP address of our peer.
@@ -96,31 +88,19 @@
 #       PLUTO_PEER_ID
 #              is the ID of our peer.
 #
-#       PLUTO_PEER_CA
-#              is the CA which issued the cert of our peer.
-#
 #       PLUTO_PEER_CLIENT
 #              is the IP address / count of the peer's client sub-
 #              net.   If the client is just the peer, this will be
 #              the peer's own IP address / max (where  max  is  32
 #              for IPv4 and 128 for IPv6).
 #
-#       PLUTO_PEER_CLIENT_NET
-#              is the IP address of the peer's client net.  If the
-#              client is just the peer, this will  be  the  peer's
-#              own IP address.
-#
-#       PLUTO_PEER_CLIENT_MASK
-#              is  the  mask  for  the  peer's client net.  If the
-#              client   is   just   the   peer,   this   will   be
-#              255.255.255.255.
-#
 #       PLUTO_PEER_PROTOCOL
 #              is the IP protocol that will be transported.
 #
 #       PLUTO_PEER_PORT
 #              is  the  UDP/TCP  port  to  which  the IPsec SA  is
-#              restricted on the peer side.
+#              restricted on the peer side.  For ICMP/ICMPv6 this contains the
+#              message code, and PLUTO_MY_PORT the message type.
 #
 #       PLUTO_XAUTH_ID
 #              is an optional user ID employed by the XAUTH protocol
@@ -146,7 +126,7 @@
 PATH="/sbin:/bin:/usr/sbin:/usr/bin:/usr/sbin"
 export PATH
 
-# uncomment to log VPN connections
+# comment to disable logging VPN connections to syslog
 VPN_LOGGING=1
 #
 # tag put in front of each log entry:
@@ -160,21 +140,11 @@ FAC_PRIO=local0.notice
 #
 # local0.notice                   -/var/log/vpn
 
-# in order to use source IP routing the Linux kernel options
-# CONFIG_IP_ADVANCED_ROUTER and CONFIG_IP_MULTIPLE_TABLES
-# must be enabled
-#
-# special routing table for sourceip routes
-SOURCEIP_ROUTING_TABLE=220
-#
-# priority of the sourceip routing table
-SOURCEIP_ROUTING_TABLE_PRIO=220
-
 # check interface version
 case "$PLUTO_VERSION" in
-1.[0|1])	# Older Pluto?!?  Play it safe, script may be using new features.
+1.[0|1])	# Older release?!?  Play it safe, script may be using new features.
 	echo "$0: obsolete interface version \`$PLUTO_VERSION'," >&2
-	echo "$0: 	called by obsolete Pluto?" >&2
+	echo "$0: 	called by obsolete release?" >&2
 	exit 2
 	;;
 1.*)	;;
@@ -196,190 +166,52 @@ custom:*)		# custom parameters (see above CAUTION comment)
 	;;
 esac
 
-# utility functions for route manipulation
-# Meddling with this stuff should not be necessary and requires great care.
-uproute() {
-	doroute add
-	ip route flush cache
-}
-downroute() {
-	doroute delete
-	ip route flush cache
-}
-
-addsource() {
-	st=0
-	if ! ip -o route get ${PLUTO_MY_SOURCEIP%/*} | grep -q ^local
-	then
-	    it="ip addr add ${PLUTO_MY_SOURCEIP%/*}/32 dev $PLUTO_INTERFACE"
-	    oops="`eval $it 2>&1`"
-	    st=$?
-	    if test " $oops" = " " -a " $st" != " 0"
-	    then
-		oops="silent error, exit status $st"
-	    fi
-	    if test " $oops" != " " -o " $st" != " 0"
-	    then
-		echo "$0: addsource \`$it' failed ($oops)" >&2
-	    fi
-	fi
-	return $st
-}
-
-doroute() {
-	st=0
-
-	if [ -z "$PLUTO_MY_SOURCEIP" ]
-	then
-	    for dir in /etc/sysconfig /etc/conf.d; do
-		if [ -f "$dir/defaultsource" ]
-		then
-		    . "$dir/defaultsource"
-		fi
-	    done
-
-	    if [ -n "$DEFAULTSOURCE" ]
-	    then
-		PLUTO_MY_SOURCEIP=$DEFAULTSOURCE
-	    fi
-        fi
-
-	if [ -z "$KLIPS" -a -z "$PLUTO_MY_SOURCEIP" ]
-	then
-	    # leave because no route entry is required
-	    return $st
-	fi
-
-	parms1="$PLUTO_PEER_CLIENT"
-
-	if [ -n "$PLUTO_NEXT_HOP" ]
-	then
-	    parms2="via $PLUTO_NEXT_HOP"
-	else
-	    parms2="via $PLUTO_PEER"
-	fi
-	parms2="$parms2 dev $PLUTO_INTERFACE"
-
-	parms3=
-	if [ -n "$PLUTO_MY_SOURCEIP" ]
-	then
-	    if test "$1" = "add"
-	    then
-		addsource
-		if ! ip rule list | grep -q "lookup $SOURCEIP_ROUTING_TABLE"
-		then
-		    ip rule add pref $SOURCEIP_ROUTING_TABLE_PRIO table $SOURCEIP_ROUTING_TABLE
-		fi
-	    fi
-	    parms3="$parms3 src ${PLUTO_MY_SOURCEIP%/*} table $SOURCEIP_ROUTING_TABLE"
-	fi
+IPSEC_POLICY="-m policy --pol ipsec --proto $PLUTO_PROTO --reqid $PLUTO_REQID"
+IPSEC_POLICY_IN="$IPSEC_POLICY --dir in"
+IPSEC_POLICY_OUT="$IPSEC_POLICY --dir out"
 
-	case "$PLUTO_PEER_CLIENT_NET/$PLUTO_PEER_CLIENT_MASK" in
-	"0.0.0.0/0.0.0.0")
-		# opportunistic encryption work around
-		# need to provide route that eclipses default, without
-		# replacing it.
-		it="ip route $1 0.0.0.0/1 $parms2 $parms3 &&
-			ip route $1 128.0.0.0/1 $parms2 $parms3"
-		;;
-	*)	it="ip route $1 $parms1 $parms2 $parms3"
-		;;
-	esac
-	oops="`eval $it 2>&1`"
-	st=$?
-	if test " $oops" = " " -a " $st" != " 0"
-	then
-	    oops="silent error, exit status $st"
-	fi
-	if test " $oops" != " " -o " $st" != " 0"
-	then
-	    echo "$0: doroute \`$it' failed ($oops)" >&2
-	fi
-	return $st
-}
-
-# in the presence of KLIPS and ipsecN interfaces do not use IPSEC_POLICY
-if [ `echo "$PLUTO_INTERFACE" | grep "ipsec"` ]
-then
-	KLIPS=1
-	IPSEC_POLICY_IN=""
-	IPSEC_POLICY_OUT=""
-else
-	KLIPS=
-	IPSEC_POLICY="-m policy --pol ipsec --proto esp --reqid $PLUTO_REQID"
-	IPSEC_POLICY_IN="$IPSEC_POLICY --dir in"
-	IPSEC_POLICY_OUT="$IPSEC_POLICY --dir out"
-fi
+# use protocol specific options to set ports
+case "$PLUTO_MY_PROTOCOL" in
+1)	# ICMP
+	ICMP_TYPE_OPTION="--icmp-type"
+	;;
+58)	# ICMPv6
+	ICMP_TYPE_OPTION="--icmpv6-type"
+	;;
+*)
+	;;
+esac
 
 # are there port numbers?
 if [ "$PLUTO_MY_PORT" != 0 ]
 then
-	S_MY_PORT="--sport $PLUTO_MY_PORT"
-	D_MY_PORT="--dport $PLUTO_MY_PORT"
+	if [ -n "$ICMP_TYPE_OPTION" ]
+	then
+		S_MY_PORT="$ICMP_TYPE_OPTION $PLUTO_MY_PORT"
+		D_MY_PORT="$ICMP_TYPE_OPTION $PLUTO_MY_PORT"
+	else
+		S_MY_PORT="--sport $PLUTO_MY_PORT"
+		D_MY_PORT="--dport $PLUTO_MY_PORT"
+	fi
 fi
 if [ "$PLUTO_PEER_PORT" != 0 ]
 then
-	S_PEER_PORT="--sport $PLUTO_PEER_PORT"
-	D_PEER_PORT="--dport $PLUTO_PEER_PORT"
+	if [ -n "$ICMP_TYPE_OPTION" ]
+	then
+		# the syntax is --icmp[v6]-type type[/code], so add it to the existing option
+		S_MY_PORT="$S_MY_PORT/$PLUTO_PEER_PORT"
+		D_MY_PORT="$D_MY_PORT/$PLUTO_PEER_PORT"
+	else
+		S_PEER_PORT="--sport $PLUTO_PEER_PORT"
+		D_PEER_PORT="--dport $PLUTO_PEER_PORT"
+	fi
 fi
 
 # resolve octal escape sequences
 PLUTO_MY_ID=`printf "$PLUTO_MY_ID"`
 PLUTO_PEER_ID=`printf "$PLUTO_PEER_ID"`
 
-# the big choice
 case "$PLUTO_VERB:$1" in
-prepare-host:*|prepare-client:*)
-	if [ -z "$KLIPS" -a -z "$PLUTO_MY_SOURCEIP" ]
-	then
-	    # exit because no route will be added,
-	    # so that existing routes can stay
-	    exit 0
-	fi
-
-	# delete possibly-existing route (preliminary to adding a route)
-	case "$PLUTO_PEER_CLIENT_NET/$PLUTO_PEER_CLIENT_MASK" in
-	"0.0.0.0/0.0.0.0")
-		# need to provide route that eclipses default, without
-		# replacing it.
-		parms1="0.0.0.0/1"
-		parms2="128.0.0.0/1"
-		it="ip route delete $parms1 2>&1 ; ip route delete $parms2 2>&1"
-		oops="`ip route delete $parms1 2>&1 ; ip route delete $parms2 2>&1`"
-		;;
-	*)
-		parms="$PLUTO_PEER_CLIENT"
-		it="ip route delete $parms 2>&1"
-		oops="`ip route delete $parms 2>&1`"
-		;;
-	esac
-	status="$?"
-	if test " $oops" = " " -a " $status" != " 0"
-	then
-		oops="silent error, exit status $status"
-	fi
-	case "$oops" in
-	*'RTNETLINK answers: No such process'*)
-		# This is what route (currently -- not documented!) gives
-		# for "could not find such a route".
-		oops=
-		status=0
-		;;
-	esac
-	if test " $oops" != " " -o " $status" != " 0"
-	then
-		echo "$0: \`$it' failed ($oops)" >&2
-	fi
-	exit $status
-	;;
-route-host:*|route-client:*)
-	# connection to me or my client subnet being routed
-	uproute
-	;;
-unroute-host:*|unroute-client:*)
-	# connection to me or my client subnet being unrouted
-	downroute
-	;;
 up-host:)
 	# connection to me coming up
 	# If you are doing a custom version, firewall commands go here.
@@ -421,6 +253,14 @@ up-host:iptables)
 	    -s $PLUTO_ME $S_MY_PORT $IPSEC_POLICY_OUT \
 	    -d $PLUTO_PEER_CLIENT $D_PEER_PORT -j ACCEPT
 	#
+	# allow IPIP traffic because of the implicit SA created by the kernel if
+	# IPComp is used (for small inbound packets that are not compressed)
+	if [ -n "$PLUTO_IPCOMP" ]
+	then
+	  iptables -I INPUT 1 -i $PLUTO_INTERFACE -p 4 \
+	      -s $PLUTO_PEER -d $PLUTO_ME $IPSEC_POLICY_IN -j ACCEPT
+	fi
+	#
 	# log IPsec host connection setup
 	if [ $VPN_LOGGING ]
 	then
@@ -445,6 +285,13 @@ down-host:iptables)
 	    -s $PLUTO_ME $S_MY_PORT $IPSEC_POLICY_OUT \
 	    -d $PLUTO_PEER_CLIENT $D_PEER_PORT -j ACCEPT
 	#
+	# IPIP exception teardown
+	if [ -n "$PLUTO_IPCOMP" ]
+	then
+	  iptables -D INPUT -i $PLUTO_INTERFACE -p 4 \
+	      -s $PLUTO_PEER -d $PLUTO_ME $IPSEC_POLICY_IN -j ACCEPT
+	fi
+	#
 	# log IPsec host connection teardown
 	if [ $VPN_LOGGING ]
 	then
@@ -484,6 +331,15 @@ up-client:iptables)
 	      -d $PLUTO_PEER_CLIENT $D_PEER_PORT $IPSEC_POLICY_OUT -j ACCEPT
 	fi
 	#
+	# allow IPIP traffic because of the implicit SA created by the kernel if
+	# IPComp is used (for small inbound packets that are not compressed).
+	# INPUT is correct here even for forwarded traffic.
+	if [ -n "$PLUTO_IPCOMP" ]
+	then
+	  iptables -I INPUT 1 -i $PLUTO_INTERFACE -p 4 \
+	      -s $PLUTO_PEER -d $PLUTO_ME $IPSEC_POLICY_IN -j ACCEPT
+	fi
+	#
 	# log IPsec client connection setup
 	if [ $VPN_LOGGING ]
 	then
@@ -527,6 +383,13 @@ down-client:iptables)
 	         $IPSEC_POLICY_OUT -j ACCEPT
 	fi
 	#
+	# IPIP exception teardown
+	if [ -n "$PLUTO_IPCOMP" ]
+	then
+	  iptables -D INPUT -i $PLUTO_INTERFACE -p 4 \
+	      -s $PLUTO_PEER -d $PLUTO_ME $IPSEC_POLICY_IN -j ACCEPT
+	fi
+	#
 	# log IPsec client connection teardown
 	if [ $VPN_LOGGING ]
 	then
@@ -543,16 +406,6 @@ down-client:iptables)
 #
 # IPv6
 #
-prepare-host-v6:*|prepare-client-v6:*)
-	;;
-route-host-v6:*|route-client-v6:*)
-	# connection to me or my client subnet being routed
-	#uproute_v6
-	;;
-unroute-host-v6:*|unroute-client-v6:*)
-	# connection to me or my client subnet being unrouted
-	#downroute_v6
-	;;
 up-host-v6:)
 	# connection to me coming up
 	# If you are doing a custom version, firewall commands go here.
diff --git a/testing/tests/libipsec/net2net-3des/hosts/sun/etc/updown b/testing/tests/libipsec/net2net-3des/hosts/sun/etc/updown
index 1a68ada..1b362e6 100755
--- a/testing/tests/libipsec/net2net-3des/hosts/sun/etc/updown
+++ b/testing/tests/libipsec/net2net-3des/hosts/sun/etc/updown
@@ -1,5 +1,5 @@
-#! /bin/sh
-# iproute2 version, default updown script
+#!/bin/sh
+# default updown script
 #
 # Copyright (C) 2003-2004 Nigel Meteringham
 # Copyright (C) 2003-2004 Tuomo Soini
@@ -22,8 +22,6 @@
 # that, and use the (left/right)updown parameters in ipsec.conf to make
 # strongSwan use yours instead of this default one.
 
-# things that this script gets (from ipsec_pluto(8) man page)
-#
 #      PLUTO_VERSION
 #              indicates  what  version of this interface is being
 #              used.  This document describes version  1.1.   This
@@ -41,15 +39,17 @@
 #              is the name of the  connection  for  which  we  are
 #              routing.
 #
-#       PLUTO_NEXT_HOP
-#              is the next hop to which packets bound for the peer
-#              must be sent.
-#
 #       PLUTO_INTERFACE
 #              is the name of the ipsec interface to be used.
 #
 #       PLUTO_REQID
-#              is the requid of the ESP policy
+#              is the requid of the AH|ESP policy
+#
+#       PLUTO_PROTO
+#              is the negotiated IPsec protocol, ah|esp
+#
+#       PLUTO_IPCOMP
+#              is not empty if IPComp was negotiated
 #
 #       PLUTO_UNIQUEID
 #              is the unique identifier of the associated IKE_SA
@@ -66,15 +66,6 @@
 #              host's own IP address / max (where max  is  32  for
 #              IPv4 and 128 for IPv6).
 #
-#       PLUTO_MY_CLIENT_NET
-#              is the IP address of our client net.  If the client
-#              is just the host, this will be the  host's  own  IP
-#              address.
-#
-#       PLUTO_MY_CLIENT_MASK
-#              is  the  mask for our client net.  If the client is
-#              just the host, this will be 255.255.255.255.
-#
 #       PLUTO_MY_SOURCEIP
 #       PLUTO_MY_SOURCEIP4_$i
 #       PLUTO_MY_SOURCEIP6_$i
@@ -88,7 +79,8 @@
 #
 #       PLUTO_MY_PORT
 #              is  the  UDP/TCP  port  to  which  the IPsec SA  is
-#              restricted on our side.
+#              restricted on our side.  For ICMP/ICMPv6 this contains the
+#              message type, and PLUTO_PEER_PORT the message code.
 #
 #       PLUTO_PEER
 #              is the IP address of our peer.
@@ -96,31 +88,19 @@
 #       PLUTO_PEER_ID
 #              is the ID of our peer.
 #
-#       PLUTO_PEER_CA
-#              is the CA which issued the cert of our peer.
-#
 #       PLUTO_PEER_CLIENT
 #              is the IP address / count of the peer's client sub-
 #              net.   If the client is just the peer, this will be
 #              the peer's own IP address / max (where  max  is  32
 #              for IPv4 and 128 for IPv6).
 #
-#       PLUTO_PEER_CLIENT_NET
-#              is the IP address of the peer's client net.  If the
-#              client is just the peer, this will  be  the  peer's
-#              own IP address.
-#
-#       PLUTO_PEER_CLIENT_MASK
-#              is  the  mask  for  the  peer's client net.  If the
-#              client   is   just   the   peer,   this   will   be
-#              255.255.255.255.
-#
 #       PLUTO_PEER_PROTOCOL
 #              is the IP protocol that will be transported.
 #
 #       PLUTO_PEER_PORT
 #              is  the  UDP/TCP  port  to  which  the IPsec SA  is
-#              restricted on the peer side.
+#              restricted on the peer side.  For ICMP/ICMPv6 this contains the
+#              message code, and PLUTO_MY_PORT the message type.
 #
 #       PLUTO_XAUTH_ID
 #              is an optional user ID employed by the XAUTH protocol
@@ -146,7 +126,7 @@
 PATH="/sbin:/bin:/usr/sbin:/usr/bin:/usr/sbin"
 export PATH
 
-# uncomment to log VPN connections
+# comment to disable logging VPN connections to syslog
 VPN_LOGGING=1
 #
 # tag put in front of each log entry:
@@ -160,21 +140,11 @@ FAC_PRIO=local0.notice
 #
 # local0.notice                   -/var/log/vpn
 
-# in order to use source IP routing the Linux kernel options
-# CONFIG_IP_ADVANCED_ROUTER and CONFIG_IP_MULTIPLE_TABLES
-# must be enabled
-#
-# special routing table for sourceip routes
-SOURCEIP_ROUTING_TABLE=220
-#
-# priority of the sourceip routing table
-SOURCEIP_ROUTING_TABLE_PRIO=220
-
 # check interface version
 case "$PLUTO_VERSION" in
-1.[0|1])	# Older Pluto?!?  Play it safe, script may be using new features.
+1.[0|1])	# Older release?!?  Play it safe, script may be using new features.
 	echo "$0: obsolete interface version \`$PLUTO_VERSION'," >&2
-	echo "$0: 	called by obsolete Pluto?" >&2
+	echo "$0: 	called by obsolete release?" >&2
 	exit 2
 	;;
 1.*)	;;
@@ -196,190 +166,52 @@ custom:*)		# custom parameters (see above CAUTION comment)
 	;;
 esac
 
-# utility functions for route manipulation
-# Meddling with this stuff should not be necessary and requires great care.
-uproute() {
-	doroute add
-	ip route flush cache
-}
-downroute() {
-	doroute delete
-	ip route flush cache
-}
-
-addsource() {
-	st=0
-	if ! ip -o route get ${PLUTO_MY_SOURCEIP%/*} | grep -q ^local
-	then
-	    it="ip addr add ${PLUTO_MY_SOURCEIP%/*}/32 dev $PLUTO_INTERFACE"
-	    oops="`eval $it 2>&1`"
-	    st=$?
-	    if test " $oops" = " " -a " $st" != " 0"
-	    then
-		oops="silent error, exit status $st"
-	    fi
-	    if test " $oops" != " " -o " $st" != " 0"
-	    then
-		echo "$0: addsource \`$it' failed ($oops)" >&2
-	    fi
-	fi
-	return $st
-}
-
-doroute() {
-	st=0
-
-	if [ -z "$PLUTO_MY_SOURCEIP" ]
-	then
-	    for dir in /etc/sysconfig /etc/conf.d; do
-		if [ -f "$dir/defaultsource" ]
-		then
-		    . "$dir/defaultsource"
-		fi
-	    done
-
-	    if [ -n "$DEFAULTSOURCE" ]
-	    then
-		PLUTO_MY_SOURCEIP=$DEFAULTSOURCE
-	    fi
-        fi
-
-	if [ -z "$KLIPS" -a -z "$PLUTO_MY_SOURCEIP" ]
-	then
-	    # leave because no route entry is required
-	    return $st
-	fi
-
-	parms1="$PLUTO_PEER_CLIENT"
-
-	if [ -n "$PLUTO_NEXT_HOP" ]
-	then
-	    parms2="via $PLUTO_NEXT_HOP"
-	else
-	    parms2="via $PLUTO_PEER"
-	fi
-	parms2="$parms2 dev $PLUTO_INTERFACE"
-
-	parms3=
-	if [ -n "$PLUTO_MY_SOURCEIP" ]
-	then
-	    if test "$1" = "add"
-	    then
-		addsource
-		if ! ip rule list | grep -q "lookup $SOURCEIP_ROUTING_TABLE"
-		then
-		    ip rule add pref $SOURCEIP_ROUTING_TABLE_PRIO table $SOURCEIP_ROUTING_TABLE
-		fi
-	    fi
-	    parms3="$parms3 src ${PLUTO_MY_SOURCEIP%/*} table $SOURCEIP_ROUTING_TABLE"
-	fi
+IPSEC_POLICY="-m policy --pol ipsec --proto $PLUTO_PROTO --reqid $PLUTO_REQID"
+IPSEC_POLICY_IN="$IPSEC_POLICY --dir in"
+IPSEC_POLICY_OUT="$IPSEC_POLICY --dir out"
 
-	case "$PLUTO_PEER_CLIENT_NET/$PLUTO_PEER_CLIENT_MASK" in
-	"0.0.0.0/0.0.0.0")
-		# opportunistic encryption work around
-		# need to provide route that eclipses default, without
-		# replacing it.
-		it="ip route $1 0.0.0.0/1 $parms2 $parms3 &&
-			ip route $1 128.0.0.0/1 $parms2 $parms3"
-		;;
-	*)	it="ip route $1 $parms1 $parms2 $parms3"
-		;;
-	esac
-	oops="`eval $it 2>&1`"
-	st=$?
-	if test " $oops" = " " -a " $st" != " 0"
-	then
-	    oops="silent error, exit status $st"
-	fi
-	if test " $oops" != " " -o " $st" != " 0"
-	then
-	    echo "$0: doroute \`$it' failed ($oops)" >&2
-	fi
-	return $st
-}
-
-# in the presence of KLIPS and ipsecN interfaces do not use IPSEC_POLICY
-if [ `echo "$PLUTO_INTERFACE" | grep "ipsec"` ]
-then
-	KLIPS=1
-	IPSEC_POLICY_IN=""
-	IPSEC_POLICY_OUT=""
-else
-	KLIPS=
-	IPSEC_POLICY="-m policy --pol ipsec --proto esp --reqid $PLUTO_REQID"
-	IPSEC_POLICY_IN="$IPSEC_POLICY --dir in"
-	IPSEC_POLICY_OUT="$IPSEC_POLICY --dir out"
-fi
+# use protocol specific options to set ports
+case "$PLUTO_MY_PROTOCOL" in
+1)	# ICMP
+	ICMP_TYPE_OPTION="--icmp-type"
+	;;
+58)	# ICMPv6
+	ICMP_TYPE_OPTION="--icmpv6-type"
+	;;
+*)
+	;;
+esac
 
 # are there port numbers?
 if [ "$PLUTO_MY_PORT" != 0 ]
 then
-	S_MY_PORT="--sport $PLUTO_MY_PORT"
-	D_MY_PORT="--dport $PLUTO_MY_PORT"
+	if [ -n "$ICMP_TYPE_OPTION" ]
+	then
+		S_MY_PORT="$ICMP_TYPE_OPTION $PLUTO_MY_PORT"
+		D_MY_PORT="$ICMP_TYPE_OPTION $PLUTO_MY_PORT"
+	else
+		S_MY_PORT="--sport $PLUTO_MY_PORT"
+		D_MY_PORT="--dport $PLUTO_MY_PORT"
+	fi
 fi
 if [ "$PLUTO_PEER_PORT" != 0 ]
 then
-	S_PEER_PORT="--sport $PLUTO_PEER_PORT"
-	D_PEER_PORT="--dport $PLUTO_PEER_PORT"
+	if [ -n "$ICMP_TYPE_OPTION" ]
+	then
+		# the syntax is --icmp[v6]-type type[/code], so add it to the existing option
+		S_MY_PORT="$S_MY_PORT/$PLUTO_PEER_PORT"
+		D_MY_PORT="$D_MY_PORT/$PLUTO_PEER_PORT"
+	else
+		S_PEER_PORT="--sport $PLUTO_PEER_PORT"
+		D_PEER_PORT="--dport $PLUTO_PEER_PORT"
+	fi
 fi
 
 # resolve octal escape sequences
 PLUTO_MY_ID=`printf "$PLUTO_MY_ID"`
 PLUTO_PEER_ID=`printf "$PLUTO_PEER_ID"`
 
-# the big choice
 case "$PLUTO_VERB:$1" in
-prepare-host:*|prepare-client:*)
-	if [ -z "$KLIPS" -a -z "$PLUTO_MY_SOURCEIP" ]
-	then
-	    # exit because no route will be added,
-	    # so that existing routes can stay
-	    exit 0
-	fi
-
-	# delete possibly-existing route (preliminary to adding a route)
-	case "$PLUTO_PEER_CLIENT_NET/$PLUTO_PEER_CLIENT_MASK" in
-	"0.0.0.0/0.0.0.0")
-		# need to provide route that eclipses default, without
-		# replacing it.
-		parms1="0.0.0.0/1"
-		parms2="128.0.0.0/1"
-		it="ip route delete $parms1 2>&1 ; ip route delete $parms2 2>&1"
-		oops="`ip route delete $parms1 2>&1 ; ip route delete $parms2 2>&1`"
-		;;
-	*)
-		parms="$PLUTO_PEER_CLIENT"
-		it="ip route delete $parms 2>&1"
-		oops="`ip route delete $parms 2>&1`"
-		;;
-	esac
-	status="$?"
-	if test " $oops" = " " -a " $status" != " 0"
-	then
-		oops="silent error, exit status $status"
-	fi
-	case "$oops" in
-	*'RTNETLINK answers: No such process'*)
-		# This is what route (currently -- not documented!) gives
-		# for "could not find such a route".
-		oops=
-		status=0
-		;;
-	esac
-	if test " $oops" != " " -o " $status" != " 0"
-	then
-		echo "$0: \`$it' failed ($oops)" >&2
-	fi
-	exit $status
-	;;
-route-host:*|route-client:*)
-	# connection to me or my client subnet being routed
-	uproute
-	;;
-unroute-host:*|unroute-client:*)
-	# connection to me or my client subnet being unrouted
-	downroute
-	;;
 up-host:)
 	# connection to me coming up
 	# If you are doing a custom version, firewall commands go here.
@@ -421,6 +253,14 @@ up-host:iptables)
 	    -s $PLUTO_ME $S_MY_PORT $IPSEC_POLICY_OUT \
 	    -d $PLUTO_PEER_CLIENT $D_PEER_PORT -j ACCEPT
 	#
+	# allow IPIP traffic because of the implicit SA created by the kernel if
+	# IPComp is used (for small inbound packets that are not compressed)
+	if [ -n "$PLUTO_IPCOMP" ]
+	then
+	  iptables -I INPUT 1 -i $PLUTO_INTERFACE -p 4 \
+	      -s $PLUTO_PEER -d $PLUTO_ME $IPSEC_POLICY_IN -j ACCEPT
+	fi
+	#
 	# log IPsec host connection setup
 	if [ $VPN_LOGGING ]
 	then
@@ -445,6 +285,13 @@ down-host:iptables)
 	    -s $PLUTO_ME $S_MY_PORT $IPSEC_POLICY_OUT \
 	    -d $PLUTO_PEER_CLIENT $D_PEER_PORT -j ACCEPT
 	#
+	# IPIP exception teardown
+	if [ -n "$PLUTO_IPCOMP" ]
+	then
+	  iptables -D INPUT -i $PLUTO_INTERFACE -p 4 \
+	      -s $PLUTO_PEER -d $PLUTO_ME $IPSEC_POLICY_IN -j ACCEPT
+	fi
+	#
 	# log IPsec host connection teardown
 	if [ $VPN_LOGGING ]
 	then
@@ -484,6 +331,15 @@ up-client:iptables)
 	      -d $PLUTO_PEER_CLIENT $D_PEER_PORT $IPSEC_POLICY_OUT -j ACCEPT
 	fi
 	#
+	# allow IPIP traffic because of the implicit SA created by the kernel if
+	# IPComp is used (for small inbound packets that are not compressed).
+	# INPUT is correct here even for forwarded traffic.
+	if [ -n "$PLUTO_IPCOMP" ]
+	then
+	  iptables -I INPUT 1 -i $PLUTO_INTERFACE -p 4 \
+	      -s $PLUTO_PEER -d $PLUTO_ME $IPSEC_POLICY_IN -j ACCEPT
+	fi
+	#
 	# log IPsec client connection setup
 	if [ $VPN_LOGGING ]
 	then
@@ -527,6 +383,13 @@ down-client:iptables)
 	         $IPSEC_POLICY_OUT -j ACCEPT
 	fi
 	#
+	# IPIP exception teardown
+	if [ -n "$PLUTO_IPCOMP" ]
+	then
+	  iptables -D INPUT -i $PLUTO_INTERFACE -p 4 \
+	      -s $PLUTO_PEER -d $PLUTO_ME $IPSEC_POLICY_IN -j ACCEPT
+	fi
+	#
 	# log IPsec client connection teardown
 	if [ $VPN_LOGGING ]
 	then
@@ -543,16 +406,6 @@ down-client:iptables)
 #
 # IPv6
 #
-prepare-host-v6:*|prepare-client-v6:*)
-	;;
-route-host-v6:*|route-client-v6:*)
-	# connection to me or my client subnet being routed
-	#uproute_v6
-	;;
-unroute-host-v6:*|unroute-client-v6:*)
-	# connection to me or my client subnet being unrouted
-	#downroute_v6
-	;;
 up-host-v6:)
 	# connection to me coming up
 	# If you are doing a custom version, firewall commands go here.
diff --git a/testing/tests/libipsec/net2net-cert/hosts/moon/etc/updown b/testing/tests/libipsec/net2net-cert/hosts/moon/etc/updown
index 1a68ada..1b362e6 100755
--- a/testing/tests/libipsec/net2net-cert/hosts/moon/etc/updown
+++ b/testing/tests/libipsec/net2net-cert/hosts/moon/etc/updown
@@ -1,5 +1,5 @@
-#! /bin/sh
-# iproute2 version, default updown script
+#!/bin/sh
+# default updown script
 #
 # Copyright (C) 2003-2004 Nigel Meteringham
 # Copyright (C) 2003-2004 Tuomo Soini
@@ -22,8 +22,6 @@
 # that, and use the (left/right)updown parameters in ipsec.conf to make
 # strongSwan use yours instead of this default one.
 
-# things that this script gets (from ipsec_pluto(8) man page)
-#
 #      PLUTO_VERSION
 #              indicates  what  version of this interface is being
 #              used.  This document describes version  1.1.   This
@@ -41,15 +39,17 @@
 #              is the name of the  connection  for  which  we  are
 #              routing.
 #
-#       PLUTO_NEXT_HOP
-#              is the next hop to which packets bound for the peer
-#              must be sent.
-#
 #       PLUTO_INTERFACE
 #              is the name of the ipsec interface to be used.
 #
 #       PLUTO_REQID
-#              is the requid of the ESP policy
+#              is the requid of the AH|ESP policy
+#
+#       PLUTO_PROTO
+#              is the negotiated IPsec protocol, ah|esp
+#
+#       PLUTO_IPCOMP
+#              is not empty if IPComp was negotiated
 #
 #       PLUTO_UNIQUEID
 #              is the unique identifier of the associated IKE_SA
@@ -66,15 +66,6 @@
 #              host's own IP address / max (where max  is  32  for
 #              IPv4 and 128 for IPv6).
 #
-#       PLUTO_MY_CLIENT_NET
-#              is the IP address of our client net.  If the client
-#              is just the host, this will be the  host's  own  IP
-#              address.
-#
-#       PLUTO_MY_CLIENT_MASK
-#              is  the  mask for our client net.  If the client is
-#              just the host, this will be 255.255.255.255.
-#
 #       PLUTO_MY_SOURCEIP
 #       PLUTO_MY_SOURCEIP4_$i
 #       PLUTO_MY_SOURCEIP6_$i
@@ -88,7 +79,8 @@
 #
 #       PLUTO_MY_PORT
 #              is  the  UDP/TCP  port  to  which  the IPsec SA  is
-#              restricted on our side.
+#              restricted on our side.  For ICMP/ICMPv6 this contains the
+#              message type, and PLUTO_PEER_PORT the message code.
 #
 #       PLUTO_PEER
 #              is the IP address of our peer.
@@ -96,31 +88,19 @@
 #       PLUTO_PEER_ID
 #              is the ID of our peer.
 #
-#       PLUTO_PEER_CA
-#              is the CA which issued the cert of our peer.
-#
 #       PLUTO_PEER_CLIENT
 #              is the IP address / count of the peer's client sub-
 #              net.   If the client is just the peer, this will be
 #              the peer's own IP address / max (where  max  is  32
 #              for IPv4 and 128 for IPv6).
 #
-#       PLUTO_PEER_CLIENT_NET
-#              is the IP address of the peer's client net.  If the
-#              client is just the peer, this will  be  the  peer's
-#              own IP address.
-#
-#       PLUTO_PEER_CLIENT_MASK
-#              is  the  mask  for  the  peer's client net.  If the
-#              client   is   just   the   peer,   this   will   be
-#              255.255.255.255.
-#
 #       PLUTO_PEER_PROTOCOL
 #              is the IP protocol that will be transported.
 #
 #       PLUTO_PEER_PORT
 #              is  the  UDP/TCP  port  to  which  the IPsec SA  is
-#              restricted on the peer side.
+#              restricted on the peer side.  For ICMP/ICMPv6 this contains the
+#              message code, and PLUTO_MY_PORT the message type.
 #
 #       PLUTO_XAUTH_ID
 #              is an optional user ID employed by the XAUTH protocol
@@ -146,7 +126,7 @@
 PATH="/sbin:/bin:/usr/sbin:/usr/bin:/usr/sbin"
 export PATH
 
-# uncomment to log VPN connections
+# comment to disable logging VPN connections to syslog
 VPN_LOGGING=1
 #
 # tag put in front of each log entry:
@@ -160,21 +140,11 @@ FAC_PRIO=local0.notice
 #
 # local0.notice                   -/var/log/vpn
 
-# in order to use source IP routing the Linux kernel options
-# CONFIG_IP_ADVANCED_ROUTER and CONFIG_IP_MULTIPLE_TABLES
-# must be enabled
-#
-# special routing table for sourceip routes
-SOURCEIP_ROUTING_TABLE=220
-#
-# priority of the sourceip routing table
-SOURCEIP_ROUTING_TABLE_PRIO=220
-
 # check interface version
 case "$PLUTO_VERSION" in
-1.[0|1])	# Older Pluto?!?  Play it safe, script may be using new features.
+1.[0|1])	# Older release?!?  Play it safe, script may be using new features.
 	echo "$0: obsolete interface version \`$PLUTO_VERSION'," >&2
-	echo "$0: 	called by obsolete Pluto?" >&2
+	echo "$0: 	called by obsolete release?" >&2
 	exit 2
 	;;
 1.*)	;;
@@ -196,190 +166,52 @@ custom:*)		# custom parameters (see above CAUTION comment)
 	;;
 esac
 
-# utility functions for route manipulation
-# Meddling with this stuff should not be necessary and requires great care.
-uproute() {
-	doroute add
-	ip route flush cache
-}
-downroute() {
-	doroute delete
-	ip route flush cache
-}
-
-addsource() {
-	st=0
-	if ! ip -o route get ${PLUTO_MY_SOURCEIP%/*} | grep -q ^local
-	then
-	    it="ip addr add ${PLUTO_MY_SOURCEIP%/*}/32 dev $PLUTO_INTERFACE"
-	    oops="`eval $it 2>&1`"
-	    st=$?
-	    if test " $oops" = " " -a " $st" != " 0"
-	    then
-		oops="silent error, exit status $st"
-	    fi
-	    if test " $oops" != " " -o " $st" != " 0"
-	    then
-		echo "$0: addsource \`$it' failed ($oops)" >&2
-	    fi
-	fi
-	return $st
-}
-
-doroute() {
-	st=0
-
-	if [ -z "$PLUTO_MY_SOURCEIP" ]
-	then
-	    for dir in /etc/sysconfig /etc/conf.d; do
-		if [ -f "$dir/defaultsource" ]
-		then
-		    . "$dir/defaultsource"
-		fi
-	    done
-
-	    if [ -n "$DEFAULTSOURCE" ]
-	    then
-		PLUTO_MY_SOURCEIP=$DEFAULTSOURCE
-	    fi
-        fi
-
-	if [ -z "$KLIPS" -a -z "$PLUTO_MY_SOURCEIP" ]
-	then
-	    # leave because no route entry is required
-	    return $st
-	fi
-
-	parms1="$PLUTO_PEER_CLIENT"
-
-	if [ -n "$PLUTO_NEXT_HOP" ]
-	then
-	    parms2="via $PLUTO_NEXT_HOP"
-	else
-	    parms2="via $PLUTO_PEER"
-	fi
-	parms2="$parms2 dev $PLUTO_INTERFACE"
-
-	parms3=
-	if [ -n "$PLUTO_MY_SOURCEIP" ]
-	then
-	    if test "$1" = "add"
-	    then
-		addsource
-		if ! ip rule list | grep -q "lookup $SOURCEIP_ROUTING_TABLE"
-		then
-		    ip rule add pref $SOURCEIP_ROUTING_TABLE_PRIO table $SOURCEIP_ROUTING_TABLE
-		fi
-	    fi
-	    parms3="$parms3 src ${PLUTO_MY_SOURCEIP%/*} table $SOURCEIP_ROUTING_TABLE"
-	fi
+IPSEC_POLICY="-m policy --pol ipsec --proto $PLUTO_PROTO --reqid $PLUTO_REQID"
+IPSEC_POLICY_IN="$IPSEC_POLICY --dir in"
+IPSEC_POLICY_OUT="$IPSEC_POLICY --dir out"
 
-	case "$PLUTO_PEER_CLIENT_NET/$PLUTO_PEER_CLIENT_MASK" in
-	"0.0.0.0/0.0.0.0")
-		# opportunistic encryption work around
-		# need to provide route that eclipses default, without
-		# replacing it.
-		it="ip route $1 0.0.0.0/1 $parms2 $parms3 &&
-			ip route $1 128.0.0.0/1 $parms2 $parms3"
-		;;
-	*)	it="ip route $1 $parms1 $parms2 $parms3"
-		;;
-	esac
-	oops="`eval $it 2>&1`"
-	st=$?
-	if test " $oops" = " " -a " $st" != " 0"
-	then
-	    oops="silent error, exit status $st"
-	fi
-	if test " $oops" != " " -o " $st" != " 0"
-	then
-	    echo "$0: doroute \`$it' failed ($oops)" >&2
-	fi
-	return $st
-}
-
-# in the presence of KLIPS and ipsecN interfaces do not use IPSEC_POLICY
-if [ `echo "$PLUTO_INTERFACE" | grep "ipsec"` ]
-then
-	KLIPS=1
-	IPSEC_POLICY_IN=""
-	IPSEC_POLICY_OUT=""
-else
-	KLIPS=
-	IPSEC_POLICY="-m policy --pol ipsec --proto esp --reqid $PLUTO_REQID"
-	IPSEC_POLICY_IN="$IPSEC_POLICY --dir in"
-	IPSEC_POLICY_OUT="$IPSEC_POLICY --dir out"
-fi
+# use protocol specific options to set ports
+case "$PLUTO_MY_PROTOCOL" in
+1)	# ICMP
+	ICMP_TYPE_OPTION="--icmp-type"
+	;;
+58)	# ICMPv6
+	ICMP_TYPE_OPTION="--icmpv6-type"
+	;;
+*)
+	;;
+esac
 
 # are there port numbers?
 if [ "$PLUTO_MY_PORT" != 0 ]
 then
-	S_MY_PORT="--sport $PLUTO_MY_PORT"
-	D_MY_PORT="--dport $PLUTO_MY_PORT"
+	if [ -n "$ICMP_TYPE_OPTION" ]
+	then
+		S_MY_PORT="$ICMP_TYPE_OPTION $PLUTO_MY_PORT"
+		D_MY_PORT="$ICMP_TYPE_OPTION $PLUTO_MY_PORT"
+	else
+		S_MY_PORT="--sport $PLUTO_MY_PORT"
+		D_MY_PORT="--dport $PLUTO_MY_PORT"
+	fi
 fi
 if [ "$PLUTO_PEER_PORT" != 0 ]
 then
-	S_PEER_PORT="--sport $PLUTO_PEER_PORT"
-	D_PEER_PORT="--dport $PLUTO_PEER_PORT"
+	if [ -n "$ICMP_TYPE_OPTION" ]
+	then
+		# the syntax is --icmp[v6]-type type[/code], so add it to the existing option
+		S_MY_PORT="$S_MY_PORT/$PLUTO_PEER_PORT"
+		D_MY_PORT="$D_MY_PORT/$PLUTO_PEER_PORT"
+	else
+		S_PEER_PORT="--sport $PLUTO_PEER_PORT"
+		D_PEER_PORT="--dport $PLUTO_PEER_PORT"
+	fi
 fi
 
 # resolve octal escape sequences
 PLUTO_MY_ID=`printf "$PLUTO_MY_ID"`
 PLUTO_PEER_ID=`printf "$PLUTO_PEER_ID"`
 
-# the big choice
 case "$PLUTO_VERB:$1" in
-prepare-host:*|prepare-client:*)
-	if [ -z "$KLIPS" -a -z "$PLUTO_MY_SOURCEIP" ]
-	then
-	    # exit because no route will be added,
-	    # so that existing routes can stay
-	    exit 0
-	fi
-
-	# delete possibly-existing route (preliminary to adding a route)
-	case "$PLUTO_PEER_CLIENT_NET/$PLUTO_PEER_CLIENT_MASK" in
-	"0.0.0.0/0.0.0.0")
-		# need to provide route that eclipses default, without
-		# replacing it.
-		parms1="0.0.0.0/1"
-		parms2="128.0.0.0/1"
-		it="ip route delete $parms1 2>&1 ; ip route delete $parms2 2>&1"
-		oops="`ip route delete $parms1 2>&1 ; ip route delete $parms2 2>&1`"
-		;;
-	*)
-		parms="$PLUTO_PEER_CLIENT"
-		it="ip route delete $parms 2>&1"
-		oops="`ip route delete $parms 2>&1`"
-		;;
-	esac
-	status="$?"
-	if test " $oops" = " " -a " $status" != " 0"
-	then
-		oops="silent error, exit status $status"
-	fi
-	case "$oops" in
-	*'RTNETLINK answers: No such process'*)
-		# This is what route (currently -- not documented!) gives
-		# for "could not find such a route".
-		oops=
-		status=0
-		;;
-	esac
-	if test " $oops" != " " -o " $status" != " 0"
-	then
-		echo "$0: \`$it' failed ($oops)" >&2
-	fi
-	exit $status
-	;;
-route-host:*|route-client:*)
-	# connection to me or my client subnet being routed
-	uproute
-	;;
-unroute-host:*|unroute-client:*)
-	# connection to me or my client subnet being unrouted
-	downroute
-	;;
 up-host:)
 	# connection to me coming up
 	# If you are doing a custom version, firewall commands go here.
@@ -421,6 +253,14 @@ up-host:iptables)
 	    -s $PLUTO_ME $S_MY_PORT $IPSEC_POLICY_OUT \
 	    -d $PLUTO_PEER_CLIENT $D_PEER_PORT -j ACCEPT
 	#
+	# allow IPIP traffic because of the implicit SA created by the kernel if
+	# IPComp is used (for small inbound packets that are not compressed)
+	if [ -n "$PLUTO_IPCOMP" ]
+	then
+	  iptables -I INPUT 1 -i $PLUTO_INTERFACE -p 4 \
+	      -s $PLUTO_PEER -d $PLUTO_ME $IPSEC_POLICY_IN -j ACCEPT
+	fi
+	#
 	# log IPsec host connection setup
 	if [ $VPN_LOGGING ]
 	then
@@ -445,6 +285,13 @@ down-host:iptables)
 	    -s $PLUTO_ME $S_MY_PORT $IPSEC_POLICY_OUT \
 	    -d $PLUTO_PEER_CLIENT $D_PEER_PORT -j ACCEPT
 	#
+	# IPIP exception teardown
+	if [ -n "$PLUTO_IPCOMP" ]
+	then
+	  iptables -D INPUT -i $PLUTO_INTERFACE -p 4 \
+	      -s $PLUTO_PEER -d $PLUTO_ME $IPSEC_POLICY_IN -j ACCEPT
+	fi
+	#
 	# log IPsec host connection teardown
 	if [ $VPN_LOGGING ]
 	then
@@ -484,6 +331,15 @@ up-client:iptables)
 	      -d $PLUTO_PEER_CLIENT $D_PEER_PORT $IPSEC_POLICY_OUT -j ACCEPT
 	fi
 	#
+	# allow IPIP traffic because of the implicit SA created by the kernel if
+	# IPComp is used (for small inbound packets that are not compressed).
+	# INPUT is correct here even for forwarded traffic.
+	if [ -n "$PLUTO_IPCOMP" ]
+	then
+	  iptables -I INPUT 1 -i $PLUTO_INTERFACE -p 4 \
+	      -s $PLUTO_PEER -d $PLUTO_ME $IPSEC_POLICY_IN -j ACCEPT
+	fi
+	#
 	# log IPsec client connection setup
 	if [ $VPN_LOGGING ]
 	then
@@ -527,6 +383,13 @@ down-client:iptables)
 	         $IPSEC_POLICY_OUT -j ACCEPT
 	fi
 	#
+	# IPIP exception teardown
+	if [ -n "$PLUTO_IPCOMP" ]
+	then
+	  iptables -D INPUT -i $PLUTO_INTERFACE -p 4 \
+	      -s $PLUTO_PEER -d $PLUTO_ME $IPSEC_POLICY_IN -j ACCEPT
+	fi
+	#
 	# log IPsec client connection teardown
 	if [ $VPN_LOGGING ]
 	then
@@ -543,16 +406,6 @@ down-client:iptables)
 #
 # IPv6
 #
-prepare-host-v6:*|prepare-client-v6:*)
-	;;
-route-host-v6:*|route-client-v6:*)
-	# connection to me or my client subnet being routed
-	#uproute_v6
-	;;
-unroute-host-v6:*|unroute-client-v6:*)
-	# connection to me or my client subnet being unrouted
-	#downroute_v6
-	;;
 up-host-v6:)
 	# connection to me coming up
 	# If you are doing a custom version, firewall commands go here.
diff --git a/testing/tests/libipsec/net2net-cert/hosts/sun/etc/updown b/testing/tests/libipsec/net2net-cert/hosts/sun/etc/updown
index 1a68ada..1b362e6 100755
--- a/testing/tests/libipsec/net2net-cert/hosts/sun/etc/updown
+++ b/testing/tests/libipsec/net2net-cert/hosts/sun/etc/updown
@@ -1,5 +1,5 @@
-#! /bin/sh
-# iproute2 version, default updown script
+#!/bin/sh
+# default updown script
 #
 # Copyright (C) 2003-2004 Nigel Meteringham
 # Copyright (C) 2003-2004 Tuomo Soini
@@ -22,8 +22,6 @@
 # that, and use the (left/right)updown parameters in ipsec.conf to make
 # strongSwan use yours instead of this default one.
 
-# things that this script gets (from ipsec_pluto(8) man page)
-#
 #      PLUTO_VERSION
 #              indicates  what  version of this interface is being
 #              used.  This document describes version  1.1.   This
@@ -41,15 +39,17 @@
 #              is the name of the  connection  for  which  we  are
 #              routing.
 #
-#       PLUTO_NEXT_HOP
-#              is the next hop to which packets bound for the peer
-#              must be sent.
-#
 #       PLUTO_INTERFACE
 #              is the name of the ipsec interface to be used.
 #
 #       PLUTO_REQID
-#              is the requid of the ESP policy
+#              is the requid of the AH|ESP policy
+#
+#       PLUTO_PROTO
+#              is the negotiated IPsec protocol, ah|esp
+#
+#       PLUTO_IPCOMP
+#              is not empty if IPComp was negotiated
 #
 #       PLUTO_UNIQUEID
 #              is the unique identifier of the associated IKE_SA
@@ -66,15 +66,6 @@
 #              host's own IP address / max (where max  is  32  for
 #              IPv4 and 128 for IPv6).
 #
-#       PLUTO_MY_CLIENT_NET
-#              is the IP address of our client net.  If the client
-#              is just the host, this will be the  host's  own  IP
-#              address.
-#
-#       PLUTO_MY_CLIENT_MASK
-#              is  the  mask for our client net.  If the client is
-#              just the host, this will be 255.255.255.255.
-#
 #       PLUTO_MY_SOURCEIP
 #       PLUTO_MY_SOURCEIP4_$i
 #       PLUTO_MY_SOURCEIP6_$i
@@ -88,7 +79,8 @@
 #
 #       PLUTO_MY_PORT
 #              is  the  UDP/TCP  port  to  which  the IPsec SA  is
-#              restricted on our side.
+#              restricted on our side.  For ICMP/ICMPv6 this contains the
+#              message type, and PLUTO_PEER_PORT the message code.
 #
 #       PLUTO_PEER
 #              is the IP address of our peer.
@@ -96,31 +88,19 @@
 #       PLUTO_PEER_ID
 #              is the ID of our peer.
 #
-#       PLUTO_PEER_CA
-#              is the CA which issued the cert of our peer.
-#
 #       PLUTO_PEER_CLIENT
 #              is the IP address / count of the peer's client sub-
 #              net.   If the client is just the peer, this will be
 #              the peer's own IP address / max (where  max  is  32
 #              for IPv4 and 128 for IPv6).
 #
-#       PLUTO_PEER_CLIENT_NET
-#              is the IP address of the peer's client net.  If the
-#              client is just the peer, this will  be  the  peer's
-#              own IP address.
-#
-#       PLUTO_PEER_CLIENT_MASK
-#              is  the  mask  for  the  peer's client net.  If the
-#              client   is   just   the   peer,   this   will   be
-#              255.255.255.255.
-#
 #       PLUTO_PEER_PROTOCOL
 #              is the IP protocol that will be transported.
 #
 #       PLUTO_PEER_PORT
 #              is  the  UDP/TCP  port  to  which  the IPsec SA  is
-#              restricted on the peer side.
+#              restricted on the peer side.  For ICMP/ICMPv6 this contains the
+#              message code, and PLUTO_MY_PORT the message type.
 #
 #       PLUTO_XAUTH_ID
 #              is an optional user ID employed by the XAUTH protocol
@@ -146,7 +126,7 @@
 PATH="/sbin:/bin:/usr/sbin:/usr/bin:/usr/sbin"
 export PATH
 
-# uncomment to log VPN connections
+# comment to disable logging VPN connections to syslog
 VPN_LOGGING=1
 #
 # tag put in front of each log entry:
@@ -160,21 +140,11 @@ FAC_PRIO=local0.notice
 #
 # local0.notice                   -/var/log/vpn
 
-# in order to use source IP routing the Linux kernel options
-# CONFIG_IP_ADVANCED_ROUTER and CONFIG_IP_MULTIPLE_TABLES
-# must be enabled
-#
-# special routing table for sourceip routes
-SOURCEIP_ROUTING_TABLE=220
-#
-# priority of the sourceip routing table
-SOURCEIP_ROUTING_TABLE_PRIO=220
-
 # check interface version
 case "$PLUTO_VERSION" in
-1.[0|1])	# Older Pluto?!?  Play it safe, script may be using new features.
+1.[0|1])	# Older release?!?  Play it safe, script may be using new features.
 	echo "$0: obsolete interface version \`$PLUTO_VERSION'," >&2
-	echo "$0: 	called by obsolete Pluto?" >&2
+	echo "$0: 	called by obsolete release?" >&2
 	exit 2
 	;;
 1.*)	;;
@@ -196,190 +166,52 @@ custom:*)		# custom parameters (see above CAUTION comment)
 	;;
 esac
 
-# utility functions for route manipulation
-# Meddling with this stuff should not be necessary and requires great care.
-uproute() {
-	doroute add
-	ip route flush cache
-}
-downroute() {
-	doroute delete
-	ip route flush cache
-}
-
-addsource() {
-	st=0
-	if ! ip -o route get ${PLUTO_MY_SOURCEIP%/*} | grep -q ^local
-	then
-	    it="ip addr add ${PLUTO_MY_SOURCEIP%/*}/32 dev $PLUTO_INTERFACE"
-	    oops="`eval $it 2>&1`"
-	    st=$?
-	    if test " $oops" = " " -a " $st" != " 0"
-	    then
-		oops="silent error, exit status $st"
-	    fi
-	    if test " $oops" != " " -o " $st" != " 0"
-	    then
-		echo "$0: addsource \`$it' failed ($oops)" >&2
-	    fi
-	fi
-	return $st
-}
-
-doroute() {
-	st=0
-
-	if [ -z "$PLUTO_MY_SOURCEIP" ]
-	then
-	    for dir in /etc/sysconfig /etc/conf.d; do
-		if [ -f "$dir/defaultsource" ]
-		then
-		    . "$dir/defaultsource"
-		fi
-	    done
-
-	    if [ -n "$DEFAULTSOURCE" ]
-	    then
-		PLUTO_MY_SOURCEIP=$DEFAULTSOURCE
-	    fi
-        fi
-
-	if [ -z "$KLIPS" -a -z "$PLUTO_MY_SOURCEIP" ]
-	then
-	    # leave because no route entry is required
-	    return $st
-	fi
-
-	parms1="$PLUTO_PEER_CLIENT"
-
-	if [ -n "$PLUTO_NEXT_HOP" ]
-	then
-	    parms2="via $PLUTO_NEXT_HOP"
-	else
-	    parms2="via $PLUTO_PEER"
-	fi
-	parms2="$parms2 dev $PLUTO_INTERFACE"
-
-	parms3=
-	if [ -n "$PLUTO_MY_SOURCEIP" ]
-	then
-	    if test "$1" = "add"
-	    then
-		addsource
-		if ! ip rule list | grep -q "lookup $SOURCEIP_ROUTING_TABLE"
-		then
-		    ip rule add pref $SOURCEIP_ROUTING_TABLE_PRIO table $SOURCEIP_ROUTING_TABLE
-		fi
-	    fi
-	    parms3="$parms3 src ${PLUTO_MY_SOURCEIP%/*} table $SOURCEIP_ROUTING_TABLE"
-	fi
+IPSEC_POLICY="-m policy --pol ipsec --proto $PLUTO_PROTO --reqid $PLUTO_REQID"
+IPSEC_POLICY_IN="$IPSEC_POLICY --dir in"
+IPSEC_POLICY_OUT="$IPSEC_POLICY --dir out"
 
-	case "$PLUTO_PEER_CLIENT_NET/$PLUTO_PEER_CLIENT_MASK" in
-	"0.0.0.0/0.0.0.0")
-		# opportunistic encryption work around
-		# need to provide route that eclipses default, without
-		# replacing it.
-		it="ip route $1 0.0.0.0/1 $parms2 $parms3 &&
-			ip route $1 128.0.0.0/1 $parms2 $parms3"
-		;;
-	*)	it="ip route $1 $parms1 $parms2 $parms3"
-		;;
-	esac
-	oops="`eval $it 2>&1`"
-	st=$?
-	if test " $oops" = " " -a " $st" != " 0"
-	then
-	    oops="silent error, exit status $st"
-	fi
-	if test " $oops" != " " -o " $st" != " 0"
-	then
-	    echo "$0: doroute \`$it' failed ($oops)" >&2
-	fi
-	return $st
-}
-
-# in the presence of KLIPS and ipsecN interfaces do not use IPSEC_POLICY
-if [ `echo "$PLUTO_INTERFACE" | grep "ipsec"` ]
-then
-	KLIPS=1
-	IPSEC_POLICY_IN=""
-	IPSEC_POLICY_OUT=""
-else
-	KLIPS=
-	IPSEC_POLICY="-m policy --pol ipsec --proto esp --reqid $PLUTO_REQID"
-	IPSEC_POLICY_IN="$IPSEC_POLICY --dir in"
-	IPSEC_POLICY_OUT="$IPSEC_POLICY --dir out"
-fi
+# use protocol specific options to set ports
+case "$PLUTO_MY_PROTOCOL" in
+1)	# ICMP
+	ICMP_TYPE_OPTION="--icmp-type"
+	;;
+58)	# ICMPv6
+	ICMP_TYPE_OPTION="--icmpv6-type"
+	;;
+*)
+	;;
+esac
 
 # are there port numbers?
 if [ "$PLUTO_MY_PORT" != 0 ]
 then
-	S_MY_PORT="--sport $PLUTO_MY_PORT"
-	D_MY_PORT="--dport $PLUTO_MY_PORT"
+	if [ -n "$ICMP_TYPE_OPTION" ]
+	then
+		S_MY_PORT="$ICMP_TYPE_OPTION $PLUTO_MY_PORT"
+		D_MY_PORT="$ICMP_TYPE_OPTION $PLUTO_MY_PORT"
+	else
+		S_MY_PORT="--sport $PLUTO_MY_PORT"
+		D_MY_PORT="--dport $PLUTO_MY_PORT"
+	fi
 fi
 if [ "$PLUTO_PEER_PORT" != 0 ]
 then
-	S_PEER_PORT="--sport $PLUTO_PEER_PORT"
-	D_PEER_PORT="--dport $PLUTO_PEER_PORT"
+	if [ -n "$ICMP_TYPE_OPTION" ]
+	then
+		# the syntax is --icmp[v6]-type type[/code], so add it to the existing option
+		S_MY_PORT="$S_MY_PORT/$PLUTO_PEER_PORT"
+		D_MY_PORT="$D_MY_PORT/$PLUTO_PEER_PORT"
+	else
+		S_PEER_PORT="--sport $PLUTO_PEER_PORT"
+		D_PEER_PORT="--dport $PLUTO_PEER_PORT"
+	fi
 fi
 
 # resolve octal escape sequences
 PLUTO_MY_ID=`printf "$PLUTO_MY_ID"`
 PLUTO_PEER_ID=`printf "$PLUTO_PEER_ID"`
 
-# the big choice
 case "$PLUTO_VERB:$1" in
-prepare-host:*|prepare-client:*)
-	if [ -z "$KLIPS" -a -z "$PLUTO_MY_SOURCEIP" ]
-	then
-	    # exit because no route will be added,
-	    # so that existing routes can stay
-	    exit 0
-	fi
-
-	# delete possibly-existing route (preliminary to adding a route)
-	case "$PLUTO_PEER_CLIENT_NET/$PLUTO_PEER_CLIENT_MASK" in
-	"0.0.0.0/0.0.0.0")
-		# need to provide route that eclipses default, without
-		# replacing it.
-		parms1="0.0.0.0/1"
-		parms2="128.0.0.0/1"
-		it="ip route delete $parms1 2>&1 ; ip route delete $parms2 2>&1"
-		oops="`ip route delete $parms1 2>&1 ; ip route delete $parms2 2>&1`"
-		;;
-	*)
-		parms="$PLUTO_PEER_CLIENT"
-		it="ip route delete $parms 2>&1"
-		oops="`ip route delete $parms 2>&1`"
-		;;
-	esac
-	status="$?"
-	if test " $oops" = " " -a " $status" != " 0"
-	then
-		oops="silent error, exit status $status"
-	fi
-	case "$oops" in
-	*'RTNETLINK answers: No such process'*)
-		# This is what route (currently -- not documented!) gives
-		# for "could not find such a route".
-		oops=
-		status=0
-		;;
-	esac
-	if test " $oops" != " " -o " $status" != " 0"
-	then
-		echo "$0: \`$it' failed ($oops)" >&2
-	fi
-	exit $status
-	;;
-route-host:*|route-client:*)
-	# connection to me or my client subnet being routed
-	uproute
-	;;
-unroute-host:*|unroute-client:*)
-	# connection to me or my client subnet being unrouted
-	downroute
-	;;
 up-host:)
 	# connection to me coming up
 	# If you are doing a custom version, firewall commands go here.
@@ -421,6 +253,14 @@ up-host:iptables)
 	    -s $PLUTO_ME $S_MY_PORT $IPSEC_POLICY_OUT \
 	    -d $PLUTO_PEER_CLIENT $D_PEER_PORT -j ACCEPT
 	#
+	# allow IPIP traffic because of the implicit SA created by the kernel if
+	# IPComp is used (for small inbound packets that are not compressed)
+	if [ -n "$PLUTO_IPCOMP" ]
+	then
+	  iptables -I INPUT 1 -i $PLUTO_INTERFACE -p 4 \
+	      -s $PLUTO_PEER -d $PLUTO_ME $IPSEC_POLICY_IN -j ACCEPT
+	fi
+	#
 	# log IPsec host connection setup
 	if [ $VPN_LOGGING ]
 	then
@@ -445,6 +285,13 @@ down-host:iptables)
 	    -s $PLUTO_ME $S_MY_PORT $IPSEC_POLICY_OUT \
 	    -d $PLUTO_PEER_CLIENT $D_PEER_PORT -j ACCEPT
 	#
+	# IPIP exception teardown
+	if [ -n "$PLUTO_IPCOMP" ]
+	then
+	  iptables -D INPUT -i $PLUTO_INTERFACE -p 4 \
+	      -s $PLUTO_PEER -d $PLUTO_ME $IPSEC_POLICY_IN -j ACCEPT
+	fi
+	#
 	# log IPsec host connection teardown
 	if [ $VPN_LOGGING ]
 	then
@@ -484,6 +331,15 @@ up-client:iptables)
 	      -d $PLUTO_PEER_CLIENT $D_PEER_PORT $IPSEC_POLICY_OUT -j ACCEPT
 	fi
 	#
+	# allow IPIP traffic because of the implicit SA created by the kernel if
+	# IPComp is used (for small inbound packets that are not compressed).
+	# INPUT is correct here even for forwarded traffic.
+	if [ -n "$PLUTO_IPCOMP" ]
+	then
+	  iptables -I INPUT 1 -i $PLUTO_INTERFACE -p 4 \
+	      -s $PLUTO_PEER -d $PLUTO_ME $IPSEC_POLICY_IN -j ACCEPT
+	fi
+	#
 	# log IPsec client connection setup
 	if [ $VPN_LOGGING ]
 	then
@@ -527,6 +383,13 @@ down-client:iptables)
 	         $IPSEC_POLICY_OUT -j ACCEPT
 	fi
 	#
+	# IPIP exception teardown
+	if [ -n "$PLUTO_IPCOMP" ]
+	then
+	  iptables -D INPUT -i $PLUTO_INTERFACE -p 4 \
+	      -s $PLUTO_PEER -d $PLUTO_ME $IPSEC_POLICY_IN -j ACCEPT
+	fi
+	#
 	# log IPsec client connection teardown
 	if [ $VPN_LOGGING ]
 	then
@@ -543,16 +406,6 @@ down-client:iptables)
 #
 # IPv6
 #
-prepare-host-v6:*|prepare-client-v6:*)
-	;;
-route-host-v6:*|route-client-v6:*)
-	# connection to me or my client subnet being routed
-	#uproute_v6
-	;;
-unroute-host-v6:*|unroute-client-v6:*)
-	# connection to me or my client subnet being unrouted
-	#downroute_v6
-	;;
 up-host-v6:)
 	# connection to me coming up
 	# If you are doing a custom version, firewall commands go here.
diff --git a/testing/tests/libipsec/rw-suite-b/evaltest.dat b/testing/tests/libipsec/rw-suite-b/evaltest.dat
index d59ea3c..3a9493b 100644
--- a/testing/tests/libipsec/rw-suite-b/evaltest.dat
+++ b/testing/tests/libipsec/rw-suite-b/evaltest.dat
@@ -1,8 +1,8 @@
 carol::cat /var/log/daemon.log::openssl FIPS mode(2) - enabled::YES
-dave:: cat /var/log/daemon.log::openssl FIPS mode(2) - enabled::YES 
+dave:: cat /var/log/daemon.log::openssl FIPS mode(2) - enabled::YES
 moon:: cat /var/log/daemon.log::openssl FIPS mode(2) - enabled::YES
-moon:: cat /var/log/daemon.log::authentication of.*carol at strongswan.org.*with ECDSA-256 signature successful::YES
-moon:: cat /var/log/daemon.log::authentication of.*dave at strongswan.org.*with ECDSA-256 signature successful::YES
+moon:: cat /var/log/daemon.log::authentication of.*carol at strongswan.org.*with ECDSA_WITH_SHA256_DER successful::YES
+moon:: cat /var/log/daemon.log::authentication of.*dave at strongswan.org.*with ECDSA_WITH_SHA256_DER successful::YES
 carol::ipsec status 2> /dev/null::home.*ESTABLISHED.*carol at strongswan.org.*moon.strongswan.org::YES
 dave:: ipsec status 2> /dev/null::home.*ESTABLISHED.*dave at strongswan.org.*moon.strongswan.org::YES
 moon:: ipsec status 2> /dev/null::rw\[1]: ESTABLISHED.*moon.strongswan.org.*carol at strongswan.org::YES
diff --git a/testing/tests/libipsec/rw-suite-b/hosts/carol/etc/updown b/testing/tests/libipsec/rw-suite-b/hosts/carol/etc/updown
index 15c2394..7d0c583 100755
--- a/testing/tests/libipsec/rw-suite-b/hosts/carol/etc/updown
+++ b/testing/tests/libipsec/rw-suite-b/hosts/carol/etc/updown
@@ -1,5 +1,5 @@
-#! /bin/sh
-# iproute2 version, default updown script
+#!/bin/sh
+# default updown script
 #
 # Copyright (C) 2003-2004 Nigel Meteringham
 # Copyright (C) 2003-2004 Tuomo Soini
@@ -22,8 +22,6 @@
 # that, and use the (left/right)updown parameters in ipsec.conf to make
 # strongSwan use yours instead of this default one.
 
-# things that this script gets (from ipsec_pluto(8) man page)
-#
 #      PLUTO_VERSION
 #              indicates  what  version of this interface is being
 #              used.  This document describes version  1.1.   This
@@ -41,15 +39,17 @@
 #              is the name of the  connection  for  which  we  are
 #              routing.
 #
-#       PLUTO_NEXT_HOP
-#              is the next hop to which packets bound for the peer
-#              must be sent.
-#
 #       PLUTO_INTERFACE
 #              is the name of the ipsec interface to be used.
 #
 #       PLUTO_REQID
-#              is the requid of the ESP policy
+#              is the requid of the AH|ESP policy
+#
+#       PLUTO_PROTO
+#              is the negotiated IPsec protocol, ah|esp
+#
+#       PLUTO_IPCOMP
+#              is not empty if IPComp was negotiated
 #
 #       PLUTO_UNIQUEID
 #              is the unique identifier of the associated IKE_SA
@@ -66,15 +66,6 @@
 #              host's own IP address / max (where max  is  32  for
 #              IPv4 and 128 for IPv6).
 #
-#       PLUTO_MY_CLIENT_NET
-#              is the IP address of our client net.  If the client
-#              is just the host, this will be the  host's  own  IP
-#              address.
-#
-#       PLUTO_MY_CLIENT_MASK
-#              is  the  mask for our client net.  If the client is
-#              just the host, this will be 255.255.255.255.
-#
 #       PLUTO_MY_SOURCEIP
 #       PLUTO_MY_SOURCEIP4_$i
 #       PLUTO_MY_SOURCEIP6_$i
@@ -88,7 +79,8 @@
 #
 #       PLUTO_MY_PORT
 #              is  the  UDP/TCP  port  to  which  the IPsec SA  is
-#              restricted on our side.
+#              restricted on our side.  For ICMP/ICMPv6 this contains the
+#              message type, and PLUTO_PEER_PORT the message code.
 #
 #       PLUTO_PEER
 #              is the IP address of our peer.
@@ -96,31 +88,19 @@
 #       PLUTO_PEER_ID
 #              is the ID of our peer.
 #
-#       PLUTO_PEER_CA
-#              is the CA which issued the cert of our peer.
-#
 #       PLUTO_PEER_CLIENT
 #              is the IP address / count of the peer's client sub-
 #              net.   If the client is just the peer, this will be
 #              the peer's own IP address / max (where  max  is  32
 #              for IPv4 and 128 for IPv6).
 #
-#       PLUTO_PEER_CLIENT_NET
-#              is the IP address of the peer's client net.  If the
-#              client is just the peer, this will  be  the  peer's
-#              own IP address.
-#
-#       PLUTO_PEER_CLIENT_MASK
-#              is  the  mask  for  the  peer's client net.  If the
-#              client   is   just   the   peer,   this   will   be
-#              255.255.255.255.
-#
 #       PLUTO_PEER_PROTOCOL
 #              is the IP protocol that will be transported.
 #
 #       PLUTO_PEER_PORT
 #              is  the  UDP/TCP  port  to  which  the IPsec SA  is
-#              restricted on the peer side.
+#              restricted on the peer side.  For ICMP/ICMPv6 this contains the
+#              message code, and PLUTO_MY_PORT the message type.
 #
 #       PLUTO_XAUTH_ID
 #              is an optional user ID employed by the XAUTH protocol
@@ -146,7 +126,7 @@
 PATH="/sbin:/bin:/usr/sbin:/usr/bin:/usr/sbin"
 export PATH
 
-# uncomment to log VPN connections
+# comment to disable logging VPN connections to syslog
 VPN_LOGGING=1
 #
 # tag put in front of each log entry:
@@ -160,21 +140,11 @@ FAC_PRIO=local0.notice
 #
 # local0.notice                   -/var/log/vpn
 
-# in order to use source IP routing the Linux kernel options
-# CONFIG_IP_ADVANCED_ROUTER and CONFIG_IP_MULTIPLE_TABLES
-# must be enabled
-#
-# special routing table for sourceip routes
-SOURCEIP_ROUTING_TABLE=220
-#
-# priority of the sourceip routing table
-SOURCEIP_ROUTING_TABLE_PRIO=220
-
 # check interface version
 case "$PLUTO_VERSION" in
-1.[0|1])	# Older Pluto?!?  Play it safe, script may be using new features.
+1.[0|1])	# Older release?!?  Play it safe, script may be using new features.
 	echo "$0: obsolete interface version \`$PLUTO_VERSION'," >&2
-	echo "$0: 	called by obsolete Pluto?" >&2
+	echo "$0: 	called by obsolete release?" >&2
 	exit 2
 	;;
 1.*)	;;
@@ -196,190 +166,52 @@ custom:*)		# custom parameters (see above CAUTION comment)
 	;;
 esac
 
-# utility functions for route manipulation
-# Meddling with this stuff should not be necessary and requires great care.
-uproute() {
-	doroute add
-	ip route flush cache
-}
-downroute() {
-	doroute delete
-	ip route flush cache
-}
-
-addsource() {
-	st=0
-	if ! ip -o route get ${PLUTO_MY_SOURCEIP%/*} | grep -q ^local
-	then
-	    it="ip addr add ${PLUTO_MY_SOURCEIP%/*}/32 dev $PLUTO_INTERFACE"
-	    oops="`eval $it 2>&1`"
-	    st=$?
-	    if test " $oops" = " " -a " $st" != " 0"
-	    then
-		oops="silent error, exit status $st"
-	    fi
-	    if test " $oops" != " " -o " $st" != " 0"
-	    then
-		echo "$0: addsource \`$it' failed ($oops)" >&2
-	    fi
-	fi
-	return $st
-}
-
-doroute() {
-	st=0
-
-	if [ -z "$PLUTO_MY_SOURCEIP" ]
-	then
-	    for dir in /etc/sysconfig /etc/conf.d; do
-		if [ -f "$dir/defaultsource" ]
-		then
-		    . "$dir/defaultsource"
-		fi
-	    done
-
-	    if [ -n "$DEFAULTSOURCE" ]
-	    then
-		PLUTO_MY_SOURCEIP=$DEFAULTSOURCE
-	    fi
-        fi
+IPSEC_POLICY="-m policy --pol ipsec --proto $PLUTO_PROTO --reqid $PLUTO_REQID"
+IPSEC_POLICY_IN="$IPSEC_POLICY --dir in"
+IPSEC_POLICY_OUT="$IPSEC_POLICY --dir out"
 
-	if [ -z "$KLIPS" -a -z "$PLUTO_MY_SOURCEIP" ]
-	then
-	    # leave because no route entry is required
-	    return $st
-	fi
-
-	parms1="$PLUTO_PEER_CLIENT"
-
-	if [ -n "$PLUTO_NEXT_HOP" ]
-	then
-	    parms2="via $PLUTO_NEXT_HOP"
-	else
-	    parms2="via $PLUTO_PEER"
-	fi
-	parms2="$parms2 dev $PLUTO_INTERFACE"
-
-	parms3=
-	if [ -n "$PLUTO_MY_SOURCEIP" ]
-	then
-	    if test "$1" = "add"
-	    then
-		addsource
-		if ! ip rule list | grep -q "lookup $SOURCEIP_ROUTING_TABLE"
-		then
-		    ip rule add pref $SOURCEIP_ROUTING_TABLE_PRIO table $SOURCEIP_ROUTING_TABLE
-		fi
-	    fi
-	    parms3="$parms3 src ${PLUTO_MY_SOURCEIP%/*} table $SOURCEIP_ROUTING_TABLE"
-	fi
-
-	case "$PLUTO_PEER_CLIENT_NET/$PLUTO_PEER_CLIENT_MASK" in
-	"0.0.0.0/0.0.0.0")
-		# opportunistic encryption work around
-		# need to provide route that eclipses default, without
-		# replacing it.
-		it="ip route $1 0.0.0.0/1 $parms2 $parms3 &&
-			ip route $1 128.0.0.0/1 $parms2 $parms3"
-		;;
-	*)	it="ip route $1 $parms1 $parms2 $parms3"
-		;;
-	esac
-	oops="`eval $it 2>&1`"
-	st=$?
-	if test " $oops" = " " -a " $st" != " 0"
-	then
-	    oops="silent error, exit status $st"
-	fi
-	if test " $oops" != " " -o " $st" != " 0"
-	then
-	    echo "$0: doroute \`$it' failed ($oops)" >&2
-	fi
-	return $st
-}
-
-# in the presence of KLIPS and ipsecN interfaces do not use IPSEC_POLICY
-if [ `echo "$PLUTO_INTERFACE" | grep "ipsec"` ]
-then
-	KLIPS=1
-	IPSEC_POLICY_IN=""
-	IPSEC_POLICY_OUT=""
-else
-	KLIPS=
-	IPSEC_POLICY="-m policy --pol ipsec --proto esp --reqid $PLUTO_REQID"
-	IPSEC_POLICY_IN="$IPSEC_POLICY --dir in"
-	IPSEC_POLICY_OUT="$IPSEC_POLICY --dir out"
-fi
+# use protocol specific options to set ports
+case "$PLUTO_MY_PROTOCOL" in
+1)	# ICMP
+	ICMP_TYPE_OPTION="--icmp-type"
+	;;
+58)	# ICMPv6
+	ICMP_TYPE_OPTION="--icmpv6-type"
+	;;
+*)
+	;;
+esac
 
 # are there port numbers?
 if [ "$PLUTO_MY_PORT" != 0 ]
 then
-	S_MY_PORT="--sport $PLUTO_MY_PORT"
-	D_MY_PORT="--dport $PLUTO_MY_PORT"
+	if [ -n "$ICMP_TYPE_OPTION" ]
+	then
+		S_MY_PORT="$ICMP_TYPE_OPTION $PLUTO_MY_PORT"
+		D_MY_PORT="$ICMP_TYPE_OPTION $PLUTO_MY_PORT"
+	else
+		S_MY_PORT="--sport $PLUTO_MY_PORT"
+		D_MY_PORT="--dport $PLUTO_MY_PORT"
+	fi
 fi
 if [ "$PLUTO_PEER_PORT" != 0 ]
 then
-	S_PEER_PORT="--sport $PLUTO_PEER_PORT"
-	D_PEER_PORT="--dport $PLUTO_PEER_PORT"
+	if [ -n "$ICMP_TYPE_OPTION" ]
+	then
+		# the syntax is --icmp[v6]-type type[/code], so add it to the existing option
+		S_MY_PORT="$S_MY_PORT/$PLUTO_PEER_PORT"
+		D_MY_PORT="$D_MY_PORT/$PLUTO_PEER_PORT"
+	else
+		S_PEER_PORT="--sport $PLUTO_PEER_PORT"
+		D_PEER_PORT="--dport $PLUTO_PEER_PORT"
+	fi
 fi
 
 # resolve octal escape sequences
 PLUTO_MY_ID=`printf "$PLUTO_MY_ID"`
 PLUTO_PEER_ID=`printf "$PLUTO_PEER_ID"`
 
-# the big choice
 case "$PLUTO_VERB:$1" in
-prepare-host:*|prepare-client:*)
-	if [ -z "$KLIPS" -a -z "$PLUTO_MY_SOURCEIP" ]
-	then
-	    # exit because no route will be added,
-	    # so that existing routes can stay
-	    exit 0
-	fi
-
-	# delete possibly-existing route (preliminary to adding a route)
-	case "$PLUTO_PEER_CLIENT_NET/$PLUTO_PEER_CLIENT_MASK" in
-	"0.0.0.0/0.0.0.0")
-		# need to provide route that eclipses default, without
-		# replacing it.
-		parms1="0.0.0.0/1"
-		parms2="128.0.0.0/1"
-		it="ip route delete $parms1 2>&1 ; ip route delete $parms2 2>&1"
-		oops="`ip route delete $parms1 2>&1 ; ip route delete $parms2 2>&1`"
-		;;
-	*)
-		parms="$PLUTO_PEER_CLIENT"
-		it="ip route delete $parms 2>&1"
-		oops="`ip route delete $parms 2>&1`"
-		;;
-	esac
-	status="$?"
-	if test " $oops" = " " -a " $status" != " 0"
-	then
-		oops="silent error, exit status $status"
-	fi
-	case "$oops" in
-	*'RTNETLINK answers: No such process'*)
-		# This is what route (currently -- not documented!) gives
-		# for "could not find such a route".
-		oops=
-		status=0
-		;;
-	esac
-	if test " $oops" != " " -o " $status" != " 0"
-	then
-		echo "$0: \`$it' failed ($oops)" >&2
-	fi
-	exit $status
-	;;
-route-host:*|route-client:*)
-	# connection to me or my client subnet being routed
-	uproute
-	;;
-unroute-host:*|unroute-client:*)
-	# connection to me or my client subnet being unrouted
-	downroute
-	;;
 up-host:)
 	# connection to me coming up
 	# If you are doing a custom version, firewall commands go here.
@@ -395,7 +227,7 @@ down-host:)
 	# connection to me going down
 	# If you are doing a custom version, firewall commands go here.
 	PLUTO_INTERFACE=ipsec0
- 	iptables -D INPUT -i $PLUTO_INTERFACE -p $PLUTO_MY_PROTOCOL \
+	iptables -D INPUT -i $PLUTO_INTERFACE -p $PLUTO_MY_PROTOCOL \
 	    -s $PLUTO_PEER_CLIENT $S_PEER_PORT \
 	    -d $PLUTO_ME $D_MY_PORT -j ACCEPT
 	iptables -D OUTPUT -o $PLUTO_INTERFACE -p $PLUTO_PEER_PROTOCOL \
@@ -406,8 +238,8 @@ up-client:)
 	# connection to my client subnet coming up
 	# If you are doing a custom version, firewall commands go here.
 	PLUTO_INTERFACE=ipsec0
-        if [ "$PLUTO_PEER_CLIENT" != "$PLUTO_MY_SOURCEIP/32" ]
-        then
+	if [ "$PLUTO_PEER_CLIENT" != "$PLUTO_MY_SOURCEIP/32" ]
+	then
 	    iptables -I FORWARD 1 -o $PLUTO_INTERFACE -p $PLUTO_PEER_PROTOCOL \
 		-s $PLUTO_MY_CLIENT $S_MY_PORT \
 		-d $PLUTO_PEER_CLIENT $D_PEER_PORT -j ACCEPT
@@ -444,7 +276,7 @@ down-client:)
 	if [ -n "$PLUTO_MY_SOURCEIP" -o -n "$PLUTO_HOST_ACCESS" ]
 	then
 	    iptables -D INPUT -i $PLUTO_INTERFACE -p $PLUTO_MY_PROTOCOL \
- 		-s $PLUTO_PEER_CLIENT $S_PEER_PORT \
+		-s $PLUTO_PEER_CLIENT $S_PEER_PORT \
 		-d $PLUTO_MY_CLIENT $D_MY_PORT -j ACCEPT
 	    iptables -D OUTPUT -o $PLUTO_INTERFACE -p $PLUTO_PEER_PROTOCOL \
 		-s $PLUTO_MY_CLIENT $S_MY_PORT \
@@ -462,6 +294,14 @@ up-host:iptables)
 	    -s $PLUTO_ME $S_MY_PORT $IPSEC_POLICY_OUT \
 	    -d $PLUTO_PEER_CLIENT $D_PEER_PORT -j ACCEPT
 	#
+	# allow IPIP traffic because of the implicit SA created by the kernel if
+	# IPComp is used (for small inbound packets that are not compressed)
+	if [ -n "$PLUTO_IPCOMP" ]
+	then
+	  iptables -I INPUT 1 -i $PLUTO_INTERFACE -p 4 \
+	      -s $PLUTO_PEER -d $PLUTO_ME $IPSEC_POLICY_IN -j ACCEPT
+	fi
+	#
 	# log IPsec host connection setup
 	if [ $VPN_LOGGING ]
 	then
@@ -486,6 +326,13 @@ down-host:iptables)
 	    -s $PLUTO_ME $S_MY_PORT $IPSEC_POLICY_OUT \
 	    -d $PLUTO_PEER_CLIENT $D_PEER_PORT -j ACCEPT
 	#
+	# IPIP exception teardown
+	if [ -n "$PLUTO_IPCOMP" ]
+	then
+	  iptables -D INPUT -i $PLUTO_INTERFACE -p 4 \
+	      -s $PLUTO_PEER -d $PLUTO_ME $IPSEC_POLICY_IN -j ACCEPT
+	fi
+	#
 	# log IPsec host connection teardown
 	if [ $VPN_LOGGING ]
 	then
@@ -525,6 +372,15 @@ up-client:iptables)
 	      -d $PLUTO_PEER_CLIENT $D_PEER_PORT $IPSEC_POLICY_OUT -j ACCEPT
 	fi
 	#
+	# allow IPIP traffic because of the implicit SA created by the kernel if
+	# IPComp is used (for small inbound packets that are not compressed).
+	# INPUT is correct here even for forwarded traffic.
+	if [ -n "$PLUTO_IPCOMP" ]
+	then
+	  iptables -I INPUT 1 -i $PLUTO_INTERFACE -p 4 \
+	      -s $PLUTO_PEER -d $PLUTO_ME $IPSEC_POLICY_IN -j ACCEPT
+	fi
+	#
 	# log IPsec client connection setup
 	if [ $VPN_LOGGING ]
 	then
@@ -568,6 +424,13 @@ down-client:iptables)
 	         $IPSEC_POLICY_OUT -j ACCEPT
 	fi
 	#
+	# IPIP exception teardown
+	if [ -n "$PLUTO_IPCOMP" ]
+	then
+	  iptables -D INPUT -i $PLUTO_INTERFACE -p 4 \
+	      -s $PLUTO_PEER -d $PLUTO_ME $IPSEC_POLICY_IN -j ACCEPT
+	fi
+	#
 	# log IPsec client connection teardown
 	if [ $VPN_LOGGING ]
 	then
@@ -584,16 +447,6 @@ down-client:iptables)
 #
 # IPv6
 #
-prepare-host-v6:*|prepare-client-v6:*)
-	;;
-route-host-v6:*|route-client-v6:*)
-	# connection to me or my client subnet being routed
-	#uproute_v6
-	;;
-unroute-host-v6:*|unroute-client-v6:*)
-	# connection to me or my client subnet being unrouted
-	#downroute_v6
-	;;
 up-host-v6:)
 	# connection to me coming up
 	# If you are doing a custom version, firewall commands go here.
diff --git a/testing/tests/libipsec/rw-suite-b/hosts/dave/etc/updown b/testing/tests/libipsec/rw-suite-b/hosts/dave/etc/updown
index 15c2394..7d0c583 100755
--- a/testing/tests/libipsec/rw-suite-b/hosts/dave/etc/updown
+++ b/testing/tests/libipsec/rw-suite-b/hosts/dave/etc/updown
@@ -1,5 +1,5 @@
-#! /bin/sh
-# iproute2 version, default updown script
+#!/bin/sh
+# default updown script
 #
 # Copyright (C) 2003-2004 Nigel Meteringham
 # Copyright (C) 2003-2004 Tuomo Soini
@@ -22,8 +22,6 @@
 # that, and use the (left/right)updown parameters in ipsec.conf to make
 # strongSwan use yours instead of this default one.
 
-# things that this script gets (from ipsec_pluto(8) man page)
-#
 #      PLUTO_VERSION
 #              indicates  what  version of this interface is being
 #              used.  This document describes version  1.1.   This
@@ -41,15 +39,17 @@
 #              is the name of the  connection  for  which  we  are
 #              routing.
 #
-#       PLUTO_NEXT_HOP
-#              is the next hop to which packets bound for the peer
-#              must be sent.
-#
 #       PLUTO_INTERFACE
 #              is the name of the ipsec interface to be used.
 #
 #       PLUTO_REQID
-#              is the requid of the ESP policy
+#              is the requid of the AH|ESP policy
+#
+#       PLUTO_PROTO
+#              is the negotiated IPsec protocol, ah|esp
+#
+#       PLUTO_IPCOMP
+#              is not empty if IPComp was negotiated
 #
 #       PLUTO_UNIQUEID
 #              is the unique identifier of the associated IKE_SA
@@ -66,15 +66,6 @@
 #              host's own IP address / max (where max  is  32  for
 #              IPv4 and 128 for IPv6).
 #
-#       PLUTO_MY_CLIENT_NET
-#              is the IP address of our client net.  If the client
-#              is just the host, this will be the  host's  own  IP
-#              address.
-#
-#       PLUTO_MY_CLIENT_MASK
-#              is  the  mask for our client net.  If the client is
-#              just the host, this will be 255.255.255.255.
-#
 #       PLUTO_MY_SOURCEIP
 #       PLUTO_MY_SOURCEIP4_$i
 #       PLUTO_MY_SOURCEIP6_$i
@@ -88,7 +79,8 @@
 #
 #       PLUTO_MY_PORT
 #              is  the  UDP/TCP  port  to  which  the IPsec SA  is
-#              restricted on our side.
+#              restricted on our side.  For ICMP/ICMPv6 this contains the
+#              message type, and PLUTO_PEER_PORT the message code.
 #
 #       PLUTO_PEER
 #              is the IP address of our peer.
@@ -96,31 +88,19 @@
 #       PLUTO_PEER_ID
 #              is the ID of our peer.
 #
-#       PLUTO_PEER_CA
-#              is the CA which issued the cert of our peer.
-#
 #       PLUTO_PEER_CLIENT
 #              is the IP address / count of the peer's client sub-
 #              net.   If the client is just the peer, this will be
 #              the peer's own IP address / max (where  max  is  32
 #              for IPv4 and 128 for IPv6).
 #
-#       PLUTO_PEER_CLIENT_NET
-#              is the IP address of the peer's client net.  If the
-#              client is just the peer, this will  be  the  peer's
-#              own IP address.
-#
-#       PLUTO_PEER_CLIENT_MASK
-#              is  the  mask  for  the  peer's client net.  If the
-#              client   is   just   the   peer,   this   will   be
-#              255.255.255.255.
-#
 #       PLUTO_PEER_PROTOCOL
 #              is the IP protocol that will be transported.
 #
 #       PLUTO_PEER_PORT
 #              is  the  UDP/TCP  port  to  which  the IPsec SA  is
-#              restricted on the peer side.
+#              restricted on the peer side.  For ICMP/ICMPv6 this contains the
+#              message code, and PLUTO_MY_PORT the message type.
 #
 #       PLUTO_XAUTH_ID
 #              is an optional user ID employed by the XAUTH protocol
@@ -146,7 +126,7 @@
 PATH="/sbin:/bin:/usr/sbin:/usr/bin:/usr/sbin"
 export PATH
 
-# uncomment to log VPN connections
+# comment to disable logging VPN connections to syslog
 VPN_LOGGING=1
 #
 # tag put in front of each log entry:
@@ -160,21 +140,11 @@ FAC_PRIO=local0.notice
 #
 # local0.notice                   -/var/log/vpn
 
-# in order to use source IP routing the Linux kernel options
-# CONFIG_IP_ADVANCED_ROUTER and CONFIG_IP_MULTIPLE_TABLES
-# must be enabled
-#
-# special routing table for sourceip routes
-SOURCEIP_ROUTING_TABLE=220
-#
-# priority of the sourceip routing table
-SOURCEIP_ROUTING_TABLE_PRIO=220
-
 # check interface version
 case "$PLUTO_VERSION" in
-1.[0|1])	# Older Pluto?!?  Play it safe, script may be using new features.
+1.[0|1])	# Older release?!?  Play it safe, script may be using new features.
 	echo "$0: obsolete interface version \`$PLUTO_VERSION'," >&2
-	echo "$0: 	called by obsolete Pluto?" >&2
+	echo "$0: 	called by obsolete release?" >&2
 	exit 2
 	;;
 1.*)	;;
@@ -196,190 +166,52 @@ custom:*)		# custom parameters (see above CAUTION comment)
 	;;
 esac
 
-# utility functions for route manipulation
-# Meddling with this stuff should not be necessary and requires great care.
-uproute() {
-	doroute add
-	ip route flush cache
-}
-downroute() {
-	doroute delete
-	ip route flush cache
-}
-
-addsource() {
-	st=0
-	if ! ip -o route get ${PLUTO_MY_SOURCEIP%/*} | grep -q ^local
-	then
-	    it="ip addr add ${PLUTO_MY_SOURCEIP%/*}/32 dev $PLUTO_INTERFACE"
-	    oops="`eval $it 2>&1`"
-	    st=$?
-	    if test " $oops" = " " -a " $st" != " 0"
-	    then
-		oops="silent error, exit status $st"
-	    fi
-	    if test " $oops" != " " -o " $st" != " 0"
-	    then
-		echo "$0: addsource \`$it' failed ($oops)" >&2
-	    fi
-	fi
-	return $st
-}
-
-doroute() {
-	st=0
-
-	if [ -z "$PLUTO_MY_SOURCEIP" ]
-	then
-	    for dir in /etc/sysconfig /etc/conf.d; do
-		if [ -f "$dir/defaultsource" ]
-		then
-		    . "$dir/defaultsource"
-		fi
-	    done
-
-	    if [ -n "$DEFAULTSOURCE" ]
-	    then
-		PLUTO_MY_SOURCEIP=$DEFAULTSOURCE
-	    fi
-        fi
+IPSEC_POLICY="-m policy --pol ipsec --proto $PLUTO_PROTO --reqid $PLUTO_REQID"
+IPSEC_POLICY_IN="$IPSEC_POLICY --dir in"
+IPSEC_POLICY_OUT="$IPSEC_POLICY --dir out"
 
-	if [ -z "$KLIPS" -a -z "$PLUTO_MY_SOURCEIP" ]
-	then
-	    # leave because no route entry is required
-	    return $st
-	fi
-
-	parms1="$PLUTO_PEER_CLIENT"
-
-	if [ -n "$PLUTO_NEXT_HOP" ]
-	then
-	    parms2="via $PLUTO_NEXT_HOP"
-	else
-	    parms2="via $PLUTO_PEER"
-	fi
-	parms2="$parms2 dev $PLUTO_INTERFACE"
-
-	parms3=
-	if [ -n "$PLUTO_MY_SOURCEIP" ]
-	then
-	    if test "$1" = "add"
-	    then
-		addsource
-		if ! ip rule list | grep -q "lookup $SOURCEIP_ROUTING_TABLE"
-		then
-		    ip rule add pref $SOURCEIP_ROUTING_TABLE_PRIO table $SOURCEIP_ROUTING_TABLE
-		fi
-	    fi
-	    parms3="$parms3 src ${PLUTO_MY_SOURCEIP%/*} table $SOURCEIP_ROUTING_TABLE"
-	fi
-
-	case "$PLUTO_PEER_CLIENT_NET/$PLUTO_PEER_CLIENT_MASK" in
-	"0.0.0.0/0.0.0.0")
-		# opportunistic encryption work around
-		# need to provide route that eclipses default, without
-		# replacing it.
-		it="ip route $1 0.0.0.0/1 $parms2 $parms3 &&
-			ip route $1 128.0.0.0/1 $parms2 $parms3"
-		;;
-	*)	it="ip route $1 $parms1 $parms2 $parms3"
-		;;
-	esac
-	oops="`eval $it 2>&1`"
-	st=$?
-	if test " $oops" = " " -a " $st" != " 0"
-	then
-	    oops="silent error, exit status $st"
-	fi
-	if test " $oops" != " " -o " $st" != " 0"
-	then
-	    echo "$0: doroute \`$it' failed ($oops)" >&2
-	fi
-	return $st
-}
-
-# in the presence of KLIPS and ipsecN interfaces do not use IPSEC_POLICY
-if [ `echo "$PLUTO_INTERFACE" | grep "ipsec"` ]
-then
-	KLIPS=1
-	IPSEC_POLICY_IN=""
-	IPSEC_POLICY_OUT=""
-else
-	KLIPS=
-	IPSEC_POLICY="-m policy --pol ipsec --proto esp --reqid $PLUTO_REQID"
-	IPSEC_POLICY_IN="$IPSEC_POLICY --dir in"
-	IPSEC_POLICY_OUT="$IPSEC_POLICY --dir out"
-fi
+# use protocol specific options to set ports
+case "$PLUTO_MY_PROTOCOL" in
+1)	# ICMP
+	ICMP_TYPE_OPTION="--icmp-type"
+	;;
+58)	# ICMPv6
+	ICMP_TYPE_OPTION="--icmpv6-type"
+	;;
+*)
+	;;
+esac
 
 # are there port numbers?
 if [ "$PLUTO_MY_PORT" != 0 ]
 then
-	S_MY_PORT="--sport $PLUTO_MY_PORT"
-	D_MY_PORT="--dport $PLUTO_MY_PORT"
+	if [ -n "$ICMP_TYPE_OPTION" ]
+	then
+		S_MY_PORT="$ICMP_TYPE_OPTION $PLUTO_MY_PORT"
+		D_MY_PORT="$ICMP_TYPE_OPTION $PLUTO_MY_PORT"
+	else
+		S_MY_PORT="--sport $PLUTO_MY_PORT"
+		D_MY_PORT="--dport $PLUTO_MY_PORT"
+	fi
 fi
 if [ "$PLUTO_PEER_PORT" != 0 ]
 then
-	S_PEER_PORT="--sport $PLUTO_PEER_PORT"
-	D_PEER_PORT="--dport $PLUTO_PEER_PORT"
+	if [ -n "$ICMP_TYPE_OPTION" ]
+	then
+		# the syntax is --icmp[v6]-type type[/code], so add it to the existing option
+		S_MY_PORT="$S_MY_PORT/$PLUTO_PEER_PORT"
+		D_MY_PORT="$D_MY_PORT/$PLUTO_PEER_PORT"
+	else
+		S_PEER_PORT="--sport $PLUTO_PEER_PORT"
+		D_PEER_PORT="--dport $PLUTO_PEER_PORT"
+	fi
 fi
 
 # resolve octal escape sequences
 PLUTO_MY_ID=`printf "$PLUTO_MY_ID"`
 PLUTO_PEER_ID=`printf "$PLUTO_PEER_ID"`
 
-# the big choice
 case "$PLUTO_VERB:$1" in
-prepare-host:*|prepare-client:*)
-	if [ -z "$KLIPS" -a -z "$PLUTO_MY_SOURCEIP" ]
-	then
-	    # exit because no route will be added,
-	    # so that existing routes can stay
-	    exit 0
-	fi
-
-	# delete possibly-existing route (preliminary to adding a route)
-	case "$PLUTO_PEER_CLIENT_NET/$PLUTO_PEER_CLIENT_MASK" in
-	"0.0.0.0/0.0.0.0")
-		# need to provide route that eclipses default, without
-		# replacing it.
-		parms1="0.0.0.0/1"
-		parms2="128.0.0.0/1"
-		it="ip route delete $parms1 2>&1 ; ip route delete $parms2 2>&1"
-		oops="`ip route delete $parms1 2>&1 ; ip route delete $parms2 2>&1`"
-		;;
-	*)
-		parms="$PLUTO_PEER_CLIENT"
-		it="ip route delete $parms 2>&1"
-		oops="`ip route delete $parms 2>&1`"
-		;;
-	esac
-	status="$?"
-	if test " $oops" = " " -a " $status" != " 0"
-	then
-		oops="silent error, exit status $status"
-	fi
-	case "$oops" in
-	*'RTNETLINK answers: No such process'*)
-		# This is what route (currently -- not documented!) gives
-		# for "could not find such a route".
-		oops=
-		status=0
-		;;
-	esac
-	if test " $oops" != " " -o " $status" != " 0"
-	then
-		echo "$0: \`$it' failed ($oops)" >&2
-	fi
-	exit $status
-	;;
-route-host:*|route-client:*)
-	# connection to me or my client subnet being routed
-	uproute
-	;;
-unroute-host:*|unroute-client:*)
-	# connection to me or my client subnet being unrouted
-	downroute
-	;;
 up-host:)
 	# connection to me coming up
 	# If you are doing a custom version, firewall commands go here.
@@ -395,7 +227,7 @@ down-host:)
 	# connection to me going down
 	# If you are doing a custom version, firewall commands go here.
 	PLUTO_INTERFACE=ipsec0
- 	iptables -D INPUT -i $PLUTO_INTERFACE -p $PLUTO_MY_PROTOCOL \
+	iptables -D INPUT -i $PLUTO_INTERFACE -p $PLUTO_MY_PROTOCOL \
 	    -s $PLUTO_PEER_CLIENT $S_PEER_PORT \
 	    -d $PLUTO_ME $D_MY_PORT -j ACCEPT
 	iptables -D OUTPUT -o $PLUTO_INTERFACE -p $PLUTO_PEER_PROTOCOL \
@@ -406,8 +238,8 @@ up-client:)
 	# connection to my client subnet coming up
 	# If you are doing a custom version, firewall commands go here.
 	PLUTO_INTERFACE=ipsec0
-        if [ "$PLUTO_PEER_CLIENT" != "$PLUTO_MY_SOURCEIP/32" ]
-        then
+	if [ "$PLUTO_PEER_CLIENT" != "$PLUTO_MY_SOURCEIP/32" ]
+	then
 	    iptables -I FORWARD 1 -o $PLUTO_INTERFACE -p $PLUTO_PEER_PROTOCOL \
 		-s $PLUTO_MY_CLIENT $S_MY_PORT \
 		-d $PLUTO_PEER_CLIENT $D_PEER_PORT -j ACCEPT
@@ -444,7 +276,7 @@ down-client:)
 	if [ -n "$PLUTO_MY_SOURCEIP" -o -n "$PLUTO_HOST_ACCESS" ]
 	then
 	    iptables -D INPUT -i $PLUTO_INTERFACE -p $PLUTO_MY_PROTOCOL \
- 		-s $PLUTO_PEER_CLIENT $S_PEER_PORT \
+		-s $PLUTO_PEER_CLIENT $S_PEER_PORT \
 		-d $PLUTO_MY_CLIENT $D_MY_PORT -j ACCEPT
 	    iptables -D OUTPUT -o $PLUTO_INTERFACE -p $PLUTO_PEER_PROTOCOL \
 		-s $PLUTO_MY_CLIENT $S_MY_PORT \
@@ -462,6 +294,14 @@ up-host:iptables)
 	    -s $PLUTO_ME $S_MY_PORT $IPSEC_POLICY_OUT \
 	    -d $PLUTO_PEER_CLIENT $D_PEER_PORT -j ACCEPT
 	#
+	# allow IPIP traffic because of the implicit SA created by the kernel if
+	# IPComp is used (for small inbound packets that are not compressed)
+	if [ -n "$PLUTO_IPCOMP" ]
+	then
+	  iptables -I INPUT 1 -i $PLUTO_INTERFACE -p 4 \
+	      -s $PLUTO_PEER -d $PLUTO_ME $IPSEC_POLICY_IN -j ACCEPT
+	fi
+	#
 	# log IPsec host connection setup
 	if [ $VPN_LOGGING ]
 	then
@@ -486,6 +326,13 @@ down-host:iptables)
 	    -s $PLUTO_ME $S_MY_PORT $IPSEC_POLICY_OUT \
 	    -d $PLUTO_PEER_CLIENT $D_PEER_PORT -j ACCEPT
 	#
+	# IPIP exception teardown
+	if [ -n "$PLUTO_IPCOMP" ]
+	then
+	  iptables -D INPUT -i $PLUTO_INTERFACE -p 4 \
+	      -s $PLUTO_PEER -d $PLUTO_ME $IPSEC_POLICY_IN -j ACCEPT
+	fi
+	#
 	# log IPsec host connection teardown
 	if [ $VPN_LOGGING ]
 	then
@@ -525,6 +372,15 @@ up-client:iptables)
 	      -d $PLUTO_PEER_CLIENT $D_PEER_PORT $IPSEC_POLICY_OUT -j ACCEPT
 	fi
 	#
+	# allow IPIP traffic because of the implicit SA created by the kernel if
+	# IPComp is used (for small inbound packets that are not compressed).
+	# INPUT is correct here even for forwarded traffic.
+	if [ -n "$PLUTO_IPCOMP" ]
+	then
+	  iptables -I INPUT 1 -i $PLUTO_INTERFACE -p 4 \
+	      -s $PLUTO_PEER -d $PLUTO_ME $IPSEC_POLICY_IN -j ACCEPT
+	fi
+	#
 	# log IPsec client connection setup
 	if [ $VPN_LOGGING ]
 	then
@@ -568,6 +424,13 @@ down-client:iptables)
 	         $IPSEC_POLICY_OUT -j ACCEPT
 	fi
 	#
+	# IPIP exception teardown
+	if [ -n "$PLUTO_IPCOMP" ]
+	then
+	  iptables -D INPUT -i $PLUTO_INTERFACE -p 4 \
+	      -s $PLUTO_PEER -d $PLUTO_ME $IPSEC_POLICY_IN -j ACCEPT
+	fi
+	#
 	# log IPsec client connection teardown
 	if [ $VPN_LOGGING ]
 	then
@@ -584,16 +447,6 @@ down-client:iptables)
 #
 # IPv6
 #
-prepare-host-v6:*|prepare-client-v6:*)
-	;;
-route-host-v6:*|route-client-v6:*)
-	# connection to me or my client subnet being routed
-	#uproute_v6
-	;;
-unroute-host-v6:*|unroute-client-v6:*)
-	# connection to me or my client subnet being unrouted
-	#downroute_v6
-	;;
 up-host-v6:)
 	# connection to me coming up
 	# If you are doing a custom version, firewall commands go here.
diff --git a/testing/tests/libipsec/rw-suite-b/hosts/moon/etc/updown b/testing/tests/libipsec/rw-suite-b/hosts/moon/etc/updown
index 15c2394..7d0c583 100755
--- a/testing/tests/libipsec/rw-suite-b/hosts/moon/etc/updown
+++ b/testing/tests/libipsec/rw-suite-b/hosts/moon/etc/updown
@@ -1,5 +1,5 @@
-#! /bin/sh
-# iproute2 version, default updown script
+#!/bin/sh
+# default updown script
 #
 # Copyright (C) 2003-2004 Nigel Meteringham
 # Copyright (C) 2003-2004 Tuomo Soini
@@ -22,8 +22,6 @@
 # that, and use the (left/right)updown parameters in ipsec.conf to make
 # strongSwan use yours instead of this default one.
 
-# things that this script gets (from ipsec_pluto(8) man page)
-#
 #      PLUTO_VERSION
 #              indicates  what  version of this interface is being
 #              used.  This document describes version  1.1.   This
@@ -41,15 +39,17 @@
 #              is the name of the  connection  for  which  we  are
 #              routing.
 #
-#       PLUTO_NEXT_HOP
-#              is the next hop to which packets bound for the peer
-#              must be sent.
-#
 #       PLUTO_INTERFACE
 #              is the name of the ipsec interface to be used.
 #
 #       PLUTO_REQID
-#              is the requid of the ESP policy
+#              is the requid of the AH|ESP policy
+#
+#       PLUTO_PROTO
+#              is the negotiated IPsec protocol, ah|esp
+#
+#       PLUTO_IPCOMP
+#              is not empty if IPComp was negotiated
 #
 #       PLUTO_UNIQUEID
 #              is the unique identifier of the associated IKE_SA
@@ -66,15 +66,6 @@
 #              host's own IP address / max (where max  is  32  for
 #              IPv4 and 128 for IPv6).
 #
-#       PLUTO_MY_CLIENT_NET
-#              is the IP address of our client net.  If the client
-#              is just the host, this will be the  host's  own  IP
-#              address.
-#
-#       PLUTO_MY_CLIENT_MASK
-#              is  the  mask for our client net.  If the client is
-#              just the host, this will be 255.255.255.255.
-#
 #       PLUTO_MY_SOURCEIP
 #       PLUTO_MY_SOURCEIP4_$i
 #       PLUTO_MY_SOURCEIP6_$i
@@ -88,7 +79,8 @@
 #
 #       PLUTO_MY_PORT
 #              is  the  UDP/TCP  port  to  which  the IPsec SA  is
-#              restricted on our side.
+#              restricted on our side.  For ICMP/ICMPv6 this contains the
+#              message type, and PLUTO_PEER_PORT the message code.
 #
 #       PLUTO_PEER
 #              is the IP address of our peer.
@@ -96,31 +88,19 @@
 #       PLUTO_PEER_ID
 #              is the ID of our peer.
 #
-#       PLUTO_PEER_CA
-#              is the CA which issued the cert of our peer.
-#
 #       PLUTO_PEER_CLIENT
 #              is the IP address / count of the peer's client sub-
 #              net.   If the client is just the peer, this will be
 #              the peer's own IP address / max (where  max  is  32
 #              for IPv4 and 128 for IPv6).
 #
-#       PLUTO_PEER_CLIENT_NET
-#              is the IP address of the peer's client net.  If the
-#              client is just the peer, this will  be  the  peer's
-#              own IP address.
-#
-#       PLUTO_PEER_CLIENT_MASK
-#              is  the  mask  for  the  peer's client net.  If the
-#              client   is   just   the   peer,   this   will   be
-#              255.255.255.255.
-#
 #       PLUTO_PEER_PROTOCOL
 #              is the IP protocol that will be transported.
 #
 #       PLUTO_PEER_PORT
 #              is  the  UDP/TCP  port  to  which  the IPsec SA  is
-#              restricted on the peer side.
+#              restricted on the peer side.  For ICMP/ICMPv6 this contains the
+#              message code, and PLUTO_MY_PORT the message type.
 #
 #       PLUTO_XAUTH_ID
 #              is an optional user ID employed by the XAUTH protocol
@@ -146,7 +126,7 @@
 PATH="/sbin:/bin:/usr/sbin:/usr/bin:/usr/sbin"
 export PATH
 
-# uncomment to log VPN connections
+# comment to disable logging VPN connections to syslog
 VPN_LOGGING=1
 #
 # tag put in front of each log entry:
@@ -160,21 +140,11 @@ FAC_PRIO=local0.notice
 #
 # local0.notice                   -/var/log/vpn
 
-# in order to use source IP routing the Linux kernel options
-# CONFIG_IP_ADVANCED_ROUTER and CONFIG_IP_MULTIPLE_TABLES
-# must be enabled
-#
-# special routing table for sourceip routes
-SOURCEIP_ROUTING_TABLE=220
-#
-# priority of the sourceip routing table
-SOURCEIP_ROUTING_TABLE_PRIO=220
-
 # check interface version
 case "$PLUTO_VERSION" in
-1.[0|1])	# Older Pluto?!?  Play it safe, script may be using new features.
+1.[0|1])	# Older release?!?  Play it safe, script may be using new features.
 	echo "$0: obsolete interface version \`$PLUTO_VERSION'," >&2
-	echo "$0: 	called by obsolete Pluto?" >&2
+	echo "$0: 	called by obsolete release?" >&2
 	exit 2
 	;;
 1.*)	;;
@@ -196,190 +166,52 @@ custom:*)		# custom parameters (see above CAUTION comment)
 	;;
 esac
 
-# utility functions for route manipulation
-# Meddling with this stuff should not be necessary and requires great care.
-uproute() {
-	doroute add
-	ip route flush cache
-}
-downroute() {
-	doroute delete
-	ip route flush cache
-}
-
-addsource() {
-	st=0
-	if ! ip -o route get ${PLUTO_MY_SOURCEIP%/*} | grep -q ^local
-	then
-	    it="ip addr add ${PLUTO_MY_SOURCEIP%/*}/32 dev $PLUTO_INTERFACE"
-	    oops="`eval $it 2>&1`"
-	    st=$?
-	    if test " $oops" = " " -a " $st" != " 0"
-	    then
-		oops="silent error, exit status $st"
-	    fi
-	    if test " $oops" != " " -o " $st" != " 0"
-	    then
-		echo "$0: addsource \`$it' failed ($oops)" >&2
-	    fi
-	fi
-	return $st
-}
-
-doroute() {
-	st=0
-
-	if [ -z "$PLUTO_MY_SOURCEIP" ]
-	then
-	    for dir in /etc/sysconfig /etc/conf.d; do
-		if [ -f "$dir/defaultsource" ]
-		then
-		    . "$dir/defaultsource"
-		fi
-	    done
-
-	    if [ -n "$DEFAULTSOURCE" ]
-	    then
-		PLUTO_MY_SOURCEIP=$DEFAULTSOURCE
-	    fi
-        fi
+IPSEC_POLICY="-m policy --pol ipsec --proto $PLUTO_PROTO --reqid $PLUTO_REQID"
+IPSEC_POLICY_IN="$IPSEC_POLICY --dir in"
+IPSEC_POLICY_OUT="$IPSEC_POLICY --dir out"
 
-	if [ -z "$KLIPS" -a -z "$PLUTO_MY_SOURCEIP" ]
-	then
-	    # leave because no route entry is required
-	    return $st
-	fi
-
-	parms1="$PLUTO_PEER_CLIENT"
-
-	if [ -n "$PLUTO_NEXT_HOP" ]
-	then
-	    parms2="via $PLUTO_NEXT_HOP"
-	else
-	    parms2="via $PLUTO_PEER"
-	fi
-	parms2="$parms2 dev $PLUTO_INTERFACE"
-
-	parms3=
-	if [ -n "$PLUTO_MY_SOURCEIP" ]
-	then
-	    if test "$1" = "add"
-	    then
-		addsource
-		if ! ip rule list | grep -q "lookup $SOURCEIP_ROUTING_TABLE"
-		then
-		    ip rule add pref $SOURCEIP_ROUTING_TABLE_PRIO table $SOURCEIP_ROUTING_TABLE
-		fi
-	    fi
-	    parms3="$parms3 src ${PLUTO_MY_SOURCEIP%/*} table $SOURCEIP_ROUTING_TABLE"
-	fi
-
-	case "$PLUTO_PEER_CLIENT_NET/$PLUTO_PEER_CLIENT_MASK" in
-	"0.0.0.0/0.0.0.0")
-		# opportunistic encryption work around
-		# need to provide route that eclipses default, without
-		# replacing it.
-		it="ip route $1 0.0.0.0/1 $parms2 $parms3 &&
-			ip route $1 128.0.0.0/1 $parms2 $parms3"
-		;;
-	*)	it="ip route $1 $parms1 $parms2 $parms3"
-		;;
-	esac
-	oops="`eval $it 2>&1`"
-	st=$?
-	if test " $oops" = " " -a " $st" != " 0"
-	then
-	    oops="silent error, exit status $st"
-	fi
-	if test " $oops" != " " -o " $st" != " 0"
-	then
-	    echo "$0: doroute \`$it' failed ($oops)" >&2
-	fi
-	return $st
-}
-
-# in the presence of KLIPS and ipsecN interfaces do not use IPSEC_POLICY
-if [ `echo "$PLUTO_INTERFACE" | grep "ipsec"` ]
-then
-	KLIPS=1
-	IPSEC_POLICY_IN=""
-	IPSEC_POLICY_OUT=""
-else
-	KLIPS=
-	IPSEC_POLICY="-m policy --pol ipsec --proto esp --reqid $PLUTO_REQID"
-	IPSEC_POLICY_IN="$IPSEC_POLICY --dir in"
-	IPSEC_POLICY_OUT="$IPSEC_POLICY --dir out"
-fi
+# use protocol specific options to set ports
+case "$PLUTO_MY_PROTOCOL" in
+1)	# ICMP
+	ICMP_TYPE_OPTION="--icmp-type"
+	;;
+58)	# ICMPv6
+	ICMP_TYPE_OPTION="--icmpv6-type"
+	;;
+*)
+	;;
+esac
 
 # are there port numbers?
 if [ "$PLUTO_MY_PORT" != 0 ]
 then
-	S_MY_PORT="--sport $PLUTO_MY_PORT"
-	D_MY_PORT="--dport $PLUTO_MY_PORT"
+	if [ -n "$ICMP_TYPE_OPTION" ]
+	then
+		S_MY_PORT="$ICMP_TYPE_OPTION $PLUTO_MY_PORT"
+		D_MY_PORT="$ICMP_TYPE_OPTION $PLUTO_MY_PORT"
+	else
+		S_MY_PORT="--sport $PLUTO_MY_PORT"
+		D_MY_PORT="--dport $PLUTO_MY_PORT"
+	fi
 fi
 if [ "$PLUTO_PEER_PORT" != 0 ]
 then
-	S_PEER_PORT="--sport $PLUTO_PEER_PORT"
-	D_PEER_PORT="--dport $PLUTO_PEER_PORT"
+	if [ -n "$ICMP_TYPE_OPTION" ]
+	then
+		# the syntax is --icmp[v6]-type type[/code], so add it to the existing option
+		S_MY_PORT="$S_MY_PORT/$PLUTO_PEER_PORT"
+		D_MY_PORT="$D_MY_PORT/$PLUTO_PEER_PORT"
+	else
+		S_PEER_PORT="--sport $PLUTO_PEER_PORT"
+		D_PEER_PORT="--dport $PLUTO_PEER_PORT"
+	fi
 fi
 
 # resolve octal escape sequences
 PLUTO_MY_ID=`printf "$PLUTO_MY_ID"`
 PLUTO_PEER_ID=`printf "$PLUTO_PEER_ID"`
 
-# the big choice
 case "$PLUTO_VERB:$1" in
-prepare-host:*|prepare-client:*)
-	if [ -z "$KLIPS" -a -z "$PLUTO_MY_SOURCEIP" ]
-	then
-	    # exit because no route will be added,
-	    # so that existing routes can stay
-	    exit 0
-	fi
-
-	# delete possibly-existing route (preliminary to adding a route)
-	case "$PLUTO_PEER_CLIENT_NET/$PLUTO_PEER_CLIENT_MASK" in
-	"0.0.0.0/0.0.0.0")
-		# need to provide route that eclipses default, without
-		# replacing it.
-		parms1="0.0.0.0/1"
-		parms2="128.0.0.0/1"
-		it="ip route delete $parms1 2>&1 ; ip route delete $parms2 2>&1"
-		oops="`ip route delete $parms1 2>&1 ; ip route delete $parms2 2>&1`"
-		;;
-	*)
-		parms="$PLUTO_PEER_CLIENT"
-		it="ip route delete $parms 2>&1"
-		oops="`ip route delete $parms 2>&1`"
-		;;
-	esac
-	status="$?"
-	if test " $oops" = " " -a " $status" != " 0"
-	then
-		oops="silent error, exit status $status"
-	fi
-	case "$oops" in
-	*'RTNETLINK answers: No such process'*)
-		# This is what route (currently -- not documented!) gives
-		# for "could not find such a route".
-		oops=
-		status=0
-		;;
-	esac
-	if test " $oops" != " " -o " $status" != " 0"
-	then
-		echo "$0: \`$it' failed ($oops)" >&2
-	fi
-	exit $status
-	;;
-route-host:*|route-client:*)
-	# connection to me or my client subnet being routed
-	uproute
-	;;
-unroute-host:*|unroute-client:*)
-	# connection to me or my client subnet being unrouted
-	downroute
-	;;
 up-host:)
 	# connection to me coming up
 	# If you are doing a custom version, firewall commands go here.
@@ -395,7 +227,7 @@ down-host:)
 	# connection to me going down
 	# If you are doing a custom version, firewall commands go here.
 	PLUTO_INTERFACE=ipsec0
- 	iptables -D INPUT -i $PLUTO_INTERFACE -p $PLUTO_MY_PROTOCOL \
+	iptables -D INPUT -i $PLUTO_INTERFACE -p $PLUTO_MY_PROTOCOL \
 	    -s $PLUTO_PEER_CLIENT $S_PEER_PORT \
 	    -d $PLUTO_ME $D_MY_PORT -j ACCEPT
 	iptables -D OUTPUT -o $PLUTO_INTERFACE -p $PLUTO_PEER_PROTOCOL \
@@ -406,8 +238,8 @@ up-client:)
 	# connection to my client subnet coming up
 	# If you are doing a custom version, firewall commands go here.
 	PLUTO_INTERFACE=ipsec0
-        if [ "$PLUTO_PEER_CLIENT" != "$PLUTO_MY_SOURCEIP/32" ]
-        then
+	if [ "$PLUTO_PEER_CLIENT" != "$PLUTO_MY_SOURCEIP/32" ]
+	then
 	    iptables -I FORWARD 1 -o $PLUTO_INTERFACE -p $PLUTO_PEER_PROTOCOL \
 		-s $PLUTO_MY_CLIENT $S_MY_PORT \
 		-d $PLUTO_PEER_CLIENT $D_PEER_PORT -j ACCEPT
@@ -444,7 +276,7 @@ down-client:)
 	if [ -n "$PLUTO_MY_SOURCEIP" -o -n "$PLUTO_HOST_ACCESS" ]
 	then
 	    iptables -D INPUT -i $PLUTO_INTERFACE -p $PLUTO_MY_PROTOCOL \
- 		-s $PLUTO_PEER_CLIENT $S_PEER_PORT \
+		-s $PLUTO_PEER_CLIENT $S_PEER_PORT \
 		-d $PLUTO_MY_CLIENT $D_MY_PORT -j ACCEPT
 	    iptables -D OUTPUT -o $PLUTO_INTERFACE -p $PLUTO_PEER_PROTOCOL \
 		-s $PLUTO_MY_CLIENT $S_MY_PORT \
@@ -462,6 +294,14 @@ up-host:iptables)
 	    -s $PLUTO_ME $S_MY_PORT $IPSEC_POLICY_OUT \
 	    -d $PLUTO_PEER_CLIENT $D_PEER_PORT -j ACCEPT
 	#
+	# allow IPIP traffic because of the implicit SA created by the kernel if
+	# IPComp is used (for small inbound packets that are not compressed)
+	if [ -n "$PLUTO_IPCOMP" ]
+	then
+	  iptables -I INPUT 1 -i $PLUTO_INTERFACE -p 4 \
+	      -s $PLUTO_PEER -d $PLUTO_ME $IPSEC_POLICY_IN -j ACCEPT
+	fi
+	#
 	# log IPsec host connection setup
 	if [ $VPN_LOGGING ]
 	then
@@ -486,6 +326,13 @@ down-host:iptables)
 	    -s $PLUTO_ME $S_MY_PORT $IPSEC_POLICY_OUT \
 	    -d $PLUTO_PEER_CLIENT $D_PEER_PORT -j ACCEPT
 	#
+	# IPIP exception teardown
+	if [ -n "$PLUTO_IPCOMP" ]
+	then
+	  iptables -D INPUT -i $PLUTO_INTERFACE -p 4 \
+	      -s $PLUTO_PEER -d $PLUTO_ME $IPSEC_POLICY_IN -j ACCEPT
+	fi
+	#
 	# log IPsec host connection teardown
 	if [ $VPN_LOGGING ]
 	then
@@ -525,6 +372,15 @@ up-client:iptables)
 	      -d $PLUTO_PEER_CLIENT $D_PEER_PORT $IPSEC_POLICY_OUT -j ACCEPT
 	fi
 	#
+	# allow IPIP traffic because of the implicit SA created by the kernel if
+	# IPComp is used (for small inbound packets that are not compressed).
+	# INPUT is correct here even for forwarded traffic.
+	if [ -n "$PLUTO_IPCOMP" ]
+	then
+	  iptables -I INPUT 1 -i $PLUTO_INTERFACE -p 4 \
+	      -s $PLUTO_PEER -d $PLUTO_ME $IPSEC_POLICY_IN -j ACCEPT
+	fi
+	#
 	# log IPsec client connection setup
 	if [ $VPN_LOGGING ]
 	then
@@ -568,6 +424,13 @@ down-client:iptables)
 	         $IPSEC_POLICY_OUT -j ACCEPT
 	fi
 	#
+	# IPIP exception teardown
+	if [ -n "$PLUTO_IPCOMP" ]
+	then
+	  iptables -D INPUT -i $PLUTO_INTERFACE -p 4 \
+	      -s $PLUTO_PEER -d $PLUTO_ME $IPSEC_POLICY_IN -j ACCEPT
+	fi
+	#
 	# log IPsec client connection teardown
 	if [ $VPN_LOGGING ]
 	then
@@ -584,16 +447,6 @@ down-client:iptables)
 #
 # IPv6
 #
-prepare-host-v6:*|prepare-client-v6:*)
-	;;
-route-host-v6:*|route-client-v6:*)
-	# connection to me or my client subnet being routed
-	#uproute_v6
-	;;
-unroute-host-v6:*|unroute-client-v6:*)
-	# connection to me or my client subnet being unrouted
-	#downroute_v6
-	;;
 up-host-v6:)
 	# connection to me coming up
 	# If you are doing a custom version, firewall commands go here.
diff --git a/testing/tests/openssl-ikev2/critical-extension/hosts/moon/etc/ipsec.d/private/moonKey.pem b/testing/tests/openssl-ikev2/critical-extension/hosts/moon/etc/ipsec.d/private/moonKey.pem
new file mode 100644
index 0000000..4d99866
--- /dev/null
+++ b/testing/tests/openssl-ikev2/critical-extension/hosts/moon/etc/ipsec.d/private/moonKey.pem
@@ -0,0 +1,27 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIIEowIBAAKCAQEAyi9jPdS7ugWGIVsVoDEvc/UzEk8LM5ua4Tu2SLArTEaODwHm
+MPvvkhl7dwj12//qfklihpZtdazxO9XkN3oYIdgt4QLq35ljtIkEGgsPn3a3niFQ
+qjkCDj+lKmd9u4ecmGKR5PFUL+LwSU6cXJVNT6p1oXqntWZS8bFu+9y0Zpf30Lf1
+ILyZAgU2WTjSzTHyvu0w52GlbALZ3ILwze/J1DRHtqmPdiiu0qwSekqVBIOPZudR
+fl4LBnLIFlR0vOaJ9zpvxuPHKyxFSY3bvAsXsEkVYG/pTyVsx3fELFNFYP+75arN
+2UTMjbTSq6+KKUr1WwOmoBpU14Qwq3g4l1PChwIDAQABAoIBACBFB/Xqajv6fbn9
+K6pxrz02uXwGmacXAtVIDoPzejWmXS4QA4l17HrJDmelSnhelDKry8nnYHkTrTz7
+mn0wQ4HDWy86o/okJUG/TKRLd6bf79aRQqqohqd3iQkHk43GyzuXH+oGioVKF0fc
+ACDWw4wfjL7FMNdHCZ4Bz9DrHO/ysHe9B6rvSYm3VZRhSxaneIkaLkkDadKpVx3f
+XNFlMxY4qKPJYYSoJZ61iMqrO7+rnA93tmyDDs8PKU3BtnpfNrdePgleJHhk8Zqy
+Ev2/NOCSUxbKE8NCtLpGTs+T0qjjnu4k3WPd3ZOBAan0uPDekHZeHB/aXGLhYcxx
+J5SurqECgYEA+F1gppkER5Jtoaudt/CUpdQ1sR9wxf75VBqJ4FiYABGQz9xlG4oj
+zL/o572s0iV3bwFpnQa+WuWrxGkP6ZuB/Z82npc0N/vLou/b4dxvg4n7K+eOOEf0
+8FMjsse2tqTIXKCqcmQnR0NPQ1jwuvEKsXP5w/JOlnRXAXnd4jxsJI0CgYEA0GaT
+61ySttUW9jC3mxuY6jkQy8TEQqR3nOFvWwmCXIWOpN/MTTPus+Telxp/pdKhU+mo
+PmX3Unyne5PvwleWDq3YzltX5ZDZGJ5UJlKuNnfGIzQ6OcHRbb7zBpQG6qSRPuug
+bgo688hTnb1L59nK88zWVK45euf6pyuoI+SwIGMCgYEA7yvE8knyhBXvezuv0z1b
+eGHmHp5/VDwY0DQKSEAoiBBiWrkLqLybgwXf/KJ8dZZc8En08aFX2GLJyYe/KiB1
+ys3ypEBJqgvRayP+o/9KZ+qNNRd0rqAksPXvL7ABNNt0kzapTSVDae3Yu6s/j1am
+DIL5qAeERIDedG5uDPpQzdUCgYB7MtjpP63ABhLv8XbpbBQnCxtByw3W89F+Xcrt
+v55gQdhE4cSuMzA/CuMH4vNpPS6AI9aBJNhj3CtKo/cOJachAGb1/wvkO5ALvLW0
+fhZdPstUTnDJain7vfF/hwzbs/PlhXgu9T9KlLfRvXFdG+Sd4g8mumRiozcLkoRw
+y6XPTwKBgDJP+s9wXmdG90HST/aqC7FKrVXLpB63dY5swNUfQP6sa0pFnON0r0JC
+h/YCsGFFIAebQ2uOkM3g3f9nkwTp7910ov+/5uThvRI2w2BBPy0mVuALPjyyF1Z2
+cb9zpyKiIuXoXRCf4sd8r1lR9bn0Fxx0Svpxf+fpMGSI5quHNBKY
+-----END RSA PRIVATE KEY-----
diff --git a/testing/tests/openssl-ikev2/critical-extension/hosts/sun/etc/ipsec.d/private/sunKey.pem b/testing/tests/openssl-ikev2/critical-extension/hosts/sun/etc/ipsec.d/private/sunKey.pem
new file mode 100644
index 0000000..d8fad9a
--- /dev/null
+++ b/testing/tests/openssl-ikev2/critical-extension/hosts/sun/etc/ipsec.d/private/sunKey.pem
@@ -0,0 +1,27 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIIEpAIBAAKCAQEA35VUimfpDmNpT/8Q3qnoDlxJ9R+EErSYVraVoUVmH9jSHroB
+eqqtDdf3XuHtg2xKTryijBj2H0jeA7HuE1UGwmvZWN1gL5vSrk1OFrT38DmaKa/+
+mtiPqjTJrDGg+OgOz1iHsPsp/4Xx+SCTSy2Ucllfront02sVduDXEGV34Snk6vYV
+sRn1BZSlFBO6F2k23/j1i7FDn0N6Zj0hFvCysoIcfSYasmwN2p5vRqn7xC9JceMK
+3V+v0w0pZoAUBAspAjh7R1rWe08IRAt4Tzff401EGAa5+TQqoZPd4BeqvFr0AQhQ
+mdVw97FB2pQyNxSlcVvxY3NFYHwSCHcEMroWwQIDAQABAoIBADH51hjN2zk9HVgl
+QmcTAWzcUie5cLMhrP+M9mtC8O3jcCwwFY6OwfnbMU8DHy0GMqHg5lB8b99UUVPw
+HLAzjDw/ESkc6pgZs4EEhJTsxJLsvTnePgHssEgyXnXf7gRVEqJkPohfy+Zy0UCH
+eIUQXiMlOQ7xg7iDMhwNa+UdWSt539DztSKilQn2xdPZjFnMT0/prvl4NA/8Zn54
+/SdWDq5yRdLWb6EK1V7yJ3687GXR1jzGtgy7TXuncUJVTYgX7RdP1Tn6gWD8YAQ/
+RfT0DdWYm4WHSgSb9/NW8lBZH2yy3hg+lNgofXEvTfBkO5QyW31LIr0tCV6zhJIc
+Y9MxaKUCgYEA9sktaXfhPLe0ECjdeQEOq5EKuDrCviSKCOuAV4BDSOsdw6+5LWfY
+Vb/oke8N70lL3RCblcj1pOKWUi2O/SpEJdDRduiw2gM9cXt3/bChSTHC4TsIxxN/
+Db9OGg72kZ4sRY5Au+zyAAQYBwXhFWux194Jk5qK0JblNG9J5QMqZDcCgYEA5+5h
+BgHUMEO+pdME5lAiSc5PcNTejpA6j+OikCh4/HFXy3C/dLx+Cs1+egw64c8iVaIv
+NEo7n7E9I0e3XqanPRXhMnBRrP+39OVsWPmZ18Li2Hi84KwJyi8Y11l3XJOqaYpF
+wMVUuZpxR0dfG5k/5GwT/tEkmQBglOgG3m2zUMcCgYEA4m3Vd9ahV5dp5AXKpzKc
+JjiPMFfhxJo7+FEz0ZUCp03qYljBu/Jy4MKS/grrqyiCLdQGHNlk4SNxLvdUId78
+5gGBnuuDEJU2dAAIKUE9yq2YlBUZSacOxStI2snt28/X6P3LUWHm7LLU5OS1D3Vf
+mKPF/6MlSJuas5CEqVZNN+MCgYBH9Qh7IaQgmVQUBKVXg3Mv7OduvUyTdKIGtHxi
+N3xZ7hxsDP4JjNWaKmlcGmFGX8pqQRheI83d3NJ4GK8GmbP3Wst0p65fezMqsudr
+r30QmPFicgs/tYCQDw6o+aPzwAi2F+VOSqrfrtAIaldSq7hL+VA21dKB+cD9UgOX
+jPd+TwKBgQCbKeg2QNS2qhPIG9eaqJDROuxmxb/07d7OBctgMgxVvKhqW9hW42Sy
+gJ59fyz5QjFBaSfcOdf4gkKyEawVo45/q6ymIQU37R4vF4CW9Z3CfaIbwJp7LcHV
+zH07so/HNsZua6GWCSCLJU5MeCRiZzk2RFiS9KIaLP4gZndv4lXOiQ==
+-----END RSA PRIVATE KEY-----
diff --git a/testing/tests/openssl-ikev2/ecdsa-certs/evaltest.dat b/testing/tests/openssl-ikev2/ecdsa-certs/evaltest.dat
index 0110bb9..55ac109 100644
--- a/testing/tests/openssl-ikev2/ecdsa-certs/evaltest.dat
+++ b/testing/tests/openssl-ikev2/ecdsa-certs/evaltest.dat
@@ -6,9 +6,9 @@ carol::ipsec status 2> /dev/null::home.*INSTALLED, TUNNEL::YES
 dave:: ipsec status 2> /dev/null::home.*INSTALLED, TUNNEL::YES
 moon:: ipsec status 2> /dev/null::rw[{]1}.*INSTALLED, TUNNEL::YES
 moon:: ipsec status 2> /dev/null::rw[{]2}.*INSTALLED, TUNNEL::YES
-moon:: cat /var/log/daemon.log::authentication of.*carol at strongswan.org.*with ECDSA-256 signature successful::YES
+moon:: cat /var/log/daemon.log::authentication of.*carol at strongswan.org.*with ECDSA_WITH_SHA256_DER successful::YES
 moon:: cat /var/log/daemon.log::authentication of.*dave at strongswan.org.*with ECDSA-384 signature successful::YES
-carol::cat /var/log/daemon.log::authentication of.*moon.strongswan.org.*with ECDSA-521 signature successful::YES
+carol::cat /var/log/daemon.log::authentication of.*moon.strongswan.org.*with ECDSA_WITH_SHA512_DER successful::YES
 dave:: cat /var/log/daemon.log::authentication of.*moon.strongswan.org.*with ECDSA-521 signature successful::YES
 carol::ping -c 1 PH_IP_ALICE::64 bytes from PH_IP_ALICE: icmp_req=1::YES
 dave:: ping -c 1 PH_IP_ALICE::64 bytes from PH_IP_ALICE: icmp_req=1::YES
diff --git a/testing/tests/openssl-ikev2/ecdsa-certs/hosts/dave/etc/strongswan.conf b/testing/tests/openssl-ikev2/ecdsa-certs/hosts/dave/etc/strongswan.conf
index 4a5e52d..d94b179 100644
--- a/testing/tests/openssl-ikev2/ecdsa-certs/hosts/dave/etc/strongswan.conf
+++ b/testing/tests/openssl-ikev2/ecdsa-certs/hosts/dave/etc/strongswan.conf
@@ -2,4 +2,5 @@
 
 charon {
   load = pem pkcs1 openssl curl revocation random nonce hmac stroke kernel-netlink socket-default updown
+  signature_authentication = no
 }
diff --git a/testing/tests/openssl-ikev2/ecdsa-pkcs8/evaltest.dat b/testing/tests/openssl-ikev2/ecdsa-pkcs8/evaltest.dat
index 8a4215d..2d7324a 100644
--- a/testing/tests/openssl-ikev2/ecdsa-pkcs8/evaltest.dat
+++ b/testing/tests/openssl-ikev2/ecdsa-pkcs8/evaltest.dat
@@ -2,10 +2,10 @@ carol::ipsec status 2> /dev/null::home.*ESTABLISHED.*carol at strongswan.org.*moon.
 dave:: ipsec status 2> /dev/null::home.*ESTABLISHED.*dave at strongswan.org.*moon.strongswan.org::YES
 moon:: ipsec status 2> /dev/null::rw\[1]: ESTABLISHED.*moon.strongswan.org.*carol at strongswan.org::YES
 moon:: ipsec status 2> /dev/null::rw\[2]: ESTABLISHED.*moon.strongswan.org.*dave at strongswan.org::YES
-moon:: cat /var/log/daemon.log::authentication of.*carol at strongswan.org.*with ECDSA-256 signature successful::YES
-moon:: cat /var/log/daemon.log::authentication of.*dave at strongswan.org.*with ECDSA-384 signature successful::YES
-carol::cat /var/log/daemon.log::authentication of.*moon.strongswan.org.*with ECDSA-521 signature successful::YES
-dave:: cat /var/log/daemon.log::authentication of.*moon.strongswan.org.*with ECDSA-521 signature successful::YES
+moon:: cat /var/log/daemon.log::authentication of.*carol at strongswan.org.*with ECDSA_WITH_SHA256_DER successful::YES
+moon:: cat /var/log/daemon.log::authentication of.*dave at strongswan.org.*with ECDSA_WITH_SHA384_DER successful::YES
+carol::cat /var/log/daemon.log::authentication of.*moon.strongswan.org.*with ECDSA_WITH_SHA512_DER successful::YES
+dave:: cat /var/log/daemon.log::authentication of.*moon.strongswan.org.*with ECDSA_WITH_SHA512_DER successful::YES
 carol::ping -c 1 PH_IP_ALICE::64 bytes from PH_IP_ALICE: icmp_req=1::YES
 dave:: ping -c 1 PH_IP_ALICE::64 bytes from PH_IP_ALICE: icmp_req=1::YES
 moon::tcpdump::IP carol.strongswan.org > moon.strongswan.org: ESP::YES
diff --git a/testing/tests/openssl-ikev2/rw-suite-b-128/evaltest.dat b/testing/tests/openssl-ikev2/rw-suite-b-128/evaltest.dat
index 7169a09..a0831f7 100644
--- a/testing/tests/openssl-ikev2/rw-suite-b-128/evaltest.dat
+++ b/testing/tests/openssl-ikev2/rw-suite-b-128/evaltest.dat
@@ -1,7 +1,7 @@
 dave:: cat /var/log/daemon.log::establishing IKE_SA failed, peer not responding::YES
 carol::cat /var/log/daemon.log::openssl FIPS mode(2) - enabled::YES
 moon:: cat /var/log/daemon.log::openssl FIPS mode(2) - enabled::YES
-moon:: cat /var/log/daemon.log::authentication of.*carol at strongswan.org.*with ECDSA-256 signature successful::YES
+moon:: cat /var/log/daemon.log::authentication of.*carol at strongswan.org.*with ECDSA_WITH_SHA256_DER successful::YES
 carol::ipsec status 2> /dev/null::home.*ESTABLISHED.*carol at strongswan.org.*moon.strongswan.org::YES
 moon:: ipsec status 2> /dev/null::rw\[1]: ESTABLISHED.*moon.strongswan.org.*carol at strongswan.org::YES
 carol::ipsec status 2> /dev/null::home.*INSTALLED, TUNNEL::YES
diff --git a/testing/tests/openssl-ikev2/rw-suite-b-192/evaltest.dat b/testing/tests/openssl-ikev2/rw-suite-b-192/evaltest.dat
index 57cbee1..200ec3c 100644
--- a/testing/tests/openssl-ikev2/rw-suite-b-192/evaltest.dat
+++ b/testing/tests/openssl-ikev2/rw-suite-b-192/evaltest.dat
@@ -1,7 +1,7 @@
 dave:: cat /var/log/daemon.log::establishing IKE_SA failed, peer not responding::YES
 carol::cat /var/log/daemon.log::openssl FIPS mode(2) - enabled::YES
 moon:: cat /var/log/daemon.log::openssl FIPS mode(2) - enabled::YES
-moon:: cat /var/log/daemon.log::authentication of.*carol at strongswan.org.*with ECDSA-384 signature successful::YES
+moon:: cat /var/log/daemon.log::authentication of.*carol at strongswan.org.*with ECDSA_WITH_SHA384_DER successful::YES
 carol::ipsec status 2> /dev/null::home.*ESTABLISHED.*carol at strongswan.org.*moon.strongswan.org::YES
 moon:: ipsec status 2> /dev/null::rw\[1]: ESTABLISHED.*moon.strongswan.org.*carol at strongswan.org::YES
 carol::ipsec status 2> /dev/null::home.*INSTALLED, TUNNEL::YES
diff --git a/testing/tests/sql/rw-eap-aka-rsa/evaltest.dat b/testing/tests/sql/rw-eap-aka-rsa/evaltest.dat
index e1d33fe..73173f0 100644
--- a/testing/tests/sql/rw-eap-aka-rsa/evaltest.dat
+++ b/testing/tests/sql/rw-eap-aka-rsa/evaltest.dat
@@ -1,4 +1,4 @@
-carol::cat /var/log/daemon.log::authentication of 'moon.strongswan.org' with RSA signature successful::YES
+carol::cat /var/log/daemon.log::authentication of 'moon.strongswan.org' with RSA.* successful::YES
 carol::cat /var/log/daemon.log::authentication of 'moon.strongswan.org' with EAP successful::YES
 moon:: cat /var/log/daemon.log::authentication of 'carol at strongswan.org' with EAP successful::YES
 carol::ipsec status 2> /dev/null::home.*ESTABLISHED.*carol at strongswan.org.*moon.strongswan.org::YES
diff --git a/testing/tests/sql/rw-psk-rsa-split/evaltest.dat b/testing/tests/sql/rw-psk-rsa-split/evaltest.dat
index 1648c95..1206ea4 100644
--- a/testing/tests/sql/rw-psk-rsa-split/evaltest.dat
+++ b/testing/tests/sql/rw-psk-rsa-split/evaltest.dat
@@ -1,6 +1,6 @@
 moon:: cat /var/log/daemon.log::authentication of 'carol at strongswan.org' with pre-shared key successful::YES
 moon:: cat /var/log/daemon.log::authentication of 'dave at strongswan.org' with pre-shared key successful::YES
-moon:: cat /var/log/daemon.log::authentication of 'moon.strongswan.org' (myself) with RSA signature successful::YES
+moon:: cat /var/log/daemon.log::authentication of 'moon.strongswan.org' (myself) with RSA.* successful::YES
 carol::ipsec status 2> /dev/null::home.*ESTABLISHED.*carol at strongswan.org.*moon.strongswan.org::YES
 dave:: ipsec status 2> /dev/null::home.*ESTABLISHED.*dave at strongswan.org.*moon.strongswan.org::YES
 moon:: ipsec status 2> /dev/null::rw\[1]: ESTABLISHED.*moon.strongswan.org.*carol at strongswan.org::YES
diff --git a/testing/tests/swanctl/net2net-cert-ipv6/description.txt b/testing/tests/swanctl/net2net-cert-ipv6/description.txt
deleted file mode 100755
index 5952ecc..0000000
--- a/testing/tests/swanctl/net2net-cert-ipv6/description.txt
+++ /dev/null
@@ -1,6 +0,0 @@
-An IPv6 ESP tunnel connection between the gateways <b>moon</b> and <b>sun</b> is successfully set up.
-It connects the two subnets hiding behind their respective gateways. The authentication is based on
-X.509 certificates. Upon the successful establishment of the IPsec tunnel, <b>leftfirewall=yes</b>
-automatically inserts ip6tables-based firewall rules that let pass the tunneled traffic.
-In order to test both the net-to-net tunnel and the firewall rules, client <b>alice</b> behind <b>moon</b>
-sends an IPv6 ICMP request to client <b>bob</b> behind <b>sun</b> using the ping6 command.
diff --git a/testing/tests/swanctl/net2net-cert-ipv6/evaltest.dat b/testing/tests/swanctl/net2net-cert-ipv6/evaltest.dat
deleted file mode 100755
index cdbecd5..0000000
--- a/testing/tests/swanctl/net2net-cert-ipv6/evaltest.dat
+++ /dev/null
@@ -1,5 +0,0 @@
-moon::swanctl --list-sas --raw 2> /dev/null::gw-gw.*version=2 state=ESTABLISHED local-host=192.168.0.1 local-id=moon.strongswan.org remote-host=192.168.0.2 remote-id=sun.strongswan.org initiator=yes.*encr-alg=AES_CBC encr-keysize=128 integ-alg=HMAC_SHA2_256_128 prf-alg=PRF_HMAC_SHA2_256 dh-group=MODP_2048.*child-sas.*net-net.*state=INSTALLED mode=TUNNEL.*ESP.*encr-alg=AES_GCM_16 encr-keysize=128.*local-ts=\[10.1.0.0/16] remote-ts=\[10.2.0.0/16]::YES
-sun:: swanctl --list-sas --raw 2> /dev/null::gw-gw.*version=2 state=ESTABLISHED local-host=192.168.0.2 local-id=sun.strongswan.org remote-host=192.168.0.1 remote-id=moon.strongswan.org.*encr-alg=AES_CBC encr-keysize=128 integ-alg=HMAC_SHA2_256_128 prf-alg=PRF_HMAC_SHA2_256 dh-group=MODP_2048.*child-sas.*net-net.*state=INSTALLED mode=TUNNEL.*ESP.*encr-alg=AES_GCM_16 encr-keysize=128.*local-ts=\[10.2.0.0/16] remote-ts=\[10.1.0.0/16]::YES
-alice::ping -c 1 PH_IP_BOB::64 bytes from PH_IP_BOB: icmp_req=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/swanctl/net2net-cert-ipv6/hosts/moon/etc/strongswan.conf b/testing/tests/swanctl/net2net-cert-ipv6/hosts/moon/etc/strongswan.conf
deleted file mode 100755
index bd131af..0000000
--- a/testing/tests/swanctl/net2net-cert-ipv6/hosts/moon/etc/strongswan.conf
+++ /dev/null
@@ -1,15 +0,0 @@
-# /etc/strongswan.conf - strongSwan configuration file
-
-swanctl {
-  load = pem pkcs1 x509 revocation constraints pubkey openssl random 
-}
-
-charon {
-  load = sha1 sha2 md5 aes des hmac pem pkcs1 x509 revocation constraints pubkey gmp random nonce curl kernel-netlink socket-default updown vici 
-
-  fragment_size = 1400
-}
-
-libstrongswan {
-  dh_exponent_ansi_x9_42 = no
-}
diff --git a/testing/tests/swanctl/net2net-cert-ipv6/hosts/moon/etc/swanctl/swanctl.conf b/testing/tests/swanctl/net2net-cert-ipv6/hosts/moon/etc/swanctl/swanctl.conf
deleted file mode 100755
index 16e145c..0000000
--- a/testing/tests/swanctl/net2net-cert-ipv6/hosts/moon/etc/swanctl/swanctl.conf
+++ /dev/null
@@ -1,35 +0,0 @@
-connections {
-
-   gw-gw {
-      local_addrs  = fec0::1
-      remote_addrs = fec0::2 
-
-      local {
-         auth = pubkey
-         certs = moonCert.pem
-         id = moon.strongswan.org
-      }
-      remote {
-         auth = pubkey
-         id = sun.strongswan.org 
-      }
-      children {
-         net-net {
-            local_ts  = fec1::0/16 
-            remote_ts = fec2::0/16 
-
-            start_action = none
-            updown = /usr/local/libexec/ipsec/_updown iptables
-            rekey_time = 10m 
-            esp_proposals = aes128gcm128-modp2048
-         }
-      }
-
-      version = 2
-      mobike = no
-      fragmentation = yes
-      reauth_time = 60m
-      rekey_time =  20m
-      proposals = aes128-sha256-modp2048
-   }
-}
diff --git a/testing/tests/swanctl/net2net-cert-ipv6/hosts/sun/etc/strongswan.conf b/testing/tests/swanctl/net2net-cert-ipv6/hosts/sun/etc/strongswan.conf
deleted file mode 100755
index bd131af..0000000
--- a/testing/tests/swanctl/net2net-cert-ipv6/hosts/sun/etc/strongswan.conf
+++ /dev/null
@@ -1,15 +0,0 @@
-# /etc/strongswan.conf - strongSwan configuration file
-
-swanctl {
-  load = pem pkcs1 x509 revocation constraints pubkey openssl random 
-}
-
-charon {
-  load = sha1 sha2 md5 aes des hmac pem pkcs1 x509 revocation constraints pubkey gmp random nonce curl kernel-netlink socket-default updown vici 
-
-  fragment_size = 1400
-}
-
-libstrongswan {
-  dh_exponent_ansi_x9_42 = no
-}
diff --git a/testing/tests/swanctl/net2net-cert-ipv6/hosts/sun/etc/swanctl/swanctl.conf b/testing/tests/swanctl/net2net-cert-ipv6/hosts/sun/etc/swanctl/swanctl.conf
deleted file mode 100755
index 90aa137..0000000
--- a/testing/tests/swanctl/net2net-cert-ipv6/hosts/sun/etc/swanctl/swanctl.conf
+++ /dev/null
@@ -1,35 +0,0 @@
-connections {
-
-   gw-gw {
-      local_addrs  = fec0::2
-      remote_addrs = fec0::1 
-
-      local {
-         auth = pubkey
-         certs = sunCert.pem
-         id = sun.strongswan.org
-      }
-      remote {
-         auth = pubkey
-         id = moon.strongswan.org 
-      }
-      children {
-         net-net {
-            local_ts  = fec2::0/16 
-            remote_ts = fec1::0/16 
-
-            start_action = none
-            updown = /usr/local/libexec/ipsec/_updown iptables
-            rekey_time = 10m 
-            esp_proposals = aes128gcm128-modp2048
-         }
-      }
-
-      version = 2
-      mobike = no
-      fragmentation = yes
-      reauth_time = 60m
-      rekey_time =  20m
-      proposals = aes128-sha256-modp2048
-   }
-}
diff --git a/testing/tests/swanctl/net2net-cert-ipv6/posttest.dat b/testing/tests/swanctl/net2net-cert-ipv6/posttest.dat
deleted file mode 100755
index a40a7dd..0000000
--- a/testing/tests/swanctl/net2net-cert-ipv6/posttest.dat
+++ /dev/null
@@ -1,11 +0,0 @@
-moon::swanctl --terminate --ike gw-gw 2> /dev/null
-moon::service charon stop 2> /dev/null
-sun::service charon stop 2> /dev/null
-alice::"ip route del fec2:\:/16 via fec1:\:1"
-moon::"ip route del fec2:\:/16 via fec0:\:2"
-sun::"ip route del fec1:\:/16 via fec0:\:1"
-bob::"ip route del fec1:\:/16 via fec2:\:1"
-moon::iptables-restore < /etc/iptables.flush
-sun::iptables-restore < /etc/iptables.flush
-moon::ip6tables-restore < /etc/ip6tables.flush
-sun::ip6tables-restore < /etc/ip6tables.flush
diff --git a/testing/tests/swanctl/net2net-cert-ipv6/pretest.dat b/testing/tests/swanctl/net2net-cert-ipv6/pretest.dat
deleted file mode 100755
index 36e8e19..0000000
--- a/testing/tests/swanctl/net2net-cert-ipv6/pretest.dat
+++ /dev/null
@@ -1,16 +0,0 @@
-moon::iptables-restore < /etc/iptables.drop
-sun::iptables-restore < /etc/iptables.drop
-moon::ip6tables-restore < /etc/ip6tables.rules
-sun::ip6tables-restore < /etc/ip6tables.rules
-alice::"ip route add fec2:\:/16 via fec1:\:1"
-moon::"ip route add fec2:\:/16 via fec0:\:2"
-sun::"ip route add fec1:\:/16 via fec0:\:1"
-bob::"ip route add fec1:\:/16 via fec2:\:1"
-moon::service charon start 2> /dev/null
-sun::service charon start 2> /dev/null
-moon::sleep 1
-moon::swanctl --load-conns 2> /dev/null
-sun::swanctl --load-conns 2> /dev/null
-moon::swanctl --load-creds 2> /dev/null
-sun::swanctl --load-creds 2> /dev/null
-moon::swanctl --initiate --child net-net 2> /dev/null
diff --git a/testing/tests/swanctl/net2net-cert-ipv6/test.conf b/testing/tests/swanctl/net2net-cert-ipv6/test.conf
deleted file mode 100755
index 646b8b3..0000000
--- a/testing/tests/swanctl/net2net-cert-ipv6/test.conf
+++ /dev/null
@@ -1,21 +0,0 @@
-#!/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/host2host-initiator/evaltest.dat b/testing/tests/tkm/host2host-initiator/evaltest.dat
index d8d44df..de50ab3 100644
--- a/testing/tests/tkm/host2host-initiator/evaltest.dat
+++ b/testing/tests/tkm/host2host-initiator/evaltest.dat
@@ -10,3 +10,7 @@ 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::Adding SA \[ 1, 192.168.0.1 <-> 192.168.0.2, SPI_in.*, SPI_out.*, soft 30, hard 60 \]::YES
+moon::DAEMON_NAME=charon-tkm ipsec down conn1 && sleep 1::no output expected::NO
+moon::cat /var/log/daemon.log::deleting child SA (esa: 1, spi:.*)::YES
+moon::cat /tmp/tkm.log::Resetting ESA context 1::YES
+moon::cat /tmp/tkm.log::Deleting SA \[ 1, 192.168.0.1 <=> 192.168.0.2, SPI_in.*, SPI_out.* \]::YES
diff --git a/testing/tests/tkm/host2host-xfrmproxy/evaltest.dat b/testing/tests/tkm/host2host-xfrmproxy/evaltest.dat
index 7c8c6b2..f5143f1 100644
--- a/testing/tests/tkm/host2host-xfrmproxy/evaltest.dat
+++ b/testing/tests/tkm/host2host-xfrmproxy/evaltest.dat
@@ -5,6 +5,7 @@ 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_req=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 /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
diff --git a/testing/tests/tkm/multiple-clients/evaltest.dat b/testing/tests/tkm/multiple-clients/evaltest.dat
index 8e00421..1f0c88b 100644
--- a/testing/tests/tkm/multiple-clients/evaltest.dat
+++ b/testing/tests/tkm/multiple-clients/evaltest.dat
@@ -15,8 +15,7 @@ dave::tcpdump::IP sun.strongswan.org > dave.strongswan.org: ESP::YES
 sun::cat /tmp/tkm.log::RSA private key '/etc/tkm/sunKey.der' loaded::YES
 sun::cat /tmp/tkm.log::Adding policy \[ 1, 192.168.0.2 <-> 192.168.0.100 \]::YES
 sun::cat /tmp/tkm.log::Adding policy \[ 2, 192.168.0.2 <-> 192.168.0.200 \]::YES
-sun::cat /tmp/tkm.log::Checked CA certificate of CC context 1::YES
-sun::cat /tmp/tkm.log::Checked CA certificate of CC context 2::YES
+sun::cat /tmp/tkm.log | grep "Checked CA certificate of CC context 1" | wc -l::2::YES
 sun::cat /tmp/tkm.log::Authentication of ISA context 1 successful::YES
 sun::cat /tmp/tkm.log::Authentication of ISA context 2 successful::YES
 sun::cat /tmp/tkm.log::Adding SA \[ 1, 192.168.0.2 <-> 192.168.0.100, SPI_in.*, SPI_out.*, soft 30, hard 60 \]::YES
diff --git a/testing/tests/tkm/net2net-xfrmproxy/evaltest.dat b/testing/tests/tkm/net2net-xfrmproxy/evaltest.dat
index a38dba0..98eff24 100644
--- a/testing/tests/tkm/net2net-xfrmproxy/evaltest.dat
+++ b/testing/tests/tkm/net2net-xfrmproxy/evaltest.dat
@@ -5,6 +5,7 @@ sun::ipsec status 2> /dev/null::net-net.*INSTALLED, TUNNEL::YES
 alice::ping -c 1 PH_IP_BOB::64 bytes from PH_IP_BOB: icmp_req=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 /tmp/tkm.log::RSA private key '/etc/tkm/moonKey.der' loaded::YES
 moon::cat /tmp/tkm.log::Adding policy \[ 1, 10.1.0.0/16 > 192.168.0.1 <=> 192.168.0.2 < 10.2.0.0/16 \]::YES
 moon::cat /tmp/tkm.log::Checked CA certificate of CC context 1::YES
diff --git a/testing/tests/tkm/xfrmproxy-expire/description.txt b/testing/tests/tkm/xfrmproxy-expire/description.txt
new file mode 100644
index 0000000..9578cd8
--- /dev/null
+++ b/testing/tests/tkm/xfrmproxy-expire/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 XFRM expire messages from the kernel are
+handled correctly.
diff --git a/testing/tests/tkm/xfrmproxy-expire/evaltest.dat b/testing/tests/tkm/xfrmproxy-expire/evaltest.dat
new file mode 100644
index 0000000..96b486a
--- /dev/null
+++ b/testing/tests/tkm/xfrmproxy-expire/evaltest.dat
@@ -0,0 +1,22 @@
+moon::ipsec stroke status 2> /dev/null::conn1.*ESTABLISHED.*moon.strongswan.org.*sun.strongswan.org::YES
+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_req=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:.*)::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 SA \[ 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::Resetting ESA context 1::YES
+moon::cat /tmp/tkm.log::Deleting SA \[ 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-expire/hosts/moon/etc/strongswan.conf
new file mode 100644
index 0000000..cc9d6e0
--- /dev/null
+++ b/testing/tests/tkm/xfrmproxy-expire/hosts/moon/etc/strongswan.conf
@@ -0,0 +1,8 @@
+# /etc/strongswan.conf - strongSwan configuration file
+
+charon-tkm {
+  dh_mapping {
+    15 = 1
+    16 = 2
+  }
+}
diff --git a/testing/tests/tkm/xfrmproxy-expire/hosts/moon/etc/tkm/moonKey.der b/testing/tests/tkm/xfrmproxy-expire/hosts/moon/etc/tkm/moonKey.der
new file mode 100644
index 0000000..d374893
Binary files /dev/null and b/testing/tests/tkm/xfrmproxy-expire/hosts/moon/etc/tkm/moonKey.der differ
diff --git a/testing/tests/tkm/xfrmproxy-expire/hosts/moon/etc/tkm/strongswanCert.der b/testing/tests/tkm/xfrmproxy-expire/hosts/moon/etc/tkm/strongswanCert.der
new file mode 100644
index 0000000..a5a631f
Binary files /dev/null and b/testing/tests/tkm/xfrmproxy-expire/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-expire/hosts/moon/etc/tkm/tkm.conf
new file mode 100644
index 0000000..23e958a
--- /dev/null
+++ b/testing/tests/tkm/xfrmproxy-expire/hosts/moon/etc/tkm/tkm.conf
@@ -0,0 +1,21 @@
+<tkmconfig>
+    <local_identity id="1">
+        <identity>moon.strongswan.org</identity>
+        <certificate>moonCert.pem</certificate>
+    </local_identity>
+    <policy id="1">
+        <mode>transport</mode>
+        <local>
+            <identity_id>1</identity_id>
+            <ip>192.168.0.1</ip>
+        </local>
+        <remote>
+            <identity>sun.strongswan.org</identity>
+            <ip>192.168.0.2</ip>
+        </remote>
+        <lifetime>
+            <soft>2</soft>
+            <hard>60</hard>
+        </lifetime>
+    </policy>
+</tkmconfig>
diff --git a/testing/tests/tkm/xfrmproxy-expire/hosts/sun/etc/ipsec.conf b/testing/tests/tkm/xfrmproxy-expire/hosts/sun/etc/ipsec.conf
new file mode 100644
index 0000000..e52a04f
--- /dev/null
+++ b/testing/tests/tkm/xfrmproxy-expire/hosts/sun/etc/ipsec.conf
@@ -0,0 +1,21 @@
+# /etc/ipsec.conf - strongSwan IPsec configuration file
+
+config setup
+
+conn %default
+	ikelifetime=60m
+	keylife=20m
+	rekeymargin=3m
+	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-expire/hosts/sun/etc/strongswan.conf b/testing/tests/tkm/xfrmproxy-expire/hosts/sun/etc/strongswan.conf
new file mode 100644
index 0000000..f585edf
--- /dev/null
+++ b/testing/tests/tkm/xfrmproxy-expire/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-expire/posttest.dat b/testing/tests/tkm/xfrmproxy-expire/posttest.dat
new file mode 100644
index 0000000..99efe7b
--- /dev/null
+++ b/testing/tests/tkm/xfrmproxy-expire/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-expire/pretest.dat b/testing/tests/tkm/xfrmproxy-expire/pretest.dat
new file mode 100644
index 0000000..d645ddb
--- /dev/null
+++ b/testing/tests/tkm/xfrmproxy-expire/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-expire/test.conf b/testing/tests/tkm/xfrmproxy-expire/test.conf
new file mode 100644
index 0000000..9647dc6
--- /dev/null
+++ b/testing/tests/tkm/xfrmproxy-expire/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-11-radius-block/evaltest.dat b/testing/tests/tnc/tnccs-11-radius-block/evaltest.dat
index d934074..b9eee4f 100644
--- a/testing/tests/tnc/tnccs-11-radius-block/evaltest.dat
+++ b/testing/tests/tnc/tnccs-11-radius-block/evaltest.dat
@@ -1,8 +1,8 @@
-carol::cat /var/log/daemon.log::authentication of 'moon.strongswan.org' with RSA signature successful::YES
+carol::cat /var/log/daemon.log::authentication of 'moon.strongswan.org' with RSA.* successful::YES
 carol::cat /var/log/daemon.log::TNCCS-Recommendation.*allow::YES
 carol::cat /var/log/daemon.log::EAP method EAP_TTLS succeeded, MSK established::YES
 carol::cat /var/log/daemon.log::CHILD_SA home{1} established.*TS 192.168.0.100/32 === 10.1.0.0/16::YES
-dave:: cat /var/log/daemon.log::authentication of 'moon.strongswan.org' with RSA signature successful::YES
+dave:: cat /var/log/daemon.log::authentication of 'moon.strongswan.org' with RSA.* successful::YES
 dave:: cat /var/log/daemon.log::TNCCS-Recommendation.*none::YES
 dave:: cat /var/log/daemon.log::received EAP_FAILURE, EAP authentication failed::YES
 dave:: cat /var/log/daemon.log::CHILD_SA home{1} established.*TS 192.168.0.200/32 === 10.1.0.0/16::NO
diff --git a/testing/tests/tnc/tnccs-11-radius-pts/evaltest.dat b/testing/tests/tnc/tnccs-11-radius-pts/evaltest.dat
index e22b767..2248078 100644
--- a/testing/tests/tnc/tnccs-11-radius-pts/evaltest.dat
+++ b/testing/tests/tnc/tnccs-11-radius-pts/evaltest.dat
@@ -1,8 +1,8 @@
-carol::cat /var/log/daemon.log::authentication of 'moon.strongswan.org' with RSA signature successful::YES
+carol::cat /var/log/daemon.log::authentication of 'moon.strongswan.org' with RSA.* successful::YES
 carol::cat /var/log/daemon.log::TNCCS-Recommendation.*allow::YES
 carol::cat /var/log/daemon.log::EAP method EAP_TTLS succeeded, MSK established::YES
 carol::cat /var/log/daemon.log::CHILD_SA home{1} established.*TS 192.168.0.100/32 === 10.1.0.0/28::YES
-dave:: cat /var/log/daemon.log::authentication of 'moon.strongswan.org' with RSA signature successful::YES
+dave:: cat /var/log/daemon.log::authentication of 'moon.strongswan.org' with RSA.* successful::YES
 dave:: cat /var/log/daemon.log::TNCCS-Recommendation.*isolate::YES
 dave:: cat /var/log/daemon.log::EAP method EAP_TTLS succeeded, MSK established::YES
 dave:: cat /var/log/daemon.log::CHILD_SA home{1} established.*TS 192.168.0.200/32 === 10.1.0.16/28::YES
diff --git a/testing/tests/tnc/tnccs-11-radius/evaltest.dat b/testing/tests/tnc/tnccs-11-radius/evaltest.dat
index e22b767..2248078 100644
--- a/testing/tests/tnc/tnccs-11-radius/evaltest.dat
+++ b/testing/tests/tnc/tnccs-11-radius/evaltest.dat
@@ -1,8 +1,8 @@
-carol::cat /var/log/daemon.log::authentication of 'moon.strongswan.org' with RSA signature successful::YES
+carol::cat /var/log/daemon.log::authentication of 'moon.strongswan.org' with RSA.* successful::YES
 carol::cat /var/log/daemon.log::TNCCS-Recommendation.*allow::YES
 carol::cat /var/log/daemon.log::EAP method EAP_TTLS succeeded, MSK established::YES
 carol::cat /var/log/daemon.log::CHILD_SA home{1} established.*TS 192.168.0.100/32 === 10.1.0.0/28::YES
-dave:: cat /var/log/daemon.log::authentication of 'moon.strongswan.org' with RSA signature successful::YES
+dave:: cat /var/log/daemon.log::authentication of 'moon.strongswan.org' with RSA.* successful::YES
 dave:: cat /var/log/daemon.log::TNCCS-Recommendation.*isolate::YES
 dave:: cat /var/log/daemon.log::EAP method EAP_TTLS succeeded, MSK established::YES
 dave:: cat /var/log/daemon.log::CHILD_SA home{1} established.*TS 192.168.0.200/32 === 10.1.0.16/28::YES
diff --git a/testing/tests/tnc/tnccs-20-fail-init/description.txt b/testing/tests/tnc/tnccs-20-fail-init/description.txt
new file mode 100644
index 0000000..91fbbaa
--- /dev/null
+++ b/testing/tests/tnc/tnccs-20-fail-init/description.txt
@@ -0,0 +1,10 @@
+The roadwarriors <b>carol</b> and <b>dave</b> set up a connection each to gateway <b>moon</b>
+using EAP-TTLS authentication only with the gateway presenting a server certificate and
+the clients doing EAP-MD5 password-based authentication.
+In a next step the EAP-TNC protocol is used within the EAP-TTLS tunnel to determine the
+health of <b>carol</b> and <b>dave</b> via the <b>TNCCS 2.0 </b> client-server interface
+compliant with <b>RFC 5793 PB-TNC</b>.
+<p/>
+Unfortunately <b>carol</b> sends her first PB-TNC batch with a wrong version number and
+<b>dave</b> sends a PB-TNC message not supported by <b>moon</b> with the NOSKIP flag set.
+Therefore both connection setups fail due to fatal PB-TNC errors.
diff --git a/testing/tests/tnc/tnccs-20-fail-init/evaltest.dat b/testing/tests/tnc/tnccs-20-fail-init/evaltest.dat
new file mode 100644
index 0000000..4cbf60f
--- /dev/null
+++ b/testing/tests/tnc/tnccs-20-fail-init/evaltest.dat
@@ -0,0 +1,10 @@
+moon:: cat /var/log/daemon.log::unsupported TNCCS batch version 0x03::YES
+carol::cat /var/log/daemon.log::received fatal PB-TNC error.*Version Not Supported.*caused by bad version 0x03::YES
+carol::cat /var/log/daemon.log::EAP_PT_EAP method failed::YES
+moon:: cat /var/log/daemon.log::EAP method EAP_TTLS failed for peer carol at strongswan.org::YES
+carol::cat /var/log/daemon.log::received EAP_FAILURE, EAP authentication failed::YES
+moon:: cat /var/log/daemon.log::reject PB-TNC message (0x00902a/0x00000000)::YES
+dave:: cat /var/log/daemon.log::received fatal PB-TNC error.*Unsupported Mandatory Message::YES
+dave::cat /var/log/daemon.log::EAP_PT_EAP method failed::YES
+moon:: cat /var/log/daemon.log::EAP method EAP_TTLS failed for peer dave at strongswan.org::YES
+dave::cat /var/log/daemon.log::received EAP_FAILURE, EAP authentication failed::YES
diff --git a/testing/tests/tnc/tnccs-20-fail-init/hosts/carol/etc/ipsec.conf b/testing/tests/tnc/tnccs-20-fail-init/hosts/carol/etc/ipsec.conf
new file mode 100644
index 0000000..e2bf349
--- /dev/null
+++ b/testing/tests/tnc/tnccs-20-fail-init/hosts/carol/etc/ipsec.conf
@@ -0,0 +1,23 @@
+# /etc/ipsec.conf - strongSwan IPsec configuration file
+
+config setup
+	charondebug="tnc 3, imc 3"
+
+conn %default
+	ikelifetime=60m
+	keylife=20m
+	rekeymargin=3m
+	keyingtries=1
+	keyexchange=ikev2
+
+conn home
+	left=PH_IP_CAROL
+	leftid=carol at strongswan.org
+	leftauth=eap
+	leftfirewall=yes
+	right=PH_IP_MOON
+	rightid=@moon.strongswan.org
+	rightauth=any
+	rightsendcert=never
+	rightsubnet=10.1.0.0/16
+	auto=add
diff --git a/testing/tests/tnc/tnccs-20-fail-init/hosts/carol/etc/ipsec.secrets b/testing/tests/tnc/tnccs-20-fail-init/hosts/carol/etc/ipsec.secrets
new file mode 100644
index 0000000..74942af
--- /dev/null
+++ b/testing/tests/tnc/tnccs-20-fail-init/hosts/carol/etc/ipsec.secrets
@@ -0,0 +1,3 @@
+# /etc/ipsec.secrets - strongSwan IPsec secrets file
+
+carol at strongswan.org : EAP "Ar3etTnp"
diff --git a/testing/tests/tnc/tnccs-20-fail-init/hosts/carol/etc/strongswan.conf b/testing/tests/tnc/tnccs-20-fail-init/hosts/carol/etc/strongswan.conf
new file mode 100644
index 0000000..fcd2246
--- /dev/null
+++ b/testing/tests/tnc/tnccs-20-fail-init/hosts/carol/etc/strongswan.conf
@@ -0,0 +1,23 @@
+# /etc/strongswan.conf - strongSwan configuration file
+
+charon {
+  load = aes des sha1 sha2 md5 pem pkcs1 gmp random nonce x509 curl revocation hmac stroke kernel-netlink socket-default eap-identity eap-md5 eap-ttls eap-tnc tnc-tnccs tnc-imc tnccs-20 updown
+
+  multiple_authentication = no
+
+  plugins {
+    tnccs-20 {
+      tests {
+        pb_tnc_version = 3
+      }
+    }
+  }
+}
+
+libimcv {
+  plugins {
+    imc-test {
+      command = allow
+    }
+  }
+}
diff --git a/testing/tests/tnc/tnccs-20-fail-init/hosts/carol/etc/tnc_config b/testing/tests/tnc/tnccs-20-fail-init/hosts/carol/etc/tnc_config
new file mode 100644
index 0000000..bfa6667
--- /dev/null
+++ b/testing/tests/tnc/tnccs-20-fail-init/hosts/carol/etc/tnc_config
@@ -0,0 +1,3 @@
+#IMC configuration file for strongSwan client 
+
+IMC "Test"	/usr/local/lib/ipsec/imcvs/imc-test.so
diff --git a/testing/tests/tnc/tnccs-20-fail-init/hosts/dave/etc/ipsec.conf b/testing/tests/tnc/tnccs-20-fail-init/hosts/dave/etc/ipsec.conf
new file mode 100644
index 0000000..5044084
--- /dev/null
+++ b/testing/tests/tnc/tnccs-20-fail-init/hosts/dave/etc/ipsec.conf
@@ -0,0 +1,23 @@
+# /etc/ipsec.conf - strongSwan IPsec configuration file
+
+config setup
+	charondebug="tnc 3, imc 3"
+
+conn %default
+	ikelifetime=60m
+	keylife=20m
+	rekeymargin=3m
+	keyingtries=1
+	keyexchange=ikev2
+
+conn home
+	left=PH_IP_DAVE
+	leftid=dave at strongswan.org
+	leftauth=eap
+	leftfirewall=yes
+	right=PH_IP_MOON
+	rightid=moon.strongswan.org
+	rightauth=any
+	rightsendcert=never
+	rightsubnet=10.1.0.0/16
+	auto=add
diff --git a/testing/tests/tnc/tnccs-20-fail-init/hosts/dave/etc/ipsec.secrets b/testing/tests/tnc/tnccs-20-fail-init/hosts/dave/etc/ipsec.secrets
new file mode 100644
index 0000000..5496df7
--- /dev/null
+++ b/testing/tests/tnc/tnccs-20-fail-init/hosts/dave/etc/ipsec.secrets
@@ -0,0 +1,3 @@
+# /etc/ipsec.secrets - strongSwan IPsec secrets file
+
+dave at strongswan.org : EAP "W7R0g3do"
diff --git a/testing/tests/tnc/tnccs-20-fail-init/hosts/dave/etc/strongswan.conf b/testing/tests/tnc/tnccs-20-fail-init/hosts/dave/etc/strongswan.conf
new file mode 100644
index 0000000..76f4137
--- /dev/null
+++ b/testing/tests/tnc/tnccs-20-fail-init/hosts/dave/etc/strongswan.conf
@@ -0,0 +1,26 @@
+# /etc/strongswan.conf - strongSwan configuration file
+
+charon {
+  load = aes des sha1 sha2 md5 pem pkcs1 gmp random nonce x509 curl revocation hmac stroke kernel-netlink socket-default eap-identity eap-md5 eap-ttls eap-tnc tnc-imc tnc-tnccs tnccs-20 updown
+
+  multiple_authentication = no
+
+  plugins {
+    tnc-imc {
+      preferred_language = ru, pl  , de
+    }
+    tnccs-20 {
+      tests {
+        pb_tnc_noskip = yes 
+      }
+    }
+  }
+}
+
+libimcv {
+  plugins {
+    imc-test {
+      command = isolate
+    }
+  }
+}
diff --git a/testing/tests/tnc/tnccs-20-fail-init/hosts/dave/etc/tnc_config b/testing/tests/tnc/tnccs-20-fail-init/hosts/dave/etc/tnc_config
new file mode 100644
index 0000000..bfa6667
--- /dev/null
+++ b/testing/tests/tnc/tnccs-20-fail-init/hosts/dave/etc/tnc_config
@@ -0,0 +1,3 @@
+#IMC configuration file for strongSwan client 
+
+IMC "Test"	/usr/local/lib/ipsec/imcvs/imc-test.so
diff --git a/testing/tests/tnc/tnccs-20-fail-init/hosts/moon/etc/ipsec.conf b/testing/tests/tnc/tnccs-20-fail-init/hosts/moon/etc/ipsec.conf
new file mode 100644
index 0000000..e21ef0d
--- /dev/null
+++ b/testing/tests/tnc/tnccs-20-fail-init/hosts/moon/etc/ipsec.conf
@@ -0,0 +1,34 @@
+# /etc/ipsec.conf - strongSwan IPsec configuration file
+
+config setup
+	charondebug="tnc 3, imv 3"
+
+conn %default
+	ikelifetime=60m
+	keylife=20m
+	rekeymargin=3m
+	keyingtries=1
+	keyexchange=ikev2
+
+conn rw-allow
+	rightgroups=allow
+	leftsubnet=10.1.0.0/28
+	also=rw-eap
+	auto=add
+
+conn rw-isolate
+	rightgroups=isolate
+	leftsubnet=10.1.0.16/28
+	also=rw-eap
+	auto=add
+
+conn rw-eap
+	left=PH_IP_MOON
+	leftcert=moonCert.pem
+	leftid=@moon.strongswan.org
+	leftauth=eap-ttls
+	leftfirewall=yes
+	rightauth=eap-ttls
+	rightid=*@strongswan.org
+	rightsendcert=never
+	right=%any
diff --git a/testing/tests/tnc/tnccs-20-fail-init/hosts/moon/etc/ipsec.secrets b/testing/tests/tnc/tnccs-20-fail-init/hosts/moon/etc/ipsec.secrets
new file mode 100644
index 0000000..2e277cc
--- /dev/null
+++ b/testing/tests/tnc/tnccs-20-fail-init/hosts/moon/etc/ipsec.secrets
@@ -0,0 +1,6 @@
+# /etc/ipsec.secrets - strongSwan IPsec secrets file
+
+: RSA moonKey.pem
+
+carol at strongswan.org : EAP "Ar3etTnp"
+dave at strongswan.org  : EAP "W7R0g3do"
diff --git a/testing/tests/tnc/tnccs-20-fail-init/hosts/moon/etc/strongswan.conf b/testing/tests/tnc/tnccs-20-fail-init/hosts/moon/etc/strongswan.conf
new file mode 100644
index 0000000..9c13fcb
--- /dev/null
+++ b/testing/tests/tnc/tnccs-20-fail-init/hosts/moon/etc/strongswan.conf
@@ -0,0 +1,23 @@
+# /etc/strongswan.conf - strongSwan configuration file
+
+charon {
+  load = aes des sha1 sha2 md5 pem pkcs1 gmp random nonce x509 curl revocation hmac stroke kernel-netlink socket-default eap-identity eap-ttls eap-md5 eap-tnc tnc-imv tnc-tnccs tnccs-20 updown
+
+  multiple_authentication = no
+
+  plugins {
+    eap-ttls {
+      phase2_method = md5
+      phase2_piggyback = yes
+      phase2_tnc = yes
+    }
+  }
+}
+
+libimcv {
+  plugins {
+    imv-test {
+      rounds = 1
+    }
+  }
+}
diff --git a/testing/tests/tnc/tnccs-20-fail-init/hosts/moon/etc/tnc_config b/testing/tests/tnc/tnccs-20-fail-init/hosts/moon/etc/tnc_config
new file mode 100644
index 0000000..61b1410
--- /dev/null
+++ b/testing/tests/tnc/tnccs-20-fail-init/hosts/moon/etc/tnc_config
@@ -0,0 +1,3 @@
+#IMV configuration file for strongSwan client 
+
+IMV "Test"	/usr/local/lib/ipsec/imcvs/imv-test.so
diff --git a/testing/tests/tnc/tnccs-20-fail-init/posttest.dat b/testing/tests/tnc/tnccs-20-fail-init/posttest.dat
new file mode 100644
index 0000000..b757d8b
--- /dev/null
+++ b/testing/tests/tnc/tnccs-20-fail-init/posttest.dat
@@ -0,0 +1,6 @@
+carol::ipsec stop
+dave::ipsec stop
+moon::ipsec stop
+moon::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-fail-init/pretest.dat b/testing/tests/tnc/tnccs-20-fail-init/pretest.dat
new file mode 100644
index 0000000..38c6513
--- /dev/null
+++ b/testing/tests/tnc/tnccs-20-fail-init/pretest.dat
@@ -0,0 +1,12 @@
+moon::iptables-restore < /etc/iptables.rules
+carol::iptables-restore < /etc/iptables.rules
+dave::iptables-restore < /etc/iptables.rules
+moon::cat /etc/tnc_config
+carol::cat /etc/tnc_config
+dave::cat /etc/tnc_config
+moon::ipsec start
+carol::ipsec start 
+dave::ipsec start
+carol::sleep 1
+carol::ipsec up home
+dave::ipsec up home
diff --git a/testing/tests/tnc/tnccs-20-fail-init/test.conf b/testing/tests/tnc/tnccs-20-fail-init/test.conf
new file mode 100644
index 0000000..3c8e399
--- /dev/null
+++ b/testing/tests/tnc/tnccs-20-fail-init/test.conf
@@ -0,0 +1,26 @@
+#!/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 carol winnetou dave"
+
+# Corresponding block diagram
+#
+DIAGRAM="a-m-c-w-d.png"
+
+# Guest instances on which tcpdump is to be started
+#
+TCPDUMPHOSTS=""
+
+# Guest instances on which IPsec is started
+# Used for IPsec logging purposes
+#
+IPSECHOSTS="moon carol dave"
+
+# Guest instances on which FreeRadius is started
+#
+RADIUSHOSTS=
+
diff --git a/testing/tests/tnc/tnccs-20-fail-resp/description.txt b/testing/tests/tnc/tnccs-20-fail-resp/description.txt
new file mode 100644
index 0000000..0aa0719
--- /dev/null
+++ b/testing/tests/tnc/tnccs-20-fail-resp/description.txt
@@ -0,0 +1,9 @@
+The roadwarrior <b>carol</b> sets up a connection to gateway <b>moon</b>
+using EAP-TTLS authentication only with the gateway presenting a server certificate and
+the client doing EAP-MD5 password-based authentication.
+In a next step the EAP-TNC protocol is used within the EAP-TTLS tunnel to determine the
+health of <b>carol</b> via the <b>TNCCS 2.0 </b> client-server interface
+compliant with <b>RFC 5793 PB-TNC</b>.
+<p/>
+Unfortunately <b>moon</b> sends his first PB-TNC batch with a wrong version number .
+Therefore the connection setup fails due to a fatal PB-TNC error.
diff --git a/testing/tests/tnc/tnccs-20-fail-resp/evaltest.dat b/testing/tests/tnc/tnccs-20-fail-resp/evaltest.dat
new file mode 100644
index 0000000..df4bdc8
--- /dev/null
+++ b/testing/tests/tnc/tnccs-20-fail-resp/evaltest.dat
@@ -0,0 +1,5 @@
+carol:: cat /var/log/daemon.log::unsupported TNCCS batch version 0x03::YES
+moon::cat /var/log/daemon.log::received fatal PB-TNC error.*Version Not Supported.*caused by bad version 0x03::YES
+moon::cat /var/log/daemon.log::EAP_PT_EAP method failed::YES
+moon:: cat /var/log/daemon.log::EAP method EAP_TTLS failed for peer carol at strongswan.org::YES
+carol::cat /var/log/daemon.log::received EAP_FAILURE, EAP authentication failed::YES
diff --git a/testing/tests/tnc/tnccs-20-fail-resp/hosts/carol/etc/ipsec.conf b/testing/tests/tnc/tnccs-20-fail-resp/hosts/carol/etc/ipsec.conf
new file mode 100644
index 0000000..e2bf349
--- /dev/null
+++ b/testing/tests/tnc/tnccs-20-fail-resp/hosts/carol/etc/ipsec.conf
@@ -0,0 +1,23 @@
+# /etc/ipsec.conf - strongSwan IPsec configuration file
+
+config setup
+	charondebug="tnc 3, imc 3"
+
+conn %default
+	ikelifetime=60m
+	keylife=20m
+	rekeymargin=3m
+	keyingtries=1
+	keyexchange=ikev2
+
+conn home
+	left=PH_IP_CAROL
+	leftid=carol at strongswan.org
+	leftauth=eap
+	leftfirewall=yes
+	right=PH_IP_MOON
+	rightid=@moon.strongswan.org
+	rightauth=any
+	rightsendcert=never
+	rightsubnet=10.1.0.0/16
+	auto=add
diff --git a/testing/tests/tnc/tnccs-20-fail-resp/hosts/carol/etc/ipsec.secrets b/testing/tests/tnc/tnccs-20-fail-resp/hosts/carol/etc/ipsec.secrets
new file mode 100644
index 0000000..74942af
--- /dev/null
+++ b/testing/tests/tnc/tnccs-20-fail-resp/hosts/carol/etc/ipsec.secrets
@@ -0,0 +1,3 @@
+# /etc/ipsec.secrets - strongSwan IPsec secrets file
+
+carol at strongswan.org : EAP "Ar3etTnp"
diff --git a/testing/tests/tnc/tnccs-20-fail-resp/hosts/carol/etc/strongswan.conf b/testing/tests/tnc/tnccs-20-fail-resp/hosts/carol/etc/strongswan.conf
new file mode 100644
index 0000000..ed6d6f7
--- /dev/null
+++ b/testing/tests/tnc/tnccs-20-fail-resp/hosts/carol/etc/strongswan.conf
@@ -0,0 +1,15 @@
+# /etc/strongswan.conf - strongSwan configuration file
+
+charon {
+  load = aes des sha1 sha2 md5 pem pkcs1 gmp random nonce x509 curl revocation hmac stroke kernel-netlink socket-default eap-identity eap-md5 eap-ttls eap-tnc tnc-tnccs tnc-imc tnccs-20 updown
+
+  multiple_authentication = no
+}
+
+libimcv {
+  plugins {
+    imc-test {
+      command = allow
+    }
+  }
+}
diff --git a/testing/tests/tnc/tnccs-20-fail-resp/hosts/carol/etc/tnc_config b/testing/tests/tnc/tnccs-20-fail-resp/hosts/carol/etc/tnc_config
new file mode 100644
index 0000000..bfa6667
--- /dev/null
+++ b/testing/tests/tnc/tnccs-20-fail-resp/hosts/carol/etc/tnc_config
@@ -0,0 +1,3 @@
+#IMC configuration file for strongSwan client 
+
+IMC "Test"	/usr/local/lib/ipsec/imcvs/imc-test.so
diff --git a/testing/tests/tnc/tnccs-20-fail-resp/hosts/moon/etc/ipsec.conf b/testing/tests/tnc/tnccs-20-fail-resp/hosts/moon/etc/ipsec.conf
new file mode 100644
index 0000000..e21ef0d
--- /dev/null
+++ b/testing/tests/tnc/tnccs-20-fail-resp/hosts/moon/etc/ipsec.conf
@@ -0,0 +1,34 @@
+# /etc/ipsec.conf - strongSwan IPsec configuration file
+
+config setup
+	charondebug="tnc 3, imv 3"
+
+conn %default
+	ikelifetime=60m
+	keylife=20m
+	rekeymargin=3m
+	keyingtries=1
+	keyexchange=ikev2
+
+conn rw-allow
+	rightgroups=allow
+	leftsubnet=10.1.0.0/28
+	also=rw-eap
+	auto=add
+
+conn rw-isolate
+	rightgroups=isolate
+	leftsubnet=10.1.0.16/28
+	also=rw-eap
+	auto=add
+
+conn rw-eap
+	left=PH_IP_MOON
+	leftcert=moonCert.pem
+	leftid=@moon.strongswan.org
+	leftauth=eap-ttls
+	leftfirewall=yes
+	rightauth=eap-ttls
+	rightid=*@strongswan.org
+	rightsendcert=never
+	right=%any
diff --git a/testing/tests/tnc/tnccs-20-fail-resp/hosts/moon/etc/ipsec.secrets b/testing/tests/tnc/tnccs-20-fail-resp/hosts/moon/etc/ipsec.secrets
new file mode 100644
index 0000000..2e277cc
--- /dev/null
+++ b/testing/tests/tnc/tnccs-20-fail-resp/hosts/moon/etc/ipsec.secrets
@@ -0,0 +1,6 @@
+# /etc/ipsec.secrets - strongSwan IPsec secrets file
+
+: RSA moonKey.pem
+
+carol at strongswan.org : EAP "Ar3etTnp"
+dave at strongswan.org  : EAP "W7R0g3do"
diff --git a/testing/tests/tnc/tnccs-20-fail-resp/hosts/moon/etc/strongswan.conf b/testing/tests/tnc/tnccs-20-fail-resp/hosts/moon/etc/strongswan.conf
new file mode 100644
index 0000000..626731f
--- /dev/null
+++ b/testing/tests/tnc/tnccs-20-fail-resp/hosts/moon/etc/strongswan.conf
@@ -0,0 +1,28 @@
+# /etc/strongswan.conf - strongSwan configuration file
+
+charon {
+  load = aes des sha1 sha2 md5 pem pkcs1 gmp random nonce x509 curl revocation hmac stroke kernel-netlink socket-default eap-identity eap-ttls eap-md5 eap-tnc tnc-imv tnc-tnccs tnccs-20 updown
+
+  multiple_authentication = no
+
+  plugins {
+    eap-ttls {
+      phase2_method = md5
+      phase2_piggyback = yes
+      phase2_tnc = yes
+    }
+    tnccs-20 {
+      tests {
+        pb_tnc_version = 3
+      }
+    }
+  }
+}
+
+libimcv {
+  plugins {
+    imv-test {
+      rounds = 1
+    }
+  }
+}
diff --git a/testing/tests/tnc/tnccs-20-fail-resp/hosts/moon/etc/tnc_config b/testing/tests/tnc/tnccs-20-fail-resp/hosts/moon/etc/tnc_config
new file mode 100644
index 0000000..61b1410
--- /dev/null
+++ b/testing/tests/tnc/tnccs-20-fail-resp/hosts/moon/etc/tnc_config
@@ -0,0 +1,3 @@
+#IMV configuration file for strongSwan client 
+
+IMV "Test"	/usr/local/lib/ipsec/imcvs/imv-test.so
diff --git a/testing/tests/tnc/tnccs-20-fail-resp/posttest.dat b/testing/tests/tnc/tnccs-20-fail-resp/posttest.dat
new file mode 100644
index 0000000..80ce1a1
--- /dev/null
+++ b/testing/tests/tnc/tnccs-20-fail-resp/posttest.dat
@@ -0,0 +1,4 @@
+carol::ipsec stop
+moon::ipsec stop
+moon::iptables-restore < /etc/iptables.flush
+carol::iptables-restore < /etc/iptables.flush
diff --git a/testing/tests/tnc/tnccs-20-fail-resp/pretest.dat b/testing/tests/tnc/tnccs-20-fail-resp/pretest.dat
new file mode 100644
index 0000000..6947c4b
--- /dev/null
+++ b/testing/tests/tnc/tnccs-20-fail-resp/pretest.dat
@@ -0,0 +1,8 @@
+moon::iptables-restore < /etc/iptables.rules
+carol::iptables-restore < /etc/iptables.rules
+moon::cat /etc/tnc_config
+carol::cat /etc/tnc_config
+moon::ipsec start
+carol::ipsec start 
+carol::sleep 1
+carol::ipsec up home
diff --git a/testing/tests/tnc/tnccs-20-fail-resp/test.conf b/testing/tests/tnc/tnccs-20-fail-resp/test.conf
new file mode 100644
index 0000000..e843074
--- /dev/null
+++ b/testing/tests/tnc/tnccs-20-fail-resp/test.conf
@@ -0,0 +1,26 @@
+#!/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 carol winnetou"
+
+# Corresponding block diagram
+#
+DIAGRAM="a-m-c-w.png"
+
+# Guest instances on which tcpdump is to be started
+#
+TCPDUMPHOSTS=""
+
+# Guest instances on which IPsec is started
+# Used for IPsec logging purposes
+#
+IPSECHOSTS="moon carol"
+
+# Guest instances on which FreeRadius is started
+#
+RADIUSHOSTS=
+
diff --git a/testing/tests/tnc/tnccs-20-mutual-eap/description.txt b/testing/tests/tnc/tnccs-20-mutual-eap/description.txt
new file mode 100644
index 0000000..6c79b8c
--- /dev/null
+++ b/testing/tests/tnc/tnccs-20-mutual-eap/description.txt
@@ -0,0 +1,3 @@
+The hosts <b>moon</b> and <b>sun</b> do mutual TNC measurements over IKEv2-EAP
+using the PA-TNC, PB-TNC and PT-EAP protocols. The authentication is based on
+X.509 certificates.
diff --git a/testing/tests/tnc/tnccs-20-mutual-eap/evaltest.dat b/testing/tests/tnc/tnccs-20-mutual-eap/evaltest.dat
new file mode 100644
index 0000000..0ef7b5d
--- /dev/null
+++ b/testing/tests/tnc/tnccs-20-mutual-eap/evaltest.dat
@@ -0,0 +1,11 @@
+moon::cat /var/log/daemon.log::activating mutual PB-TNC half duplex protocol::YES
+sun:: cat /var/log/daemon.log::activating mutual PB-TNC half duplex protocol::YES
+moon::cat /var/log/daemon.log::PB-TNC access recommendation is.*Access Allowed::YES
+sun:: cat /var/log/daemon.log::PB-TNC access recommendation is.*Access Allowed::YES
+moon::ipsec status 2> /dev/null::host-host.*ESTABLISHED.*moon.strongswan.org.*sun.strongswan.org::YES
+sun:: ipsec status 2> /dev/null::host-host.*ESTABLISHED.*sun.strongswan.org.*moon.strongswan.org::YES
+moon::ipsec status 2> /dev/null::host-host.*INSTALLED, TUNNEL::YES
+sun:: ipsec status 2> /dev/null::host-host.*INSTALLED, TUNNEL::YES
+moon::ping -c 1 PH_IP_SUN::64 bytes from PH_IP_SUN: icmp_req=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/tnc/tnccs-20-mutual-eap/hosts/moon/etc/ipsec.conf b/testing/tests/tnc/tnccs-20-mutual-eap/hosts/moon/etc/ipsec.conf
new file mode 100644
index 0000000..47a0283
--- /dev/null
+++ b/testing/tests/tnc/tnccs-20-mutual-eap/hosts/moon/etc/ipsec.conf
@@ -0,0 +1,23 @@
+# /etc/ipsec.conf - strongSwan IPsec configuration file
+
+config setup
+	charondebug="tnc 2, imc 2, imv 2"
+
+conn %default
+	ikelifetime=60m
+	keylife=20m
+	rekeymargin=3m
+	keyingtries=1
+	keyexchange=ikev2
+
+conn host-host
+	left=PH_IP_MOON
+	leftcert=moonCert.pem
+	leftid=moon.strongswan.org
+	leftauth=eap
+	leftfirewall=yes
+	right=PH_IP_SUN
+	rightid=sun.strongswan.org
+	rightsendcert=never
+	rightauth=any
+	auto=add
diff --git a/testing/tests/tnc/tnccs-20-mutual-eap/hosts/moon/etc/strongswan.conf b/testing/tests/tnc/tnccs-20-mutual-eap/hosts/moon/etc/strongswan.conf
new file mode 100644
index 0000000..953e7fc
--- /dev/null
+++ b/testing/tests/tnc/tnccs-20-mutual-eap/hosts/moon/etc/strongswan.conf
@@ -0,0 +1,26 @@
+# /etc/strongswan.conf - strongSwan configuration file
+
+charon {
+  load = x509 openssl pem pkcs1 random nonce curl revocation stroke kernel-netlink socket-default eap-identity eap-ttls eap-tnc tnc-tnccs tnc-imc tnc-imv tnccs-20 updown
+
+  multiple_authentication = no
+  plugins {
+    eap-ttls {
+      phase2_tnc =yes
+    }
+    tnccs-20 {
+      mutual = yes
+    }
+  }
+}
+
+libimcv {
+  plugins {
+    imc-test {
+      command = allow
+    }
+    imv-test {
+      rounds = 1
+    }   
+  }
+}
diff --git a/testing/tests/tnc/tnccs-20-mutual-eap/hosts/moon/etc/tnc_config b/testing/tests/tnc/tnccs-20-mutual-eap/hosts/moon/etc/tnc_config
new file mode 100644
index 0000000..476e880
--- /dev/null
+++ b/testing/tests/tnc/tnccs-20-mutual-eap/hosts/moon/etc/tnc_config
@@ -0,0 +1,4 @@
+#IMC/IMV configuration file for strongSwan endpoint 
+
+IMC "Test" /usr/local/lib/ipsec/imcvs/imc-test.so
+IMV "Test" /usr/local/lib/ipsec/imcvs/imv-test.so
diff --git a/testing/tests/tnc/tnccs-20-mutual-eap/hosts/sun/etc/ipsec.conf b/testing/tests/tnc/tnccs-20-mutual-eap/hosts/sun/etc/ipsec.conf
new file mode 100644
index 0000000..c20bce9
--- /dev/null
+++ b/testing/tests/tnc/tnccs-20-mutual-eap/hosts/sun/etc/ipsec.conf
@@ -0,0 +1,23 @@
+# /etc/ipsec.conf - strongSwan IPsec configuration file
+
+config setup
+	charondebug="tnc 2, imc 2, imv 2"
+
+conn %default
+	ikelifetime=60m
+	keylife=20m
+	rekeymargin=3m
+	keyingtries=1
+	keyexchange=ikev2
+
+conn host-host
+	left=PH_IP_SUN
+	leftcert=sunCert.pem
+	leftid=sun.strongswan.org
+	leftauth=eap-ttls
+	leftfirewall=yes
+	right=PH_IP_MOON
+	rightid=moon.strongswan.org
+	rightauth=eap-ttls
+	rightsendcert=never
+	auto=add
diff --git a/testing/tests/tnc/tnccs-20-mutual-eap/hosts/sun/etc/strongswan.conf b/testing/tests/tnc/tnccs-20-mutual-eap/hosts/sun/etc/strongswan.conf
new file mode 100644
index 0000000..570126a
--- /dev/null
+++ b/testing/tests/tnc/tnccs-20-mutual-eap/hosts/sun/etc/strongswan.conf
@@ -0,0 +1,28 @@
+# /etc/strongswan.conf - strongSwan configuration file
+
+charon {
+  load = x509 openssl pem pkcs1 random nonce curl revocation stroke kernel-netlink socket-default eap-identity eap-ttls eap-tnc tnc-tnccs tnc-imc tnc-imv tnccs-20 updown
+
+  multiple_authentication = no
+  plugins {
+    eap-ttls {
+      request_peer_auth = yes
+      phase2_piggyback = yes
+      phase2_tnc =yes
+    }
+    tnccs-20 {
+      mutual = yes
+    }
+  }
+}
+
+libimcv {
+  plugins {
+    imc-test {
+      command = allow 
+    }
+    imv-test {
+      rounds = 1 
+    }   
+  }
+}
diff --git a/testing/tests/tnc/tnccs-20-mutual-eap/hosts/sun/etc/tnc_config b/testing/tests/tnc/tnccs-20-mutual-eap/hosts/sun/etc/tnc_config
new file mode 100644
index 0000000..476e880
--- /dev/null
+++ b/testing/tests/tnc/tnccs-20-mutual-eap/hosts/sun/etc/tnc_config
@@ -0,0 +1,4 @@
+#IMC/IMV configuration file for strongSwan endpoint 
+
+IMC "Test" /usr/local/lib/ipsec/imcvs/imc-test.so
+IMV "Test" /usr/local/lib/ipsec/imcvs/imv-test.so
diff --git a/testing/tests/tnc/tnccs-20-mutual-eap/posttest.dat b/testing/tests/tnc/tnccs-20-mutual-eap/posttest.dat
new file mode 100644
index 0000000..1f7aa73
--- /dev/null
+++ b/testing/tests/tnc/tnccs-20-mutual-eap/posttest.dat
@@ -0,0 +1,4 @@
+moon::ipsec stop
+sun::ipsec stop
+moon::iptables-restore < /etc/iptables.flush
+sun::iptables-restore < /etc/iptables.flush
diff --git a/testing/tests/tnc/tnccs-20-mutual-eap/pretest.dat b/testing/tests/tnc/tnccs-20-mutual-eap/pretest.dat
new file mode 100644
index 0000000..3bce9f6
--- /dev/null
+++ b/testing/tests/tnc/tnccs-20-mutual-eap/pretest.dat
@@ -0,0 +1,6 @@
+moon::iptables-restore < /etc/iptables.rules
+sun::iptables-restore < /etc/iptables.rules
+moon::ipsec start
+sun::ipsec start
+moon::sleep 1 
+moon::ipsec up host-host
diff --git a/testing/tests/tnc/tnccs-20-mutual-eap/test.conf b/testing/tests/tnc/tnccs-20-mutual-eap/test.conf
new file mode 100644
index 0000000..55d6e9f
--- /dev/null
+++ b/testing/tests/tnc/tnccs-20-mutual-eap/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-mutual-pt-tls/description.txt b/testing/tests/tnc/tnccs-20-mutual-pt-tls/description.txt
new file mode 100644
index 0000000..09ab8e9
--- /dev/null
+++ b/testing/tests/tnc/tnccs-20-mutual-pt-tls/description.txt
@@ -0,0 +1,3 @@
+The hosts <b>moon</b> and <b>sun</b> do mutual TNC measurements using the
+PA-TNC, PB-TNC and PT-TLS protocols. The authentication is based on
+X.509 certificates.
diff --git a/testing/tests/tnc/tnccs-20-mutual-pt-tls/evaltest.dat b/testing/tests/tnc/tnccs-20-mutual-pt-tls/evaltest.dat
new file mode 100644
index 0000000..eb99619
--- /dev/null
+++ b/testing/tests/tnc/tnccs-20-mutual-pt-tls/evaltest.dat
@@ -0,0 +1,6 @@
+moon::cat /var/log/auth.log::PT-TLS authentication complete::YES
+sun:: cat /var/log/daemon.log::skipping SASL, client already authenticated by TLS certificate::YES
+moon::cat /var/log/auth.log::activating mutual PB-TNC half duplex protocol::YES
+sun:: cat /var/log/daemon.log::activating mutual PB-TNC half duplex protocol::YES
+moon::cat /var/log/auth.log::PB-TNC access recommendation is.*Access Allowed::YES
+sun:: cat /var/log/daemon.log::PB-TNC access recommendation is.*Access Allowed::YES
diff --git a/testing/tests/tnc/tnccs-20-mutual-pt-tls/hosts/moon/etc/ipsec.conf b/testing/tests/tnc/tnccs-20-mutual-pt-tls/hosts/moon/etc/ipsec.conf
new file mode 100644
index 0000000..98c415e
--- /dev/null
+++ b/testing/tests/tnc/tnccs-20-mutual-pt-tls/hosts/moon/etc/ipsec.conf
@@ -0,0 +1,3 @@
+# /etc/ipsec.conf - strongSwan IPsec configuration file
+
+/* configuration is read from /etc/pts/options  */
diff --git a/testing/tests/tnc/tnccs-20-mutual-pt-tls/hosts/moon/etc/pts/options b/testing/tests/tnc/tnccs-20-mutual-pt-tls/hosts/moon/etc/pts/options
new file mode 100644
index 0000000..79ae1e8
--- /dev/null
+++ b/testing/tests/tnc/tnccs-20-mutual-pt-tls/hosts/moon/etc/pts/options
@@ -0,0 +1,8 @@
+--connect sun.strongswan.org
+--client moon.strongswan.org
+--key /etc/ipsec.d/private/moonKey.pem
+--cert /etc/ipsec.d/certs/moonCert.pem
+--cert /etc/ipsec.d/cacerts/strongswanCert.pem
+--mutual
+--quiet
+--debug 2
diff --git a/testing/tests/tnc/tnccs-20-mutual-pt-tls/hosts/moon/etc/strongswan.conf b/testing/tests/tnc/tnccs-20-mutual-pt-tls/hosts/moon/etc/strongswan.conf
new file mode 100644
index 0000000..fafdac4
--- /dev/null
+++ b/testing/tests/tnc/tnccs-20-mutual-pt-tls/hosts/moon/etc/strongswan.conf
@@ -0,0 +1,16 @@
+# /etc/strongswan.conf - strongSwan configuration file
+
+pt-tls-client {
+  load = x509 openssl pem pkcs1 random nonce revocation curl tnc-tnccs tnc-imc tnc-imv tnccs-20 
+}
+
+libimcv {
+  plugins {
+    imc-test {
+      command = allow
+    }
+    imv-test {
+      rounds = 1
+    }   
+  }
+}
diff --git a/testing/tests/tnc/tnccs-20-mutual-pt-tls/hosts/moon/etc/tnc_config b/testing/tests/tnc/tnccs-20-mutual-pt-tls/hosts/moon/etc/tnc_config
new file mode 100644
index 0000000..476e880
--- /dev/null
+++ b/testing/tests/tnc/tnccs-20-mutual-pt-tls/hosts/moon/etc/tnc_config
@@ -0,0 +1,4 @@
+#IMC/IMV configuration file for strongSwan endpoint 
+
+IMC "Test" /usr/local/lib/ipsec/imcvs/imc-test.so
+IMV "Test" /usr/local/lib/ipsec/imcvs/imv-test.so
diff --git a/testing/tests/tnc/tnccs-20-mutual-pt-tls/hosts/sun/etc/ipsec.conf b/testing/tests/tnc/tnccs-20-mutual-pt-tls/hosts/sun/etc/ipsec.conf
new file mode 100644
index 0000000..ba629a2
--- /dev/null
+++ b/testing/tests/tnc/tnccs-20-mutual-pt-tls/hosts/sun/etc/ipsec.conf
@@ -0,0 +1,9 @@
+# /etc/ipsec.conf - strongSwan IPsec configuration file
+
+config setup
+	charondebug="tnc 2, imc 2, imv 2"
+
+conn pdp 
+	leftcert=sunCert.pem
+	leftid=sun.strongswan.org
+	auto=add
diff --git a/testing/tests/tnc/tnccs-20-mutual-pt-tls/hosts/sun/etc/strongswan.conf b/testing/tests/tnc/tnccs-20-mutual-pt-tls/hosts/sun/etc/strongswan.conf
new file mode 100644
index 0000000..05ffdb1
--- /dev/null
+++ b/testing/tests/tnc/tnccs-20-mutual-pt-tls/hosts/sun/etc/strongswan.conf
@@ -0,0 +1,28 @@
+# /etc/strongswan.conf - strongSwan configuration file
+
+charon {
+  load = x509 openssl pem pkcs1 random nonce curl revocation stroke kernel-netlink socket-default tnc-pdp tnc-tnccs tnc-imc tnc-imv tnccs-20 
+
+  plugins {
+    tnc-pdp {
+      server = sun.strongswan.org
+      radius {
+        enable = no
+      }
+    }
+    tnccs-20 {
+      mutual = yes
+    }
+  }
+}
+
+libimcv {
+  plugins {
+    imc-test {
+      command = allow 
+    }
+    imv-test {
+      rounds = 1 
+    }   
+  }
+}
diff --git a/testing/tests/tnc/tnccs-20-mutual-pt-tls/hosts/sun/etc/tnc_config b/testing/tests/tnc/tnccs-20-mutual-pt-tls/hosts/sun/etc/tnc_config
new file mode 100644
index 0000000..476e880
--- /dev/null
+++ b/testing/tests/tnc/tnccs-20-mutual-pt-tls/hosts/sun/etc/tnc_config
@@ -0,0 +1,4 @@
+#IMC/IMV configuration file for strongSwan endpoint 
+
+IMC "Test" /usr/local/lib/ipsec/imcvs/imc-test.so
+IMV "Test" /usr/local/lib/ipsec/imcvs/imv-test.so
diff --git a/testing/tests/tnc/tnccs-20-mutual-pt-tls/posttest.dat b/testing/tests/tnc/tnccs-20-mutual-pt-tls/posttest.dat
new file mode 100644
index 0000000..e6ccb14
--- /dev/null
+++ b/testing/tests/tnc/tnccs-20-mutual-pt-tls/posttest.dat
@@ -0,0 +1 @@
+sun::ipsec stop
diff --git a/testing/tests/tnc/tnccs-20-mutual-pt-tls/pretest.dat b/testing/tests/tnc/tnccs-20-mutual-pt-tls/pretest.dat
new file mode 100644
index 0000000..fab55d1
--- /dev/null
+++ b/testing/tests/tnc/tnccs-20-mutual-pt-tls/pretest.dat
@@ -0,0 +1,4 @@
+sun::ipsec start
+moon::cat /etc/pts/options
+moon::sleep 1
+moon::ipsec pt-tls-client --optionsfrom /etc/pts/options 
diff --git a/testing/tests/tnc/tnccs-20-mutual-pt-tls/test.conf b/testing/tests/tnc/tnccs-20-mutual-pt-tls/test.conf
new file mode 100644
index 0000000..55d6e9f
--- /dev/null
+++ b/testing/tests/tnc/tnccs-20-mutual-pt-tls/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-pdp-eap/evaltest.dat b/testing/tests/tnc/tnccs-20-pdp-eap/evaltest.dat
index a86fcff..f744453 100644
--- a/testing/tests/tnc/tnccs-20-pdp-eap/evaltest.dat
+++ b/testing/tests/tnc/tnccs-20-pdp-eap/evaltest.dat
@@ -1,10 +1,10 @@
-dave:: cat /var/log/daemon.log::authentication of 'moon.strongswan.org' with RSA signature successful::YES
+dave:: cat /var/log/daemon.log::authentication of 'moon.strongswan.org' with RSA.* successful::YES
 dave:: cat /var/log/daemon.log::PDP server.*aaa.strongswan.org.*is listening on port 271::YES
 dave:: cat /var/log/daemon.log::collected ... SWID tags::YES
 dave:: cat /var/log/daemon.log::PB-TNC access recommendation is .*Quarantined::YES
 dave:: cat /var/log/daemon.log::EAP method EAP_TTLS succeeded, MSK established::YES
 dave:: cat /var/log/daemon.log::CHILD_SA home{1} established.*TS 192.168.0.200/32 === 10.1.0.16/28::YES
-carol::cat /var/log/daemon.log::authentication of 'moon.strongswan.org' with RSA signature successful::YES
+carol::cat /var/log/daemon.log::authentication of 'moon.strongswan.org' with RSA.* successful::YES
 carol::cat /var/log/daemon.log::PDP server.*aaa.strongswan.org.*is listening on port 271::YES
 carol::cat /var/log/daemon.log::collected ... SWID tag IDs::YES
 carol::cat /var/log/daemon.log::collected 1 SWID tag::YES

-- 
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